diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 26b6ad7..5a83604 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -258,6 +258,7 @@
             // DISCONNECTED for GPRS in any order.  if we receive the CONNECTED first, and then
             // a DISCONNECTED, we want to make sure we set mDataConnectionIsConnected to true
             // since we still have a WiFi connection.
+            final boolean wasConnected = mDataConnectionIsConnected;
             switch (state) {
                 case CONNECTED:
                     mDataConnectionIsConnected = true;
@@ -273,6 +274,12 @@
                     // ignore the rest of the states -- leave our boolean alone.
             }
             if (mDataConnectionIsConnected) {
+                if (!wasConnected) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, "Reconnection detected: clearing all backoffs");
+                    }
+                    mSyncStorageEngine.clearAllBackoffs();
+                }
                 sendCheckAlarmsMessage();
             }
         }
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index e1a9dbb..faf1365 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -525,6 +525,32 @@
         }
     }
 
+    public void clearAllBackoffs() {
+        boolean changed = false;
+        synchronized (mAuthorities) {
+            for (AccountInfo accountInfo : mAccounts.values()) {
+                for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) {
+                    if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE
+                            || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) {
+                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                            Log.v(TAG, "clearAllBackoffs:"
+                                    + " authority:" + authorityInfo.authority
+                                    + " account:" + accountInfo.account.name
+                                    + " backoffTime was: " + authorityInfo.backoffTime
+                                    + " backoffDelay was: " + authorityInfo.backoffDelay);
+                        }
+                        authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE;
+                        authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE;
+                        changed = true;
+                    }
+                }
+            }
+        }
+
+        if (changed) {
+            reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
+        }
+    }
     public void setDelayUntilTime(Account account, String providerName, long delayUntil) {
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG, "setDelayUntil: " + account + ", provider " + providerName
diff --git a/core/java/android/net/http/AndroidHttpClient.java b/core/java/android/net/http/AndroidHttpClient.java
index e07ee59..0757293 100644
--- a/core/java/android/net/http/AndroidHttpClient.java
+++ b/core/java/android/net/http/AndroidHttpClient.java
@@ -108,8 +108,8 @@
         HttpConnectionParams.setStaleCheckingEnabled(params, false);
 
         // Default connection and socket timeout of 20 seconds.  Tweak to taste.
-        HttpConnectionParams.setConnectionTimeout(params, 20 * 1000);
-        HttpConnectionParams.setSoTimeout(params, 20 * 1000);
+        HttpConnectionParams.setConnectionTimeout(params, 60 * 1000);
+        HttpConnectionParams.setSoTimeout(params, 60 * 1000);
         HttpConnectionParams.setSocketBufferSize(params, 8192);
 
         // Don't handle redirects -- return them to the caller.  Our code
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 622bcdb..8c56fda 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -702,4 +702,28 @@
             return null;
         }
     }
+
+    /**
+     * To change the Secure Element Card Emulation state (ON/OFF)
+     * @hide
+     */
+    public void changeNfcSecureElementCardEmulationState(boolean state)
+    {
+        int seId = 11259375;
+        if(state){
+            /* Enable card emulation */
+            try {
+                sService.selectSecureElement(seId);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Enable card emulation failed", e);
+            }
+        }else{
+            /* Disable card emulation */
+            try {
+                sService.deselectSecureElement();
+            } catch (RemoteException e) {
+                Log.e(TAG, " card emulation failed", e);
+            }
+        }
+    }
 }
diff --git a/core/java/android/nfc/tech/Ndef.java b/core/java/android/nfc/tech/Ndef.java
index 6727d6a..e4daa57 100644
--- a/core/java/android/nfc/tech/Ndef.java
+++ b/core/java/android/nfc/tech/Ndef.java
@@ -103,6 +103,8 @@
     public static final int TYPE_4 = 4;
     /** @hide */
     public static final int TYPE_MIFARE_CLASSIC = 101;
+    /** @hide */
+    public static final int TYPE_ICODE_SLI = 102;
 
     /** @hide */
     public static final String UNKNOWN = "android.ndef.unknown";
@@ -117,6 +119,11 @@
     public static final String NFC_FORUM_TYPE_4 = "org.nfcforum.ndef.type4";
     /** NDEF on MIFARE Classic */
     public static final String MIFARE_CLASSIC = "com.nxp.ndef.mifareclassic";
+    /**
+     * NDEF on iCODE SLI
+     * @hide
+     */
+    public static final String ICODE_SLI = "com.nxp.ndef.icodesli";
 
     private final int mMaxNdefSize;
     private final int mCardState;
@@ -200,6 +207,8 @@
                 return NFC_FORUM_TYPE_4;
             case TYPE_MIFARE_CLASSIC:
                 return MIFARE_CLASSIC;
+            case TYPE_ICODE_SLI:
+                return ICODE_SLI;
             default:
                 return UNKNOWN;
         }
diff --git a/core/java/android/nfc/tech/package.html b/core/java/android/nfc/tech/package.html
new file mode 100644
index 0000000..a99828f
--- /dev/null
+++ b/core/java/android/nfc/tech/package.html
@@ -0,0 +1,13 @@
+<HTML>
+<BODY>
+<p>
+These classes provide access to a tag technology's features, which vary by the type
+of tag that is scanned. A scanned tag can support multiple technologies, and you can find
+out what they are by calling {@link android.nfc.Tag#getTechList getTechList()}.</p>
+
+<p>For more information on dealing with tag technologies and handling the ones that you care about, see
+<a href="{@docRoot}guide/topics/nfc/index.html#dispatch">The Tag Dispatch System</a>.
+The {@link android.nfc.tech.TagTechnology} interface provides an overview of the
+supported technologies.</p>
+</BODY>
+</HTML>
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index e4485d1..5de76ff 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -132,6 +132,7 @@
     private static final String NETWORK_DATA = "nt";
     private static final String USER_ACTIVITY_DATA = "ua";
     private static final String BATTERY_DATA = "bt";
+    private static final String BATTERY_DISCHARGE_DATA = "dc";
     private static final String BATTERY_LEVEL_DATA = "lv";
     private static final String WIFI_LOCK_DATA = "wfl";
     private static final String MISC_DATA = "m";
@@ -801,6 +802,30 @@
     public abstract int getHighDischargeAmountSinceCharge();
 
     /**
+     * Get the amount the battery has discharged while the screen was on,
+     * since the last time power was unplugged.
+     */
+    public abstract int getDischargeAmountScreenOn();
+
+    /**
+     * Get the amount the battery has discharged while the screen was on,
+     * since the last time the device was charged.
+     */
+    public abstract int getDischargeAmountScreenOnSinceCharge();
+
+    /**
+     * Get the amount the battery has discharged while the screen was off,
+     * since the last time power was unplugged.
+     */
+    public abstract int getDischargeAmountScreenOff();
+
+    /**
+     * Get the amount the battery has discharged while the screen was off,
+     * since the last time the device was charged.
+     */
+    public abstract int getDischargeAmountScreenOffSinceCharge();
+
+    /**
      * Returns the total, last, or current battery uptime in microseconds.
      *
      * @param curTime the elapsed realtime in microseconds.
@@ -1095,6 +1120,17 @@
                     getDischargeCurrentLevel());
         }
         
+        if (which == STATS_SINCE_UNPLUGGED) {
+            dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
+                    getDischargeStartLevel()-getDischargeCurrentLevel(),
+                    getDischargeStartLevel()-getDischargeCurrentLevel(),
+                    getDischargeAmountScreenOn(), getDischargeAmountScreenOff());
+        } else {
+            dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA,
+                    getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(),
+                    getDischargeAmountScreenOn(), getDischargeAmountScreenOff());
+        }
+        
         if (reqUid < 0) {
             Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
             if (kernelWakelocks.size() > 0) {
@@ -1451,6 +1487,10 @@
                 pw.print(prefix); pw.print("    Last discharge cycle end level: "); 
                         pw.println(getDischargeCurrentLevel());
             }
+            pw.print(prefix); pw.print("    Amount discharged while screen on: ");
+                    pw.println(getDischargeAmountScreenOn());
+            pw.print(prefix); pw.print("    Amount discharged while screen off: ");
+                    pw.println(getDischargeAmountScreenOff());
             pw.println(" ");
         } else {
             pw.print(prefix); pw.println("  Device battery use since last full charge");
@@ -1458,6 +1498,10 @@
                     pw.println(getLowDischargeAmountSinceCharge());
             pw.print(prefix); pw.print("    Amount discharged (upper bound): ");
                     pw.println(getHighDischargeAmountSinceCharge());
+            pw.print(prefix); pw.print("    Amount discharged while screen on: ");
+                    pw.println(getDischargeAmountScreenOnSinceCharge());
+            pw.print(prefix); pw.print("    Amount discharged while screen off: ");
+                    pw.println(getDischargeAmountScreenOffSinceCharge());
             pw.println(" ");
         }
         
diff --git a/core/java/android/pim/ICalendar.java b/core/java/android/pim/ICalendar.java
index cc0f45e..9c4eaf4 100644
--- a/core/java/android/pim/ICalendar.java
+++ b/core/java/android/pim/ICalendar.java
@@ -578,6 +578,23 @@
                             + text);
                 }
                 parameter.name = text.substring(startIndex + 1, equalIndex);
+            } else if (c == '"') {
+                if (parameter == null) {
+                    throw new FormatException("Expected parameter before '\"' in " + text);
+                }
+                if (equalIndex == -1) {
+                    throw new FormatException("Expected '=' within parameter in " + text);
+                }
+                if (state.index > equalIndex + 1) {
+                    throw new FormatException("Parameter value cannot contain a '\"' in " + text);
+                }
+                final int endQuote = text.indexOf('"', state.index + 1);
+                if (endQuote < 0) {
+                    throw new FormatException("Expected closing '\"' in " + text);
+                }
+                parameter.value = text.substring(state.index + 1, endQuote);
+                state.index = endQuote + 1;
+                return parameter;
             }
             ++state.index;
         }
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index a371290..595b487 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -22,6 +22,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.format.DateFormat;
+import android.text.format.DateUtils;
 import android.util.AttributeSet;
 import android.util.SparseArray;
 import android.view.LayoutInflater;
@@ -33,6 +34,7 @@
 import java.text.DateFormatSymbols;
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
+import java.util.Locale;
 
 /**
  * A view for selecting a month / year / day based on a calendar like layout.
@@ -47,7 +49,10 @@
 
     private static final int DEFAULT_START_YEAR = 1900;
     private static final int DEFAULT_END_YEAR = 2100;
-    
+
+    // This ignores Undecimber, but we only support real Gregorian calendars.
+    private static final int NUMBER_OF_MONTHS = 12;
+
     /* UI Components */
     private final NumberPicker mDayPicker;
     private final NumberPicker mMonthPicker;
@@ -62,6 +67,10 @@
     private int mMonth;
     private int mYear;
 
+    private Object mMonthUpdateLock = new Object();
+    private volatile Locale mMonthLocale;
+    private String[] mShortMonths;
+
     /**
      * The callback used to indicate the user changes the date.
      */
@@ -102,8 +111,7 @@
         });
         mMonthPicker = (NumberPicker) findViewById(R.id.month);
         mMonthPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
-        DateFormatSymbols dfs = new DateFormatSymbols();
-        String[] months = dfs.getShortMonths();
+        final String[] months = getShortMonths();
 
         /*
          * If the user is in a locale where the month names are numeric,
@@ -114,9 +122,9 @@
             for (int i = 0; i < months.length; i++) {
                 months[i] = String.valueOf(i + 1);
             }
-            mMonthPicker.setRange(1, 12);
+            mMonthPicker.setRange(1, NUMBER_OF_MONTHS);
         } else {
-            mMonthPicker.setRange(1, 12, months);
+            mMonthPicker.setRange(1, NUMBER_OF_MONTHS, months);
         }
 
         mMonthPicker.setSpeed(200);
@@ -246,11 +254,30 @@
             mMonth = monthOfYear;
             mDay = dayOfMonth;
             updateSpinners();
-            reorderPickers(new DateFormatSymbols().getShortMonths());
+            reorderPickers(getShortMonths());
             notifyDateChanged();
         }
     }
 
+    private String[] getShortMonths() {
+        final Locale currentLocale = Locale.getDefault();
+        if (currentLocale.equals(mMonthLocale) && mShortMonths != null) {
+            return mShortMonths;
+        } else {
+            synchronized (mMonthUpdateLock) {
+                if (!currentLocale.equals(mMonthLocale)) {
+                    mShortMonths = new String[NUMBER_OF_MONTHS];
+                    for (int i = 0; i < NUMBER_OF_MONTHS; i++) {
+                        mShortMonths[i] = DateUtils.getMonthString(Calendar.JANUARY + i,
+                                DateUtils.LENGTH_MEDIUM);
+                    }
+                    mMonthLocale = currentLocale;
+                }
+            }
+            return mShortMonths;
+        }
+    }
+
     private static class SavedState extends BaseSavedState {
 
         private final int mYear;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 0afd5a0..05e9678c 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -6822,11 +6822,11 @@
     public boolean onTouchEvent(MotionEvent event) {
         final int action = event.getActionMasked();
 
-        if (mInsertionPointCursorController != null) {
-            mInsertionPointCursorController.onTouchEvent(event);
+        if (hasInsertionController()) {
+            getInsertionController().onTouchEvent(event);
         }
-        if (mSelectionModifierCursorController != null) {
-            mSelectionModifierCursorController.onTouchEvent(event);
+        if (hasSelectionController()) {
+            getSelectionController().onTouchEvent(event);
         }
 
         if (action == MotionEvent.ACTION_DOWN) {
@@ -7324,9 +7324,9 @@
             minOffset = getSelectionStart();
             maxOffset = getSelectionEnd();
         } else {
-            // selectionModifierCursorController is not null at that point
+            // hasSelectionController is true since we canSelectText.
             SelectionModifierCursorController selectionModifierCursorController =
-                ((SelectionModifierCursorController) mSelectionModifierCursorController);
+                (SelectionModifierCursorController) getSelectionController();
             minOffset = selectionModifierCursorController.getMinTouchOffset();
             maxOffset = selectionModifierCursorController.getMaxTouchOffset();
         }
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index f020a06..5000517 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -68,7 +68,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS' 
 
     // Current on-disk Parcel version
-    private static final int VERSION = 52;
+    private static final int VERSION = 53;
 
     // Maximum number of items we will record in the history.
     private static final int MAX_HISTORY_ITEMS = 2000;
@@ -235,6 +235,12 @@
     int mDischargeCurrentLevel;
     int mLowDischargeAmountSinceCharge;
     int mHighDischargeAmountSinceCharge;
+    int mDischargeScreenOnUnplugLevel;
+    int mDischargeScreenOffUnplugLevel;
+    int mDischargeAmountScreenOn;
+    int mDischargeAmountScreenOnSinceCharge;
+    int mDischargeAmountScreenOff;
+    int mDischargeAmountScreenOffSinceCharge;
 
     long mLastWriteTime = 0; // Milliseconds
 
@@ -1565,6 +1571,11 @@
             // Fake a wake lock, so we consider the device waked as long
             // as the screen is on.
             noteStartWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
+            
+            // Update discharge amounts.
+            if (mOnBatteryInternal) {
+                updateDischargeScreenLevels(false, true);
+            }
         }
     }
     
@@ -1581,6 +1592,11 @@
             }
 
             noteStopWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
+            
+            // Update discharge amounts.
+            if (mOnBatteryInternal) {
+                updateDischargeScreenLevels(true, false);
+            }
         }
     }
     
@@ -3897,8 +3913,7 @@
         mDischargeStartLevel = 0;
         mDischargeUnplugLevel = 0;
         mDischargeCurrentLevel = 0;
-        mLowDischargeAmountSinceCharge = 0;
-        mHighDischargeAmountSinceCharge = 0;
+        initDischarge();
     }
 
     public BatteryStatsImpl(Parcel p) {
@@ -3968,6 +3983,15 @@
         mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
         mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
     }
+
+    void initDischarge() {
+        mLowDischargeAmountSinceCharge = 0;
+        mHighDischargeAmountSinceCharge = 0;
+        mDischargeAmountScreenOn = 0;
+        mDischargeAmountScreenOnSinceCharge = 0;
+        mDischargeAmountScreenOff = 0;
+        mDischargeAmountScreenOffSinceCharge = 0;
+    }
     
     public void resetAllStatsLocked() {
         mStartCount = 0;
@@ -4005,11 +4029,33 @@
             mKernelWakelockStats.clear();
         }
         
-        mLowDischargeAmountSinceCharge = 0;
-        mHighDischargeAmountSinceCharge = 0;
+        initDischarge();
 
         clearHistoryLocked();
     }
+
+    void updateDischargeScreenLevels(boolean oldScreenOn, boolean newScreenOn) {
+        if (oldScreenOn) {
+            int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
+            if (diff > 0) {
+                mDischargeAmountScreenOn += diff;
+                mDischargeAmountScreenOnSinceCharge += diff;
+            }
+        } else {
+            int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
+            if (diff > 0) {
+                mDischargeAmountScreenOff += diff;
+                mDischargeAmountScreenOffSinceCharge += diff;
+            }
+        }
+        if (newScreenOn) {
+            mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
+            mDischargeScreenOffUnplugLevel = 0;
+        } else {
+            mDischargeScreenOnUnplugLevel = 0;
+            mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
+        }
+    }
     
     void setOnBattery(boolean onBattery, int oldStatus, int level) {
         synchronized(this) {
@@ -4045,6 +4091,15 @@
                 mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
                 mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
                 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
+                if (mScreenOn) {
+                    mDischargeScreenOnUnplugLevel = level;
+                    mDischargeScreenOffUnplugLevel = 0;
+                } else {
+                    mDischargeScreenOnUnplugLevel = 0;
+                    mDischargeScreenOffUnplugLevel = level;
+                }
+                mDischargeAmountScreenOn = 0;
+                mDischargeAmountScreenOff = 0;
                 doUnplugLocked(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
             } else {
                 updateKernelWakelocksLocked();
@@ -4060,6 +4115,7 @@
                     mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
                     mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
                 }
+                updateDischargeScreenLevels(mScreenOn, mScreenOn);
                 doPlugLocked(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
             }
             if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
@@ -4348,6 +4404,50 @@
             return val;
         }
     }
+    
+    public int getDischargeAmountScreenOn() {
+        synchronized(this) {
+            int val = mDischargeAmountScreenOn;
+            if (mOnBattery && mScreenOn
+                    && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
+                val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
+            }
+            return val;
+        }
+    }
+
+    public int getDischargeAmountScreenOnSinceCharge() {
+        synchronized(this) {
+            int val = mDischargeAmountScreenOnSinceCharge;
+            if (mOnBattery && mScreenOn
+                    && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
+                val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
+            }
+            return val;
+        }
+    }
+
+    public int getDischargeAmountScreenOff() {
+        synchronized(this) {
+            int val = mDischargeAmountScreenOff;
+            if (mOnBattery && !mScreenOn
+                    && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
+                val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
+            }
+            return val;
+        }
+    }
+
+    public int getDischargeAmountScreenOffSinceCharge() {
+        synchronized(this) {
+            int val = mDischargeAmountScreenOffSinceCharge;
+            if (mOnBattery && !mScreenOn
+                    && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
+                val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
+            }
+            return val;
+        }
+    }
 
     @Override
     public int getCpuSpeedSteps() {
@@ -4654,7 +4754,9 @@
         mDischargeCurrentLevel = in.readInt();
         mLowDischargeAmountSinceCharge = in.readInt();
         mHighDischargeAmountSinceCharge = in.readInt();
-        
+        mDischargeAmountScreenOnSinceCharge = in.readInt();
+        mDischargeAmountScreenOffSinceCharge = in.readInt();
+
         mStartCount++;
         
         mScreenOn = false;
@@ -4849,6 +4951,8 @@
         out.writeInt(mDischargeCurrentLevel);
         out.writeInt(getLowDischargeAmountSinceCharge());
         out.writeInt(getHighDischargeAmountSinceCharge());
+        out.writeInt(getDischargeAmountScreenOnSinceCharge());
+        out.writeInt(getDischargeAmountScreenOffSinceCharge());
         
         mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
@@ -5088,6 +5192,10 @@
         mDischargeCurrentLevel = in.readInt();
         mLowDischargeAmountSinceCharge = in.readInt();
         mHighDischargeAmountSinceCharge = in.readInt();
+        mDischargeAmountScreenOn = in.readInt();
+        mDischargeAmountScreenOnSinceCharge = in.readInt();
+        mDischargeAmountScreenOff = in.readInt();
+        mDischargeAmountScreenOffSinceCharge = in.readInt();
         mLastWriteTime = in.readLong();
 
         mMobileDataRx[STATS_LAST] = in.readLong();
@@ -5189,6 +5297,10 @@
         out.writeInt(mDischargeCurrentLevel);
         out.writeInt(mLowDischargeAmountSinceCharge);
         out.writeInt(mHighDischargeAmountSinceCharge);
+        out.writeInt(mDischargeAmountScreenOn);
+        out.writeInt(mDischargeAmountScreenOnSinceCharge);
+        out.writeInt(mDischargeAmountScreenOff);
+        out.writeInt(mDischargeAmountScreenOffSinceCharge);
         out.writeLong(mLastWriteTime);
 
         out.writeLong(getMobileTcpBytesReceived(STATS_SINCE_UNPLUGGED));
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index a130bf5..e3323b3 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -339,7 +339,7 @@
         android:description="@string/permdesc_bluetooth"
         android:label="@string/permlab_bluetooth" />
 
-    <!-- Allows applications to directly communicate over NFC -->
+    <!-- Allows applications to perform I/O operations over NFC -->
     <permission android:name="android.permission.NFC"
         android:permissionGroup="android.permission-group.NETWORK"
         android:protectionLevel="dangerous"
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 48c73cc..b15764c 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -270,7 +270,7 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"機密ログデータの読み取り"</string>
     <string name="permdesc_readLogs" msgid="8896449437464867766">"システムの各種ログファイルの読み取りをアプリケーションに許可します。許可すると端末の使用状況に関する全般的な情報が読み取られます。この情報には個人情報や機密情報が含まれる場合があります。"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"diagが所有するリソースの読み書き"</string>
-    <string name="permdesc_diagnostic" msgid="3121238373951637049">"diagグループが所有するリソース（例:/dev内のファイル）への読み書きをアプリケーションに許可します。システムの安定性とセキュリティに影響する恐れがあります。メーカー/オペレーターによるハードウェア固有の診断以外には使用しないでください。"</string>
+    <string name="permdesc_diagnostic" msgid="3121238373951637049">"diagグループが所有するリソース（例:/dev内のファイル）への読み書きをアプリケーションに許可します。システムの安定性とセキュリティに影響する恐れがあります。メーカー/通信事業者によるハードウェア固有の診断以外には使用しないでください。"</string>
     <string name="permlab_changeComponentState" msgid="79425198834329406">"アプリケーションのコンポーネントを有効/無効にする"</string>
     <string name="permdesc_changeComponentState" msgid="4569107043246700630">"別アプリケーションのコンポーネントの有効/無効を変更することをアプリケーションに許可します。これにより悪意のあるアプリケーションが、携帯電話の重要な機能を無効にする恐れがあります。アプリケーションコンポーネントが利用できない、整合性が取れない、または不安定な状態になる恐れがあるので、許可には注意が必要です。"</string>
     <string name="permlab_setPreferredApplications" msgid="3393305202145172005">"優先アプリケーションの設定"</string>
@@ -352,13 +352,13 @@
     <string name="permlab_bindGadget" msgid="776905339015863471">"ウィジェットの選択"</string>
     <string name="permdesc_bindGadget" msgid="2098697834497452046">"どのアプリケーションがどのウィジェットを使用できるかシステムに指定することをこのアプリケーションに許可します。これにより、アプリケーション間で個人データにアクセスできるようになります。通常のアプリケーションでは使用しません。"</string>
     <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"端末ステータスの変更"</string>
-    <string name="permdesc_modifyPhoneState" msgid="3302284561346956587">"端末の電話機能のコントロールをアプリケーションに許可します。アプリケーションは、ネットワークの切り替え、携帯電話の無線通信のオン/オフなどを通知せずに行うことができます。"</string>
+    <string name="permdesc_modifyPhoneState" msgid="3302284561346956587">"端末の電話機能のコントロールをアプリケーションに許可します。アプリケーションは、ネットワークの切り替え、携帯電話の無線通信のON/OFFなどを通知せずに行うことができます。"</string>
     <string name="permlab_readPhoneState" msgid="2326172951448691631">"携帯のステータスとIDの読み取り"</string>
     <string name="permdesc_readPhoneState" msgid="188877305147626781">"端末の電話機能へのアクセスをアプリケーションに許可します。この権限が許可されたアプリケーションでは、この携帯の電話番号やシリアル番号、通話中かどうか、通話相手の電話番号などを特定できます。"</string>
     <string name="permlab_wakeLock" msgid="573480187941496130">"端末のスリープを無効にする"</string>
     <string name="permdesc_wakeLock" msgid="7584036471227467099">"端末のスリープを無効にすることをアプリケーションに許可します。"</string>
     <string name="permlab_devicePower" msgid="4928622470980943206">"電源のON/OFF"</string>
-    <string name="permdesc_devicePower" msgid="4577331933252444818">"携帯電話の電源のオン/オフをアプリケーションに許可します。"</string>
+    <string name="permdesc_devicePower" msgid="4577331933252444818">"携帯電話の電源のON/OFFをアプリケーションに許可します。"</string>
     <string name="permlab_factoryTest" msgid="3715225492696416187">"出荷時試験モードでの実行"</string>
     <string name="permdesc_factoryTest" msgid="8136644990319244802">"携帯電話のハードウェアへのアクセスを完全に許可して、低レベルのメーカーテストとして実行します。メーカーのテストモードで携帯電話を使用するときのみ利用できます。"</string>
     <string name="permlab_setWallpaper" msgid="6627192333373465143">"壁紙の設定"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 179dabe..dbb76ff 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -177,7 +177,7 @@
     <string name="permdesc_statusBarService" msgid="4097605867643520920">"애플리케이션이 상태 표시줄이 되도록 허용합니다."</string>
     <string name="permlab_expandStatusBar" msgid="1148198785937489264">"상태 표시줄 확장/축소"</string>
     <string name="permdesc_expandStatusBar" msgid="7088604400110768665">"애플리케이션이 상태 표시줄을 확장하거나 축소할 수 있도록 합니다."</string>
-    <string name="permlab_processOutgoingCalls" msgid="1136262550878335980">"발신전화 가로채기"</string>
+    <string name="permlab_processOutgoingCalls" msgid="1136262550878335980">"발신전화 차단"</string>
     <string name="permdesc_processOutgoingCalls" msgid="2228988201852654461">"애플리케이션이 발신전화를 처리하고 전화를 걸 번호를 변경할 수 있도록 합니다. 이 경우 악성 애플리케이션이 발신전화를 모니터링하거나, 다른 방향으로 돌리거나, 중단시킬 수 있습니다."</string>
     <string name="permlab_receiveSms" msgid="2697628268086208535">"SMS 수신"</string>
     <string name="permdesc_receiveSms" msgid="6298292335965966117">"애플리케이션이 SMS 메시지를 받고 처리할 수 있도록 합니다. 이 경우 악성 애플리케이션이 메시지를 모니터링하거나 사용자가 보기 전에 삭제할 수 있습니다."</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index de72e8c..0968c04 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -50,7 +50,7 @@
     <string name="needPuk2" msgid="4526033371987193070">"Wprowadź kod PUK2, aby odblokować kartę SIM."</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Identyfikator rozmówcy przy połączeniach przychodzących"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Identyfikator rozmówcy przy połączeniach wychodzących"</string>
-    <string name="CfMmi" msgid="5123218989141573515">"Przekierowania połączeń"</string>
+    <string name="CfMmi" msgid="5123218989141573515">"Przekazywanie połączeń"</string>
     <string name="CwMmi" msgid="9129678056795016867">"Połączenia oczekujące"</string>
     <string name="BaMmi" msgid="455193067926770581">"Blokada dzwonienia"</string>
     <string name="PwdMmi" msgid="7043715687905254199">"Zmiana hasła"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index dc095c5..3568292 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -547,7 +547,7 @@
     <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Экран заблокирован."</string>
     <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Нажмите \"Меню\", чтобы разблокировать экран или вызвать службу экстренной помощи."</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Для разблокировки нажмите \"Меню\"."</string>
-    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Для разблокировки введите графический ключ"</string>
+    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Введите графический ключ"</string>
     <string name="lockscreen_emergency_call" msgid="5347633784401285225">"Экстренный вызов"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Вернуться к вызову"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Правильно!"</string>
@@ -874,17 +874,17 @@
     <string name="sync_binding_label" msgid="3687969138375092423">"Синхр."</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Спец. возможности"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Фоновый рисунок"</string>
-    <string name="chooser_wallpaper" msgid="7873476199295190279">"Изменить фоновый рисунок"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Сменить обои"</string>
     <string name="pptp_vpn_description" msgid="2688045385181439401">"Протокол PPTP"</string>
     <string name="l2tp_vpn_description" msgid="3750692169378923304">"Протокол L2TP"</string>
-    <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"L2TP/IPSec VPN (на основе предв. общ. ключа)"</string>
-    <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"L2TP/IPSec VPN (на основе сертификата)"</string>
+    <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"L2TP/IPSec VPN с использованием общего ключа"</string>
+    <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"L2TP/IPSec VPN с использованием сертификатов"</string>
     <string name="upload_file" msgid="2897957172366730416">"Выбрать файл"</string>
     <string name="reset" msgid="2448168080964209908">"Сбросить"</string>
     <string name="submit" msgid="1602335572089911941">"Отправить"</string>
     <string name="description_star" msgid="2654319874908576133">"избранное"</string>
-    <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Режим громкой связи включен"</string>
-    <string name="car_mode_disable_notification_message" msgid="668663626721675614">"Выберите для выхода из режима громкой связи."</string>
+    <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Включен режим \"Штурман\""</string>
+    <string name="car_mode_disable_notification_message" msgid="668663626721675614">"Чтобы закрыть приложение, нажмите здесь."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"USB-модем или точка доступа Wi-Fi активны"</string>
     <string name="tethered_notification_message" msgid="3067108323903048927">"Нажмите для настройки"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Активная передача данных"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 78fe64b..da8e69e 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -191,11 +191,11 @@
     <string name="permdesc_writeSms" msgid="6299398896177548095">"Tillåter att program skriver till SMS-meddelanden som lagrats på din telefon eller SIM-kort. Skadliga program kan radera dina meddelanden."</string>
     <string name="permlab_receiveWapPush" msgid="8258226427716551388">"ta emot WAP"</string>
     <string name="permdesc_receiveWapPush" msgid="5979623826128082171">"Tillåter att program tar emot och bearbetar WAP-meddelanden. Skadliga program kan övervaka dina meddelanden eller ta bort dem utan att visa dem för dig."</string>
-    <string name="permlab_getTasks" msgid="5005277531132573353">"hämta program som körs"</string>
+    <string name="permlab_getTasks" msgid="5005277531132573353">"hämta appar som körs"</string>
     <string name="permdesc_getTasks" msgid="7048711358713443341">"Tillåter att program hämtar information om uppgifter som körs och har körts. Skadliga program kan upptäcka privat information om andra program."</string>
     <string name="permlab_reorderTasks" msgid="5669588525059921549">"byt ordning på program som körs"</string>
     <string name="permdesc_reorderTasks" msgid="126252774270522835">"Tillåter att ett program flyttar uppgifter till förgrunden eller bakgrunden. Skadliga program kan tvinga sig till förgrunden utan att du kan styra det."</string>
-    <string name="permlab_setDebugApp" msgid="4339730312925176742">"aktivera felsökning av program"</string>
+    <string name="permlab_setDebugApp" msgid="4339730312925176742">"aktivera felsökning av appar"</string>
     <string name="permdesc_setDebugApp" msgid="5584310661711990702">"Tillåter att ett program aktiverar felsökning för ett annat program. Skadliga program kan använda detta för att avsluta andra program."</string>
     <string name="permlab_changeConfiguration" msgid="8214475779521218295">"ändra dina gränssnittsinställningar"</string>
     <string name="permdesc_changeConfiguration" msgid="3465121501528064399">"Tillåter att ett program ändrar den aktuella konfigurationen, till exempel språk eller övergripande teckenformat."</string>
@@ -249,11 +249,11 @@
     <string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Tillåter att innehavaren skickar avsikter till en enhetsadministratör. Vanliga program behöver aldrig göra detta."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"ändra bildskärmens rikting"</string>
     <string name="permdesc_setOrientation" msgid="6335814461615851863">"Tillåter att ett program när som helst ändrar skärmens rotering. Behövs inte för vanliga program."</string>
-    <string name="permlab_signalPersistentProcesses" msgid="4255467255488653854">"skicka Linux-signaler till program"</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4255467255488653854">"skicka Linux-signaler till appar"</string>
     <string name="permdesc_signalPersistentProcesses" msgid="3565530463215015289">"Tillåter att programmet begär att den angivna signalen skickas till alla beständiga processer."</string>
     <string name="permlab_persistentActivity" msgid="8659652042401085862">"se till att programmet alltid körs"</string>
     <string name="permdesc_persistentActivity" msgid="5037199778265006008">"Tillåter att ett program gör vissa delar beständiga så att systemet inte kan använda det för andra program."</string>
-    <string name="permlab_deletePackages" msgid="3343439331576348805">"ta bort program"</string>
+    <string name="permlab_deletePackages" msgid="3343439331576348805">"ta bort appar"</string>
     <string name="permdesc_deletePackages" msgid="3634943677518723314">"Tillåter att ett program tar bort Android-paket. Skadliga program kan använda detta för att ta bort viktiga program."</string>
     <string name="permlab_clearAppUserData" msgid="2192134353540277878">"ta bort de andra programmens uppgifter"</string>
     <string name="permdesc_clearAppUserData" msgid="7546345080434325456">"Tillåter att ett program tar bort användardata."</string>
@@ -263,7 +263,7 @@
     <string name="permdesc_getPackageSize" msgid="5557253039670753437">"Tillåter att ett program hämtar kod, data och cachestorlekar"</string>
     <string name="permlab_installPackages" msgid="335800214119051089">"installera program direkt"</string>
     <string name="permdesc_installPackages" msgid="526669220850066132">"Tillåter att ett program installerar nya eller uppdaterade Android-paket. Skadliga program kan använda detta för att lägga till nya program med godtyckliga och starka behörigheter."</string>
-    <string name="permlab_clearAppCache" msgid="4747698311163766540">"ta bort cacheinformation för alla program"</string>
+    <string name="permlab_clearAppCache" msgid="4747698311163766540">"ta bort cacheinformation för alla appar"</string>
     <string name="permdesc_clearAppCache" msgid="7740465694193671402">"Tillåter att ett program frigör lagringsutrymme i telefonen genom att ta bort filer i programmets katalog för cachelagring. Åtkomst är mycket begränsad, vanligtvis till systemprocesser."</string>
     <string name="permlab_movePackage" msgid="728454979946503926">"Flytta programresurser"</string>
     <string name="permdesc_movePackage" msgid="6323049291923925277">"Tillåter att ett program flyttar programresurser från interna till externa medier och tvärt om."</string>
@@ -782,7 +782,7 @@
     <item quantity="other" msgid="7915895323644292768">"Öppna Wi-Fi-nätverk är tillgängliga"</item>
   </plurals>
     <string name="select_character" msgid="3365550120617701745">"Infoga tecken"</string>
-    <string name="sms_control_default_app_name" msgid="7630529934366549163">"Okänt program"</string>
+    <string name="sms_control_default_app_name" msgid="7630529934366549163">"Okänd app"</string>
     <string name="sms_control_title" msgid="7296612781128917719">"Skickar SMS"</string>
     <string name="sms_control_message" msgid="1289331457999236205">"Flera SMS-meddelanden skickas. Tryck på OK om du vill fortsätta eller på Avbryt om du vill avsluta sändningen."</string>
     <string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 9762d77..09e2820 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -377,4 +377,7 @@
     <!-- Do not translate. Defines the slots is Two Digit Number for dialing normally not USSD -->
     <string-array name="config_twoDigitNumberPattern">
     </string-array>
+
+    <!-- The VoiceMail default value is displayed to my own number if it is true -->
+    <bool name="config_telephony_use_own_number_for_voicemail">false</bool>
 </resources>
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 492b3a3..24970d8 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -243,6 +243,9 @@
       <li><a href="<?cs var:toroot?>guide/topics/wireless/bluetooth.html">
             <span class="en">Bluetooth</span>
           </a></li>
+      <li><a href="<?cs var:toroot?>guide/topics/nfc/index.html">
+            <span class="en">Near Field Communication</span></a>
+            <span class="new">new!</span></li>
        <li><a href="<?cs var:toroot?>guide/topics/network/sip.html">
             <span class="en">Session Initiation Protocol</span></a>
             <span class="new">new!</span>
diff --git a/docs/html/guide/topics/nfc/index.jd b/docs/html/guide/topics/nfc/index.jd
new file mode 100644
index 0000000..c4917b4
--- /dev/null
+++ b/docs/html/guide/topics/nfc/index.jd
@@ -0,0 +1,613 @@
+page.title=Near Field Communication
+@jd:body
+
+  <div id="qv-wrapper">
+    <div id="qv">
+      <h2>Near Field Communication quickview</h2>
+
+      <ol>
+        <li><a href="#api">API Overview</a></li>
+
+        <li><a href="#manifest">Declaring Android Manifest Elements</a></li>
+
+        <li>
+          <a href="#dispatch">The Tag Dispatch System</a>
+
+          <ol>
+            <li><a href="#foreground-dispatch">Using the foreground dispatch system</a></li>
+
+            <li><a href="#intent-dispatch">Using the intent dispatch system</a></li>
+          </ol>
+        </li>
+
+        <li><a href="#ndef">NDEF messages</a></li>
+
+        <li><a href="#read">Reading an NFC tag</a></li>
+
+        <li><a href="#write">Writing to an NFC tag</a></li>
+
+        <li><a href="#p2p">Peer to Peer Data Exchange</a></li>
+      </ol>
+    </div>
+  </div>
+
+  <p>Near Field Communication (NFC) is a set of short-range wireless technologies, typically
+  requiring a distance of 4cm or less. NFC operates at 13.56mhz, and at rates ranging
+  from 106 kbit/s to 848 kbit/s. NFC communication always involves an initiator and a target.
+  The initiator actively generates an RF field that can power a passive target. This
+  enables NFC targets to take very simple form factors such as tags, stickers or cards that do
+  not require power. NFC peer-to-peer communication is also possible, where both devices
+  are powered.
+  <p>
+  Compared to other wireless technologies such as Bluetooth or WiFi, NFC provides much lower
+  bandwidth and range, but enables low-cost, un-powered targets
+  and does not require discovery or pairing. Interactions can be initiated with just a tap.
+  <p>
+  An Android device with NFC hardware will typically act as an initiator when the screen is
+  on. This mode is also known as NFC reader/writer. It will actively look for NFC tags and start
+  activities to handle them. Android 2.3.3 also has some limited P2P support.
+  <p>
+  Tags can range in complexity, simple tags just offer read/write semantics, sometimes
+  with one-time-programmable areas to make the card read-only. More complex tags offer
+  math operations, and have cryptographic hardware to authenticate access to a sector.
+  The most sophisticated tags contain operating environments, allowing
+  complex interactions with code executing on the tag.
+
+  <h2 id="api">API Overview</h2>
+
+  <p>The {@link android.nfc} package contains the high-level classes to interact
+  with the local device's NFC adapter, to represent discovered tags, and to use
+  the NDEF data format.
+
+  <table>
+    <tr>
+      <th>Class</th>
+
+      <th>Description</th>
+    </tr>
+
+    <tr>
+      <td>{@link android.nfc.NfcManager}</td>
+
+
+      <td>A high level manager class that enumerates the NFC adapters on this Android device.
+      Since most Android devices only have one NFC adapter, you can just use the static helper
+      {@link android.nfc.NfcAdapter#getDefaultAdapter(Context)} for most situations.</td>
+    </tr>
+
+    <tr>
+      <td>{@link android.nfc.NfcAdapter}</td>
+
+      <td>Represents the local NFC adapter. Defines the intent's used to request
+      tag dispatch to your activity, and provides methods to register for foreground
+      tag dispatch and foreground NDEF push. Foreground NDEF push is the only
+      peer-to-peer support that is currently provided in Android.</td>
+    </tr>
+
+    <tr>
+      <td>{@link android.nfc.NdefMessage} and {@link android.nfc.NdefRecord}</td>
+
+      <td>NDEF is an NFC Forum defined data structure, designed to efficiently
+      store data on NFC tags, such as text, URL's, and other MIME types. A
+      {@link android.nfc.NdefMessage} acts as a
+      container for the data that you want to transmit or read. One {@link android.nfc.NdefMessage}
+      object contains zero or more {@link android.nfc.NdefRecord}s. Each NDEF record
+      has a type such as text, URL, smart poster, or any MIME data. The type of the
+      first NDEF record in the NDEF message is used to dispatch a tag to an activity
+      on Android.</td>
+    </tr>
+
+    <tr>
+      <td>{@link android.nfc.Tag}</td>
+
+      <td>Represents a passive NFC target. These can come in many form factors such as
+      a tag, card, key fob, or even a phone doing card emulation. When a tag is
+      discovered, a {@link android.nfc.Tag} object is created and wrapped inside an
+      Intent. The NFC dispatch system sends the intent to a compatible actvitiy
+      using <code>startActivity()</code>. You can use the {@link
+      android.nfc.Tag#getTechList getTechList()} method to determine the technologies supported by
+      this tag and create the corresponding {@link android.nfc.tech.TagTechnology} object with one
+      of classes provided by {@link android.nfc.tech}.</td>
+    </tr>
+  </table>
+
+  <p>The {@link android.nfc.tech} package contains classes to query properties
+  and perform I/O operations on a tag. The classes are divided to represent different
+  NFC technologies that can be available on a tag.
+
+  <p>The {@link android.nfc.tech} package contains classes to query properties and perform I/O
+  operations on a tag. The classes are divided to represent different NFC technologies that can be
+  available on a Tag:</p>
+
+  <table>
+    <tr>
+      <th>Class</th>
+
+      <th>Description</th>
+    </tr>
+
+    <tr>
+      <td>{@link android.nfc.tech.TagTechnology}</td>
+
+      <td>The interface that all tag technology classes must implement.</td>
+    </tr>
+
+    <tr>
+      <td>{@link android.nfc.tech.NfcA}</td>
+
+      <td>Provides access to NFC-A (ISO 14443-3A) properties and I/O operations.</td>
+    </tr>
+
+    <tr>
+      <td>{@link android.nfc.tech.NfcB}</td>
+
+      <td>Provides access to NFC-B (ISO 14443-3B) properties and I/O operations.</td>
+    </tr>
+
+    <tr>
+      <td>{@link android.nfc.tech.NfcF}</td>
+
+      <td>Provides access to NFC-F (JIS 6319-4) properties and I/O operations.</td>
+    </tr>
+
+    <tr>
+      <td>{@link android.nfc.tech.NfcV}</td>
+
+      <td>Provides access to NFC-V (ISO 15693) properties and I/O operations.</td>
+    </tr>
+
+    <tr>
+      <td>{@link android.nfc.tech.IsoDep}</td>
+
+      <td>Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations.</td>
+    </tr>
+
+    <tr>
+      <td>{@link android.nfc.tech.Ndef}</td>
+
+      <td>Provides access to NDEF data and operations on NFC tags that have been formatted as NDEF.
+      </td>
+    </tr>
+
+    <tr>
+      <td>{@link android.nfc.tech.NdefFormatable}</td>
+
+      <td>Provides a format operations for tags that may be NDEF formatable.</td>
+    </tr>
+
+    <tr>
+      <td>{@link android.nfc.tech.MifareClassic}</td>
+
+      <td>Provides access to MIFARE Classic properties and I/O operations, if this
+      Android device supports MIFARE.</td>
+    </tr>
+
+    <tr>
+      <td>{@link android.nfc.tech.MifareUltralight}</td>
+
+      <td>Provides access to MIFARE Ultralight properties and I/O operations, if this
+      Android device supports MIFARE.</td>
+    </tr>
+  </table>
+
+  <h2 id="manifest">Declaring Android Manifest elements</h2>
+
+  <p>Before you can access a device's NFC hardware and properly handle NFC intents, declare these
+  items in your <code>AndroidManifest.xml</code> file:</p>
+
+  <ol>
+    <li>The NFC <code>&lt;uses-permission&gt;</code> element to access the NFC hardware:
+      <pre>
+&lt;uses-permission android:name="android.permission.NFC" /&gt;
+</pre>
+    </li>
+
+    <li>The minimum SDK version that your application can support. API level 9 only supports
+    limited tag dispatch via {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED},
+    and only gives access to NDEF messages via the {@link android.nfc.NfcAdapter#EXTRA_NDEF_MESSAGES}
+    extra. No other tag properties or I/O operations are accessible. You probably want
+    to use API level 10 which includes comprehensive reader/writer support.
+
+<pre class="pretty-print">
+&lt;uses-sdk android:minSdkVersion="10"/&gt;
+</pre>
+    </li>
+
+    <li>The uses-feature element so that your application can show up in the Android Market for
+    devices that have NFC hardware:
+      <pre>
+&lt;uses-feature android:name="android.hardware.nfc" android:required="true" /&gt;
+</pre>
+    </li>
+
+    <li>The NFC intent filter to tell the Android system your Activity can handle NFC data. Specify
+    one or more of these three intent filters:
+      <pre>
+&lt;intent-filter&gt;
+  &lt;action android:name="android.nfc.action.NDEF_DISCOVERED"/&gt;
+  &lt;data android:mimeType="<em>mime/type</em>" /&gt;
+&lt;/intent-filter&gt;
+
+&lt;intent-filter&gt;
+  &lt;action android:name="android.nfc.action.TECH_DISCOVERED"/&gt;
+  &lt;meta-data android:name="android.nfc.action.TECH_DISCOVERED"
+                android:resource="@xml/<em>nfc_tech_filter</em>.xml" /&gt;
+&lt;/intent-filter&gt;
+
+&lt;intent-filter&gt;
+  &lt;action android:name="android.nfc.action.TAG_DISCOVERED"/&gt;
+&lt;/intent-filter&gt;
+</pre>
+
+      <p>The three intent filters are prioritized and behave in specific ways. Declare only the
+      ones that your Activity needs to handle. For more information on how to handle these filters,
+      see the section about <a href="#dispatch">The Tag Dispatch System</a>.</p>
+    </li>
+  </ol>
+
+  <p>View the <a href=
+  "../../../resources/samples/NFCDemo/AndroidManifest.html">AndroidManifest.xml</a> from the
+  NFCDemo sample to see a complete example.</p>
+
+  <h2 id="dispatch">The Tag Dispatch System</h2>
+
+  <p>When an Android device scans an NFC tag, the desired behavior is to have the most appropriate
+  Activity handle the intent without asking the user what appplication to use. Because devices scan
+  NFC tags at a very short range, it is likely that making users manually select an Activity forces
+  them to move the device away from the tag and break the connection. You should develop your
+  Activity to only handle the NFC tags that your Activity cares about to prevent the Activity
+  Chooser from appearing. Android provides two systems to help you correctly identify an NFC tag
+  that your Activity should handle: the Intent dispatch system and the foreground Activity dispatch
+  system.</p>
+
+  <p>The intent dispatch system checks the intent filters of all the Activities along with the
+  types of data that the Activities support to find the best Activity that can handle the NFC tag.
+  If multiple Activities specify the same intent filter and data to handle, then the Activity
+  Chooser is presented to the user as a last resort.</p>
+
+  <p>The foreground dispatch system allows an Activity application to override the intent dispatch
+  system and have priority when an NFC tag is scanned. The Activity handling the request must be
+  running in the foreground of the device. When an NFC tag is scanned and matches the intent and
+  data type that the foreground dispatch Activity defines, the intent is immediately sent to the
+  Activity even if another Activity can handle the intent. If the Activity cannot handle the
+  intent, the foreground dispatch system falls back to the intent dispatch system.</p>
+
+  <h3 id="intent-dispatch">Using the intent dispatch system</h3>
+
+  <p>The intent dispatch system specifies three intents that each have a priority. The intents that
+  start when a device scans a tag depend on the type of tag scanned. In general, the intents are
+  started in the following manner:</p>
+
+  <ul>
+    <li>
+      <code>android.nfc.action.NDEF_DISCOVERED</code>: This intent starts when a tag that contains
+      an NDEF payload is scanned. This is the highest priority intent. The Android system does not
+      let you specify this intent generically to handle all data types. You must specify
+      <code>&lt;data&gt;</code> elements in the <code>AndroidManifest.xml</code> along with this
+      intent to correctly handle NFC tags that start this intent. For example, to handle a
+      <code>NDEF_DISCOVERED</code> intent that contains plain text, specify the following filter in
+      your <code>AndroidManifest.xml</code> file:
+      <pre>
+&lt;intent-filter&gt;
+    &lt;action android:name="android.nfc.action.NDEF_DISCOVERED"/&gt;
+    &lt;data android:mimeType="text/plain" /&gt;
+&lt;/intent-filter&gt;
+</pre>
+
+      <p>If the <code>NDEF_DISCOVERED</code> intent is started, the <code>TECH_DISCOVERED</code>
+      and <code>TAG_DISCOVERED</code> intents are not started. This intent does not start if an
+      unknown tag is scanned or if the tag does not contain an NDEF payload.</p>
+    </li>
+
+    <li><code>android.nfc.action.TECH_DISCOVERED</code>: If the <code>NDEF_DISCOVERED</code> intent
+    does not start or is not filtered by any Activity on the device, this intent starts if the tag
+    is known. The <code>TECH_DISCOVERED</code> intent requires that you specify the technologies
+    that you want to support in an XML resource file. For more information, see the section about
+    <a href="#technology-resources">Specifying tag technologies to handle</a>.</li>
+
+    <li><code>android.nfc.action.TAG_DISCOVERED</code>: This intent starts if no Activities handle
+    the <code>NDEF_DISCOVERED</code> and <code>TECH_DISCOVERED</code> intents or if the tag that is
+    scanned is unknown.</li>
+  </ul>
+
+  <h4 id="tech">Specifying tag technologies to handle</h4>
+
+  <p>If your Activity declares the <code>android.nfc.action.TECH_DISCOVERED</code> intent in your
+  <code>AndroidManifest.xml</code> file, you must create an XML resource file that specifies the
+  technologies that your Activity supports. The following sample defines all of the technologies.
+  Specifiying multiple technologies within the same list tells the system
+  to filter tags that support all of the technologies. The example below never filters a tag
+  because no tag supports all of the technologies at once.
+  You can remove the ones that you do not need. Save this file (you can name it anything you wish)
+  in the <code>&lt;project-root&gt;/res/xml</code> folder.</p>
+  <pre>
+&lt;resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"&gt;
+    &lt;tech-list&gt;
+        &lt;tech&gt;android.nfc.tech.IsoDep&lt;/tech&gt;
+        &lt;tech&gt;android.nfc.tech.NfcA&lt;/tech&gt;        
+        &lt;tech&gt;android.nfc.tech.NfcB&lt;/tech&gt;
+        &lt;tech&gt;android.nfc.tech.NfcF&lt;/tech&gt;
+        &lt;tech&gt;android.nfc.tech.NfcV&lt;/tech&gt;
+        &lt;tech&gt;android.nfc.tech.Ndef&lt;/tech&gt;
+        &lt;tech&gt;android.nfc.tech.NdefFormatable&lt;/tech&gt;
+        &lt;tech&gt;android.nfc.tech.MifareClassic&lt;/tech&gt;
+        &lt;tech&gt;android.nfc.tech.MifareUltralight&lt;/tech&gt;
+    &lt;/tech-list&gt;
+&lt;/resources&gt;
+</pre>
+
+You can also specify multiple filter lists. In this case, a tag must match all of the
+technologies within one of the lists. The following example filters for
+cards that support the NfcA and Ndef technology or support the
+NfcB and Ndef technology.
+
+<pre>
+&lt;resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"&gt;
+    &lt;tech-list&gt;
+        &lt;tech&gt;android.nfc.tech.NfcA&lt;/tech&gt;        
+        &lt;tech&gt;android.nfc.tech.Ndef&lt;/tech&gt;
+    &lt;/tech-list&gt;
+&lt;/resources&gt;
+
+&lt;resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"&gt;
+    &lt;tech-list&gt;
+        &lt;tech&gt;android.nfc.tech.NfcB&lt;/tech&gt;        
+        &lt;tech&gt;android.nfc.tech.Ndef&lt;/tech&gt;
+    &lt;/tech-list&gt;
+&lt;/resources&gt;
+</pre>
+
+  <p>In your <code>AndroidManifest.xml</code> file, specify the resource file that you just created
+  in the <code>&lt;meta-data&gt;</code> element inside the <code>&lt;intent-filter&gt;</code>
+  element like in the following example:</p>
+  <pre>
+&lt;intent-filter&gt;
+    &lt;action android:name="android.nfc.action.TECH_DISCOVERED"/&gt;
+    &lt;meta-data android:name="android.nfc.action.TECH_DISCOVERED"
+        android:resource="@xml/nfc_tech_filter.xml" /&gt;
+&lt;/intent-filter&gt;
+</pre>
+
+  <h3 id="foreground-dispatch">Using the foreground dispatch system</h3>
+
+  <p>The foreground dispatch system allows an Activity to intercept an intent and claim priority
+  over other Activities that handle the same intent. The system is easy to use and involves
+  constructing a few data structures for the Android system to be able to send the appropriate
+  intents to your application. To enable the foreground dispatch system:</p>
+
+  <ol>
+    <li>Add the following code in the onCreate() method of your Activity:
+
+      <ol type="a">
+        <li>Create a {@link android.app.PendingIntent} object so the Android system can populate it
+        with the details of the tag when it is scanned
+          <pre>
+PendingIntent pendingIntent = PendingIntent.getActivity(
+    this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
+</pre>
+        </li>
+
+        <li>Declare intent filters to handle the intents that you want to intercept. The foreground
+        dispatch system checks the specified intent filters with the intent that is received when
+        the device scans a tag. If they match, then your application handles the intent. If it does
+        not match, the foreground dispatch system falls back to the intent dispatch system.
+        Specifying a <code>null</code> array of intent filters and for the technology filters,
+        you receive a <code>TAG_DISCOVERED</code> intent for all tags discovered. Note that the
+        snippet below handles all MIME types. You should only handle the ones that you need.
+          <pre>
+    IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
+        try {
+            ndef.addDataType("*/*");    /* Handles all MIME based dispatches. 
+                                           You should specify only the ones that you need. */
+        }
+        catch (MalformedMimeTypeException e) {
+            throw new RuntimeException("fail", e);
+        }
+        intentFiltersArray = new IntentFilter[] {
+                ndef,
+        };
+</pre>
+        </li>
+
+        <li>Set up an array of tag technologies that your application wants to handle. Call the
+        <code>Object.class.getName()</code> method to obtain the class of the technology that you
+        want to support.
+          <pre>
+
+  techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
+  
+</pre>
+        </li>
+      </ol>
+    </li>
+
+    <li>Override the following Activity lifecycle callbacks and add logic to enable and disable the
+    foreground dispatch when the Activity loses ({@link android.app.Activity#onPause onPause()})
+    and regains ({@link android.app.Activity#onResume onResume()}) focus. {@link
+    android.nfc.NfcAdapter#enableForegroundDispatch} must best called from the main thread and only
+    when the activity is in the foreground (calling in {@link android.app.Activity#onResume
+    onResume()} guarantees this). You also need to implement the {@link
+    android.app.Activity#onNewIntent onNewIntent} callback to process the data from the scanned NFC
+    tag.
+      <pre>
+public void onPause() {
+    super.onPause();
+    mAdapter.disableForegroundDispatch(this);
+}   
+
+public void onResume() {
+    super.onResume();
+    mAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray);
+}
+
+public void onNewIntent(Intent intent) {
+    Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
+    //do something with tagFromIntent
+}
+</pre>
+    </li>
+  </ol>
+
+  <p>See the <a href=
+  "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundDispatch.html">ForegroundDispatch</a>
+  sample from API Demos for the complete sample.</p>
+
+  <h2 id="ndef">Working with Data on NFC tags</h2>
+
+  <p>Data on NFC tags are encoded in raw bytes, so you must convert the bytes to something human
+  readable if you are presenting the data to the user. When writing to NFC tags, you must write
+  them in bytes as well. Android provides APIs to help write messages that conform to the NDEF
+  standard, which was developed by the <a href="http://www.nfc-forum.org/specs/">NFC Forum</a> to
+  standardized data on tags. Using this standard ensures that your data will be supported by all
+  Android NFC devices if you are writing to tags. However, many tag technologies use their own
+  standard for storing data and are supported by Android as well, but you have to implement your
+  own protocol stack to read and write to these tags. You can find a full list of the supported
+  technologies in {@link android.nfc.tech} and an overview of the technolgies in the {@link
+  android.nfc.tech.TagTechnology} interface. This section is a brief overview of how to work with
+  NDEF messages in the context of the Android system. It is not meant to be a complete discussion
+  of the NDEF specification, but highlights the main things that you need to be aware of when
+  working with NDEF messages in Android.</p>
+
+  <p>To facilitate working with NDEF messages, Android provides the {@link android.nfc.NdefRecord}
+  and {@link android.nfc.NdefMessage} to encapsulate the raw bytes that represent NDEF messages. An
+  {@link android.nfc.NdefMessage} is the container for zero or more {@link
+  android.nfc.NdefRecord}s. Each {@link android.nfc.NdefRecord} has its own unique type name
+  format, record type, and ID to distinguish them from other records within the same {@link
+  android.nfc.NdefMessage}. You can store different types of records of varying length in a single
+  {@link android.nfc.NdefMessage}. The size constraint of the NFC tag determines how big your
+  {@link android.nfc.NdefMessage} can be.</p>
+
+  <p>Tags that support the {@link android.nfc.tech.Ndef} and {@link android.nfc.tech.NdefFormatable}
+  technologies return and accept {@link android.nfc.NdefMessage}
+  objects as parameters for read and write operations. You need to create your own logic to read
+  and write bytes for other tag technologies in {@link android.nfc.tech}.</p>
+
+  <p>You can download technical specifications for different types of NDEF message standards, such
+  as plain text and Smart Posters, at the <a href="http://www.nfc-forum.org/specs/">NFC Forum</a>
+  website. The NFCDemo sample application also declares sample <a href=
+  "{@docRoot}resources/samples/NFCDemo/src/com/example/android/nfc/simulator/MockNdefMessages.html">
+  plain text and SmartPoster NDEF messages.</a></p>
+
+  <h2 id="read">Reading an NFC tag</h2>
+
+  <p>When a device comes in proximity to an NFC tag, the appropriate intent is started on the
+  device, notifying interested applications that a NFC tag was scanned. By previously declaring the
+  appropriate intent filter in your <code>AndroidManifest.xml</code> file or using foreground
+  dispatching, your application can request to handle the intent.</p>
+
+  <p>The following method (slightly modified from the NFCDemo sample application), handles the
+  <code>TAG_DISCOVERED</code> intent and iterates through an array obtained from the intent that
+  contains the NDEF payload:</p>
+  <pre>
+NdefMessage[] getNdefMessages(Intent intent) {
+    // Parse the intent
+    NdefMessage[] msgs = null;
+    String action = intent.getAction();
+    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
+        Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
+        if (rawMsgs != null) {
+            msgs = new NdefMessage[rawMsgs.length];
+            for (int i = 0; i &lt; rawMsgs.length; i++) {
+                msgs[i] = (NdefMessage) rawMsgs[i];
+            }
+        }
+        else {
+        // Unknown tag type
+            byte[] empty = new byte[] {};
+            NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, empty, empty);
+            NdefMessage msg = new NdefMessage(new NdefRecord[] {record});
+            msgs = new NdefMessage[] {msg};
+        }
+    }        
+    else {
+        Log.e(TAG, "Unknown intent " + intent);
+        finish();
+    }
+    return msgs;
+}
+</pre>
+
+  <p>Keep in mind that the data that the device reads is in bytes, so you must implement your own
+  logic if you need to present the data in a readable format to the user. The classes in
+  <code>com.example.android.nfc.record</code> of the NFCDemo sample show you how to parse some
+  common types of NDEF messages such as plain text or a SmartPoster.</p>
+
+  <h2 id="write">Writing to an NFC tag</h2>
+
+  <p>Writing to an NFC tag involves constructing your NDEF message in bytes and using the
+  appropriate tag technology for the tag that you are writing to. The following code sample shows
+  you how to write a simple text message to a {@link android.nfc.tech.NdefFormatable} tag:</p>
+  <pre>
+NdefFormatable tag = NdefFormatable.get(t);
+Locale locale = Locale.US;
+final byte[] langBytes = locale.getLanguage().getBytes(Charsets.US_ASCII);
+String text = "Tag, you're it!";
+final byte[] textBytes = text.getBytes(Charsets.UTF_8);
+final int utfBit = 0;
+final char status = (char) (utfBit + langBytes.length);
+final byte[] data = Bytes.concat(new byte[] {(byte) status}, langBytes, textBytes);
+NdefRecord record = NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
+try {
+    NdefRecord[] records = {text};
+    NdefMessage message = new NdefMessage(records);
+    tag.connect();
+    tag.format(message);
+}
+catch (Exception e){
+    //do error handling
+}
+</pre>
+
+  <h2 id="p2p">Peer-to-peer data exchange</h2>
+
+  <p>Support for simple peer-to-peer data exchange is supported by the foreground push feature,
+  which is enabled with the {@link android.nfc.NfcAdapter#enableForegroundNdefPush} method. To use
+  this feature:</p>
+
+  <ul>
+    <li>The Activity that is pushing the data must be in the foreground</li>
+
+    <li>You must encapsulate the data that you are sending in an {@link android.nfc.NdefMessage}
+    object</li>
+
+    <li>The NFC device that is receiving the pushed data (the scanned device) must support the
+    <code>com.android.npp</code> NDEF push protocol, which is optional for Android devices.</li>
+</li>
+  </ul>
+
+  <p class="note">If your Activity enables the foreground push feature and is in the foreground,
+  the standard intent dispatch system is disabled. However, if your Activity also enables
+  foreground dispatching, then it can still scan tags that match the intent filters set in the
+  foreground dispatching.</p>
+
+  <p>To enable foreground dispatching:</p>
+
+  <ol>
+    <li>Create an NdefMessage that contains the NdefRecords that you want to push onto the other
+    device.</li>
+
+    <li>Implement the {@link android.app.Activity#onResume onResume()} and {@link
+    android.app.Activity#onPause onPause()} callbacks in your Activity to appropriately handle the
+    foreground pushing lifecycle. You must call {@link
+    android.nfc.NfcAdapter#enableForegroundNdefPush} from the main thread and only when the
+    activity is in the foreground (calling in {@link android.app.Activity#onResume onResume()}
+    guarantees this).
+      <pre>
+public void onResume() {
+    super.onResume();
+    if (mAdapter != null)
+        mAdapter.enableForegroundNdefPush(this, myNdefMessage);
+}
+public void onPause() {
+    super.onPause();
+    if (mAdapter != null)
+        mAdapter.disableForegroundNdefPush(this);
+}
+</pre>
+    </li>
+  </ol>
+
+  <p>When the Activity is in the foreground, you can now tap the device to another device and push
+  the data to it. See the <a href=
+  "../../../resources/samples/ApiDemos/src/com/example/android/apis/nfc/ForegroundNdefPush.html">ForegroundNdefPush</a>
+  sample in API Demos for a simple example of peer-to-peer data exchange.</p>
diff --git a/docs/html/index.jd b/docs/html/index.jd
index 909dd32..0c57527 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -129,17 +129,16 @@
     'sdk': {
       'layout':"imgLeft",
       'icon':"sdk-small.png",
-      'name':"Android 2.3",
+      'name':"Android 2.3.3",
       'img':"gingerdroid.png",
-      'title':"Android 2.3 is here!",
-      'desc': "<p>Android 2.3 is now available for the Android SDK. In addition, new "
-+ "tools and documentation are available, plus a new NDK that offers more than ever. "
-+ "For more information about what's in Android 2.3, read the "
-+ "<a href='{@docRoot}sdk/android-2.3.html'>version notes</a>.</p>"
-+ "<p>If you have an existing SDK, add Android 2.3 as an "
-+ "<a href='{@docRoot}sdk/adding-components.html'>SDK "
-+ "component</a>. If you're new to Android, install the "
-+ "<a href='{@docRoot}sdk/index.html'>SDK starter package</a>."
+      'title':"Android 2.3.3, more NFC!",
+      'desc': "<p>Android 2.3.3 is now available for the Android SDK. "
++ "This update adds new NFC capabilities for developers, including advanced tag dispatching APIs "
++ "and the ability to write to tags.</p>"
++ "<p>The new APIs enable exciting new applications, such as for ticketing, "
++ "ratings, check-ins, advertising, and data exchange with other devices. "
++ "For more information about Android 2.3.3, read the "
++ "<a href='/sdk/android-2.3.3.html'>version notes</a>.</p>"
     },
 
     'tv': {
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index bfcd14e..551361f7 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -3,7 +3,7 @@
 
 sdk.win_installer=installer_r09-windows.exe
 sdk.win_installer_bytes=32828818
-sdk.win_installer_checksum=a0185701ac0d635a4fbf8169ac949a3c5b3d31e0 
+sdk.win_installer_checksum=ef92e643731f820360e036eb11658656
 
 sdk.win_download=android-sdk_r09-windows.zip
 sdk.win_bytes=32779808
diff --git a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
index 13988cd..9f6bd29 100644
--- a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
+++ b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
@@ -104,7 +104,7 @@
       mNextExpectedSeqNoValid(false),
       mNextExpectedSeqNo(0),
       mAccessUnitDamaged(false) {
-    mIsGeneric = desc.startsWith("mpeg4-generic/");
+    mIsGeneric = !strncasecmp(desc.c_str(),"mpeg4-generic/", 14);
 
     if (mIsGeneric) {
         AString value;
diff --git a/media/libstagefright/rtsp/APacketSource.cpp b/media/libstagefright/rtsp/APacketSource.cpp
index 10cc88b..7f09248 100644
--- a/media/libstagefright/rtsp/APacketSource.cpp
+++ b/media/libstagefright/rtsp/APacketSource.cpp
@@ -627,7 +627,7 @@
 
         mFormat->setInt32(kKeyWidth, width);
         mFormat->setInt32(kKeyHeight, height);
-    } else if (!strncmp(desc.c_str(), "mpeg4-generic/", 14)) {
+    } else if (!strncasecmp(desc.c_str(), "mpeg4-generic/", 14)) {
         AString val;
         if (!GetAttribute(params.c_str(), "mode", &val)
                 || (strcasecmp(val.c_str(), "AAC-lbr")
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index 5a1ea5c..72943ff 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -123,7 +123,7 @@
         struct sockaddr_in addr;
         memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
         addr.sin_family = AF_INET;
-        addr.sin_addr.s_addr = INADDR_ANY;
+        addr.sin_addr.s_addr = htonl(INADDR_ANY);
         addr.sin_port = htons(port);
 
         if (bind(*rtpSocket,
@@ -346,6 +346,8 @@
 }
 
 status_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) {
+    LOGV("receiving %s", receiveRTP ? "RTP" : "RTCP");
+
     CHECK(!s->mIsInjected);
 
     sp<ABuffer> buffer = new ABuffer(65536);
diff --git a/media/libstagefright/rtsp/ARTPSource.cpp b/media/libstagefright/rtsp/ARTPSource.cpp
index 5aae4e7..87b5a7e 100644
--- a/media/libstagefright/rtsp/ARTPSource.cpp
+++ b/media/libstagefright/rtsp/ARTPSource.cpp
@@ -67,7 +67,7 @@
     } else  if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
         mAssembler = new AAMRAssembler(notify, true /* isWide */, params);
     } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)
-            || !strncmp(desc.c_str(), "mpeg4-generic/", 14)) {
+            || !strncasecmp(desc.c_str(), "mpeg4-generic/", 14)) {
         mAssembler = new AMPEG4ElementaryAssembler(notify, desc, params);
         mIssueFIRRequests = true;
     } else {
diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index e936923..0740515 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -545,6 +545,10 @@
     return buffer;
 }
 
+static bool IsRTSPVersion(const AString &s) {
+    return s == "RTSP/1.0";
+}
+
 bool ARTSPConnection::receiveRTSPReponse() {
     AString statusLine;
 
@@ -584,13 +588,27 @@
         return false;
     }
 
-    AString statusCodeStr(
-            response->mStatusLine, space1 + 1, space2 - space1 - 1);
+    bool isRequest = false;
 
-    if (!ParseSingleUnsignedLong(
-                statusCodeStr.c_str(), &response->mStatusCode)
-            || response->mStatusCode < 100 || response->mStatusCode > 999) {
-        return false;
+    if (!IsRTSPVersion(AString(response->mStatusLine, 0, space1))) {
+        CHECK(IsRTSPVersion(
+                    AString(
+                        response->mStatusLine,
+                        space2 + 1,
+                        response->mStatusLine.size() - space2 - 1)));
+
+        isRequest = true;
+
+        response->mStatusCode = 0;
+    } else {
+        AString statusCodeStr(
+                response->mStatusLine, space1 + 1, space2 - space1 - 1);
+
+        if (!ParseSingleUnsignedLong(
+                    statusCodeStr.c_str(), &response->mStatusCode)
+                || response->mStatusCode < 100 || response->mStatusCode > 999) {
+            return false;
+        }
     }
 
     AString line;
@@ -680,7 +698,63 @@
         }
     }
 
-    return notifyResponseListener(response);
+    return isRequest
+        ? handleServerRequest(response)
+        : notifyResponseListener(response);
+}
+
+bool ARTSPConnection::handleServerRequest(const sp<ARTSPResponse> &request) {
+    // Implementation of server->client requests is optional for all methods
+    // but we do need to respond, even if it's just to say that we don't
+    // support the method.
+
+    ssize_t space1 = request->mStatusLine.find(" ");
+    CHECK_GE(space1, 0);
+
+    AString response;
+    response.append("RTSP/1.0 501 Not Implemented\r\n");
+
+    ssize_t i = request->mHeaders.indexOfKey("cseq");
+
+    if (i >= 0) {
+        AString value = request->mHeaders.valueAt(i);
+
+        unsigned long cseq;
+        if (!ParseSingleUnsignedLong(value.c_str(), &cseq)) {
+            return false;
+        }
+
+        response.append("CSeq: ");
+        response.append(cseq);
+        response.append("\r\n");
+    }
+
+    response.append("\r\n");
+
+    size_t numBytesSent = 0;
+    while (numBytesSent < response.size()) {
+        ssize_t n =
+            send(mSocket, response.c_str() + numBytesSent,
+                 response.size() - numBytesSent, 0);
+
+        if (n == 0) {
+            // Server closed the connection.
+            LOGE("Server unexpectedly closed the connection.");
+
+            return false;
+        } else if (n < 0) {
+            if (errno == EINTR) {
+                continue;
+            }
+
+            LOGE("Error sending rtsp response.");
+            return false;
+        }
+
+        numBytesSent += (size_t)n;
+    }
+
+    return true;
 }
 
 // static
diff --git a/media/libstagefright/rtsp/ARTSPConnection.h b/media/libstagefright/rtsp/ARTSPConnection.h
index 19be2a6..0fecf3c 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.h
+++ b/media/libstagefright/rtsp/ARTSPConnection.h
@@ -109,6 +109,8 @@
     status_t findPendingRequest(
             const sp<ARTSPResponse> &response, ssize_t *index) const;
 
+    bool handleServerRequest(const sp<ARTSPResponse> &request);
+
     static bool ParseSingleUnsignedLong(
             const char *from, unsigned long *x);
 
diff --git a/media/libstagefright/rtsp/ASessionDescription.cpp b/media/libstagefright/rtsp/ASessionDescription.cpp
index 2843ee6..aa2618e 100644
--- a/media/libstagefright/rtsp/ASessionDescription.cpp
+++ b/media/libstagefright/rtsp/ASessionDescription.cpp
@@ -71,6 +71,11 @@
             line.setTo(desc, i, eolPos - i);
         }
 
+        if (line.empty()) {
+            i = eolPos + 1;
+            continue;
+        }
+
         if (line.size() < 2 || line.c_str()[1] != '=') {
             return false;
         }
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index 5c6ff82..7bf534d 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -38,6 +38,7 @@
 
 #include <arpa/inet.h>
 #include <sys/socket.h>
+#include <netdb.h>
 
 // If no access units are received within 3 secs, assume that the rtp
 // stream has ended and signal end of stream.
@@ -119,9 +120,10 @@
         // want to transmit user/pass in cleartext.
         AString host, path, user, pass;
         unsigned port;
-        if (ARTSPConnection::ParseURL(
-                    mSessionURL.c_str(), &host, &port, &path, &user, &pass)
-                && user.size() > 0) {
+        CHECK(ARTSPConnection::ParseURL(
+                    mSessionURL.c_str(), &host, &port, &path, &user, &pass));
+
+        if (user.size() > 0) {
             mSessionURL.clear();
             mSessionURL.append("rtsp://");
             mSessionURL.append(host);
@@ -131,6 +133,8 @@
 
             LOGI("rewritten session url: '%s'", mSessionURL.c_str());
         }
+
+        mSessionHost = host;
     }
 
     void connect(const sp<AMessage> &doneMsg) {
@@ -246,34 +250,64 @@
     // In case we're behind NAT, fire off two UDP packets to the remote
     // rtp/rtcp ports to poke a hole into the firewall for future incoming
     // packets. We're going to send an RR/SDES RTCP packet to both of them.
-    void pokeAHole(int rtpSocket, int rtcpSocket, const AString &transport) {
+    bool pokeAHole(int rtpSocket, int rtcpSocket, const AString &transport) {
+        struct sockaddr_in addr;
+        memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
+        addr.sin_family = AF_INET;
+
         AString source;
         AString server_port;
         if (!GetAttribute(transport.c_str(),
                           "source",
-                          &source)
-                || !GetAttribute(transport.c_str(),
+                          &source)) {
+            LOGW("Missing 'source' field in Transport response. Using "
+                 "RTSP endpoint address.");
+
+            struct hostent *ent = gethostbyname(mSessionHost.c_str());
+            if (ent == NULL) {
+                LOGE("Failed to look up address of session host '%s'",
+                     mSessionHost.c_str());
+
+                return false;
+            }
+
+            addr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr;
+        } else {
+            addr.sin_addr.s_addr = inet_addr(source.c_str());
+        }
+
+        if (!GetAttribute(transport.c_str(),
                                  "server_port",
                                  &server_port)) {
-            return;
+            LOGI("Missing 'server_port' field in Transport response.");
+            return false;
         }
 
         int rtpPort, rtcpPort;
         if (sscanf(server_port.c_str(), "%d-%d", &rtpPort, &rtcpPort) != 2
                 || rtpPort <= 0 || rtpPort > 65535
                 || rtcpPort <=0 || rtcpPort > 65535
-                || rtcpPort != rtpPort + 1
-                || (rtpPort & 1) != 0) {
-            return;
+                || rtcpPort != rtpPort + 1) {
+            LOGE("Server picked invalid RTP/RTCP port pair %s,"
+                 " RTP port must be even, RTCP port must be one higher.",
+                 server_port.c_str());
+
+            return false;
         }
 
-        struct sockaddr_in addr;
-        memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
-        addr.sin_family = AF_INET;
-        addr.sin_addr.s_addr = inet_addr(source.c_str());
+        if (rtpPort & 1) {
+            LOGW("Server picked an odd RTP port, it should've picked an "
+                 "even one, we'll let it pass for now, but this may break "
+                 "in the future.");
+        }
 
         if (addr.sin_addr.s_addr == INADDR_NONE) {
-            return;
+            return true;
+        }
+
+        if (IN_LOOPBACK(ntohl(addr.sin_addr.s_addr))) {
+            // No firewalls to traverse on the loopback interface.
+            return true;
         }
 
         // Make up an RR/SDES RTCP packet.
@@ -287,16 +321,26 @@
         ssize_t n = sendto(
                 rtpSocket, buf->data(), buf->size(), 0,
                 (const sockaddr *)&addr, sizeof(addr));
-        CHECK_EQ(n, (ssize_t)buf->size());
+
+        if (n < (ssize_t)buf->size()) {
+            LOGE("failed to poke a hole for RTP packets");
+            return false;
+        }
 
         addr.sin_port = htons(rtcpPort);
 
         n = sendto(
                 rtcpSocket, buf->data(), buf->size(), 0,
                 (const sockaddr *)&addr, sizeof(addr));
-        CHECK_EQ(n, (ssize_t)buf->size());
+
+        if (n < (ssize_t)buf->size()) {
+            LOGE("failed to poke a hole for RTCP packets");
+            return false;
+        }
 
         LOGV("successfully poked holes.");
+
+        return true;
     }
 
     virtual void onMessageReceived(const sp<AMessage> &msg) {
@@ -379,6 +423,7 @@
                                 response->mContent->size());
 
                         if (!mSessionDesc->isValid()) {
+                            LOGE("Failed to parse session description.");
                             result = ERROR_MALFORMED;
                         } else {
                             ssize_t i = response->mHeaders.indexOfKey("content-base");
@@ -393,6 +438,25 @@
                                 }
                             }
 
+                            if (!mBaseURL.startsWith("rtsp://")) {
+                                // Some misbehaving servers specify a relative
+                                // URL in one of the locations above, combine
+                                // it with the absolute session URL to get
+                                // something usable...
+
+                                LOGW("Server specified a non-absolute base URL"
+                                     ", combining it with the session URL to "
+                                     "get something usable...");
+
+                                AString tmp;
+                                CHECK(MakeURL(
+                                            mSessionURL.c_str(),
+                                            mBaseURL.c_str(),
+                                            &tmp));
+
+                                mBaseURL = tmp;
+                            }
+
                             CHECK_GT(mSessionDesc->countTracks(), 1u);
                             setupTrack(1);
                         }
@@ -453,9 +517,12 @@
                         if (!track->mUsingInterleavedTCP) {
                             AString transport = response->mHeaders.valueAt(i);
 
-                            pokeAHole(track->mRTPSocket,
-                                      track->mRTCPSocket,
-                                      transport);
+                            // We are going to continue even if we were
+                            // unable to poke a hole into the firewall...
+                            pokeAHole(
+                                    track->mRTPSocket,
+                                    track->mRTCPSocket,
+                                    transport);
                         }
 
                         mRTPConn->addStream(
@@ -865,10 +932,7 @@
             case 'tiou':
             {
                 if (!mReceivedFirstRTCPPacket) {
-                    if (mTryFakeRTCP) {
-                        LOGW("Never received any data, disconnecting.");
-                        (new AMessage('abor', id()))->post();
-                    } else if (mTryTCPInterleaving && mReceivedFirstRTPPacket) {
+                    if (mReceivedFirstRTPPacket && !mTryFakeRTCP) {
                         LOGW("We received RTP packets but no RTCP packets, "
                              "using fake timestamps.");
 
@@ -876,7 +940,7 @@
 
                         mReceivedFirstRTCPPacket = true;
                         mRTPConn->fakeTimestamps();
-                    } else {
+                    } else if (!mReceivedFirstRTPPacket && !mTryTCPInterleaving) {
                         LOGW("Never received any data, switching transports.");
 
                         mTryTCPInterleaving = true;
@@ -884,6 +948,9 @@
                         sp<AMessage> msg = new AMessage('abor', id());
                         msg->setInt32("reconnect", true);
                         msg->post();
+                    } else {
+                        LOGW("Never received any data, disconnecting.");
+                        (new AMessage('abor', id()))->post();
                     }
                 }
                 break;
@@ -1010,6 +1077,7 @@
     sp<ASessionDescription> mSessionDesc;
     AString mOriginalSessionURL;  // This one still has user:pass@
     AString mSessionURL;
+    AString mSessionHost;
     AString mBaseURL;
     AString mSessionID;
     bool mSetupTracksSuccessful;
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index ebe2193..7e0c169 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -814,7 +814,7 @@
     dp->refs--;
     dp->numTotalConfigs = 0;
     delete [] dp->configs;
-    clearTLS();
+
     return res;
 }
 
@@ -1150,6 +1150,27 @@
     return result;
 }
 
+static void loseCurrent(egl_context_t * cur_c)
+{
+    if (cur_c) {
+        egl_surface_t * cur_r = get_surface(cur_c->read);
+        egl_surface_t * cur_d = get_surface(cur_c->draw);
+
+        // by construction, these are either 0 or valid (possibly terminated)
+        // it should be impossible for these to be invalid
+        ContextRef _cur_c(cur_c);
+        SurfaceRef _cur_r(cur_r);
+        SurfaceRef _cur_d(cur_d);
+
+        cur_c->read = NULL;
+        cur_c->draw = NULL;
+
+        _cur_c.release();
+        _cur_r.release();
+        _cur_d.release();
+    }
+}
+
 EGLBoolean eglMakeCurrent(  EGLDisplay dpy, EGLSurface draw,
                             EGLSurface read, EGLContext ctx)
 {
@@ -1178,13 +1199,9 @@
 
     // these are the current objects structs
     egl_context_t * cur_c = get_context(getContext());
-    egl_surface_t * cur_r = NULL;
-    egl_surface_t * cur_d = NULL;
     
     if (ctx != EGL_NO_CONTEXT) {
         c = get_context(ctx);
-        cur_r = get_surface(c->read);
-        cur_d = get_surface(c->draw);
         impl_ctx = c->context;
     } else {
         // no context given, use the implementation of the current context
@@ -1230,30 +1247,21 @@
     }
 
     if (result == EGL_TRUE) {
-        // by construction, these are either 0 or valid (possibly terminated)
-        // it should be impossible for these to be invalid
-        ContextRef _cur_c(cur_c);
-        SurfaceRef _cur_r(cur_r);
-        SurfaceRef _cur_d(cur_d);
 
-        // cur_c has to be valid here (but could be terminated)
+        loseCurrent(cur_c);
+
         if (ctx != EGL_NO_CONTEXT) {
             setGlThreadSpecific(c->cnx->hooks[c->version]);
             setContext(ctx);
             _c.acquire();
+            _r.acquire();
+            _d.acquire();
+            c->read = read;
+            c->draw = draw;
         } else {
             setGlThreadSpecific(&gHooksNoContext);
             setContext(EGL_NO_CONTEXT);
         }
-        _cur_c.release();
-
-        _r.acquire();
-        _cur_r.release();
-        if (c) c->read = read;
-
-        _d.acquire();
-        _cur_d.release();
-        if (c) c->draw = draw;
     }
     return result;
 }
@@ -1637,6 +1645,9 @@
 
 EGLBoolean eglReleaseThread(void)
 {
+    // If there is context bound to the thread, release it
+    loseCurrent(get_context(getContext()));
+
     for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
         if (cnx->dso) {
diff --git a/packages/DefaultContainerService/res/values-ro/strings.xml b/packages/DefaultContainerService/res/values-ro/strings.xml
index 69de00f..cf9d709 100644
--- a/packages/DefaultContainerService/res/values-ro/strings.xml
+++ b/packages/DefaultContainerService/res/values-ro/strings.xml
@@ -20,5 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="service_name" msgid="4841491635055379553">"Ajutor accesare pachet"</string>
+    <!-- outdated translation 2860331691588000093 -->     <string name="service_name" msgid="4841491635055379553">"Ajutor accesare pachet"</string>
 </resources>
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_4g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_4g.png
new file mode 100644
index 0000000..1aea612
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_4g.png
new file mode 100644
index 0000000..425535e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_4g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_4g.png
new file mode 100644
index 0000000..fcad363
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_4g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_4g.png
new file mode 100644
index 0000000..4ff7db3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_4g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_4g.png
new file mode 100644
index 0000000..2c4a07f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_4g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_4g.png
new file mode 100644
index 0000000..879c703
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inadnout_e.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inadnout_e.png
new file mode 100644
index 0000000..61a7503
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inadnout_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_4g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_4g.png
new file mode 100644
index 0000000..c5edf2c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_4g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_4g.png
new file mode 100644
index 0000000..ddf88be
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_1x.png
index 78ece9e..c77e61e 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_1x.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_3g.png
index 31fc1b0..b9f721a 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_3g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_4g.png
new file mode 100644
index 0000000..cff969e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_e.png
index 19adb4b..d2d7ab3 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_e.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_g.png
index fd419ea..83ce6d0 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_h.png
index 94e77ae..abe511f 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_h.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_1x.png
index 91328c0..d685af8 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_1x.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_3g.png
index 2fee6924..8c697a1 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_3g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_4g.png
new file mode 100644
index 0000000..9a4b807
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_e.png
index d0968aa..eb11d04 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_e.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_g.png
index 991228b..6e54de0 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_h.png
index ae03e38..5bfb33b 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_h.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_1x.png
index 97b011e..119067b 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_1x.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_3g.png
index a826866..a70cc2e 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_3g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_4g.png
new file mode 100644
index 0000000..ea3dba7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_e.png
index f6a6891..53221b9 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_e.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_g.png
index 19b9816..11d44d0 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_h.png
index f8c0961..9defd79 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_h.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_in_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_1x.png
index 22deb70..136576d 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_1x.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_3g.png
index c7c1b49..26ca31f 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_3g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_4g.png
new file mode 100644
index 0000000..de8c5ee
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_e.png
index d9a0702..64dbf3c 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_e.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_g.png
index 6beed8a..34923fb 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_h.png
index e4179c1..506b5c6 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_h.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_inandout_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_1x.png
index 4b2f86d..163976f 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_1x.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_3g.png
index 6779604..a6af649 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_3g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_4g.png
new file mode 100644
index 0000000..0c08e52
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_e.png
index 1309a97..1d02edb 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_e.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_g.png
index 2fc1e8e..edc9536 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_h.png
index 0eef2c1..8376817 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_h.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_out_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_1x.png
index f8904e2..ecef547 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_1x.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_3g.png
index 3ef306e..a7c48b6 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_3g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_4g.png
new file mode 100644
index 0000000..f4bcd9a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_e.png
index 2ff6d90..b46bb3a 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_e.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_g.png
index 8ff49b0..e8b70f2 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_h.png
index f416203..4e23c4e 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_h.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inadnout_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inadnout_e.png
new file mode 100644
index 0000000..ced9175
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inadnout_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_1x.png
index 24b7daa..92d4a19 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_1x.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_3g.png
index 5ea9142..a208736 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_3g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_4g.png
new file mode 100644
index 0000000..f407bc9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_g.png
index 002bf46..b8a65c2 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_h.png
index 924b84f..a978b68 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_h.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_1x.png
index bd0d1ca..710dd52 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_1x.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_3g.png
index f583eec..a7b35e4 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_3g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_4g.png
new file mode 100644
index 0000000..bb05449
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_e.png
index 66940eaf..a144222 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_e.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_g.png
index 0381f52..b0eafb6 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_h.png
index 0b84fe8..f6b83d0 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_h.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_h.png
Binary files differ
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index bc102e4..4e5aa33 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -1037,59 +1037,32 @@
             for (int checkType=0; checkType <= ConnectivityManager.MAX_NETWORK_TYPE; checkType++) {
                 if (checkType == prevNetType) continue;
                 if (mNetAttributes[checkType] == null) continue;
+                if (mNetAttributes[checkType].isDefault() == false) continue;
                 if (mNetAttributes[checkType].mRadio == ConnectivityManager.TYPE_MOBILE &&
                         noMobileData) {
                     Slog.e(TAG, "not failing over to mobile type " + checkType +
                             " because Mobile Data Disabled");
                     continue;
                 }
-                if (mNetAttributes[checkType].isDefault()) {
-                    /* TODO - if we have multiple nets we could use
-                     * we may want to put more thought into which we choose
-                     */
-                    if (checkType == mNetworkPreference) {
-                        newType = checkType;
-                        break;
-                    }
-                    if (mNetAttributes[checkType].mPriority > newPriority) {
-                        newType = checkType;
-                        newPriority = mNetAttributes[newType].mPriority;
-                    }
+                NetworkStateTracker tracker = mNetTrackers[checkType];
+                NetworkInfo info = tracker.getNetworkInfo();
+                if (!info.isConnectedOrConnecting() ||
+                        tracker.isTeardownRequested()) {
+                    info.setFailover(true);
+                    tracker.reconnect();
                 }
-            }
+                if (DBG) Slog.d(TAG, "Attempting to switch to " + info.getTypeName());
 
-            if (newType != -1) {
-                newNet = mNetTrackers[newType];
-                /**
-                 * See if the other network is available to fail over to.
-                 * If is not available, we enable it anyway, so that it
-                 * will be able to connect when it does become available,
-                 * but we report a total loss of connectivity rather than
-                 * report that we are attempting to fail over.
-                 */
-                if (newNet.isAvailable()) {
-                    NetworkInfo switchTo = newNet.getNetworkInfo();
-                    switchTo.setFailover(true);
-                    if (!switchTo.isConnectedOrConnecting() ||
-                            newNet.isTeardownRequested()) {
-                        newNet.reconnect();
-                    }
-                    if (DBG) {
-                        if (switchTo.isConnected()) {
-                            Slog.v(TAG, "Switching to already connected " +
-                                    switchTo.getTypeName());
-                        } else {
-                            Slog.v(TAG, "Attempting to switch to " +
-                                    switchTo.getTypeName());
-                        }
-                    }
-                } else {
-                    newNet.reconnect();
-                    newNet = null; // not officially avail..  try anyway, but
-                                   // report no failover
+                // figure out if this is the highest priority network
+                // so we send an appropriate return value
+                if (checkType == mNetworkPreference) {
+                    newType = checkType;
                 }
-            } else {
-                Slog.e(TAG, "Network failover failing.");
+                if (mNetAttributes[checkType].mPriority > newPriority &&
+                        newType != mNetworkPreference) {
+                    newType = checkType;
+                    newPriority = mNetAttributes[checkType].mPriority;
+                }
             }
         }
 
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index ea5e5cc..697e879 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -293,18 +293,21 @@
     return result;
 }
 
-void SensorService::cleanupConnection(const wp<SensorEventConnection>& connection)
+void SensorService::cleanupConnection(SensorEventConnection* c)
 {
     Mutex::Autolock _l(mLock);
+    const wp<SensorEventConnection> connection(c);
     size_t size = mActiveSensors.size();
     for (size_t i=0 ; i<size ; ) {
-        SensorRecord* rec = mActiveSensors.valueAt(i);
-        if (rec && rec->removeConnection(connection)) {
-            int handle = mActiveSensors.keyAt(i);
+        int handle = mActiveSensors.keyAt(i);
+        if (c->hasSensor(handle)) {
             SensorInterface* sensor = mSensorMap.valueFor( handle );
             if (sensor) {
-                sensor->activate(connection.unsafe_get(), false);
+                sensor->activate(c, false);
             }
+        }
+        SensorRecord* rec = mActiveSensors.valueAt(i);
+        if (rec && rec->removeConnection(connection)) {
             mActiveSensors.removeItemsAt(i, 1);
             mActiveVirtualSensors.removeItem(handle);
             delete rec;
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 540c7e2..21f12bd 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -129,7 +129,7 @@
 public:
     static char const* getServiceName() { return "sensorservice"; }
 
-    void cleanupConnection(const wp<SensorEventConnection>& connection);
+    void cleanupConnection(SensorEventConnection* connection);
     status_t enable(const sp<SensorEventConnection>& connection, int handle);
     status_t disable(const sp<SensorEventConnection>& connection, int handle);
     status_t setEventRate(const sp<SensorEventConnection>& connection, int handle, nsecs_t ns);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 249b050..c11dd0b 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -730,7 +730,14 @@
         String number = null;
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
         // TODO: The default value of voicemail number should be read from a system property
-        number = sp.getString(VM_NUMBER_CDMA, "*86");
+
+        // Read platform settings for dynamic voicemail number
+        if (getContext().getResources().getBoolean(com.android.internal
+                .R.bool.config_telephony_use_own_number_for_voicemail)) {
+            number = sp.getString(VM_NUMBER_CDMA, getLine1Number());
+        } else {
+            number = sp.getString(VM_NUMBER_CDMA, "*86");
+        }
         return number;
     }
 
diff --git a/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java b/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
index 41e527c..6458fda 100644
--- a/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
+++ b/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
@@ -284,8 +284,15 @@
         fileIds = mPbrFile.mFileIds.get(recNum);
         if (fileIds == null || fileIds.isEmpty()) return;
 
+
+        int extEf = 0;
+        // Only call fileIds.get while EFEXT1_TAG is available
+        if (fileIds.containsKey(USIM_EFEXT1_TAG)) {
+            extEf = fileIds.get(USIM_EFEXT1_TAG);
+        }
+
         mAdnCache.requestLoadAllAdnLike(fileIds.get(USIM_EFADN_TAG),
-            fileIds.get(USIM_EFEXT1_TAG), obtainMessage(EVENT_USIM_ADN_LOAD_DONE));
+            extEf, obtainMessage(EVENT_USIM_ADN_LOAD_DONE));
         try {
             mLock.wait();
         } catch (InterruptedException e) {
diff --git a/tools/layoutlib/README b/tools/layoutlib/README
new file mode 100644
index 0000000..0fea9bd
--- /dev/null
+++ b/tools/layoutlib/README
@@ -0,0 +1,4 @@
+Layoutlib is a custom version of the android View framework designed to run inside Eclipse.
+The goal of the library is to provide layout rendering in Eclipse that are very very close to their rendering on devices.
+
+None of the com.android.* or android.* classes in layoutlib run on devices.
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath
index 175a98b..5cfda29 100644
--- a/tools/layoutlib/bridge/.classpath
+++ b/tools/layoutlib/bridge/.classpath
@@ -4,9 +4,10 @@
 	<classpathentry kind="src" path="tests"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/layoutlib_api"/>
-	<classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_SRC/dalvik/libcore/xml/src/main/java"/>
-	<classpathentry kind="var" path="ANDROID_OUT_FRAMEWORK/layoutlib.jar" sourcepath="/ANDROID_SRC/frameworks/base/core/java"/>
-	<classpathentry kind="var" path="ANDROID_OUT_FRAMEWORK/ninepatch.jar" sourcepath="/ANDROID_SRC/development/tools/ninepatch/src"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/layoutlib_api/layoutlib_api-prebuilt.jar"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/ninepatch/ninepatch-prebuilt.jar"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/tools-common/tools-common-prebuilt.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/tools/layoutlib/bridge/Android.mk b/tools/layoutlib/bridge/Android.mk
index b2010d5..7e70f33 100644
--- a/tools/layoutlib/bridge/Android.mk
+++ b/tools/layoutlib/bridge/Android.mk
@@ -17,13 +17,17 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := $(call all-java-files-under,src)
+LOCAL_JAVA_RESOURCE_DIRS := resources
+
 
 LOCAL_JAVA_LIBRARIES := \
 	kxml2-2.3.0 \
-	layoutlib_api \
-	ninepatch
+	layoutlib_api-prebuilt \
+	tools-common-prebuilt
 
-LOCAL_STATIC_JAVA_LIBRARIES := temp_layoutlib
+LOCAL_STATIC_JAVA_LIBRARIES := \
+	temp_layoutlib \
+	ninepatch-prebuilt
 
 LOCAL_MODULE := layoutlib
 
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_wifi_signal_4_fully.png
new file mode 100644
index 0000000..bd44b52
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_wifi_signal_4_fully.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/status_bar_background.9.png b/tools/layoutlib/bridge/resources/bars/hdpi/status_bar_background.9.png
new file mode 100644
index 0000000..a4be298
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/hdpi/status_bar_background.9.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_wifi_signal_4_fully.png
new file mode 100644
index 0000000..c629387
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_wifi_signal_4_fully.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/status_bar_background.9.png b/tools/layoutlib/bridge/resources/bars/mdpi/status_bar_background.9.png
new file mode 100644
index 0000000..eb7c1a4
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/mdpi/status_bar_background.9.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/phone_system_bar.xml b/tools/layoutlib/bridge/resources/bars/phone_system_bar.xml
new file mode 100644
index 0000000..d3c492e
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/phone_system_bar.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+	<TextView
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:layout_weight="1"/>
+	<ImageView
+			android:layout_height="wrap_content"
+			android:layout_width="wrap_content"/>
+	<ImageView
+			android:layout_height="wrap_content"
+			android:layout_width="wrap_content"
+			android:layout_marginLeft="3dip"
+			android:layout_marginRight="5dip"/>
+</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/title_bar.xml b/tools/layoutlib/bridge/resources/bars/title_bar.xml
new file mode 100644
index 0000000..76d78d9
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/title_bar.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+	<TextView
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"/>
+</merge>
diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java
new file mode 100644
index 0000000..413894b
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/content/res/Resources_Theme_Delegate.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.res;
+
+import com.android.layoutlib.bridge.impl.RenderSessionImpl;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.content.res.Resources.NotFoundException;
+import android.content.res.Resources.Theme;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+
+/**
+ * Delegate used to provide new implementation of a select few methods of {@link Theme}
+ *
+ * Through the layoutlib_create tool, the original  methods of Theme have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ */
+public class Resources_Theme_Delegate {
+
+    @LayoutlibDelegate
+    /*package*/ static TypedArray obtainStyledAttributes(
+            Resources thisResources, Theme thisTheme,
+            int[] attrs) {
+        return RenderSessionImpl.getCurrentContext().obtainStyledAttributes(attrs);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static TypedArray obtainStyledAttributes(
+            Resources thisResources, Theme thisTheme,
+            int resid, int[] attrs)
+            throws NotFoundException {
+        return RenderSessionImpl.getCurrentContext().obtainStyledAttributes(resid, attrs);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static TypedArray obtainStyledAttributes(
+            Resources thisResources, Theme thisTheme,
+            AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) {
+        return RenderSessionImpl.getCurrentContext().obtainStyledAttributes(
+                set, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean resolveAttribute(
+            Resources thisResources, Theme thisTheme,
+            int resid, TypedValue outValue,
+            boolean resolveRefs) {
+        return RenderSessionImpl.getCurrentContext().resolveThemeAttribute(
+                resid, outValue, resolveRefs);
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/AvoidXfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/AvoidXfermode_Delegate.java
new file mode 100644
index 0000000..a50a2bd
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/AvoidXfermode_Delegate.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import java.awt.Composite;
+
+/**
+ * Delegate implementing the native methods of android.graphics.AvoidXfermode
+ *
+ * Through the layoutlib_create tool, the original native methods of AvoidXfermode have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original AvoidXfermode class.
+ *
+ * Because this extends {@link Xfermode_Delegate}, there's no need to use a
+ * {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
+ * {@link Xfermode_Delegate}.
+ *
+ */
+public class AvoidXfermode_Delegate extends Xfermode_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public Composite getComposite(int alpha) {
+        // FIXME
+        return null;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Avoid Xfermodes are not supported in Layout Preview mode.";
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreate(int opColor, int tolerance, int nativeMode) {
+        AvoidXfermode_Delegate newDelegate = new AvoidXfermode_Delegate();
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap.java
deleted file mode 100644
index 35f022e..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-
-import java.awt.image.BufferedImage;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.imageio.ImageIO;
-
-public final class Bitmap extends _Original_Bitmap {
-
-    private BufferedImage mImage;
-
-    public Bitmap(File input) throws IOException {
-        super(1, true, null, -1);
-
-        mImage = ImageIO.read(input);
-    }
-
-    public Bitmap(InputStream is) throws IOException {
-        super(1, true, null, -1);
-
-        mImage = ImageIO.read(is);
-    }
-
-    Bitmap(BufferedImage image) {
-        super(1, true, null, -1);
-        mImage = image;
-    }
-
-    public BufferedImage getImage() {
-        return mImage;
-    }
-
-    // ----- overriden methods
-
-    public enum Config {
-        // these native values must match up with the enum in SkBitmap.h
-        ALPHA_8     (2),
-        RGB_565     (4),
-        ARGB_4444   (5),
-        ARGB_8888   (6);
-
-        Config(int ni) {
-            this.nativeInt = ni;
-        }
-        final int nativeInt;
-
-        /* package */ static Config nativeToConfig(int ni) {
-            return sConfigs[ni];
-        }
-
-        private static Config sConfigs[] = {
-            null, null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888
-        };
-    }
-
-    @Override
-    public int getWidth() {
-        return mImage.getWidth();
-    }
-
-    @Override
-    public int getHeight() {
-        return mImage.getHeight();
-    }
-
-    /**
-     * Returns an immutable bitmap from the source bitmap. The new bitmap may
-     * be the same object as source, or a copy may have been made.
-     */
-    public static Bitmap createBitmap(Bitmap src) {
-        return createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), null, false);
-    }
-
-    /**
-     * Returns an immutable bitmap from the specified subset of the source
-     * bitmap. The new bitmap may be the same object as source, or a copy may
-     * have been made.
-     *
-     * @param source   The bitmap we are subsetting
-     * @param x        The x coordinate of the first pixel in source
-     * @param y        The y coordinate of the first pixel in source
-     * @param width    The number of pixels in each row
-     * @param height   The number of rows
-     */
-    public static Bitmap createBitmap(Bitmap source, int x, int y,
-                                      int width, int height) {
-        return new Bitmap(source.mImage.getSubimage(x, y, width, height));
-    }
-
-    /**
-     * Returns an immutable bitmap from subset of the source bitmap,
-     * transformed by the optional matrix.
-     *
-     * @param source   The bitmap we are subsetting
-     * @param x        The x coordinate of the first pixel in source
-     * @param y        The y coordinate of the first pixel in source
-     * @param width    The number of pixels in each row
-     * @param height   The number of rows
-     * @param m        Option matrix to be applied to the pixels
-     * @param filter   true if the source should be filtered.
-     *                   Only applies if the matrix contains more than just
-     *                   translation.
-     * @return A bitmap that represents the specified subset of source
-     * @throws IllegalArgumentException if the x, y, width, height values are
-     *         outside of the dimensions of the source bitmap.
-     */
-    public static Bitmap createBitmap(Bitmap source, int x, int y, int width,
-                                      int height, Matrix m, boolean filter) {
-        checkXYSign(x, y);
-        checkWidthHeight(width, height);
-        if (x + width > source.getWidth()) {
-            throw new IllegalArgumentException(
-                    "x + width must be <= bitmap.width()");
-        }
-        if (y + height > source.getHeight()) {
-            throw new IllegalArgumentException(
-                    "y + height must be <= bitmap.height()");
-        }
-
-        // check if we can just return our argument unchanged
-        if (!source.isMutable() && x == 0 && y == 0
-                && width == source.getWidth() && height == source.getHeight()
-                && (m == null || m.isIdentity())) {
-            return source;
-        }
-
-        if (m == null || m.isIdentity()) {
-            return new Bitmap(source.mImage.getSubimage(x, y, width, height));
-        }
-
-        int neww = width;
-        int newh = height;
-        Paint paint;
-
-        Rect srcR = new Rect(x, y, x + width, y + height);
-        RectF dstR = new RectF(0, 0, width, height);
-
-        /*  the dst should have alpha if the src does, or if our matrix
-            doesn't preserve rectness
-        */
-        boolean hasAlpha = source.hasAlpha() || !m.rectStaysRect();
-        RectF deviceR = new RectF();
-        m.mapRect(deviceR, dstR);
-        neww = Math.round(deviceR.width());
-        newh = Math.round(deviceR.height());
-
-        Canvas canvas = new Canvas(neww, newh);
-
-        canvas.translate(-deviceR.left, -deviceR.top);
-        canvas.concat(m);
-        paint = new Paint();
-        paint.setFilterBitmap(filter);
-        if (!m.rectStaysRect()) {
-            paint.setAntiAlias(true);
-        }
-
-        canvas.drawBitmap(source, srcR, dstR, paint);
-
-        return new Bitmap(canvas.getImage());
-    }
-
-    /**
-     * Returns a mutable bitmap with the specified width and height.
-     *
-     * @param width    The width of the bitmap
-     * @param height   The height of the bitmap
-     * @param config   The bitmap config to create.
-     * @throws IllegalArgumentException if the width or height are <= 0
-     */
-    public static Bitmap createBitmap(int width, int height, Config config) {
-        return new Bitmap(new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB));
-    }
-
-    /**
-     * Returns a immutable bitmap with the specified width and height, with each
-     * pixel value set to the corresponding value in the colors array.
-     *
-     * @param colors   Array of {@link Color} used to initialize the pixels.
-     * @param offset   Number of values to skip before the first color in the
-     *                 array of colors.
-     * @param stride   Number of colors in the array between rows (must be >=
-     *                 width or <= -width).
-     * @param width    The width of the bitmap
-     * @param height   The height of the bitmap
-     * @param config   The bitmap config to create. If the config does not
-     *                 support per-pixel alpha (e.g. RGB_565), then the alpha
-     *                 bytes in the colors[] will be ignored (assumed to be FF)
-     * @throws IllegalArgumentException if the width or height are <= 0, or if
-     *         the color array's length is less than the number of pixels.
-     */
-    public static Bitmap createBitmap(int colors[], int offset, int stride,
-                                      int width, int height, Config config) {
-        checkWidthHeight(width, height);
-        if (Math.abs(stride) < width) {
-            throw new IllegalArgumentException("abs(stride) must be >= width");
-        }
-        int lastScanline = offset + (height - 1) * stride;
-        int length = colors.length;
-        if (offset < 0 || (offset + width > length)
-            || lastScanline < 0
-            || (lastScanline + width > length)) {
-            throw new ArrayIndexOutOfBoundsException();
-        }
-
-        // TODO: create an immutable bitmap...
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Returns a immutable bitmap with the specified width and height, with each
-     * pixel value set to the corresponding value in the colors array.
-     *
-     * @param colors   Array of {@link Color} used to initialize the pixels.
-     *                 This array must be at least as large as width * height.
-     * @param width    The width of the bitmap
-     * @param height   The height of the bitmap
-     * @param config   The bitmap config to create. If the config does not
-     *                 support per-pixel alpha (e.g. RGB_565), then the alpha
-     *                 bytes in the colors[] will be ignored (assumed to be FF)
-     * @throws IllegalArgumentException if the width or height are <= 0, or if
-     *         the color array's length is less than the number of pixels.
-     */
-    public static Bitmap createBitmap(int colors[], int width, int height,
-                                      Config config) {
-        return createBitmap(colors, 0, width, width, height, config);
-    }
-
-    public static Bitmap createScaledBitmap(Bitmap src, int dstWidth,
-            int dstHeight, boolean filter) {
-        Matrix m;
-        synchronized (Bitmap.class) {
-            // small pool of just 1 matrix
-            m = sScaleMatrix;
-            sScaleMatrix = null;
-        }
-
-        if (m == null) {
-            m = new Matrix();
-        }
-
-        final int width = src.getWidth();
-        final int height = src.getHeight();
-        final float sx = dstWidth  / (float)width;
-        final float sy = dstHeight / (float)height;
-        m.setScale(sx, sy);
-        Bitmap b = Bitmap.createBitmap(src, 0, 0, width, height, m, filter);
-
-        synchronized (Bitmap.class) {
-            // do we need to check for null? why not just assign everytime?
-            if (sScaleMatrix == null) {
-                sScaleMatrix = m;
-            }
-        }
-
-        return b;
-    }
-
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java
deleted file mode 100644
index e978fe8..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory.java
+++ /dev/null
@@ -1,566 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import android.content.res.AssetManager;
-import android.content.res.Resources;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-
-import java.io.BufferedInputStream;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Creates Bitmap objects from various sources, including files, streams,
- * and byte-arrays.
- */
-public class BitmapFactory {
-    public static class Options {
-        /**
-         * Create a default Options object, which if left unchanged will give
-         * the same result from the decoder as if null were passed.
-         */
-        public Options() {
-            inDither = true;
-            inScaled = true;
-        }
-
-        /**
-         * If set to true, the decoder will return null (no bitmap), but
-         * the out... fields will still be set, allowing the caller to query
-         * the bitmap without having to allocate the memory for its pixels.
-         */
-        public boolean inJustDecodeBounds;
-
-        /**
-         * If set to a value > 1, requests the decoder to subsample the original
-         * image, returning a smaller image to save memory. The sample size is
-         * the number of pixels in either dimension that correspond to a single
-         * pixel in the decoded bitmap. For example, inSampleSize == 4 returns
-         * an image that is 1/4 the width/height of the original, and 1/16 the
-         * number of pixels. Any value <= 1 is treated the same as 1. Note: the
-         * decoder will try to fulfill this request, but the resulting bitmap
-         * may have different dimensions that precisely what has been requested.
-         * Also, powers of 2 are often faster/easier for the decoder to honor.
-         */
-        public int inSampleSize;
-
-        /**
-         * If this is non-null, the decoder will try to decode into this
-         * internal configuration. If it is null, or the request cannot be met,
-         * the decoder will try to pick the best matching config based on the
-         * system's screen depth, and characteristics of the original image such
-         * as if it has per-pixel alpha (requiring a config that also does).
-         */
-        public Bitmap.Config inPreferredConfig;
-
-        /**
-         * If dither is true, the decoder will attempt to dither the decoded
-         * image.
-         */
-        public boolean inDither;
-
-        /**
-         * The pixel density to use for the bitmap.  This will always result
-         * in the returned bitmap having a density set for it (see
-         * {@link Bitmap#setDensity(int) Bitmap.setDensity(int)).  In addition,
-         * if {@link #inScaled} is set (which it is by default} and this
-         * density does not match {@link #inTargetDensity}, then the bitmap
-         * will be scaled to the target density before being returned.
-         *
-         * <p>If this is 0,
-         * {@link BitmapFactory#decodeResource(Resources, int)},
-         * {@link BitmapFactory#decodeResource(Resources, int, android.graphics.BitmapFactory.Options)},
-         * and {@link BitmapFactory#decodeResourceStream}
-         * will fill in the density associated with the resource.  The other
-         * functions will leave it as-is and no density will be applied.
-         *
-         * @see #inTargetDensity
-         * @see #inScreenDensity
-         * @see #inScaled
-         * @see Bitmap#setDensity(int)
-         * @see android.util.DisplayMetrics#densityDpi
-         */
-        public int inDensity;
-
-        /**
-         * The pixel density of the destination this bitmap will be drawn to.
-         * This is used in conjunction with {@link #inDensity} and
-         * {@link #inScaled} to determine if and how to scale the bitmap before
-         * returning it.
-         *
-         * <p>If this is 0,
-         * {@link BitmapFactory#decodeResource(Resources, int)},
-         * {@link BitmapFactory#decodeResource(Resources, int, android.graphics.BitmapFactory.Options)},
-         * and {@link BitmapFactory#decodeResourceStream}
-         * will fill in the density associated the Resources object's
-         * DisplayMetrics.  The other
-         * functions will leave it as-is and no scaling for density will be
-         * performed.
-         *
-         * @see #inDensity
-         * @see #inScreenDensity
-         * @see #inScaled
-         * @see android.util.DisplayMetrics#densityDpi
-         */
-        public int inTargetDensity;
-
-        /**
-         * The pixel density of the actual screen that is being used.  This is
-         * purely for applications running in density compatibility code, where
-         * {@link #inTargetDensity} is actually the density the application
-         * sees rather than the real screen density.
-         *
-         * <p>By setting this, you
-         * allow the loading code to avoid scaling a bitmap that is currently
-         * in the screen density up/down to the compatibility density.  Instead,
-         * if {@link #inDensity} is the same as {@link #inScreenDensity}, the
-         * bitmap will be left as-is.  Anything using the resulting bitmap
-         * must also used {@link Bitmap#getScaledWidth(int)
-         * Bitmap.getScaledWidth} and {@link Bitmap#getScaledHeight
-         * Bitmap.getScaledHeight} to account for any different between the
-         * bitmap's density and the target's density.
-         *
-         * <p>This is never set automatically for the caller by
-         * {@link BitmapFactory} itself.  It must be explicitly set, since the
-         * caller must deal with the resulting bitmap in a density-aware way.
-         *
-         * @see #inDensity
-         * @see #inTargetDensity
-         * @see #inScaled
-         * @see android.util.DisplayMetrics#densityDpi
-         */
-        public int inScreenDensity;
-
-        /**
-         * When this flag is set, if {@link #inDensity} and
-         * {@link #inTargetDensity} are not 0, the
-         * bitmap will be scaled to match {@link #inTargetDensity} when loaded,
-         * rather than relying on the graphics system scaling it each time it
-         * is drawn to a Canvas.
-         *
-         * <p>This flag is turned on by default and should be turned off if you need
-         * a non-scaled version of the bitmap.  Nine-patch bitmaps ignore this
-         * flag and are always scaled.
-         */
-        public boolean inScaled;
-
-        /**
-         * If this is set to true, then the resulting bitmap will allocate its
-         * pixels such that they can be purged if the system needs to reclaim
-         * memory. In that instance, when the pixels need to be accessed again
-         * (e.g. the bitmap is drawn, getPixels() is called), they will be
-         * automatically re-decoded.
-         *
-         * For the re-decode to happen, the bitmap must have access to the
-         * encoded data, either by sharing a reference to the input
-         * or by making a copy of it. This distinction is controlled by
-         * inInputShareable. If this is true, then the bitmap may keep a shallow
-         * reference to the input. If this is false, then the bitmap will
-         * explicitly make a copy of the input data, and keep that. Even if
-         * sharing is allowed, the implementation may still decide to make a
-         * deep copy of the input data.
-         */
-        public boolean inPurgeable;
-
-        /**
-         * This field works in conjuction with inPurgeable. If inPurgeable is
-         * false, then this field is ignored. If inPurgeable is true, then this
-         * field determines whether the bitmap can share a reference to the
-         * input data (inputstream, array, etc.) or if it must make a deep copy.
-         */
-        public boolean inInputShareable;
-
-        /**
-         * Normally bitmap allocations count against the dalvik heap, which
-         * means they help trigger GCs when a lot have been allocated. However,
-         * in rare cases, the caller may want to allocate the bitmap outside of
-         * that heap. To request that, set inNativeAlloc to true. In these
-         * rare instances, it is solely up to the caller to ensure that OOM is
-         * managed explicitly by calling bitmap.recycle() as soon as such a
-         * bitmap is no longer needed.
-         *
-         * @hide pending API council approval
-         */
-        public boolean inNativeAlloc;
-
-        /**
-         * The resulting width of the bitmap, set independent of the state of
-         * inJustDecodeBounds. However, if there is an error trying to decode,
-         * outWidth will be set to -1.
-         */
-        public int outWidth;
-
-        /**
-         * The resulting height of the bitmap, set independent of the state of
-         * inJustDecodeBounds. However, if there is an error trying to decode,
-         * outHeight will be set to -1.
-         */
-        public int outHeight;
-
-        /**
-         * If known, this string is set to the mimetype of the decoded image.
-         * If not know, or there is an error, it is set to null.
-         */
-        public String outMimeType;
-
-        /**
-         * Temp storage to use for decoding.  Suggest 16K or so.
-         */
-        public byte[] inTempStorage;
-
-        private native void requestCancel();
-
-        /**
-         * Flag to indicate that cancel has been called on this object.  This
-         * is useful if there's an intermediary that wants to first decode the
-         * bounds and then decode the image.  In that case the intermediary
-         * can check, inbetween the bounds decode and the image decode, to see
-         * if the operation is canceled.
-         */
-        public boolean mCancel;
-
-        /**
-         *  This can be called from another thread while this options object is
-         *  inside a decode... call. Calling this will notify the decoder that
-         *  it should cancel its operation. This is not guaranteed to cancel
-         *  the decode, but if it does, the decoder... operation will return
-         *  null, or if inJustDecodeBounds is true, will set outWidth/outHeight
-         *  to -1
-         */
-        public void requestCancelDecode() {
-            mCancel = true;
-            requestCancel();
-        }
-    }
-
-    /**
-     * Decode a file path into a bitmap. If the specified file name is null,
-     * or cannot be decoded into a bitmap, the function returns null.
-     *
-     * @param pathName complete path name for the file to be decoded.
-     * @param opts null-ok; Options that control downsampling and whether the
-     *             image should be completely decoded, or just is size returned.
-     * @return The decoded bitmap, or null if the image data could not be
-     *         decoded, or, if opts is non-null, if opts requested only the
-     *         size be returned (in opts.outWidth and opts.outHeight)
-     */
-    public static Bitmap decodeFile(String pathName, Options opts) {
-        Bitmap bm = null;
-        InputStream stream = null;
-        try {
-            stream = new FileInputStream(pathName);
-            bm = decodeStream(stream, null, opts);
-        } catch (Exception e) {
-            /*  do nothing.
-                If the exception happened on open, bm will be null.
-            */
-        } finally {
-            if (stream != null) {
-                try {
-                    stream.close();
-                } catch (IOException e) {
-                    // do nothing here
-                }
-            }
-        }
-        return bm;
-    }
-
-    /**
-     * Decode a file path into a bitmap. If the specified file name is null,
-     * or cannot be decoded into a bitmap, the function returns null.
-     *
-     * @param pathName complete path name for the file to be decoded.
-     * @return the resulting decoded bitmap, or null if it could not be decoded.
-     */
-    public static Bitmap decodeFile(String pathName) {
-        return decodeFile(pathName, null);
-    }
-
-    /**
-     * Decode a new Bitmap from an InputStream. This InputStream was obtained from
-     * resources, which we pass to be able to scale the bitmap accordingly.
-     */
-    public static Bitmap decodeResourceStream(Resources res, TypedValue value,
-            InputStream is, Rect pad, Options opts) {
-
-        if (opts == null) {
-            opts = new Options();
-        }
-
-        if (opts.inDensity == 0 && value != null) {
-            final int density = value.density;
-            if (density == TypedValue.DENSITY_DEFAULT) {
-                opts.inDensity = DisplayMetrics.DENSITY_DEFAULT;
-            } else if (density != TypedValue.DENSITY_NONE) {
-                opts.inDensity = density;
-            }
-        }
-
-        if (opts.inTargetDensity == 0 && res != null) {
-            opts.inTargetDensity = res.getDisplayMetrics().densityDpi;
-        }
-
-        return decodeStream(is, pad, opts);
-    }
-
-    /**
-     * Synonym for opening the given resource and calling
-     * {@link #decodeResourceStream}.
-     *
-     * @param res   The resources object containing the image data
-     * @param id The resource id of the image data
-     * @param opts null-ok; Options that control downsampling and whether the
-     *             image should be completely decoded, or just is size returned.
-     * @return The decoded bitmap, or null if the image data could not be
-     *         decoded, or, if opts is non-null, if opts requested only the
-     *         size be returned (in opts.outWidth and opts.outHeight)
-     */
-    public static Bitmap decodeResource(Resources res, int id, Options opts) {
-        Bitmap bm = null;
-        InputStream is = null;
-
-        try {
-            final TypedValue value = new TypedValue();
-            is = res.openRawResource(id, value);
-
-            bm = decodeResourceStream(res, value, is, null, opts);
-        } catch (Exception e) {
-            /*  do nothing.
-                If the exception happened on open, bm will be null.
-                If it happened on close, bm is still valid.
-            */
-        } finally {
-            try {
-                if (is != null) is.close();
-            } catch (IOException e) {
-                // Ignore
-            }
-        }
-
-        return bm;
-    }
-
-    /**
-     * Synonym for {@link #decodeResource(Resources, int, android.graphics.BitmapFactory.Options)}
-     * will null Options.
-     *
-     * @param res The resources object containing the image data
-     * @param id The resource id of the image data
-     * @return The decoded bitmap, or null if the image could not be decode.
-     */
-    public static Bitmap decodeResource(Resources res, int id) {
-        return decodeResource(res, id, null);
-    }
-
-    /**
-     * Decode an immutable bitmap from the specified byte array.
-     *
-     * @param data byte array of compressed image data
-     * @param offset offset into imageData for where the decoder should begin
-     *               parsing.
-     * @param length the number of bytes, beginning at offset, to parse
-     * @param opts null-ok; Options that control downsampling and whether the
-     *             image should be completely decoded, or just is size returned.
-     * @return The decoded bitmap, or null if the image data could not be
-     *         decoded, or, if opts is non-null, if opts requested only the
-     *         size be returned (in opts.outWidth and opts.outHeight)
-     */
-    public static Bitmap decodeByteArray(byte[] data, int offset, int length, Options opts) {
-        if ((offset | length) < 0 || data.length < offset + length) {
-            throw new ArrayIndexOutOfBoundsException();
-        }
-
-        // FIXME: implement as needed, but it's unlikely that this is needed in the context of the bridge.
-        return null;
-        //return nativeDecodeByteArray(data, offset, length, opts);
-    }
-
-    /**
-     * Decode an immutable bitmap from the specified byte array.
-     *
-     * @param data byte array of compressed image data
-     * @param offset offset into imageData for where the decoder should begin
-     *               parsing.
-     * @param length the number of bytes, beginning at offset, to parse
-     * @return The decoded bitmap, or null if the image could not be decode.
-     */
-    public static Bitmap decodeByteArray(byte[] data, int offset, int length) {
-        return decodeByteArray(data, offset, length, null);
-    }
-
-    /**
-     * Decode an input stream into a bitmap. If the input stream is null, or
-     * cannot be used to decode a bitmap, the function returns null.
-     * The stream's position will be where ever it was after the encoded data
-     * was read.
-     *
-     * @param is The input stream that holds the raw data to be decoded into a
-     *           bitmap.
-     * @param outPadding If not null, return the padding rect for the bitmap if
-     *                   it exists, otherwise set padding to [-1,-1,-1,-1]. If
-     *                   no bitmap is returned (null) then padding is
-     *                   unchanged.
-     * @param opts null-ok; Options that control downsampling and whether the
-     *             image should be completely decoded, or just is size returned.
-     * @return The decoded bitmap, or null if the image data could not be
-     *         decoded, or, if opts is non-null, if opts requested only the
-     *         size be returned (in opts.outWidth and opts.outHeight)
-     */
-    public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts) {
-        // we don't throw in this case, thus allowing the caller to only check
-        // the cache, and not force the image to be decoded.
-        if (is == null) {
-            return null;
-        }
-
-        // we need mark/reset to work properly
-
-        if (!is.markSupported()) {
-            is = new BufferedInputStream(is, 16 * 1024);
-        }
-
-        // so we can call reset() if a given codec gives up after reading up to
-        // this many bytes. FIXME: need to find out from the codecs what this
-        // value should be.
-        is.mark(1024);
-
-        Bitmap  bm;
-
-        if (is instanceof AssetManager.AssetInputStream) {
-            // FIXME: log this.
-            return null;
-        } else {
-            // pass some temp storage down to the native code. 1024 is made up,
-            // but should be large enough to avoid too many small calls back
-            // into is.read(...) This number is not related to the value passed
-            // to mark(...) above.
-            try {
-                bm = new Bitmap(is);
-            } catch (IOException e) {
-                return null;
-            }
-        }
-
-        return finishDecode(bm, outPadding, opts);
-    }
-
-    private static Bitmap finishDecode(Bitmap bm, Rect outPadding, Options opts) {
-        if (bm == null || opts == null) {
-            return bm;
-        }
-
-        final int density = opts.inDensity;
-        if (density == 0) {
-            return bm;
-        }
-
-        bm.setDensity(density);
-        final int targetDensity = opts.inTargetDensity;
-        if (targetDensity == 0 || density == targetDensity
-                || density == opts.inScreenDensity) {
-            return bm;
-        }
-
-        byte[] np = bm.getNinePatchChunk();
-        final boolean isNinePatch = false; //np != null && NinePatch.isNinePatchChunk(np);
-        if (opts.inScaled || isNinePatch) {
-            float scale = targetDensity / (float)density;
-            // TODO: This is very inefficient and should be done in native by Skia
-            final Bitmap oldBitmap = bm;
-            bm = Bitmap.createScaledBitmap(oldBitmap, (int) (bm.getWidth() * scale + 0.5f),
-                    (int) (bm.getHeight() * scale + 0.5f), true);
-            oldBitmap.recycle();
-
-            if (isNinePatch) {
-                //np = nativeScaleNinePatch(np, scale, outPadding);
-                bm.setNinePatchChunk(np);
-            }
-            bm.setDensity(targetDensity);
-        }
-
-        return bm;
-    }
-
-    /**
-     * Decode an input stream into a bitmap. If the input stream is null, or
-     * cannot be used to decode a bitmap, the function returns null.
-     * The stream's position will be where ever it was after the encoded data
-     * was read.
-     *
-     * @param is The input stream that holds the raw data to be decoded into a
-     *           bitmap.
-     * @return The decoded bitmap, or null if the image data could not be
-     *         decoded, or, if opts is non-null, if opts requested only the
-     *         size be returned (in opts.outWidth and opts.outHeight)
-     */
-    public static Bitmap decodeStream(InputStream is) {
-        return decodeStream(is, null, null);
-    }
-
-    /**
-     * Decode a bitmap from the file descriptor. If the bitmap cannot be decoded
-     * return null. The position within the descriptor will not be changed when
-     * this returns, so the descriptor can be used again as-is.
-     *
-     * @param fd The file descriptor containing the bitmap data to decode
-     * @param outPadding If not null, return the padding rect for the bitmap if
-     *                   it exists, otherwise set padding to [-1,-1,-1,-1]. If
-     *                   no bitmap is returned (null) then padding is
-     *                   unchanged.
-     * @param opts null-ok; Options that control downsampling and whether the
-     *             image should be completely decoded, or just is size returned.
-     * @return the decoded bitmap, or null
-     */
-    public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts) {
-        return null;
-
-        /* FIXME: implement as needed
-        try {
-            if (MemoryFile.isMemoryFile(fd)) {
-                int mappedlength = MemoryFile.getMappedSize(fd);
-                MemoryFile file = new MemoryFile(fd, mappedlength, "r");
-                InputStream is = file.getInputStream();
-                Bitmap bm = decodeStream(is, outPadding, opts);
-                return finishDecode(bm, outPadding, opts);
-            }
-        } catch (IOException ex) {
-            // invalid filedescriptor, no need to call nativeDecodeFileDescriptor()
-            return null;
-        }
-        //Bitmap bm = nativeDecodeFileDescriptor(fd, outPadding, opts);
-        //return finishDecode(bm, outPadding, opts);
-        */
-    }
-
-    /**
-     * Decode a bitmap from the file descriptor. If the bitmap cannot be decoded
-     * return null. The position within the descriptor will not be changed when
-     * this returns, so the descriptor can be used again as is.
-     *
-     * @param fd The file descriptor containing the bitmap data to decode
-     * @return the decoded bitmap, or null
-     */
-    public static Bitmap decodeFileDescriptor(FileDescriptor fd) {
-        return decodeFileDescriptor(fd, null, null);
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
new file mode 100644
index 0000000..9c86e80
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.android.BridgeResources.NinePatchInputStream;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.ninepatch.NinePatchChunk;
+import com.android.resources.Density;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.graphics.BitmapFactory.Options;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Delegate implementing the native methods of android.graphics.BitmapFactory
+ *
+ * Through the layoutlib_create tool, the original native methods of BitmapFactory have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
+ * around to map int to instance of the delegate.
+ *
+ */
+/*package*/ class BitmapFactory_Delegate {
+
+    // ------ Java delegates ------
+
+    @LayoutlibDelegate
+    /*package*/ static Bitmap finishDecode(Bitmap bm, Rect outPadding, Options opts) {
+        if (bm == null || opts == null) {
+            return bm;
+        }
+
+        final int density = opts.inDensity;
+        if (density == 0) {
+            return bm;
+        }
+
+        bm.setDensity(density);
+        final int targetDensity = opts.inTargetDensity;
+        if (targetDensity == 0 || density == targetDensity || density == opts.inScreenDensity) {
+            return bm;
+        }
+
+        byte[] np = bm.getNinePatchChunk();
+        final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np);
+        // DELEGATE CHANGE: never scale 9-patch
+        if (opts.inScaled && isNinePatch == false) {
+            float scale = targetDensity / (float)density;
+            // TODO: This is very inefficient and should be done in native by Skia
+            final Bitmap oldBitmap = bm;
+            bm = Bitmap.createScaledBitmap(oldBitmap, (int) (bm.getWidth() * scale + 0.5f),
+                    (int) (bm.getHeight() * scale + 0.5f), true);
+            oldBitmap.recycle();
+
+            if (isNinePatch) {
+                np = nativeScaleNinePatch(np, scale, outPadding);
+                bm.setNinePatchChunk(np);
+            }
+            bm.setDensity(targetDensity);
+        }
+
+        return bm;
+    }
+
+
+    // ------ Native Delegates ------
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeSetDefaultConfig(int nativeConfig) {
+        // pass
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage,
+            Rect padding, Options opts) {
+        Bitmap bm = null;
+
+        Density density = Density.MEDIUM;
+        if (opts != null) {
+            density = Density.getEnum(opts.inDensity);
+        }
+
+        try {
+            if (is instanceof NinePatchInputStream) {
+                NinePatchInputStream npis = (NinePatchInputStream) is;
+                npis.disableFakeMarkSupport();
+
+                // load the bitmap as a nine patch
+                com.android.ninepatch.NinePatch ninePatch = com.android.ninepatch.NinePatch.load(
+                        npis, true /*is9Patch*/, false /*convert*/);
+
+                // get the bitmap and chunk objects.
+                bm = Bitmap_Delegate.createBitmap(ninePatch.getImage(), true /*isMutable*/,
+                        density);
+                NinePatchChunk chunk = ninePatch.getChunk();
+
+                // put the chunk in the bitmap
+                bm.setNinePatchChunk(NinePatch_Delegate.serialize(chunk));
+
+                // read the padding
+                int[] paddingarray = chunk.getPadding();
+                padding.left = paddingarray[0];
+                padding.top = paddingarray[1];
+                padding.right = paddingarray[2];
+                padding.bottom = paddingarray[3];
+            } else {
+                // load the bitmap directly.
+                bm = Bitmap_Delegate.createBitmap(is, true, density);
+            }
+        } catch (IOException e) {
+            Bridge.getLog().error(null,"Failed to load image" , e, null);
+        }
+
+        return bm;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
+            Rect padding, Options opts) {
+        return null;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts) {
+        return null;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static Bitmap nativeDecodeByteArray(byte[] data, int offset,
+            int length, Options opts) {
+        return null;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static byte[] nativeScaleNinePatch(byte[] chunk, float scale, Rect pad) {
+        // don't scale for now. This should not be called anyway since we re-implement
+        // BitmapFactory.finishDecode();
+        return chunk;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapShader.java b/tools/layoutlib/bridge/src/android/graphics/BitmapShader.java
deleted file mode 100644
index ad3974c..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapShader.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import java.awt.Paint;
-
-public class BitmapShader extends Shader {
-
-    // we hold on just for the GC, since our native counterpart is using it
-    private final Bitmap mBitmap;
-
-    /**
-     * Call this to create a new shader that will draw with a bitmap.
-     *
-     * @param bitmap            The bitmap to use inside the shader
-     * @param tileX             The tiling mode for x to draw the bitmap in.
-     * @param tileY             The tiling mode for y to draw the bitmap in.
-     */
-    public BitmapShader(Bitmap bitmap, TileMode tileX, TileMode tileY) {
-        mBitmap = bitmap;
-    }
-
-    //---------- Custom methods
-
-    public Bitmap getBitmap() {
-        return mBitmap;
-    }
-
-    @Override
-    Paint getJavaPaint() {
-        return null;
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
new file mode 100644
index 0000000..8eb0693
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.graphics.Shader.TileMode;
+
+/**
+ * Delegate implementing the native methods of android.graphics.BitmapShader
+ *
+ * Through the layoutlib_create tool, the original native methods of BitmapShader have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original BitmapShader class.
+ *
+ * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
+ * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
+ *
+ * @see Shader_Delegate
+ *
+ */
+public class BitmapShader_Delegate extends Shader_Delegate {
+
+    // ---- delegate data ----
+    private java.awt.Paint mJavaPaint;
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public java.awt.Paint getJavaPaint() {
+        return mJavaPaint;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return true;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        // no message since isSupported returns true;
+        return null;
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreate(int native_bitmap, int shaderTileModeX,
+            int shaderTileModeY) {
+        Bitmap_Delegate bitmap = Bitmap_Delegate.getDelegate(native_bitmap);
+        if (bitmap == null) {
+            return 0;
+        }
+
+        BitmapShader_Delegate newDelegate = new BitmapShader_Delegate(
+                bitmap.getImage(),
+                Shader_Delegate.getTileMode(shaderTileModeX),
+                Shader_Delegate.getTileMode(shaderTileModeY));
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+
+    private BitmapShader_Delegate(java.awt.image.BufferedImage image,
+            TileMode tileModeX, TileMode tileModeY) {
+        mJavaPaint = new BitmapShaderPaint(image, tileModeX, tileModeY);
+    }
+
+    private class BitmapShaderPaint implements java.awt.Paint {
+        private final java.awt.image.BufferedImage mImage;
+        private final TileMode mTileModeX;
+        private final TileMode mTileModeY;
+
+        BitmapShaderPaint(java.awt.image.BufferedImage image,
+                TileMode tileModeX, TileMode tileModeY) {
+            mImage = image;
+            mTileModeX = tileModeX;
+            mTileModeY = tileModeY;
+        }
+
+        public java.awt.PaintContext createContext(
+                java.awt.image.ColorModel      colorModel,
+                java.awt.Rectangle             deviceBounds,
+                java.awt.geom.Rectangle2D      userBounds,
+                java.awt.geom.AffineTransform  xform,
+                java.awt.RenderingHints        hints) {
+
+            java.awt.geom.AffineTransform canvasMatrix;
+            try {
+                canvasMatrix = xform.createInverse();
+            } catch (java.awt.geom.NoninvertibleTransformException e) {
+                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
+                        "Unable to inverse matrix in BitmapShader", e, null /*data*/);
+                canvasMatrix = new java.awt.geom.AffineTransform();
+            }
+
+            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
+            try {
+                localMatrix = localMatrix.createInverse();
+            } catch (java.awt.geom.NoninvertibleTransformException e) {
+                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
+                        "Unable to inverse matrix in BitmapShader", e, null /*data*/);
+                localMatrix = new java.awt.geom.AffineTransform();
+            }
+
+            return new BitmapShaderContext(canvasMatrix, localMatrix, colorModel);
+        }
+
+        private class BitmapShaderContext implements java.awt.PaintContext {
+
+            private final java.awt.geom.AffineTransform mCanvasMatrix;
+            private final java.awt.geom.AffineTransform mLocalMatrix;
+            private final java.awt.image.ColorModel mColorModel;
+
+            public BitmapShaderContext(
+                    java.awt.geom.AffineTransform canvasMatrix,
+                    java.awt.geom.AffineTransform localMatrix,
+                    java.awt.image.ColorModel colorModel) {
+                mCanvasMatrix = canvasMatrix;
+                mLocalMatrix = localMatrix;
+                mColorModel = colorModel;
+            }
+
+            public void dispose() {
+            }
+
+            public java.awt.image.ColorModel getColorModel() {
+                return mColorModel;
+            }
+
+            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
+                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
+                        java.awt.image.BufferedImage.TYPE_INT_ARGB);
+
+                int[] data = new int[w*h];
+
+                int index = 0;
+                float[] pt1 = new float[2];
+                float[] pt2 = new float[2];
+                for (int iy = 0 ; iy < h ; iy++) {
+                    for (int ix = 0 ; ix < w ; ix++) {
+                        // handle the canvas transform
+                        pt1[0] = x + ix;
+                        pt1[1] = y + iy;
+                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
+
+                        // handle the local matrix.
+                        pt1[0] = pt2[0];
+                        pt1[1] = pt2[1];
+                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
+
+                        data[index++] = getColor(pt2[0], pt2[1]);
+                    }
+                }
+
+                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
+
+                return image.getRaster();
+            }
+        }
+
+        /**
+         * Returns a color for an arbitrary point.
+         */
+        private int getColor(float fx, float fy) {
+            int x = getCoordinate(Math.round(fx), mImage.getWidth(), mTileModeX);
+            int y = getCoordinate(Math.round(fy), mImage.getHeight(), mTileModeY);
+
+            return mImage.getRGB(x, y);
+        }
+
+        private int getCoordinate(int i, int size, TileMode mode) {
+            if (i < 0) {
+                switch (mode) {
+                    case CLAMP:
+                        i = 0;
+                        break;
+                    case REPEAT:
+                        i = size - 1 - (-i % size);
+                        break;
+                    case MIRROR:
+                        // this is the same as the positive side, just make the value positive
+                        // first.
+                        i = -i;
+                        int count = i / size;
+                        i = i % size;
+
+                        if ((count % 2) == 1) {
+                            i = size - 1 - i;
+                        }
+                        break;
+                }
+            } else if (i >= size) {
+                switch (mode) {
+                    case CLAMP:
+                        i = size - 1;
+                        break;
+                    case REPEAT:
+                        i = i % size;
+                        break;
+                    case MIRROR:
+                        int count = i / size;
+                        i = i % size;
+
+                        if ((count % 2) == 1) {
+                            i = size - 1 - i;
+                        }
+                        break;
+                }
+            }
+
+            return i;
+        }
+
+
+        public int getTransparency() {
+            return java.awt.Paint.TRANSLUCENT;
+        }
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
new file mode 100644
index 0000000..87c3eb6
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
@@ -0,0 +1,542 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.resources.Density;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.os.Parcel;
+
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.Buffer;
+import java.util.Arrays;
+
+import javax.imageio.ImageIO;
+
+/**
+ * Delegate implementing the native methods of android.graphics.Bitmap
+ *
+ * Through the layoutlib_create tool, the original native methods of Bitmap have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original Bitmap class.
+ *
+ * @see DelegateManager
+ *
+ */
+public final class Bitmap_Delegate {
+
+    // ---- delegate manager ----
+    private static final DelegateManager<Bitmap_Delegate> sManager =
+            new DelegateManager<Bitmap_Delegate>(Bitmap_Delegate.class);
+
+    // ---- delegate helper data ----
+
+    // ---- delegate data ----
+    private final Config mConfig;
+    private BufferedImage mImage;
+    private boolean mHasAlpha = true;
+
+    // ---- Public Helper methods ----
+
+    /**
+     * Returns the native delegate associated to a given {@link Bitmap_Delegate} object.
+     */
+    public static Bitmap_Delegate getDelegate(Bitmap bitmap) {
+        return sManager.getDelegate(bitmap.mNativeBitmap);
+    }
+
+    /**
+     * Returns the native delegate associated to a given an int referencing a {@link Bitmap} object.
+     */
+    public static Bitmap_Delegate getDelegate(int native_bitmap) {
+        return sManager.getDelegate(native_bitmap);
+    }
+
+    /**
+     * Creates and returns a {@link Bitmap} initialized with the given file content.
+     *
+     * @param input the file from which to read the bitmap content
+     * @param isMutable whether the bitmap is mutable
+     * @param density the density associated with the bitmap
+     *
+     * @see Bitmap#isMutable()
+     * @see Bitmap#getDensity()
+     */
+    public static Bitmap createBitmap(File input, boolean isMutable, Density density)
+            throws IOException {
+        // create a delegate with the content of the file.
+        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
+
+        return createBitmap(delegate, isMutable, density.getDpiValue());
+    }
+
+    /**
+     * Creates and returns a {@link Bitmap} initialized with the given stream content.
+     *
+     * @param input the stream from which to read the bitmap content
+     * @param isMutable whether the bitmap is mutable
+     * @param density the density associated with the bitmap
+     *
+     * @see Bitmap#isMutable()
+     * @see Bitmap#getDensity()
+     */
+    public static Bitmap createBitmap(InputStream input, boolean isMutable, Density density)
+            throws IOException {
+        // create a delegate with the content of the stream.
+        Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
+
+        return createBitmap(delegate, isMutable, density.getDpiValue());
+    }
+
+    /**
+     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
+     *
+     * @param image the bitmap content
+     * @param isMutable whether the bitmap is mutable
+     * @param density the density associated with the bitmap
+     *
+     * @see Bitmap#isMutable()
+     * @see Bitmap#getDensity()
+     */
+    public static Bitmap createBitmap(BufferedImage image, boolean isMutable,
+            Density density) throws IOException {
+        // create a delegate with the given image.
+        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888);
+
+        return createBitmap(delegate, isMutable, density.getDpiValue());
+    }
+
+    /**
+     * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}.
+     */
+    public static BufferedImage getImage(Bitmap bitmap) {
+        // get the delegate from the native int.
+        Bitmap_Delegate delegate = sManager.getDelegate(bitmap.mNativeBitmap);
+        if (delegate == null) {
+            return null;
+        }
+
+        return delegate.mImage;
+    }
+
+    public static int getBufferedImageType(int nativeBitmapConfig) {
+        switch (Config.sConfigs[nativeBitmapConfig]) {
+            case ALPHA_8:
+                return BufferedImage.TYPE_INT_ARGB;
+            case RGB_565:
+                return BufferedImage.TYPE_INT_ARGB;
+            case ARGB_4444:
+                return BufferedImage.TYPE_INT_ARGB;
+            case ARGB_8888:
+                return BufferedImage.TYPE_INT_ARGB;
+        }
+
+        return BufferedImage.TYPE_INT_ARGB;
+    }
+
+    /**
+     * Returns the {@link BufferedImage} used by the delegate of the given {@link Bitmap}.
+     */
+    public BufferedImage getImage() {
+        return mImage;
+    }
+
+    /**
+     * Returns the Android bitmap config. Note that this not the config of the underlying
+     * Java2D bitmap.
+     */
+    public Config getConfig() {
+        return mConfig;
+    }
+
+    /**
+     * Returns the hasAlpha rendering hint
+     * @return true if the bitmap alpha should be used at render time
+     */
+    public boolean hasAlpha() {
+        return mHasAlpha && mConfig != Config.RGB_565;
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width,
+            int height, int nativeConfig, boolean mutable) {
+        int imageType = getBufferedImageType(nativeConfig);
+
+        // create the image
+        BufferedImage image = new BufferedImage(width, height, imageType);
+
+        if (colors != null) {
+            image.setRGB(0, 0, width, height, colors, offset, stride);
+        }
+
+        // create a delegate with the content of the stream.
+        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.sConfigs[nativeConfig]);
+
+        return createBitmap(delegate, mutable, Bitmap.getDefaultDensity());
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static Bitmap nativeCopy(int srcBitmap, int nativeConfig, boolean isMutable) {
+        Bitmap_Delegate srcBmpDelegate = sManager.getDelegate(srcBitmap);
+        if (srcBmpDelegate == null) {
+            return null;
+        }
+
+        BufferedImage srcImage = srcBmpDelegate.getImage();
+
+        int width = srcImage.getWidth();
+        int height = srcImage.getHeight();
+
+        int imageType = getBufferedImageType(nativeConfig);
+
+        // create the image
+        BufferedImage image = new BufferedImage(width, height, imageType);
+
+        // copy the source image into the image.
+        int[] argb = new int[width * height];
+        srcImage.getRGB(0, 0, width, height, argb, 0, width);
+        image.setRGB(0, 0, width, height, argb, 0, width);
+
+        // create a delegate with the content of the stream.
+        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.sConfigs[nativeConfig]);
+
+        return createBitmap(delegate, isMutable, Bitmap.getDefaultDensity());
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeDestructor(int nativeBitmap) {
+        sManager.removeJavaReferenceFor(nativeBitmap);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeRecycle(int nativeBitmap) {
+        sManager.removeJavaReferenceFor(nativeBitmap);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nativeCompress(int nativeBitmap, int format, int quality,
+            OutputStream stream, byte[] tempStorage) {
+        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+                "Bitmap.compress() is not supported", null /*data*/);
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeErase(int nativeBitmap, int color) {
+        // get the delegate from the native int.
+        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
+        if (delegate == null) {
+            return;
+        }
+
+        BufferedImage image = delegate.mImage;
+
+        Graphics2D g = image.createGraphics();
+        try {
+            g.setColor(new java.awt.Color(color, true));
+
+            g.fillRect(0, 0, image.getWidth(), image.getHeight());
+        } finally {
+            g.dispose();
+        }
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeWidth(int nativeBitmap) {
+        // get the delegate from the native int.
+        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
+        if (delegate == null) {
+            return 0;
+        }
+
+        return delegate.mImage.getWidth();
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeHeight(int nativeBitmap) {
+        // get the delegate from the native int.
+        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
+        if (delegate == null) {
+            return 0;
+        }
+
+        return delegate.mImage.getHeight();
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeRowBytes(int nativeBitmap) {
+        // get the delegate from the native int.
+        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
+        if (delegate == null) {
+            return 0;
+        }
+
+        return delegate.mImage.getWidth();
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeConfig(int nativeBitmap) {
+        // get the delegate from the native int.
+        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
+        if (delegate == null) {
+            return 0;
+        }
+
+        return delegate.mConfig.nativeInt;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nativeHasAlpha(int nativeBitmap) {
+        // get the delegate from the native int.
+        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
+        if (delegate == null) {
+            return true;
+        }
+
+        return delegate.mHasAlpha;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeGetPixel(int nativeBitmap, int x, int y) {
+        // get the delegate from the native int.
+        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
+        if (delegate == null) {
+            return 0;
+        }
+
+        return delegate.mImage.getRGB(x, y);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeGetPixels(int nativeBitmap, int[] pixels, int offset,
+            int stride, int x, int y, int width, int height) {
+        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
+        if (delegate == null) {
+            return;
+        }
+
+        delegate.getImage().getRGB(x, y, width, height, pixels, offset, stride);
+    }
+
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeSetPixel(int nativeBitmap, int x, int y, int color) {
+        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
+        if (delegate == null) {
+            return;
+        }
+
+        delegate.getImage().setRGB(x, y, color);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeSetPixels(int nativeBitmap, int[] colors, int offset,
+            int stride, int x, int y, int width, int height) {
+        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
+        if (delegate == null) {
+            return;
+        }
+
+        delegate.getImage().setRGB(x, y, width, height, colors, offset, stride);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeCopyPixelsToBuffer(int nativeBitmap, Buffer dst) {
+        // FIXME implement native delegate
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Bitmap.copyPixelsToBuffer is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeCopyPixelsFromBuffer(int nb, Buffer src) {
+        // FIXME implement native delegate
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Bitmap.copyPixelsFromBuffer is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static Bitmap nativeCreateFromParcel(Parcel p) {
+        // This is only called by Bitmap.CREATOR (Parcelable.Creator<Bitmap>), which is only
+        // used during aidl call so really this should not be called.
+        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+                "AIDL is not suppored, and therefore Bitmaps cannot be created from parcels.",
+                null /*data*/);
+        return null;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nativeWriteToParcel(int nativeBitmap, boolean isMutable,
+            int density, Parcel p) {
+        // This is only called when sending a bitmap through aidl, so really this should not
+        // be called.
+        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+                "AIDL is not suppored, and therefore Bitmaps cannot be written to parcels.",
+                null /*data*/);
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static Bitmap nativeExtractAlpha(int nativeBitmap, int nativePaint,
+            int[] offsetXY) {
+        Bitmap_Delegate bitmap = sManager.getDelegate(nativeBitmap);
+        if (bitmap == null) {
+            return null;
+        }
+
+        // get the paint which can be null if nativePaint is 0.
+        Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint);
+
+        if (paint != null && paint.getMaskFilter() != null) {
+            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
+                    "MaskFilter not supported in Bitmap.extractAlpha",
+                    null, null /*data*/);
+        }
+
+        int alpha = paint != null ? paint.getAlpha() : 0xFF;
+        BufferedImage image = createCopy(bitmap.getImage(), BufferedImage.TYPE_INT_ARGB, alpha);
+
+        // create the delegate. The actual Bitmap config is only an alpha channel
+        Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ALPHA_8);
+
+        // the density doesn't matter, it's set by the Java method.
+        return createBitmap(delegate, false /*isMutable*/,
+                Density.DEFAULT_DENSITY /*density*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativePrepareToDraw(int nativeBitmap) {
+        // nothing to be done here.
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeSetHasAlpha(int nativeBitmap, boolean hasAlpha) {
+        // get the delegate from the native int.
+        Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
+        if (delegate == null) {
+            return;
+        }
+
+        delegate.mHasAlpha = hasAlpha;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nativeSameAs(int nb0, int nb1) {
+        Bitmap_Delegate delegate1 = sManager.getDelegate(nb0);
+        if (delegate1 == null) {
+            return false;
+        }
+
+        Bitmap_Delegate delegate2 = sManager.getDelegate(nb1);
+        if (delegate2 == null) {
+            return false;
+        }
+
+        BufferedImage image1 = delegate1.getImage();
+        BufferedImage image2 = delegate2.getImage();
+        if (delegate1.mConfig != delegate2.mConfig ||
+                image1.getWidth() != image2.getWidth() ||
+                image1.getHeight() != image2.getHeight()) {
+            return false;
+        }
+
+        // get the internal data
+        int w = image1.getWidth();
+        int h = image2.getHeight();
+        int[] argb1 = new int[w*h];
+        int[] argb2 = new int[w*h];
+
+        image1.getRGB(0, 0, w, h, argb1, 0, w);
+        image2.getRGB(0, 0, w, h, argb2, 0, w);
+
+        // compares
+        if (delegate1.mConfig == Config.ALPHA_8) {
+            // in this case we have to manually compare the alpha channel as the rest is garbage.
+            final int length = w*h;
+            for (int i = 0 ; i < length ; i++) {
+                if ((argb1[i] & 0xFF000000) != (argb2[i] & 0xFF000000)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        return Arrays.equals(argb1, argb2);
+    }
+
+    // ---- Private delegate/helper methods ----
+
+    private Bitmap_Delegate(BufferedImage image, Config config) {
+        mImage = image;
+        mConfig = config;
+    }
+
+    private static Bitmap createBitmap(Bitmap_Delegate delegate, boolean isMutable, int density) {
+        // get its native_int
+        int nativeInt = sManager.addNewDelegate(delegate);
+
+        // and create/return a new Bitmap with it
+        return new Bitmap(nativeInt, isMutable, null /*ninePatchChunk*/, density);
+    }
+
+    /**
+     * Creates and returns a copy of a given BufferedImage.
+     * <p/>
+     * if alpha is different than 255, then it is applied to the alpha channel of each pixel.
+     *
+     * @param image the image to copy
+     * @param imageType the type of the new image
+     * @param alpha an optional alpha modifier
+     * @return a new BufferedImage
+     */
+    /*package*/ static BufferedImage createCopy(BufferedImage image, int imageType, int alpha) {
+        int w = image.getWidth();
+        int h = image.getHeight();
+
+        BufferedImage result = new BufferedImage(w, h, imageType);
+
+        int[] argb = new int[w * h];
+        image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth());
+
+        if (alpha != 255) {
+            final int length = argb.length;
+            for (int i = 0 ; i < length; i++) {
+                int a = (argb[i] >>> 24 * alpha) / 255;
+                argb[i] = (a << 24) | (argb[i] & 0x00FFFFFF);
+            }
+        }
+
+        result.setRGB(0, 0, w, h, argb, 0, w);
+
+        return result;
+    }
+
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java
new file mode 100644
index 0000000..4becba1
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/BlurMaskFilter_Delegate.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate implementing the native methods of android.graphics.BlurMaskFilter
+ *
+ * Through the layoutlib_create tool, the original native methods of BlurMaskFilter have
+ * been replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original BlurMaskFilter class.
+ *
+ * Because this extends {@link MaskFilter_Delegate}, there's no need to use a
+ * {@link DelegateManager}, as all the Shader classes will be added to the manager
+ * owned by {@link MaskFilter_Delegate}.
+ *
+ * @see MaskFilter_Delegate
+ *
+ */
+public class BlurMaskFilter_Delegate extends MaskFilter_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Blur Mask Filters are not supported.";
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeConstructor(float radius, int style) {
+        BlurMaskFilter_Delegate newDelegate = new BlurMaskFilter_Delegate();
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas.java b/tools/layoutlib/bridge/src/android/graphics/Canvas.java
deleted file mode 100644
index d5d315e..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas.java
+++ /dev/null
@@ -1,1279 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.api.ILayoutLog;
-
-import android.graphics.DrawFilter;
-import android.graphics.Picture;
-import android.graphics.PorterDuff;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.Region;
-import android.graphics.Xfermode;
-import android.graphics.Paint.Align;
-import android.graphics.Paint.FontInfo;
-import android.graphics.Paint.Style;
-import android.graphics.Region.Op;
-
-import java.awt.AlphaComposite;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.geom.AffineTransform;
-import java.awt.image.BufferedImage;
-import java.util.List;
-import java.util.Stack;
-
-import javax.microedition.khronos.opengles.GL;
-
-/**
- * Re-implementation of the Canvas, 100% in java on top of a BufferedImage.
- */
-public class Canvas extends _Original_Canvas {
-
-    private BufferedImage mBufferedImage;
-    private final Stack<Graphics2D> mGraphicsStack = new Stack<Graphics2D>();
-    private final ILayoutLog mLogger;
-
-    public Canvas() {
-        mLogger = null;
-        // the mBufferedImage will be taken from a bitmap in #setBitmap()
-    }
-
-    public Canvas(Bitmap bitmap) {
-        mLogger = null;
-        mBufferedImage = bitmap.getImage();
-        mGraphicsStack.push(mBufferedImage.createGraphics());
-    }
-
-    public Canvas(int nativeCanvas) {
-        mLogger = null;
-        throw new UnsupportedOperationException("Can't create Canvas(int)");
-    }
-
-    public Canvas(javax.microedition.khronos.opengles.GL gl) {
-        mLogger = null;
-        throw new UnsupportedOperationException("Can't create Canvas(javax.microedition.khronos.opengles.GL)");
-    }
-
-    // custom constructors for our use.
-    public Canvas(int width, int height, ILayoutLog logger) {
-        mLogger = logger;
-        mBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
-        mGraphicsStack.push(mBufferedImage.createGraphics());
-    }
-
-    public Canvas(int width, int height) {
-        this(width, height, null /* logger*/);
-    }
-
-    // custom mehtods
-    public BufferedImage getImage() {
-        return mBufferedImage;
-    }
-
-    public Graphics2D getGraphics2d() {
-        return mGraphicsStack.peek();
-    }
-
-    public void dispose() {
-        while (mGraphicsStack.size() > 0) {
-            mGraphicsStack.pop().dispose();
-        }
-    }
-
-    /**
-     * Creates a new {@link Graphics2D} based on the {@link Paint} parameters.
-     * <p/>The object must be disposed ({@link Graphics2D#dispose()}) after being used.
-     */
-    private Graphics2D getCustomGraphics(Paint paint) {
-        // make new one
-        Graphics2D g = getGraphics2d();
-        g = (Graphics2D)g.create();
-
-        // configure it
-        g.setColor(new Color(paint.getColor()));
-        int alpha = paint.getAlpha();
-        float falpha = alpha / 255.f;
-
-        Style style = paint.getStyle();
-        if (style == Style.STROKE || style == Style.FILL_AND_STROKE) {
-            PathEffect e = paint.getPathEffect();
-            if (e instanceof DashPathEffect) {
-                DashPathEffect dpe = (DashPathEffect)e;
-                g.setStroke(new BasicStroke(
-                        paint.getStrokeWidth(),
-                        paint.getStrokeCap().getJavaCap(),
-                        paint.getStrokeJoin().getJavaJoin(),
-                        paint.getStrokeMiter(),
-                        dpe.getIntervals(),
-                        dpe.getPhase()));
-            } else {
-                g.setStroke(new BasicStroke(
-                        paint.getStrokeWidth(),
-                        paint.getStrokeCap().getJavaCap(),
-                        paint.getStrokeJoin().getJavaJoin(),
-                        paint.getStrokeMiter()));
-            }
-        }
-
-        Xfermode xfermode = paint.getXfermode();
-        if (xfermode instanceof PorterDuffXfermode) {
-            PorterDuff.Mode mode = ((PorterDuffXfermode)xfermode).getMode();
-
-            setModeInGraphics(mode, g, falpha);
-        } else {
-            if (mLogger != null && xfermode != null) {
-                mLogger.warning(String.format(
-                        "Xfermode '%1$s' is not supported in the Layout Editor.",
-                        xfermode.getClass().getCanonicalName()));
-            }
-            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha));
-        }
-
-        Shader shader = paint.getShader();
-        if (shader != null) {
-            java.awt.Paint shaderPaint = shader.getJavaPaint();
-            if (shaderPaint != null) {
-                g.setPaint(shaderPaint);
-            } else {
-                if (mLogger != null) {
-                    mLogger.warning(String.format(
-                            "Shader '%1$s' is not supported in the Layout Editor.",
-                            shader.getClass().getCanonicalName()));
-                }
-            }
-        }
-
-        return g;
-    }
-
-    private void setModeInGraphics(PorterDuff.Mode mode, Graphics2D g, float falpha) {
-        switch (mode) {
-            case CLEAR:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, falpha));
-                break;
-            case DARKEN:
-                break;
-            case DST:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST, falpha));
-                break;
-            case DST_ATOP:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_ATOP, falpha));
-                break;
-            case DST_IN:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_IN, falpha));
-                break;
-            case DST_OUT:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OUT, falpha));
-                break;
-            case DST_OVER:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OVER, falpha));
-                break;
-            case LIGHTEN:
-                break;
-            case MULTIPLY:
-                break;
-            case SCREEN:
-                break;
-            case SRC:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, falpha));
-                break;
-            case SRC_ATOP:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, falpha));
-                break;
-            case SRC_IN:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, falpha));
-                break;
-            case SRC_OUT:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OUT, falpha));
-                break;
-            case SRC_OVER:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha));
-                break;
-            case XOR:
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.XOR, falpha));
-                break;
-        }
-    }
-
-
-    // --------------------
-    // OVERRIDEN ENUMS
-    // This is needed since we rename Canvas into _Original_Canvas
-    // --------------------
-
-    public enum EdgeType {
-        BW(0),  //!< treat edges by just rounding to nearest pixel boundary
-        AA(1);  //!< treat edges by rounding-out, since they may be antialiased
-
-        EdgeType(int nativeInt) {
-            this.nativeInt = nativeInt;
-        }
-        final int nativeInt;
-    }
-
-
-    // --------------------
-    // OVERRIDEN METHODS
-    // --------------------
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#setBitmap(android.graphics.Bitmap)
-     */
-    @Override
-    public void setBitmap(Bitmap bitmap) {
-        mBufferedImage = bitmap.getImage();
-        mGraphicsStack.push(mBufferedImage.createGraphics());
-    }
-
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#translate(float, float)
-     */
-    @Override
-    public void translate(float dx, float dy) {
-        getGraphics2d().translate(dx, dy);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#save()
-     */
-    @Override
-    public int save() {
-        // get the current save count
-        int count = mGraphicsStack.size();
-
-        // create a new graphics and add it to the stack
-        Graphics2D g = (Graphics2D)getGraphics2d().create();
-        mGraphicsStack.push(g);
-
-        // return the old save count
-        return count;
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#save(int)
-     */
-    @Override
-    public int save(int saveFlags) {
-        // For now we ignore saveFlags
-        return save();
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#restore()
-     */
-    @Override
-    public void restore() {
-        mGraphicsStack.pop();
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#restoreToCount(int)
-     */
-    @Override
-    public void restoreToCount(int saveCount) {
-        while (mGraphicsStack.size() > saveCount) {
-            mGraphicsStack.pop();
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#getSaveCount()
-     */
-    @Override
-    public int getSaveCount() {
-        return mGraphicsStack.size();
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#clipRect(float, float, float, float, android.graphics.Region.Op)
-     */
-    @Override
-    public boolean clipRect(float left, float top, float right, float bottom, Op op) {
-        return clipRect(left, top, right, bottom);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#clipRect(float, float, float, float)
-     */
-    @Override
-    public boolean clipRect(float left, float top, float right, float bottom) {
-        getGraphics2d().clipRect((int)left, (int)top, (int)(right-left), (int)(bottom-top));
-        return true;
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#clipRect(int, int, int, int)
-     */
-    @Override
-    public boolean clipRect(int left, int top, int right, int bottom) {
-        getGraphics2d().clipRect(left, top, right-left, bottom-top);
-        return true;
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#clipRect(android.graphics.Rect, android.graphics.Region.Op)
-     */
-    @Override
-    public boolean clipRect(Rect rect, Op op) {
-        return clipRect(rect.left, rect.top, rect.right, rect.bottom);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#clipRect(android.graphics.Rect)
-     */
-    @Override
-    public boolean clipRect(Rect rect) {
-        return clipRect(rect.left, rect.top, rect.right, rect.bottom);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#clipRect(android.graphics.RectF, android.graphics.Region.Op)
-     */
-    @Override
-    public boolean clipRect(RectF rect, Op op) {
-        return clipRect(rect.left, rect.top, rect.right, rect.bottom);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#clipRect(android.graphics.RectF)
-     */
-    @Override
-    public boolean clipRect(RectF rect) {
-        return clipRect(rect.left, rect.top, rect.right, rect.bottom);
-    }
-
-    public boolean quickReject(RectF rect, EdgeType type) {
-        return false;
-    }
-
-    @Override
-    public boolean quickReject(RectF rect, _Original_Canvas.EdgeType type) {
-        throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
-    }
-
-    public boolean quickReject(Path path, EdgeType type) {
-        return false;
-    }
-
-    @Override
-    public boolean quickReject(Path path, _Original_Canvas.EdgeType type) {
-        throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
-    }
-
-    public boolean quickReject(float left, float top, float right, float bottom,
-                               EdgeType type) {
-        return false;
-    }
-
-    @Override
-    public boolean quickReject(float left, float top, float right, float bottom,
-                               _Original_Canvas.EdgeType type) {
-        throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
-    }
-
-    /**
-     * Retrieve the clip bounds, returning true if they are non-empty.
-     *
-     * @param bounds Return the clip bounds here. If it is null, ignore it but
-     *               still return true if the current clip is non-empty.
-     * @return true if the current clip is non-empty.
-     */
-    @Override
-    public boolean getClipBounds(Rect bounds) {
-        Rectangle rect = getGraphics2d().getClipBounds();
-        if (rect != null) {
-            bounds.left = rect.x;
-            bounds.top = rect.y;
-            bounds.right = rect.x + rect.width;
-            bounds.bottom = rect.y + rect.height;
-            return true;
-        }
-        return false;
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawColor(int, android.graphics.PorterDuff.Mode)
-     */
-    @Override
-    public void drawColor(int color, PorterDuff.Mode mode) {
-        Graphics2D g = getGraphics2d();
-
-        // save old color
-        Color c = g.getColor();
-
-        Composite composite = g.getComposite();
-
-        // get the alpha from the color
-        int alpha = color >>> 24;
-        float falpha = alpha / 255.f;
-
-        setModeInGraphics(mode, g, falpha);
-
-        g.setColor(new Color(color));
-
-        g.fillRect(0, 0, getWidth(), getHeight());
-
-        g.setComposite(composite);
-
-        // restore color
-        g.setColor(c);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawColor(int)
-     */
-    @Override
-    public void drawColor(int color) {
-        drawColor(color, PorterDuff.Mode.SRC_OVER);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawARGB(int, int, int, int)
-     */
-    @Override
-    public void drawARGB(int a, int r, int g, int b) {
-        drawColor(a << 24 | r << 16 | g << 8 | b, PorterDuff.Mode.SRC_OVER);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawRGB(int, int, int)
-     */
-    @Override
-    public void drawRGB(int r, int g, int b) {
-        drawColor(0xFF << 24 | r << 16 | g << 8 | b, PorterDuff.Mode.SRC_OVER);
-    }
-
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#getWidth()
-     */
-    @Override
-    public int getWidth() {
-        return mBufferedImage.getWidth();
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#getHeight()
-     */
-    @Override
-    public int getHeight() {
-        return mBufferedImage.getHeight();
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawPaint(android.graphics.Paint)
-     */
-    @Override
-    public void drawPaint(Paint paint) {
-        drawColor(paint.getColor());
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawBitmap(android.graphics.Bitmap, float, float, android.graphics.Paint)
-     */
-    @Override
-    public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
-        drawBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),
-                (int)left, (int)top,
-                (int)left+bitmap.getWidth(), (int)top+bitmap.getHeight(), paint);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawBitmap(android.graphics.Bitmap, android.graphics.Matrix, android.graphics.Paint)
-     */
-    @Override
-    public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
-        boolean needsRestore = false;
-        if (matrix.isIdentity() == false) {
-            // create a new graphics and apply the matrix to it
-            save(); // this creates a new Graphics2D, and stores it for children call to use
-            needsRestore = true;
-            Graphics2D g = getGraphics2d(); // get the newly create Graphics2D
-
-            // get the Graphics2D current matrix
-            AffineTransform currentTx = g.getTransform();
-            // get the AffineTransform from the matrix
-            AffineTransform matrixTx = matrix.getTransform();
-
-            // combine them so that the matrix is applied after.
-            currentTx.preConcatenate(matrixTx);
-
-            // give it to the graphics as a new matrix replacing all previous transform
-            g.setTransform(currentTx);
-        }
-
-        // draw the bitmap
-        drawBitmap(bitmap, 0, 0, paint);
-
-        if (needsRestore) {
-            // remove the new graphics
-            restore();
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawBitmap(android.graphics.Bitmap, android.graphics.Rect, android.graphics.Rect, android.graphics.Paint)
-     */
-    @Override
-    public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
-        if (src == null) {
-            drawBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),
-                    dst.left, dst.top, dst.right, dst.bottom, paint);
-        } else {
-            drawBitmap(bitmap, src.left, src.top, src.width(), src.height(),
-                    dst.left, dst.top, dst.right, dst.bottom, paint);
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawBitmap(android.graphics.Bitmap, android.graphics.Rect, android.graphics.RectF, android.graphics.Paint)
-     */
-    @Override
-    public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
-        if (src == null) {
-            drawBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),
-                    (int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom, paint);
-        } else {
-            drawBitmap(bitmap, src.left, src.top, src.width(), src.height(),
-                    (int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom, paint);
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawBitmap(int[], int, int, int, int, int, int, boolean, android.graphics.Paint)
-     */
-    @Override
-    public void drawBitmap(int[] colors, int offset, int stride, int x, int y, int width,
-            int height, boolean hasAlpha, Paint paint) {
-        throw new UnsupportedOperationException();
-    }
-
-    private void drawBitmap(Bitmap bitmap, int sleft, int stop, int sright, int sbottom, int dleft,
-            int dtop, int dright, int dbottom, Paint paint) {
-        BufferedImage image = bitmap.getImage();
-
-        Graphics2D g = getGraphics2d();
-
-        Composite c = null;
-
-        if (paint != null) {
-            if (paint.isFilterBitmap()) {
-                g = (Graphics2D)g.create();
-                g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-                        RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-            }
-
-            if (paint.getAlpha() != 0xFF) {
-                c = g.getComposite();
-                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
-                        paint.getAlpha()/255.f));
-            }
-        }
-
-        g.drawImage(image, dleft, dtop, dright, dbottom,
-                sleft, stop, sright, sbottom, null);
-
-        if (paint != null) {
-            if (paint.isFilterBitmap()) {
-                g.dispose();
-            }
-            if (c != null) {
-                g.setComposite(c);
-            }
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#rotate(float, float, float)
-     */
-    @Override
-    public void rotate(float degrees, float px, float py) {
-        if (degrees != 0) {
-            Graphics2D g = getGraphics2d();
-            g.translate(px, py);
-            g.rotate(Math.toRadians(degrees));
-            g.translate(-px, -py);
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#rotate(float)
-     */
-    @Override
-    public void rotate(float degrees) {
-        getGraphics2d().rotate(Math.toRadians(degrees));
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#scale(float, float, float, float)
-     */
-    @Override
-    public void scale(float sx, float sy, float px, float py) {
-        Graphics2D g = getGraphics2d();
-        g.translate(px, py);
-        g.scale(sx, sy);
-        g.translate(-px, -py);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#scale(float, float)
-     */
-    @Override
-    public void scale(float sx, float sy) {
-        getGraphics2d().scale(sx, sy);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawText(char[], int, int, float, float, android.graphics.Paint)
-     */
-    @Override
-    public void drawText(char[] text, int index, int count, float x, float y, Paint paint) {
-        // WARNING: the logic in this method is similar to Paint.measureText.
-        // Any change to this method should be reflected in Paint.measureText
-        Graphics2D g = getGraphics2d();
-
-        g = (Graphics2D)g.create();
-        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-
-        // set the color. because this only handles RGB, the alpha channel is handled
-        // as a composite.
-        g.setColor(new Color(paint.getColor()));
-        int alpha = paint.getAlpha();
-        float falpha = alpha / 255.f;
-        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha));
-
-
-        // Paint.TextAlign indicates how the text is positioned relative to X.
-        // LEFT is the default and there's nothing to do.
-        if (paint.getTextAlign() != Align.LEFT) {
-            float m = paint.measureText(text, index, count);
-            if (paint.getTextAlign() == Align.CENTER) {
-                x -= m / 2;
-            } else if (paint.getTextAlign() == Align.RIGHT) {
-                x -= m;
-            }
-        }
-
-        List<FontInfo> fonts = paint.getFonts();
-        try {
-            if (fonts.size() > 0) {
-                FontInfo mainFont = fonts.get(0);
-                int i = index;
-                int lastIndex = index + count;
-                while (i < lastIndex) {
-                    // always start with the main font.
-                    int upTo = mainFont.mFont.canDisplayUpTo(text, i, lastIndex);
-                    if (upTo == -1) {
-                        // draw all the rest and exit.
-                        g.setFont(mainFont.mFont);
-                        g.drawChars(text, i, lastIndex - i, (int)x, (int)y);
-                        return;
-                    } else if (upTo > 0) {
-                        // draw what's possible
-                        g.setFont(mainFont.mFont);
-                        g.drawChars(text, i, upTo - i, (int)x, (int)y);
-
-                        // compute the width that was drawn to increase x
-                        x += mainFont.mMetrics.charsWidth(text, i, upTo - i);
-
-                        // move index to the first non displayed char.
-                        i = upTo;
-
-                        // don't call continue at this point. Since it is certain the main font
-                        // cannot display the font a index upTo (now ==i), we move on to the
-                        // fallback fonts directly.
-                    }
-
-                    // no char supported, attempt to read the next char(s) with the
-                    // fallback font. In this case we only test the first character
-                    // and then go back to test with the main font.
-                    // Special test for 2-char characters.
-                    boolean foundFont = false;
-                    for (int f = 1 ; f < fonts.size() ; f++) {
-                        FontInfo fontInfo = fonts.get(f);
-
-                        // need to check that the font can display the character. We test
-                        // differently if the char is a high surrogate.
-                        int charCount = Character.isHighSurrogate(text[i]) ? 2 : 1;
-                        upTo = fontInfo.mFont.canDisplayUpTo(text, i, i + charCount);
-                        if (upTo == -1) {
-                            // draw that char
-                            g.setFont(fontInfo.mFont);
-                            g.drawChars(text, i, charCount, (int)x, (int)y);
-
-                            // update x
-                            x += fontInfo.mMetrics.charsWidth(text, i, charCount);
-
-                            // update the index in the text, and move on
-                            i += charCount;
-                            foundFont = true;
-                            break;
-
-                        }
-                    }
-
-                    // in case no font can display the char, display it with the main font.
-                    // (it'll put a square probably)
-                    if (foundFont == false) {
-                        int charCount = Character.isHighSurrogate(text[i]) ? 2 : 1;
-
-                        g.setFont(mainFont.mFont);
-                        g.drawChars(text, i, charCount, (int)x, (int)y);
-
-                        // measure it to advance x
-                        x += mainFont.mMetrics.charsWidth(text, i, charCount);
-
-                        // and move to the next chars.
-                        i += charCount;
-                    }
-                }
-            }
-        } finally {
-            g.dispose();
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawText(java.lang.CharSequence, int, int, float, float, android.graphics.Paint)
-     */
-    @Override
-    public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) {
-        drawText(text.toString().toCharArray(), start, end - start, x, y, paint);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawText(java.lang.String, float, float, android.graphics.Paint)
-     */
-    @Override
-    public void drawText(String text, float x, float y, Paint paint) {
-        drawText(text.toCharArray(), 0, text.length(), x, y, paint);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawText(java.lang.String, int, int, float, float, android.graphics.Paint)
-     */
-    @Override
-    public void drawText(String text, int start, int end, float x, float y, Paint paint) {
-        drawText(text.toCharArray(), start, end - start, x, y, paint);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawRect(android.graphics.RectF, android.graphics.Paint)
-     */
-    @Override
-    public void drawRect(RectF rect, Paint paint) {
-        doDrawRect((int)rect.left, (int)rect.top, (int)rect.width(), (int)rect.height(), paint);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawRect(float, float, float, float, android.graphics.Paint)
-     */
-    @Override
-    public void drawRect(float left, float top, float right, float bottom, Paint paint) {
-        doDrawRect((int)left, (int)top, (int)(right-left), (int)(bottom-top), paint);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawRect(android.graphics.Rect, android.graphics.Paint)
-     */
-    @Override
-    public void drawRect(Rect r, Paint paint) {
-        doDrawRect(r.left, r.top, r.width(), r.height(), paint);
-    }
-
-    private final void doDrawRect(int left, int top, int width, int height, Paint paint) {
-        if (width > 0 && height > 0) {
-            // get a Graphics2D object configured with the drawing parameters.
-            Graphics2D g = getCustomGraphics(paint);
-
-            Style style = paint.getStyle();
-
-            // draw
-            if (style == Style.FILL || style == Style.FILL_AND_STROKE) {
-                g.fillRect(left, top, width, height);
-            }
-
-            if (style == Style.STROKE || style == Style.FILL_AND_STROKE) {
-                g.drawRect(left, top, width, height);
-            }
-
-            // dispose Graphics2D object
-            g.dispose();
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawRoundRect(android.graphics.RectF, float, float, android.graphics.Paint)
-     */
-    @Override
-    public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
-        if (rect.width() > 0 && rect.height() > 0) {
-            // get a Graphics2D object configured with the drawing parameters.
-            Graphics2D g = getCustomGraphics(paint);
-
-            Style style = paint.getStyle();
-
-            // draw
-
-            int arcWidth = (int)(rx * 2);
-            int arcHeight = (int)(ry * 2);
-
-            if (style == Style.FILL || style == Style.FILL_AND_STROKE) {
-                g.fillRoundRect((int)rect.left, (int)rect.top, (int)rect.width(), (int)rect.height(),
-                        arcWidth, arcHeight);
-            }
-
-            if (style == Style.STROKE || style == Style.FILL_AND_STROKE) {
-                g.drawRoundRect((int)rect.left, (int)rect.top, (int)rect.width(), (int)rect.height(),
-                        arcWidth, arcHeight);
-            }
-
-            // dispose Graphics2D object
-            g.dispose();
-        }
-    }
-
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawLine(float, float, float, float, android.graphics.Paint)
-     */
-    @Override
-    public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) {
-        // get a Graphics2D object configured with the drawing parameters.
-        Graphics2D g = getCustomGraphics(paint);
-
-        g.drawLine((int)startX, (int)startY, (int)stopX, (int)stopY);
-
-        // dispose Graphics2D object
-        g.dispose();
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawLines(float[], int, int, android.graphics.Paint)
-     */
-    @Override
-    public void drawLines(float[] pts, int offset, int count, Paint paint) {
-        // get a Graphics2D object configured with the drawing parameters.
-        Graphics2D g = getCustomGraphics(paint);
-
-        for (int i = 0 ; i < count ; i += 4) {
-            g.drawLine((int)pts[i + offset], (int)pts[i + offset + 1],
-                    (int)pts[i + offset + 2], (int)pts[i + offset + 3]);
-        }
-
-        // dispose Graphics2D object
-        g.dispose();
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawLines(float[], android.graphics.Paint)
-     */
-    @Override
-    public void drawLines(float[] pts, Paint paint) {
-        drawLines(pts, 0, pts.length, paint);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawCircle(float, float, float, android.graphics.Paint)
-     */
-    @Override
-    public void drawCircle(float cx, float cy, float radius, Paint paint) {
-        // get a Graphics2D object configured with the drawing parameters.
-        Graphics2D g = getCustomGraphics(paint);
-
-        Style style = paint.getStyle();
-
-        int size = (int)(radius * 2);
-
-        // draw
-        if (style == Style.FILL || style == Style.FILL_AND_STROKE) {
-            g.fillOval((int)(cx - radius), (int)(cy - radius), size, size);
-        }
-
-        if (style == Style.STROKE || style == Style.FILL_AND_STROKE) {
-            g.drawOval((int)(cx - radius), (int)(cy - radius), size, size);
-        }
-
-        // dispose Graphics2D object
-        g.dispose();
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawOval(android.graphics.RectF, android.graphics.Paint)
-     */
-    @Override
-    public void drawOval(RectF oval, Paint paint) {
-        // get a Graphics2D object configured with the drawing parameters.
-        Graphics2D g = getCustomGraphics(paint);
-
-        Style style = paint.getStyle();
-
-        // draw
-        if (style == Style.FILL || style == Style.FILL_AND_STROKE) {
-            g.fillOval((int)oval.left, (int)oval.top, (int)oval.width(), (int)oval.height());
-        }
-
-        if (style == Style.STROKE || style == Style.FILL_AND_STROKE) {
-            g.drawOval((int)oval.left, (int)oval.top, (int)oval.width(), (int)oval.height());
-        }
-
-        // dispose Graphics2D object
-        g.dispose();
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawPath(android.graphics.Path, android.graphics.Paint)
-     */
-    @Override
-    public void drawPath(Path path, Paint paint) {
-        // get a Graphics2D object configured with the drawing parameters.
-        Graphics2D g = getCustomGraphics(paint);
-
-        Style style = paint.getStyle();
-
-        // draw
-        if (style == Style.FILL || style == Style.FILL_AND_STROKE) {
-            g.fill(path.getAwtShape());
-        }
-
-        if (style == Style.STROKE || style == Style.FILL_AND_STROKE) {
-            g.draw(path.getAwtShape());
-        }
-
-        // dispose Graphics2D object
-        g.dispose();
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#setMatrix(android.graphics.Matrix)
-     */
-    @Override
-    public void setMatrix(Matrix matrix) {
-        // get the new current graphics
-        Graphics2D g = getGraphics2d();
-
-        // and apply the matrix
-        g.setTransform(matrix.getTransform());
-
-        if (mLogger != null && matrix.hasPerspective()) {
-            mLogger.warning("android.graphics.Canvas#setMatrix(android.graphics.Matrix) only supports affine transformations in the Layout Editor.");
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#concat(android.graphics.Matrix)
-     */
-    @Override
-    public void concat(Matrix matrix) {
-        // get the current top graphics2D object.
-        Graphics2D g = getGraphics2d();
-
-        // get its current matrix
-        AffineTransform currentTx = g.getTransform();
-        // get the AffineTransform of the given matrix
-        AffineTransform matrixTx = matrix.getTransform();
-
-        // combine them so that the given matrix is applied after.
-        currentTx.preConcatenate(matrixTx);
-
-        // give it to the graphics2D as a new matrix replacing all previous transform
-        g.setTransform(currentTx);
-    }
-
-
-    // --------------------
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#clipPath(android.graphics.Path, android.graphics.Region.Op)
-     */
-    @Override
-    public boolean clipPath(Path path, Op op) {
-        // TODO Auto-generated method stub
-        return super.clipPath(path, op);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#clipPath(android.graphics.Path)
-     */
-    @Override
-    public boolean clipPath(Path path) {
-        // TODO Auto-generated method stub
-        return super.clipPath(path);
-    }
-
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#clipRegion(android.graphics.Region, android.graphics.Region.Op)
-     */
-    @Override
-    public boolean clipRegion(Region region, Op op) {
-        // TODO Auto-generated method stub
-        return super.clipRegion(region, op);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#clipRegion(android.graphics.Region)
-     */
-    @Override
-    public boolean clipRegion(Region region) {
-        // TODO Auto-generated method stub
-        return super.clipRegion(region);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawArc(android.graphics.RectF, float, float, boolean, android.graphics.Paint)
-     */
-    @Override
-    public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,
-            Paint paint) {
-        // TODO Auto-generated method stub
-        super.drawArc(oval, startAngle, sweepAngle, useCenter, paint);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawBitmapMesh(android.graphics.Bitmap, int, int, float[], int, int[], int, android.graphics.Paint)
-     */
-    @Override
-    public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts,
-            int vertOffset, int[] colors, int colorOffset, Paint paint) {
-        // TODO Auto-generated method stub
-        super.drawBitmapMesh(bitmap, meshWidth, meshHeight, verts, vertOffset, colors, colorOffset, paint);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawPicture(android.graphics.Picture, android.graphics.Rect)
-     */
-    @Override
-    public void drawPicture(Picture picture, Rect dst) {
-        // TODO Auto-generated method stub
-        super.drawPicture(picture, dst);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawPicture(android.graphics.Picture, android.graphics.RectF)
-     */
-    @Override
-    public void drawPicture(Picture picture, RectF dst) {
-        // TODO Auto-generated method stub
-        super.drawPicture(picture, dst);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawPicture(android.graphics.Picture)
-     */
-    @Override
-    public void drawPicture(Picture picture) {
-        // TODO Auto-generated method stub
-        super.drawPicture(picture);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawPoint(float, float, android.graphics.Paint)
-     */
-    @Override
-    public void drawPoint(float x, float y, Paint paint) {
-        // TODO Auto-generated method stub
-        super.drawPoint(x, y, paint);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawPoints(float[], int, int, android.graphics.Paint)
-     */
-    @Override
-    public void drawPoints(float[] pts, int offset, int count, Paint paint) {
-        // TODO Auto-generated method stub
-        super.drawPoints(pts, offset, count, paint);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawPoints(float[], android.graphics.Paint)
-     */
-    @Override
-    public void drawPoints(float[] pts, Paint paint) {
-        // TODO Auto-generated method stub
-        super.drawPoints(pts, paint);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawPosText(char[], int, int, float[], android.graphics.Paint)
-     */
-    @Override
-    public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) {
-        // TODO Auto-generated method stub
-        super.drawPosText(text, index, count, pos, paint);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawPosText(java.lang.String, float[], android.graphics.Paint)
-     */
-    @Override
-    public void drawPosText(String text, float[] pos, Paint paint) {
-        // TODO Auto-generated method stub
-        super.drawPosText(text, pos, paint);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawTextOnPath(char[], int, int, android.graphics.Path, float, float, android.graphics.Paint)
-     */
-    @Override
-    public void drawTextOnPath(char[] text, int index, int count, Path path, float offset,
-            float offset2, Paint paint) {
-        // TODO Auto-generated method stub
-        super.drawTextOnPath(text, index, count, path, offset, offset2, paint);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawTextOnPath(java.lang.String, android.graphics.Path, float, float, android.graphics.Paint)
-     */
-    @Override
-    public void drawTextOnPath(String text, Path path, float offset, float offset2, Paint paint) {
-        // TODO Auto-generated method stub
-        super.drawTextOnPath(text, path, offset, offset2, paint);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#drawVertices(android.graphics.Canvas.VertexMode, int, float[], int, float[], int, int[], int, short[], int, int, android.graphics.Paint)
-     */
-    @Override
-    public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset,
-            float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices,
-            int indexOffset, int indexCount, Paint paint) {
-        // TODO Auto-generated method stub
-        super.drawVertices(mode, vertexCount, verts, vertOffset, texs, texOffset, colors, colorOffset,
-                indices, indexOffset, indexCount, paint);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#getDrawFilter()
-     */
-    @Override
-    public DrawFilter getDrawFilter() {
-        // TODO Auto-generated method stub
-        return super.getDrawFilter();
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#getGL()
-     */
-    @Override
-    public GL getGL() {
-        // TODO Auto-generated method stub
-        return super.getGL();
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#getMatrix()
-     */
-    @Override
-    public Matrix getMatrix() {
-        // TODO Auto-generated method stub
-        return super.getMatrix();
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#getMatrix(android.graphics.Matrix)
-     */
-    @Override
-    public void getMatrix(Matrix ctm) {
-        // TODO Auto-generated method stub
-        super.getMatrix(ctm);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#isOpaque()
-     */
-    @Override
-    public boolean isOpaque() {
-        // TODO Auto-generated method stub
-        return super.isOpaque();
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#saveLayer(float, float, float, float, android.graphics.Paint, int)
-     */
-    @Override
-    public int saveLayer(float left, float top, float right, float bottom, Paint paint,
-            int saveFlags) {
-        // TODO Auto-generated method stub
-        return super.saveLayer(left, top, right, bottom, paint, saveFlags);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#saveLayer(android.graphics.RectF, android.graphics.Paint, int)
-     */
-    @Override
-    public int saveLayer(RectF bounds, Paint paint, int saveFlags) {
-        // TODO Auto-generated method stub
-        return super.saveLayer(bounds, paint, saveFlags);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#saveLayerAlpha(float, float, float, float, int, int)
-     */
-    @Override
-    public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
-            int saveFlags) {
-        // TODO Auto-generated method stub
-        return super.saveLayerAlpha(left, top, right, bottom, alpha, saveFlags);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#saveLayerAlpha(android.graphics.RectF, int, int)
-     */
-    @Override
-    public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) {
-        // TODO Auto-generated method stub
-        return super.saveLayerAlpha(bounds, alpha, saveFlags);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#setDrawFilter(android.graphics.DrawFilter)
-     */
-    @Override
-    public void setDrawFilter(DrawFilter filter) {
-        // TODO Auto-generated method stub
-        super.setDrawFilter(filter);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#setViewport(int, int)
-     */
-    @Override
-    public void setViewport(int width, int height) {
-        // TODO Auto-generated method stub
-        super.setViewport(width, height);
-    }
-
-    /* (non-Javadoc)
-     * @see android.graphics.Canvas#skew(float, float)
-     */
-    @Override
-    public void skew(float sx, float sy) {
-        // TODO Auto-generated method stub
-        super.skew(sx, sy);
-    }
-
-
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
new file mode 100644
index 0000000..02a2ddf
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -0,0 +1,1334 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.layoutlib.bridge.impl.GcSnapshot;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.graphics.Bitmap.Config;
+import android.graphics.Paint_Delegate.FontInfo;
+import android.text.TextUtils;
+
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.util.List;
+
+
+/**
+ * Delegate implementing the native methods of android.graphics.Canvas
+ *
+ * Through the layoutlib_create tool, the original native methods of Canvas have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original Canvas class.
+ *
+ * @see DelegateManager
+ *
+ */
+public final class Canvas_Delegate {
+
+    // ---- delegate manager ----
+    private static final DelegateManager<Canvas_Delegate> sManager =
+            new DelegateManager<Canvas_Delegate>(Canvas_Delegate.class);
+
+    // ---- delegate helper data ----
+
+    private final static boolean[] sBoolOut = new boolean[1];
+
+    // ---- delegate data ----
+    private Bitmap_Delegate mBitmap;
+    private GcSnapshot mSnapshot;
+
+    private DrawFilter_Delegate mDrawFilter = null;
+
+    // ---- Public Helper methods ----
+
+    /**
+     * Returns the native delegate associated to a given {@link Canvas} object.
+     */
+    public static Canvas_Delegate getDelegate(Canvas canvas) {
+        return sManager.getDelegate(canvas.mNativeCanvas);
+    }
+
+    /**
+     * Returns the native delegate associated to a given an int referencing a {@link Canvas} object.
+     */
+    public static Canvas_Delegate getDelegate(int native_canvas) {
+        return sManager.getDelegate(native_canvas);
+    }
+
+    /**
+     * Returns the current {@link Graphics2D} used to draw.
+     */
+    public GcSnapshot getSnapshot() {
+        return mSnapshot;
+    }
+
+    /**
+     * Returns the {@link DrawFilter} delegate or null if none have been set.
+     *
+     * @return the delegate or null.
+     */
+    public DrawFilter_Delegate getDrawFilter() {
+        return mDrawFilter;
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static boolean isOpaque(Canvas thisCanvas) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+        if (canvasDelegate == null) {
+            return false;
+        }
+
+        return canvasDelegate.mBitmap.getConfig() == Config.RGB_565;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int getWidth(Canvas thisCanvas) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+        if (canvasDelegate == null) {
+            return 0;
+        }
+
+        return canvasDelegate.mBitmap.getImage().getWidth();
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int getHeight(Canvas thisCanvas) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+        if (canvasDelegate == null) {
+            return 0;
+        }
+
+        return canvasDelegate.mBitmap.getImage().getHeight();
+    }
+
+    @LayoutlibDelegate
+   /*package*/ static void translate(Canvas thisCanvas, float dx, float dy) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+        if (canvasDelegate == null) {
+            return;
+        }
+
+        canvasDelegate.getSnapshot().translate(dx, dy);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void rotate(Canvas thisCanvas, float degrees) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+        if (canvasDelegate == null) {
+            return;
+        }
+
+        canvasDelegate.getSnapshot().rotate(Math.toRadians(degrees));
+    }
+
+    @LayoutlibDelegate
+   /*package*/ static void scale(Canvas thisCanvas, float sx, float sy) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+        if (canvasDelegate == null) {
+            return;
+        }
+
+        canvasDelegate.getSnapshot().scale(sx, sy);
+    }
+
+    @LayoutlibDelegate
+   /*package*/ static void skew(Canvas thisCanvas, float kx, float ky) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+        if (canvasDelegate == null) {
+            return;
+        }
+
+        // get the current top graphics2D object.
+        GcSnapshot g = canvasDelegate.getSnapshot();
+
+        // get its current matrix
+        AffineTransform currentTx = g.getTransform();
+        // get the AffineTransform for the given skew.
+        float[] mtx = Matrix_Delegate.getSkew(kx, ky);
+        AffineTransform matrixTx = Matrix_Delegate.getAffineTransform(mtx);
+
+        // combine them so that the given matrix is applied after.
+        currentTx.preConcatenate(matrixTx);
+
+        // give it to the graphics2D as a new matrix replacing all previous transform
+        g.setTransform(currentTx);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean clipRect(Canvas thisCanvas, RectF rect) {
+        return clipRect(thisCanvas, rect.left, rect.top, rect.right, rect.bottom);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean clipRect(Canvas thisCanvas, Rect rect) {
+        return clipRect(thisCanvas, (float) rect.left, (float) rect.top,
+                (float) rect.right, (float) rect.bottom);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean clipRect(Canvas thisCanvas, float left, float top, float right,
+            float bottom) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+        if (canvasDelegate == null) {
+            return false;
+        }
+
+        return canvasDelegate.clipRect(left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean clipRect(Canvas thisCanvas, int left, int top, int right,
+            int bottom) {
+
+        return clipRect(thisCanvas, (float) left, (float) top, (float) right, (float) bottom);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int save(Canvas thisCanvas) {
+        return save(thisCanvas, Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int save(Canvas thisCanvas, int saveFlags) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+        if (canvasDelegate == null) {
+            return 0;
+        }
+
+        return canvasDelegate.save(saveFlags);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void restore(Canvas thisCanvas) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+        if (canvasDelegate == null) {
+            return;
+        }
+
+        canvasDelegate.restore();
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int getSaveCount(Canvas thisCanvas) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+        if (canvasDelegate == null) {
+            return 0;
+        }
+
+        return canvasDelegate.getSnapshot().size();
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void restoreToCount(Canvas thisCanvas, int saveCount) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
+        if (canvasDelegate == null) {
+            return;
+        }
+
+        canvasDelegate.restoreTo(saveCount);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void drawText(Canvas thisCanvas,
+            String text, float x, float y, Paint paint) {
+        native_drawText(thisCanvas.mNativeCanvas, text, 0, text.length(), x, y,
+                paint.mNativePaint);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void drawPoints(Canvas thisCanvas, float[] pts, int offset, int count,
+            Paint paint) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Canvas.drawPoint is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void drawPoint(Canvas thisCanvas, float x, float y, Paint paint) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Canvas.drawPoint is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void drawLines(Canvas thisCanvas,
+            final float[] pts, final int offset, final int count,
+            Paint paint) {
+        draw(thisCanvas.mNativeCanvas, paint.mNativePaint, false /*compositeOnly*/,
+                false /*forceSrcMode*/, new GcSnapshot.Drawable() {
+                    public void draw(Graphics2D graphics, Paint_Delegate paint) {
+                        for (int i = 0 ; i < count ; i += 4) {
+                            graphics.drawLine((int)pts[i + offset], (int)pts[i + offset + 1],
+                                    (int)pts[i + offset + 2], (int)pts[i + offset + 3]);
+                        }
+                    }
+                });
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void freeCaches() {
+        // nothing to be done here.
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int initRaster(int nativeBitmapOrZero) {
+        if (nativeBitmapOrZero > 0) {
+            // get the Bitmap from the int
+            Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nativeBitmapOrZero);
+
+            // create a new Canvas_Delegate with the given bitmap and return its new native int.
+            Canvas_Delegate newDelegate = new Canvas_Delegate(bitmapDelegate);
+
+            return sManager.addNewDelegate(newDelegate);
+        } else {
+            // create a new Canvas_Delegate and return its new native int.
+            Canvas_Delegate newDelegate = new Canvas_Delegate();
+
+            return sManager.addNewDelegate(newDelegate);
+        }
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int initGL() {
+        // not supported.
+        return 0;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setBitmap(int nativeCanvas, int bitmap) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
+        if (canvasDelegate == null) {
+            return;
+        }
+
+        // get the delegate from the native int.
+        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
+        if (bitmapDelegate == null) {
+            return;
+        }
+
+        canvasDelegate.setBitmap(bitmapDelegate);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeSetViewport(int nCanvas, int w, int h) {
+        // only useful in GL which is not supported, so no need to do anything.
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_saveLayer(int nativeCanvas, RectF bounds,
+                                               int paint, int layerFlags) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
+        if (canvasDelegate == null) {
+            return 0;
+        }
+
+        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(paint);
+        if (paintDelegate == null) {
+            return 0;
+        }
+
+        return canvasDelegate.saveLayer(bounds, paintDelegate, layerFlags);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_saveLayer(int nativeCanvas, float l,
+                                               float t, float r, float b,
+                                               int paint, int layerFlags) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
+        if (canvasDelegate == null) {
+            return 0;
+        }
+
+        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(paint);
+        if (paintDelegate == null) {
+            return 0;
+        }
+
+        return canvasDelegate.saveLayer(new RectF(l, t, r, b),
+                paintDelegate, layerFlags);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_saveLayerAlpha(int nativeCanvas,
+                                                    RectF bounds, int alpha,
+                                                    int layerFlags) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
+        if (canvasDelegate == null) {
+            return 0;
+        }
+
+        return canvasDelegate.saveLayerAlpha(bounds, alpha, layerFlags);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_saveLayerAlpha(int nativeCanvas, float l,
+                                                    float t, float r, float b,
+                                                    int alpha, int layerFlags) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
+        if (canvasDelegate == null) {
+            return 0;
+        }
+
+        return canvasDelegate.saveLayerAlpha(new RectF(l, t, r, b), alpha, layerFlags);
+    }
+
+
+    @LayoutlibDelegate
+    /*package*/ static void native_concat(int nCanvas, int nMatrix) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
+        if (canvasDelegate == null) {
+            return;
+        }
+
+        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
+        if (matrixDelegate == null) {
+            return;
+        }
+
+        // get the current top graphics2D object.
+        GcSnapshot snapshot = canvasDelegate.getSnapshot();
+
+        // get its current matrix
+        AffineTransform currentTx = snapshot.getTransform();
+        // get the AffineTransform of the given matrix
+        AffineTransform matrixTx = matrixDelegate.getAffineTransform();
+
+        // combine them so that the given matrix is applied after.
+        currentTx.preConcatenate(matrixTx);
+
+        // give it to the graphics2D as a new matrix replacing all previous transform
+        snapshot.setTransform(currentTx);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setMatrix(int nCanvas, int nMatrix) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
+        if (canvasDelegate == null) {
+            return;
+        }
+
+        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
+        if (matrixDelegate == null) {
+            return;
+        }
+
+        // get the current top graphics2D object.
+        GcSnapshot snapshot = canvasDelegate.getSnapshot();
+
+        // get the AffineTransform of the given matrix
+        AffineTransform matrixTx = matrixDelegate.getAffineTransform();
+
+        // give it to the graphics2D as a new matrix replacing all previous transform
+        snapshot.setTransform(matrixTx);
+
+        if (matrixDelegate.hasPerspective()) {
+            assert false;
+            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_AFFINE,
+                    "android.graphics.Canvas#setMatrix(android.graphics.Matrix) only " +
+                    "supports affine transformations.", null, null /*data*/);
+        }
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_clipRect(int nCanvas,
+                                                  float left, float top,
+                                                  float right, float bottom,
+                                                  int regionOp) {
+
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
+        if (canvasDelegate == null) {
+            return false;
+        }
+
+        return canvasDelegate.clipRect(left, top, right, bottom, regionOp);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_clipPath(int nativeCanvas,
+                                                  int nativePath,
+                                                  int regionOp) {
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
+        if (canvasDelegate == null) {
+            return true;
+        }
+
+        Path_Delegate pathDelegate = Path_Delegate.getDelegate(nativePath);
+        if (pathDelegate == null) {
+            return true;
+        }
+
+        return canvasDelegate.mSnapshot.clip(pathDelegate.getJavaShape(), regionOp);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_clipRegion(int nativeCanvas,
+                                                    int nativeRegion,
+                                                    int regionOp) {
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
+        if (canvasDelegate == null) {
+            return true;
+        }
+
+        Region_Delegate region = Region_Delegate.getDelegate(nativeRegion);
+        if (region == null) {
+            return true;
+        }
+
+        return canvasDelegate.mSnapshot.clip(region.getJavaArea(), regionOp);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeSetDrawFilter(int nativeCanvas, int nativeFilter) {
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
+        if (canvasDelegate == null) {
+            return;
+        }
+
+        canvasDelegate.mDrawFilter = DrawFilter_Delegate.getDelegate(nativeFilter);
+
+        if (canvasDelegate.mDrawFilter != null &&
+                canvasDelegate.mDrawFilter.isSupported() == false) {
+            Bridge.getLog().fidelityWarning(LayoutLog.TAG_DRAWFILTER,
+                    canvasDelegate.mDrawFilter.getSupportMessage(), null, null /*data*/);
+        }
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_getClipBounds(int nativeCanvas,
+                                                       Rect bounds) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
+        if (canvasDelegate == null) {
+            return false;
+        }
+
+        Rectangle rect = canvasDelegate.getSnapshot().getClip().getBounds();
+        if (rect != null && rect.isEmpty() == false) {
+            bounds.left = rect.x;
+            bounds.top = rect.y;
+            bounds.right = rect.x + rect.width;
+            bounds.bottom = rect.y + rect.height;
+            return true;
+        }
+
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_getCTM(int canvas, int matrix) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(canvas);
+        if (canvasDelegate == null) {
+            return;
+        }
+
+        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
+        if (matrixDelegate == null) {
+            return;
+        }
+
+        AffineTransform transform = canvasDelegate.getSnapshot().getTransform();
+        matrixDelegate.set(Matrix_Delegate.makeValues(transform));
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_quickReject(int nativeCanvas,
+                                                     RectF rect,
+                                                     int native_edgeType) {
+        // FIXME properly implement quickReject
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_quickReject(int nativeCanvas,
+                                                     int path,
+                                                     int native_edgeType) {
+        // FIXME properly implement quickReject
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_quickReject(int nativeCanvas,
+                                                     float left, float top,
+                                                     float right, float bottom,
+                                                     int native_edgeType) {
+        // FIXME properly implement quickReject
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawRGB(int nativeCanvas, int r, int g, int b) {
+        native_drawColor(nativeCanvas, 0xFF000000 | r << 16 | (g&0xFF) << 8 | (b&0xFF),
+                PorterDuff.Mode.SRC_OVER.nativeInt);
+
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawARGB(int nativeCanvas, int a, int r, int g, int b) {
+        native_drawColor(nativeCanvas, a << 24 | (r&0xFF) << 16 | (g&0xFF) << 8 | (b&0xFF),
+                PorterDuff.Mode.SRC_OVER.nativeInt);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawColor(int nativeCanvas, int color) {
+        native_drawColor(nativeCanvas, color, PorterDuff.Mode.SRC_OVER.nativeInt);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawColor(int nativeCanvas, final int color, final int mode) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
+        if (canvasDelegate == null) {
+            return;
+        }
+
+        final int w = canvasDelegate.mBitmap.getImage().getWidth();
+        final int h = canvasDelegate.mBitmap.getImage().getHeight();
+        draw(nativeCanvas, new GcSnapshot.Drawable() {
+
+            public void draw(Graphics2D graphics, Paint_Delegate paint) {
+                // reset its transform just in case
+                graphics.setTransform(new AffineTransform());
+
+                // set the color
+                graphics.setColor(new Color(color, true /*alpha*/));
+
+                Composite composite = PorterDuffXfermode_Delegate.getComposite(
+                        PorterDuffXfermode_Delegate.getPorterDuffMode(mode), 0xFF);
+                if (composite != null) {
+                    graphics.setComposite(composite);
+                }
+
+                graphics.fillRect(0, 0, w, h);
+            }
+        });
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawPaint(int nativeCanvas, int paint) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Canvas.drawPaint is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawLine(int nativeCanvas,
+            final float startX, final float startY, final float stopX, final float stopY,
+            int paint) {
+
+        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
+                new GcSnapshot.Drawable() {
+                    public void draw(Graphics2D graphics, Paint_Delegate paint) {
+                        graphics.drawLine((int)startX, (int)startY, (int)stopX, (int)stopY);
+                    }
+        });
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawRect(int nativeCanvas, RectF rect,
+                                               int paint) {
+        native_drawRect(nativeCanvas, rect.left, rect.top, rect.right, rect.bottom, paint);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawRect(int nativeCanvas,
+            final float left, final float top, final float right, final float bottom, int paint) {
+
+        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
+                new GcSnapshot.Drawable() {
+                    public void draw(Graphics2D graphics, Paint_Delegate paint) {
+                        int style = paint.getStyle();
+
+                        // draw
+                        if (style == Paint.Style.FILL.nativeInt ||
+                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
+                            graphics.fillRect((int)left, (int)top,
+                                    (int)(right-left), (int)(bottom-top));
+                        }
+
+                        if (style == Paint.Style.STROKE.nativeInt ||
+                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
+                            graphics.drawRect((int)left, (int)top,
+                                    (int)(right-left), (int)(bottom-top));
+                        }
+                    }
+        });
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawOval(int nativeCanvas, final RectF oval, int paint) {
+        if (oval.right > oval.left && oval.bottom > oval.top) {
+            draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
+                    new GcSnapshot.Drawable() {
+                        public void draw(Graphics2D graphics, Paint_Delegate paint) {
+                            int style = paint.getStyle();
+
+                            // draw
+                            if (style == Paint.Style.FILL.nativeInt ||
+                                    style == Paint.Style.FILL_AND_STROKE.nativeInt) {
+                                graphics.fillOval((int)oval.left, (int)oval.top,
+                                        (int)oval.width(), (int)oval.height());
+                            }
+
+                            if (style == Paint.Style.STROKE.nativeInt ||
+                                    style == Paint.Style.FILL_AND_STROKE.nativeInt) {
+                                graphics.drawOval((int)oval.left, (int)oval.top,
+                                        (int)oval.width(), (int)oval.height());
+                            }
+                        }
+            });
+        }
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawCircle(int nativeCanvas,
+            float cx, float cy, float radius, int paint) {
+        native_drawOval(nativeCanvas,
+                new RectF(cx - radius, cy - radius, radius*2, radius*2),
+                paint);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawArc(int nativeCanvas,
+            RectF oval, float startAngle, float sweep, boolean useCenter, int paint) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Canvas.drawArc is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawRoundRect(int nativeCanvas,
+            final RectF rect, final float rx, final float ry, int paint) {
+
+        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
+                new GcSnapshot.Drawable() {
+                    public void draw(Graphics2D graphics, Paint_Delegate paint) {
+                        int style = paint.getStyle();
+
+                        // draw
+                        if (style == Paint.Style.FILL.nativeInt ||
+                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
+                            graphics.fillRoundRect(
+                                    (int)rect.left, (int)rect.top,
+                                    (int)rect.width(), (int)rect.height(),
+                                    (int)rx, (int)ry);
+                        }
+
+                        if (style == Paint.Style.STROKE.nativeInt ||
+                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
+                            graphics.drawRoundRect(
+                                    (int)rect.left, (int)rect.top,
+                                    (int)rect.width(), (int)rect.height(),
+                                    (int)rx, (int)ry);
+                        }
+                    }
+        });
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawPath(int nativeCanvas, int path, int paint) {
+        final Path_Delegate pathDelegate = Path_Delegate.getDelegate(path);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
+                new GcSnapshot.Drawable() {
+                    public void draw(Graphics2D graphics, Paint_Delegate paint) {
+                        Shape shape = pathDelegate.getJavaShape();
+                        int style = paint.getStyle();
+
+                        if (style == Paint.Style.FILL.nativeInt ||
+                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
+                            graphics.fill(shape);
+                        }
+
+                        if (style == Paint.Style.STROKE.nativeInt ||
+                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
+                            graphics.draw(shape);
+                        }
+                    }
+        });
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawBitmap(Canvas thisCanvas, int nativeCanvas, int bitmap,
+                                                 float left, float top,
+                                                 int nativePaintOrZero,
+                                                 int canvasDensity,
+                                                 int screenDensity,
+                                                 int bitmapDensity) {
+        // get the delegate from the native int.
+        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
+        if (bitmapDelegate == null) {
+            return;
+        }
+
+        BufferedImage image = bitmapDelegate.getImage();
+        float right = left + image.getWidth();
+        float bottom = top + image.getHeight();
+
+        drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
+                0, 0, image.getWidth(), image.getHeight(),
+                (int)left, (int)top, (int)right, (int)bottom);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawBitmap(Canvas thisCanvas, int nativeCanvas, int bitmap,
+                                                 Rect src, RectF dst,
+                                                 int nativePaintOrZero,
+                                                 int screenDensity,
+                                                 int bitmapDensity) {
+        // get the delegate from the native int.
+        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
+        if (bitmapDelegate == null) {
+            return;
+        }
+
+        BufferedImage image = bitmapDelegate.getImage();
+
+        if (src == null) {
+            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
+                    0, 0, image.getWidth(), image.getHeight(),
+                    (int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom);
+        } else {
+            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
+                    src.left, src.top, src.width(), src.height(),
+                    (int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom);
+        }
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawBitmap(int nativeCanvas, int bitmap,
+                                                 Rect src, Rect dst,
+                                                 int nativePaintOrZero,
+                                                 int screenDensity,
+                                                 int bitmapDensity) {
+        // get the delegate from the native int.
+        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
+        if (bitmapDelegate == null) {
+            return;
+        }
+
+        BufferedImage image = bitmapDelegate.getImage();
+
+        if (src == null) {
+            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
+                    0, 0, image.getWidth(), image.getHeight(),
+                    dst.left, dst.top, dst.right, dst.bottom);
+        } else {
+            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
+                    src.left, src.top, src.width(), src.height(),
+                    dst.left, dst.top, dst.right, dst.bottom);
+        }
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawBitmap(int nativeCanvas, int[] colors,
+                                                int offset, int stride, final float x,
+                                                 final float y, int width, int height,
+                                                 boolean hasAlpha,
+                                                 int nativePaintOrZero) {
+
+        // create a temp BufferedImage containing the content.
+        final BufferedImage image = new BufferedImage(width, height,
+                hasAlpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB);
+        image.setRGB(0, 0, width, height, colors, offset, stride);
+
+        draw(nativeCanvas, nativePaintOrZero, true /*compositeOnly*/, false /*forceSrcMode*/,
+                new GcSnapshot.Drawable() {
+                    public void draw(Graphics2D graphics, Paint_Delegate paint) {
+                        if (paint != null && paint.isFilterBitmap()) {
+                            graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+                                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+                        }
+
+                        graphics.drawImage(image, (int) x, (int) y, null);
+                    }
+        });
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeDrawBitmapMatrix(int nCanvas, int nBitmap,
+                                                      int nMatrix, int nPaint) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
+        if (canvasDelegate == null) {
+            return;
+        }
+
+        // get the delegate from the native int, which can be null
+        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nPaint);
+
+        // get the delegate from the native int.
+        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nBitmap);
+        if (bitmapDelegate == null) {
+            return;
+        }
+
+        final BufferedImage image = getImageToDraw(bitmapDelegate, paintDelegate, sBoolOut);
+
+        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
+        if (matrixDelegate == null) {
+            return;
+        }
+
+        final AffineTransform mtx = matrixDelegate.getAffineTransform();
+
+        canvasDelegate.getSnapshot().draw(new GcSnapshot.Drawable() {
+                public void draw(Graphics2D graphics, Paint_Delegate paint) {
+                    if (paint != null && paint.isFilterBitmap()) {
+                        graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+                                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+                    }
+
+                    //FIXME add support for canvas, screen and bitmap densities.
+                    graphics.drawImage(image, mtx, null);
+                }
+        }, paintDelegate, true /*compositeOnly*/, false /*forceSrcMode*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeDrawBitmapMesh(int nCanvas, int nBitmap,
+            int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors,
+            int colorOffset, int nPaint) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Canvas.drawBitmapMesh is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeDrawVertices(int nCanvas, int mode, int n,
+            float[] verts, int vertOffset,
+            float[] texs, int texOffset,
+            int[] colors, int colorOffset,
+            short[] indices, int indexOffset,
+            int indexCount, int nPaint) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Canvas.drawVertices is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawText(int nativeCanvas,
+            final char[] text, final int index, final int count,
+            final float startX, final float startY, int paint) {
+        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
+                new GcSnapshot.Drawable() {
+            public void draw(Graphics2D graphics, Paint_Delegate paint) {
+                // WARNING: the logic in this method is similar to Paint_Delegate.measureText.
+                // Any change to this method should be reflected in Paint.measureText
+                // Paint.TextAlign indicates how the text is positioned relative to X.
+                // LEFT is the default and there's nothing to do.
+                float x = startX;
+                float y = startY;
+                if (paint.getTextAlign() != Paint.Align.LEFT.nativeInt) {
+                    float m = paint.measureText(text, index, count);
+                    if (paint.getTextAlign() == Paint.Align.CENTER.nativeInt) {
+                        x -= m / 2;
+                    } else if (paint.getTextAlign() == Paint.Align.RIGHT.nativeInt) {
+                        x -= m;
+                    }
+                }
+
+                List<FontInfo> fonts = paint.getFonts();
+
+                if (fonts.size() > 0) {
+                    FontInfo mainFont = fonts.get(0);
+                    int i = index;
+                    int lastIndex = index + count;
+                    while (i < lastIndex) {
+                        // always start with the main font.
+                        int upTo = mainFont.mFont.canDisplayUpTo(text, i, lastIndex);
+                        if (upTo == -1) {
+                            // draw all the rest and exit.
+                            graphics.setFont(mainFont.mFont);
+                            graphics.drawChars(text, i, lastIndex - i, (int)x, (int)y);
+                            return;
+                        } else if (upTo > 0) {
+                            // draw what's possible
+                            graphics.setFont(mainFont.mFont);
+                            graphics.drawChars(text, i, upTo - i, (int)x, (int)y);
+
+                            // compute the width that was drawn to increase x
+                            x += mainFont.mMetrics.charsWidth(text, i, upTo - i);
+
+                            // move index to the first non displayed char.
+                            i = upTo;
+
+                            // don't call continue at this point. Since it is certain the main font
+                            // cannot display the font a index upTo (now ==i), we move on to the
+                            // fallback fonts directly.
+                        }
+
+                        // no char supported, attempt to read the next char(s) with the
+                        // fallback font. In this case we only test the first character
+                        // and then go back to test with the main font.
+                        // Special test for 2-char characters.
+                        boolean foundFont = false;
+                        for (int f = 1 ; f < fonts.size() ; f++) {
+                            FontInfo fontInfo = fonts.get(f);
+
+                            // need to check that the font can display the character. We test
+                            // differently if the char is a high surrogate.
+                            int charCount = Character.isHighSurrogate(text[i]) ? 2 : 1;
+                            upTo = fontInfo.mFont.canDisplayUpTo(text, i, i + charCount);
+                            if (upTo == -1) {
+                                // draw that char
+                                graphics.setFont(fontInfo.mFont);
+                                graphics.drawChars(text, i, charCount, (int)x, (int)y);
+
+                                // update x
+                                x += fontInfo.mMetrics.charsWidth(text, i, charCount);
+
+                                // update the index in the text, and move on
+                                i += charCount;
+                                foundFont = true;
+                                break;
+
+                            }
+                        }
+
+                        // in case no font can display the char, display it with the main font.
+                        // (it'll put a square probably)
+                        if (foundFont == false) {
+                            int charCount = Character.isHighSurrogate(text[i]) ? 2 : 1;
+
+                            graphics.setFont(mainFont.mFont);
+                            graphics.drawChars(text, i, charCount, (int)x, (int)y);
+
+                            // measure it to advance x
+                            x += mainFont.mMetrics.charsWidth(text, i, charCount);
+
+                            // and move to the next chars.
+                            i += charCount;
+                        }
+                    }
+                }
+            }
+        });
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawText(int nativeCanvas, String text,
+                                               int start, int end, float x,
+                                               float y, int paint) {
+        int count = end - start;
+        char[] buffer = TemporaryBuffer.obtain(count);
+        TextUtils.getChars(text, start, end, buffer, 0);
+
+        native_drawText(nativeCanvas, buffer, 0, count, x, y, paint);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawPosText(int nativeCanvas,
+                                                  char[] text, int index,
+                                                  int count, float[] pos,
+                                                  int paint) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Canvas.drawPosText is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawPosText(int nativeCanvas,
+                                                  String text, float[] pos,
+                                                  int paint) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Canvas.drawPosText is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawTextOnPath(int nativeCanvas,
+                                                     char[] text, int index,
+                                                     int count, int path,
+                                                     float hOffset,
+                                                     float vOffset,
+                                                     int paint) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Canvas.drawTextOnPath is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawTextOnPath(int nativeCanvas,
+                                                     String text, int path,
+                                                     float hOffset,
+                                                     float vOffset,
+                                                     int paint) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Canvas.drawTextOnPath is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_drawPicture(int nativeCanvas,
+                                                  int nativePicture) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Canvas.drawPicture is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void finalizer(int nativeCanvas) {
+        // get the delegate from the native int so that it can be disposed.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
+        if (canvasDelegate == null) {
+            return;
+        }
+
+        canvasDelegate.dispose();
+
+        // remove it from the manager.
+        sManager.removeJavaReferenceFor(nativeCanvas);
+    }
+
+    // ---- Private delegate/helper methods ----
+
+    /**
+     * Executes a {@link GcSnapshot.Drawable} with a given canvas and paint.
+     * <p>Note that the drawable may actually be executed several times if there are
+     * layers involved (see {@link #saveLayer(RectF, int, int)}.
+     */
+    private static void draw(int nCanvas, int nPaint, boolean compositeOnly, boolean forceSrcMode,
+            GcSnapshot.Drawable drawable) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
+        if (canvasDelegate == null) {
+            return;
+        }
+
+        // get the paint which can be null if nPaint is 0;
+        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nPaint);
+
+        canvasDelegate.getSnapshot().draw(drawable, paintDelegate, compositeOnly, forceSrcMode);
+    }
+
+    /**
+     * Executes a {@link GcSnapshot.Drawable} with a given canvas. No paint object will be provided
+     * to {@link GcSnapshot.Drawable#draw(Graphics2D, Paint_Delegate)}.
+     * <p>Note that the drawable may actually be executed several times if there are
+     * layers involved (see {@link #saveLayer(RectF, int, int)}.
+     */
+    private static void draw(int nCanvas, GcSnapshot.Drawable drawable) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
+        if (canvasDelegate == null) {
+            return;
+        }
+
+        canvasDelegate.mSnapshot.draw(drawable);
+    }
+
+    private Canvas_Delegate(Bitmap_Delegate bitmap) {
+        mSnapshot = GcSnapshot.createDefaultSnapshot(mBitmap = bitmap);
+    }
+
+    private Canvas_Delegate() {
+        mSnapshot = GcSnapshot.createDefaultSnapshot(null /*image*/);
+    }
+
+    /**
+     * Disposes of the {@link Graphics2D} stack.
+     */
+    private void dispose() {
+        mSnapshot.dispose();
+    }
+
+    private int save(int saveFlags) {
+        // get the current save count
+        int count = mSnapshot.size();
+
+        mSnapshot = mSnapshot.save(saveFlags);
+
+        // return the old save count
+        return count;
+    }
+
+    private int saveLayerAlpha(RectF rect, int alpha, int saveFlags) {
+        Paint_Delegate paint = new Paint_Delegate();
+        paint.setAlpha(alpha);
+        return saveLayer(rect, paint, saveFlags);
+    }
+
+    private int saveLayer(RectF rect, Paint_Delegate paint, int saveFlags) {
+        // get the current save count
+        int count = mSnapshot.size();
+
+        mSnapshot = mSnapshot.saveLayer(rect, paint, saveFlags);
+
+        // return the old save count
+        return count;
+    }
+
+    /**
+     * Restores the {@link GcSnapshot} to <var>saveCount</var>
+     * @param saveCount the saveCount
+     */
+    private void restoreTo(int saveCount) {
+        mSnapshot = mSnapshot.restoreTo(saveCount);
+    }
+
+    /**
+     * Restores the {@link GcSnapshot} to <var>saveCount</var>
+     * @param saveCount the saveCount
+     */
+    private void restore() {
+        mSnapshot = mSnapshot.restore();
+    }
+
+    private boolean clipRect(float left, float top, float right, float bottom, int regionOp) {
+        return mSnapshot.clipRect(left, top, right, bottom, regionOp);
+    }
+
+    private void setBitmap(Bitmap_Delegate bitmap) {
+        mBitmap = bitmap;
+        assert mSnapshot.size() == 1;
+        mSnapshot.setBitmap(mBitmap);
+    }
+
+    private static void drawBitmap(
+            int nativeCanvas,
+            Bitmap_Delegate bitmap,
+            int nativePaintOrZero,
+            final int sleft, final int stop, final int sright, final int sbottom,
+            final int dleft, final int dtop, final int dright, final int dbottom) {
+        // get the delegate from the native int.
+        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
+        if (canvasDelegate == null) {
+            return;
+        }
+
+        // get the paint, which could be null if the int is 0
+        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nativePaintOrZero);
+
+        final BufferedImage image = getImageToDraw(bitmap, paintDelegate, sBoolOut);
+
+        draw(nativeCanvas, nativePaintOrZero, true /*compositeOnly*/, sBoolOut[0],
+                new GcSnapshot.Drawable() {
+                    public void draw(Graphics2D graphics, Paint_Delegate paint) {
+                        if (paint != null && paint.isFilterBitmap()) {
+                            graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+                                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+                        }
+
+                        //FIXME add support for canvas, screen and bitmap densities.
+                        graphics.drawImage(image, dleft, dtop, dright, dbottom,
+                                sleft, stop, sright, sbottom, null);
+                    }
+        });
+    }
+
+
+    /**
+     * Returns a BufferedImage ready for drawing, based on the bitmap and paint delegate.
+     * The image returns, through a 1-size boolean array, whether the drawing code should
+     * use a SRC composite no matter what the paint says.
+     *
+     * @param bitmap the bitmap
+     * @param paint the paint that will be used to draw
+     * @param forceSrcMode whether the composite will have to be SRC
+     * @return the image to draw
+     */
+    private static BufferedImage getImageToDraw(Bitmap_Delegate bitmap, Paint_Delegate paint,
+            boolean[] forceSrcMode) {
+        BufferedImage image = bitmap.getImage();
+        forceSrcMode[0] = false;
+
+        // if the bitmap config is alpha_8, then we erase all color value from it
+        // before drawing it.
+        if (bitmap.getConfig() == Bitmap.Config.ALPHA_8) {
+            fixAlpha8Bitmap(image);
+        } else if (bitmap.hasAlpha() == false) {
+            // hasAlpha is merely a rendering hint. There can in fact be alpha values
+            // in the bitmap but it should be ignored at drawing time.
+            // There is two ways to do this:
+            // - override the composite to be SRC. This can only be used if the composite
+            //   was going to be SRC or SRC_OVER in the first place
+            // - Create a different bitmap to draw in which all the alpha channel values is set
+            //   to 0xFF.
+            if (paint != null) {
+                Xfermode_Delegate xfermodeDelegate = paint.getXfermode();
+                if (xfermodeDelegate instanceof PorterDuffXfermode_Delegate) {
+                    PorterDuff.Mode mode =
+                        ((PorterDuffXfermode_Delegate)xfermodeDelegate).getMode();
+
+                    forceSrcMode[0] = mode == PorterDuff.Mode.SRC_OVER ||
+                            mode == PorterDuff.Mode.SRC;
+                }
+            }
+
+            // if we can't force SRC mode, then create a temp bitmap of TYPE_RGB
+            if (forceSrcMode[0] == false) {
+                image = Bitmap_Delegate.createCopy(image, BufferedImage.TYPE_INT_RGB, 0xFF);
+            }
+        }
+
+        return image;
+    }
+
+    private static void fixAlpha8Bitmap(final BufferedImage image) {
+        int w = image.getWidth();
+        int h = image.getHeight();
+        int[] argb = new int[w * h];
+        image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth());
+
+        final int length = argb.length;
+        for (int i = 0 ; i < length; i++) {
+            argb[i] &= 0xFF000000;
+        }
+        image.setRGB(0, 0, w, h, argb, 0, w);
+    }
+}
+
diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
new file mode 100644
index 0000000..4c692c2
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate implementing the native methods of android.graphics.ColorFilter
+ *
+ * Through the layoutlib_create tool, the original native methods of ColorFilter have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original ColorFilter class.
+ *
+ * This also serve as a base class for all ColorFilter delegate classes.
+ *
+ * @see DelegateManager
+ *
+ */
+public abstract class ColorFilter_Delegate {
+
+    // ---- delegate manager ----
+    protected static final DelegateManager<ColorFilter_Delegate> sManager =
+            new DelegateManager<ColorFilter_Delegate>(ColorFilter_Delegate.class);
+
+    // ---- delegate helper data ----
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    public static ColorFilter_Delegate getDelegate(int nativeShader) {
+        return sManager.getDelegate(nativeShader);
+    }
+
+    public abstract boolean isSupported();
+    public abstract String getSupportMessage();
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static void finalizer(int native_instance) {
+        sManager.removeJavaReferenceFor(native_instance);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
new file mode 100644
index 0000000..d4c5b8d
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate implementing the native methods of android.graphics.ColorMatrixColorFilter
+ *
+ * Through the layoutlib_create tool, the original native methods of ColorMatrixColorFilter have
+ * been replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original ColorMatrixColorFilter class.
+ *
+ * Because this extends {@link ColorFilter_Delegate}, there's no need to use a
+ * {@link DelegateManager}, as all the Shader classes will be added to the manager
+ * owned by {@link ColorFilter_Delegate}.
+ *
+ * @see ColorFilter_Delegate
+ *
+ */
+public class ColorMatrixColorFilter_Delegate extends ColorFilter_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "ColorMatrix Color Filters are not supported.";
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeColorMatrixFilter(float[] array) {
+        ColorMatrixColorFilter_Delegate newDelegate = new ColorMatrixColorFilter_Delegate();
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java
new file mode 100644
index 0000000..7c04a87
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/ComposePathEffect_Delegate.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import java.awt.Stroke;
+
+/**
+ * Delegate implementing the native methods of android.graphics.ComposePathEffect
+ *
+ * Through the layoutlib_create tool, the original native methods of ComposePathEffect have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original ComposePathEffect class.
+ *
+ * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
+ * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
+ *
+ * @see PathEffect_Delegate
+ *
+ */
+public class ComposePathEffect_Delegate extends PathEffect_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public Stroke getStroke(Paint_Delegate paint) {
+        // FIXME
+        return null;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Compose Path Effects are not supported in Layout Preview mode.";
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreate(int outerpe, int innerpe) {
+        ComposePathEffect_Delegate newDelegate = new ComposePathEffect_Delegate();
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/ComposeShader.java b/tools/layoutlib/bridge/src/android/graphics/ComposeShader.java
deleted file mode 100644
index 863d64a..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/ComposeShader.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import java.awt.Paint;
-
-/** A subclass of shader that returns the composition of two other shaders, combined by
-    an {@link android.graphics.Xfermode} subclass.
-*/
-public class ComposeShader extends Shader {
-    /** Create a new compose shader, given shaders A, B, and a combining mode.
-        When the mode is applied, it will be given the result from shader A as its
-        "dst", and the result of from shader B as its "src".
-        @param shaderA  The colors from this shader are seen as the "dst" by the mode
-        @param shaderB  The colors from this shader are seen as the "src" by the mode
-        @param mode     The mode that combines the colors from the two shaders. If mode
-                        is null, then SRC_OVER is assumed.
-    */
-    public ComposeShader(Shader shaderA, Shader shaderB, Xfermode mode) {
-        // FIXME Implement shader
-    }
-
-    /** Create a new compose shader, given shaders A, B, and a combining PorterDuff mode.
-        When the mode is applied, it will be given the result from shader A as its
-        "dst", and the result of from shader B as its "src".
-        @param shaderA  The colors from this shader are seen as the "dst" by the mode
-        @param shaderB  The colors from this shader are seen as the "src" by the mode
-        @param mode     The PorterDuff mode that combines the colors from the two shaders.
-    */
-    public ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode) {
-        // FIXME Implement shader
-    }
-
-    @Override
-    Paint getJavaPaint() {
-        return null;
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java
new file mode 100644
index 0000000..fcc12d7
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/ComposeShader_Delegate.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import java.awt.Paint;
+
+/**
+ * Delegate implementing the native methods of android.graphics.ComposeShader
+ *
+ * Through the layoutlib_create tool, the original native methods of ComposeShader have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original ComposeShader class.
+ *
+ * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
+ * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
+ *
+ * @see Shader_Delegate
+ *
+ */
+public class ComposeShader_Delegate extends Shader_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public Paint getJavaPaint() {
+        // FIXME
+        return null;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Compose Shaders are not supported in Layout Preview mode.";
+    }
+
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreate1(int native_shaderA, int native_shaderB,
+            int native_mode) {
+        // FIXME not supported yet.
+        ComposeShader_Delegate newDelegate = new ComposeShader_Delegate();
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreate2(int native_shaderA, int native_shaderB,
+            int porterDuffMode) {
+        // FIXME not supported yet.
+        ComposeShader_Delegate newDelegate = new ComposeShader_Delegate();
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java
new file mode 100644
index 0000000..b0f8168
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/CornerPathEffect_Delegate.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import java.awt.Stroke;
+
+/**
+ * Delegate implementing the native methods of android.graphics.CornerPathEffect
+ *
+ * Through the layoutlib_create tool, the original native methods of CornerPathEffect have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original CornerPathEffect class.
+ *
+ * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
+ * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
+ *
+ * @see PathEffect_Delegate
+ *
+ */
+public class CornerPathEffect_Delegate extends PathEffect_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public Stroke getStroke(Paint_Delegate paint) {
+        // FIXME
+        return null;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Corner Path Effects are not supported in Layout Preview mode.";
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreate(float radius) {
+        CornerPathEffect_Delegate newDelegate = new CornerPathEffect_Delegate();
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect.java b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect.java
deleted file mode 100644
index 46d4c70..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-public class DashPathEffect extends PathEffect {
-
-    private final float[] mIntervals;
-    private final float mPhase;
-
-    /**
-     * The intervals array must contain an even number of entries (>=2), with
-     * the even indices specifying the "on" intervals, and the odd indices
-     * specifying the "off" intervals. phase is an offset into the intervals
-     * array (mod the sum of all of the intervals). The intervals array
-     * controls the length of the dashes. The paint's strokeWidth controls the
-     * thickness of the dashes.
-     * Note: this patheffect only affects drawing with the paint's style is set
-     * to STROKE or STROKE_AND_FILL. It is ignored if the drawing is done with
-     * style == FILL.
-     * @param intervals array of ON and OFF distances
-     * @param phase offset into the intervals array
-     */
-    public DashPathEffect(float intervals[], float phase) {
-        if (intervals.length < 2) {
-            throw new ArrayIndexOutOfBoundsException();
-        }
-
-        mIntervals = intervals;
-        mPhase = phase;
-    }
-
-    public float[] getIntervals() {
-        return mIntervals;
-    }
-
-    public float getPhase() {
-        return mPhase;
-    }
-}
-
diff --git a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
new file mode 100644
index 0000000..d97c2ec
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import java.awt.BasicStroke;
+import java.awt.Stroke;
+
+/**
+ * Delegate implementing the native methods of android.graphics.DashPathEffect
+ *
+ * Through the layoutlib_create tool, the original native methods of DashPathEffect have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original DashPathEffect class.
+ *
+ * Because this extends {@link PathEffect_Delegate}, there's no need to use a
+ * {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
+ * {@link PathEffect_Delegate}.
+ *
+ * @see PathEffect_Delegate
+ *
+ */
+public final class DashPathEffect_Delegate extends PathEffect_Delegate {
+
+    // ---- delegate data ----
+
+    private final float[] mIntervals;
+    private final float mPhase;
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public Stroke getStroke(Paint_Delegate paint) {
+        return new BasicStroke(
+                paint.getStrokeWidth(),
+                paint.getJavaCap(),
+                paint.getJavaJoin(),
+                paint.getJavaStrokeMiter(),
+                mIntervals,
+                mPhase);
+    }
+
+    @Override
+    public boolean isSupported() {
+        return true;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        // no message since isSupported returns true;
+        return null;
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreate(float intervals[], float phase) {
+        DashPathEffect_Delegate newDelegate = new DashPathEffect_Delegate(intervals, phase);
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+
+    private DashPathEffect_Delegate(float intervals[], float phase) {
+        mIntervals = new float[intervals.length];
+        System.arraycopy(intervals, 0, mIntervals, 0, intervals.length);
+        mPhase = phase;
+    }
+}
+
diff --git a/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java
new file mode 100644
index 0000000..ec4a810
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/DiscretePathEffect_Delegate.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import java.awt.Stroke;
+
+/**
+ * Delegate implementing the native methods of android.graphics.DiscretePathEffect
+ *
+ * Through the layoutlib_create tool, the original native methods of DiscretePathEffect have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original DiscretePathEffect class.
+ *
+ * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
+ * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
+ *
+ * @see PathEffect_Delegate
+ *
+ */
+public class DiscretePathEffect_Delegate extends PathEffect_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public Stroke getStroke(Paint_Delegate paint) {
+        // FIXME
+        return null;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Discrete Path Effects are not supported in Layout Preview mode.";
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreate(float length, float deviation) {
+        DiscretePathEffect_Delegate newDelegate = new DiscretePathEffect_Delegate();
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java
new file mode 100644
index 0000000..870c46b
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/DrawFilter_Delegate.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate implementing the native methods of android.graphics.DrawFilter
+ *
+ * Through the layoutlib_create tool, the original native methods of DrawFilter have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original DrawFilter class.
+ *
+ * This also serve as a base class for all DrawFilter delegate classes.
+ *
+ * @see DelegateManager
+ *
+ */
+public abstract class DrawFilter_Delegate {
+
+    // ---- delegate manager ----
+    protected static final DelegateManager<DrawFilter_Delegate> sManager =
+            new DelegateManager<DrawFilter_Delegate>(DrawFilter_Delegate.class);
+
+    // ---- delegate helper data ----
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    public static DrawFilter_Delegate getDelegate(int nativeDrawFilter) {
+        return sManager.getDelegate(nativeDrawFilter);
+    }
+
+    public abstract boolean isSupported();
+    public abstract String getSupportMessage();
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeDestructor(int nativeDrawFilter) {
+        sManager.removeJavaReferenceFor(nativeDrawFilter);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java
new file mode 100644
index 0000000..ebc1c1d
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/EmbossMaskFilter_Delegate.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate implementing the native methods of android.graphics.EmbossMaskFilter
+ *
+ * Through the layoutlib_create tool, the original native methods of EmbossMaskFilter have
+ * been replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original EmbossMaskFilter class.
+ *
+ * Because this extends {@link MaskFilter_Delegate}, there's no need to use a
+ * {@link DelegateManager}, as all the Shader classes will be added to the manager
+ * owned by {@link MaskFilter_Delegate}.
+ *
+ * @see MaskFilter_Delegate
+ *
+ */
+public class EmbossMaskFilter_Delegate extends MaskFilter_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Emboss Mask Filters are not supported.";
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeConstructor(float[] direction, float ambient,
+            float specular, float blurRadius) {
+        EmbossMaskFilter_Delegate newDelegate = new EmbossMaskFilter_Delegate();
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/GradientShader.java b/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
similarity index 84%
rename from tools/layoutlib/bridge/src/android/graphics/GradientShader.java
rename to tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
index 8c5a2a4..38c092d 100644
--- a/tools/layoutlib/bridge/src/android/graphics/GradientShader.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Gradient_Delegate.java
@@ -16,23 +16,28 @@
 
 package android.graphics;
 
+import android.graphics.Shader.TileMode;
 
 /**
- * Base class for Gradient shader. This is not a standard android class and is just used
- * as a base class for the re-implemented gradient classes.
- *
- * It also provides a base class to handle common code between the different shaders'
- * implementations of {@link java.awt.Paint}.
- *
- * @see LinearGradient
- * @see RadialGradient
- * @see SweepGradient
+ * Base class for true Gradient shader delegate.
  */
-public abstract class GradientShader extends Shader {
+public abstract class Gradient_Delegate extends Shader_Delegate {
 
     protected final int[] mColors;
     protected final float[] mPositions;
 
+    @Override
+    public boolean isSupported() {
+        // all gradient shaders are supported.
+        return true;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        // all gradient shaders are supported, no need for a gradient support
+        return null;
+    }
+
     /**
      * Creates the base shader and do some basic test on the parameters.
      *
@@ -41,7 +46,7 @@
      *            corresponding color in the colors array. If this is null, the
      *            the colors are distributed evenly along the gradient line.
      */
-    protected GradientShader(int colors[], float positions[]) {
+    protected Gradient_Delegate(int colors[], float positions[]) {
         if (colors.length < 2) {
             throw new IllegalArgumentException("needs >= 2 number of colors");
         }
@@ -90,7 +95,7 @@
          * Pre-computes the colors for the gradient. This must be called once before any call
          * to {@link #getGradientColor(float)}
          */
-        protected synchronized void precomputeGradientColors() {
+        protected void precomputeGradientColors() {
             if (mGradient == null) {
                 // actually create an array with an extra size, so that we can really go
                 // from 0 to SIZE (100%), or currentPos in the loop below will never equal 1.0
@@ -126,20 +131,23 @@
                             pos = 0.f;
                             break;
                         case REPEAT:
-                            // remove the integer part to stay in the [0,1] range
-                            // careful: this is a negative value, so use ceil instead of floor
-                            pos = pos - (float)Math.ceil(pos);
+                            // remove the integer part to stay in the [0,1] range.
+                            // we also need to invert the value from [-1,0] to [0, 1]
+                            pos = pos - (float)Math.floor(pos);
                             break;
                         case MIRROR:
+                            // this is the same as the positive side, just make the value positive
+                            // first.
+                            pos = Math.abs(pos);
+
                             // get the integer and the decimal part
-                            // careful: this is a negative value, so use ceil instead of floor
-                            int intPart = (int)Math.ceil(pos);
+                            int intPart = (int)Math.floor(pos);
                             pos = pos - intPart;
-                            // 0  -> -1 : mirrored order
-                            // -1 -> -2: normal order
+                            // 0 -> 1 : normal order
+                            // 1 -> 2: mirrored
                             // etc..
-                            // this means if the intpart is even we invert
-                            if ((intPart % 2) == 0) {
+                            // this means if the intpart is odd we invert
+                            if ((intPart % 2) == 1) {
                                 pos = 1.f - pos;
                             }
                             break;
@@ -199,7 +207,5 @@
         private int computeChannel(int c1, int c2, float percent) {
             return c1 + (int)((percent * (c2-c1)) + .5);
         }
-
-
     }
 }
diff --git a/tools/layoutlib/bridge/src/android/graphics/LayerRasterizer_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LayerRasterizer_Delegate.java
new file mode 100644
index 0000000..51e0576
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/LayerRasterizer_Delegate.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate implementing the native methods of android.graphics.LayerRasterizer
+ *
+ * Through the layoutlib_create tool, the original native methods of LayerRasterizer have
+ * been replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original LayerRasterizer class.
+ *
+ * Because this extends {@link Rasterizer_Delegate}, there's no need to use a
+ * {@link DelegateManager}, as all the Shader classes will be added to the manager
+ * owned by {@link Rasterizer_Delegate}.
+ *
+ * @see Rasterizer_Delegate
+ *
+ */
+public class LayerRasterizer_Delegate extends Rasterizer_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Layer Rasterizers are not supported.";
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeConstructor() {
+        LayerRasterizer_Delegate newDelegate = new LayerRasterizer_Delegate();
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeAddLayer(int native_layer, int native_paint, float dx, float dy) {
+
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
new file mode 100644
index 0000000..3afe965
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate implementing the native methods of android.graphics.LightingColorFilter
+ *
+ * Through the layoutlib_create tool, the original native methods of LightingColorFilter have
+ * been replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original LightingColorFilter class.
+ *
+ * Because this extends {@link ColorFilter_Delegate}, there's no need to use a
+ * {@link DelegateManager}, as all the Shader classes will be added to the manager
+ * owned by {@link ColorFilter_Delegate}.
+ *
+ * @see ColorFilter_Delegate
+ *
+ */
+public class LightingColorFilter_Delegate extends ColorFilter_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Lighting Color Filters are not supported.";
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int native_CreateLightingFilter(int mul, int add) {
+        LightingColorFilter_Delegate newDelegate = new LightingColorFilter_Delegate();
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/LinearGradient.java b/tools/layoutlib/bridge/src/android/graphics/LinearGradient.java
deleted file mode 100644
index 10c4a5e..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/LinearGradient.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-public class LinearGradient extends GradientShader {
-
-    private java.awt.Paint mJavaPaint;
-
-    /**
-     * Create a shader that draws a linear gradient along a line.
-     *
-     * @param x0 The x-coordinate for the start of the gradient line
-     * @param y0 The y-coordinate for the start of the gradient line
-     * @param x1 The x-coordinate for the end of the gradient line
-     * @param y1 The y-coordinate for the end of the gradient line
-     * @param colors The colors to be distributed along the gradient line
-     * @param positions May be null. The relative positions [0..1] of each
-     *            corresponding color in the colors array. If this is null, the
-     *            the colors are distributed evenly along the gradient line.
-     * @param tile The Shader tiling mode
-     */
-    public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],
-            TileMode tile) {
-        super(colors, positions);
-        mJavaPaint = new LinearGradientPaint(x0, y0, x1, y1, mColors, mPositions, tile);
-    }
-
-    /**
-     * Create a shader that draws a linear gradient along a line.
-     *
-     * @param x0 The x-coordinate for the start of the gradient line
-     * @param y0 The y-coordinate for the start of the gradient line
-     * @param x1 The x-coordinate for the end of the gradient line
-     * @param y1 The y-coordinate for the end of the gradient line
-     * @param color0 The color at the start of the gradient line.
-     * @param color1 The color at the end of the gradient line.
-     * @param tile The Shader tiling mode
-     */
-    public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1,
-            TileMode tile) {
-        this(x0, y0, x1, y1, new int[] { color0, color1}, null /*positions*/, tile);
-    }
-
-    // ---------- Custom Methods
-
-    @Override
-    java.awt.Paint getJavaPaint() {
-        return mJavaPaint;
-    }
-
-    /**
-     * Linear Gradient (Java) Paint able to handle more than 2 points, as
-     * {@link java.awt.GradientPaint} only supports 2 points and does not support Android's tile
-     * modes.
-     */
-    private static class LinearGradientPaint extends GradientPaint {
-
-        private final float mX0;
-        private final float mY0;
-        private final float mDx;
-        private final float mDy;
-        private final float mDSize2;
-
-        public LinearGradientPaint(float x0, float y0, float x1, float y1, int colors[],
-                float positions[], TileMode tile) {
-            super(colors, positions, tile);
-                mX0 = x0;
-                mY0 = y0;
-                mDx = x1 - x0;
-                mDy = y1 - y0;
-                mDSize2 = mDx * mDx + mDy * mDy;
-        }
-
-        public java.awt.PaintContext createContext(
-                java.awt.image.ColorModel      colorModel,
-                java.awt.Rectangle             deviceBounds,
-                java.awt.geom.Rectangle2D      userBounds,
-                java.awt.geom.AffineTransform  xform,
-                java.awt.RenderingHints        hints) {
-            precomputeGradientColors();
-            return new LinearGradientPaintContext(colorModel);
-        }
-
-        private class LinearGradientPaintContext implements java.awt.PaintContext {
-
-            private final java.awt.image.ColorModel mColorModel;
-
-            public LinearGradientPaintContext(java.awt.image.ColorModel colorModel) {
-                mColorModel = colorModel;
-                // FIXME: so far all this is always the same rect gotten in getRaster with an indentity matrix?
-            }
-
-            public void dispose() {
-            }
-
-            public java.awt.image.ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
-                        java.awt.image.BufferedImage.TYPE_INT_ARGB);
-
-                int[] data = new int[w*h];
-
-                if (mDx == 0) { // vertical gradient
-                    // compute first column and copy to all other columns
-                    int index = 0;
-                    for (int iy = 0 ; iy < h ; iy++) {
-                        int color = getColor(iy + y, mY0, mDy);
-                        for (int ix = 0 ; ix < w ; ix++) {
-                            data[index++] = color;
-                        }
-                    }
-                } else if (mDy == 0) { // horizontal
-                    // compute first line in a tmp array and copy to all lines
-                    int[] line = new int[w];
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        line[ix] = getColor(ix + x, mX0, mDx);
-                    }
-
-                    for (int iy = 0 ; iy < h ; iy++) {
-                        System.arraycopy(line, 0, data, iy*w, line.length);
-                    }
-                } else {
-                    int index = 0;
-                    for (int iy = 0 ; iy < h ; iy++) {
-                        for (int ix = 0 ; ix < w ; ix++) {
-                            data[index++] = getColor(ix + x, iy + y);
-                        }
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-        }
-
-        /** Returns a color for the easy vertical/horizontal mode */
-        private int getColor(float absPos, float refPos, float refSize) {
-            float pos = (absPos - refPos) / refSize;
-
-            return getGradientColor(pos);
-        }
-
-        /**
-         * Returns a color for an arbitrary point.
-         */
-        private int getColor(float x, float y) {
-            // find the x position on the gradient vector.
-            float _x = (mDx*mDy*(y-mY0) + mDy*mDy*mX0 + mDx*mDx*x) / mDSize2;
-            // from it get the position relative to the vector
-            float pos = (float) ((_x - mX0) / mDx);
-
-            return getGradientColor(pos);
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
new file mode 100644
index 0000000..a735ea1
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.graphics.Shader.TileMode;
+
+/**
+ * Delegate implementing the native methods of android.graphics.LinearGradient
+ *
+ * Through the layoutlib_create tool, the original native methods of LinearGradient have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original LinearGradient class.
+ *
+ * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
+ * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
+ *
+ * @see Shader_Delegate
+ *
+ */
+public final class LinearGradient_Delegate extends Gradient_Delegate {
+
+    // ---- delegate data ----
+    private java.awt.Paint mJavaPaint;
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public java.awt.Paint getJavaPaint() {
+        return mJavaPaint;
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreate1(
+            float x0, float y0, float x1, float y1,
+            int colors[], float positions[], int tileMode) {
+        LinearGradient_Delegate newDelegate = new LinearGradient_Delegate(x0, y0, x1, y1,
+                colors, positions, Shader_Delegate.getTileMode(tileMode));
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreate2(
+            float x0, float y0, float x1, float y1,
+            int color0, int color1, int tileMode) {
+        return nativeCreate1(x0, y0, x1, y1, new int[] { color0, color1}, null /*positions*/,
+                tileMode);
+    }
+
+    // ---- Private delegate/helper methods ----
+
+    /**
+     * Create a shader that draws a linear gradient along a line.
+     *
+     * @param x0 The x-coordinate for the start of the gradient line
+     * @param y0 The y-coordinate for the start of the gradient line
+     * @param x1 The x-coordinate for the end of the gradient line
+     * @param y1 The y-coordinate for the end of the gradient line
+     * @param colors The colors to be distributed along the gradient line
+     * @param positions May be null. The relative positions [0..1] of each
+     *            corresponding color in the colors array. If this is null, the
+     *            the colors are distributed evenly along the gradient line.
+     * @param tile The Shader tiling mode
+     */
+    private LinearGradient_Delegate(float x0, float y0, float x1, float y1,
+            int colors[], float positions[], TileMode tile) {
+        super(colors, positions);
+        mJavaPaint = new LinearGradientPaint(x0, y0, x1, y1, mColors, mPositions, tile);
+    }
+
+    // ---- Custom Java Paint ----
+    /**
+     * Linear Gradient (Java) Paint able to handle more than 2 points, as
+     * {@link java.awt.GradientPaint} only supports 2 points and does not support Android's tile
+     * modes.
+     */
+    private class LinearGradientPaint extends GradientPaint {
+
+        private final float mX0;
+        private final float mY0;
+        private final float mDx;
+        private final float mDy;
+        private final float mDSize2;
+
+        public LinearGradientPaint(float x0, float y0, float x1, float y1, int colors[],
+                float positions[], TileMode tile) {
+            super(colors, positions, tile);
+            mX0 = x0;
+            mY0 = y0;
+            mDx = x1 - x0;
+            mDy = y1 - y0;
+            mDSize2 = mDx * mDx + mDy * mDy;
+        }
+
+        public java.awt.PaintContext createContext(
+                java.awt.image.ColorModel      colorModel,
+                java.awt.Rectangle             deviceBounds,
+                java.awt.geom.Rectangle2D      userBounds,
+                java.awt.geom.AffineTransform  xform,
+                java.awt.RenderingHints        hints) {
+            precomputeGradientColors();
+
+            java.awt.geom.AffineTransform canvasMatrix;
+            try {
+                canvasMatrix = xform.createInverse();
+            } catch (java.awt.geom.NoninvertibleTransformException e) {
+                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
+                        "Unable to inverse matrix in LinearGradient", e, null /*data*/);
+                canvasMatrix = new java.awt.geom.AffineTransform();
+            }
+
+            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
+            try {
+                localMatrix = localMatrix.createInverse();
+            } catch (java.awt.geom.NoninvertibleTransformException e) {
+                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
+                        "Unable to inverse matrix in LinearGradient", e, null /*data*/);
+                localMatrix = new java.awt.geom.AffineTransform();
+            }
+
+            return new LinearGradientPaintContext(canvasMatrix, localMatrix, colorModel);
+        }
+
+        private class LinearGradientPaintContext implements java.awt.PaintContext {
+
+            private final java.awt.geom.AffineTransform mCanvasMatrix;
+            private final java.awt.geom.AffineTransform mLocalMatrix;
+            private final java.awt.image.ColorModel mColorModel;
+
+            private LinearGradientPaintContext(
+                    java.awt.geom.AffineTransform canvasMatrix,
+                    java.awt.geom.AffineTransform localMatrix,
+                    java.awt.image.ColorModel colorModel) {
+                mCanvasMatrix = canvasMatrix;
+                mLocalMatrix = localMatrix;
+                mColorModel = colorModel;
+            }
+
+            public void dispose() {
+            }
+
+            public java.awt.image.ColorModel getColorModel() {
+                return mColorModel;
+            }
+
+            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
+                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
+                        java.awt.image.BufferedImage.TYPE_INT_ARGB);
+
+                int[] data = new int[w*h];
+
+                int index = 0;
+                float[] pt1 = new float[2];
+                float[] pt2 = new float[2];
+                for (int iy = 0 ; iy < h ; iy++) {
+                    for (int ix = 0 ; ix < w ; ix++) {
+                        // handle the canvas transform
+                        pt1[0] = x + ix;
+                        pt1[1] = y + iy;
+                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
+
+                        // handle the local matrix.
+                        pt1[0] = pt2[0];
+                        pt1[1] = pt2[1];
+                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
+
+                        data[index++] = getColor(pt2[0], pt2[1]);
+                    }
+                }
+
+                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
+
+                return image.getRaster();
+            }
+        }
+
+        /**
+         * Returns a color for an arbitrary point.
+         */
+        private int getColor(float x, float y) {
+            float pos;
+            if (mDx == 0) {
+                pos = (y - mY0) / mDy;
+            } else if (mDy == 0) {
+                pos = (x - mX0) / mDx;
+            } else {
+                // find the x position on the gradient vector.
+                float _x = (mDx*mDy*(y-mY0) + mDy*mDy*mX0 + mDx*mDx*x) / mDSize2;
+                // from it get the position relative to the vector
+                pos = (_x - mX0) / mDx;
+            }
+
+            return getGradientColor(pos);
+        }
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java
new file mode 100644
index 0000000..c2f27e4
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/MaskFilter_Delegate.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate implementing the native methods of android.graphics.MaskFilter
+ *
+ * Through the layoutlib_create tool, the original native methods of MaskFilter have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original MaskFilter class.
+ *
+ * This also serve as a base class for all MaskFilter delegate classes.
+ *
+ * @see DelegateManager
+ *
+ */
+public abstract class MaskFilter_Delegate {
+
+    // ---- delegate manager ----
+    protected static final DelegateManager<MaskFilter_Delegate> sManager =
+            new DelegateManager<MaskFilter_Delegate>(MaskFilter_Delegate.class);
+
+    // ---- delegate helper data ----
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    public static MaskFilter_Delegate getDelegate(int nativeShader) {
+        return sManager.getDelegate(nativeShader);
+    }
+
+    public abstract boolean isSupported();
+    public abstract String getSupportMessage();
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeDestructor(int native_filter) {
+        sManager.removeJavaReferenceFor(native_filter);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix.java b/tools/layoutlib/bridge/src/android/graphics/Matrix.java
deleted file mode 100644
index 9e30671..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Matrix.java
+++ /dev/null
@@ -1,1032 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import java.awt.geom.AffineTransform;
-import java.awt.geom.NoninvertibleTransformException;
-
-
-/**
- * A matrix implementation overridden by the LayoutLib bridge.
- */
-public class Matrix extends _Original_Matrix {
-
-    float mValues[] = new float[9];
-
-    /**
-     * Create an identity matrix
-     */
-    public Matrix() {
-        reset();
-    }
-
-    /**
-     * Create a matrix that is a (deep) copy of src
-     * @param src The matrix to copy into this matrix
-     */
-    public Matrix(Matrix src) {
-        set(src);
-    }
-
-    /**
-     * Creates a Matrix object from the float array. The array becomes the internal storage
-     * of the object.
-     * @param data
-     */
-    private Matrix(float[] data) {
-        assert data.length != 9;
-        mValues = data;
-    }
-
-    //---------- Custom Methods
-
-    /**
-     * Adds the given transformation to the current Matrix
-     * <p/>This in effect does this = this*matrix
-     * @param matrix
-     */
-    private void addTransform(float[] matrix) {
-        float[] tmp = new float[9];
-
-        // first row
-        tmp[0] = matrix[0] * mValues[0] + matrix[1] * mValues[3] + matrix[2] * mValues[6];
-        tmp[1] = matrix[0] * mValues[1] + matrix[1] * mValues[4] + matrix[2] * mValues[7];
-        tmp[2] = matrix[0] * mValues[2] + matrix[1] * mValues[5] + matrix[2] * mValues[8];
-
-        // 2nd row
-        tmp[3] = matrix[3] * mValues[0] + matrix[4] * mValues[3] + matrix[5] * mValues[6];
-        tmp[4] = matrix[3] * mValues[1] + matrix[4] * mValues[4] + matrix[5] * mValues[7];
-        tmp[5] = matrix[3] * mValues[2] + matrix[4] * mValues[5] + matrix[5] * mValues[8];
-
-        // 3rd row
-        tmp[6] = matrix[6] * mValues[0] + matrix[7] * mValues[3] + matrix[8] * mValues[6];
-        tmp[7] = matrix[6] * mValues[1] + matrix[7] * mValues[4] + matrix[8] * mValues[7];
-        tmp[8] = matrix[6] * mValues[2] + matrix[7] * mValues[5] + matrix[8] * mValues[8];
-
-        // copy the result over to mValues
-        mValues = tmp;
-    }
-
-    public AffineTransform getTransform() {
-        // the AffineTransform constructor takes the value in a different order
-        // for a matrix [ 0 1 2 ]
-        //              [ 3 4 5 ]
-        // the order is 0, 3, 1, 4, 2, 5...
-        return new AffineTransform(mValues[0], mValues[3], mValues[1],
-                mValues[4], mValues[2], mValues[5]);
-    }
-
-    public boolean hasPerspective() {
-        return (mValues[6] != 0 || mValues[7] != 0 || mValues[8] != 1);
-    }
-
-    //----------
-
-    /**
-     * Returns true if the matrix is identity.
-     * This maybe faster than testing if (getType() == 0)
-     */
-    @Override
-    public boolean isIdentity() {
-        for (int i = 0, k = 0; i < 3; i++) {
-            for (int j = 0; j < 3; j++, k++) {
-                if (mValues[k] != ((i==j) ? 1 : 0)) {
-                    return false;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns true if will map a rectangle to another rectangle. This can be
-     * true if the matrix is identity, scale-only, or rotates a multiple of 90
-     * degrees.
-     */
-    @Override
-    public boolean rectStaysRect() {
-        return (computeTypeMask() & kRectStaysRect_Mask) != 0;
-    }
-
-    /**
-     * (deep) copy the src matrix into this matrix. If src is null, reset this
-     * matrix to the identity matrix.
-     */
-    public void set(Matrix src) {
-        if (src == null) {
-            reset();
-        } else {
-            System.arraycopy(src.mValues, 0, mValues, 0, mValues.length);
-        }
-    }
-
-    @Override
-    public void set(_Original_Matrix src) {
-        throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
-    }
-
-    /** Returns true if obj is a Matrix and its values equal our values.
-    */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj != null && obj instanceof Matrix) {
-            Matrix matrix = (Matrix)obj;
-            for (int i = 0 ; i < 9 ; i++) {
-                if (mValues[i] != matrix.mValues[i]) {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-
-        return false;
-    }
-
-    /** Set the matrix to identity */
-    @Override
-    public void reset() {
-        for (int i = 0, k = 0; i < 3; i++) {
-            for (int j = 0; j < 3; j++, k++) {
-                mValues[k] = ((i==j) ? 1 : 0);
-            }
-        }
-    }
-
-    /** Set the matrix to translate by (dx, dy). */
-    @Override
-    public void setTranslate(float dx, float dy) {
-        mValues[0] = 1;
-        mValues[1] = 0;
-        mValues[2] = dx;
-        mValues[3] = 0;
-        mValues[4] = 1;
-        mValues[5] = dy;
-        mValues[6] = 0;
-        mValues[7] = 0;
-        mValues[8] = 1;
-    }
-
-    /**
-     * Set the matrix to scale by sx and sy, with a pivot point at (px, py).
-     * The pivot point is the coordinate that should remain unchanged by the
-     * specified transformation.
-     */
-    @Override
-    public void setScale(float sx, float sy, float px, float py) {
-        // TODO: do it in one pass
-
-        // translate so that the pivot is in 0,0
-        mValues[0] = 1;
-        mValues[1] = 0;
-        mValues[2] = -px;
-        mValues[3] = 0;
-        mValues[4] = 1;
-        mValues[5] = -py;
-        mValues[6] = 0;
-        mValues[7] = 0;
-        mValues[8] = 1;
-
-        // scale
-        addTransform(new float[] { sx, 0, 0, 0, sy, 0, 0, 0, 1 });
-        // translate back the pivot
-        addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 });
-    }
-
-    /** Set the matrix to scale by sx and sy. */
-    @Override
-    public void setScale(float sx, float sy) {
-        mValues[0] = sx;
-        mValues[1] = 0;
-        mValues[2] = 0;
-        mValues[3] = 0;
-        mValues[4] = sy;
-        mValues[5] = 0;
-        mValues[6] = 0;
-        mValues[7] = 0;
-        mValues[8] = 1;
-    }
-
-    /**
-     * Set the matrix to rotate by the specified number of degrees, with a pivot
-     * point at (px, py). The pivot point is the coordinate that should remain
-     * unchanged by the specified transformation.
-     */
-    @Override
-    public void setRotate(float degrees, float px, float py) {
-        // TODO: do it in one pass
-
-        // translate so that the pivot is in 0,0
-        mValues[0] = 1;
-        mValues[1] = 0;
-        mValues[2] = -px;
-        mValues[3] = 0;
-        mValues[4] = 1;
-        mValues[5] = -py;
-        mValues[6] = 0;
-        mValues[7] = 0;
-        mValues[8] = 1;
-
-        // scale
-        double rad = Math.toRadians(degrees);
-        float cos = (float)Math.cos(rad);
-        float sin = (float)Math.sin(rad);
-        addTransform(new float[] { cos, -sin, 0, sin, cos, 0, 0, 0, 1 });
-        // translate back the pivot
-        addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 });
-    }
-
-    /**
-     * Set the matrix to rotate about (0,0) by the specified number of degrees.
-     */
-    @Override
-    public void setRotate(float degrees) {
-        double rad = Math.toRadians(degrees);
-        float cos = (float)Math.cos(rad);
-        float sin = (float)Math.sin(rad);
-
-        mValues[0] = cos;
-        mValues[1] = -sin;
-        mValues[2] = 0;
-        mValues[3] = sin;
-        mValues[4] = cos;
-        mValues[5] = 0;
-        mValues[6] = 0;
-        mValues[7] = 0;
-        mValues[8] = 1;
-    }
-
-    /**
-     * Set the matrix to rotate by the specified sine and cosine values, with a
-     * pivot point at (px, py). The pivot point is the coordinate that should
-     * remain unchanged by the specified transformation.
-     */
-    @Override
-    public void setSinCos(float sinValue, float cosValue, float px, float py) {
-        // TODO: do it in one pass
-
-        // translate so that the pivot is in 0,0
-        mValues[0] = 1;
-        mValues[1] = 0;
-        mValues[2] = -px;
-        mValues[3] = 0;
-        mValues[4] = 1;
-        mValues[5] = -py;
-        mValues[6] = 0;
-        mValues[7] = 0;
-        mValues[8] = 1;
-
-        // scale
-        addTransform(new float[] { cosValue, -sinValue, 0, sinValue, cosValue, 0, 0, 0, 1 });
-        // translate back the pivot
-        addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 });
-    }
-
-    /** Set the matrix to rotate by the specified sine and cosine values. */
-    @Override
-    public void setSinCos(float sinValue, float cosValue) {
-        mValues[0] = cosValue;
-        mValues[1] = -sinValue;
-        mValues[2] = 0;
-        mValues[3] = sinValue;
-        mValues[4] = cosValue;
-        mValues[5] = 0;
-        mValues[6] = 0;
-        mValues[7] = 0;
-        mValues[8] = 1;
-    }
-
-    /**
-     * Set the matrix to skew by sx and sy, with a pivot point at (px, py).
-     * The pivot point is the coordinate that should remain unchanged by the
-     * specified transformation.
-     */
-    @Override
-    public void setSkew(float kx, float ky, float px, float py) {
-        // TODO: do it in one pass
-
-        // translate so that the pivot is in 0,0
-        mValues[0] = 1;
-        mValues[1] = 0;
-        mValues[2] = -px;
-        mValues[3] = 0;
-        mValues[4] = 1;
-        mValues[5] = -py;
-        mValues[6] = 0;
-        mValues[7] = 0;
-        mValues[8] = 1;
-
-        // scale
-        addTransform(new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 });
-        // translate back the pivot
-        addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 });
-    }
-
-    /** Set the matrix to skew by sx and sy. */
-    @Override
-    public void setSkew(float kx, float ky) {
-        mValues[0] = 1;
-        mValues[1] = kx;
-        mValues[2] = -0;
-        mValues[3] = ky;
-        mValues[4] = 1;
-        mValues[5] = 0;
-        mValues[6] = 0;
-        mValues[7] = 0;
-        mValues[8] = 1;
-    }
-
-    /**
-     * Set the matrix to the concatenation of the two specified matrices,
-     * returning true if the the result can be represented. Either of the two
-     * matrices may also be the target matrix. this = a * b
-     */
-    public boolean setConcat(Matrix a, Matrix b) {
-        if (a == this) {
-            preConcat(b);
-        } else if (b == this) {
-            postConcat(b);
-        } else {
-            Matrix tmp = new Matrix(b);
-            tmp.addTransform(a.mValues);
-            set(tmp);
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean setConcat(_Original_Matrix a, _Original_Matrix b) {
-        throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
-    }
-
-    /**
-     * Preconcats the matrix with the specified translation.
-     * M' = M * T(dx, dy)
-     */
-    @Override
-    public boolean preTranslate(float dx, float dy) {
-        // create a matrix that will be multiply by this
-        Matrix m = new Matrix(new float[] { 1, 0, dx, 0, 1, dy, 0, 0, 1 });
-        m.addTransform(this.mValues);
-
-        System.arraycopy(m.mValues, 0, mValues, 0, 9);
-        return true;
-    }
-
-    /**
-     * Preconcats the matrix with the specified scale.
-     * M' = M * S(sx, sy, px, py)
-     */
-    @Override
-    public boolean preScale(float sx, float sy, float px, float py) {
-        Matrix m = new Matrix();
-        m.setScale(sx, sy, px, py);
-        m.addTransform(mValues);
-        set(m);
-
-        return true;
-    }
-
-    /**
-     * Preconcats the matrix with the specified scale.
-     * M' = M * S(sx, sy)
-     */
-    @Override
-    public boolean preScale(float sx, float sy) {
-        Matrix m = new Matrix();
-        m.setScale(sx, sy);
-        m.addTransform(mValues);
-        set(m);
-
-        return true;
-    }
-
-    /**
-     * Preconcats the matrix with the specified rotation.
-     * M' = M * R(degrees, px, py)
-     */
-    @Override
-    public boolean preRotate(float degrees, float px, float py) {
-        Matrix m = new Matrix();
-        m.setRotate(degrees, px, py);
-        m.addTransform(mValues);
-        set(m);
-
-        return true;
-    }
-
-    /**
-     * Preconcats the matrix with the specified rotation.
-     * M' = M * R(degrees)
-     */
-    @Override
-    public boolean preRotate(float degrees) {
-        Matrix m = new Matrix();
-        m.setRotate(degrees);
-        m.addTransform(mValues);
-        set(m);
-
-        return true;
-    }
-
-    /**
-     * Preconcats the matrix with the specified skew.
-     * M' = M * K(kx, ky, px, py)
-     */
-    @Override
-    public boolean preSkew(float kx, float ky, float px, float py) {
-        Matrix m = new Matrix();
-        m.setSkew(kx, ky, px, py);
-        m.addTransform(mValues);
-        set(m);
-
-        return true;
-    }
-
-    /**
-     * Preconcats the matrix with the specified skew.
-     * M' = M * K(kx, ky)
-     */
-    @Override
-    public boolean preSkew(float kx, float ky) {
-        Matrix m = new Matrix();
-        m.setSkew(kx, ky);
-        m.addTransform(mValues);
-        set(m);
-
-        return true;
-    }
-
-    /**
-     * Preconcats the matrix with the specified matrix.
-     * M' = M * other
-     */
-    public boolean preConcat(Matrix other) {
-        Matrix m = new Matrix(other);
-        other.addTransform(mValues);
-        set(m);
-
-        return true;
-    }
-
-    @Override
-    public boolean preConcat(_Original_Matrix other) {
-        throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
-    }
-
-    /**
-     * Postconcats the matrix with the specified translation.
-     * M' = T(dx, dy) * M
-     */
-    @Override
-    public boolean postTranslate(float dx, float dy) {
-        addTransform(new float[] { 1, 0, dx, 0, 1, dy, 0, 0, 1 });
-        return true;
-    }
-
-    /**
-     * Postconcats the matrix with the specified scale.
-     * M' = S(sx, sy, px, py) * M
-     */
-    @Override
-    public boolean postScale(float sx, float sy, float px, float py) {
-        // TODO: do it in one pass
-        // translate so that the pivot is in 0,0
-        addTransform(new float[] { 1, 0, -px, 0, 1, py, 0, 0, 1 });
-        // scale
-        addTransform(new float[] { sx, 0, 0, 0, sy, 0, 0, 0, 1 });
-        // translate back the pivot
-        addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 });
-
-        return true;
-    }
-
-    /**
-     * Postconcats the matrix with the specified scale.
-     * M' = S(sx, sy) * M
-     */
-    @Override
-    public boolean postScale(float sx, float sy) {
-        addTransform(new float[] { sx, 0, 0, 0, sy, 0, 0, 0, 1 });
-        return true;
-    }
-
-    /**
-     * Postconcats the matrix with the specified rotation.
-     * M' = R(degrees, px, py) * M
-     */
-    @Override
-    public boolean postRotate(float degrees, float px, float py) {
-        // TODO: do it in one pass
-        // translate so that the pivot is in 0,0
-        addTransform(new float[] { 1, 0, -px, 0, 1, py, 0, 0, 1 });
-        // scale
-        double rad = Math.toRadians(degrees);
-        float cos = (float)Math.cos(rad);
-        float sin = (float)Math.sin(rad);
-        addTransform(new float[] { cos, -sin, 0, sin, cos, 0, 0, 0, 1 });
-        // translate back the pivot
-        addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 });
-
-        return true;
-    }
-
-    /**
-     * Postconcats the matrix with the specified rotation.
-     * M' = R(degrees) * M
-     */
-    @Override
-    public boolean postRotate(float degrees) {
-        double rad = Math.toRadians(degrees);
-        float cos = (float)Math.cos(rad);
-        float sin = (float)Math.sin(rad);
-        addTransform(new float[] { cos, -sin, 0, sin, cos, 0, 0, 0, 1 });
-
-        return true;
-    }
-
-    /**
-     * Postconcats the matrix with the specified skew.
-     * M' = K(kx, ky, px, py) * M
-     */
-    @Override
-    public boolean postSkew(float kx, float ky, float px, float py) {
-        // TODO: do it in one pass
-        // translate so that the pivot is in 0,0
-        addTransform(new float[] { 1, 0, -px, 0, 1, py, 0, 0, 1 });
-        // scale
-        addTransform(new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 });
-        // translate back the pivot
-        addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 });
-
-        return true;
-    }
-
-    /**
-     * Postconcats the matrix with the specified skew.
-     * M' = K(kx, ky) * M
-     */
-    @Override
-    public boolean postSkew(float kx, float ky) {
-        addTransform(new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 });
-
-        return true;
-    }
-
-    /**
-     * Postconcats the matrix with the specified matrix.
-     * M' = other * M
-     */
-    public boolean postConcat(Matrix other) {
-        addTransform(other.mValues);
-
-        return true;
-    }
-
-    @Override
-    public boolean postConcat(_Original_Matrix other) {
-        throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
-    }
-
-    /** Controlls how the src rect should align into the dst rect for
-        setRectToRect().
-    */
-    public enum ScaleToFit {
-        /**
-         * Scale in X and Y independently, so that src matches dst exactly.
-         * This may change the aspect ratio of the src.
-         */
-        FILL    (0),
-        /**
-         * Compute a scale that will maintain the original src aspect ratio,
-         * but will also ensure that src fits entirely inside dst. At least one
-         * axis (X or Y) will fit exactly. START aligns the result to the
-         * left and top edges of dst.
-         */
-        START   (1),
-        /**
-         * Compute a scale that will maintain the original src aspect ratio,
-         * but will also ensure that src fits entirely inside dst. At least one
-         * axis (X or Y) will fit exactly. The result is centered inside dst.
-         */
-        CENTER  (2),
-        /**
-         * Compute a scale that will maintain the original src aspect ratio,
-         * but will also ensure that src fits entirely inside dst. At least one
-         * axis (X or Y) will fit exactly. END aligns the result to the
-         * right and bottom edges of dst.
-         */
-        END     (3);
-
-        // the native values must match those in SkMatrix.h
-        ScaleToFit(int nativeInt) {
-            this.nativeInt = nativeInt;
-        }
-        final int nativeInt;
-    }
-
-    /**
-     * Set the matrix to the scale and translate values that map the source
-     * rectangle to the destination rectangle, returning true if the result
-     * can be represented.
-     *
-     * @param src the source rectangle to map from.
-     * @param dst the destination rectangle to map to.
-     * @param stf the ScaleToFit option
-     * @return true if the matrix can be represented by the rectangle mapping.
-     */
-    public boolean setRectToRect(RectF src, RectF dst, ScaleToFit stf) {
-        if (dst == null || src == null) {
-            throw new NullPointerException();
-        }
-
-        if (src.isEmpty()) {
-            reset();
-            return false;
-        }
-
-        if (dst.isEmpty()) {
-            mValues[0] = mValues[1] = mValues[2] = mValues[3] = mValues[4] = mValues[5]
-               = mValues[6] = mValues[7] = 0;
-            mValues[8] = 1;
-        } else {
-            float    tx, sx = dst.width() / src.width();
-            float    ty, sy = dst.height() / src.height();
-            boolean  xLarger = false;
-
-            if (stf != ScaleToFit.FILL) {
-                if (sx > sy) {
-                    xLarger = true;
-                    sx = sy;
-                } else {
-                    sy = sx;
-                }
-            }
-
-            tx = dst.left - src.left * sx;
-            ty = dst.top - src.top * sy;
-            if (stf == ScaleToFit.CENTER || stf == ScaleToFit.END) {
-                float diff;
-
-                if (xLarger) {
-                    diff = dst.width() - src.width() * sy;
-                } else {
-                    diff = dst.height() - src.height() * sy;
-                }
-
-                if (stf == ScaleToFit.CENTER) {
-                    diff = diff / 2;
-                }
-
-                if (xLarger) {
-                    tx += diff;
-                } else {
-                    ty += diff;
-                }
-            }
-
-            mValues[0] = sx;
-            mValues[4] = sy;
-            mValues[2] = tx;
-            mValues[5] = ty;
-            mValues[1]  = mValues[3] = mValues[6] = mValues[7] = 0;
-
-        }
-        // shared cleanup
-        mValues[8] = 1;
-        return true;
-    }
-
-    @Override
-    public boolean setRectToRect(RectF src, RectF dst, _Original_Matrix.ScaleToFit stf) {
-        throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
-    }
-
-    /**
-     * Set the matrix such that the specified src points would map to the
-     * specified dst points. The "points" are represented as an array of floats,
-     * order [x0, y0, x1, y1, ...], where each "point" is 2 float values.
-     *
-     * @param src   The array of src [x,y] pairs (points)
-     * @param srcIndex Index of the first pair of src values
-     * @param dst   The array of dst [x,y] pairs (points)
-     * @param dstIndex Index of the first pair of dst values
-     * @param pointCount The number of pairs/points to be used. Must be [0..4]
-     * @return true if the matrix was set to the specified transformation
-     */
-    @Override
-    public boolean setPolyToPoly(float[] src, int srcIndex,
-                                 float[] dst, int dstIndex,
-                                 int pointCount) {
-        if (pointCount > 4) {
-            throw new IllegalArgumentException();
-        }
-        checkPointArrays(src, srcIndex, dst, dstIndex, pointCount);
-        throw new UnsupportedOperationException("STUB NEEDED");
-    }
-
-    /**
-     * If this matrix can be inverted, return true and if inverse is not null,
-     * set inverse to be the inverse of this matrix. If this matrix cannot be
-     * inverted, ignore inverse and return false.
-     */
-    public boolean invert(Matrix inverse) {
-        if (inverse == null) {
-            return false;
-        }
-
-        try {
-            AffineTransform affineTransform = getTransform();
-            AffineTransform inverseTransform = affineTransform.createInverse();
-            inverse.mValues[0] = (float)inverseTransform.getScaleX();
-            inverse.mValues[1] = (float)inverseTransform.getShearX();
-            inverse.mValues[2] = (float)inverseTransform.getTranslateX();
-            inverse.mValues[3] = (float)inverseTransform.getScaleX();
-            inverse.mValues[4] = (float)inverseTransform.getShearY();
-            inverse.mValues[5] = (float)inverseTransform.getTranslateY();
-
-            return true;
-        } catch (NoninvertibleTransformException e) {
-            return false;
-        }
-    }
-
-    @Override
-    public boolean invert(_Original_Matrix inverse) {
-        throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
-    }
-
-    /**
-    * Apply this matrix to the array of 2D points specified by src, and write
-     * the transformed points into the array of points specified by dst. The
-     * two arrays represent their "points" as pairs of floats [x, y].
-     *
-     * @param dst   The array of dst points (x,y pairs)
-     * @param dstIndex The index of the first [x,y] pair of dst floats
-     * @param src   The array of src points (x,y pairs)
-     * @param srcIndex The index of the first [x,y] pair of src floats
-     * @param pointCount The number of points (x,y pairs) to transform
-     */
-    @Override
-    public void mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex,
-                          int pointCount) {
-        checkPointArrays(src, srcIndex, dst, dstIndex, pointCount);
-
-        for (int i = 0 ; i < pointCount ; i++) {
-            // just in case we are doing in place, we better put this in temp vars
-            float x = mValues[0] * src[i + srcIndex] +
-                      mValues[1] * src[i + srcIndex + 1] +
-                      mValues[2];
-            float y = mValues[3] * src[i + srcIndex] +
-                      mValues[4] * src[i + srcIndex + 1] +
-                      mValues[5];
-
-            dst[i + dstIndex]     = x;
-            dst[i + dstIndex + 1] = y;
-        }
-    }
-
-    /**
-    * Apply this matrix to the array of 2D vectors specified by src, and write
-     * the transformed vectors into the array of vectors specified by dst. The
-     * two arrays represent their "vectors" as pairs of floats [x, y].
-     *
-     * @param dst   The array of dst vectors (x,y pairs)
-     * @param dstIndex The index of the first [x,y] pair of dst floats
-     * @param src   The array of src vectors (x,y pairs)
-     * @param srcIndex The index of the first [x,y] pair of src floats
-     * @param vectorCount The number of vectors (x,y pairs) to transform
-     */
-    @Override
-    public void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex,
-                          int vectorCount) {
-        checkPointArrays(src, srcIndex, dst, dstIndex, vectorCount);
-        throw new UnsupportedOperationException("STUB NEEDED");
-    }
-
-    /**
-     * Apply this matrix to the array of 2D points specified by src, and write
-     * the transformed points into the array of points specified by dst. The
-     * two arrays represent their "points" as pairs of floats [x, y].
-     *
-     * @param dst   The array of dst points (x,y pairs)
-     * @param src   The array of src points (x,y pairs)
-     */
-    @Override
-    public void mapPoints(float[] dst, float[] src) {
-        if (dst.length != src.length) {
-            throw new ArrayIndexOutOfBoundsException();
-        }
-        mapPoints(dst, 0, src, 0, dst.length >> 1);
-    }
-
-    /**
-     * Apply this matrix to the array of 2D vectors specified by src, and write
-     * the transformed vectors into the array of vectors specified by dst. The
-     * two arrays represent their "vectors" as pairs of floats [x, y].
-     *
-     * @param dst   The array of dst vectors (x,y pairs)
-     * @param src   The array of src vectors (x,y pairs)
-     */
-    @Override
-    public void mapVectors(float[] dst, float[] src) {
-        if (dst.length != src.length) {
-            throw new ArrayIndexOutOfBoundsException();
-        }
-        mapVectors(dst, 0, src, 0, dst.length >> 1);
-    }
-
-    /**
-     * Apply this matrix to the array of 2D points, and write the transformed
-     * points back into the array
-     *
-     * @param pts The array [x0, y0, x1, y1, ...] of points to transform.
-     */
-    @Override
-    public void mapPoints(float[] pts) {
-        mapPoints(pts, 0, pts, 0, pts.length >> 1);
-    }
-
-    /**
-     * Apply this matrix to the array of 2D vectors, and write the transformed
-     * vectors back into the array.
-     * @param vecs The array [x0, y0, x1, y1, ...] of vectors to transform.
-     */
-    @Override
-    public void mapVectors(float[] vecs) {
-        mapVectors(vecs, 0, vecs, 0, vecs.length >> 1);
-    }
-
-    /**
-     * Apply this matrix to the src rectangle, and write the transformed
-     * rectangle into dst. This is accomplished by transforming the 4 corners of
-     * src, and then setting dst to the bounds of those points.
-     *
-     * @param dst Where the transformed rectangle is written.
-     * @param src The original rectangle to be transformed.
-     * @return the result of calling rectStaysRect()
-     */
-    @Override
-    public boolean mapRect(RectF dst, RectF src) {
-        if (dst == null || src == null) {
-            throw new NullPointerException();
-        }
-
-        // array with 4 corners
-        float[] corners = new float[] {
-                src.left, src.top,
-                src.right, src.top,
-                src.right, src.bottom,
-                src.left, src.bottom,
-        };
-
-        // apply the transform to them.
-        mapPoints(corners);
-
-        // now put the result in the rect. We take the min/max of Xs and min/max of Ys
-        dst.left = Math.min(Math.min(corners[0], corners[2]), Math.min(corners[4], corners[6]));
-        dst.right = Math.max(Math.max(corners[0], corners[2]), Math.max(corners[4], corners[6]));
-
-        dst.top = Math.min(Math.min(corners[1], corners[3]), Math.min(corners[5], corners[7]));
-        dst.bottom = Math.max(Math.max(corners[1], corners[3]), Math.max(corners[5], corners[7]));
-
-        return rectStaysRect();
-    }
-
-    /**
-     * Apply this matrix to the rectangle, and write the transformed rectangle
-     * back into it. This is accomplished by transforming the 4 corners of rect,
-     * and then setting it to the bounds of those points
-     *
-     * @param rect The rectangle to transform.
-     * @return the result of calling rectStaysRect()
-     */
-    @Override
-    public boolean mapRect(RectF rect) {
-        return mapRect(rect, rect);
-    }
-
-    /**
-     * Return the mean radius of a circle after it has been mapped by
-     * this matrix. NOTE: in perspective this value assumes the circle
-     * has its center at the origin.
-     */
-    @Override
-    public float mapRadius(float radius) {
-        throw new UnsupportedOperationException("STUB NEEDED");
-    }
-
-    /** Copy 9 values from the matrix into the array.
-    */
-    @Override
-    public void getValues(float[] values) {
-        if (values.length < 9) {
-            throw new ArrayIndexOutOfBoundsException();
-        }
-        System.arraycopy(mValues, 0, values, 0, mValues.length);
-    }
-
-    /** Copy 9 values from the array into the matrix.
-        Depending on the implementation of Matrix, these may be
-        transformed into 16.16 integers in the Matrix, such that
-        a subsequent call to getValues() will not yield exactly
-        the same values.
-    */
-    @Override
-    public void setValues(float[] values) {
-        if (values.length < 9) {
-            throw new ArrayIndexOutOfBoundsException();
-        }
-        System.arraycopy(values, 0, mValues, 0, mValues.length);
-    }
-
-    @SuppressWarnings("unused")
-    private final static int kIdentity_Mask      = 0;
-    private final static int kTranslate_Mask     = 0x01;  //!< set if the matrix has translation
-    private final static int kScale_Mask         = 0x02;  //!< set if the matrix has X or Y scale
-    private final static int kAffine_Mask        = 0x04;  //!< set if the matrix skews or rotates
-    private final static int kPerspective_Mask   = 0x08;  //!< set if the matrix is in perspective
-    private final static int kRectStaysRect_Mask = 0x10;
-    @SuppressWarnings("unused")
-    private final static int kUnknown_Mask       = 0x80;
-
-    @SuppressWarnings("unused")
-    private final static int kAllMasks           = kTranslate_Mask |
-                                                     kScale_Mask |
-                                                     kAffine_Mask |
-                                                     kPerspective_Mask |
-                                                     kRectStaysRect_Mask;
-
-    // these guys align with the masks, so we can compute a mask from a variable 0/1
-    @SuppressWarnings("unused")
-    private final static int kTranslate_Shift = 0;
-    @SuppressWarnings("unused")
-    private final static int kScale_Shift = 1;
-    @SuppressWarnings("unused")
-    private final static int kAffine_Shift = 2;
-    @SuppressWarnings("unused")
-    private final static int kPerspective_Shift = 3;
-    private final static int kRectStaysRect_Shift = 4;
-
-    private int computeTypeMask() {
-        int mask = 0;
-
-        if (mValues[6] != 0. || mValues[7] != 0. || mValues[8] != 1.) {
-            mask |= kPerspective_Mask;
-        }
-
-        if (mValues[2] != 0. || mValues[5] != 0.) {
-            mask |= kTranslate_Mask;
-        }
-
-        float m00 = mValues[0];
-        float m01 = mValues[1];
-        float m10 = mValues[3];
-        float m11 = mValues[4];
-
-        if (m01 != 0. || m10 != 0.) {
-            mask |= kAffine_Mask;
-        }
-
-        if (m00 != 1. || m11 != 1.) {
-            mask |= kScale_Mask;
-        }
-
-        if ((mask & kPerspective_Mask) == 0) {
-            // map non-zero to 1
-            int im00 = m00 != 0 ? 1 : 0;
-            int im01 = m01 != 0 ? 1 : 0;
-            int im10 = m10 != 0 ? 1 : 0;
-            int im11 = m11 != 0 ? 1 : 0;
-
-            // record if the (p)rimary and (s)econdary diagonals are all 0 or
-            // all non-zero (answer is 0 or 1)
-            int dp0 = (im00 | im11) ^ 1;  // true if both are 0
-            int dp1 = im00 & im11;        // true if both are 1
-            int ds0 = (im01 | im10) ^ 1;  // true if both are 0
-            int ds1 = im01 & im10;        // true if both are 1
-
-            // return 1 if primary is 1 and secondary is 0 or
-            // primary is 0 and secondary is 1
-            mask |= ((dp0 & ds1) | (dp1 & ds0)) << kRectStaysRect_Shift;
-        }
-
-        return mask;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
new file mode 100644
index 0000000..451edd2
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
@@ -0,0 +1,1129 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.graphics.Matrix.ScaleToFit;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+
+/**
+ * Delegate implementing the native methods of android.graphics.Matrix
+ *
+ * Through the layoutlib_create tool, the original native methods of Matrix have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original Matrix class.
+ *
+ * @see DelegateManager
+ *
+ */
+public final class Matrix_Delegate {
+
+    private final static int MATRIX_SIZE = 9;
+
+    // ---- delegate manager ----
+    private static final DelegateManager<Matrix_Delegate> sManager =
+            new DelegateManager<Matrix_Delegate>(Matrix_Delegate.class);
+
+    // ---- delegate data ----
+    private float mValues[] = new float[MATRIX_SIZE];
+
+    // ---- Public Helper methods ----
+
+    public static Matrix_Delegate getDelegate(int native_instance) {
+        return sManager.getDelegate(native_instance);
+    }
+
+    /**
+     * Returns an {@link AffineTransform} matching the given Matrix.
+     */
+    public static AffineTransform getAffineTransform(Matrix m) {
+        Matrix_Delegate delegate = sManager.getDelegate(m.native_instance);
+        if (delegate == null) {
+            return null;
+        }
+
+        return delegate.getAffineTransform();
+    }
+
+    public static boolean hasPerspective(Matrix m) {
+        Matrix_Delegate delegate = sManager.getDelegate(m.native_instance);
+        if (delegate == null) {
+            return false;
+        }
+
+        return delegate.hasPerspective();
+    }
+
+    /**
+     * Sets the content of the matrix with the content of another matrix.
+     */
+    public void set(Matrix_Delegate matrix) {
+        System.arraycopy(matrix.mValues, 0, mValues, 0, MATRIX_SIZE);
+    }
+
+    /**
+     * Sets the content of the matrix with the content of another matrix represented as an array
+     * of values.
+     */
+    public void set(float[] values) {
+        System.arraycopy(values, 0, mValues, 0, MATRIX_SIZE);
+    }
+
+    /**
+     * Resets the matrix to be the identity matrix.
+     */
+    public void reset() {
+        reset(mValues);
+    }
+
+    /**
+     * Returns whether or not the matrix is identity.
+     */
+    public boolean isIdentity() {
+        for (int i = 0, k = 0; i < 3; i++) {
+            for (int j = 0; j < 3; j++, k++) {
+                if (mValues[k] != ((i==j) ? 1 : 0)) {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    public static float[] makeValues(AffineTransform matrix) {
+        float[] values = new float[MATRIX_SIZE];
+        values[0] = (float) matrix.getScaleX();
+        values[1] = (float) matrix.getShearX();
+        values[2] = (float) matrix.getTranslateX();
+        values[3] = (float) matrix.getShearY();
+        values[4] = (float) matrix.getScaleY();
+        values[5] = (float) matrix.getTranslateY();
+        values[6] = 0.f;
+        values[7] = 0.f;
+        values[8] = 1.f;
+
+        return values;
+    }
+
+    public static Matrix_Delegate make(AffineTransform matrix) {
+        return new Matrix_Delegate(makeValues(matrix));
+    }
+
+    public boolean mapRect(RectF dst, RectF src) {
+        // array with 4 corners
+        float[] corners = new float[] {
+                src.left, src.top,
+                src.right, src.top,
+                src.right, src.bottom,
+                src.left, src.bottom,
+        };
+
+        // apply the transform to them.
+        mapPoints(corners);
+
+        // now put the result in the rect. We take the min/max of Xs and min/max of Ys
+        dst.left = Math.min(Math.min(corners[0], corners[2]), Math.min(corners[4], corners[6]));
+        dst.right = Math.max(Math.max(corners[0], corners[2]), Math.max(corners[4], corners[6]));
+
+        dst.top = Math.min(Math.min(corners[1], corners[3]), Math.min(corners[5], corners[7]));
+        dst.bottom = Math.max(Math.max(corners[1], corners[3]), Math.max(corners[5], corners[7]));
+
+
+        return (computeTypeMask() & kRectStaysRect_Mask) != 0;
+    }
+
+
+    /**
+     * Returns an {@link AffineTransform} matching the matrix.
+     */
+    public AffineTransform getAffineTransform() {
+        return getAffineTransform(mValues);
+    }
+
+    public boolean hasPerspective() {
+        return (mValues[6] != 0 || mValues[7] != 0 || mValues[8] != 1);
+    }
+
+
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int native_create(int native_src_or_zero) {
+        // create the delegate
+        Matrix_Delegate newDelegate = new Matrix_Delegate();
+
+        // copy from values if needed.
+        if (native_src_or_zero > 0) {
+            Matrix_Delegate oldDelegate = sManager.getDelegate(native_src_or_zero);
+            if (oldDelegate != null) {
+                System.arraycopy(
+                        oldDelegate.mValues, 0,
+                        newDelegate.mValues, 0,
+                        MATRIX_SIZE);
+            }
+        }
+
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_isIdentity(int native_object) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        return d.isIdentity();
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_rectStaysRect(int native_object) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return true;
+        }
+
+        return (d.computeTypeMask() & kRectStaysRect_Mask) != 0;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_reset(int native_object) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return;
+        }
+
+        reset(d.mValues);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_set(int native_object, int other) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return;
+        }
+
+        Matrix_Delegate src = sManager.getDelegate(other);
+        if (src == null) {
+            return;
+        }
+
+        System.arraycopy(src.mValues, 0, d.mValues, 0, MATRIX_SIZE);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setTranslate(int native_object, float dx, float dy) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return;
+        }
+
+        setTranslate(d.mValues, dx, dy);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setScale(int native_object, float sx, float sy,
+            float px, float py) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return;
+        }
+
+        d.mValues = getScale(sx, sy, px, py);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setScale(int native_object, float sx, float sy) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return;
+        }
+
+        d.mValues[0] = sx;
+        d.mValues[1] = 0;
+        d.mValues[2] = 0;
+        d.mValues[3] = 0;
+        d.mValues[4] = sy;
+        d.mValues[5] = 0;
+        d.mValues[6] = 0;
+        d.mValues[7] = 0;
+        d.mValues[8] = 1;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setRotate(int native_object, float degrees, float px, float py) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return;
+        }
+
+        d.mValues = getRotate(degrees, px, py);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setRotate(int native_object, float degrees) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return;
+        }
+
+        setRotate(d.mValues, degrees);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setSinCos(int native_object, float sinValue, float cosValue,
+            float px, float py) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return;
+        }
+
+        // TODO: do it in one pass
+
+        // translate so that the pivot is in 0,0
+        setTranslate(d.mValues, -px, -py);
+
+        // scale
+        d.postTransform(getRotate(sinValue, cosValue));
+        // translate back the pivot
+        d.postTransform(getTranslate(px, py));
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setSinCos(int native_object, float sinValue, float cosValue) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return;
+        }
+
+        setRotate(d.mValues, sinValue, cosValue);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setSkew(int native_object, float kx, float ky,
+            float px, float py) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return;
+        }
+
+        d.mValues = getSkew(kx, ky, px, py);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setSkew(int native_object, float kx, float ky) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return;
+        }
+
+        d.mValues[0] = 1;
+        d.mValues[1] = kx;
+        d.mValues[2] = -0;
+        d.mValues[3] = ky;
+        d.mValues[4] = 1;
+        d.mValues[5] = 0;
+        d.mValues[6] = 0;
+        d.mValues[7] = 0;
+        d.mValues[8] = 1;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_setConcat(int native_object, int a, int b) {
+        if (a == native_object) {
+            return native_preConcat(native_object, b);
+        } else if (b == native_object) {
+            return native_postConcat(native_object, a);
+        }
+
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        Matrix_Delegate a_mtx = sManager.getDelegate(a);
+        if (a_mtx == null) {
+            return false;
+        }
+
+        Matrix_Delegate b_mtx = sManager.getDelegate(b);
+        if (b_mtx == null) {
+            return false;
+        }
+
+        multiply(d.mValues, a_mtx.mValues, b_mtx.mValues);
+
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_preTranslate(int native_object, float dx, float dy) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        d.preTransform(getTranslate(dx, dy));
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_preScale(int native_object, float sx, float sy,
+            float px, float py) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        d.preTransform(getScale(sx, sy, px, py));
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_preScale(int native_object, float sx, float sy) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        d.preTransform(getScale(sx, sy));
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_preRotate(int native_object, float degrees,
+            float px, float py) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        d.preTransform(getRotate(degrees, px, py));
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_preRotate(int native_object, float degrees) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        double rad = Math.toRadians(degrees);
+        float sin = (float)Math.sin(rad);
+        float cos = (float)Math.cos(rad);
+
+        d.preTransform(getRotate(sin, cos));
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_preSkew(int native_object, float kx, float ky,
+            float px, float py) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        d.preTransform(getSkew(kx, ky, px, py));
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_preSkew(int native_object, float kx, float ky) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        d.preTransform(getSkew(kx, ky));
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_preConcat(int native_object, int other_matrix) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        Matrix_Delegate other = sManager.getDelegate(other_matrix);
+        if (d == null) {
+            return false;
+        }
+
+        d.preTransform(other.mValues);
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_postTranslate(int native_object, float dx, float dy) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        d.postTransform(getTranslate(dx, dy));
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_postScale(int native_object, float sx, float sy,
+            float px, float py) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        d.postTransform(getScale(sx, sy, px, py));
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_postScale(int native_object, float sx, float sy) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        d.postTransform(getScale(sx, sy));
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_postRotate(int native_object, float degrees,
+            float px, float py) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        d.postTransform(getRotate(degrees, px, py));
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_postRotate(int native_object, float degrees) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        d.postTransform(getRotate(degrees));
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_postSkew(int native_object, float kx, float ky,
+            float px, float py) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        d.postTransform(getSkew(kx, ky, px, py));
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_postSkew(int native_object, float kx, float ky) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        d.postTransform(getSkew(kx, ky));
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_postConcat(int native_object, int other_matrix) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        Matrix_Delegate other = sManager.getDelegate(other_matrix);
+        if (d == null) {
+            return false;
+        }
+
+        d.postTransform(other.mValues);
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_setRectToRect(int native_object, RectF src,
+            RectF dst, int stf) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        if (src.isEmpty()) {
+            reset(d.mValues);
+            return false;
+        }
+
+        if (dst.isEmpty()) {
+            d.mValues[0] = d.mValues[1] = d.mValues[2] = d.mValues[3] = d.mValues[4] = d.mValues[5]
+               = d.mValues[6] = d.mValues[7] = 0;
+            d.mValues[8] = 1;
+        } else {
+            float    tx, sx = dst.width() / src.width();
+            float    ty, sy = dst.height() / src.height();
+            boolean  xLarger = false;
+
+            if (stf != ScaleToFit.FILL.nativeInt) {
+                if (sx > sy) {
+                    xLarger = true;
+                    sx = sy;
+                } else {
+                    sy = sx;
+                }
+            }
+
+            tx = dst.left - src.left * sx;
+            ty = dst.top - src.top * sy;
+            if (stf == ScaleToFit.CENTER.nativeInt || stf == ScaleToFit.END.nativeInt) {
+                float diff;
+
+                if (xLarger) {
+                    diff = dst.width() - src.width() * sy;
+                } else {
+                    diff = dst.height() - src.height() * sy;
+                }
+
+                if (stf == ScaleToFit.CENTER.nativeInt) {
+                    diff = diff / 2;
+                }
+
+                if (xLarger) {
+                    tx += diff;
+                } else {
+                    ty += diff;
+                }
+            }
+
+            d.mValues[0] = sx;
+            d.mValues[4] = sy;
+            d.mValues[2] = tx;
+            d.mValues[5] = ty;
+            d.mValues[1]  = d.mValues[3] = d.mValues[6] = d.mValues[7] = 0;
+
+        }
+        // shared cleanup
+        d.mValues[8] = 1;
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_setPolyToPoly(int native_object, float[] src, int srcIndex,
+            float[] dst, int dstIndex, int pointCount) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Matrix.setPolyToPoly is not supported.",
+                null, null /*data*/);
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_invert(int native_object, int inverse) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        Matrix_Delegate inv_mtx = sManager.getDelegate(inverse);
+        if (inv_mtx == null) {
+            return false;
+        }
+
+        try {
+            AffineTransform affineTransform = d.getAffineTransform();
+            AffineTransform inverseTransform = affineTransform.createInverse();
+            inv_mtx.mValues[0] = (float)inverseTransform.getScaleX();
+            inv_mtx.mValues[1] = (float)inverseTransform.getShearX();
+            inv_mtx.mValues[2] = (float)inverseTransform.getTranslateX();
+            inv_mtx.mValues[3] = (float)inverseTransform.getScaleX();
+            inv_mtx.mValues[4] = (float)inverseTransform.getShearY();
+            inv_mtx.mValues[5] = (float)inverseTransform.getTranslateY();
+
+            return true;
+        } catch (NoninvertibleTransformException e) {
+            return false;
+        }
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_mapPoints(int native_object, float[] dst, int dstIndex,
+            float[] src, int srcIndex, int ptCount, boolean isPts) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return;
+        }
+
+        if (isPts) {
+            d.mapPoints(dst, dstIndex, src, srcIndex, ptCount);
+        } else {
+            d.mapVectors(dst, dstIndex, src, srcIndex, ptCount);
+        }
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_mapRect(int native_object, RectF dst, RectF src) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return false;
+        }
+
+        return d.mapRect(dst, src);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float native_mapRadius(int native_object, float radius) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return 0.f;
+        }
+
+        float[] src = new float[] { radius, 0.f, 0.f, radius };
+        d.mapVectors(src, 0, src, 0, 2);
+
+        float l1 = getPointLength(src, 0);
+        float l2 = getPointLength(src, 2);
+
+        return (float) Math.sqrt(l1 * l2);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_getValues(int native_object, float[] values) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return;
+        }
+
+        System.arraycopy(d.mValues, 0, d.mValues, 0, MATRIX_SIZE);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setValues(int native_object, float[] values) {
+        Matrix_Delegate d = sManager.getDelegate(native_object);
+        if (d == null) {
+            return;
+        }
+
+        System.arraycopy(values, 0, d.mValues, 0, MATRIX_SIZE);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_equals(int native_a, int native_b) {
+        Matrix_Delegate a = sManager.getDelegate(native_a);
+        if (a == null) {
+            return false;
+        }
+
+        Matrix_Delegate b = sManager.getDelegate(native_b);
+        if (b == null) {
+            return false;
+        }
+
+        for (int i = 0 ; i < MATRIX_SIZE ; i++) {
+            if (a.mValues[i] != b.mValues[i]) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void finalizer(int native_instance) {
+        sManager.removeJavaReferenceFor(native_instance);
+    }
+
+    // ---- Private helper methods ----
+
+    /*package*/ static AffineTransform getAffineTransform(float[] matrix) {
+        // the AffineTransform constructor takes the value in a different order
+        // for a matrix [ 0 1 2 ]
+        //              [ 3 4 5 ]
+        // the order is 0, 3, 1, 4, 2, 5...
+        return new AffineTransform(
+                matrix[0], matrix[3], matrix[1],
+                matrix[4], matrix[2], matrix[5]);
+    }
+
+    /**
+     * Reset a matrix to the identity
+     */
+    private static void reset(float[] mtx) {
+        for (int i = 0, k = 0; i < 3; i++) {
+            for (int j = 0; j < 3; j++, k++) {
+                mtx[k] = ((i==j) ? 1 : 0);
+            }
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private final static int kIdentity_Mask      = 0;
+    private final static int kTranslate_Mask     = 0x01;  //!< set if the matrix has translation
+    private final static int kScale_Mask         = 0x02;  //!< set if the matrix has X or Y scale
+    private final static int kAffine_Mask        = 0x04;  //!< set if the matrix skews or rotates
+    private final static int kPerspective_Mask   = 0x08;  //!< set if the matrix is in perspective
+    private final static int kRectStaysRect_Mask = 0x10;
+    @SuppressWarnings("unused")
+    private final static int kUnknown_Mask       = 0x80;
+
+    @SuppressWarnings("unused")
+    private final static int kAllMasks           = kTranslate_Mask |
+                                                   kScale_Mask |
+                                                   kAffine_Mask |
+                                                   kPerspective_Mask |
+                                                   kRectStaysRect_Mask;
+
+    // these guys align with the masks, so we can compute a mask from a variable 0/1
+    @SuppressWarnings("unused")
+    private final static int kTranslate_Shift = 0;
+    @SuppressWarnings("unused")
+    private final static int kScale_Shift = 1;
+    @SuppressWarnings("unused")
+    private final static int kAffine_Shift = 2;
+    @SuppressWarnings("unused")
+    private final static int kPerspective_Shift = 3;
+    private final static int kRectStaysRect_Shift = 4;
+
+    private int computeTypeMask() {
+        int mask = 0;
+
+        if (mValues[6] != 0. || mValues[7] != 0. || mValues[8] != 1.) {
+            mask |= kPerspective_Mask;
+        }
+
+        if (mValues[2] != 0. || mValues[5] != 0.) {
+            mask |= kTranslate_Mask;
+        }
+
+        float m00 = mValues[0];
+        float m01 = mValues[1];
+        float m10 = mValues[3];
+        float m11 = mValues[4];
+
+        if (m01 != 0. || m10 != 0.) {
+            mask |= kAffine_Mask;
+        }
+
+        if (m00 != 1. || m11 != 1.) {
+            mask |= kScale_Mask;
+        }
+
+        if ((mask & kPerspective_Mask) == 0) {
+            // map non-zero to 1
+            int im00 = m00 != 0 ? 1 : 0;
+            int im01 = m01 != 0 ? 1 : 0;
+            int im10 = m10 != 0 ? 1 : 0;
+            int im11 = m11 != 0 ? 1 : 0;
+
+            // record if the (p)rimary and (s)econdary diagonals are all 0 or
+            // all non-zero (answer is 0 or 1)
+            int dp0 = (im00 | im11) ^ 1;  // true if both are 0
+            int dp1 = im00 & im11;        // true if both are 1
+            int ds0 = (im01 | im10) ^ 1;  // true if both are 0
+            int ds1 = im01 & im10;        // true if both are 1
+
+            // return 1 if primary is 1 and secondary is 0 or
+            // primary is 0 and secondary is 1
+            mask |= ((dp0 & ds1) | (dp1 & ds0)) << kRectStaysRect_Shift;
+        }
+
+        return mask;
+    }
+
+    private Matrix_Delegate() {
+        reset();
+    }
+
+    private Matrix_Delegate(float[] values) {
+        System.arraycopy(values, 0, mValues, 0, MATRIX_SIZE);
+    }
+
+    /**
+     * Adds the given transformation to the current Matrix
+     * <p/>This in effect does this = this*matrix
+     * @param matrix
+     */
+    private void postTransform(float[] matrix) {
+        float[] tmp = new float[9];
+        multiply(tmp, mValues, matrix);
+        mValues = tmp;
+    }
+
+    /**
+     * Adds the given transformation to the current Matrix
+     * <p/>This in effect does this = matrix*this
+     * @param matrix
+     */
+    private void preTransform(float[] matrix) {
+        float[] tmp = new float[9];
+        multiply(tmp, matrix, mValues);
+        mValues = tmp;
+    }
+
+    /**
+     * Apply this matrix to the array of 2D points specified by src, and write
+      * the transformed points into the array of points specified by dst. The
+      * two arrays represent their "points" as pairs of floats [x, y].
+      *
+      * @param dst   The array of dst points (x,y pairs)
+      * @param dstIndex The index of the first [x,y] pair of dst floats
+      * @param src   The array of src points (x,y pairs)
+      * @param srcIndex The index of the first [x,y] pair of src floats
+      * @param pointCount The number of points (x,y pairs) to transform
+      */
+
+     private void mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex,
+                           int pointCount) {
+         final int count = pointCount * 2;
+
+         float[] tmpDest = dst;
+         boolean inPlace = dst == src;
+         if (inPlace) {
+             tmpDest = new float[dstIndex + count];
+         }
+
+         for (int i = 0 ; i < count ; i += 2) {
+             // just in case we are doing in place, we better put this in temp vars
+             float x = mValues[0] * src[i + srcIndex] +
+                       mValues[1] * src[i + srcIndex + 1] +
+                       mValues[2];
+             float y = mValues[3] * src[i + srcIndex] +
+                       mValues[4] * src[i + srcIndex + 1] +
+                       mValues[5];
+
+             tmpDest[i + dstIndex]     = x;
+             tmpDest[i + dstIndex + 1] = y;
+         }
+
+         if (inPlace) {
+             System.arraycopy(tmpDest, dstIndex, dst, dstIndex, count);
+         }
+     }
+
+     /**
+      * Apply this matrix to the array of 2D points, and write the transformed
+      * points back into the array
+      *
+      * @param pts The array [x0, y0, x1, y1, ...] of points to transform.
+      */
+
+     private void mapPoints(float[] pts) {
+         mapPoints(pts, 0, pts, 0, pts.length >> 1);
+     }
+
+     private void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex, int ptCount) {
+         if (hasPerspective()) {
+             // transform the (0,0) point
+             float[] origin = new float[] { 0.f, 0.f};
+             mapPoints(origin);
+
+             // translate the vector data as points
+             mapPoints(dst, dstIndex, src, srcIndex, ptCount);
+
+             // then substract the transformed origin.
+             final int count = ptCount * 2;
+             for (int i = 0 ; i < count ; i += 2) {
+                 dst[dstIndex + i] = dst[dstIndex + i] - origin[0];
+                 dst[dstIndex + i + 1] = dst[dstIndex + i + 1] - origin[1];
+             }
+         } else {
+             // make a copy of the matrix
+             Matrix_Delegate copy = new Matrix_Delegate(mValues);
+
+             // remove the translation
+             setTranslate(copy.mValues, 0, 0);
+
+             // map the content as points.
+             copy.mapPoints(dst, dstIndex, src, srcIndex, ptCount);
+         }
+     }
+
+     private static float getPointLength(float[] src, int index) {
+         return (float) Math.sqrt(src[index] * src[index] + src[index + 1] * src[index + 1]);
+     }
+
+    /**
+     * multiply two matrices and store them in a 3rd.
+     * <p/>This in effect does dest = a*b
+     * dest cannot be the same as a or b.
+     */
+     /*package*/ static void multiply(float dest[], float[] a, float[] b) {
+        // first row
+        dest[0] = b[0] * a[0] + b[1] * a[3] + b[2] * a[6];
+        dest[1] = b[0] * a[1] + b[1] * a[4] + b[2] * a[7];
+        dest[2] = b[0] * a[2] + b[1] * a[5] + b[2] * a[8];
+
+        // 2nd row
+        dest[3] = b[3] * a[0] + b[4] * a[3] + b[5] * a[6];
+        dest[4] = b[3] * a[1] + b[4] * a[4] + b[5] * a[7];
+        dest[5] = b[3] * a[2] + b[4] * a[5] + b[5] * a[8];
+
+        // 3rd row
+        dest[6] = b[6] * a[0] + b[7] * a[3] + b[8] * a[6];
+        dest[7] = b[6] * a[1] + b[7] * a[4] + b[8] * a[7];
+        dest[8] = b[6] * a[2] + b[7] * a[5] + b[8] * a[8];
+    }
+
+    /**
+     * Returns a matrix that represents a given translate
+     * @param dx
+     * @param dy
+     * @return
+     */
+    /*package*/ static float[] getTranslate(float dx, float dy) {
+        return setTranslate(new float[9], dx, dy);
+    }
+
+    /*package*/ static float[] setTranslate(float[] dest, float dx, float dy) {
+        dest[0] = 1;
+        dest[1] = 0;
+        dest[2] = dx;
+        dest[3] = 0;
+        dest[4] = 1;
+        dest[5] = dy;
+        dest[6] = 0;
+        dest[7] = 0;
+        dest[8] = 1;
+        return dest;
+    }
+
+    /*package*/ static float[] getScale(float sx, float sy) {
+        return new float[] { sx, 0, 0, 0, sy, 0, 0, 0, 1 };
+    }
+
+    /**
+     * Returns a matrix that represents the given scale info.
+     * @param sx
+     * @param sy
+     * @param px
+     * @param py
+     */
+    /*package*/ static float[] getScale(float sx, float sy, float px, float py) {
+        float[] tmp = new float[9];
+        float[] tmp2 = new float[9];
+
+        // TODO: do it in one pass
+
+        // translate tmp so that the pivot is in 0,0
+        setTranslate(tmp, -px, -py);
+
+        // scale into tmp2
+        multiply(tmp2, tmp, getScale(sx, sy));
+
+        // translate back the pivot back into tmp
+        multiply(tmp, tmp2, getTranslate(px, py));
+
+        return tmp;
+    }
+
+
+    /*package*/ static float[] getRotate(float degrees) {
+        double rad = Math.toRadians(degrees);
+        float sin = (float)Math.sin(rad);
+        float cos = (float)Math.cos(rad);
+
+        return getRotate(sin, cos);
+    }
+
+    /*package*/ static float[] getRotate(float sin, float cos) {
+        return setRotate(new float[9], sin, cos);
+    }
+
+    /*package*/ static float[] setRotate(float[] dest, float degrees) {
+        double rad = Math.toRadians(degrees);
+        float sin = (float)Math.sin(rad);
+        float cos = (float)Math.cos(rad);
+
+        return setRotate(dest, sin, cos);
+    }
+
+    /*package*/ static float[] setRotate(float[] dest, float sin, float cos) {
+        dest[0] = cos;
+        dest[1] = -sin;
+        dest[2] = 0;
+        dest[3] = sin;
+        dest[4] = cos;
+        dest[5] = 0;
+        dest[6] = 0;
+        dest[7] = 0;
+        dest[8] = 1;
+        return dest;
+    }
+
+    /*package*/ static float[] getRotate(float degrees, float px, float py) {
+        float[] tmp = new float[9];
+        float[] tmp2 = new float[9];
+
+        // TODO: do it in one pass
+
+        // translate so that the pivot is in 0,0
+        setTranslate(tmp, -px, -py);
+
+        // rotate into tmp2
+        double rad = Math.toRadians(degrees);
+        float cos = (float)Math.cos(rad);
+        float sin = (float)Math.sin(rad);
+        multiply(tmp2, tmp, getRotate(sin, cos));
+
+        // translate back the pivot back into tmp
+        multiply(tmp, tmp2, getTranslate(px, py));
+
+        return tmp;
+    }
+
+    /*package*/ static float[] getSkew(float kx, float ky) {
+        return new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 };
+    }
+
+    /*package*/ static float[] getSkew(float kx, float ky, float px, float py) {
+        float[] tmp = new float[9];
+        float[] tmp2 = new float[9];
+
+        // TODO: do it in one pass
+
+        // translate so that the pivot is in 0,0
+        setTranslate(tmp, -px, -py);
+
+        // skew into tmp2
+        multiply(tmp2, tmp, new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 });
+        // translate back the pivot back into tmp
+        multiply(tmp, tmp2, getTranslate(px, py));
+
+        return tmp;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
new file mode 100644
index 0000000..5e882ce
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.layoutlib.bridge.impl.GcSnapshot;
+import com.android.ninepatch.NinePatchChunk;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.graphics.drawable.NinePatchDrawable;
+
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.ref.SoftReference;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Delegate implementing the native methods of android.graphics.NinePatch
+ *
+ * Through the layoutlib_create tool, the original native methods of NinePatch have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
+ * around to map int to instance of the delegate.
+ *
+ */
+public final class NinePatch_Delegate {
+
+    /**
+     * Cache map for {@link NinePatchChunk}.
+     * When the chunks are created they are serialized into a byte[], and both are put
+     * in the cache, using a {@link SoftReference} for the chunk. The default Java classes
+     * for {@link NinePatch} and {@link NinePatchDrawable} only reference to the byte[] data, and
+     * provide this for drawing.
+     * Using the cache map allows us to not have to deserialize the byte[] back into a
+     * {@link NinePatchChunk} every time a rendering is done.
+     */
+    private final static Map<byte[], SoftReference<NinePatchChunk>> sChunkCache =
+        new HashMap<byte[], SoftReference<NinePatchChunk>>();
+
+    // ---- Public Helper methods ----
+
+    /**
+     * Serializes the given chunk.
+     *
+     * @return the serialized data for the chunk.
+     */
+    public static byte[] serialize(NinePatchChunk chunk) {
+        // serialize the chunk to get a byte[]
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = null;
+        try {
+            oos = new ObjectOutputStream(baos);
+            oos.writeObject(chunk);
+        } catch (IOException e) {
+            Bridge.getLog().error(null, "Failed to serialize NinePatchChunk.", e, null /*data*/);
+            return null;
+        } finally {
+            if (oos != null) {
+                try {
+                    oos.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+
+        // get the array and add it to the cache
+        byte[] array = baos.toByteArray();
+        sChunkCache.put(array, new SoftReference<NinePatchChunk>(chunk));
+        return array;
+    }
+
+    /**
+     * Returns a {@link NinePatchChunk} object for the given serialized representation.
+     *
+     * If the chunk is present in the cache then the object from the cache is returned, otherwise
+     * the array is deserialized into a {@link NinePatchChunk} object.
+     *
+     * @param array the serialized representation of the chunk.
+     * @return the NinePatchChunk or null if deserialization failed.
+     */
+    public static NinePatchChunk getChunk(byte[] array) {
+        SoftReference<NinePatchChunk> chunkRef = sChunkCache.get(array);
+        NinePatchChunk chunk = chunkRef.get();
+        if (chunk == null) {
+            ByteArrayInputStream bais = new ByteArrayInputStream(array);
+            ObjectInputStream ois = null;
+            try {
+                ois = new ObjectInputStream(bais);
+                chunk = (NinePatchChunk) ois.readObject();
+
+                // put back the chunk in the cache
+                if (chunk != null) {
+                    sChunkCache.put(array, new SoftReference<NinePatchChunk>(chunk));
+                }
+            } catch (IOException e) {
+                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                        "Failed to deserialize NinePatchChunk content.", e, null /*data*/);
+                return null;
+            } catch (ClassNotFoundException e) {
+                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                        "Failed to deserialize NinePatchChunk class.", e, null /*data*/);
+                return null;
+            } finally {
+                if (ois != null) {
+                    try {
+                        ois.close();
+                    } catch (IOException e) {
+                    }
+                }
+            }
+        }
+
+        return chunk;
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static boolean isNinePatchChunk(byte[] chunk) {
+        NinePatchChunk chunkObject = getChunk(chunk);
+        if (chunkObject != null) {
+            return true;
+        }
+
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void validateNinePatchChunk(int bitmap, byte[] chunk) {
+        // the default JNI implementation only checks that the byte[] has the same
+        // size as the C struct it represent. Since we cannot do the same check (serialization
+        // will return different size depending on content), we do nothing.
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeDraw(int canvas_instance, RectF loc, int bitmap_instance,
+            byte[] c, int paint_instance_or_null, int destDensity, int srcDensity) {
+        draw(canvas_instance,
+                (int) loc.left, (int) loc.top, (int) loc.width(), (int) loc.height(),
+                bitmap_instance, c, paint_instance_or_null,
+                destDensity, srcDensity);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeDraw(int canvas_instance, Rect loc, int bitmap_instance,
+            byte[] c, int paint_instance_or_null, int destDensity, int srcDensity) {
+        draw(canvas_instance,
+                loc.left, loc.top, loc.width(), loc.height(),
+                bitmap_instance, c, paint_instance_or_null,
+                destDensity, srcDensity);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeGetTransparentRegion(int bitmap, byte[] chunk, Rect location) {
+        return 0;
+    }
+
+    // ---- Private Helper methods ----
+
+    private static void draw(int canvas_instance,
+            final int left, final int top, final int right, final int bottom,
+            int bitmap_instance, byte[] c, int paint_instance_or_null,
+            final int destDensity, final int srcDensity) {
+        // get the delegate from the native int.
+        final Bitmap_Delegate bitmap_delegate = Bitmap_Delegate.getDelegate(bitmap_instance);
+        if (bitmap_delegate == null) {
+            return;
+        }
+
+        if (c == null) {
+            // not a 9-patch?
+            BufferedImage image = bitmap_delegate.getImage();
+            Canvas_Delegate.native_drawBitmap(canvas_instance, bitmap_instance,
+                    new Rect(0, 0, image.getWidth(), image.getHeight()),
+                    new Rect(left, top, right, bottom),
+                    paint_instance_or_null, destDensity, srcDensity);
+            return;
+        }
+
+        final NinePatchChunk chunkObject = getChunk(c);
+        assert chunkObject != null;
+        if (chunkObject == null) {
+            return;
+        }
+
+        Canvas_Delegate canvas_delegate = Canvas_Delegate.getDelegate(canvas_instance);
+        if (canvas_delegate == null) {
+            return;
+        }
+
+        // this one can be null
+        Paint_Delegate paint_delegate = Paint_Delegate.getDelegate(paint_instance_or_null);
+
+        canvas_delegate.getSnapshot().draw(new GcSnapshot.Drawable() {
+                public void draw(Graphics2D graphics, Paint_Delegate paint) {
+                    chunkObject.draw(bitmap_delegate.getImage(), graphics,
+                            left, top, right - left, bottom - top, destDensity, srcDensity);
+                }
+            }, paint_delegate, true /*compositeOnly*/, false /*forceSrcMode*/);
+
+     }
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint.java b/tools/layoutlib/bridge/src/android/graphics/Paint.java
deleted file mode 100644
index d13b5fe..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Paint.java
+++ /dev/null
@@ -1,1211 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import android.text.SpannableString;
-import android.text.SpannableStringBuilder;
-import android.text.SpannedString;
-import android.text.TextUtils;
-
-import java.awt.BasicStroke;
-import java.awt.Font;
-import java.awt.Toolkit;
-import java.awt.font.FontRenderContext;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A paint implementation overridden by the LayoutLib bridge.
- */
-public class Paint extends _Original_Paint {
-
-    private int mColor = 0xFFFFFFFF;
-    private float mStrokeWidth = 1.f;
-    private float mTextSize = 20;
-    private float mScaleX = 1;
-    private float mSkewX = 0;
-    private Align mAlign = Align.LEFT;
-    private Style mStyle = Style.FILL;
-    private float mStrokeMiter = 4.0f;
-    private Cap mCap = Cap.BUTT;
-    private Join mJoin = Join.MITER;
-    private int mFlags = 0;
-
-    /**
-     * Class associating a {@link Font} and it's {@link java.awt.FontMetrics}.
-     */
-    public static final class FontInfo {
-        Font mFont;
-        java.awt.FontMetrics mMetrics;
-    }
-
-    private List<FontInfo> mFonts;
-    private final FontRenderContext mFontContext = new FontRenderContext(
-            new AffineTransform(), true, true);
-
-    public static final int ANTI_ALIAS_FLAG       = _Original_Paint.ANTI_ALIAS_FLAG;
-    public static final int FILTER_BITMAP_FLAG    = _Original_Paint.FILTER_BITMAP_FLAG;
-    public static final int DITHER_FLAG           = _Original_Paint.DITHER_FLAG;
-    public static final int UNDERLINE_TEXT_FLAG   = _Original_Paint.UNDERLINE_TEXT_FLAG;
-    public static final int STRIKE_THRU_TEXT_FLAG = _Original_Paint.STRIKE_THRU_TEXT_FLAG;
-    public static final int FAKE_BOLD_TEXT_FLAG   = _Original_Paint.FAKE_BOLD_TEXT_FLAG;
-    public static final int LINEAR_TEXT_FLAG      = _Original_Paint.LINEAR_TEXT_FLAG;
-    public static final int SUBPIXEL_TEXT_FLAG    = _Original_Paint.SUBPIXEL_TEXT_FLAG;
-    public static final int DEV_KERN_TEXT_FLAG    = _Original_Paint.DEV_KERN_TEXT_FLAG;
-
-    public static class FontMetrics extends _Original_Paint.FontMetrics {
-    }
-
-    public static class FontMetricsInt extends _Original_Paint.FontMetricsInt {
-    }
-
-    /**
-     * The Style specifies if the primitive being drawn is filled,
-     * stroked, or both (in the same color). The default is FILL.
-     */
-    public enum Style {
-        /**
-         * Geometry and text drawn with this style will be filled, ignoring all
-         * stroke-related settings in the paint.
-         */
-        FILL            (0),
-        /**
-         * Geometry and text drawn with this style will be stroked, respecting
-         * the stroke-related fields on the paint.
-         */
-        STROKE          (1),
-        /**
-         * Geometry and text drawn with this style will be both filled and
-         * stroked at the same time, respecting the stroke-related fields on
-         * the paint.
-         */
-        FILL_AND_STROKE (2);
-
-        Style(int nativeInt) {
-            this.nativeInt = nativeInt;
-        }
-        final int nativeInt;
-    }
-
-    /**
-     * The Cap specifies the treatment for the beginning and ending of
-     * stroked lines and paths. The default is BUTT.
-     */
-    public enum Cap {
-        /**
-         * The stroke ends with the path, and does not project beyond it.
-         */
-        BUTT    (0),
-        /**
-         * The stroke projects out as a square, with the center at the end
-         * of the path.
-         */
-        ROUND   (1),
-        /**
-         * The stroke projects out as a semicircle, with the center at the
-         * end of the path.
-         */
-        SQUARE  (2);
-
-        private Cap(int nativeInt) {
-            this.nativeInt = nativeInt;
-        }
-        final int nativeInt;
-
-        /** custom for layoutlib */
-        public int getJavaCap() {
-            switch (this) {
-                case BUTT:
-                    return BasicStroke.CAP_BUTT;
-                case ROUND:
-                    return BasicStroke.CAP_ROUND;
-                default:
-                case SQUARE:
-                    return BasicStroke.CAP_SQUARE;
-            }
-        }
-    }
-
-    /**
-     * The Join specifies the treatment where lines and curve segments
-     * join on a stroked path. The default is MITER.
-     */
-    public enum Join {
-        /**
-         * The outer edges of a join meet at a sharp angle
-         */
-        MITER   (0),
-        /**
-         * The outer edges of a join meet in a circular arc.
-         */
-        ROUND   (1),
-        /**
-         * The outer edges of a join meet with a straight line
-         */
-        BEVEL   (2);
-
-        private Join(int nativeInt) {
-            this.nativeInt = nativeInt;
-        }
-        final int nativeInt;
-
-        /** custom for layoutlib */
-        public int getJavaJoin() {
-            switch (this) {
-                default:
-                case MITER:
-                    return BasicStroke.JOIN_MITER;
-                case ROUND:
-                    return BasicStroke.JOIN_ROUND;
-                case BEVEL:
-                    return BasicStroke.JOIN_BEVEL;
-            }
-        }
-    }
-
-    /**
-     * Align specifies how drawText aligns its text relative to the
-     * [x,y] coordinates. The default is LEFT.
-     */
-    public enum Align {
-        /**
-         * The text is drawn to the right of the x,y origin
-         */
-        LEFT    (0),
-        /**
-         * The text is drawn centered horizontally on the x,y origin
-         */
-        CENTER  (1),
-        /**
-         * The text is drawn to the left of the x,y origin
-         */
-        RIGHT   (2);
-
-        private Align(int nativeInt) {
-            this.nativeInt = nativeInt;
-        }
-        final int nativeInt;
-    }
-
-    public Paint() {
-        this(0);
-    }
-
-    /*
-     * Do not remove or com.android.layoutlib.bridge.TestClassReplacement fails.
-     */
-    @Override
-    public void finalize() { }
-
-    public Paint(int flags) {
-        setFlags(flags | DEFAULT_PAINT_FLAGS);
-        initFont();
-    }
-
-    public Paint(Paint paint) {
-        set(paint);
-        initFont();
-    }
-
-    @Override
-    public void reset() {
-        super.reset();
-    }
-
-    /**
-     * Returns the list of {@link Font} objects. The first item is the main font, the rest
-     * are fall backs for characters not present in the main font.
-     */
-    public List<FontInfo> getFonts() {
-        return mFonts;
-    }
-
-    private void initFont() {
-        mTypeface = Typeface.DEFAULT;
-        updateFontObject();
-    }
-
-    /**
-     * Update the {@link Font} object from the typeface, text size and scaling
-     */
-    @SuppressWarnings("deprecation")
-    private void updateFontObject() {
-        if (mTypeface != null) {
-            // Get the fonts from the TypeFace object.
-            List<Font> fonts = mTypeface.getFonts();
-
-            // create new font objects as well as FontMetrics, based on the current text size
-            // and skew info.
-            ArrayList<FontInfo> infoList = new ArrayList<FontInfo>(fonts.size());
-            for (Font font : fonts) {
-                FontInfo info = new FontInfo();
-                info.mFont = font.deriveFont(mTextSize);
-                if (mScaleX != 1.0 || mSkewX != 0) {
-                    // TODO: support skew
-                    info.mFont = info.mFont.deriveFont(new AffineTransform(
-                            mScaleX, mSkewX, 0, 0, 1, 0));
-                }
-                info.mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(info.mFont);
-
-                infoList.add(info);
-            }
-
-            mFonts = Collections.unmodifiableList(infoList);
-        }
-    }
-
-    //----------------------------------------
-
-    public void set(Paint src) {
-        if (this != src) {
-            mColor = src.mColor;
-            mTextSize = src.mTextSize;
-            mScaleX = src.mScaleX;
-            mSkewX = src.mSkewX;
-            mAlign = src.mAlign;
-            mStyle = src.mStyle;
-            mFlags = src.mFlags;
-
-            updateFontObject();
-
-            super.set(src);
-        }
-    }
-
-    @Override
-    public void setCompatibilityScaling(float factor) {
-        super.setCompatibilityScaling(factor);
-    }
-
-    @Override
-    public int getFlags() {
-        return mFlags;
-    }
-
-    @Override
-    public void setFlags(int flags) {
-        mFlags = flags;
-    }
-
-    @Override
-    public boolean isAntiAlias() {
-        return super.isAntiAlias();
-    }
-
-    @Override
-    public boolean isDither() {
-        return super.isDither();
-    }
-
-    @Override
-    public boolean isLinearText() {
-        return super.isLinearText();
-    }
-
-    @Override
-    public boolean isStrikeThruText() {
-        return super.isStrikeThruText();
-    }
-
-    @Override
-    public boolean isUnderlineText() {
-        return super.isUnderlineText();
-    }
-
-    @Override
-    public boolean isFakeBoldText() {
-        return super.isFakeBoldText();
-    }
-
-    @Override
-    public boolean isSubpixelText() {
-        return super.isSubpixelText();
-    }
-
-    @Override
-    public boolean isFilterBitmap() {
-        return super.isFilterBitmap();
-    }
-
-    /**
-     * Return the font's recommended interline spacing, given the Paint's
-     * settings for typeface, textSize, etc. If metrics is not null, return the
-     * fontmetric values in it.
-     *
-     * @param metrics If this object is not null, its fields are filled with
-     *                the appropriate values given the paint's text attributes.
-     * @return the font's recommended interline spacing.
-     */
-    public float getFontMetrics(FontMetrics metrics) {
-        if (mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = mFonts.get(0).mMetrics;
-            if (metrics != null) {
-                // Android expects negative ascent so we invert the value from Java.
-                metrics.top = - javaMetrics.getMaxAscent();
-                metrics.ascent = - javaMetrics.getAscent();
-                metrics.descent = javaMetrics.getDescent();
-                metrics.bottom = javaMetrics.getMaxDescent();
-                metrics.leading = javaMetrics.getLeading();
-            }
-
-            return javaMetrics.getHeight();
-        }
-
-        return 0;
-    }
-
-    public int getFontMetricsInt(FontMetricsInt metrics) {
-        if (mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = mFonts.get(0).mMetrics;
-            if (metrics != null) {
-                // Android expects negative ascent so we invert the value from Java.
-                metrics.top = - javaMetrics.getMaxAscent();
-                metrics.ascent = - javaMetrics.getAscent();
-                metrics.descent = javaMetrics.getDescent();
-                metrics.bottom = javaMetrics.getMaxDescent();
-                metrics.leading = javaMetrics.getLeading();
-            }
-
-            return javaMetrics.getHeight();
-        }
-
-        return 0;
-    }
-
-    /**
-     * Reimplemented to return Paint.FontMetrics instead of _Original_Paint.FontMetrics
-     */
-    public FontMetrics getFontMetrics() {
-        FontMetrics fm = new FontMetrics();
-        getFontMetrics(fm);
-        return fm;
-    }
-
-    /**
-     * Reimplemented to return Paint.FontMetricsInt instead of _Original_Paint.FontMetricsInt
-     */
-    public FontMetricsInt getFontMetricsInt() {
-        FontMetricsInt fm = new FontMetricsInt();
-        getFontMetricsInt(fm);
-        return fm;
-    }
-
-
-
-    @Override
-    public float getFontMetrics(_Original_Paint.FontMetrics metrics) {
-        throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
-    }
-
-    @Override
-    public int getFontMetricsInt(_Original_Paint.FontMetricsInt metrics) {
-        throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
-    }
-
-    @Override
-    public Typeface setTypeface(Typeface typeface) {
-        if (typeface != null) {
-            mTypeface = typeface;
-        } else {
-            mTypeface = Typeface.DEFAULT;
-        }
-
-        updateFontObject();
-
-        return typeface;
-    }
-
-    @Override
-    public Typeface getTypeface() {
-        return super.getTypeface();
-    }
-
-    @Override
-    public int getColor() {
-        return mColor;
-    }
-
-    @Override
-    public void setColor(int color) {
-        mColor = color;
-    }
-
-    @Override
-    public void setARGB(int a, int r, int g, int b) {
-        super.setARGB(a, r, g, b);
-    }
-
-    @Override
-    public void setAlpha(int alpha) {
-        mColor = (alpha << 24) | (mColor & 0x00FFFFFF);
-    }
-
-    @Override
-    public int getAlpha() {
-        return mColor >>> 24;
-    }
-
-    /**
-     * Set or clear the shader object.
-     * <p />
-     * Pass null to clear any previous shader.
-     * As a convenience, the parameter passed is also returned.
-     *
-     * @param shader May be null. the new shader to be installed in the paint
-     * @return       shader
-     */
-    @Override
-    public Shader setShader(Shader shader) {
-        return mShader = shader;
-    }
-
-    @Override
-    public Shader getShader() {
-        return super.getShader();
-    }
-
-    /**
-     * Set or clear the paint's colorfilter, returning the parameter.
-     *
-     * @param filter May be null. The new filter to be installed in the paint
-     * @return       filter
-     */
-    @Override
-    public ColorFilter setColorFilter(ColorFilter filter) {
-        mColorFilter = filter;
-        return filter;
-    }
-
-    @Override
-    public ColorFilter getColorFilter() {
-        return super.getColorFilter();
-    }
-
-    /**
-     * Set or clear the xfermode object.
-     * <p />
-     * Pass null to clear any previous xfermode.
-     * As a convenience, the parameter passed is also returned.
-     *
-     * @param xfermode May be null. The xfermode to be installed in the paint
-     * @return         xfermode
-     */
-    @Override
-    public Xfermode setXfermode(Xfermode xfermode) {
-        return mXfermode = xfermode;
-    }
-
-    @Override
-    public Xfermode getXfermode() {
-        return super.getXfermode();
-    }
-
-    @Override
-    public Rasterizer setRasterizer(Rasterizer rasterizer) {
-        mRasterizer = rasterizer;
-        return rasterizer;
-    }
-
-    @Override
-    public Rasterizer getRasterizer() {
-        return super.getRasterizer();
-    }
-
-    @Override
-    public void setShadowLayer(float radius, float dx, float dy, int color) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void clearShadowLayer() {
-        super.clearShadowLayer();
-    }
-
-    public void setTextAlign(Align align) {
-        mAlign = align;
-    }
-
-    @Override
-    public void setTextAlign(android.graphics._Original_Paint.Align align) {
-        throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
-    }
-
-    public Align getTextAlign() {
-        return mAlign;
-    }
-
-    public void setStyle(Style style) {
-        mStyle = style;
-    }
-
-    @Override
-    public void setStyle(android.graphics._Original_Paint.Style style) {
-        throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
-    }
-
-    public Style getStyle() {
-        return mStyle;
-    }
-
-    @Override
-    public void setDither(boolean dither) {
-        mFlags |= dither ? DITHER_FLAG : ~DITHER_FLAG;
-    }
-
-    @Override
-    public void setAntiAlias(boolean aa) {
-        mFlags |= aa ? ANTI_ALIAS_FLAG : ~ANTI_ALIAS_FLAG;
-    }
-
-    @Override
-    public void setFakeBoldText(boolean flag) {
-        mFlags |= flag ? FAKE_BOLD_TEXT_FLAG : ~FAKE_BOLD_TEXT_FLAG;
-    }
-
-    @Override
-    public void setLinearText(boolean flag) {
-        mFlags |= flag ? LINEAR_TEXT_FLAG : ~LINEAR_TEXT_FLAG;
-    }
-
-    @Override
-    public void setSubpixelText(boolean flag) {
-        mFlags |= flag ? SUBPIXEL_TEXT_FLAG : ~SUBPIXEL_TEXT_FLAG;
-    }
-
-    @Override
-    public void setUnderlineText(boolean flag) {
-        mFlags |= flag ? UNDERLINE_TEXT_FLAG : ~UNDERLINE_TEXT_FLAG;
-    }
-
-    @Override
-    public void setStrikeThruText(boolean flag) {
-        mFlags |= flag ? STRIKE_THRU_TEXT_FLAG : ~STRIKE_THRU_TEXT_FLAG;
-    }
-
-    @Override
-    public void setFilterBitmap(boolean flag) {
-        mFlags |= flag ? FILTER_BITMAP_FLAG : ~FILTER_BITMAP_FLAG;
-    }
-
-    @Override
-    public float getStrokeWidth() {
-        return mStrokeWidth;
-    }
-
-    @Override
-    public void setStrokeWidth(float width) {
-        mStrokeWidth = width;
-    }
-
-    @Override
-    public float getStrokeMiter() {
-        return mStrokeMiter;
-    }
-
-    @Override
-    public void setStrokeMiter(float miter) {
-        mStrokeMiter = miter;
-    }
-
-    @Override
-    public void setStrokeCap(android.graphics._Original_Paint.Cap cap) {
-        throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
-    }
-
-    public void setStrokeCap(Cap cap) {
-        mCap = cap;
-    }
-
-    public Cap getStrokeCap() {
-        return mCap;
-    }
-
-    @Override
-    public void setStrokeJoin(android.graphics._Original_Paint.Join join) {
-        throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
-    }
-
-    public void setStrokeJoin(Join join) {
-        mJoin = join;
-    }
-
-    public Join getStrokeJoin() {
-        return mJoin;
-    }
-
-    @Override
-    public boolean getFillPath(Path src, Path dst) {
-        return super.getFillPath(src, dst);
-    }
-
-    @Override
-    public PathEffect setPathEffect(PathEffect effect) {
-        mPathEffect = effect;
-        return effect;
-    }
-
-    @Override
-    public PathEffect getPathEffect() {
-        return super.getPathEffect();
-    }
-
-    @Override
-    public MaskFilter setMaskFilter(MaskFilter maskfilter) {
-        mMaskFilter = maskfilter;
-        return maskfilter;
-    }
-
-    @Override
-    public MaskFilter getMaskFilter() {
-        return super.getMaskFilter();
-    }
-
-    /**
-     * Return the paint's text size.
-     *
-     * @return the paint's text size.
-     */
-    @Override
-    public float getTextSize() {
-        return mTextSize;
-    }
-
-    /**
-     * Set the paint's text size. This value must be > 0
-     *
-     * @param textSize set the paint's text size.
-     */
-    @Override
-    public void setTextSize(float textSize) {
-        mTextSize = textSize;
-
-        updateFontObject();
-    }
-
-    /**
-     * Return the paint's horizontal scale factor for text. The default value
-     * is 1.0.
-     *
-     * @return the paint's scale factor in X for drawing/measuring text
-     */
-    @Override
-    public float getTextScaleX() {
-        return mScaleX;
-    }
-
-    /**
-     * Set the paint's horizontal scale factor for text. The default value
-     * is 1.0. Values > 1.0 will stretch the text wider. Values < 1.0 will
-     * stretch the text narrower.
-     *
-     * @param scaleX set the paint's scale in X for drawing/measuring text.
-     */
-    @Override
-    public void setTextScaleX(float scaleX) {
-        mScaleX = scaleX;
-
-        updateFontObject();
-    }
-
-    /**
-     * Return the paint's horizontal skew factor for text. The default value
-     * is 0.
-     *
-     * @return         the paint's skew factor in X for drawing text.
-     */
-    @Override
-    public float getTextSkewX() {
-        return mSkewX;
-    }
-
-    /**
-     * Set the paint's horizontal skew factor for text. The default value
-     * is 0. For approximating oblique text, use values around -0.25.
-     *
-     * @param skewX set the paint's skew factor in X for drawing text.
-     */
-    @Override
-    public void setTextSkewX(float skewX) {
-        mSkewX = skewX;
-
-        updateFontObject();
-    }
-
-    @Override
-    public float getFontSpacing() {
-        return super.getFontSpacing();
-    }
-
-    /**
-     * Return the distance above (negative) the baseline (ascent) based on the
-     * current typeface and text size.
-     *
-     * @return the distance above (negative) the baseline (ascent) based on the
-     *         current typeface and text size.
-     */
-    @Override
-    public float ascent() {
-        if (mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = mFonts.get(0).mMetrics;
-            // Android expects negative ascent so we invert the value from Java.
-            return - javaMetrics.getAscent();
-        }
-
-        return 0;
-    }
-
-    /**
-     * Return the distance below (positive) the baseline (descent) based on the
-     * current typeface and text size.
-     *
-     * @return the distance below (positive) the baseline (descent) based on
-     *         the current typeface and text size.
-     */
-    @Override
-    public float descent() {
-        if (mFonts.size() > 0) {
-            java.awt.FontMetrics javaMetrics = mFonts.get(0).mMetrics;
-            return javaMetrics.getDescent();
-        }
-
-        return 0;
-    }
-
-    /**
-     * Return the width of the text.
-     *
-     * @param text  The text to measure
-     * @param index The index of the first character to start measuring
-     * @param count THe number of characters to measure, beginning with start
-     * @return      The width of the text
-     */
-    @Override
-    public float measureText(char[] text, int index, int count) {
-        // WARNING: the logic in this method is similar to Canvas.drawText.
-        // Any change to this method should be reflected in Canvas.drawText
-        if (mFonts.size() > 0) {
-            FontInfo mainFont = mFonts.get(0);
-            int i = index;
-            int lastIndex = index + count;
-            float total = 0f;
-            while (i < lastIndex) {
-                // always start with the main font.
-                int upTo = mainFont.mFont.canDisplayUpTo(text, i, lastIndex);
-                if (upTo == -1) {
-                    // shortcut to exit
-                    return total + mainFont.mMetrics.charsWidth(text, i, lastIndex - i);
-                } else if (upTo > 0) {
-                    total += mainFont.mMetrics.charsWidth(text, i, upTo - i);
-                    i = upTo;
-                    // don't call continue at this point. Since it is certain the main font
-                    // cannot display the font a index upTo (now ==i), we move on to the
-                    // fallback fonts directly.
-                }
-
-                // no char supported, attempt to read the next char(s) with the
-                // fallback font. In this case we only test the first character
-                // and then go back to test with the main font.
-                // Special test for 2-char characters.
-                boolean foundFont = false;
-                for (int f = 1 ; f < mFonts.size() ; f++) {
-                    FontInfo fontInfo = mFonts.get(f);
-
-                    // need to check that the font can display the character. We test
-                    // differently if the char is a high surrogate.
-                    int charCount = Character.isHighSurrogate(text[i]) ? 2 : 1;
-                    upTo = fontInfo.mFont.canDisplayUpTo(text, i, i + charCount);
-                    if (upTo == -1) {
-                        total += fontInfo.mMetrics.charsWidth(text, i, charCount);
-                        i += charCount;
-                        foundFont = true;
-                        break;
-
-                    }
-                }
-
-                // in case no font can display the char, measure it with the main font.
-                if (foundFont == false) {
-                    int size = Character.isHighSurrogate(text[i]) ? 2 : 1;
-                    total += mainFont.mMetrics.charsWidth(text, i, size);
-                    i += size;
-                }
-            }
-        }
-
-        return 0;
-    }
-
-    /**
-     * Return the width of the text.
-     *
-     * @param text  The text to measure
-     * @param start The index of the first character to start measuring
-     * @param end   1 beyond the index of the last character to measure
-     * @return      The width of the text
-     */
-    @Override
-    public float measureText(String text, int start, int end) {
-        return measureText(text.toCharArray(), start, end - start);
-    }
-
-    /**
-     * Return the width of the text.
-     *
-     * @param text  The text to measure
-     * @return      The width of the text
-     */
-    @Override
-    public float measureText(String text) {
-        return measureText(text.toCharArray(), 0, text.length());
-    }
-
-    /*
-     * re-implement to call SpannableStringBuilder.measureText with a Paint object
-     * instead of an _Original_Paint
-     */
-    @Override
-    public float measureText(CharSequence text, int start, int end) {
-        if (text instanceof String) {
-            return measureText((String)text, start, end);
-        }
-        if (text instanceof SpannedString ||
-            text instanceof SpannableString) {
-            return measureText(text.toString(), start, end);
-        }
-        if (text instanceof SpannableStringBuilder) {
-            return ((SpannableStringBuilder)text).measureText(start, end, this);
-        }
-
-        char[] buf = TemporaryBuffer.obtain(end - start);
-        TextUtils.getChars(text, start, end, buf, 0);
-        float result = measureText(buf, 0, end - start);
-        TemporaryBuffer.recycle(buf);
-        return result;
-    }
-
-    /**
-     * Measure the text, stopping early if the measured width exceeds maxWidth.
-     * Return the number of chars that were measured, and if measuredWidth is
-     * not null, return in it the actual width measured.
-     *
-     * @param text  The text to measure
-     * @param index The offset into text to begin measuring at
-     * @param count The number of maximum number of entries to measure. If count
-     *              is negative, then the characters before index are measured
-     *              in reverse order. This allows for measuring the end of
-     *              string.
-     * @param maxWidth The maximum width to accumulate.
-     * @param measuredWidth Optional. If not null, returns the actual width
-     *                     measured.
-     * @return The number of chars that were measured. Will always be <=
-     *         abs(count).
-     */
-    @Override
-    public int breakText(char[] text, int index, int count,
-                                float maxWidth, float[] measuredWidth) {
-        int inc = count > 0 ? 1 : -1;
-
-        int measureIndex = 0;
-        float measureAcc = 0;
-        for (int i = index ; i != index + count ; i += inc, measureIndex++) {
-            int start, end;
-            if (i < index) {
-                start = i;
-                end = index;
-            } else {
-                start = index;
-                end = i;
-            }
-
-            // measure from start to end
-            float res = measureText(text, start, end - start + 1);
-
-            if (measuredWidth != null) {
-                measuredWidth[measureIndex] = res;
-            }
-
-            measureAcc += res;
-            if (res > maxWidth) {
-                // we should not return this char index, but since it's 0-based and we need
-                // to return a count, we simply return measureIndex;
-                return measureIndex;
-            }
-
-        }
-
-        return measureIndex;
-    }
-
-    /**
-     * Measure the text, stopping early if the measured width exceeds maxWidth.
-     * Return the number of chars that were measured, and if measuredWidth is
-     * not null, return in it the actual width measured.
-     *
-     * @param text  The text to measure
-     * @param measureForwards If true, measure forwards, starting at index.
-     *                        Otherwise, measure backwards, starting with the
-     *                        last character in the string.
-     * @param maxWidth The maximum width to accumulate.
-     * @param measuredWidth Optional. If not null, returns the actual width
-     *                     measured.
-     * @return The number of chars that were measured. Will always be <=
-     *         abs(count).
-     */
-    @Override
-    public int breakText(String text, boolean measureForwards,
-                                float maxWidth, float[] measuredWidth) {
-        return breakText(text,
-                0 /* start */, text.length() /* end */,
-                measureForwards, maxWidth, measuredWidth);
-    }
-
-    /**
-     * Measure the text, stopping early if the measured width exceeds maxWidth.
-     * Return the number of chars that were measured, and if measuredWidth is
-     * not null, return in it the actual width measured.
-     *
-     * @param text  The text to measure
-     * @param start The offset into text to begin measuring at
-     * @param end   The end of the text slice to measure.
-     * @param measureForwards If true, measure forwards, starting at start.
-     *                        Otherwise, measure backwards, starting with end.
-     * @param maxWidth The maximum width to accumulate.
-     * @param measuredWidth Optional. If not null, returns the actual width
-     *                     measured.
-     * @return The number of chars that were measured. Will always be <=
-     *         abs(end - start).
-     */
-    @Override
-    public int breakText(CharSequence text, int start, int end, boolean measureForwards,
-            float maxWidth, float[] measuredWidth) {
-        char[] buf = new char[end - start];
-        int result;
-
-        TextUtils.getChars(text, start, end, buf, 0);
-
-        if (measureForwards) {
-            result = breakText(buf, 0, end - start, maxWidth, measuredWidth);
-        } else {
-            result = breakText(buf, 0, -(end - start), maxWidth, measuredWidth);
-        }
-
-        return result;
-    }
-
-    /**
-     * Return the advance widths for the characters in the string.
-     *
-     * @param text     The text to measure
-     * @param index    The index of the first char to to measure
-     * @param count    The number of chars starting with index to measure
-     * @param widths   array to receive the advance widths of the characters.
-     *                 Must be at least a large as count.
-     * @return         the actual number of widths returned.
-     */
-    @Override
-    public int getTextWidths(char[] text, int index, int count,
-                             float[] widths) {
-        if (mFonts.size() > 0) {
-            if ((index | count) < 0 || index + count > text.length
-                    || count > widths.length) {
-                throw new ArrayIndexOutOfBoundsException();
-            }
-
-            // FIXME: handle multi-char characters.
-            // Need to figure out if the lengths of the width array takes into account
-            // multi-char characters.
-            for (int i = 0; i < count; i++) {
-                char c = text[i + index];
-                boolean found = false;
-                for (FontInfo info : mFonts) {
-                    if (info.mFont.canDisplay(c)) {
-                        widths[i] = info.mMetrics.charWidth(c);
-                        found = true;
-                        break;
-                    }
-                }
-
-                if (found == false) {
-                    // we stop there.
-                    return i;
-                }
-            }
-
-            return count;
-        }
-
-        return 0;
-    }
-
-    /**
-     * Return the advance widths for the characters in the string.
-     *
-     * @param text   The text to measure
-     * @param start  The index of the first char to to measure
-     * @param end    The end of the text slice to measure
-     * @param widths array to receive the advance widths of the characters.
-     *               Must be at least a large as the text.
-     * @return       the number of unichars in the specified text.
-     */
-    @Override
-    public int getTextWidths(String text, int start, int end, float[] widths) {
-        if ((start | end | (end - start) | (text.length() - end)) < 0) {
-            throw new IndexOutOfBoundsException();
-        }
-        if (end - start > widths.length) {
-            throw new ArrayIndexOutOfBoundsException();
-        }
-
-        return getTextWidths(text.toCharArray(), start, end - start, widths);
-    }
-
-    /*
-     * re-implement to call SpannableStringBuilder.getTextWidths with a Paint object
-     * instead of an _Original_Paint
-     */
-    @Override
-    public int getTextWidths(CharSequence text, int start, int end, float[] widths) {
-        if (text instanceof String) {
-            return getTextWidths((String)text, start, end, widths);
-        }
-        if (text instanceof SpannedString || text instanceof SpannableString) {
-            return getTextWidths(text.toString(), start, end, widths);
-        }
-        if (text instanceof SpannableStringBuilder) {
-            return ((SpannableStringBuilder)text).getTextWidths(start, end, widths, this);
-        }
-
-        char[] buf = TemporaryBuffer.obtain(end - start);
-        TextUtils.getChars(text, start, end, buf, 0);
-        int result = getTextWidths(buf, 0, end - start, widths);
-        TemporaryBuffer.recycle(buf);
-        return result;
-    }
-
-    @Override
-    public int getTextWidths(String text, float[] widths) {
-        return super.getTextWidths(text, widths);
-    }
-
-    /**
-     * Return the path (outline) for the specified text.
-     * Note: just like Canvas.drawText, this will respect the Align setting in
-     * the paint.
-     *
-     * @param text     The text to retrieve the path from
-     * @param index    The index of the first character in text
-     * @param count    The number of characterss starting with index
-     * @param x        The x coordinate of the text's origin
-     * @param y        The y coordinate of the text's origin
-     * @param path     The path to receive the data describing the text. Must
-     *                 be allocated by the caller.
-     */
-    @Override
-    public void getTextPath(char[] text, int index, int count,
-                            float x, float y, Path path) {
-
-        // TODO this is the ORIGINAL implementation. REPLACE AS NEEDED OR REMOVE
-
-        if ((index | count) < 0 || index + count > text.length) {
-            throw new ArrayIndexOutOfBoundsException();
-        }
-
-        // TODO native_getTextPath(mNativePaint, text, index, count, x, y, path.ni());
-
-        throw new UnsupportedOperationException("IMPLEMENT AS NEEDED");
-    }
-
-    /**
-     * Return the path (outline) for the specified text.
-     * Note: just like Canvas.drawText, this will respect the Align setting
-     * in the paint.
-     *
-     * @param text  The text to retrieve the path from
-     * @param start The first character in the text
-     * @param end   1 past the last charcter in the text
-     * @param x     The x coordinate of the text's origin
-     * @param y     The y coordinate of the text's origin
-     * @param path  The path to receive the data describing the text. Must
-     *              be allocated by the caller.
-     */
-    @Override
-    public void getTextPath(String text, int start, int end,
-                            float x, float y, Path path) {
-        if ((start | end | (end - start) | (text.length() - end)) < 0) {
-            throw new IndexOutOfBoundsException();
-        }
-
-        getTextPath(text.toCharArray(), start, end - start, x, y, path);
-    }
-
-    /**
-     * Return in bounds (allocated by the caller) the smallest rectangle that
-     * encloses all of the characters, with an implied origin at (0,0).
-     *
-     * @param text  String to measure and return its bounds
-     * @param start Index of the first char in the string to measure
-     * @param end   1 past the last char in the string measure
-     * @param bounds Returns the unioned bounds of all the text. Must be
-     *               allocated by the caller.
-     */
-    @Override
-    public void getTextBounds(String text, int start, int end, Rect bounds) {
-        if ((start | end | (end - start) | (text.length() - end)) < 0) {
-            throw new IndexOutOfBoundsException();
-        }
-        if (bounds == null) {
-            throw new NullPointerException("need bounds Rect");
-        }
-
-        getTextBounds(text.toCharArray(), start, end - start, bounds);
-    }
-
-    /**
-     * Return in bounds (allocated by the caller) the smallest rectangle that
-     * encloses all of the characters, with an implied origin at (0,0).
-     *
-     * @param text  Array of chars to measure and return their unioned bounds
-     * @param index Index of the first char in the array to measure
-     * @param count The number of chars, beginning at index, to measure
-     * @param bounds Returns the unioned bounds of all the text. Must be
-     *               allocated by the caller.
-     */
-    @Override
-    public void getTextBounds(char[] text, int index, int count, Rect bounds) {
-        // FIXME
-        if (mFonts.size() > 0) {
-            if ((index | count) < 0 || index + count > text.length) {
-                throw new ArrayIndexOutOfBoundsException();
-            }
-            if (bounds == null) {
-                throw new NullPointerException("need bounds Rect");
-            }
-
-            FontInfo mainInfo = mFonts.get(0);
-
-            Rectangle2D rect = mainInfo.mFont.getStringBounds(text, index, index + count, mFontContext);
-            bounds.set(0, 0, (int)rect.getWidth(), (int)rect.getHeight());
-        }
-    }
-
-    public static void finalizer(int foo) {
-        // pass
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java
new file mode 100644
index 0000000..71d346a
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/PaintFlagsDrawFilter_Delegate.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate implementing the native methods of android.graphics.PaintFlagsDrawFilter
+ *
+ * Through the layoutlib_create tool, the original native methods of PaintFlagsDrawFilter have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original PaintFlagsDrawFilter class.
+ *
+ * Because this extends {@link DrawFilter_Delegate}, there's no need to use a
+ * {@link DelegateManager}, as all the DrawFilter classes will be added to the manager owned by
+ * {@link DrawFilter_Delegate}.
+ *
+ * @see DrawFilter_Delegate
+ *
+ */
+public class PaintFlagsDrawFilter_Delegate extends DrawFilter_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Paint Flags Draw Filters are not supported.";
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeConstructor(int clearBits, int setBits) {
+        PaintFlagsDrawFilter_Delegate newDelegate = new PaintFlagsDrawFilter_Delegate();
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
new file mode 100644
index 0000000..d4cf1f6
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -0,0 +1,1163 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.graphics.Paint.FontMetrics;
+import android.graphics.Paint.FontMetricsInt;
+
+import java.awt.BasicStroke;
+import java.awt.Font;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.Toolkit;
+import java.awt.font.FontRenderContext;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Delegate implementing the native methods of android.graphics.Paint
+ *
+ * Through the layoutlib_create tool, the original native methods of Paint have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original Paint class.
+ *
+ * @see DelegateManager
+ *
+ */
+public class Paint_Delegate {
+
+    /**
+     * Class associating a {@link Font} and it's {@link java.awt.FontMetrics}.
+     */
+    /*package*/ static final class FontInfo {
+        Font mFont;
+        java.awt.FontMetrics mMetrics;
+    }
+
+    // ---- delegate manager ----
+    private static final DelegateManager<Paint_Delegate> sManager =
+            new DelegateManager<Paint_Delegate>(Paint_Delegate.class);
+
+    // ---- delegate helper data ----
+    private List<FontInfo> mFonts;
+    private final FontRenderContext mFontContext = new FontRenderContext(
+            new AffineTransform(), true, true);
+
+    // ---- delegate data ----
+    private int mFlags;
+    private int mColor;
+    private int mStyle;
+    private int mCap;
+    private int mJoin;
+    private int mTextAlign;
+    private Typeface_Delegate mTypeface;
+    private float mStrokeWidth;
+    private float mStrokeMiter;
+    private float mTextSize;
+    private float mTextScaleX;
+    private float mTextSkewX;
+
+    private Xfermode_Delegate mXfermode;
+    private ColorFilter_Delegate mColorFilter;
+    private Shader_Delegate mShader;
+    private PathEffect_Delegate mPathEffect;
+    private MaskFilter_Delegate mMaskFilter;
+    private Rasterizer_Delegate mRasterizer;
+
+    // ---- Public Helper methods ----
+
+    public static Paint_Delegate getDelegate(int native_paint) {
+        return sManager.getDelegate(native_paint);
+    }
+
+    /**
+     * Returns the list of {@link Font} objects. The first item is the main font, the rest
+     * are fall backs for characters not present in the main font.
+     */
+    public List<FontInfo> getFonts() {
+        return mFonts;
+    }
+
+    public boolean isAntiAliased() {
+        return (mFlags & Paint.ANTI_ALIAS_FLAG) != 0;
+    }
+
+    public boolean isFilterBitmap() {
+        return (mFlags & Paint.FILTER_BITMAP_FLAG) != 0;
+    }
+
+    public int getStyle() {
+        return mStyle;
+    }
+
+    public int getColor() {
+        return mColor;
+    }
+
+    public int getAlpha() {
+        return mColor >>> 24;
+    }
+
+    public void setAlpha(int alpha) {
+        mColor = (alpha << 24) | (mColor & 0x00FFFFFF);
+    }
+
+    public int getTextAlign() {
+        return mTextAlign;
+    }
+
+    public float getStrokeWidth() {
+        return mStrokeWidth;
+    }
+
+    /**
+     * returns the value of stroke miter needed by the java api.
+     */
+    public float getJavaStrokeMiter() {
+        float miter = mStrokeMiter * mStrokeWidth;
+        if (miter < 1.f) {
+            miter = 1.f;
+        }
+        return miter;
+    }
+
+    public int getJavaCap() {
+        switch (Paint.sCapArray[mCap]) {
+            case BUTT:
+                return BasicStroke.CAP_BUTT;
+            case ROUND:
+                return BasicStroke.CAP_ROUND;
+            default:
+            case SQUARE:
+                return BasicStroke.CAP_SQUARE;
+        }
+    }
+
+    public int getJavaJoin() {
+        switch (Paint.sJoinArray[mJoin]) {
+            default:
+            case MITER:
+                return BasicStroke.JOIN_MITER;
+            case ROUND:
+                return BasicStroke.JOIN_ROUND;
+            case BEVEL:
+                return BasicStroke.JOIN_BEVEL;
+        }
+    }
+
+    public Stroke getJavaStroke() {
+        if (mPathEffect != null) {
+            if (mPathEffect.isSupported()) {
+                Stroke stroke = mPathEffect.getStroke(this);
+                assert stroke != null;
+                if (stroke != null) {
+                    return stroke;
+                }
+            } else {
+                Bridge.getLog().fidelityWarning(LayoutLog.TAG_PATHEFFECT,
+                        mPathEffect.getSupportMessage(),
+                        null, null /*data*/);
+            }
+        }
+
+        // if no custom stroke as been set, set the default one.
+        return new BasicStroke(
+                    getStrokeWidth(),
+                    getJavaCap(),
+                    getJavaJoin(),
+                    getJavaStrokeMiter());
+    }
+
+    /**
+     * Returns the {@link Xfermode} delegate or null if none have been set
+     *
+     * @return the delegate or null.
+     */
+    public Xfermode_Delegate getXfermode() {
+        return mXfermode;
+    }
+
+    /**
+     * Returns the {@link ColorFilter} delegate or null if none have been set
+     *
+     * @return the delegate or null.
+     */
+    public ColorFilter_Delegate getColorFilter() {
+        return mColorFilter;
+    }
+
+    /**
+     * Returns the {@link Shader} delegate or null if none have been set
+     *
+     * @return the delegate or null.
+     */
+    public Shader_Delegate getShader() {
+        return mShader;
+    }
+
+    /**
+     * Returns the {@link MaskFilter} delegate or null if none have been set
+     *
+     * @return the delegate or null.
+     */
+    public MaskFilter_Delegate getMaskFilter() {
+        return mMaskFilter;
+    }
+
+    /**
+     * Returns the {@link Rasterizer} delegate or null if none have been set
+     *
+     * @return the delegate or null.
+     */
+    public Rasterizer_Delegate getRasterizer() {
+        return mRasterizer;
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int getFlags(Paint thisPaint) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return 0;
+        }
+
+        return delegate.mFlags;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void setFlags(Paint thisPaint, int flags) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return;
+        }
+
+        delegate.mFlags = flags;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void setFilterBitmap(Paint thisPaint, boolean filter) {
+        setFlag(thisPaint, Paint.FILTER_BITMAP_FLAG, filter);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void setAntiAlias(Paint thisPaint, boolean aa) {
+        setFlag(thisPaint, Paint.ANTI_ALIAS_FLAG, aa);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void setSubpixelText(Paint thisPaint, boolean subpixelText) {
+        setFlag(thisPaint, Paint.SUBPIXEL_TEXT_FLAG, subpixelText);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void setUnderlineText(Paint thisPaint, boolean underlineText) {
+        setFlag(thisPaint, Paint.UNDERLINE_TEXT_FLAG, underlineText);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void setStrikeThruText(Paint thisPaint, boolean strikeThruText) {
+        setFlag(thisPaint, Paint.STRIKE_THRU_TEXT_FLAG, strikeThruText);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void setFakeBoldText(Paint thisPaint, boolean fakeBoldText) {
+        setFlag(thisPaint, Paint.FAKE_BOLD_TEXT_FLAG, fakeBoldText);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void setDither(Paint thisPaint, boolean dither) {
+        setFlag(thisPaint, Paint.DITHER_FLAG, dither);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void setLinearText(Paint thisPaint, boolean linearText) {
+        setFlag(thisPaint, Paint.LINEAR_TEXT_FLAG, linearText);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int getColor(Paint thisPaint) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return 0;
+        }
+
+        return delegate.mColor;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void setColor(Paint thisPaint, int color) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return;
+        }
+
+        delegate.mColor = color;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int getAlpha(Paint thisPaint) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return 0;
+        }
+
+        return delegate.getAlpha();
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void setAlpha(Paint thisPaint, int a) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return;
+        }
+
+        delegate.setAlpha(a);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float getStrokeWidth(Paint thisPaint) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return 1.f;
+        }
+
+        return delegate.mStrokeWidth;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void setStrokeWidth(Paint thisPaint, float width) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return;
+        }
+
+        delegate.mStrokeWidth = width;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float getStrokeMiter(Paint thisPaint) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return 1.f;
+        }
+
+        return delegate.mStrokeMiter;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void setStrokeMiter(Paint thisPaint, float miter) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return;
+        }
+
+        delegate.mStrokeMiter = miter;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void setShadowLayer(Paint thisPaint, float radius, float dx, float dy,
+            int color) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Paint.setShadowLayer is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float getTextSize(Paint thisPaint) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return 1.f;
+        }
+
+        return delegate.mTextSize;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void setTextSize(Paint thisPaint, float textSize) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return;
+        }
+
+        delegate.mTextSize = textSize;
+        delegate.updateFontObject();
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float getTextScaleX(Paint thisPaint) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return 1.f;
+        }
+
+        return delegate.mTextScaleX;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void setTextScaleX(Paint thisPaint, float scaleX) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return;
+        }
+
+        delegate.mTextScaleX = scaleX;
+        delegate.updateFontObject();
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float getTextSkewX(Paint thisPaint) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return 1.f;
+        }
+
+        return delegate.mTextSkewX;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void setTextSkewX(Paint thisPaint, float skewX) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return;
+        }
+
+        delegate.mTextSkewX = skewX;
+        delegate.updateFontObject();
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float ascent(Paint thisPaint) {
+        // get the delegate
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return 0;
+        }
+
+        if (delegate.mFonts.size() > 0) {
+            java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
+            // Android expects negative ascent so we invert the value from Java.
+            return - javaMetrics.getAscent();
+        }
+
+        return 0;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float descent(Paint thisPaint) {
+        // get the delegate
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return 0;
+        }
+
+        if (delegate.mFonts.size() > 0) {
+            java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
+            return javaMetrics.getDescent();
+        }
+
+        return 0;
+
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float getFontMetrics(Paint thisPaint, FontMetrics metrics) {
+        // get the delegate
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return 0;
+        }
+
+        return delegate.getFontMetrics(metrics);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int getFontMetricsInt(Paint thisPaint, FontMetricsInt fmi) {
+        // get the delegate
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return 0;
+        }
+
+        if (delegate.mFonts.size() > 0) {
+            java.awt.FontMetrics javaMetrics = delegate.mFonts.get(0).mMetrics;
+            if (fmi != null) {
+                // Android expects negative ascent so we invert the value from Java.
+                fmi.top = - javaMetrics.getMaxAscent();
+                fmi.ascent = - javaMetrics.getAscent();
+                fmi.descent = javaMetrics.getDescent();
+                fmi.bottom = javaMetrics.getMaxDescent();
+                fmi.leading = javaMetrics.getLeading();
+            }
+
+            return javaMetrics.getHeight();
+        }
+
+        return 0;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float native_measureText(Paint thisPaint, char[] text, int index,
+            int count) {
+        // get the delegate
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return 0;
+        }
+
+        return delegate.measureText(text, index, count);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float native_measureText(Paint thisPaint, String text, int start, int end) {
+        return native_measureText(thisPaint, text.toCharArray(), start, end - start);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float native_measureText(Paint thisPaint, String text) {
+        return native_measureText(thisPaint, text.toCharArray(), 0, text.length());
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_breakText(Paint thisPaint, char[] text, int index, int count,
+            float maxWidth, float[] measuredWidth) {
+
+        // get the delegate
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return 0;
+        }
+
+        int inc = count > 0 ? 1 : -1;
+
+        int measureIndex = 0;
+        float measureAcc = 0;
+        for (int i = index; i != index + count; i += inc, measureIndex++) {
+            int start, end;
+            if (i < index) {
+                start = i;
+                end = index;
+            } else {
+                start = index;
+                end = i;
+            }
+
+            // measure from start to end
+            float res = delegate.measureText(text, start, end - start + 1);
+
+            if (measuredWidth != null) {
+                measuredWidth[measureIndex] = res;
+            }
+
+            measureAcc += res;
+            if (res > maxWidth) {
+                // we should not return this char index, but since it's 0-based
+                // and we need to return a count, we simply return measureIndex;
+                return measureIndex;
+            }
+
+        }
+
+        return measureIndex;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_breakText(Paint thisPaint, String text, boolean measureForwards,
+            float maxWidth, float[] measuredWidth) {
+        return native_breakText(thisPaint, text.toCharArray(), 0, text.length(), maxWidth,
+                measuredWidth);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_init() {
+        Paint_Delegate newDelegate = new Paint_Delegate();
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_initWithPaint(int paint) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(paint);
+        if (delegate == null) {
+            return 0;
+        }
+
+        Paint_Delegate newDelegate = new Paint_Delegate(delegate);
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_reset(int native_object) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_object);
+        if (delegate == null) {
+            return;
+        }
+
+        delegate.reset();
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_set(int native_dst, int native_src) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate_dst = sManager.getDelegate(native_dst);
+        if (delegate_dst == null) {
+            return;
+        }
+
+        // get the delegate from the native int.
+        Paint_Delegate delegate_src = sManager.getDelegate(native_src);
+        if (delegate_src == null) {
+            return;
+        }
+
+        delegate_dst.set(delegate_src);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_getStyle(int native_object) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_object);
+        if (delegate == null) {
+            return 0;
+        }
+
+        return delegate.mStyle;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setStyle(int native_object, int style) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_object);
+        if (delegate == null) {
+            return;
+        }
+
+        delegate.mStyle = style;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_getStrokeCap(int native_object) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_object);
+        if (delegate == null) {
+            return 0;
+        }
+
+        return delegate.mCap;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setStrokeCap(int native_object, int cap) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_object);
+        if (delegate == null) {
+            return;
+        }
+
+        delegate.mCap = cap;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_getStrokeJoin(int native_object) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_object);
+        if (delegate == null) {
+            return 0;
+        }
+
+        return delegate.mJoin;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setStrokeJoin(int native_object, int join) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_object);
+        if (delegate == null) {
+            return;
+        }
+
+        delegate.mJoin = join;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_getFillPath(int native_object, int src, int dst) {
+        Paint_Delegate paint = sManager.getDelegate(native_object);
+        if (paint == null) {
+            return false;
+        }
+
+        Path_Delegate srcPath = Path_Delegate.getDelegate(src);
+        if (srcPath == null) {
+            return true;
+        }
+
+        Path_Delegate dstPath = Path_Delegate.getDelegate(dst);
+        if (dstPath == null) {
+            return true;
+        }
+
+        Stroke stroke = paint.getJavaStroke();
+        Shape strokeShape = stroke.createStrokedShape(srcPath.getJavaShape());
+
+        dstPath.setJavaShape(strokeShape);
+
+        // FIXME figure out the return value?
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_setShader(int native_object, int shader) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_object);
+        if (delegate == null) {
+            return shader;
+        }
+
+        delegate.mShader = Shader_Delegate.getDelegate(shader);
+
+        return shader;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_setColorFilter(int native_object, int filter) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_object);
+        if (delegate == null) {
+            return filter;
+        }
+
+        delegate.mColorFilter = ColorFilter_Delegate.getDelegate(filter);;
+
+        // since none of those are supported, display a fidelity warning right away
+        if (delegate.mColorFilter != null && delegate.mColorFilter.isSupported() == false) {
+            Bridge.getLog().fidelityWarning(LayoutLog.TAG_COLORFILTER,
+                    delegate.mColorFilter.getSupportMessage(), null, null /*data*/);
+        }
+
+        return filter;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_setXfermode(int native_object, int xfermode) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_object);
+        if (delegate == null) {
+            return xfermode;
+        }
+
+        delegate.mXfermode = Xfermode_Delegate.getDelegate(xfermode);
+
+        return xfermode;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_setPathEffect(int native_object, int effect) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_object);
+        if (delegate == null) {
+            return effect;
+        }
+
+        delegate.mPathEffect = PathEffect_Delegate.getDelegate(effect);
+
+        return effect;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_setMaskFilter(int native_object, int maskfilter) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_object);
+        if (delegate == null) {
+            return maskfilter;
+        }
+
+        delegate.mMaskFilter = MaskFilter_Delegate.getDelegate(maskfilter);
+
+        // since none of those are supported, display a fidelity warning right away
+        if (delegate.mMaskFilter != null && delegate.mMaskFilter.isSupported() == false) {
+            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
+                    delegate.mMaskFilter.getSupportMessage(), null, null /*data*/);
+        }
+
+        return maskfilter;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_setTypeface(int native_object, int typeface) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_object);
+        if (delegate == null) {
+            return 0;
+        }
+
+        delegate.mTypeface = Typeface_Delegate.getDelegate(typeface);
+        delegate.updateFontObject();
+        return typeface;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_setRasterizer(int native_object, int rasterizer) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_object);
+        if (delegate == null) {
+            return rasterizer;
+        }
+
+        delegate.mRasterizer = Rasterizer_Delegate.getDelegate(rasterizer);
+
+        // since none of those are supported, display a fidelity warning right away
+        if (delegate.mRasterizer != null && delegate.mRasterizer.isSupported() == false) {
+            Bridge.getLog().fidelityWarning(LayoutLog.TAG_RASTERIZER,
+                    delegate.mRasterizer.getSupportMessage(), null, null /*data*/);
+        }
+
+        return rasterizer;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_getTextAlign(int native_object) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_object);
+        if (delegate == null) {
+            return 0;
+        }
+
+        return delegate.mTextAlign;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setTextAlign(int native_object, int align) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_object);
+        if (delegate == null) {
+            return;
+        }
+
+        delegate.mTextAlign = align;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float native_getFontMetrics(int native_paint, FontMetrics metrics) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_paint);
+        if (delegate == null) {
+            return 0.f;
+        }
+
+        return delegate.getFontMetrics(metrics);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_getTextWidths(int native_object, char[] text, int index,
+            int count, float[] widths) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(native_object);
+        if (delegate == null) {
+            return 0;
+        }
+
+        if (delegate.mFonts.size() > 0) {
+            // FIXME: handle multi-char characters (see measureText)
+            float totalAdvance = 0;
+            for (int i = 0; i < count; i++) {
+                char c = text[i + index];
+                boolean found = false;
+                for (FontInfo info : delegate.mFonts) {
+                    if (info.mFont.canDisplay(c)) {
+                        float adv = info.mMetrics.charWidth(c);
+                        totalAdvance += adv;
+                        if (widths != null) {
+                            widths[i] = adv;
+                        }
+
+                        found = true;
+                        break;
+                    }
+                }
+
+                if (found == false) {
+                    // no advance for this char.
+                    if (widths != null) {
+                        widths[i] = 0.f;
+                    }
+                }
+            }
+
+            return (int) totalAdvance;
+        }
+
+        return 0;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_getTextWidths(int native_object, String text, int start,
+            int end, float[] widths) {
+        return native_getTextWidths(native_object, text.toCharArray(), start, end - start, widths);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_getTextPath(int native_object,
+                char[] text, int index, int count, float x, float y, int path) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Paint.getTextPath is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_getTextPath(int native_object,
+            String text, int start, int end, float x, float y, int path) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Paint.getTextPath is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeGetStringBounds(int nativePaint, String text, int start,
+            int end, Rect bounds) {
+        nativeGetCharArrayBounds(nativePaint, text.toCharArray(), start, end - start, bounds);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeGetCharArrayBounds(int nativePaint, char[] text, int index,
+            int count, Rect bounds) {
+
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(nativePaint);
+        if (delegate == null) {
+            return;
+        }
+
+        // FIXME should test if the main font can display all those characters.
+        // See MeasureText
+        if (delegate.mFonts.size() > 0) {
+            FontInfo mainInfo = delegate.mFonts.get(0);
+
+            Rectangle2D rect = mainInfo.mFont.getStringBounds(text, index, index + count,
+                    delegate.mFontContext);
+            bounds.set(0, 0, (int) rect.getWidth(), (int) rect.getHeight());
+        }
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void finalizer(int nativePaint) {
+        sManager.removeJavaReferenceFor(nativePaint);
+    }
+
+    // ---- Private delegate/helper methods ----
+
+    /*package*/ Paint_Delegate() {
+        reset();
+    }
+
+    private Paint_Delegate(Paint_Delegate paint) {
+        set(paint);
+    }
+
+    private void set(Paint_Delegate paint) {
+        mFlags = paint.mFlags;
+        mColor = paint.mColor;
+        mStyle = paint.mStyle;
+        mCap = paint.mCap;
+        mJoin = paint.mJoin;
+        mTextAlign = paint.mTextAlign;
+        mTypeface = paint.mTypeface;
+        mStrokeWidth = paint.mStrokeWidth;
+        mStrokeMiter = paint.mStrokeMiter;
+        mTextSize = paint.mTextSize;
+        mTextScaleX = paint.mTextScaleX;
+        mTextSkewX = paint.mTextSkewX;
+        mXfermode = paint.mXfermode;
+        mColorFilter = paint.mColorFilter;
+        mShader = paint.mShader;
+        mPathEffect = paint.mPathEffect;
+        mMaskFilter = paint.mMaskFilter;
+        mRasterizer = paint.mRasterizer;
+        updateFontObject();
+    }
+
+    private void reset() {
+        mFlags = Paint.DEFAULT_PAINT_FLAGS;
+        mColor = 0xFF000000;
+        mStyle = Paint.Style.FILL.nativeInt;
+        mCap = Paint.Cap.BUTT.nativeInt;
+        mJoin = Paint.Join.MITER.nativeInt;
+        mTextAlign = 0;
+        mTypeface = Typeface_Delegate.getDelegate(Typeface.sDefaults[0].native_instance);
+        mStrokeWidth = 1.f;
+        mStrokeMiter = 4.f;
+        mTextSize = 20.f;
+        mTextScaleX = 1.f;
+        mTextSkewX = 0.f;
+        mXfermode = null;
+        mColorFilter = null;
+        mShader = null;
+        mPathEffect = null;
+        mMaskFilter = null;
+        mRasterizer = null;
+        updateFontObject();
+    }
+
+    /**
+     * Update the {@link Font} object from the typeface, text size and scaling
+     */
+    @SuppressWarnings("deprecation")
+    private void updateFontObject() {
+        if (mTypeface != null) {
+            // Get the fonts from the TypeFace object.
+            List<Font> fonts = mTypeface.getFonts();
+
+            // create new font objects as well as FontMetrics, based on the current text size
+            // and skew info.
+            ArrayList<FontInfo> infoList = new ArrayList<FontInfo>(fonts.size());
+            for (Font font : fonts) {
+                FontInfo info = new FontInfo();
+                info.mFont = font.deriveFont(mTextSize);
+                if (mTextScaleX != 1.0 || mTextSkewX != 0) {
+                    // TODO: support skew
+                    info.mFont = info.mFont.deriveFont(new AffineTransform(
+                            mTextScaleX, mTextSkewX, 0, 0, 1, 0));
+                }
+                info.mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(info.mFont);
+
+                infoList.add(info);
+            }
+
+            mFonts = Collections.unmodifiableList(infoList);
+        }
+    }
+
+    /*package*/ float measureText(char[] text, int index, int count) {
+
+        // WARNING: the logic in this method is similar to Canvas_Delegate.native_drawText
+        // Any change to this method should be reflected there as well
+
+        if (mFonts.size() > 0) {
+            FontInfo mainFont = mFonts.get(0);
+            int i = index;
+            int lastIndex = index + count;
+            float total = 0f;
+            while (i < lastIndex) {
+                // always start with the main font.
+                int upTo = mainFont.mFont.canDisplayUpTo(text, i, lastIndex);
+                if (upTo == -1) {
+                    // shortcut to exit
+                    return total + mainFont.mMetrics.charsWidth(text, i, lastIndex - i);
+                } else if (upTo > 0) {
+                    total += mainFont.mMetrics.charsWidth(text, i, upTo - i);
+                    i = upTo;
+                    // don't call continue at this point. Since it is certain the main font
+                    // cannot display the font a index upTo (now ==i), we move on to the
+                    // fallback fonts directly.
+                }
+
+                // no char supported, attempt to read the next char(s) with the
+                // fallback font. In this case we only test the first character
+                // and then go back to test with the main font.
+                // Special test for 2-char characters.
+                boolean foundFont = false;
+                for (int f = 1 ; f < mFonts.size() ; f++) {
+                    FontInfo fontInfo = mFonts.get(f);
+
+                    // need to check that the font can display the character. We test
+                    // differently if the char is a high surrogate.
+                    int charCount = Character.isHighSurrogate(text[i]) ? 2 : 1;
+                    upTo = fontInfo.mFont.canDisplayUpTo(text, i, i + charCount);
+                    if (upTo == -1) {
+                        total += fontInfo.mMetrics.charsWidth(text, i, charCount);
+                        i += charCount;
+                        foundFont = true;
+                        break;
+
+                    }
+                }
+
+                // in case no font can display the char, measure it with the main font.
+                if (foundFont == false) {
+                    int size = Character.isHighSurrogate(text[i]) ? 2 : 1;
+                    total += mainFont.mMetrics.charsWidth(text, i, size);
+                    i += size;
+                }
+            }
+
+            return total;
+        }
+
+        return 0;
+    }
+
+    private float getFontMetrics(FontMetrics metrics) {
+        if (mFonts.size() > 0) {
+            java.awt.FontMetrics javaMetrics = mFonts.get(0).mMetrics;
+            if (metrics != null) {
+                // Android expects negative ascent so we invert the value from Java.
+                metrics.top = - javaMetrics.getMaxAscent();
+                metrics.ascent = - javaMetrics.getAscent();
+                metrics.descent = javaMetrics.getDescent();
+                metrics.bottom = javaMetrics.getMaxDescent();
+                metrics.leading = javaMetrics.getLeading();
+            }
+
+            return javaMetrics.getHeight();
+        }
+
+        return 0;
+    }
+
+
+
+    private static void setFlag(Paint thisPaint, int flagMask, boolean flagValue) {
+        // get the delegate from the native int.
+        Paint_Delegate delegate = sManager.getDelegate(thisPaint.mNativePaint);
+        if (delegate == null) {
+            return;
+        }
+
+        if (flagValue) {
+            delegate.mFlags |= flagMask;
+        } else {
+            delegate.mFlags &= ~flagMask;
+        }
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path.java b/tools/layoutlib/bridge/src/android/graphics/Path.java
deleted file mode 100644
index 12d2cde..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Path.java
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Ellipse2D;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Rectangle2D;
-
-/**
- * The Path class encapsulates compound (multiple contour) geometric paths
- * consisting of straight line segments, quadratic curves, and cubic curves.
- * It can be drawn with canvas.drawPath(path, paint), either filled or stroked
- * (based on the paint's Style), or it can be used for clipping or to draw
- * text on a path.
- */
-public class Path {
-    
-    private FillType mFillType = FillType.WINDING;
-    private GeneralPath mPath = new GeneralPath();
-    
-    private float mLastX = 0;
-    private float mLastY = 0;
-    
-    //---------- Custom methods ----------
-
-    public Shape getAwtShape() {
-        return mPath;
-    }
-
-    //----------
-
-    /**
-     * Create an empty path
-     */
-    public Path() {
-    }
-
-    /**
-     * Create a new path, copying the contents from the src path.
-     *
-     * @param src The path to copy from when initializing the new path
-     */
-    public Path(Path src) {
-        mPath.append(src.mPath, false /* connect */);
-    }
-    
-    /**
-     * Clear any lines and curves from the path, making it empty.
-     * This does NOT change the fill-type setting.
-     */
-    public void reset() {
-        mPath = new GeneralPath();
-    }
-
-    /**
-     * Rewinds the path: clears any lines and curves from the path but
-     * keeps the internal data structure for faster reuse.
-     */
-    public void rewind() {
-        // FIXME
-        throw new UnsupportedOperationException();
-    }
-
-    /** Replace the contents of this with the contents of src.
-    */
-    public void set(Path src) {
-        mPath.append(src.mPath, false /* connect */);
-    }
-
-    /** Enum for the ways a path may be filled
-    */
-    public enum FillType {
-        // these must match the values in SkPath.h
-        WINDING         (GeneralPath.WIND_NON_ZERO, false),
-        EVEN_ODD        (GeneralPath.WIND_EVEN_ODD, false),
-        INVERSE_WINDING (GeneralPath.WIND_NON_ZERO, true),
-        INVERSE_EVEN_ODD(GeneralPath.WIND_EVEN_ODD, true);
-        
-        FillType(int rule, boolean inverse) {
-            this.rule = rule;
-            this.inverse = inverse;
-        }
-
-        final int rule;
-        final boolean inverse;
-    }
-    
-    /**
-     * Return the path's fill type. This defines how "inside" is
-     * computed. The default value is WINDING.
-     *
-     * @return the path's fill type
-     */
-    public FillType getFillType() {
-        return mFillType;
-    }
-
-    /**
-     * Set the path's fill type. This defines how "inside" is computed.
-     *
-     * @param ft The new fill type for this path
-     */
-    public void setFillType(FillType ft) {
-        mFillType = ft;
-        mPath.setWindingRule(ft.rule);
-    }
-    
-    /**
-     * Returns true if the filltype is one of the INVERSE variants
-     *
-     * @return true if the filltype is one of the INVERSE variants
-     */
-    public boolean isInverseFillType() {
-        return mFillType.inverse;
-    }
-    
-    /**
-     * Toggles the INVERSE state of the filltype
-     */
-    public void toggleInverseFillType() {
-        switch (mFillType) {
-            case WINDING:
-                mFillType = FillType.INVERSE_WINDING;
-                break;
-            case EVEN_ODD:
-                mFillType = FillType.INVERSE_EVEN_ODD;
-                break;
-            case INVERSE_WINDING:
-                mFillType = FillType.WINDING;
-                break;
-            case INVERSE_EVEN_ODD:
-                mFillType = FillType.EVEN_ODD;
-                break;
-        }
-    }
-    
-    /**
-     * Returns true if the path is empty (contains no lines or curves)
-     *
-     * @return true if the path is empty (contains no lines or curves)
-     */
-    public boolean isEmpty() {
-        return mPath.getCurrentPoint() == null;
-    }
-
-    /**
-     * Returns true if the path specifies a rectangle. If so, and if rect is
-     * not null, set rect to the bounds of the path. If the path does not
-     * specify a rectangle, return false and ignore rect.
-     *
-     * @param rect If not null, returns the bounds of the path if it specifies
-     *             a rectangle
-     * @return     true if the path specifies a rectangle
-     */
-    public boolean isRect(RectF rect) {
-        // FIXME
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Compute the bounds of the path, and write the answer into bounds. If the
-     * path contains 0 or 1 points, the bounds is set to (0,0,0,0)
-     *
-     * @param bounds Returns the computed bounds of the path
-     * @param exact If true, return the exact (but slower) bounds, else return
-     *              just the bounds of all control points
-     */
-    public void computeBounds(RectF bounds, boolean exact) {
-        Rectangle2D rect = mPath.getBounds2D();
-        bounds.left = (float)rect.getMinX();
-        bounds.right = (float)rect.getMaxX();
-        bounds.top = (float)rect.getMinY();
-        bounds.bottom = (float)rect.getMaxY();
-    }
-
-    /**
-     * Hint to the path to prepare for adding more points. This can allow the
-     * path to more efficiently allocate its storage.
-     *
-     * @param extraPtCount The number of extra points that may be added to this
-     *                     path
-     */
-    public void incReserve(int extraPtCount) {
-        // pass
-    }
-
-    /**
-     * Set the beginning of the next contour to the point (x,y).
-     *
-     * @param x The x-coordinate of the start of a new contour
-     * @param y The y-coordinate of the start of a new contour
-     */
-    public void moveTo(float x, float y) {
-        mPath.moveTo(mLastX = x, mLastY = y);
-    }
-
-    /**
-     * Set the beginning of the next contour relative to the last point on the
-     * previous contour. If there is no previous contour, this is treated the
-     * same as moveTo().
-     *
-     * @param dx The amount to add to the x-coordinate of the end of the
-     *           previous contour, to specify the start of a new contour
-     * @param dy The amount to add to the y-coordinate of the end of the
-     *           previous contour, to specify the start of a new contour
-     */
-    public void rMoveTo(float dx, float dy) {
-        dx += mLastX;
-        dy += mLastY;
-        mPath.moveTo(mLastX = dx, mLastY = dy);
-    }
-
-    /**
-     * Add a line from the last point to the specified point (x,y).
-     * If no moveTo() call has been made for this contour, the first point is
-     * automatically set to (0,0).
-     *
-     * @param x The x-coordinate of the end of a line
-     * @param y The y-coordinate of the end of a line
-     */
-    public void lineTo(float x, float y) {
-        mPath.lineTo(mLastX = x, mLastY = y);
-    }
-
-    /**
-     * Same as lineTo, but the coordinates are considered relative to the last
-     * point on this contour. If there is no previous point, then a moveTo(0,0)
-     * is inserted automatically.
-     *
-     * @param dx The amount to add to the x-coordinate of the previous point on
-     *           this contour, to specify a line
-     * @param dy The amount to add to the y-coordinate of the previous point on
-     *           this contour, to specify a line
-     */
-    public void rLineTo(float dx, float dy) {
-        if (isEmpty()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-        dx += mLastX;
-        dy += mLastY;
-        mPath.lineTo(mLastX = dx, mLastY = dy);
-    }
-
-    /**
-     * Add a quadratic bezier from the last point, approaching control point
-     * (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for
-     * this contour, the first point is automatically set to (0,0).
-     *
-     * @param x1 The x-coordinate of the control point on a quadratic curve
-     * @param y1 The y-coordinate of the control point on a quadratic curve
-     * @param x2 The x-coordinate of the end point on a quadratic curve
-     * @param y2 The y-coordinate of the end point on a quadratic curve
-     */
-    public void quadTo(float x1, float y1, float x2, float y2) {
-        mPath.quadTo(x1, y1, mLastX = x2, mLastY = y2);
-    }
-
-    /**
-     * Same as quadTo, but the coordinates are considered relative to the last
-     * point on this contour. If there is no previous point, then a moveTo(0,0)
-     * is inserted automatically.
-     *
-     * @param dx1 The amount to add to the x-coordinate of the last point on
-     *            this contour, for the control point of a quadratic curve
-     * @param dy1 The amount to add to the y-coordinate of the last point on
-     *            this contour, for the control point of a quadratic curve
-     * @param dx2 The amount to add to the x-coordinate of the last point on
-     *            this contour, for the end point of a quadratic curve
-     * @param dy2 The amount to add to the y-coordinate of the last point on
-     *            this contour, for the end point of a quadratic curve
-     */
-    public void rQuadTo(float dx1, float dy1, float dx2, float dy2) {
-        if (isEmpty()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-        dx1 += mLastX;
-        dy1 += mLastY;
-        dx2 += mLastX;
-        dy2 += mLastY;
-        mPath.quadTo(dx1, dy1, mLastX = dx2, mLastY = dy2);
-    }
-
-    /**
-     * Add a cubic bezier from the last point, approaching control points
-     * (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been
-     * made for this contour, the first point is automatically set to (0,0).
-     *
-     * @param x1 The x-coordinate of the 1st control point on a cubic curve
-     * @param y1 The y-coordinate of the 1st control point on a cubic curve
-     * @param x2 The x-coordinate of the 2nd control point on a cubic curve
-     * @param y2 The y-coordinate of the 2nd control point on a cubic curve
-     * @param x3 The x-coordinate of the end point on a cubic curve
-     * @param y3 The y-coordinate of the end point on a cubic curve
-     */
-    public void cubicTo(float x1, float y1, float x2, float y2,
-                        float x3, float y3) {
-        mPath.curveTo(x1, y1, x2, y2, mLastX = x3, mLastY = y3);
-    }
-
-    /**
-     * Same as cubicTo, but the coordinates are considered relative to the
-     * current point on this contour. If there is no previous point, then a
-     * moveTo(0,0) is inserted automatically.
-     */
-    public void rCubicTo(float dx1, float dy1, float dx2, float dy2,
-                         float dx3, float dy3) {
-        if (isEmpty()) {
-            mPath.moveTo(mLastX = 0, mLastY = 0);
-        }
-        dx1 += mLastX;
-        dy1 += mLastY;
-        dx2 += mLastX;
-        dy2 += mLastY;
-        dx3 += mLastX;
-        dy3 += mLastY;
-        mPath.curveTo(dx1, dy1, dx2, dy2, mLastX = dx3, mLastY = dy3);
-    }
-
-    /**
-     * Append the specified arc to the path as a new contour. If the start of
-     * the path is different from the path's current last point, then an
-     * automatic lineTo() is added to connect the current contour to the
-     * start of the arc. However, if the path is empty, then we call moveTo()
-     * with the first point of the arc. The sweep angle is tread mod 360.
-     *
-     * @param oval        The bounds of oval defining shape and size of the arc
-     * @param startAngle  Starting angle (in degrees) where the arc begins
-     * @param sweepAngle  Sweep angle (in degrees) measured clockwise, treated
-     *                    mod 360.
-     * @param forceMoveTo If true, always begin a new contour with the arc
-     */
-    public void arcTo(RectF oval, float startAngle, float sweepAngle,
-                      boolean forceMoveTo) {
-        throw new UnsupportedOperationException();
-    }
-    
-    /**
-     * Append the specified arc to the path as a new contour. If the start of
-     * the path is different from the path's current last point, then an
-     * automatic lineTo() is added to connect the current contour to the
-     * start of the arc. However, if the path is empty, then we call moveTo()
-     * with the first point of the arc.
-     *
-     * @param oval        The bounds of oval defining shape and size of the arc
-     * @param startAngle  Starting angle (in degrees) where the arc begins
-     * @param sweepAngle  Sweep angle (in degrees) measured clockwise
-     */
-    public void arcTo(RectF oval, float startAngle, float sweepAngle) {
-        throw new UnsupportedOperationException();
-    }
-    
-    /**
-     * Close the current contour. If the current point is not equal to the
-     * first point of the contour, a line segment is automatically added.
-     */
-    public void close() {
-        mPath.closePath();
-    }
-
-    /**
-     * Specifies how closed shapes (e.g. rects, ovals) are oriented when they
-     * are added to a path.
-     */
-    public enum Direction {
-        /** clockwise */
-        CW  (0),    // must match enum in SkPath.h
-        /** counter-clockwise */
-        CCW (1);    // must match enum in SkPath.h
-        
-        Direction(int ni) {
-            nativeInt = ni;
-        }
-        final int nativeInt;
-    }
-    
-    /**
-     * Add a closed rectangle contour to the path
-     *
-     * @param rect The rectangle to add as a closed contour to the path
-     * @param dir  The direction to wind the rectangle's contour
-     */
-    public void addRect(RectF rect, Direction dir) {
-        if (rect == null) {
-            throw new NullPointerException("need rect parameter");
-        }
-        
-        addRect(rect.left, rect.top, rect.right, rect.bottom, dir);
-    }
-
-    /**
-     * Add a closed rectangle contour to the path
-     *
-     * @param left   The left side of a rectangle to add to the path
-     * @param top    The top of a rectangle to add to the path
-     * @param right  The right side of a rectangle to add to the path
-     * @param bottom The bottom of a rectangle to add to the path
-     * @param dir    The direction to wind the rectangle's contour
-     */
-    public void addRect(float left, float top, float right, float bottom,
-                        Direction dir) {
-        moveTo(left, top);
-
-        switch (dir) {
-            case CW:
-                lineTo(right, top);
-                lineTo(right, bottom);
-                lineTo(left, bottom);
-                break;
-            case CCW:
-                lineTo(left, bottom);
-                lineTo(right, bottom);
-                lineTo(right, top);
-                break;
-        }
-
-        close();
-    }
-
-    /**
-     * Add a closed oval contour to the path
-     *
-     * @param oval The bounds of the oval to add as a closed contour to the path
-     * @param dir  The direction to wind the oval's contour
-     */
-    public void addOval(RectF oval, Direction dir) {
-        if (oval == null) {
-            throw new NullPointerException("need oval parameter");
-        }
-
-        // FIXME Need to support direction
-        Ellipse2D ovalShape = new Ellipse2D.Float(oval.left, oval.top, oval.width(), oval.height());
-        
-        mPath.append(ovalShape, false /* connect */);
-    }
-
-    /**
-     * Add a closed circle contour to the path
-     *
-     * @param x   The x-coordinate of the center of a circle to add to the path
-     * @param y   The y-coordinate of the center of a circle to add to the path
-     * @param radius The radius of a circle to add to the path
-     * @param dir    The direction to wind the circle's contour
-     */
-    public void addCircle(float x, float y, float radius, Direction dir) {
-        // FIXME
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Add the specified arc to the path as a new contour.
-     *
-     * @param oval The bounds of oval defining the shape and size of the arc
-     * @param startAngle Starting angle (in degrees) where the arc begins
-     * @param sweepAngle Sweep angle (in degrees) measured clockwise
-     */
-    public void addArc(RectF oval, float startAngle, float sweepAngle) {
-        if (oval == null) {
-            throw new NullPointerException("need oval parameter");
-        }
-        // FIXME
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-        * Add a closed round-rectangle contour to the path
-     *
-     * @param rect The bounds of a round-rectangle to add to the path
-     * @param rx   The x-radius of the rounded corners on the round-rectangle
-     * @param ry   The y-radius of the rounded corners on the round-rectangle
-     * @param dir  The direction to wind the round-rectangle's contour
-     */
-    public void addRoundRect(RectF rect, float rx, float ry, Direction dir) {
-        if (rect == null) {
-            throw new NullPointerException("need rect parameter");
-        }
-        // FIXME
-        throw new UnsupportedOperationException();
-    }
-    
-    /**
-     * Add a closed round-rectangle contour to the path. Each corner receives
-     * two radius values [X, Y]. The corners are ordered top-left, top-right,
-     * bottom-right, bottom-left
-     *
-     * @param rect The bounds of a round-rectangle to add to the path
-     * @param radii Array of 8 values, 4 pairs of [X,Y] radii
-     * @param dir  The direction to wind the round-rectangle's contour
-     */
-    public void addRoundRect(RectF rect, float[] radii, Direction dir) {
-        if (rect == null) {
-            throw new NullPointerException("need rect parameter");
-        }
-        if (radii.length < 8) {
-            throw new ArrayIndexOutOfBoundsException("radii[] needs 8 values");
-        }
-        // FIXME
-        throw new UnsupportedOperationException();
-    }
-    
-    /**
-     * Add a copy of src to the path, offset by (dx,dy)
-     *
-     * @param src The path to add as a new contour
-     * @param dx  The amount to translate the path in X as it is added
-     */
-    public void addPath(Path src, float dx, float dy) {
-        PathIterator iterator = src.mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy));
-        mPath.append(iterator, false /* connect */);
-    }
-
-    /**
-     * Add a copy of src to the path
-     *
-     * @param src The path that is appended to the current path
-     */
-    public void addPath(Path src) {
-        addPath(src, 0, 0);
-    }
-
-    /**
-     * Add a copy of src to the path, transformed by matrix
-     *
-     * @param src The path to add as a new contour
-     */
-    public void addPath(Path src, Matrix matrix) {
-        // FIXME
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Offset the path by (dx,dy), returning true on success
-     *
-     * @param dx  The amount in the X direction to offset the entire path
-     * @param dy  The amount in the Y direction to offset the entire path
-     * @param dst The translated path is written here. If this is null, then
-     *            the original path is modified.
-     */
-    public void offset(float dx, float dy, Path dst) {
-        GeneralPath newPath = new GeneralPath();
-        
-        PathIterator iterator = mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy));
-        
-        newPath.append(iterator, false /* connect */);
-        
-        if (dst != null) {
-            dst.mPath = newPath;
-        } else {
-            mPath = newPath;
-        }
-    }
-
-    /**
-     * Offset the path by (dx,dy), returning true on success
-     *
-     * @param dx The amount in the X direction to offset the entire path
-     * @param dy The amount in the Y direction to offset the entire path
-     */
-    public void offset(float dx, float dy) {
-        offset(dx, dy, null /* dst */);
-    }
-
-    /**
-     * Sets the last point of the path.
-     *
-     * @param dx The new X coordinate for the last point
-     * @param dy The new Y coordinate for the last point
-     */
-    public void setLastPoint(float dx, float dy) {
-        mLastX = dx;
-        mLastY = dy;
-    }
-
-    /**
-     * Transform the points in this path by matrix, and write the answer
-     * into dst. If dst is null, then the the original path is modified.
-     *
-     * @param matrix The matrix to apply to the path
-     * @param dst    The transformed path is written here. If dst is null,
-     *               then the the original path is modified
-     */
-    public void transform(Matrix matrix, Path dst) {
-        // FIXME
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Transform the points in this path by matrix.
-     *
-     * @param matrix The matrix to apply to the path
-     */
-    public void transform(Matrix matrix) {
-        transform(matrix, null /* dst */);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java
new file mode 100644
index 0000000..c448f0e
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/PathDashPathEffect_Delegate.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import java.awt.Stroke;
+
+/**
+ * Delegate implementing the native methods of android.graphics.PathDashPathEffect
+ *
+ * Through the layoutlib_create tool, the original native methods of PathDashPathEffect have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original PathDashPathEffect class.
+ *
+ * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
+ * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
+ *
+ * @see PathEffect_Delegate
+ *
+ */
+public class PathDashPathEffect_Delegate extends PathEffect_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public Stroke getStroke(Paint_Delegate paint) {
+        // FIXME
+        return null;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Path Dash Path Effects are not supported in Layout Preview mode.";
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreate(int native_path, float advance, float phase,
+            int native_style) {
+        PathDashPathEffect_Delegate newDelegate = new PathDashPathEffect_Delegate();
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
new file mode 100644
index 0000000..bd2b6de
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import java.awt.Stroke;
+
+/**
+ * Delegate implementing the native methods of android.graphics.PathEffect
+ *
+ * Through the layoutlib_create tool, the original native methods of PathEffect have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original PathEffect class.
+ *
+ * This also serve as a base class for all PathEffect delegate classes.
+ *
+ * @see DelegateManager
+ *
+ */
+public abstract class PathEffect_Delegate {
+
+    // ---- delegate manager ----
+    protected static final DelegateManager<PathEffect_Delegate> sManager =
+            new DelegateManager<PathEffect_Delegate>(PathEffect_Delegate.class);
+
+    // ---- delegate helper data ----
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    public static PathEffect_Delegate getDelegate(int nativeShader) {
+        return sManager.getDelegate(nativeShader);
+    }
+
+    public abstract Stroke getStroke(Paint_Delegate paint);
+    public abstract boolean isSupported();
+    public abstract String getSupportMessage();
+
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeDestructor(int native_patheffect) {
+        sManager.removeJavaReferenceFor(native_patheffect);
+    }
+
+    // ---- Private delegate/helper methods ----
+
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
new file mode 100644
index 0000000..6c9f48f
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
@@ -0,0 +1,761 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.graphics.Path.Direction;
+import android.graphics.Path.FillType;
+
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Area;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * Delegate implementing the native methods of android.graphics.Path
+ *
+ * Through the layoutlib_create tool, the original native methods of Path have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original Path class.
+ *
+ * @see DelegateManager
+ *
+ */
+public final class Path_Delegate {
+
+    // ---- delegate manager ----
+    private static final DelegateManager<Path_Delegate> sManager =
+            new DelegateManager<Path_Delegate>(Path_Delegate.class);
+
+    // ---- delegate data ----
+    private FillType mFillType = FillType.WINDING;
+    private GeneralPath mPath = new GeneralPath();
+
+    private float mLastX = 0;
+    private float mLastY = 0;
+
+    // ---- Public Helper methods ----
+
+    public static Path_Delegate getDelegate(int nPath) {
+        return sManager.getDelegate(nPath);
+    }
+
+    public Shape getJavaShape() {
+        return mPath;
+    }
+
+    public void setJavaShape(Shape shape) {
+        mPath.reset();
+        mPath.append(shape, false /*connect*/);
+    }
+
+    public void reset() {
+        mPath.reset();
+    }
+
+    public void setPathIterator(PathIterator iterator) {
+        mPath.reset();
+        mPath.append(iterator, false /*connect*/);
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int init1() {
+        // create the delegate
+        Path_Delegate newDelegate = new Path_Delegate();
+
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int init2(int nPath) {
+        // create the delegate
+        Path_Delegate newDelegate = new Path_Delegate();
+
+        // get the delegate to copy, which could be null if nPath is 0
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate != null) {
+            newDelegate.set(pathDelegate);
+        }
+
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_reset(int nPath) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        pathDelegate.mPath.reset();
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_rewind(int nPath) {
+        // call out to reset since there's nothing to optimize in
+        // terms of data structs.
+        native_reset(nPath);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_set(int native_dst, int native_src) {
+        Path_Delegate pathDstDelegate = sManager.getDelegate(native_dst);
+        if (pathDstDelegate == null) {
+            return;
+        }
+
+        Path_Delegate pathSrcDelegate = sManager.getDelegate(native_src);
+        if (pathSrcDelegate == null) {
+            return;
+        }
+
+        pathDstDelegate.set(pathSrcDelegate);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_getFillType(int nPath) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return 0;
+        }
+
+        return pathDelegate.mFillType.nativeInt;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setFillType(int nPath, int ft) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        pathDelegate.mFillType = Path.sFillTypeArray[ft];
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_isEmpty(int nPath) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return true;
+        }
+
+        return pathDelegate.isEmpty();
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean native_isRect(int nPath, RectF rect) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return false;
+        }
+
+        // create an Area that can test if the path is a rect
+        Area area = new Area(pathDelegate.mPath);
+        if (area.isRectangular()) {
+            if (rect != null) {
+                pathDelegate.fillBounds(rect);
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_computeBounds(int nPath, RectF bounds) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        pathDelegate.fillBounds(bounds);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_incReserve(int nPath, int extraPtCount) {
+        // since we use a java2D path, there's no way to pre-allocate new points,
+        // so we do nothing.
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_moveTo(int nPath, float x, float y) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        pathDelegate.moveTo(x, y);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_rMoveTo(int nPath, float dx, float dy) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        pathDelegate.rMoveTo(dx, dy);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_lineTo(int nPath, float x, float y) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        pathDelegate.lineTo(x, y);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_rLineTo(int nPath, float dx, float dy) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        pathDelegate.rLineTo(dx, dy);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_quadTo(int nPath, float x1, float y1, float x2, float y2) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        pathDelegate.quadTo(x1, y1, x2, y2);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_rQuadTo(int nPath, float dx1, float dy1, float dx2, float dy2) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        pathDelegate.rQuadTo(dx1, dy1, dx2, dy2);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_cubicTo(int nPath, float x1, float y1,
+            float x2, float y2, float x3, float y3) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        pathDelegate.cubicTo(x1, y1, x2, y2, x3, y3);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_rCubicTo(int nPath, float x1, float y1,
+            float x2, float y2, float x3, float y3) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        pathDelegate.rCubicTo(x1, y1, x2, y2, x3, y3);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_arcTo(int nPath, RectF oval,
+                    float startAngle, float sweepAngle, boolean forceMoveTo) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        pathDelegate.arcTo(oval, startAngle, sweepAngle, forceMoveTo);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_close(int nPath) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        pathDelegate.close();
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_addRect(int nPath, RectF rect, int dir) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        pathDelegate.addRect(rect.left, rect.top, rect.right, rect.bottom, dir);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_addRect(int nPath,
+            float left, float top, float right, float bottom, int dir) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        pathDelegate.addRect(left, top, right, bottom, dir);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_addOval(int nPath, RectF oval, int dir) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Path.addOval is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_addCircle(int nPath, float x, float y, float radius, int dir) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Path.addCircle is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_addArc(int nPath, RectF oval,
+            float startAngle, float sweepAngle) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Path.addArc is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_addRoundRect(int nPath, RectF rect,
+            float rx, float ry, int dir) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Path.addRoundRect is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_addRoundRect(int nPath, RectF r, float[] radii, int dir) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Path.addRoundRect is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_addPath(int nPath, int src, float dx, float dy) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Path.addPath is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_addPath(int nPath, int src) {
+        native_addPath(nPath, src, 0, 0);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_addPath(int nPath, int src, int matrix) {
+        // FIXME
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Path.addPath is not supported.", null, null /*data*/);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_offset(int nPath, float dx, float dy, int dst_path) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        // could be null if the int is 0;
+        Path_Delegate dstDelegate = sManager.getDelegate(dst_path);
+
+        pathDelegate.offset(dx, dy, dstDelegate);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_offset(int nPath, float dx, float dy) {
+        native_offset(nPath, dx, dy, 0);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_setLastPoint(int nPath, float dx, float dy) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        pathDelegate.mLastX = dx;
+        pathDelegate.mLastY = dy;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_transform(int nPath, int matrix,
+                                                int dst_path) {
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
+        }
+
+        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
+        if (matrixDelegate == null) {
+            return;
+        }
+
+        // this can be null if dst_path is 0
+        Path_Delegate dstDelegate = sManager.getDelegate(dst_path);
+
+        pathDelegate.transform(matrixDelegate, dstDelegate);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void native_transform(int nPath, int matrix) {
+        native_transform(nPath, matrix, 0);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void finalizer(int nPath) {
+        sManager.removeJavaReferenceFor(nPath);
+    }
+
+
+    // ---- Private helper methods ----
+
+    private void set(Path_Delegate delegate) {
+        mPath.reset();
+        setFillType(delegate.mFillType);
+        mPath.append(delegate.mPath, false /*connect*/);
+    }
+
+    private void setFillType(FillType fillType) {
+        mFillType = fillType;
+        mPath.setWindingRule(getWindingRule(fillType));
+    }
+
+    /**
+     * Returns the Java2D winding rules matching a given Android {@link FillType}.
+     * @param type the android fill type
+     * @return the matching java2d winding rule.
+     */
+    private static int getWindingRule(FillType type) {
+        switch (type) {
+            case WINDING:
+            case INVERSE_WINDING:
+                return GeneralPath.WIND_NON_ZERO;
+            case EVEN_ODD:
+            case INVERSE_EVEN_ODD:
+                return GeneralPath.WIND_EVEN_ODD;
+        }
+
+        assert false;
+        throw new IllegalArgumentException();
+    }
+
+    private static Direction getDirection(int direction) {
+        for (Direction d : Direction.values()) {
+            if (direction == d.nativeInt) {
+                return d;
+            }
+        }
+
+        assert false;
+        return null;
+    }
+
+    /**
+     * Returns whether the path is empty.
+     * @return true if the path is empty.
+     */
+    private boolean isEmpty() {
+        return mPath.getCurrentPoint() == null;
+    }
+
+    /**
+     * Fills the given {@link RectF} with the path bounds.
+     * @param bounds the RectF to be filled.
+     */
+    private void fillBounds(RectF bounds) {
+        Rectangle2D rect = mPath.getBounds2D();
+        bounds.left = (float)rect.getMinX();
+        bounds.right = (float)rect.getMaxX();
+        bounds.top = (float)rect.getMinY();
+        bounds.bottom = (float)rect.getMaxY();
+    }
+
+    /**
+     * Set the beginning of the next contour to the point (x,y).
+     *
+     * @param x The x-coordinate of the start of a new contour
+     * @param y The y-coordinate of the start of a new contour
+     */
+    private void moveTo(float x, float y) {
+        mPath.moveTo(mLastX = x, mLastY = y);
+    }
+
+    /**
+     * Set the beginning of the next contour relative to the last point on the
+     * previous contour. If there is no previous contour, this is treated the
+     * same as moveTo().
+     *
+     * @param dx The amount to add to the x-coordinate of the end of the
+     *           previous contour, to specify the start of a new contour
+     * @param dy The amount to add to the y-coordinate of the end of the
+     *           previous contour, to specify the start of a new contour
+     */
+    private void rMoveTo(float dx, float dy) {
+        dx += mLastX;
+        dy += mLastY;
+        mPath.moveTo(mLastX = dx, mLastY = dy);
+    }
+
+    /**
+     * Add a line from the last point to the specified point (x,y).
+     * If no moveTo() call has been made for this contour, the first point is
+     * automatically set to (0,0).
+     *
+     * @param x The x-coordinate of the end of a line
+     * @param y The y-coordinate of the end of a line
+     */
+    private void lineTo(float x, float y) {
+        mPath.lineTo(mLastX = x, mLastY = y);
+    }
+
+    /**
+     * Same as lineTo, but the coordinates are considered relative to the last
+     * point on this contour. If there is no previous point, then a moveTo(0,0)
+     * is inserted automatically.
+     *
+     * @param dx The amount to add to the x-coordinate of the previous point on
+     *           this contour, to specify a line
+     * @param dy The amount to add to the y-coordinate of the previous point on
+     *           this contour, to specify a line
+     */
+    private void rLineTo(float dx, float dy) {
+        if (isEmpty()) {
+            mPath.moveTo(mLastX = 0, mLastY = 0);
+        }
+        dx += mLastX;
+        dy += mLastY;
+        mPath.lineTo(mLastX = dx, mLastY = dy);
+    }
+
+    /**
+     * Add a quadratic bezier from the last point, approaching control point
+     * (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for
+     * this contour, the first point is automatically set to (0,0).
+     *
+     * @param x1 The x-coordinate of the control point on a quadratic curve
+     * @param y1 The y-coordinate of the control point on a quadratic curve
+     * @param x2 The x-coordinate of the end point on a quadratic curve
+     * @param y2 The y-coordinate of the end point on a quadratic curve
+     */
+    private void quadTo(float x1, float y1, float x2, float y2) {
+        mPath.quadTo(x1, y1, mLastX = x2, mLastY = y2);
+    }
+
+    /**
+     * Same as quadTo, but the coordinates are considered relative to the last
+     * point on this contour. If there is no previous point, then a moveTo(0,0)
+     * is inserted automatically.
+     *
+     * @param dx1 The amount to add to the x-coordinate of the last point on
+     *            this contour, for the control point of a quadratic curve
+     * @param dy1 The amount to add to the y-coordinate of the last point on
+     *            this contour, for the control point of a quadratic curve
+     * @param dx2 The amount to add to the x-coordinate of the last point on
+     *            this contour, for the end point of a quadratic curve
+     * @param dy2 The amount to add to the y-coordinate of the last point on
+     *            this contour, for the end point of a quadratic curve
+     */
+    private void rQuadTo(float dx1, float dy1, float dx2, float dy2) {
+        if (isEmpty()) {
+            mPath.moveTo(mLastX = 0, mLastY = 0);
+        }
+        dx1 += mLastX;
+        dy1 += mLastY;
+        dx2 += mLastX;
+        dy2 += mLastY;
+        mPath.quadTo(dx1, dy1, mLastX = dx2, mLastY = dy2);
+    }
+
+    /**
+     * Add a cubic bezier from the last point, approaching control points
+     * (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been
+     * made for this contour, the first point is automatically set to (0,0).
+     *
+     * @param x1 The x-coordinate of the 1st control point on a cubic curve
+     * @param y1 The y-coordinate of the 1st control point on a cubic curve
+     * @param x2 The x-coordinate of the 2nd control point on a cubic curve
+     * @param y2 The y-coordinate of the 2nd control point on a cubic curve
+     * @param x3 The x-coordinate of the end point on a cubic curve
+     * @param y3 The y-coordinate of the end point on a cubic curve
+     */
+    private void cubicTo(float x1, float y1, float x2, float y2,
+                        float x3, float y3) {
+        mPath.curveTo(x1, y1, x2, y2, mLastX = x3, mLastY = y3);
+    }
+
+    /**
+     * Same as cubicTo, but the coordinates are considered relative to the
+     * current point on this contour. If there is no previous point, then a
+     * moveTo(0,0) is inserted automatically.
+     */
+    private void rCubicTo(float dx1, float dy1, float dx2, float dy2,
+                         float dx3, float dy3) {
+        if (isEmpty()) {
+            mPath.moveTo(mLastX = 0, mLastY = 0);
+        }
+        dx1 += mLastX;
+        dy1 += mLastY;
+        dx2 += mLastX;
+        dy2 += mLastY;
+        dx3 += mLastX;
+        dy3 += mLastY;
+        mPath.curveTo(dx1, dy1, dx2, dy2, mLastX = dx3, mLastY = dy3);
+    }
+
+    /**
+     * Append the specified arc to the path as a new contour. If the start of
+     * the path is different from the path's current last point, then an
+     * automatic lineTo() is added to connect the current contour to the
+     * start of the arc. However, if the path is empty, then we call moveTo()
+     * with the first point of the arc. The sweep angle is tread mod 360.
+     *
+     * @param oval        The bounds of oval defining shape and size of the arc
+     * @param startAngle  Starting angle (in degrees) where the arc begins
+     * @param sweepAngle  Sweep angle (in degrees) measured clockwise, treated
+     *                    mod 360.
+     * @param forceMoveTo If true, always begin a new contour with the arc
+     */
+    private void arcTo(RectF oval, float startAngle, float sweepAngle,
+                      boolean forceMoveTo) {
+        Arc2D arc = new Arc2D.Float(oval.left, oval.top, oval.width(), oval.height(), startAngle,
+                sweepAngle, Arc2D.OPEN);
+        mPath.append(arc, true /*connect*/);
+
+        resetLastPointFromPath();
+    }
+
+    /**
+     * Close the current contour. If the current point is not equal to the
+     * first point of the contour, a line segment is automatically added.
+     */
+    private void close() {
+        mPath.closePath();
+    }
+
+    private void resetLastPointFromPath() {
+        Point2D last = mPath.getCurrentPoint();
+        mLastX = (float) last.getX();
+        mLastY = (float) last.getY();
+    }
+
+    /**
+     * Add a closed rectangle contour to the path
+     *
+     * @param left   The left side of a rectangle to add to the path
+     * @param top    The top of a rectangle to add to the path
+     * @param right  The right side of a rectangle to add to the path
+     * @param bottom The bottom of a rectangle to add to the path
+     * @param dir    The direction to wind the rectangle's contour
+     */
+    private void addRect(float left, float top, float right, float bottom,
+                        int dir) {
+        moveTo(left, top);
+
+        Direction direction = getDirection(dir);
+
+        switch (direction) {
+            case CW:
+                lineTo(right, top);
+                lineTo(right, bottom);
+                lineTo(left, bottom);
+                break;
+            case CCW:
+                lineTo(left, bottom);
+                lineTo(right, bottom);
+                lineTo(right, top);
+                break;
+        }
+
+        close();
+
+        resetLastPointFromPath();
+    }
+
+    /**
+     * Offset the path by (dx,dy), returning true on success
+     *
+     * @param dx  The amount in the X direction to offset the entire path
+     * @param dy  The amount in the Y direction to offset the entire path
+     * @param dst The translated path is written here. If this is null, then
+     *            the original path is modified.
+     */
+    public void offset(float dx, float dy, Path_Delegate dst) {
+        GeneralPath newPath = new GeneralPath();
+
+        PathIterator iterator = mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy));
+
+        newPath.append(iterator, false /*connect*/);
+
+        if (dst != null) {
+            dst.mPath = newPath;
+        } else {
+            mPath = newPath;
+        }
+    }
+
+    /**
+     * Transform the points in this path by matrix, and write the answer
+     * into dst. If dst is null, then the the original path is modified.
+     *
+     * @param matrix The matrix to apply to the path
+     * @param dst    The transformed path is written here. If dst is null,
+     *               then the the original path is modified
+     */
+    public void transform(Matrix_Delegate matrix, Path_Delegate dst) {
+        if (matrix.hasPerspective()) {
+            assert false;
+            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_AFFINE,
+                    "android.graphics.Path#transform() only " +
+                    "supports affine transformations.", null, null /*data*/);
+        }
+
+        GeneralPath newPath = new GeneralPath();
+
+        PathIterator iterator = mPath.getPathIterator(matrix.getAffineTransform());
+
+        newPath.append(iterator, false /*connect*/);
+
+        if (dst != null) {
+            dst.mPath = newPath;
+        } else {
+            mPath = newPath;
+        }
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PixelXorXfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PixelXorXfermode_Delegate.java
new file mode 100644
index 0000000..4ab044b
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/PixelXorXfermode_Delegate.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import java.awt.Composite;
+
+/**
+ * Delegate implementing the native methods of android.graphics.PixelXorXfermode
+ *
+ * Through the layoutlib_create tool, the original native methods of PixelXorXfermode have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original PixelXorXfermode class.
+ *
+ * Because this extends {@link Xfermode_Delegate}, there's no need to use a
+ * {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
+ * {@link Xfermode_Delegate}.
+ *
+ * @see Xfermode_Delegate
+ */
+public class PixelXorXfermode_Delegate extends Xfermode_Delegate {
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public Composite getComposite(int alpha) {
+        // FIXME
+        return null;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Pixel XOR Xfermodes are not supported in Layout Preview mode.";
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreate(int opColor) {
+        PixelXorXfermode_Delegate newDelegate = new PixelXorXfermode_Delegate();
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
new file mode 100644
index 0000000..65c65a1
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate implementing the native methods of android.graphics.PorterDuffColorFilter
+ *
+ * Through the layoutlib_create tool, the original native methods of PorterDuffColorFilter have
+ * been replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original PorterDuffColorFilter class.
+ *
+ * Because this extends {@link ColorFilter_Delegate}, there's no need to use a
+ * {@link DelegateManager}, as all the Shader classes will be added to the manager
+ * owned by {@link ColorFilter_Delegate}.
+ *
+ * @see ColorFilter_Delegate
+ *
+ */
+public class PorterDuffColorFilter_Delegate extends ColorFilter_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "PorterDuff Color Filters are not supported.";
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int native_CreatePorterDuffFilter(int srcColor, int porterDuffMode) {
+        PorterDuffColorFilter_Delegate newDelegate = new PorterDuffColorFilter_Delegate();
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode.java
deleted file mode 100644
index 974ae49..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import android.graphics.PorterDuff.Mode;
-
-public class PorterDuffXfermode extends Xfermode {
-    private final Mode mMode;
-
-    /**
-     * Create an xfermode that uses the specified porter-duff mode.
-     *
-     * @param mode           The porter-duff mode that is applied
-     */
-    public PorterDuffXfermode(PorterDuff.Mode mode) {
-        mMode = mode;
-    }
-    
-    //---------- Custom Methods
-    
-    public PorterDuff.Mode getMode() {
-        return mMode;
-    }
-    
-    //----------
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java
new file mode 100644
index 0000000..4301c1a
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import java.awt.AlphaComposite;
+import java.awt.Composite;
+
+/**
+ * Delegate implementing the native methods of android.graphics.PorterDuffXfermode
+ *
+ * Through the layoutlib_create tool, the original native methods of PorterDuffXfermode have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original PorterDuffXfermode class.
+ *
+ * Because this extends {@link Xfermode_Delegate}, there's no need to use a
+ * {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
+ * {@link Xfermode_Delegate}.
+ *
+ */
+public class PorterDuffXfermode_Delegate extends Xfermode_Delegate {
+
+    // ---- delegate data ----
+
+    private final int mMode;
+
+    // ---- Public Helper methods ----
+
+    public PorterDuff.Mode getMode() {
+        return getPorterDuffMode(mMode);
+    }
+
+    @Override
+    public Composite getComposite(int alpha) {
+        return getComposite(getPorterDuffMode(mMode), alpha);
+    }
+
+    @Override
+    public boolean isSupported() {
+        return true;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        // no message since isSupported returns true;
+        return null;
+    }
+
+    public static PorterDuff.Mode getPorterDuffMode(int mode) {
+        for (PorterDuff.Mode m : PorterDuff.Mode.values()) {
+            if (m.nativeInt == mode) {
+                return m;
+            }
+        }
+
+        Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                String.format("Unknown PorterDuff.Mode: %d", mode), null /*data*/);
+        assert false;
+        return PorterDuff.Mode.SRC_OVER;
+    }
+
+    public static Composite getComposite(PorterDuff.Mode mode, int alpha) {
+        float falpha = alpha != 0xFF ? (float)alpha / 255.f : 1.f;
+        switch (mode) {
+            case CLEAR:
+                return AlphaComposite.getInstance(AlphaComposite.CLEAR, falpha);
+            case DARKEN:
+                break;
+            case DST:
+                return AlphaComposite.getInstance(AlphaComposite.DST, falpha);
+            case DST_ATOP:
+                return AlphaComposite.getInstance(AlphaComposite.DST_ATOP, falpha);
+            case DST_IN:
+                return AlphaComposite.getInstance(AlphaComposite.DST_IN, falpha);
+            case DST_OUT:
+                return AlphaComposite.getInstance(AlphaComposite.DST_OUT, falpha);
+            case DST_OVER:
+                return AlphaComposite.getInstance(AlphaComposite.DST_OVER, falpha);
+            case LIGHTEN:
+                break;
+            case MULTIPLY:
+                break;
+            case SCREEN:
+                break;
+            case SRC:
+                return AlphaComposite.getInstance(AlphaComposite.SRC, falpha);
+            case SRC_ATOP:
+                return AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, falpha);
+            case SRC_IN:
+                return AlphaComposite.getInstance(AlphaComposite.SRC_IN, falpha);
+            case SRC_OUT:
+                return AlphaComposite.getInstance(AlphaComposite.SRC_OUT, falpha);
+            case SRC_OVER:
+                return AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha);
+            case XOR:
+                return AlphaComposite.getInstance(AlphaComposite.XOR, falpha);
+        }
+
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
+                String.format("Unsupported PorterDuff Mode: %s", mode.name()),
+                null, null /*data*/);
+
+        return AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha);
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreateXfermode(int mode) {
+        PorterDuffXfermode_Delegate newDelegate = new PorterDuffXfermode_Delegate(mode);
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+
+    private PorterDuffXfermode_Delegate(int mode) {
+        mMode = mode;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/RadialGradient.java b/tools/layoutlib/bridge/src/android/graphics/RadialGradient.java
deleted file mode 100644
index 4409a80..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/RadialGradient.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-public class RadialGradient extends GradientShader {
-
-    private RadialGradientPaint mPaint;
-
-    /**
-     * Create a shader that draws a radial gradient given the center and radius.
-     *
-     * @param x The x-coordinate of the center of the radius
-     * @param y The y-coordinate of the center of the radius
-     * @param radius Must be positive. The radius of the circle for this
-     *            gradient
-     * @param colors The colors to be distributed between the center and edge of
-     *            the circle
-     * @param positions May be NULL. The relative position of each corresponding
-     *            color in the colors array. If this is NULL, the the colors are
-     *            distributed evenly between the center and edge of the circle.
-     * @param tile The Shader tiling mode
-     */
-    public RadialGradient(float x, float y, float radius, int colors[], float positions[],
-            TileMode tile) {
-        super(colors, positions);
-        if (radius <= 0) {
-            throw new IllegalArgumentException("radius must be > 0");
-        }
-
-        mPaint = new RadialGradientPaint(x, y, radius, mColors, mPositions, tile);
-    }
-
-    /**
-     * Create a shader that draws a radial gradient given the center and radius.
-     *
-     * @param x The x-coordinate of the center of the radius
-     * @param y The y-coordinate of the center of the radius
-     * @param radius Must be positive. The radius of the circle for this
-     *            gradient
-     * @param color0 The color at the center of the circle.
-     * @param color1 The color at the edge of the circle.
-     * @param tile The Shader tiling mode
-     */
-    public RadialGradient(float x, float y, float radius, int color0, int color1, TileMode tile) {
-        this(x, y, radius, new int[] { color0, color1 }, null /* positions */, tile);
-    }
-
-    @Override
-    java.awt.Paint getJavaPaint() {
-        return mPaint;
-    }
-
-    private static class RadialGradientPaint extends GradientPaint {
-
-        private final float mX;
-        private final float mY;
-        private final float mRadius;
-
-        public RadialGradientPaint(float x, float y, float radius, int[] colors, float[] positions, TileMode mode) {
-            super(colors, positions, mode);
-            mX = x;
-            mY = y;
-            mRadius = radius;
-        }
-
-        public java.awt.PaintContext createContext(
-                java.awt.image.ColorModel     colorModel,
-                java.awt.Rectangle            deviceBounds,
-                java.awt.geom.Rectangle2D     userBounds,
-                java.awt.geom.AffineTransform xform,
-                java.awt.RenderingHints       hints) {
-            precomputeGradientColors();
-            return new RadialGradientPaintContext(colorModel);
-        }
-
-        private class RadialGradientPaintContext implements java.awt.PaintContext {
-
-            private final java.awt.image.ColorModel mColorModel;
-
-            public RadialGradientPaintContext(java.awt.image.ColorModel colorModel) {
-                mColorModel = colorModel;
-            }
-
-            public void dispose() {
-            }
-
-            public java.awt.image.ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
-                        java.awt.image.BufferedImage.TYPE_INT_ARGB);
-
-                int[] data = new int[w*h];
-
-                // compute distance from each point to the center, and figure out the distance from
-                // it.
-                int index = 0;
-                for (int iy = 0 ; iy < h ; iy++) {
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        float _x = x + ix - mX;
-                        float _y = y + iy - mY;
-                        float distance = (float) Math.sqrt(_x * _x + _y * _y);
-
-                        data[index++] = getGradientColor(distance / mRadius);
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-
-        }
-    }
-
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
new file mode 100644
index 0000000..bdc0ab1
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.graphics.Shader.TileMode;
+
+/**
+ * Delegate implementing the native methods of android.graphics.RadialGradient
+ *
+ * Through the layoutlib_create tool, the original native methods of RadialGradient have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original RadialGradient class.
+ *
+ * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
+ * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
+ *
+ * @see Shader_Delegate
+ *
+ */
+public class RadialGradient_Delegate extends Gradient_Delegate {
+
+    // ---- delegate data ----
+    private java.awt.Paint mJavaPaint;
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public java.awt.Paint getJavaPaint() {
+        return mJavaPaint;
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreate1(float x, float y, float radius,
+            int colors[], float positions[], int tileMode) {
+        RadialGradient_Delegate newDelegate = new RadialGradient_Delegate(x, y, radius,
+                colors, positions, Shader_Delegate.getTileMode(tileMode));
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreate2(float x, float y, float radius,
+            int color0, int color1, int tileMode) {
+        return nativeCreate1(x, y, radius, new int[] { color0, color1 }, null /*positions*/,
+                tileMode);
+    }
+
+    // ---- Private delegate/helper methods ----
+
+    /**
+     * Create a shader that draws a radial gradient given the center and radius.
+     *
+     * @param x The x-coordinate of the center of the radius
+     * @param y The y-coordinate of the center of the radius
+     * @param radius Must be positive. The radius of the circle for this
+     *            gradient
+     * @param colors The colors to be distributed between the center and edge of
+     *            the circle
+     * @param positions May be NULL. The relative position of each corresponding
+     *            color in the colors array. If this is NULL, the the colors are
+     *            distributed evenly between the center and edge of the circle.
+     * @param tile The Shader tiling mode
+     */
+    private RadialGradient_Delegate(float x, float y, float radius, int colors[], float positions[],
+            TileMode tile) {
+        super(colors, positions);
+        mJavaPaint = new RadialGradientPaint(x, y, radius, mColors, mPositions, tile);
+    }
+
+    private class RadialGradientPaint extends GradientPaint {
+
+        private final float mX;
+        private final float mY;
+        private final float mRadius;
+
+        public RadialGradientPaint(float x, float y, float radius,
+                int[] colors, float[] positions, TileMode mode) {
+            super(colors, positions, mode);
+            mX = x;
+            mY = y;
+            mRadius = radius;
+        }
+
+        public java.awt.PaintContext createContext(
+                java.awt.image.ColorModel     colorModel,
+                java.awt.Rectangle            deviceBounds,
+                java.awt.geom.Rectangle2D     userBounds,
+                java.awt.geom.AffineTransform xform,
+                java.awt.RenderingHints       hints) {
+            precomputeGradientColors();
+
+            java.awt.geom.AffineTransform canvasMatrix;
+            try {
+                canvasMatrix = xform.createInverse();
+            } catch (java.awt.geom.NoninvertibleTransformException e) {
+                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
+                        "Unable to inverse matrix in RadialGradient", e, null /*data*/);
+                canvasMatrix = new java.awt.geom.AffineTransform();
+            }
+
+            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
+            try {
+                localMatrix = localMatrix.createInverse();
+            } catch (java.awt.geom.NoninvertibleTransformException e) {
+                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
+                        "Unable to inverse matrix in RadialGradient", e, null /*data*/);
+                localMatrix = new java.awt.geom.AffineTransform();
+            }
+
+            return new RadialGradientPaintContext(canvasMatrix, localMatrix, colorModel);
+        }
+
+        private class RadialGradientPaintContext implements java.awt.PaintContext {
+
+            private final java.awt.geom.AffineTransform mCanvasMatrix;
+            private final java.awt.geom.AffineTransform mLocalMatrix;
+            private final java.awt.image.ColorModel mColorModel;
+
+            public RadialGradientPaintContext(
+                    java.awt.geom.AffineTransform canvasMatrix,
+                    java.awt.geom.AffineTransform localMatrix,
+                    java.awt.image.ColorModel colorModel) {
+                mCanvasMatrix = canvasMatrix;
+                mLocalMatrix = localMatrix;
+                mColorModel = colorModel;
+            }
+
+            public void dispose() {
+            }
+
+            public java.awt.image.ColorModel getColorModel() {
+                return mColorModel;
+            }
+
+            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
+                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
+                        java.awt.image.BufferedImage.TYPE_INT_ARGB);
+
+                int[] data = new int[w*h];
+
+                // compute distance from each point to the center, and figure out the distance from
+                // it.
+                int index = 0;
+                float[] pt1 = new float[2];
+                float[] pt2 = new float[2];
+                for (int iy = 0 ; iy < h ; iy++) {
+                    for (int ix = 0 ; ix < w ; ix++) {
+                        // handle the canvas transform
+                        pt1[0] = x + ix;
+                        pt1[1] = y + iy;
+                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
+
+                        // handle the local matrix
+                        pt1[0] = pt2[0] - mX;
+                        pt1[1] = pt2[1] - mY;
+                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
+
+                        float _x = pt2[0];
+                        float _y = pt2[1];
+                        float distance = (float) Math.sqrt(_x * _x + _y * _y);
+
+                        data[index++] = getGradientColor(distance / mRadius);
+                    }
+                }
+
+                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
+
+                return image.getRaster();
+            }
+
+        }
+    }
+
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Rasterizer_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Rasterizer_Delegate.java
new file mode 100644
index 0000000..2812b6b
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/Rasterizer_Delegate.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate implementing the native methods of android.graphics.Rasterizer
+ *
+ * Through the layoutlib_create tool, the original native methods of Rasterizer have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original Rasterizer class.
+ *
+ * This also serve as a base class for all Rasterizer delegate classes.
+ *
+ * @see DelegateManager
+ *
+ */
+public abstract class Rasterizer_Delegate {
+
+    // ---- delegate manager ----
+    protected static final DelegateManager<Rasterizer_Delegate> sManager =
+            new DelegateManager<Rasterizer_Delegate>(Rasterizer_Delegate.class);
+
+    // ---- delegate helper data ----
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    public static Rasterizer_Delegate getDelegate(int nativeShader) {
+        return sManager.getDelegate(nativeShader);
+    }
+
+    public abstract boolean isSupported();
+    public abstract String getSupportMessage();
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static void finalizer(int native_instance) {
+        sManager.removeJavaReferenceFor(native_instance);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java
new file mode 100644
index 0000000..b0ee5c2
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java
@@ -0,0 +1,474 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.os.Parcel;
+
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Area;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * Delegate implementing the native methods of android.graphics.Region
+ *
+ * Through the layoutlib_create tool, the original native methods of Region have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original Region class.
+ *
+ * This also serve as a base class for all Region delegate classes.
+ *
+ * @see DelegateManager
+ *
+ */
+public class Region_Delegate {
+
+    // ---- delegate manager ----
+    protected static final DelegateManager<Region_Delegate> sManager =
+            new DelegateManager<Region_Delegate>(Region_Delegate.class);
+
+    // ---- delegate helper data ----
+
+    // ---- delegate data ----
+    private Area mArea = new Area();
+
+    // ---- Public Helper methods ----
+
+    public static Region_Delegate getDelegate(int nativeShader) {
+        return sManager.getDelegate(nativeShader);
+    }
+
+    public Area getJavaArea() {
+        return mArea;
+    }
+
+    /**
+     * Combines two {@link Shape} into another one (actually an {@link Area}), according
+     * to the given {@link Region.Op}.
+     *
+     * If the Op is not one that combines two shapes, then this return null
+     *
+     * @param shape1 the firt shape to combine which can be null if there's no original clip.
+     * @param shape2 the 2nd shape to combine
+     * @param regionOp the operande for the combine
+     * @return a new area or null.
+     */
+    public static Area combineShapes(Shape shape1, Shape shape2, int regionOp) {
+        if (regionOp == Region.Op.DIFFERENCE.nativeInt) {
+            // if shape1 is null (empty), then the result is null.
+            if (shape1 == null) {
+                return null;
+            }
+
+            // result is always a new area.
+            Area result = new Area(shape1);
+            result.subtract(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
+            return result;
+
+        } else if (regionOp == Region.Op.INTERSECT.nativeInt) {
+            // if shape1 is null, then the result is simply shape2.
+            if (shape1 == null) {
+                return new Area(shape2);
+            }
+
+            // result is always a new area.
+            Area result = new Area(shape1);
+            result.intersect(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
+            return result;
+
+        } else if (regionOp == Region.Op.UNION.nativeInt) {
+            // if shape1 is null, then the result is simply shape2.
+            if (shape1 == null) {
+                return new Area(shape2);
+            }
+
+            // result is always a new area.
+            Area result = new Area(shape1);
+            result.add(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
+            return result;
+
+        } else if (regionOp == Region.Op.XOR.nativeInt) {
+            // if shape1 is null, then the result is simply shape2
+            if (shape1 == null) {
+                return new Area(shape2);
+            }
+
+            // result is always a new area.
+            Area result = new Area(shape1);
+            result.exclusiveOr(shape2 instanceof Area ? (Area) shape2 : new Area(shape2));
+            return result;
+
+        } else if (regionOp == Region.Op.REVERSE_DIFFERENCE.nativeInt) {
+            // result is always a new area.
+            Area result = new Area(shape2);
+
+            if (shape1 != null) {
+                result.subtract(shape1 instanceof Area ? (Area) shape1 : new Area(shape1));
+            }
+
+            return result;
+        }
+
+        return null;
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static boolean isEmpty(Region thisRegion) {
+        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
+        if (regionDelegate == null) {
+            return true;
+        }
+
+        return regionDelegate.mArea.isEmpty();
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean isRect(Region thisRegion) {
+        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
+        if (regionDelegate == null) {
+            return true;
+        }
+
+        return regionDelegate.mArea.isRectangular();
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean isComplex(Region thisRegion) {
+        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
+        if (regionDelegate == null) {
+            return true;
+        }
+
+        return regionDelegate.mArea.isSingular() == false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean contains(Region thisRegion, int x, int y) {
+        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
+        if (regionDelegate == null) {
+            return false;
+        }
+
+        return regionDelegate.mArea.contains(x, y);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean quickContains(Region thisRegion,
+            int left, int top, int right, int bottom) {
+        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
+        if (regionDelegate == null) {
+            return false;
+        }
+
+        return regionDelegate.mArea.isRectangular() &&
+                regionDelegate.mArea.contains(left, top, right - left, bottom - top);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean quickReject(Region thisRegion,
+            int left, int top, int right, int bottom) {
+        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
+        if (regionDelegate == null) {
+            return false;
+        }
+
+        return regionDelegate.mArea.isEmpty() ||
+                regionDelegate.mArea.intersects(left, top, right - left, bottom - top) == false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean quickReject(Region thisRegion, Region rgn) {
+        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
+        if (regionDelegate == null) {
+            return false;
+        }
+
+        Region_Delegate targetRegionDelegate = sManager.getDelegate(rgn.mNativeRegion);
+        if (targetRegionDelegate == null) {
+            return false;
+        }
+
+        return regionDelegate.mArea.isEmpty() ||
+                regionDelegate.mArea.getBounds().intersects(
+                        targetRegionDelegate.mArea.getBounds()) == false;
+
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void translate(Region thisRegion, int dx, int dy, Region dst) {
+        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
+        if (regionDelegate == null) {
+            return;
+        }
+
+        Region_Delegate targetRegionDelegate = sManager.getDelegate(dst.mNativeRegion);
+        if (targetRegionDelegate == null) {
+            return;
+        }
+
+        if (regionDelegate.mArea.isEmpty()) {
+            targetRegionDelegate.mArea = new Area();
+        } else {
+            targetRegionDelegate.mArea = new Area(regionDelegate.mArea);
+            AffineTransform mtx = new AffineTransform();
+            mtx.translate(dx, dy);
+            targetRegionDelegate.mArea.transform(mtx);
+        }
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void scale(Region thisRegion, float scale, Region dst) {
+        Region_Delegate regionDelegate = sManager.getDelegate(thisRegion.mNativeRegion);
+        if (regionDelegate == null) {
+            return;
+        }
+
+        Region_Delegate targetRegionDelegate = sManager.getDelegate(dst.mNativeRegion);
+        if (targetRegionDelegate == null) {
+            return;
+        }
+
+        if (regionDelegate.mArea.isEmpty()) {
+            targetRegionDelegate.mArea = new Area();
+        } else {
+            targetRegionDelegate.mArea = new Area(regionDelegate.mArea);
+            AffineTransform mtx = new AffineTransform();
+            mtx.scale(scale, scale);
+            targetRegionDelegate.mArea.transform(mtx);
+        }
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeConstructor() {
+        Region_Delegate newDelegate = new Region_Delegate();
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeDestructor(int native_region) {
+        sManager.removeJavaReferenceFor(native_region);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nativeSetRegion(int native_dst, int native_src) {
+        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
+        if (dstRegion == null) {
+            return true;
+        }
+
+        Region_Delegate srcRegion = sManager.getDelegate(native_src);
+        if (srcRegion == null) {
+            return true;
+        }
+
+        dstRegion.mArea.reset();
+        dstRegion.mArea.add(srcRegion.mArea);
+
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nativeSetRect(int native_dst,
+            int left, int top, int right, int bottom) {
+        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
+        if (dstRegion == null) {
+            return true;
+        }
+
+        dstRegion.mArea = new Area(new Rectangle2D.Float(left, top, right - left, bottom - top));
+        return dstRegion.mArea.getBounds().isEmpty() == false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nativeSetPath(int native_dst, int native_path, int native_clip) {
+        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
+        if (dstRegion == null) {
+            return true;
+        }
+
+        Path_Delegate path = Path_Delegate.getDelegate(native_path);
+        if (path == null) {
+            return true;
+        }
+
+        dstRegion.mArea = new Area(path.getJavaShape());
+
+        Region_Delegate clip = sManager.getDelegate(native_clip);
+        if (clip != null) {
+            dstRegion.mArea.subtract(clip.getJavaArea());
+        }
+
+        return dstRegion.mArea.getBounds().isEmpty() == false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nativeGetBounds(int native_region, Rect rect) {
+        Region_Delegate region = sManager.getDelegate(native_region);
+        if (region == null) {
+            return true;
+        }
+
+        Rectangle bounds = region.mArea.getBounds();
+        if (bounds.isEmpty()) {
+            rect.left = rect.top = rect.right = rect.bottom = 0;
+            return false;
+        }
+
+        rect.left = bounds.x;
+        rect.top = bounds.y;
+        rect.right = bounds.x + bounds.width;
+        rect.bottom = bounds.y + bounds.height;
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nativeGetBoundaryPath(int native_region, int native_path) {
+        Region_Delegate region = sManager.getDelegate(native_region);
+        if (region == null) {
+            return false;
+        }
+
+        Path_Delegate path = Path_Delegate.getDelegate(native_path);
+        if (path == null) {
+            return false;
+        }
+
+        if (region.mArea.isEmpty()) {
+            path.reset();
+            return false;
+        }
+
+        path.setPathIterator(region.mArea.getPathIterator(new AffineTransform()));
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nativeOp(int native_dst,
+            int left, int top, int right, int bottom, int op) {
+        Region_Delegate region = sManager.getDelegate(native_dst);
+        if (region == null) {
+            return false;
+        }
+
+        region.mArea = combineShapes(region.mArea,
+                new Rectangle2D.Float(left, top, right - left, bottom - top), op);
+
+        assert region.mArea != null;
+        if (region.mArea != null) {
+            region.mArea = new Area();
+        }
+
+        return region.mArea.getBounds().isEmpty() == false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nativeOp(int native_dst, Rect rect, int native_region, int op) {
+        Region_Delegate region = sManager.getDelegate(native_dst);
+        if (region == null) {
+            return false;
+        }
+
+        region.mArea = combineShapes(region.mArea,
+                new Rectangle2D.Float(rect.left, rect.top, rect.width(), rect.height()), op);
+
+        assert region.mArea != null;
+        if (region.mArea != null) {
+            region.mArea = new Area();
+        }
+
+        return region.mArea.getBounds().isEmpty() == false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nativeOp(int native_dst,
+            int native_region1, int native_region2, int op) {
+        Region_Delegate dstRegion = sManager.getDelegate(native_dst);
+        if (dstRegion == null) {
+            return true;
+        }
+
+        Region_Delegate region1 = sManager.getDelegate(native_region1);
+        if (region1 == null) {
+            return false;
+        }
+
+        Region_Delegate region2 = sManager.getDelegate(native_region2);
+        if (region2 == null) {
+            return false;
+        }
+
+        dstRegion.mArea = combineShapes(region1.mArea, region2.mArea, op);
+
+        assert dstRegion.mArea != null;
+        if (dstRegion.mArea != null) {
+            dstRegion.mArea = new Area();
+        }
+
+        return dstRegion.mArea.getBounds().isEmpty() == false;
+
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreateFromParcel(Parcel p) {
+        // This is only called by Region.CREATOR (Parcelable.Creator<Region>), which is only
+        // used during aidl call so really this should not be called.
+        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+                "AIDL is not suppored, and therefore Regions cannot be created from parcels.",
+                null /*data*/);
+        return 0;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nativeWriteToParcel(int native_region,
+                                                      Parcel p) {
+        // This is only called when sending a region through aidl, so really this should not
+        // be called.
+        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+                "AIDL is not suppored, and therefore Regions cannot be written to parcels.",
+                null /*data*/);
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nativeEquals(int native_r1, int native_r2) {
+        Region_Delegate region1 = sManager.getDelegate(native_r1);
+        if (region1 == null) {
+            return false;
+        }
+
+        Region_Delegate region2 = sManager.getDelegate(native_r2);
+        if (region2 == null) {
+            return false;
+        }
+
+        return region1.mArea.equals(region2.mArea);
+    }
+
+    // ---- Private delegate/helper methods ----
+
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader.java b/tools/layoutlib/bridge/src/android/graphics/Shader.java
deleted file mode 100644
index 0cc5940..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Shader.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-
-
-/**
- * Shader is the based class for objects that return horizontal spans of colors
- * during drawing. A subclass of Shader is installed in a Paint calling
- * paint.setShader(shader). After that any object (other than a bitmap) that is
- * drawn with that paint will get its color(s) from the shader.
- */
-public abstract class Shader {
-
-    private final Matrix mMatrix = new Matrix();
-
-    public enum TileMode {
-        /**
-         * replicate the edge color if the shader draws outside of its
-         * original bounds
-         */
-        CLAMP   (0),
-        /**
-         * repeat the shader's image horizontally and vertically
-         */
-        REPEAT  (1),
-        /**
-         * repeat the shader's image horizontally and vertically, alternating
-         * mirror images so that adjacent images always seam
-         */
-        MIRROR  (2);
-
-        TileMode(int nativeInt) {
-            this.nativeInt = nativeInt;
-        }
-        final int nativeInt;
-    }
-
-    /**
-     * Return true if the shader has a non-identity local matrix.
-     * @param localM If not null, it is set to the shader's local matrix.
-     * @return true if the shader has a non-identity local matrix
-     */
-    public boolean getLocalMatrix(Matrix localM) {
-        if (localM != null) {
-            localM.set(mMatrix);
-        }
-
-        return !mMatrix.isIdentity();
-    }
-
-    /**
-     * Set the shader's local matrix. Passing null will reset the shader's
-     * matrix to identity
-     * @param localM The shader's new local matrix, or null to specify identity
-     */
-    public void setLocalMatrix(Matrix localM) {
-        if (localM != null) {
-            mMatrix.set(localM);
-        } else {
-            mMatrix.reset();
-        }
-    }
-
-    /**
-     * Returns a java.awt.Paint object matching this shader.
-     */
-    abstract java.awt.Paint getJavaPaint();
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
new file mode 100644
index 0000000..c6dd54b
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.graphics.Shader.TileMode;
+
+/**
+ * Delegate implementing the native methods of android.graphics.Shader
+ *
+ * Through the layoutlib_create tool, the original native methods of Shader have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original Shader class.
+ *
+ * This also serve as a base class for all Shader delegate classes.
+ *
+ * @see DelegateManager
+ *
+ */
+public abstract class Shader_Delegate {
+
+    // ---- delegate manager ----
+    protected static final DelegateManager<Shader_Delegate> sManager =
+            new DelegateManager<Shader_Delegate>(Shader_Delegate.class);
+
+    // ---- delegate helper data ----
+
+    // ---- delegate data ----
+    private Matrix_Delegate mLocalMatrix = null;
+
+    // ---- Public Helper methods ----
+
+    public static Shader_Delegate getDelegate(int nativeShader) {
+        return sManager.getDelegate(nativeShader);
+    }
+
+    /**
+     * Returns the {@link TileMode} matching the given int.
+     * @param tileMode the tile mode int value
+     * @return the TileMode enum.
+     */
+    public static TileMode getTileMode(int tileMode) {
+        for (TileMode tm : TileMode.values()) {
+            if (tm.nativeInt == tileMode) {
+                return tm;
+            }
+        }
+
+        assert false;
+        return TileMode.CLAMP;
+    }
+
+    public abstract java.awt.Paint getJavaPaint();
+    public abstract boolean isSupported();
+    public abstract String getSupportMessage();
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeDestructor(int native_shader) {
+        sManager.removeJavaReferenceFor(native_shader);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nativeGetLocalMatrix(int native_shader, int matrix_instance) {
+        // get the delegate from the native int.
+        Shader_Delegate shaderDelegate = sManager.getDelegate(native_shader);
+        if (shaderDelegate == null) {
+            return false;
+        }
+
+        // get the (optional) out matrix.
+        Matrix_Delegate outMatrixDelegate = Matrix_Delegate.getDelegate(matrix_instance);
+
+        if (shaderDelegate.mLocalMatrix == null || shaderDelegate.mLocalMatrix.isIdentity()) {
+            if (outMatrixDelegate != null) {
+                outMatrixDelegate.reset();
+            }
+            return false;
+        }
+
+        if (outMatrixDelegate != null) {
+            outMatrixDelegate.set(shaderDelegate.mLocalMatrix);
+        }
+
+        return true;
+    }
+
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeSetLocalMatrix(int native_shader, int matrix_instance) {
+        // get the delegate from the native int.
+        Shader_Delegate shaderDelegate = sManager.getDelegate(native_shader);
+        if (shaderDelegate == null) {
+            return;
+        }
+
+        shaderDelegate.mLocalMatrix = Matrix_Delegate.getDelegate(matrix_instance);
+    }
+
+    // ---- Private delegate/helper methods ----
+
+    protected java.awt.geom.AffineTransform getLocalMatrix() {
+        if (mLocalMatrix != null) {
+            return mLocalMatrix.getAffineTransform();
+        }
+
+        return new java.awt.geom.AffineTransform();
+    }
+
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java
new file mode 100644
index 0000000..410df0c
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/SumPathEffect_Delegate.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import java.awt.Stroke;
+
+/**
+ * Delegate implementing the native methods of android.graphics.SumPathEffect
+ *
+ * Through the layoutlib_create tool, the original native methods of SumPathEffect have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original SumPathEffect class.
+ *
+ * Because this extends {@link PathEffect_Delegate}, there's no need to use a {@link DelegateManager},
+ * as all the Shader classes will be added to the manager owned by {@link PathEffect_Delegate}.
+ *
+ * @see PathEffect_Delegate
+ *
+ */
+public class SumPathEffect_Delegate extends PathEffect_Delegate {
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public Stroke getStroke(Paint_Delegate paint) {
+        // FIXME
+        return null;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return false;
+    }
+
+    @Override
+    public String getSupportMessage() {
+        return "Sum Path Effects are not supported in Layout Preview mode.";
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreate(int first, int second) {
+        SumPathEffect_Delegate newDelegate = new SumPathEffect_Delegate();
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    // ---- Private delegate/helper methods ----
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/SweepGradient.java b/tools/layoutlib/bridge/src/android/graphics/SweepGradient.java
deleted file mode 100644
index 87036ed..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/SweepGradient.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-public class SweepGradient extends GradientShader {
-
-    private SweepGradientPaint mPaint;
-
-    /**
-     * A subclass of Shader that draws a sweep gradient around a center point.
-     *
-     * @param cx       The x-coordinate of the center
-     * @param cy       The y-coordinate of the center
-     * @param colors   The colors to be distributed between around the center.
-     *                 There must be at least 2 colors in the array.
-     * @param positions May be NULL. The relative position of
-     *                 each corresponding color in the colors array, beginning
-     *                 with 0 and ending with 1.0. If the values are not
-     *                 monotonic, the drawing may produce unexpected results.
-     *                 If positions is NULL, then the colors are automatically
-     *                 spaced evenly.
-     */
-    public SweepGradient(float cx, float cy,
-                         int colors[], float positions[]) {
-        super(colors, positions);
-
-        mPaint = new SweepGradientPaint(cx, cy, mColors, mPositions);
-    }
-
-    /**
-     * A subclass of Shader that draws a sweep gradient around a center point.
-     *
-     * @param cx       The x-coordinate of the center
-     * @param cy       The y-coordinate of the center
-     * @param color0   The color to use at the start of the sweep
-     * @param color1   The color to use at the end of the sweep
-     */
-    public SweepGradient(float cx, float cy, int color0, int color1) {
-        this(cx, cy, new int[] { color0, color1}, null /*positions*/);
-    }
-
-    @Override
-    java.awt.Paint getJavaPaint() {
-        return mPaint;
-    }
-
-    private static class SweepGradientPaint extends GradientPaint {
-
-        private final float mCx;
-        private final float mCy;
-
-        public SweepGradientPaint(float cx, float cy, int[] colors, float[] positions) {
-            super(colors, positions, null /*tileMode*/);
-            mCx = cx;
-            mCy = cy;
-        }
-
-        public java.awt.PaintContext createContext(
-                java.awt.image.ColorModel     colorModel,
-                java.awt.Rectangle            deviceBounds,
-                java.awt.geom.Rectangle2D     userBounds,
-                java.awt.geom.AffineTransform xform,
-                java.awt.RenderingHints       hints) {
-            precomputeGradientColors();
-            return new SweepGradientPaintContext(colorModel);
-        }
-
-        private class SweepGradientPaintContext implements java.awt.PaintContext {
-
-            private final java.awt.image.ColorModel mColorModel;
-
-            public SweepGradientPaintContext(java.awt.image.ColorModel colorModel) {
-                mColorModel = colorModel;
-            }
-
-            public void dispose() {
-            }
-
-            public java.awt.image.ColorModel getColorModel() {
-                return mColorModel;
-            }
-
-            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
-                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
-                        java.awt.image.BufferedImage.TYPE_INT_ARGB);
-
-                int[] data = new int[w*h];
-
-                // compute angle from each point to the center, and figure out the distance from
-                // it.
-                int index = 0;
-                for (int iy = 0 ; iy < h ; iy++) {
-                    for (int ix = 0 ; ix < w ; ix++) {
-                        float dx = x + ix - mCx;
-                        float dy = y + iy - mCy;
-                        float angle;
-                        if (dx == 0) {
-                            angle = (float) (dy < 0 ? 3 * Math.PI / 2 : Math.PI / 2);
-                        } else if (dy == 0) {
-                            angle = (float) (dx < 0 ? Math.PI : 0);
-                        } else {
-                            angle = (float) Math.atan(dy / dx);
-                            if (dx > 0) {
-                                if (dy < 0) {
-                                    angle += Math.PI * 2;
-                                }
-                            } else {
-                                angle += Math.PI;
-                            }
-                        }
-
-                        // convert to 0-1. value and get color
-                        data[index++] = getGradientColor((float) (angle / (2 * Math.PI)));
-                    }
-                }
-
-                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
-
-                return image.getRaster();
-            }
-
-        }
-    }
-
-}
-
diff --git a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
new file mode 100644
index 0000000..f70f9cf
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate implementing the native methods of android.graphics.SweepGradient
+ *
+ * Through the layoutlib_create tool, the original native methods of SweepGradient have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original SweepGradient class.
+ *
+ * Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
+ * as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
+ *
+ * @see Shader_Delegate
+ *
+ */
+public class SweepGradient_Delegate extends Gradient_Delegate {
+
+    // ---- delegate data ----
+    private java.awt.Paint mJavaPaint;
+
+    // ---- Public Helper methods ----
+
+    @Override
+    public java.awt.Paint getJavaPaint() {
+        return mJavaPaint;
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreate1(float x, float y, int colors[], float positions[]) {
+        SweepGradient_Delegate newDelegate = new SweepGradient_Delegate(x, y, colors, positions);
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeCreate2(float x, float y, int color0, int color1) {
+        return nativeCreate1(x, y, new int[] { color0, color1 }, null /*positions*/);
+    }
+
+    // ---- Private delegate/helper methods ----
+
+    /**
+     * A subclass of Shader that draws a sweep gradient around a center point.
+     *
+     * @param cx       The x-coordinate of the center
+     * @param cy       The y-coordinate of the center
+     * @param colors   The colors to be distributed between around the center.
+     *                 There must be at least 2 colors in the array.
+     * @param positions May be NULL. The relative position of
+     *                 each corresponding color in the colors array, beginning
+     *                 with 0 and ending with 1.0. If the values are not
+     *                 monotonic, the drawing may produce unexpected results.
+     *                 If positions is NULL, then the colors are automatically
+     *                 spaced evenly.
+     */
+    private SweepGradient_Delegate(float cx, float cy,
+                         int colors[], float positions[]) {
+        super(colors, positions);
+        mJavaPaint = new SweepGradientPaint(cx, cy, mColors, mPositions);
+    }
+
+    private class SweepGradientPaint extends GradientPaint {
+
+        private final float mCx;
+        private final float mCy;
+
+        public SweepGradientPaint(float cx, float cy, int[] colors,
+                float[] positions) {
+            super(colors, positions, null /*tileMode*/);
+            mCx = cx;
+            mCy = cy;
+        }
+
+        public java.awt.PaintContext createContext(
+                java.awt.image.ColorModel     colorModel,
+                java.awt.Rectangle            deviceBounds,
+                java.awt.geom.Rectangle2D     userBounds,
+                java.awt.geom.AffineTransform xform,
+                java.awt.RenderingHints       hints) {
+            precomputeGradientColors();
+
+            java.awt.geom.AffineTransform canvasMatrix;
+            try {
+                canvasMatrix = xform.createInverse();
+            } catch (java.awt.geom.NoninvertibleTransformException e) {
+                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
+                        "Unable to inverse matrix in SweepGradient", e, null /*data*/);
+                canvasMatrix = new java.awt.geom.AffineTransform();
+            }
+
+            java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
+            try {
+                localMatrix = localMatrix.createInverse();
+            } catch (java.awt.geom.NoninvertibleTransformException e) {
+                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
+                        "Unable to inverse matrix in SweepGradient", e, null /*data*/);
+                localMatrix = new java.awt.geom.AffineTransform();
+            }
+
+            return new SweepGradientPaintContext(canvasMatrix, localMatrix, colorModel);
+        }
+
+        private class SweepGradientPaintContext implements java.awt.PaintContext {
+
+            private final java.awt.geom.AffineTransform mCanvasMatrix;
+            private final java.awt.geom.AffineTransform mLocalMatrix;
+            private final java.awt.image.ColorModel mColorModel;
+
+            public SweepGradientPaintContext(
+                    java.awt.geom.AffineTransform canvasMatrix,
+                    java.awt.geom.AffineTransform localMatrix,
+                    java.awt.image.ColorModel colorModel) {
+                mCanvasMatrix = canvasMatrix;
+                mLocalMatrix = localMatrix;
+                mColorModel = colorModel;
+            }
+
+            public void dispose() {
+            }
+
+            public java.awt.image.ColorModel getColorModel() {
+                return mColorModel;
+            }
+
+            public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
+                java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
+                        java.awt.image.BufferedImage.TYPE_INT_ARGB);
+
+                int[] data = new int[w*h];
+
+                // compute angle from each point to the center, and figure out the distance from
+                // it.
+                int index = 0;
+                float[] pt1 = new float[2];
+                float[] pt2 = new float[2];
+                for (int iy = 0 ; iy < h ; iy++) {
+                    for (int ix = 0 ; ix < w ; ix++) {
+                        // handle the canvas transform
+                        pt1[0] = x + ix;
+                        pt1[1] = y + iy;
+                        mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
+
+                        // handle the local matrix
+                        pt1[0] = pt2[0] - mCx;
+                        pt1[1] = pt2[1] - mCy;
+                        mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
+
+                        float dx = pt2[0];
+                        float dy = pt2[1];
+
+                        float angle;
+                        if (dx == 0) {
+                            angle = (float) (dy < 0 ? 3 * Math.PI / 2 : Math.PI / 2);
+                        } else if (dy == 0) {
+                            angle = (float) (dx < 0 ? Math.PI : 0);
+                        } else {
+                            angle = (float) Math.atan(dy / dx);
+                            if (dx > 0) {
+                                if (dy < 0) {
+                                    angle += Math.PI * 2;
+                                }
+                            } else {
+                                angle += Math.PI;
+                            }
+                        }
+
+                        // convert to 0-1. value and get color
+                        data[index++] = getGradientColor((float) (angle / (2 * Math.PI)));
+                    }
+                }
+
+                image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
+
+                return image.getRaster();
+            }
+
+        }
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface.java b/tools/layoutlib/bridge/src/android/graphics/Typeface.java
deleted file mode 100644
index af3adb5..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import com.android.layoutlib.bridge.FontLoader;
-
-import android.content.res.AssetManager;
-
-import java.awt.Font;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Re-implementation of Typeface over java.awt
- */
-public class Typeface {
-    private static final String DEFAULT_FAMILY = "sans-serif";
-    private static final int[] styleBuffer = new int[1];
-
-    /** The default NORMAL typeface object */
-    public static Typeface DEFAULT;
-    /**
-     * The default BOLD typeface object. Note: this may be not actually be
-     * bold, depending on what fonts are installed. Call getStyle() to know
-     * for sure.
-     */
-    public static Typeface DEFAULT_BOLD;
-    /** The NORMAL style of the default sans serif typeface. */
-    public static Typeface SANS_SERIF;
-    /** The NORMAL style of the default serif typeface. */
-    public static Typeface SERIF;
-    /** The NORMAL style of the default monospace typeface. */
-    public static Typeface MONOSPACE;
-
-    private static Typeface[] sDefaults;
-    private static FontLoader mFontLoader;
-
-    private final int mStyle;
-    private final List<Font> mFonts;
-    private final String mFamily;
-
-    // Style
-    public static final int NORMAL = _Original_Typeface.NORMAL;
-    public static final int BOLD = _Original_Typeface.BOLD;
-    public static final int ITALIC = _Original_Typeface.ITALIC;
-    public static final int BOLD_ITALIC = _Original_Typeface.BOLD_ITALIC;
-
-    /**
-     * Returns the underlying {@link Font} objects. The first item in the list is the real
-     * font. Any other items are fallback fonts for characters not found in the first one.
-     */
-    public List<Font> getFonts() {
-        return mFonts;
-    }
-
-    /** Returns the typeface's intrinsic style attributes */
-    public int getStyle() {
-        return mStyle;
-    }
-
-    /** Returns true if getStyle() has the BOLD bit set. */
-    public final boolean isBold() {
-        return (getStyle() & BOLD) != 0;
-    }
-
-    /** Returns true if getStyle() has the ITALIC bit set. */
-    public final boolean isItalic() {
-        return (getStyle() & ITALIC) != 0;
-    }
-
-    /**
-     * Create a typeface object given a family name, and option style information.
-     * If null is passed for the name, then the "default" font will be chosen.
-     * The resulting typeface object can be queried (getStyle()) to discover what
-     * its "real" style characteristics are.
-     *
-     * @param familyName May be null. The name of the font family.
-     * @param style  The style (normal, bold, italic) of the typeface.
-     *               e.g. NORMAL, BOLD, ITALIC, BOLD_ITALIC
-     * @return The best matching typeface.
-     */
-    public static Typeface create(String familyName, int style) {
-        styleBuffer[0] = style;
-        Font font = mFontLoader.getFont(familyName, styleBuffer);
-        if (font != null) {
-            ArrayList<Font> list = new ArrayList<Font>();
-            list.add(font);
-            list.addAll(mFontLoader.getFallBackFonts());
-            return new Typeface(familyName, styleBuffer[0], list);
-        }
-
-        return null;
-    }
-
-    /**
-     * Create a typeface object that best matches the specified existing
-     * typeface and the specified Style. Use this call if you want to pick a new
-     * style from the same family of an existing typeface object. If family is
-     * null, this selects from the default font's family.
-     *
-     * @param family May be null. The name of the existing type face.
-     * @param style  The style (normal, bold, italic) of the typeface.
-     *               e.g. NORMAL, BOLD, ITALIC, BOLD_ITALIC
-     * @return The best matching typeface.
-     */
-    public static Typeface create(Typeface family, int style) {
-        styleBuffer[0] = style;
-        Font font = mFontLoader.getFont(family.mFamily, styleBuffer);
-        if (font != null) {
-            ArrayList<Font> list = new ArrayList<Font>();
-            list.add(font);
-            list.addAll(mFontLoader.getFallBackFonts());
-            return new Typeface(family.mFamily, styleBuffer[0], list);
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns one of the default typeface objects, based on the specified style
-     *
-     * @return the default typeface that corresponds to the style
-     */
-    public static Typeface defaultFromStyle(int style) {
-        return sDefaults[style];
-    }
-
-    /**
-     * Create a new typeface from the specified font data.
-     * @param mgr The application's asset manager
-     * @param path  The file name of the font data in the assets directory
-     * @return The new typeface.
-     */
-    public static Typeface createFromAsset(AssetManager mgr, String path) {
-        return null;
-        //return new Typeface(nativeCreateFromAsset(mgr, path));
-    }
-
-    // don't allow clients to call this directly
-    private Typeface(String family, int style, List<Font> fonts) {
-        mFamily = family;
-        mFonts = Collections.unmodifiableList(fonts);
-        mStyle = style;
-    }
-
-    public static void init(FontLoader fontLoader) {
-        mFontLoader = fontLoader;
-
-        DEFAULT = create(DEFAULT_FAMILY, NORMAL);
-        DEFAULT_BOLD = create(DEFAULT_FAMILY, BOLD);
-        SANS_SERIF = create("sans-serif", NORMAL);
-        SERIF = create("serif", NORMAL);
-        MONOSPACE = create("monospace", NORMAL);
-        sDefaults = new Typeface[] {
-                DEFAULT,
-                DEFAULT_BOLD,
-                create(DEFAULT_FAMILY, ITALIC),
-                create(DEFAULT_FAMILY, BOLD_ITALIC),
-        };
-
-        /*
-        DEFAULT         = create((String)null, 0);
-        DEFAULT_BOLD    = create((String)null, Typeface.BOLD);
-        SANS_SERIF      = create("sans-serif", 0);
-        SERIF           = create("serif", 0);
-        MONOSPACE       = create("monospace", 0);
-
-        sDefaults = new Typeface[] {
-            DEFAULT,
-            DEFAULT_BOLD,
-            create((String)null, Typeface.ITALIC),
-            create((String)null, Typeface.BOLD_ITALIC),
-        };*/
-    }
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
new file mode 100644
index 0000000..0f084f7
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.layoutlib.bridge.impl.FontLoader;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.content.res.AssetManager;
+
+import java.awt.Font;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Delegate implementing the native methods of android.graphics.Typeface
+ *
+ * Through the layoutlib_create tool, the original native methods of Typeface have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original Typeface class.
+ *
+ * @see DelegateManager
+ *
+ */
+public final class Typeface_Delegate {
+
+    // ---- delegate manager ----
+    private static final DelegateManager<Typeface_Delegate> sManager =
+            new DelegateManager<Typeface_Delegate>(Typeface_Delegate.class);
+
+    // ---- delegate helper data ----
+    private static final String DEFAULT_FAMILY = "sans-serif";
+    private static final int[] STYLE_BUFFER = new int[1];
+
+    private static FontLoader sFontLoader;
+    private static final List<Typeface_Delegate> sPostInitDelegate =
+            new ArrayList<Typeface_Delegate>();
+
+    // ---- delegate data ----
+
+    private final String mFamily;
+    private int mStyle;
+    private List<Font> mFonts;
+
+
+    // ---- Public Helper methods ----
+
+    public static synchronized void init(FontLoader fontLoader) {
+        sFontLoader = fontLoader;
+
+        for (Typeface_Delegate delegate : sPostInitDelegate) {
+            delegate.init();
+        }
+        sPostInitDelegate.clear();
+    }
+
+    public static Typeface_Delegate getDelegate(int nativeTypeface) {
+        return sManager.getDelegate(nativeTypeface);
+    }
+
+    public static List<Font> getFonts(Typeface typeface) {
+        return getFonts(typeface.native_instance);
+    }
+
+    public static List<Font> getFonts(int native_int) {
+        Typeface_Delegate delegate = sManager.getDelegate(native_int);
+        if (delegate == null) {
+            return null;
+        }
+
+        return delegate.getFonts();
+    }
+
+    public List<Font> getFonts() {
+        return mFonts;
+    }
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static synchronized int nativeCreate(String familyName, int style) {
+        if (familyName == null) {
+            familyName = DEFAULT_FAMILY;
+        }
+
+        Typeface_Delegate newDelegate = new Typeface_Delegate(familyName, style);
+        if (sFontLoader != null) {
+            newDelegate.init();
+        } else {
+            // font loader has not been initialized yet, add the delegate to a list of delegates
+            // to init when the font loader is initialized.
+            // There won't be any rendering before this happens anyway.
+            sPostInitDelegate.add(newDelegate);
+        }
+
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static synchronized int nativeCreateFromTypeface(int native_instance, int style) {
+        Typeface_Delegate delegate = sManager.getDelegate(native_instance);
+        if (delegate == null) {
+            return 0;
+        }
+
+        Typeface_Delegate newDelegate = new Typeface_Delegate(delegate.mFamily, style);
+        if (sFontLoader != null) {
+            newDelegate.init();
+        } else {
+            // font loader has not been initialized yet, add the delegate to a list of delegates
+            // to init when the font loader is initialized.
+            // There won't be any rendering before this happens anyway.
+            sPostInitDelegate.add(newDelegate);
+        }
+
+        return sManager.addNewDelegate(newDelegate);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static synchronized int nativeCreateFromAsset(AssetManager mgr, String path) {
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Typeface.createFromAsset() is not supported.", null /*throwable*/, null /*data*/);
+        return 0;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static synchronized int nativeCreateFromFile(String path) {
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Typeface.createFromFile() is not supported.", null /*throwable*/, null /*data*/);
+        return 0;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nativeUnref(int native_instance) {
+        sManager.removeJavaReferenceFor(native_instance);
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int nativeGetStyle(int native_instance) {
+        Typeface_Delegate delegate = sManager.getDelegate(native_instance);
+        if (delegate == null) {
+            return 0;
+        }
+
+        return delegate.mStyle;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void setGammaForText(float blackGamma, float whiteGamma) {
+        // This is for device testing only: pass
+    }
+
+    // ---- Private delegate/helper methods ----
+
+    private Typeface_Delegate(String family, int style) {
+        mFamily = family;
+        mStyle = style;
+    }
+
+    private void init() {
+        STYLE_BUFFER[0] = mStyle;
+        Font font = sFontLoader.getFont(mFamily, STYLE_BUFFER);
+        if (font != null) {
+            List<Font> list = new ArrayList<Font>();
+            list.add(font);
+            list.addAll(sFontLoader.getFallBackFonts());
+            mFonts = Collections.unmodifiableList(list);
+            mStyle = STYLE_BUFFER[0];
+        }
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java
new file mode 100644
index 0000000..962d69c
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import java.awt.Composite;
+
+/**
+ * Delegate implementing the native methods of android.graphics.Xfermode
+ *
+ * Through the layoutlib_create tool, the original native methods of Xfermode have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original Xfermode class.
+ *
+ * This also serve as a base class for all Xfermode delegate classes.
+ *
+ * @see DelegateManager
+ *
+ */
+public abstract class Xfermode_Delegate {
+
+    // ---- delegate manager ----
+    protected static final DelegateManager<Xfermode_Delegate> sManager =
+            new DelegateManager<Xfermode_Delegate>(Xfermode_Delegate.class);
+
+    // ---- delegate helper data ----
+
+    // ---- delegate data ----
+
+    // ---- Public Helper methods ----
+
+    public static Xfermode_Delegate getDelegate(int native_instance) {
+        return sManager.getDelegate(native_instance);
+    }
+
+    public abstract Composite getComposite(int alpha);
+    public abstract boolean isSupported();
+    public abstract String getSupportMessage();
+
+
+    // ---- native methods ----
+
+    @LayoutlibDelegate
+    /*package*/ static void finalizer(int native_instance) {
+        sManager.removeJavaReferenceFor(native_instance);
+    }
+
+    // ---- Private delegate/helper methods ----
+
+}
diff --git a/tools/layoutlib/bridge/src/android/os/Build_Delegate.java b/tools/layoutlib/bridge/src/android/os/Build_Delegate.java
new file mode 100644
index 0000000..ff82a5e
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/os/Build_Delegate.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import java.util.Map;
+
+/**
+ * Delegate implementing the native methods of android.os.Build
+ *
+ * Through the layoutlib_create tool, the original native methods of Build have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
+ * around to map int to instance of the delegate.
+ *
+ */
+public class Build_Delegate {
+
+    @LayoutlibDelegate
+    /*package*/ static String getString(String property) {
+        Map<String, String> properties = Bridge.getPlatformProperties();
+        String value = properties.get(property);
+        if (value != null) {
+            return value;
+        }
+
+        return Build.UNKNOWN;
+    }
+
+}
diff --git a/tools/layoutlib/bridge/src/android/os/Handler_Delegate.java b/tools/layoutlib/bridge/src/android/os/Handler_Delegate.java
new file mode 100644
index 0000000..2152c8a
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/os/Handler_Delegate.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+
+/**
+ * Delegate overriding selected methods of android.os.Handler
+ *
+ * Through the layoutlib_create tool, selected methods of Handler have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ *
+ */
+public class Handler_Delegate {
+
+    // -------- Delegate methods
+
+    @LayoutlibDelegate
+    /*package*/ static boolean sendMessageAtTime(Handler handler, Message msg, long uptimeMillis) {
+        // get the callback
+        IHandlerCallback callback = sCallbacks.get();
+        if (callback != null) {
+            callback.sendMessageAtTime(handler, msg, uptimeMillis);
+        }
+        return true;
+    }
+
+    // -------- Delegate implementation
+
+    public interface IHandlerCallback {
+        void sendMessageAtTime(Handler handler, Message msg, long uptimeMillis);
+    }
+
+    private final static ThreadLocal<IHandlerCallback> sCallbacks =
+        new ThreadLocal<IHandlerCallback>();
+
+    public static void setCallback(IHandlerCallback callback) {
+        sCallbacks.set(callback);
+    }
+
+}
diff --git a/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java b/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
new file mode 100644
index 0000000..63711a7
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate implementing the native methods of android.os.SystemClock
+ *
+ * Through the layoutlib_create tool, the original native methods of SystemClock have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
+ * around to map int to instance of the delegate.
+ *
+ */
+public class SystemClock_Delegate {
+    private static long sBootTime = System.currentTimeMillis();
+
+    @LayoutlibDelegate
+    /*package*/ static boolean setCurrentTimeMillis(long millis) {
+        return true;
+    }
+
+    /**
+     * Returns milliseconds since boot, not counting time spent in deep sleep.
+     * <b>Note:</b> This value may get reset occasionally (before it would
+     * otherwise wrap around).
+     *
+     * @return milliseconds of non-sleep uptime since boot.
+     */
+    @LayoutlibDelegate
+    /*package*/ static long uptimeMillis() {
+        return System.currentTimeMillis() - sBootTime;
+    }
+
+    /**
+     * Returns milliseconds since boot, including time spent in sleep.
+     *
+     * @return elapsed milliseconds since boot.
+     */
+    @LayoutlibDelegate
+    /*package*/ static long elapsedRealtime() {
+        return System.currentTimeMillis() - sBootTime;
+    }
+
+    /**
+     * Returns milliseconds running in the current thread.
+     *
+     * @return elapsed milliseconds in the thread
+     */
+    @LayoutlibDelegate
+    /*package*/ static long currentThreadTimeMillis() {
+        return System.currentTimeMillis();
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/util/FloatMath.java b/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java
similarity index 67%
rename from tools/layoutlib/bridge/src/android/util/FloatMath.java
rename to tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java
index aae44f2..1df78c2 100644
--- a/tools/layoutlib/bridge/src/android/util/FloatMath.java
+++ b/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java
@@ -16,20 +16,23 @@
 
 package android.util;
 
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
 /**
- * Reimplements _Original_FloatMath with the standard libraries.
- * 
- * Math routines similar to those found in {@link java.lang.Math}. Performs
- * computations on {@code float} values directly without incurring the overhead
- * of conversions to and from {@code double}.
+ * Delegate implementing the native methods of android.util.FloatMath
  *
- * <p>On one platform, {@code FloatMath.sqrt(100)} executes in one third of the
- * time required by {@code java.lang.Math.sqrt(100)}.</p>
+ * Through the layoutlib_create tool, the original native methods of FloatMath have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
+ * around to map int to instance of the delegate.
+ *
  */
-public class FloatMath {
+/*package*/ final class FloatMath_Delegate {
 
     /** Prevents instantiation. */
-    private FloatMath() {}
+    private FloatMath_Delegate() {}
 
     /**
      * Returns the float conversion of the most positive (i.e. closest to
@@ -38,7 +41,8 @@
      * @param value to be converted
      * @return the floor of value
      */
-    public static float floor(float value) {
+    @LayoutlibDelegate
+    /*package*/ static float floor(float value) {
         return (float)Math.floor(value);
     }
 
@@ -49,7 +53,8 @@
      * @param value to be converted
      * @return the ceiling of value
      */
-    public static float ceil(float value) {
+    @LayoutlibDelegate
+    /*package*/ static float ceil(float value) {
         return (float)Math.ceil(value);
     }
 
@@ -59,7 +64,8 @@
      * @param angle to compute the cosine of, in radians
      * @return the sine of angle
      */
-    public static  float sin(float angle) {
+    @LayoutlibDelegate
+    /*package*/ static  float sin(float angle) {
         return (float)Math.sin(angle);
     }
 
@@ -69,7 +75,8 @@
      * @param angle to compute the cosine of, in radians
      * @return the cosine of angle
      */
-    public static float cos(float angle) {
+    @LayoutlibDelegate
+    /*package*/ static float cos(float angle) {
         return (float)Math.cos(angle);
     }
 
@@ -80,7 +87,8 @@
      * @param value to compute sqrt of
      * @return the square root of value
      */
-    public static float sqrt(float value) {
+    @LayoutlibDelegate
+    /*package*/ static float sqrt(float value) {
         return (float)Math.sqrt(value);
     }
 }
diff --git a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
new file mode 100644
index 0000000..d5266a5
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import com.android.layoutlib.bridge.android.BridgeInflater;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.util.AttributeSet;
+import android.util.Xml;
+
+import java.io.IOException;
+
+/**
+ * Delegate used to provide new implementation of a select few methods of {@link LayoutInflater}
+ *
+ * Through the layoutlib_create tool, the original  methods of LayoutInflater have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * Generally we don't want to copy-paste a huge method like that just for one small features,
+ * but because this is done after this platform is final and the next version (Honeycomb) has a
+ * better mechanism (or slightly less copy-paste), maintenance of this duplicated code is not
+ * a problem.
+ *
+ */
+public class LayoutInflater_Delegate {
+
+    @LayoutlibDelegate
+    /*package*/ static void parseInclude(LayoutInflater thisInflater,
+            XmlPullParser parser, View parent, AttributeSet attrs)
+            throws XmlPullParserException, IOException {
+
+        int type;
+
+        if (parent instanceof ViewGroup) {
+            final int layout = attrs.getAttributeResourceValue(null, "layout", 0);
+            if (layout == 0) {
+                final String value = attrs.getAttributeValue(null, "layout");
+                if (value == null) {
+                    throw new InflateException("You must specifiy a layout in the"
+                            + " include tag: <include layout=\"@layout/layoutID\" />");
+                } else {
+                    throw new InflateException("You must specifiy a valid layout "
+                            + "reference. The layout ID " + value + " is not valid.");
+                }
+            } else {
+                final XmlResourceParser childParser =
+                    thisInflater.getContext().getResources().getLayout(layout);
+
+                try {
+                    final AttributeSet childAttrs = Xml.asAttributeSet(childParser);
+
+                    while ((type = childParser.next()) != XmlPullParser.START_TAG &&
+                            type != XmlPullParser.END_DOCUMENT) {
+                        // Empty.
+                    }
+
+                    if (type != XmlPullParser.START_TAG) {
+                        throw new InflateException(childParser.getPositionDescription() +
+                                ": No start tag found!");
+                    }
+
+                    final String childName = childParser.getName();
+
+                    if (LayoutInflater.TAG_MERGE.equals(childName)) {
+                        // ---- START MODIFICATIONS ----
+                        if (thisInflater instanceof BridgeInflater) {
+                            ((BridgeInflater) thisInflater).setIsInMerge(true);
+                        }
+                        // ---- END MODIFICATIONS ----
+
+                        // Inflate all children.
+                        thisInflater.rInflate(childParser, parent, childAttrs);
+
+                        // ---- START MODIFICATIONS ----
+                        if (thisInflater instanceof BridgeInflater) {
+                            ((BridgeInflater) thisInflater).setIsInMerge(false);
+                        }
+                        // ---- END MODIFICATIONS ----
+                    } else {
+                        final View view = thisInflater.createViewFromTag(childName, childAttrs);
+                        final ViewGroup group = (ViewGroup) parent;
+
+                        // We try to load the layout params set in the <include /> tag. If
+                        // they don't exist, we will rely on the layout params set in the
+                        // included XML file.
+                        // During a layoutparams generation, a runtime exception is thrown
+                        // if either layout_width or layout_height is missing. We catch
+                        // this exception and set localParams accordingly: true means we
+                        // successfully loaded layout params from the <include /> tag,
+                        // false means we need to rely on the included layout params.
+                        ViewGroup.LayoutParams params = null;
+                        try {
+                            params = group.generateLayoutParams(attrs);
+                        } catch (RuntimeException e) {
+                            params = group.generateLayoutParams(childAttrs);
+                        } finally {
+                            if (params != null) {
+                                view.setLayoutParams(params);
+                            }
+                        }
+
+                        // Inflate all children.
+                        thisInflater.rInflate(childParser, view, childAttrs);
+
+                        // Attempt to override the included layout's android:id with the
+                        // one set on the <include /> tag itself.
+                        TypedArray a = thisInflater.mContext.obtainStyledAttributes(attrs,
+                            com.android.internal.R.styleable.View, 0, 0);
+                        int id = a.getResourceId(com.android.internal.R.styleable.View_id, View.NO_ID);
+                        // While we're at it, let's try to override android:visibility.
+                        int visibility = a.getInt(com.android.internal.R.styleable.View_visibility, -1);
+                        a.recycle();
+
+                        if (id != View.NO_ID) {
+                            view.setId(id);
+                        }
+
+                        switch (visibility) {
+                            case 0:
+                                view.setVisibility(View.VISIBLE);
+                                break;
+                            case 1:
+                                view.setVisibility(View.INVISIBLE);
+                                break;
+                            case 2:
+                                view.setVisibility(View.GONE);
+                                break;
+                        }
+
+                        group.addView(view);
+                    }
+                } finally {
+                    childParser.close();
+                }
+            }
+        } else {
+            throw new InflateException("<include /> can only be used inside of a ViewGroup");
+        }
+
+        final int currentDepth = parser.getDepth();
+        while (((type = parser.next()) != XmlPullParser.END_TAG ||
+                parser.getDepth() > currentDepth) && type != XmlPullParser.END_DOCUMENT) {
+            // Empty
+        }
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/view/View_Delegate.java b/tools/layoutlib/bridge/src/android/view/View_Delegate.java
new file mode 100644
index 0000000..8215f7c
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/view/View_Delegate.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate used to provide new implementation of a select few methods of {@link View}
+ *
+ * Through the layoutlib_create tool, the original  methods of View have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ */
+public class View_Delegate {
+
+    @LayoutlibDelegate
+    /*package*/ static boolean isInEditMode(View thisView) {
+        return true;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/internal/util/XmlUtils_Delegate.java b/tools/layoutlib/bridge/src/com/android/internal/util/XmlUtils_Delegate.java
new file mode 100644
index 0000000..bf998b8
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/internal/util/XmlUtils_Delegate.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+
+/**
+ * Delegate used to provide new implementation of a select few methods of {@link XmlUtils}
+ *
+ * Through the layoutlib_create tool, the original  methods of XmlUtils have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ */
+public class XmlUtils_Delegate {
+
+    @LayoutlibDelegate
+    /*package*/ static final int convertValueToInt(CharSequence charSeq, int defaultValue) {
+        if (null == charSeq)
+            return defaultValue;
+
+        String nm = charSeq.toString();
+
+        // This code is copied from the original implementation. The issue is that
+        // The Dalvik libraries are able to handle Integer.parse("XXXXXXXX", 16) where XXXXXXX
+        // is > 80000000 but the Java VM cannot.
+
+        int sign = 1;
+        int index = 0;
+        int len = nm.length();
+        int base = 10;
+
+        if ('-' == nm.charAt(0)) {
+            sign = -1;
+            index++;
+        }
+
+        if ('0' == nm.charAt(index)) {
+            //  Quick check for a zero by itself
+            if (index == (len - 1))
+                return 0;
+
+            char c = nm.charAt(index + 1);
+
+            if ('x' == c || 'X' == c) {
+                index += 2;
+                base = 16;
+            } else {
+                index++;
+                base = 8;
+            }
+        }
+        else if ('#' == nm.charAt(index)) {
+            index++;
+            base = 16;
+        }
+
+        return ((int)Long.parseLong(nm.substring(index), base)) * sign;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index f91f601..2792100 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -16,68 +16,47 @@
 
 package com.android.layoutlib.bridge;
 
-import com.android.internal.util.XmlUtils;
-import com.android.layoutlib.api.ILayoutBridge;
-import com.android.layoutlib.api.ILayoutLog;
-import com.android.layoutlib.api.ILayoutResult;
-import com.android.layoutlib.api.IProjectCallback;
-import com.android.layoutlib.api.IResourceValue;
-import com.android.layoutlib.api.IStyleResourceValue;
-import com.android.layoutlib.api.IXmlPullParser;
-import com.android.layoutlib.api.ILayoutResult.ILayoutViewInfo;
-import com.android.layoutlib.bridge.LayoutResult.LayoutViewInfo;
-import com.android.ninepatch.NinePatch;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
+import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
+
+import com.android.ide.common.rendering.api.Capability;
+import com.android.ide.common.rendering.api.DrawableParams;
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.RenderSession;
+import com.android.ide.common.rendering.api.Result;
+import com.android.ide.common.rendering.api.SessionParams;
+import com.android.layoutlib.bridge.android.BridgeAssetManager;
+import com.android.layoutlib.bridge.impl.FontLoader;
+import com.android.layoutlib.bridge.impl.RenderDrawable;
+import com.android.layoutlib.bridge.impl.RenderSessionImpl;
+import com.android.ninepatch.NinePatchChunk;
+import com.android.resources.ResourceType;
 import com.android.tools.layoutlib.create.MethodAdapter;
 import com.android.tools.layoutlib.create.OverrideMethod;
+import com.android.util.Pair;
 
-import android.content.res.Configuration;
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.Region;
 import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
+import android.graphics.Typeface_Delegate;
 import android.os.Looper;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.BridgeInflater;
-import android.view.InputChannel;
-import android.view.IWindow;
-import android.view.IWindowSession;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.Surface;
-import android.view.SurfaceView;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.View.AttachInfo;
-import android.view.View.MeasureSpec;
-import android.view.WindowManager.LayoutParams;
-import android.widget.FrameLayout;
-import android.widget.TabHost;
-import android.widget.TabWidget;
 
+import java.io.File;
 import java.lang.ref.SoftReference;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
-import java.util.Collection;
+import java.util.Arrays;
+import java.util.EnumMap;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.locks.ReentrantLock;
 
 /**
  * Main entry point of the LayoutLib Bridge.
  * <p/>To use this bridge, simply instantiate an object of type {@link Bridge} and call
- * {@link #computeLayout(IXmlPullParser, Object, int, int, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}.
+ * {@link #createScene(SceneParams)}
  */
-public final class Bridge implements ILayoutBridge {
-
-    private static final int DEFAULT_TITLE_BAR_HEIGHT = 25;
-    private static final int DEFAULT_STATUS_BAR_HEIGHT = 25;
+public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
 
     public static class StaticMethodNotImplementedException extends RuntimeException {
         private static final long serialVersionUID = 1L;
@@ -88,84 +67,137 @@
     }
 
     /**
-     * Maps from id to resource name/type. This is for android.R only.
+     * Lock to ensure only one rendering/inflating happens at a time.
+     * This is due to some singleton in the Android framework.
      */
-    private final static Map<Integer, String[]> sRMap = new HashMap<Integer, String[]>();
+    private final static ReentrantLock sLock = new ReentrantLock();
+
+    /**
+     * Maps from id to resource type/name. This is for android.R only.
+     */
+    private final static Map<Integer, Pair<ResourceType, String>> sRMap =
+        new HashMap<Integer, Pair<ResourceType, String>>();
+
     /**
      * Same as sRMap except for int[] instead of int resources. This is for android.R only.
      */
-    private final static Map<int[], String> sRArrayMap = new HashMap<int[], String>();
+    private final static Map<IntArray, String> sRArrayMap = new HashMap<IntArray, String>();
     /**
      * Reverse map compared to sRMap, resource type -> (resource name -> id).
      * This is for android.R only.
      */
-    private final static Map<String, Map<String, Integer>> sRFullMap =
-        new HashMap<String, Map<String,Integer>>();
+    private final static Map<ResourceType, Map<String, Integer>> sRFullMap =
+        new EnumMap<ResourceType, Map<String,Integer>>(ResourceType.class);
 
     private final static Map<Object, Map<String, SoftReference<Bitmap>>> sProjectBitmapCache =
         new HashMap<Object, Map<String, SoftReference<Bitmap>>>();
-    private final static Map<Object, Map<String, SoftReference<NinePatch>>> sProject9PatchCache =
-        new HashMap<Object, Map<String, SoftReference<NinePatch>>>();
+    private final static Map<Object, Map<String, SoftReference<NinePatchChunk>>> sProject9PatchCache =
+        new HashMap<Object, Map<String, SoftReference<NinePatchChunk>>>();
 
     private final static Map<String, SoftReference<Bitmap>> sFrameworkBitmapCache =
         new HashMap<String, SoftReference<Bitmap>>();
-    private final static Map<String, SoftReference<NinePatch>> sFramework9PatchCache =
-        new HashMap<String, SoftReference<NinePatch>>();
+    private final static Map<String, SoftReference<NinePatchChunk>> sFramework9PatchCache =
+        new HashMap<String, SoftReference<NinePatchChunk>>();
 
     private static Map<String, Map<String, Integer>> sEnumValueMap;
+    private static Map<String, String> sPlatformProperties;
 
     /**
-     * A default logger than prints to stdout/stderr.
+     * int[] wrapper to use as keys in maps.
      */
-    private final static ILayoutLog sDefaultLogger = new ILayoutLog() {
-        public void error(String message) {
+    private final static class IntArray {
+        private int[] mArray;
+
+        private IntArray() {
+            // do nothing
+        }
+
+        private IntArray(int[] a) {
+            mArray = a;
+        }
+
+        private void set(int[] a) {
+            mArray = a;
+        }
+
+        @Override
+        public int hashCode() {
+            return Arrays.hashCode(mArray);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) return true;
+            if (obj == null) return false;
+            if (getClass() != obj.getClass()) return false;
+
+            IntArray other = (IntArray) obj;
+            if (!Arrays.equals(mArray, other.mArray)) return false;
+            return true;
+        }
+    }
+
+    /** Instance of IntArrayWrapper to be reused in {@link #resolveResourceId(int[])}. */
+    private final static IntArray sIntArrayWrapper = new IntArray();
+
+    /**
+     * A default log than prints to stdout/stderr.
+     */
+    private final static LayoutLog sDefaultLog = new LayoutLog() {
+        @Override
+        public void error(String tag, String message, Object data) {
             System.err.println(message);
         }
 
-        public void error(Throwable t) {
-            String message = t.getMessage();
-            if (message == null) {
-                message = t.getClass().getName();
-            }
-
+        @Override
+        public void error(String tag, String message, Throwable throwable, Object data) {
             System.err.println(message);
         }
 
-        public void warning(String message) {
+        @Override
+        public void warning(String tag, String message, Object data) {
             System.out.println(message);
         }
     };
 
     /**
-     * Logger defined during a compute layout operation.
-     * <p/>
-     * This logger is generally set to {@link #sDefaultLogger} except during rendering
-     * operations when it might be set to a specific provided logger.
-     * <p/>
-     * To change this value, use a block synchronized on {@link #sDefaultLogger}.
+     * Current log.
      */
-    private static ILayoutLog sLogger = sDefaultLogger;
+    private static LayoutLog sCurrentLog = sDefaultLog;
 
-    /*
-     * (non-Javadoc)
-     * @see com.android.layoutlib.api.ILayoutBridge#getApiLevel()
-     */
+    private EnumSet<Capability> mCapabilities;
+
+    @Override
     public int getApiLevel() {
-        return API_CURRENT;
+        return com.android.ide.common.rendering.api.Bridge.API_CURRENT;
     }
 
-    /*
-     * (non-Javadoc)
-     * @see com.android.layoutlib.api.ILayoutLibBridge#init(java.lang.String, java.util.Map)
-     */
-    public boolean init(
-            String fontOsLocation, Map<String, Map<String, Integer>> enumValueMap) {
-
-        return sinit(fontOsLocation, enumValueMap);
+    @Override
+    public EnumSet<Capability> getCapabilities() {
+        return mCapabilities;
     }
 
-    private static synchronized boolean sinit(String fontOsLocation,
-            Map<String, Map<String, Integer>> enumValueMap) {
+    @Override
+    public boolean init(Map<String,String> platformProperties,
+            File fontLocation,
+            Map<String, Map<String, Integer>> enumValueMap,
+            LayoutLog log) {
+        sPlatformProperties = platformProperties;
+        sEnumValueMap = enumValueMap;
+
+        // don't use EnumSet.allOf(), because the bridge doesn't come with its specific version
+        // of layoutlib_api. It is provided by the client which could have a more recent version
+        // with newer, unsupported capabilities.
+        mCapabilities = EnumSet.of(
+                Capability.UNBOUND_RENDERING,
+                Capability.CUSTOM_BACKGROUND_COLOR,
+                Capability.RENDER,
+                Capability.LAYOUT_ONLY,
+                Capability.EMBEDDED_LAYOUT,
+                Capability.VIEW_MANIPULATION);
+
+
+        BridgeAssetManager.initSystem();
 
         // When DEBUG_LAYOUT is set and is not 0 or false, setup a default listener
         // on static (native) methods which prints the signature on the console and
@@ -182,12 +214,8 @@
             OverrideMethod.setDefaultListener(new MethodAdapter() {
                 @Override
                 public void onInvokeV(String signature, boolean isNative, Object caller) {
-                    if (sLogger != null) {
-                        synchronized (sDefaultLogger) {
-                            sLogger.error("Missing Stub: " + signature +
-                                    (isNative ? " (native)" : ""));
-                        }
-                    }
+                    sDefaultLog.error(null, "Missing Stub: " + signature +
+                            (isNative ? " (native)" : ""), null /*data*/);
 
                     if (debug.equalsIgnoreCase("throw")) {
                         // Throwing this exception doesn't seem that useful. It breaks
@@ -200,293 +228,138 @@
             });
         }
 
-        // Override View.isInEditMode to return true.
-        //
-        // This allows custom views that are drawn in the Graphical Layout Editor to adapt their
-        // rendering for preview. Most important this let custom views know that they can't expect
-        // the rest of their activities to be alive.
-        OverrideMethod.setMethodListener("android.view.View#isInEditMode()Z",
-            new MethodAdapter() {
-                @Override
-                public int onInvokeI(String signature, boolean isNative, Object caller) {
-                    return 1;
-                }
-            }
-        );
-
         // load the fonts.
-        FontLoader fontLoader = FontLoader.create(fontOsLocation);
+        FontLoader fontLoader = FontLoader.create(fontLocation.getAbsolutePath());
         if (fontLoader != null) {
-            Typeface.init(fontLoader);
+            Typeface_Delegate.init(fontLoader);
         } else {
             return false;
         }
 
-        sEnumValueMap = enumValueMap;
-
         // now parse com.android.internal.R (and only this one as android.R is a subset of
         // the internal version), and put the content in the maps.
         try {
-            // WARNING: this only works because the class is already loaded, and therefore
-            // the objects returned by Field.get() are the same as the ones used by
-            // the code accessing the R class.
-            // int[] does not implement equals/hashCode, and if the parsing used a different class
-            // loader for the R class, this would NOT work.
             Class<?> r = com.android.internal.R.class;
 
             for (Class<?> inner : r.getDeclaredClasses()) {
-                String resType = inner.getSimpleName();
+                String resTypeName = inner.getSimpleName();
+                ResourceType resType = ResourceType.getEnum(resTypeName);
+                if (resType != null) {
+                    Map<String, Integer> fullMap = new HashMap<String, Integer>();
+                    sRFullMap.put(resType, fullMap);
 
-                Map<String, Integer> fullMap = new HashMap<String, Integer>();
-                sRFullMap.put(resType, fullMap);
-
-                for (Field f : inner.getDeclaredFields()) {
-                    // only process static final fields. Since the final attribute may have
-                    // been altered by layoutlib_create, we only check static
-                    int modifiers = f.getModifiers();
-                    if (Modifier.isStatic(modifiers)) {
-                        Class<?> type = f.getType();
-                        if (type.isArray() && type.getComponentType() == int.class) {
-                            // if the object is an int[] we put it in sRArrayMap
-                            sRArrayMap.put((int[]) f.get(null), f.getName());
-                        } else if (type == int.class) {
-                            Integer value = (Integer) f.get(null);
-                            sRMap.put(value, new String[] { f.getName(), resType });
-                            fullMap.put(f.getName(), value);
-                        } else {
-                            assert false;
+                    for (Field f : inner.getDeclaredFields()) {
+                        // only process static final fields. Since the final attribute may have
+                        // been altered by layoutlib_create, we only check static
+                        int modifiers = f.getModifiers();
+                        if (Modifier.isStatic(modifiers)) {
+                            Class<?> type = f.getType();
+                            if (type.isArray() && type.getComponentType() == int.class) {
+                                // if the object is an int[] we put it in sRArrayMap using an IntArray
+                                // wrapper that properly implements equals and hashcode for the array
+                                // objects, as required by the map contract.
+                                sRArrayMap.put(new IntArray((int[]) f.get(null)), f.getName());
+                            } else if (type == int.class) {
+                                Integer value = (Integer) f.get(null);
+                                sRMap.put(value, Pair.of(resType, f.getName()));
+                                fullMap.put(f.getName(), value);
+                            } else {
+                                assert false;
+                            }
                         }
                     }
                 }
             }
-        } catch (IllegalArgumentException e) {
-            // FIXME: log/return the error (there's no logger object at this point!)
-            e.printStackTrace();
-            return false;
-        } catch (IllegalAccessException e) {
-            e.printStackTrace();
+        } catch (Throwable throwable) {
+            if (log != null) {
+                log.error(LayoutLog.TAG_BROKEN,
+                        "Failed to load com.android.internal.R from the layout library jar",
+                        throwable);
+            }
             return false;
         }
 
         return true;
     }
 
-    /*
-     * For compatilibty purposes, we implement the old deprecated version of computeLayout.
-     * (non-Javadoc)
-     * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, java.lang.String, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
-     */
-    @Deprecated
-    public ILayoutResult computeLayout(IXmlPullParser layoutDescription,
-            Object projectKey,
-            int screenWidth, int screenHeight, String themeName,
-            Map<String, Map<String, IResourceValue>> projectResources,
-            Map<String, Map<String, IResourceValue>> frameworkResources,
-            IProjectCallback customViewLoader, ILayoutLog logger) {
-        boolean isProjectTheme = false;
-        if (themeName.charAt(0) == '*') {
-            themeName = themeName.substring(1);
-            isProjectTheme = true;
-        }
+    @Override
+    public boolean dispose() {
+        BridgeAssetManager.clearSystem();
 
-        return computeLayout(layoutDescription, projectKey,
-                screenWidth, screenHeight, DisplayMetrics.DENSITY_DEFAULT,
-                DisplayMetrics.DENSITY_DEFAULT, DisplayMetrics.DENSITY_DEFAULT,
-                themeName, isProjectTheme,
-                projectResources, frameworkResources, customViewLoader, logger);
+        // dispose of the default typeface.
+        Typeface.sDefaults = null;
+
+        return true;
     }
 
-    /*
-     * For compatilibty purposes, we implement the old deprecated version of computeLayout.
-     * (non-Javadoc)
-     * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
+    /**
+     * Starts a layout session by inflating and rendering it. The method returns a
+     * {@link RenderSession} on which further actions can be taken.
+     *
+     * @param params the {@link SessionParams} object with all the information necessary to create
+     *           the scene.
+     * @return a new {@link RenderSession} object that contains the result of the layout.
+     * @since 5
      */
-    @Deprecated
-    public ILayoutResult computeLayout(IXmlPullParser layoutDescription, Object projectKey,
-            int screenWidth, int screenHeight, String themeName, boolean isProjectTheme,
-            Map<String, Map<String, IResourceValue>> projectResources,
-            Map<String, Map<String, IResourceValue>> frameworkResources,
-            IProjectCallback customViewLoader, ILayoutLog logger) {
-        return computeLayout(layoutDescription, projectKey,
-                screenWidth, screenHeight, DisplayMetrics.DENSITY_DEFAULT,
-                DisplayMetrics.DENSITY_DEFAULT, DisplayMetrics.DENSITY_DEFAULT,
-                themeName, isProjectTheme,
-                projectResources, frameworkResources, customViewLoader, logger);
-    }
-
-    /*
-     * For compatilibty purposes, we implement the old deprecated version of computeLayout.
-     * (non-Javadoc)
-     * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, int, float, float, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
-     */
-    public ILayoutResult computeLayout(IXmlPullParser layoutDescription, Object projectKey,
-            int screenWidth, int screenHeight, int density, float xdpi, float ydpi,
-            String themeName, boolean isProjectTheme,
-            Map<String, Map<String, IResourceValue>> projectResources,
-            Map<String, Map<String, IResourceValue>> frameworkResources,
-            IProjectCallback customViewLoader, ILayoutLog logger) {
-        return computeLayout(layoutDescription, projectKey,
-                screenWidth, screenHeight, false /* renderFullSize */,
-                density, xdpi, ydpi, themeName, isProjectTheme,
-                projectResources, frameworkResources, customViewLoader, logger);
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, boolean, int, float, float, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
-     */
-    public ILayoutResult computeLayout(IXmlPullParser layoutDescription, Object projectKey,
-            int screenWidth, int screenHeight, boolean renderFullSize,
-            int density, float xdpi, float ydpi,
-            String themeName, boolean isProjectTheme,
-            Map<String, Map<String, IResourceValue>> projectResources,
-            Map<String, Map<String, IResourceValue>> frameworkResources,
-            IProjectCallback customViewLoader, ILayoutLog logger) {
-        if (logger == null) {
-            logger = sDefaultLogger;
-        }
-
-        synchronized (sDefaultLogger) {
-            sLogger = logger;
-        }
-
-        // find the current theme and compute the style inheritance map
-        Map<IStyleResourceValue, IStyleResourceValue> styleParentMap =
-            new HashMap<IStyleResourceValue, IStyleResourceValue>();
-
-        IStyleResourceValue currentTheme = computeStyleMaps(themeName, isProjectTheme,
-                projectResources.get(BridgeConstants.RES_STYLE),
-                frameworkResources.get(BridgeConstants.RES_STYLE), styleParentMap);
-
-        BridgeContext context = null;
+    @Override
+    public RenderSession createSession(SessionParams params) {
         try {
-            // setup the display Metrics.
-            DisplayMetrics metrics = new DisplayMetrics();
-            metrics.densityDpi = density;
-            metrics.density = density / (float) DisplayMetrics.DENSITY_DEFAULT;
-            metrics.scaledDensity = metrics.density;
-            metrics.widthPixels = screenWidth;
-            metrics.heightPixels = screenHeight;
-            metrics.xdpi = xdpi;
-            metrics.ydpi = ydpi;
-
-            context = new BridgeContext(projectKey, metrics, currentTheme, projectResources,
-                    frameworkResources, styleParentMap, customViewLoader, logger);
-            BridgeInflater inflater = new BridgeInflater(context, customViewLoader);
-            context.setBridgeInflater(inflater);
-
-            IResourceValue windowBackground = null;
-            int screenOffset = 0;
-            if (currentTheme != null) {
-                windowBackground = context.findItemInStyle(currentTheme, "windowBackground");
-                windowBackground = context.resolveResValue(windowBackground);
-
-                screenOffset = getScreenOffset(frameworkResources, currentTheme, context);
-            }
-
-            // we need to make sure the Looper has been initialized for this thread.
-            // this is required for View that creates Handler objects.
-            if (Looper.myLooper() == null) {
-                Looper.prepare();
-            }
-
-            BridgeXmlBlockParser parser = new BridgeXmlBlockParser(layoutDescription,
-                    context, false /* platformResourceFlag */);
-
-            ViewGroup root = new FrameLayout(context);
-
-            View view = inflater.inflate(parser, root);
-
-            // post-inflate process. For now this supports TabHost/TabWidget
-            postInflateProcess(view, customViewLoader);
-
-            // set the AttachInfo on the root view.
-            AttachInfo info = new AttachInfo(new WindowSession(), new Window(),
-                    new Handler(), null);
-            info.mHasWindowFocus = true;
-            info.mWindowVisibility = View.VISIBLE;
-            info.mInTouchMode = false; // this is so that we can display selections.
-            root.dispatchAttachedToWindow(info, 0);
-
-            // get the background drawable
-            if (windowBackground != null) {
-                Drawable d = ResourceHelper.getDrawable(windowBackground,
-                        context, true /* isFramework */);
-                root.setBackgroundDrawable(d);
-            }
-
-            // measure the views
-            int w_spec, h_spec;
-
-            if (renderFullSize) {
-                // measure the full size needed by the layout.
-                w_spec = MeasureSpec.makeMeasureSpec(screenWidth,
-                        MeasureSpec.UNSPECIFIED); // this lets us know the actual needed size
-                h_spec = MeasureSpec.makeMeasureSpec(screenHeight - screenOffset,
-                        MeasureSpec.UNSPECIFIED); // this lets us know the actual needed size
-                view.measure(w_spec, h_spec);
-
-                int neededWidth = root.getChildAt(0).getMeasuredWidth();
-                if (neededWidth > screenWidth) {
-                    screenWidth = neededWidth;
+            Result lastResult = SUCCESS.createResult();
+            RenderSessionImpl scene = new RenderSessionImpl(params);
+            try {
+                prepareThread();
+                lastResult = scene.init(params.getTimeout());
+                if (lastResult.isSuccess()) {
+                    lastResult = scene.inflate();
+                    if (lastResult.isSuccess()) {
+                        lastResult = scene.render(true /*freshRender*/);
+                    }
                 }
-
-                int neededHeight = root.getChildAt(0).getMeasuredHeight();
-                if (neededHeight > screenHeight - screenOffset) {
-                    screenHeight = neededHeight + screenOffset;
-                }
+            } finally {
+                scene.release();
+                cleanupThread();
             }
 
-            // remeasure with only the size we need
-            // This must always be done before the call to layout
-            w_spec = MeasureSpec.makeMeasureSpec(screenWidth, MeasureSpec.EXACTLY);
-            h_spec = MeasureSpec.makeMeasureSpec(screenHeight - screenOffset,
-                    MeasureSpec.EXACTLY);
-            view.measure(w_spec, h_spec);
-
-            // now do the layout.
-            view.layout(0, screenOffset, screenWidth, screenHeight);
-
-            // draw the views
-            Canvas canvas = new Canvas(screenWidth, screenHeight - screenOffset, logger);
-
-            root.draw(canvas);
-            canvas.dispose();
-
-            return new LayoutResult(visit(((ViewGroup)view).getChildAt(0), context),
-                    canvas.getImage());
-        } catch (PostInflateException e) {
-            return new LayoutResult(ILayoutResult.ERROR, "Error during post inflation process:\n"
-                    + e.getMessage());
-        } catch (Throwable e) {
+            return new BridgeRenderSession(scene, lastResult);
+        } catch (Throwable t) {
             // get the real cause of the exception.
-            Throwable t = e;
-            while (t.getCause() != null) {
-                t = t.getCause();
+            Throwable t2 = t;
+            while (t2.getCause() != null) {
+                t2 = t.getCause();
             }
-
-            // log it
-            logger.error(t);
-
-            // then return with an ERROR status and the message from the real exception
-            return new LayoutResult(ILayoutResult.ERROR,
-                    t.getClass().getSimpleName() + ": " + t.getMessage());
-        } finally {
-            // Make sure to remove static references, otherwise we could not unload the lib
-            BridgeResources.clearSystem();
-            BridgeAssetManager.clearSystem();
-
-            // Remove the global logger
-            synchronized (sDefaultLogger) {
-                sLogger = sDefaultLogger;
-            }
+            return new BridgeRenderSession(null,
+                    ERROR_UNKNOWN.createResult(t2.getMessage(), t));
         }
     }
 
-    /*
-     * (non-Javadoc)
-     * @see com.android.layoutlib.api.ILayoutLibBridge#clearCaches(java.lang.Object)
-     */
+    @Override
+    public Result renderDrawable(DrawableParams params) {
+        try {
+            Result lastResult = SUCCESS.createResult();
+            RenderDrawable action = new RenderDrawable(params);
+            try {
+                prepareThread();
+                lastResult = action.init(params.getTimeout());
+                if (lastResult.isSuccess()) {
+                    lastResult = action.render();
+                }
+            } finally {
+                action.release();
+                cleanupThread();
+            }
+
+            return lastResult;
+        } catch (Throwable t) {
+            // get the real cause of the exception.
+            Throwable t2 = t;
+            while (t2.getCause() != null) {
+                t2 = t.getCause();
+            }
+            return ERROR_UNKNOWN.createResult(t2.getMessage(), t);
+        }
+    }
+
+    @Override
     public void clearCaches(Object projectKey) {
         if (projectKey != null) {
             sProjectBitmapCache.remove(projectKey);
@@ -495,22 +368,71 @@
     }
 
     /**
+     * Returns the lock for the bridge
+     */
+    public static ReentrantLock getLock() {
+        return sLock;
+    }
+
+    /**
+     * Prepares the current thread for rendering.
+     *
+     * Note that while this can be called several time, the first call to {@link #cleanupThread()}
+     * will do the clean-up, and make the thread unable to do further scene actions.
+     */
+    public static void prepareThread() {
+        // we need to make sure the Looper has been initialized for this thread.
+        // this is required for View that creates Handler objects.
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+    }
+
+    /**
+     * Cleans up thread-specific data. After this, the thread cannot be used for scene actions.
+     * <p>
+     * Note that it doesn't matter how many times {@link #prepareThread()} was called, a single
+     * call to this will prevent the thread from doing further scene actions
+     */
+    public static void cleanupThread() {
+        // clean up the looper
+        Looper.sThreadLocal.remove();
+    }
+
+    public static LayoutLog getLog() {
+        return sCurrentLog;
+    }
+
+    public static void setLog(LayoutLog log) {
+        // check only the thread currently owning the lock can do this.
+        if (sLock.isHeldByCurrentThread() == false) {
+            throw new IllegalStateException("scene must be acquired first. see #acquire(long)");
+        }
+
+        if (log != null) {
+            sCurrentLog = log;
+        } else {
+            sCurrentLog = sDefaultLog;
+        }
+    }
+
+    /**
      * Returns details of a framework resource from its integer value.
      * @param value the integer value
-     * @return an array of 2 strings containing the resource name and type, or null if the id
-     * does not match any resource.
+     * @return a Pair containing the resource type and name, or null if the id
+     *     does not match any resource.
      */
-    public static String[] resolveResourceValue(int value) {
+    public static Pair<ResourceType, String> resolveResourceId(int value) {
         return sRMap.get(value);
-
     }
 
     /**
      * Returns the name of a framework resource whose value is an int array.
      * @param array
      */
-    public static String resolveResourceValue(int[] array) {
-        return sRArrayMap.get(array);
+    public static String resolveResourceId(int[] array) {
+        sIntArrayWrapper.set(array);
+        return sRArrayMap.get(sIntArrayWrapper);
     }
 
     /**
@@ -519,7 +441,7 @@
      * @param name the name of the resource.
      * @return an {@link Integer} containing the resource id, or null if no resource were found.
      */
-    public static Integer getResourceValue(String type, String name) {
+    public static Integer getResourceId(ResourceType type, String name) {
         Map<String, Integer> map = sRFullMap.get(type);
         if (map != null) {
             return map.get(name);
@@ -528,7 +450,10 @@
         return null;
     }
 
-    static Map<String, Integer> getEnumValues(String attributeName) {
+    /**
+     * Returns the list of possible enums for a given attribute name.
+     */
+    public static Map<String, Integer> getEnumValues(String attributeName) {
         if (sEnumValueMap != null) {
             return sEnumValueMap.get(attributeName);
         }
@@ -537,348 +462,10 @@
     }
 
     /**
-     * Visits a View and its children and generate a {@link ILayoutViewInfo} containing the
-     * bounds of all the views.
-     * @param view the root View
-     * @param context the context.
+     * Returns the platform build properties.
      */
-    private ILayoutViewInfo visit(View view, BridgeContext context) {
-        if (view == null) {
-            return null;
-        }
-
-        LayoutViewInfo result = new LayoutViewInfo(view.getClass().getName(),
-                context.getViewKey(view),
-                view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
-
-        if (view instanceof ViewGroup) {
-            ViewGroup group = ((ViewGroup) view);
-            int n = group.getChildCount();
-            ILayoutViewInfo[] children = new ILayoutViewInfo[n];
-            for (int i = 0; i < group.getChildCount(); i++) {
-                children[i] = visit(group.getChildAt(i), context);
-            }
-            result.setChildren(children);
-        }
-
-        return result;
-    }
-
-    /**
-     * Compute style information from the given list of style for the project and framework.
-     * @param themeName the name of the current theme.  In order to differentiate project and
-     * platform themes sharing the same name, all project themes must be prepended with
-     * a '*' character.
-     * @param isProjectTheme Is this a project theme
-     * @param inProjectStyleMap the project style map
-     * @param inFrameworkStyleMap the framework style map
-     * @param outInheritanceMap the map of style inheritance. This is filled by the method
-     * @return the {@link IStyleResourceValue} matching <var>themeName</var>
-     */
-    private IStyleResourceValue computeStyleMaps(
-            String themeName, boolean isProjectTheme, Map<String,
-            IResourceValue> inProjectStyleMap, Map<String, IResourceValue> inFrameworkStyleMap,
-            Map<IStyleResourceValue, IStyleResourceValue> outInheritanceMap) {
-
-        if (inProjectStyleMap != null && inFrameworkStyleMap != null) {
-            // first, get the theme
-            IResourceValue theme = null;
-
-            // project theme names have been prepended with a *
-            if (isProjectTheme) {
-                theme = inProjectStyleMap.get(themeName);
-            } else {
-                theme = inFrameworkStyleMap.get(themeName);
-            }
-
-            if (theme instanceof IStyleResourceValue) {
-                // compute the inheritance map for both the project and framework styles
-                computeStyleInheritance(inProjectStyleMap.values(), inProjectStyleMap,
-                        inFrameworkStyleMap, outInheritanceMap);
-
-                // Compute the style inheritance for the framework styles/themes.
-                // Since, for those, the style parent values do not contain 'android:'
-                // we want to force looking in the framework style only to avoid using
-                // similarly named styles from the project.
-                // To do this, we pass null in lieu of the project style map.
-                computeStyleInheritance(inFrameworkStyleMap.values(), null /*inProjectStyleMap */,
-                        inFrameworkStyleMap, outInheritanceMap);
-
-                return (IStyleResourceValue)theme;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Compute the parent style for all the styles in a given list.
-     * @param styles the styles for which we compute the parent.
-     * @param inProjectStyleMap the map of project styles.
-     * @param inFrameworkStyleMap the map of framework styles.
-     * @param outInheritanceMap the map of style inheritance. This is filled by the method.
-     */
-    private void computeStyleInheritance(Collection<IResourceValue> styles,
-            Map<String, IResourceValue> inProjectStyleMap,
-            Map<String, IResourceValue> inFrameworkStyleMap,
-            Map<IStyleResourceValue, IStyleResourceValue> outInheritanceMap) {
-        for (IResourceValue value : styles) {
-            if (value instanceof IStyleResourceValue) {
-                IStyleResourceValue style = (IStyleResourceValue)value;
-                IStyleResourceValue parentStyle = null;
-
-                // first look for a specified parent.
-                String parentName = style.getParentStyle();
-
-                // no specified parent? try to infer it from the name of the style.
-                if (parentName == null) {
-                    parentName = getParentName(value.getName());
-                }
-
-                if (parentName != null) {
-                    parentStyle = getStyle(parentName, inProjectStyleMap, inFrameworkStyleMap);
-
-                    if (parentStyle != null) {
-                        outInheritanceMap.put(style, parentStyle);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Searches for and returns the {@link IStyleResourceValue} from a given name.
-     * <p/>The format of the name can be:
-     * <ul>
-     * <li>[android:]&lt;name&gt;</li>
-     * <li>[android:]style/&lt;name&gt;</li>
-     * <li>@[android:]style/&lt;name&gt;</li>
-     * </ul>
-     * @param parentName the name of the style.
-     * @param inProjectStyleMap the project style map. Can be <code>null</code>
-     * @param inFrameworkStyleMap the framework style map.
-     * @return The matching {@link IStyleResourceValue} object or <code>null</code> if not found.
-     */
-    private IStyleResourceValue getStyle(String parentName,
-            Map<String, IResourceValue> inProjectStyleMap,
-            Map<String, IResourceValue> inFrameworkStyleMap) {
-        boolean frameworkOnly = false;
-
-        String name = parentName;
-
-        // remove the useless @ if it's there
-        if (name.startsWith(BridgeConstants.PREFIX_RESOURCE_REF)) {
-            name = name.substring(BridgeConstants.PREFIX_RESOURCE_REF.length());
-        }
-
-        // check for framework identifier.
-        if (name.startsWith(BridgeConstants.PREFIX_ANDROID)) {
-            frameworkOnly = true;
-            name = name.substring(BridgeConstants.PREFIX_ANDROID.length());
-        }
-
-        // at this point we could have the format <type>/<name>. we want only the name as long as
-        // the type is style.
-        if (name.startsWith(BridgeConstants.REFERENCE_STYLE)) {
-            name = name.substring(BridgeConstants.REFERENCE_STYLE.length());
-        } else if (name.indexOf('/') != -1) {
-            return null;
-        }
-
-        IResourceValue parent = null;
-
-        // if allowed, search in the project resources.
-        if (frameworkOnly == false && inProjectStyleMap != null) {
-            parent = inProjectStyleMap.get(name);
-        }
-
-        // if not found, then look in the framework resources.
-        if (parent == null) {
-            parent = inFrameworkStyleMap.get(name);
-        }
-
-        // make sure the result is the proper class type and return it.
-        if (parent instanceof IStyleResourceValue) {
-            return (IStyleResourceValue)parent;
-        }
-
-        sLogger.error(String.format("Unable to resolve parent style name: %s", parentName));
-
-        return null;
-    }
-
-    /**
-     * Computes the name of the parent style, or <code>null</code> if the style is a root style.
-     */
-    private String getParentName(String styleName) {
-        int index = styleName.lastIndexOf('.');
-        if (index != -1) {
-            return styleName.substring(0, index);
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the top screen offset. This depends on whether the current theme defines the user
-     * of the title and status bars.
-     * @param frameworkResources The framework resources
-     * @param currentTheme The current theme
-     * @param context The context
-     * @return the pixel height offset
-     */
-    private int getScreenOffset(Map<String, Map<String, IResourceValue>> frameworkResources,
-            IStyleResourceValue currentTheme, BridgeContext context) {
-        int offset = 0;
-
-        // get the title bar flag from the current theme.
-        IResourceValue value = context.findItemInStyle(currentTheme, "windowNoTitle");
-
-        // because it may reference something else, we resolve it.
-        value = context.resolveResValue(value);
-
-        // if there's a value and it's true (default is false)
-        if (value == null || value.getValue() == null ||
-                XmlUtils.convertValueToBoolean(value.getValue(), false /* defValue */) == false) {
-            // default size of the window title bar
-            int defaultOffset = DEFAULT_TITLE_BAR_HEIGHT;
-
-            // get value from the theme.
-            value = context.findItemInStyle(currentTheme, "windowTitleSize");
-
-            // resolve it
-            value = context.resolveResValue(value);
-
-            if (value != null) {
-                // get the numerical value, if available
-                TypedValue typedValue = ResourceHelper.getValue(value.getValue());
-                if (typedValue != null) {
-                    // compute the pixel value based on the display metrics
-                    defaultOffset = (int)typedValue.getDimension(context.getResources().mMetrics);
-                }
-            }
-
-            offset += defaultOffset;
-        }
-
-        // get the fullscreen flag from the current theme.
-        value = context.findItemInStyle(currentTheme, "windowFullscreen");
-
-        // because it may reference something else, we resolve it.
-        value = context.resolveResValue(value);
-
-        if (value == null || value.getValue() == null ||
-                XmlUtils.convertValueToBoolean(value.getValue(), false /* defValue */) == false) {
-
-            // default value
-            int defaultOffset = DEFAULT_STATUS_BAR_HEIGHT;
-
-            // get the real value, first the list of Dimensions from the framework map
-            Map<String, IResourceValue> dimens = frameworkResources.get(BridgeConstants.RES_DIMEN);
-
-            // now get the value
-            value = dimens.get("status_bar_height");
-            if (value != null) {
-                TypedValue typedValue = ResourceHelper.getValue(value.getValue());
-                if (typedValue != null) {
-                    // compute the pixel value based on the display metrics
-                    defaultOffset = (int)typedValue.getDimension(context.getResources().mMetrics);
-                }
-            }
-
-            // add the computed offset.
-            offset += defaultOffset;
-        }
-
-        return offset;
-    }
-
-    /**
-     * Post process on a view hierachy that was just inflated.
-     * <p/>At the moment this only support TabHost: If {@link TabHost} is detected, look for the
-     * {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically
-     * based on the content of the {@link FrameLayout}.
-     * @param view the root view to process.
-     * @param projectCallback callback to the project.
-     */
-    private void postInflateProcess(View view, IProjectCallback projectCallback)
-            throws PostInflateException {
-        if (view instanceof TabHost) {
-            setupTabHost((TabHost)view, projectCallback);
-        } else if (view instanceof ViewGroup) {
-            ViewGroup group = (ViewGroup)view;
-            final int count = group.getChildCount();
-            for (int c = 0 ; c < count ; c++) {
-                View child = group.getChildAt(c);
-                postInflateProcess(child, projectCallback);
-            }
-        }
-    }
-
-    /**
-     * Sets up a {@link TabHost} object.
-     * @param tabHost the TabHost to setup.
-     * @param projectCallback The project callback object to access the project R class.
-     * @throws PostInflateException
-     */
-    private void setupTabHost(TabHost tabHost, IProjectCallback projectCallback)
-            throws PostInflateException {
-        // look for the TabWidget, and the FrameLayout. They have their own specific names
-        View v = tabHost.findViewById(android.R.id.tabs);
-
-        if (v == null) {
-            throw new PostInflateException(
-                    "TabHost requires a TabWidget with id \"android:id/tabs\".\n");
-        }
-
-        if ((v instanceof TabWidget) == false) {
-            throw new PostInflateException(String.format(
-                    "TabHost requires a TabWidget with id \"android:id/tabs\".\n" +
-                    "View found with id 'tabs' is '%s'", v.getClass().getCanonicalName()));
-        }
-
-        v = tabHost.findViewById(android.R.id.tabcontent);
-
-        if (v == null) {
-            // TODO: see if we can fake tabs even without the FrameLayout (same below when the framelayout is empty)
-            throw new PostInflateException(
-                    "TabHost requires a FrameLayout with id \"android:id/tabcontent\".");
-        }
-
-        if ((v instanceof FrameLayout) == false) {
-            throw new PostInflateException(String.format(
-                    "TabHost requires a FrameLayout with id \"android:id/tabcontent\".\n" +
-                    "View found with id 'tabcontent' is '%s'", v.getClass().getCanonicalName()));
-        }
-
-        FrameLayout content = (FrameLayout)v;
-
-        // now process the content of the framelayout and dynamically create tabs for it.
-        final int count = content.getChildCount();
-
-        if (count == 0) {
-            throw new PostInflateException(
-                    "The FrameLayout for the TabHost has no content. Rendering failed.\n");
-        }
-
-        // this must be called before addTab() so that the TabHost searches its TabWidget
-        // and FrameLayout.
-        tabHost.setup();
-
-        // for each child of the framelayout, add a new TabSpec
-        for (int i = 0 ; i < count ; i++) {
-            View child = content.getChildAt(i);
-            String tabSpec = String.format("tab_spec%d", i+1);
-            int id = child.getId();
-            String[] resource = projectCallback.resolveResourceValue(id);
-            String name;
-            if (resource != null) {
-                name = resource[0]; // 0 is resource name, 1 is resource type.
-            } else {
-                name = String.format("Tab %d", i+1); // default name if id is unresolved.
-            }
-            tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(name).setContent(id));
-        }
+    public static Map<String, String> getPlatformProperties() {
+        return sPlatformProperties;
     }
 
     /**
@@ -888,7 +475,7 @@
      * @param projectKey the key of the project, or null to query the framework cache.
      * @return the cached Bitmap or null if not found.
      */
-    static Bitmap getCachedBitmap(String value, Object projectKey) {
+    public static Bitmap getCachedBitmap(String value, Object projectKey) {
         if (projectKey != null) {
             Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey);
             if (map != null) {
@@ -913,7 +500,7 @@
      * @param bmp the Bitmap object
      * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
      */
-    static void setCachedBitmap(String value, Bitmap bmp, Object projectKey) {
+    public static void setCachedBitmap(String value, Bitmap bmp, Object projectKey) {
         if (projectKey != null) {
             Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey);
 
@@ -929,24 +516,24 @@
     }
 
     /**
-     * Returns the 9 patch for a specific path, from a specific project cache, or from the
+     * Returns the 9 patch chunk for a specific path, from a specific project cache, or from the
      * framework cache.
      * @param value the path of the 9 patch
      * @param projectKey the key of the project, or null to query the framework cache.
      * @return the cached 9 patch or null if not found.
      */
-    static NinePatch getCached9Patch(String value, Object projectKey) {
+    public static NinePatchChunk getCached9Patch(String value, Object projectKey) {
         if (projectKey != null) {
-            Map<String, SoftReference<NinePatch>> map = sProject9PatchCache.get(projectKey);
+            Map<String, SoftReference<NinePatchChunk>> map = sProject9PatchCache.get(projectKey);
 
             if (map != null) {
-                SoftReference<NinePatch> ref = map.get(value);
+                SoftReference<NinePatchChunk> ref = map.get(value);
                 if (ref != null) {
                     return ref.get();
                 }
             }
         } else {
-            SoftReference<NinePatch> ref = sFramework9PatchCache.get(value);
+            SoftReference<NinePatchChunk> ref = sFramework9PatchCache.get(value);
             if (ref != null) {
                 return ref.get();
             }
@@ -956,224 +543,25 @@
     }
 
     /**
-     * Sets a 9 patch in a project cache or in the framework cache.
+     * Sets a 9 patch chunk in a project cache or in the framework cache.
      * @param value the path of the 9 patch
      * @param ninePatch the 9 patch object
      * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
      */
-    static void setCached9Patch(String value, NinePatch ninePatch, Object projectKey) {
+    public static void setCached9Patch(String value, NinePatchChunk ninePatch, Object projectKey) {
         if (projectKey != null) {
-            Map<String, SoftReference<NinePatch>> map = sProject9PatchCache.get(projectKey);
+            Map<String, SoftReference<NinePatchChunk>> map = sProject9PatchCache.get(projectKey);
 
             if (map == null) {
-                map = new HashMap<String, SoftReference<NinePatch>>();
+                map = new HashMap<String, SoftReference<NinePatchChunk>>();
                 sProject9PatchCache.put(projectKey, map);
             }
 
-            map.put(value, new SoftReference<NinePatch>(ninePatch));
+            map.put(value, new SoftReference<NinePatchChunk>(ninePatch));
         } else {
-            sFramework9PatchCache.put(value, new SoftReference<NinePatch>(ninePatch));
+            sFramework9PatchCache.put(value, new SoftReference<NinePatchChunk>(ninePatch));
         }
     }
 
-    private static final class PostInflateException extends Exception {
-        private static final long serialVersionUID = 1L;
-
-        public PostInflateException(String message) {
-            super(message);
-        }
-    }
-
-    /**
-     * Implementation of {@link IWindowSession} so that mSession is not null in
-     * the {@link SurfaceView}.
-     */
-    private static final class WindowSession implements IWindowSession {
-
-        @SuppressWarnings("unused")
-        public int add(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3,
-                InputChannel outInputchannel)
-                throws RemoteException {
-            // pass for now.
-            return 0;
-        }
-
-        @SuppressWarnings("unused")
-        public int addWithoutInputChannel(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3)
-                throws RemoteException {
-            // pass for now.
-            return 0;
-        }
-        
-        @SuppressWarnings("unused")
-        public void finishDrawing(IWindow arg0) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void finishKey(IWindow arg0) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public boolean getInTouchMode() throws RemoteException {
-            // pass for now.
-            return false;
-        }
-
-        @SuppressWarnings("unused")
-        public boolean performHapticFeedback(IWindow window, int effectId, boolean always) {
-            // pass for now.
-            return false;
-        }
-
-        @SuppressWarnings("unused")
-        public MotionEvent getPendingPointerMove(IWindow arg0) throws RemoteException {
-            // pass for now.
-            return null;
-        }
-
-        @SuppressWarnings("unused")
-        public MotionEvent getPendingTrackballMove(IWindow arg0) throws RemoteException {
-            // pass for now.
-            return null;
-        }
-
-        @SuppressWarnings("unused")
-        public int relayout(IWindow arg0, LayoutParams arg1, int arg2, int arg3, int arg4,
-                boolean arg4_5, Rect arg5, Rect arg6, Rect arg7, Configuration arg7b, Surface arg8)
-                throws RemoteException {
-            // pass for now.
-            return 0;
-        }
-
-        public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void remove(IWindow arg0) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void setInTouchMode(boolean arg0) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void setTransparentRegion(IWindow arg0, Region arg1) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void setInsets(IWindow window, int touchable, Rect contentInsets,
-                Rect visibleInsets) {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void setWallpaperPosition(IBinder window, float x, float y,
-            float xStep, float yStep) {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void wallpaperOffsetsComplete(IBinder window) {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
-                int z, Bundle extras, boolean sync) {
-            // pass for now.
-            return null;
-        }
-
-        @SuppressWarnings("unused")
-        public void wallpaperCommandComplete(IBinder window, Bundle result) {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void closeSystemDialogs(String reason) {
-            // pass for now.
-        }
-
-        public IBinder asBinder() {
-            // pass for now.
-            return null;
-        }
-    }
-
-    /**
-     * Implementation of {@link IWindow} to pass to the {@link AttachInfo}.
-     */
-    private static final class Window implements IWindow {
-
-        @SuppressWarnings("unused")
-        public void dispatchAppVisibility(boolean arg0) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void dispatchGetNewSurface() throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void dispatchKey(KeyEvent arg0) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void dispatchPointer(MotionEvent arg0, long arg1, boolean arg2) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void dispatchTrackball(MotionEvent arg0, long arg1, boolean arg2) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void executeCommand(String arg0, String arg1, ParcelFileDescriptor arg2)
-                throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void resized(int arg0, int arg1, Rect arg2, Rect arg3, boolean arg4, Configuration arg5)
-                throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void windowFocusChanged(boolean arg0, boolean arg1) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
-                boolean sync) {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void dispatchWallpaperCommand(String action, int x, int y,
-                int z, Bundle extras, boolean sync) {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void closeSystemDialogs(String reason) {
-            // pass for now.
-        }
-
-        public IBinder asBinder() {
-            // pass for now.
-            return null;
-        }
-    }
 
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
index 791e53b..112af1e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
@@ -41,24 +41,6 @@
 
     public final static String R = "com.android.internal.R";
 
-    public final static String PREFIX_ANDROID_RESOURCE_REF = "@android:";
-    public final static String PREFIX_RESOURCE_REF = "@";
-    public final static String PREFIX_ANDROID_THEME_REF = "?android:";
-    public final static String PREFIX_THEME_REF = "?";
-
-    public final static String PREFIX_ANDROID = "android:";
-
-    public final static String RES_STYLE = "style";
-    public final static String RES_ATTR = "attr";
-    public final static String RES_DIMEN = "dimen";
-    public final static String RES_DRAWABLE = "drawable";
-    public final static String RES_COLOR = "color";
-    public final static String RES_LAYOUT = "layout";
-    public final static String RES_STRING = "string";
-    public final static String RES_ID = "id";
-
-    public final static String REFERENCE_STYLE = RES_STYLE + "/";
-    public final static String REFERENCE_NULL = "@null";
 
     public final static String MATCH_PARENT = "match_parent";
     public final static String FILL_PARENT = "fill_parent";
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentResolver.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentResolver.java
deleted file mode 100644
index 20ccc0b..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentResolver.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import android.content.ContentProviderOperation;
-import android.content.ContentProviderResult;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.IContentProvider;
-import android.content.OperationApplicationException;
-import android.content.res.AssetFileDescriptor;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.database.CursorWindow;
-import android.database.IBulkCursor;
-import android.database.IContentObserver;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-
-/**
- * A mock content resolver for the LayoutLib Bridge.
- * <p/>
- * It won't serve any actual data but it's good enough for all
- * the widgets which expect to have a content resolver available via
- * {@link BridgeContext#getContentResolver()}.
- */
-public class BridgeContentResolver extends ContentResolver {
-
-    private BridgeContentProvider mProvider = null;
-
-    public static final class BridgeContentProvider implements IContentProvider {
-
-        public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> arg0)
-                throws RemoteException, OperationApplicationException {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        public int bulkInsert(Uri arg0, ContentValues[] arg1) throws RemoteException {
-            // TODO Auto-generated method stub
-            return 0;
-        }
-
-        public IBulkCursor bulkQuery(Uri arg0, String[] arg1, String arg2, String[] arg3,
-                String arg4, IContentObserver arg5, CursorWindow arg6) throws RemoteException {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        public Bundle call(String arg0, String arg1, Bundle arg2) throws RemoteException {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        public int delete(Uri arg0, String arg1, String[] arg2) throws RemoteException {
-            // TODO Auto-generated method stub
-            return 0;
-        }
-
-        public String getType(Uri arg0) throws RemoteException {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        public Uri insert(Uri arg0, ContentValues arg1) throws RemoteException {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        public AssetFileDescriptor openAssetFile(Uri arg0, String arg1) throws RemoteException,
-                FileNotFoundException {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        public ParcelFileDescriptor openFile(Uri arg0, String arg1) throws RemoteException,
-                FileNotFoundException {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4)
-                throws RemoteException {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3)
-                throws RemoteException {
-            // TODO Auto-generated method stub
-            return 0;
-        }
-
-        public IBinder asBinder() {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-    }
-
-    public BridgeContentResolver(Context context) {
-        super(context);
-    }
-
-    @Override
-    public IContentProvider acquireProvider(Context c, String name) {
-        if (mProvider == null) {
-            mProvider = new BridgeContentProvider();
-        }
-
-        return mProvider;
-    }
-
-    @Override
-    public IContentProvider acquireExistingProvider(Context c, String name) {
-        if (mProvider == null) {
-            mProvider = new BridgeContentProvider();
-        }
-
-        return mProvider;
-    }
-
-    @Override
-    public boolean releaseProvider(IContentProvider icp) {
-        // ignore
-        return false;
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void registerContentObserver(Uri uri, boolean notifyForDescendents,
-            ContentObserver observer) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void unregisterContentObserver(ContentObserver observer) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void startSync(Uri uri, Bundle extras) {
-        // pass
-    }
-
-    /**
-     * Stub for the layoutlib bridge content resolver.
-     */
-    @Override
-    public void cancelSync(Uri uri) {
-        // pass
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
deleted file mode 100644
index ecd22e2..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
+++ /dev/null
@@ -1,1207 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import com.android.layoutlib.api.ILayoutLog;
-import com.android.layoutlib.api.IProjectCallback;
-import com.android.layoutlib.api.IResourceValue;
-import com.android.layoutlib.api.IStyleResourceValue;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.ServiceConnection;
-import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.res.AssetManager;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.content.res.Resources.Theme;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteDatabase.CursorFactory;
-import android.graphics.Bitmap;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.view.BridgeInflater;
-import android.view.View;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TreeMap;
-import java.util.Map.Entry;
-
-/**
- * Custom implementation of Context to handle non compiled resources.
- */
-public final class BridgeContext extends Context {
-
-    private final Resources mResources;
-    private final Theme mTheme;
-    private final HashMap<View, Object> mViewKeyMap = new HashMap<View, Object>();
-    private final IStyleResourceValue mThemeValues;
-    private final Object mProjectKey;
-    private final Map<String, Map<String, IResourceValue>> mProjectResources;
-    private final Map<String, Map<String, IResourceValue>> mFrameworkResources;
-    private final Map<IStyleResourceValue, IStyleResourceValue> mStyleInheritanceMap;
-
-    // maps for dynamically generated id representing style objects (IStyleResourceValue)
-    private Map<Integer, IStyleResourceValue> mDynamicIdToStyleMap;
-    private Map<IStyleResourceValue, Integer> mStyleToDynamicIdMap;
-    private int mDynamicIdGenerator = 0x01030000; // Base id for framework R.style
-
-    // cache for TypedArray generated from IStyleResourceValue object
-    private Map<int[], Map<Integer, TypedArray>> mTypedArrayCache;
-    private BridgeInflater mInflater;
-
-    private final IProjectCallback mProjectCallback;
-    private final ILayoutLog mLogger;
-    private BridgeContentResolver mContentResolver;
-
-    /**
-     * @param projectKey An Object identifying the project. This is used for the cache mechanism.
-     * @param metrics the {@link DisplayMetrics}.
-     * @param themeName The name of the theme to use.
-     * @param projectResources the resources of the project. The map contains (String, map) pairs
-     * where the string is the type of the resource reference used in the layout file, and the
-     * map contains (String, {@link IResourceValue}) pairs where the key is the resource name,
-     * and the value is the resource value.
-     * @param frameworkResources the framework resources. The map contains (String, map) pairs
-     * where the string is the type of the resource reference used in the layout file, and the map
-     * contains (String, {@link IResourceValue}) pairs where the key is the resource name, and the
-     * value is the resource value.
-     * @param styleInheritanceMap
-     * @param customViewLoader
-     */
-    public BridgeContext(Object projectKey, DisplayMetrics metrics,
-            IStyleResourceValue currentTheme,
-            Map<String, Map<String, IResourceValue>> projectResources,
-            Map<String, Map<String, IResourceValue>> frameworkResources,
-            Map<IStyleResourceValue, IStyleResourceValue> styleInheritanceMap,
-            IProjectCallback customViewLoader, ILayoutLog logger) {
-        mProjectKey = projectKey;
-        mProjectCallback = customViewLoader;
-        mLogger = logger;
-        Configuration config = new Configuration();
-
-        AssetManager assetManager = BridgeAssetManager.initSystem();
-        mResources = BridgeResources.initSystem(
-                this,
-                assetManager,
-                metrics,
-                config,
-                customViewLoader);
-
-        mTheme = mResources.newTheme();
-
-        mThemeValues = currentTheme;
-        mProjectResources = projectResources;
-        mFrameworkResources = frameworkResources;
-        mStyleInheritanceMap = styleInheritanceMap;
-    }
-
-    public void setBridgeInflater(BridgeInflater inflater) {
-        mInflater = inflater;
-    }
-
-    public void addViewKey(View view, Object viewKey) {
-        mViewKeyMap.put(view, viewKey);
-    }
-
-    public Object getViewKey(View view) {
-        return mViewKeyMap.get(view);
-    }
-
-    public Object getProjectKey() {
-        return mProjectKey;
-    }
-
-    public IProjectCallback getProjectCallback() {
-        return mProjectCallback;
-    }
-
-    public ILayoutLog getLogger() {
-        return mLogger;
-    }
-
-    // ------------ Context methods
-
-    @Override
-    public Resources getResources() {
-        return mResources;
-    }
-
-    @Override
-    public Theme getTheme() {
-        return mTheme;
-    }
-
-    @Override
-    public ClassLoader getClassLoader() {
-        return this.getClass().getClassLoader();
-    }
-
-    @Override
-    public Object getSystemService(String service) {
-        if (LAYOUT_INFLATER_SERVICE.equals(service)) {
-            return mInflater;
-        }
-
-        // AutoCompleteTextView and MultiAutoCompleteTextView want a window
-        // service. We don't have any but it's not worth an exception.
-        if (WINDOW_SERVICE.equals(service)) {
-            return null;
-        }
-
-        throw new UnsupportedOperationException("Unsupported Service: " + service);
-    }
-
-
-    @Override
-    public final TypedArray obtainStyledAttributes(int[] attrs) {
-        return createStyleBasedTypedArray(mThemeValues, attrs);
-    }
-
-    @Override
-    public final TypedArray obtainStyledAttributes(int resid, int[] attrs)
-            throws Resources.NotFoundException {
-        // get the IStyleResourceValue based on the resId;
-        IStyleResourceValue style = getStyleByDynamicId(resid);
-
-        if (style == null) {
-            throw new Resources.NotFoundException();
-        }
-
-        if (mTypedArrayCache == null) {
-            mTypedArrayCache = new HashMap<int[], Map<Integer,TypedArray>>();
-
-            Map<Integer, TypedArray> map = new HashMap<Integer, TypedArray>();
-            mTypedArrayCache.put(attrs, map);
-
-            BridgeTypedArray ta = createStyleBasedTypedArray(style, attrs);
-            map.put(resid, ta);
-
-            return ta;
-        }
-
-        // get the 2nd map
-        Map<Integer, TypedArray> map = mTypedArrayCache.get(attrs);
-        if (map == null) {
-            map = new HashMap<Integer, TypedArray>();
-            mTypedArrayCache.put(attrs, map);
-        }
-
-        // get the array from the 2nd map
-        TypedArray ta = map.get(resid);
-
-        if (ta == null) {
-            ta = createStyleBasedTypedArray(style, attrs);
-            map.put(resid, ta);
-        }
-
-        return ta;
-    }
-
-    @Override
-    public final TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs) {
-        return obtainStyledAttributes(set, attrs, 0, 0);
-    }
-
-    @Override
-    public TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs,
-            int defStyleAttr, int defStyleRes) {
-
-        // Hint: for XmlPullParser, attach source //DEVICE_SRC/dalvik/libcore/xml/src/java
-        BridgeXmlBlockParser parser = null;
-        if (set instanceof BridgeXmlBlockParser) {
-            parser = (BridgeXmlBlockParser)set;
-        } else if (set != null) { // null parser is ok
-            // really this should not be happening since its instantiated in Bridge
-            mLogger.error("Parser is not a BridgeXmlBlockParser!");
-            return null;
-        }
-
-        boolean[] frameworkAttributes = new boolean[1];
-        TreeMap<Integer, String> styleNameMap = searchAttrs(attrs, frameworkAttributes);
-
-        BridgeTypedArray ta = ((BridgeResources) mResources).newTypeArray(attrs.length,
-                parser != null ? parser.isPlatformFile() : true);
-
-        // resolve the defStyleAttr value into a IStyleResourceValue
-        IStyleResourceValue defStyleValues = null;
-
-        // look for a custom style.
-        String customStyle = null;
-        if (parser != null) {
-            customStyle = parser.getAttributeValue(null /* namespace*/, "style");
-        }
-        if (customStyle != null) {
-            IResourceValue item = findResValue(customStyle, false /*forceFrameworkOnly*/);
-
-            if (item instanceof IStyleResourceValue) {
-                defStyleValues = (IStyleResourceValue)item;
-            }
-        }
-
-        if (defStyleValues == null && defStyleAttr != 0) {
-            // get the name from the int.
-            String defStyleName = searchAttr(defStyleAttr);
-
-            // look for the style in the current theme, and its parent:
-            if (mThemeValues != null) {
-                IResourceValue item = findItemInStyle(mThemeValues, defStyleName);
-
-                if (item != null) {
-                    // item is a reference to a style entry. Search for it.
-                    item = findResValue(item.getValue(), false /*forceFrameworkOnly*/);
-
-                    if (item instanceof IStyleResourceValue) {
-                        defStyleValues = (IStyleResourceValue)item;
-                    }
-                } else {
-                    // TODO: log the error properly
-                    System.out.println("Failed to find defStyle: " + defStyleName);
-                }
-            }
-        }
-
-        if (defStyleRes != 0) {
-            // FIXME: See what we need to do with this.
-            throw new UnsupportedOperationException();
-        }
-
-        String namespace = BridgeConstants.NS_RESOURCES;
-        if (frameworkAttributes[0] == false) {
-            // need to use the application namespace
-            namespace = mProjectCallback.getNamespace();
-        }
-
-        if (styleNameMap != null) {
-            for (Entry<Integer, String> styleAttribute : styleNameMap.entrySet()) {
-                int index = styleAttribute.getKey().intValue();
-
-                String name = styleAttribute.getValue();
-                String value = null;
-                if (parser != null) {
-                    value = parser.getAttributeValue(namespace, name);
-                }
-
-                // if there's no direct value for this attribute in the XML, we look for default
-                // values in the widget defStyle, and then in the theme.
-                if (value == null) {
-                    IResourceValue resValue = null;
-
-                    // look for the value in the defStyle first (and its parent if needed)
-                    if (defStyleValues != null) {
-                        resValue = findItemInStyle(defStyleValues, name);
-                    }
-
-                    // if the item is not present in the defStyle, we look in the main theme (and
-                    // its parent themes)
-                    if (resValue == null && mThemeValues != null) {
-                        resValue = findItemInStyle(mThemeValues, name);
-                    }
-
-                    // if we found a value, we make sure this doesn't reference another value.
-                    // So we resolve it.
-                    if (resValue != null) {
-                        resValue = resolveResValue(resValue);
-                    }
-
-                    ta.bridgeSetValue(index, name, resValue);
-                } else {
-                    // there is a value in the XML, but we need to resolve it in case it's
-                    // referencing another resource or a theme value.
-                    ta.bridgeSetValue(index, name, resolveValue(null, name, value));
-                }
-            }
-        }
-
-        ta.sealArray();
-
-        return ta;
-    }
-
-    @Override
-    public Looper getMainLooper() {
-        return Looper.myLooper();
-    }
-
-
-    // ------------- private new methods
-
-    /**
-     * Creates a {@link BridgeTypedArray} by filling the values defined by the int[] with the
-     * values found in the given style.
-     * @see #obtainStyledAttributes(int, int[])
-     */
-    private BridgeTypedArray createStyleBasedTypedArray(IStyleResourceValue style, int[] attrs)
-            throws Resources.NotFoundException {
-        TreeMap<Integer, String> styleNameMap = searchAttrs(attrs, null);
-
-        BridgeTypedArray ta = ((BridgeResources) mResources).newTypeArray(attrs.length,
-                false /* platformResourceFlag */);
-
-        // loop through all the values in the style map, and init the TypedArray with
-        // the style we got from the dynamic id
-        for (Entry<Integer, String> styleAttribute : styleNameMap.entrySet()) {
-            int index = styleAttribute.getKey().intValue();
-
-            String name = styleAttribute.getValue();
-
-            // get the value from the style, or its parent styles.
-            IResourceValue resValue = findItemInStyle(style, name);
-
-            // resolve it to make sure there are no references left.
-            ta.bridgeSetValue(index, name, resolveResValue(resValue));
-        }
-
-        ta.sealArray();
-
-        return ta;
-    }
-
-
-    /**
-     * Resolves the value of a resource, if the value references a theme or resource value.
-     * <p/>
-     * This method ensures that it returns a {@link IResourceValue} object that does not
-     * reference another resource.
-     * If the resource cannot be resolved, it returns <code>null</code>.
-     * <p/>
-     * If a value that does not need to be resolved is given, the method will return a new
-     * instance of IResourceValue that contains the input value.
-     *
-     * @param type the type of the resource
-     * @param name the name of the attribute containing this value.
-     * @param value the resource value, or reference to resolve
-     * @return the resolved resource value or <code>null</code> if it failed to resolve it.
-     */
-    private IResourceValue resolveValue(String type, String name, String value) {
-        if (value == null) {
-            return null;
-        }
-
-        // get the IResourceValue referenced by this value
-        IResourceValue resValue = findResValue(value, false /*forceFrameworkOnly*/);
-
-        // if resValue is null, but value is not null, this means it was not a reference.
-        // we return the name/value wrapper in a IResourceValue
-        if (resValue == null) {
-            return new ResourceValue(type, name, value);
-        }
-
-        // we resolved a first reference, but we need to make sure this isn't a reference also.
-        return resolveResValue(resValue);
-    }
-
-    /**
-     * Returns the {@link IResourceValue} referenced by the value of <var>value</var>.
-     * <p/>
-     * This method ensures that it returns a {@link IResourceValue} object that does not
-     * reference another resource.
-     * If the resource cannot be resolved, it returns <code>null</code>.
-     * <p/>
-     * If a value that does not need to be resolved is given, the method will return the input
-     * value.
-     *
-     * @param value the value containing the reference to resolve.
-     * @return a {@link IResourceValue} object or <code>null</code>
-     */
-    IResourceValue resolveResValue(IResourceValue value) {
-        if (value == null) {
-            return null;
-        }
-
-        // if the resource value is a style, we simply return it.
-        if (value instanceof IStyleResourceValue) {
-            return value;
-        }
-
-        // else attempt to find another IResourceValue referenced by this one.
-        IResourceValue resolvedValue = findResValue(value.getValue(), value.isFramework());
-
-        // if the value did not reference anything, then we simply return the input value
-        if (resolvedValue == null) {
-            return value;
-        }
-
-        // otherwise, we attempt to resolve this new value as well
-        return resolveResValue(resolvedValue);
-    }
-
-    /**
-     * Searches for, and returns a {@link IResourceValue} by its reference.
-     * <p/>
-     * The reference format can be:
-     * <pre>@resType/resName</pre>
-     * <pre>@android:resType/resName</pre>
-     * <pre>@resType/android:resName</pre>
-     * <pre>?resType/resName</pre>
-     * <pre>?android:resType/resName</pre>
-     * <pre>?resType/android:resName</pre>
-     * Any other string format will return <code>null</code>.
-     * <p/>
-     * The actual format of a reference is <pre>@[namespace:]resType/resName</pre> but this method
-     * only support the android namespace.
-     *
-     * @param reference the resource reference to search for.
-     * @param forceFrameworkOnly if true all references are considered to be toward framework
-     *      resource even if the reference does not include the android: prefix.
-     * @return a {@link IResourceValue} or <code>null</code>.
-     */
-    IResourceValue findResValue(String reference, boolean forceFrameworkOnly) {
-        if (reference == null) {
-            return null;
-        }
-        if (reference.startsWith(BridgeConstants.PREFIX_THEME_REF)) {
-            // no theme? no need to go further!
-            if (mThemeValues == null) {
-                return null;
-            }
-
-            boolean frameworkOnly = false;
-
-            // eleminate the prefix from the string
-            if (reference.startsWith(BridgeConstants.PREFIX_ANDROID_THEME_REF)) {
-                frameworkOnly = true;
-                reference = reference.substring(BridgeConstants.PREFIX_ANDROID_THEME_REF.length());
-            } else {
-                reference = reference.substring(BridgeConstants.PREFIX_THEME_REF.length());
-            }
-
-            // at this point, value can contain type/name (drawable/foo for instance).
-            // split it to make sure.
-            String[] segments = reference.split("\\/");
-
-            // we look for the referenced item name.
-            String referenceName = null;
-
-            if (segments.length == 2) {
-                // there was a resType in the reference. If it's attr, we ignore it
-                // else, we assert for now.
-                if (BridgeConstants.RES_ATTR.equals(segments[0])) {
-                    referenceName = segments[1];
-                } else {
-                    // At this time, no support for ?type/name where type is not "attr"
-                    return null;
-                }
-            } else {
-                // it's just an item name.
-                referenceName = segments[0];
-            }
-
-            // now we look for android: in the referenceName in order to support format
-            // such as: ?attr/android:name
-            if (referenceName.startsWith(BridgeConstants.PREFIX_ANDROID)) {
-                frameworkOnly = true;
-                referenceName = referenceName.substring(BridgeConstants.PREFIX_ANDROID.length());
-            }
-
-            // Now look for the item in the theme, starting with the current one.
-            if (frameworkOnly) {
-                // FIXME for now we do the same as if it didn't specify android:
-                return findItemInStyle(mThemeValues, referenceName);
-            }
-
-            return findItemInStyle(mThemeValues, referenceName);
-        } else if (reference.startsWith(BridgeConstants.PREFIX_RESOURCE_REF)) {
-            boolean frameworkOnly = false;
-
-            // check for the specific null reference value.
-            if (BridgeConstants.REFERENCE_NULL.equals(reference)) {
-                return null;
-            }
-
-            // Eliminate the prefix from the string.
-            if (reference.startsWith(BridgeConstants.PREFIX_ANDROID_RESOURCE_REF)) {
-                frameworkOnly = true;
-                reference = reference.substring(
-                        BridgeConstants.PREFIX_ANDROID_RESOURCE_REF.length());
-            } else {
-                reference = reference.substring(BridgeConstants.PREFIX_RESOURCE_REF.length());
-            }
-
-            // at this point, value contains type/[android:]name (drawable/foo for instance)
-            String[] segments = reference.split("\\/");
-
-            // now we look for android: in the resource name in order to support format
-            // such as: @drawable/android:name
-            if (segments[1].startsWith(BridgeConstants.PREFIX_ANDROID)) {
-                frameworkOnly = true;
-                segments[1] = segments[1].substring(BridgeConstants.PREFIX_ANDROID.length());
-            }
-
-            return findResValue(segments[0], segments[1],
-                    forceFrameworkOnly ? true :frameworkOnly);
-        }
-
-        // Looks like the value didn't reference anything. Return null.
-        return null;
-    }
-
-    /**
-     * Searches for, and returns a {@link IResourceValue} by its name, and type.
-     * @param resType the type of the resource
-     * @param resName  the name of the resource
-     * @param frameworkOnly if <code>true</code>, the method does not search in the
-     * project resources
-     */
-    private IResourceValue findResValue(String resType, String resName, boolean frameworkOnly) {
-        // map of IResouceValue for the given type
-        Map<String, IResourceValue> typeMap;
-
-        // if allowed, search in the project resources first.
-        if (frameworkOnly == false) {
-            typeMap = mProjectResources.get(resType);
-            if (typeMap != null) {
-                IResourceValue item = typeMap.get(resName);
-                if (item != null) {
-                    return item;
-                }
-            }
-        }
-
-        // now search in the framework resources.
-        typeMap = mFrameworkResources.get(resType);
-        if (typeMap != null) {
-            IResourceValue item = typeMap.get(resName);
-            if (item != null) {
-                return item;
-            }
-        }
-
-        // didn't find the resource anywhere.
-        return null;
-    }
-
-    /**
-     * Returns a framework resource by type and name. The returned resource is resolved.
-     * @param resourceType the type of the resource
-     * @param resourceName the name of the resource
-     */
-    public IResourceValue getFrameworkResource(String resourceType, String resourceName) {
-        return getResource(resourceType, resourceName, mFrameworkResources);
-    }
-
-    /**
-     * Returns a project resource by type and name. The returned resource is resolved.
-     * @param resourceType the type of the resource
-     * @param resourceName the name of the resource
-     */
-    public IResourceValue getProjectResource(String resourceType, String resourceName) {
-        return getResource(resourceType, resourceName, mProjectResources);
-    }
-
-    IResourceValue getResource(String resourceType, String resourceName,
-            Map<String, Map<String, IResourceValue>> resourceRepository) {
-        Map<String, IResourceValue> typeMap = resourceRepository.get(resourceType);
-        if (typeMap != null) {
-            IResourceValue item = typeMap.get(resourceName);
-            if (item != null) {
-                item = resolveResValue(item);
-                return item;
-            }
-        }
-
-        // didn't find the resource anywhere.
-        return null;
-
-    }
-
-    /**
-     * Returns the {@link IResourceValue} matching a given name in a given style. If the
-     * item is not directly available in the style, the method looks in its parent style.
-     * @param style the style to search in
-     * @param itemName the name of the item to search for.
-     * @return the {@link IResourceValue} object or <code>null</code>
-     */
-    IResourceValue findItemInStyle(IStyleResourceValue style, String itemName) {
-        IResourceValue item = style.findItem(itemName);
-
-        // if we didn't find it, we look in the parent style (if applicable)
-        if (item == null && mStyleInheritanceMap != null) {
-            IStyleResourceValue parentStyle = mStyleInheritanceMap.get(style);
-            if (parentStyle != null) {
-                return findItemInStyle(parentStyle, itemName);
-            }
-        }
-
-        return item;
-    }
-
-    /**
-     * The input int[] attrs is one of com.android.internal.R.styleable fields where the name
-     * of the field is the style being referenced and the array contains one index per attribute.
-     * <p/>
-     * searchAttrs() finds all the names of the attributes referenced so for example if
-     * attrs == com.android.internal.R.styleable.View, this returns the list of the "xyz" where
-     * there's a field com.android.internal.R.styleable.View_xyz and the field value is the index
-     * that is used to reference the attribute later in the TypedArray.
-     *
-     * @param attrs An attribute array reference given to obtainStyledAttributes.
-     * @return A sorted map Attribute-Value to Attribute-Name for all attributes declared by the
-     *         attribute array. Returns null if nothing is found.
-     */
-    private TreeMap<Integer,String> searchAttrs(int[] attrs, boolean[] outFrameworkFlag) {
-        // get the name of the array from the framework resources
-        String arrayName = Bridge.resolveResourceValue(attrs);
-        if (arrayName != null) {
-            // if we found it, get the name of each of the int in the array.
-            TreeMap<Integer,String> attributes = new TreeMap<Integer, String>();
-            for (int i = 0 ; i < attrs.length ; i++) {
-                String[] info = Bridge.resolveResourceValue(attrs[i]);
-                if (info != null) {
-                    attributes.put(i, info[0]);
-                } else {
-                    // FIXME Not sure what we should be doing here...
-                    attributes.put(i, null);
-                }
-            }
-
-            if (outFrameworkFlag != null) {
-                outFrameworkFlag[0] = true;
-            }
-
-            return attributes;
-        }
-
-        // if the name was not found in the framework resources, look in the project
-        // resources
-        arrayName = mProjectCallback.resolveResourceValue(attrs);
-        if (arrayName != null) {
-            TreeMap<Integer,String> attributes = new TreeMap<Integer, String>();
-            for (int i = 0 ; i < attrs.length ; i++) {
-                String[] info = mProjectCallback.resolveResourceValue(attrs[i]);
-                if (info != null) {
-                    attributes.put(i, info[0]);
-                } else {
-                    // FIXME Not sure what we should be doing here...
-                    attributes.put(i, null);
-                }
-            }
-
-            if (outFrameworkFlag != null) {
-                outFrameworkFlag[0] = false;
-            }
-
-            return attributes;
-        }
-
-        return null;
-    }
-
-    /**
-     * Searches for the attribute referenced by its internal id.
-     *
-     * @param attr An attribute reference given to obtainStyledAttributes such as defStyle.
-     * @return The unique name of the attribute, if found, e.g. "buttonStyle". Returns null
-     *         if nothing is found.
-     */
-    public String searchAttr(int attr) {
-        String[] info = Bridge.resolveResourceValue(attr);
-        if (info != null) {
-            return info[0];
-        }
-
-        info = mProjectCallback.resolveResourceValue(attr);
-        if (info != null) {
-            return info[0];
-        }
-
-        return null;
-    }
-
-    int getDynamicIdByStyle(IStyleResourceValue resValue) {
-        if (mDynamicIdToStyleMap == null) {
-            // create the maps.
-            mDynamicIdToStyleMap = new HashMap<Integer, IStyleResourceValue>();
-            mStyleToDynamicIdMap = new HashMap<IStyleResourceValue, Integer>();
-        }
-
-        // look for an existing id
-        Integer id = mStyleToDynamicIdMap.get(resValue);
-
-        if (id == null) {
-            // generate a new id
-            id = Integer.valueOf(++mDynamicIdGenerator);
-
-            // and add it to the maps.
-            mDynamicIdToStyleMap.put(id, resValue);
-            mStyleToDynamicIdMap.put(resValue, id);
-        }
-
-        return id;
-    }
-
-    private IStyleResourceValue getStyleByDynamicId(int i) {
-        if (mDynamicIdToStyleMap != null) {
-            return mDynamicIdToStyleMap.get(i);
-        }
-
-        return null;
-    }
-
-    int getFrameworkIdValue(String idName, int defValue) {
-        Integer value = Bridge.getResourceValue(BridgeConstants.RES_ID, idName);
-        if (value != null) {
-            return value.intValue();
-        }
-
-        return defValue;
-    }
-
-    int getProjectIdValue(String idName, int defValue) {
-        if (mProjectCallback != null) {
-            Integer value = mProjectCallback.getResourceValue(BridgeConstants.RES_ID, idName);
-            if (value != null) {
-                return value.intValue();
-            }
-        }
-
-        return defValue;
-    }
-
-    //------------ NOT OVERRIDEN --------------------
-
-    @Override
-    public boolean bindService(Intent arg0, ServiceConnection arg1, int arg2) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public int checkCallingOrSelfPermission(String arg0) {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public int checkCallingOrSelfUriPermission(Uri arg0, int arg1) {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public int checkCallingPermission(String arg0) {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public int checkCallingUriPermission(Uri arg0, int arg1) {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public int checkPermission(String arg0, int arg1, int arg2) {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3) {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public int checkUriPermission(Uri arg0, String arg1, String arg2, int arg3,
-            int arg4, int arg5) {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    @Override
-    public void clearWallpaper() {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public Context createPackageContext(String arg0, int arg1) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public String[] databaseList() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean deleteDatabase(String arg0) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean deleteFile(String arg0) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void enforceCallingOrSelfPermission(String arg0, String arg1) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void enforceCallingOrSelfUriPermission(Uri arg0, int arg1,
-            String arg2) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void enforceCallingPermission(String arg0, String arg1) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void enforceCallingUriPermission(Uri arg0, int arg1, String arg2) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void enforcePermission(String arg0, int arg1, int arg2, String arg3) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void enforceUriPermission(Uri arg0, int arg1, int arg2, int arg3,
-            String arg4) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void enforceUriPermission(Uri arg0, String arg1, String arg2,
-            int arg3, int arg4, int arg5, String arg6) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public String[] fileList() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public AssetManager getAssets() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public File getCacheDir() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public File getExternalCacheDir() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public ContentResolver getContentResolver() {
-        if (mContentResolver == null) {
-            mContentResolver = new BridgeContentResolver(this);
-        }
-        return mContentResolver;
-    }
-
-    @Override
-    public File getDatabasePath(String arg0) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public File getDir(String arg0, int arg1) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public File getFileStreamPath(String arg0) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public File getFilesDir() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public File getExternalFilesDir(String type) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public String getPackageCodePath() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public PackageManager getPackageManager() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public String getPackageName() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public ApplicationInfo getApplicationInfo() {
-        return new ApplicationInfo();
-    }
-
-    @Override
-    public String getPackageResourcePath() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public File getSharedPrefsFile(String name) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public SharedPreferences getSharedPreferences(String arg0, int arg1) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Drawable getWallpaper() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public int getWallpaperDesiredMinimumWidth() {
-        return -1;
-    }
-
-    @Override
-    public int getWallpaperDesiredMinimumHeight() {
-        return -1;
-    }
-
-    @Override
-    public void grantUriPermission(String arg0, Uri arg1, int arg2) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @SuppressWarnings("unused")
-    @Override
-    public FileInputStream openFileInput(String arg0)
-            throws FileNotFoundException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @SuppressWarnings("unused")
-    @Override
-    public FileOutputStream openFileOutput(String arg0, int arg1)
-            throws FileNotFoundException {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1,
-            CursorFactory arg2) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Drawable peekWallpaper() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1,
-            String arg2, Handler arg3) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void removeStickyBroadcast(Intent arg0) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void revokeUriPermission(Uri arg0, int arg1) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void sendBroadcast(Intent arg0) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void sendBroadcast(Intent arg0, String arg1) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void sendOrderedBroadcast(Intent arg0, String arg1) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void sendOrderedBroadcast(Intent arg0, String arg1,
-            BroadcastReceiver arg2, Handler arg3, int arg4, String arg5,
-            Bundle arg6) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void sendStickyBroadcast(Intent arg0) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void sendStickyOrderedBroadcast(Intent intent,
-            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
-           Bundle initialExtras) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setTheme(int arg0) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @SuppressWarnings("unused")
-    @Override
-    public void setWallpaper(Bitmap arg0) throws IOException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @SuppressWarnings("unused")
-    @Override
-    public void setWallpaper(InputStream arg0) throws IOException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void startActivity(Intent arg0) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void startIntentSender(IntentSender intent,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
-            throws IntentSender.SendIntentException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public boolean startInstrumentation(ComponentName arg0, String arg1,
-            Bundle arg2) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public ComponentName startService(Intent arg0) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean stopService(Intent arg0) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void unbindService(ServiceConnection arg0) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void unregisterReceiver(BroadcastReceiver arg0) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public Context getApplicationContext() {
-        throw new UnsupportedOperationException();
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
new file mode 100644
index 0000000..bf22c4d
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge;
+
+import com.android.ide.common.rendering.api.IAnimationListener;
+import com.android.ide.common.rendering.api.ILayoutPullParser;
+import com.android.ide.common.rendering.api.RenderParams;
+import com.android.ide.common.rendering.api.RenderSession;
+import com.android.ide.common.rendering.api.Result;
+import com.android.ide.common.rendering.api.ViewInfo;
+import com.android.ide.common.rendering.api.Result.Status;
+import com.android.layoutlib.bridge.impl.RenderSessionImpl;
+
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+
+import java.awt.image.BufferedImage;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An implementation of {@link RenderSession}.
+ *
+ * This is a pretty basic class that does almost nothing. All of the work is done in
+ * {@link RenderSessionImpl}.
+ *
+ */
+public class BridgeRenderSession extends RenderSession {
+
+    private final RenderSessionImpl mSession;
+    private Result mLastResult;
+
+    @Override
+    public Result getResult() {
+        return mLastResult;
+    }
+
+    @Override
+    public BufferedImage getImage() {
+        return mSession.getImage();
+    }
+
+    @Override
+    public boolean isAlphaChannelImage() {
+        return mSession.isAlphaChannelImage();
+    }
+
+    @Override
+    public List<ViewInfo> getRootViews() {
+        return mSession.getViewInfos();
+    }
+
+    @Override
+    public Map<String, String> getDefaultProperties(Object viewObject) {
+        return mSession.getDefaultProperties(viewObject);
+    }
+
+    @Override
+    public Result getProperty(Object objectView, String propertyName) {
+        // TODO Auto-generated method stub
+        return super.getProperty(objectView, propertyName);
+    }
+
+    @Override
+    public Result setProperty(Object objectView, String propertyName, String propertyValue) {
+        // TODO Auto-generated method stub
+        return super.setProperty(objectView, propertyName, propertyValue);
+    }
+
+    @Override
+    public Result getViewParent(Object viewObject) {
+        if (viewObject instanceof View) {
+            return Status.SUCCESS.createResult(((View)viewObject).getParent());
+        }
+
+        throw new IllegalArgumentException("viewObject is not a View");
+    }
+
+    @Override
+    public Result getViewIndex(Object viewObject) {
+        if (viewObject instanceof View) {
+            View view = (View) viewObject;
+            ViewParent parentView = view.getParent();
+
+            if (parentView instanceof ViewGroup) {
+                Status.SUCCESS.createResult(((ViewGroup) parentView).indexOfChild(view));
+            }
+
+            return Status.SUCCESS.createResult();
+        }
+
+        throw new IllegalArgumentException("viewObject is not a View");
+    }
+
+    @Override
+    public Result render(long timeout) {
+        try {
+            Bridge.prepareThread();
+            mLastResult = mSession.acquire(timeout);
+            if (mLastResult.isSuccess()) {
+                mLastResult = mSession.render(false /*freshRender*/);
+            }
+        } finally {
+            mSession.release();
+            Bridge.cleanupThread();
+        }
+
+        return mLastResult;
+    }
+
+    @Override
+    public Result animate(Object targetObject, String animationName,
+            boolean isFrameworkAnimation, IAnimationListener listener) {
+        // Animation is only supported in API 11+
+        return super.animate(targetObject, animationName, isFrameworkAnimation, listener);
+    }
+
+    @Override
+    public Result insertChild(Object parentView, ILayoutPullParser childXml, int index,
+            IAnimationListener listener) {
+        if (parentView instanceof ViewGroup == false) {
+            throw new IllegalArgumentException("parentView is not a ViewGroup");
+        }
+
+        try {
+            Bridge.prepareThread();
+            mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
+            if (mLastResult.isSuccess()) {
+                mLastResult = mSession.insertChild((ViewGroup) parentView, childXml, index,
+                        listener);
+            }
+        } finally {
+            mSession.release();
+            Bridge.cleanupThread();
+        }
+
+        return mLastResult;
+    }
+
+
+    @Override
+    public Result moveChild(Object parentView, Object childView, int index,
+            Map<String, String> layoutParams, IAnimationListener listener) {
+        if (parentView instanceof ViewGroup == false) {
+            throw new IllegalArgumentException("parentView is not a ViewGroup");
+        }
+        if (childView instanceof View == false) {
+            throw new IllegalArgumentException("childView is not a View");
+        }
+
+        try {
+            Bridge.prepareThread();
+            mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
+            if (mLastResult.isSuccess()) {
+                mLastResult = mSession.moveChild((ViewGroup) parentView, (View) childView, index,
+                        layoutParams, listener);
+            }
+        } finally {
+            mSession.release();
+            Bridge.cleanupThread();
+        }
+
+        return mLastResult;
+    }
+
+    @Override
+    public Result removeChild(Object childView, IAnimationListener listener) {
+        if (childView instanceof View == false) {
+            throw new IllegalArgumentException("childView is not a View");
+        }
+
+        try {
+            Bridge.prepareThread();
+            mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
+            if (mLastResult.isSuccess()) {
+                mLastResult = mSession.removeChild((View) childView, listener);
+            }
+        } finally {
+            mSession.release();
+            Bridge.cleanupThread();
+        }
+
+        return mLastResult;
+    }
+
+    @Override
+    public void dispose() {
+    }
+
+    /*package*/ BridgeRenderSession(RenderSessionImpl scene, Result lastResult) {
+        mSession = scene;
+        if (scene != null) {
+            mSession.setScene(this);
+        }
+        mLastResult = lastResult;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/LayoutResult.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/LayoutResult.java
deleted file mode 100644
index c4c5225..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/LayoutResult.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import com.android.layoutlib.api.ILayoutResult;
-
-import java.awt.image.BufferedImage;
-
-/**
- * Implementation of {@link ILayoutResult}
- */
-public final class LayoutResult implements ILayoutResult {
-
-    private final ILayoutViewInfo mRootView;
-    private final BufferedImage mImage;
-    private final int mSuccess;
-    private final String mErrorMessage;
-
-    /**
-     * Creates a {@link #SUCCESS} {@link ILayoutResult} with the specified params
-     * @param rootView
-     * @param image
-     */
-    public LayoutResult(ILayoutViewInfo rootView, BufferedImage image) {
-        mSuccess = SUCCESS;
-        mErrorMessage = null;
-        mRootView = rootView;
-        mImage = image;
-    }
-    
-    /**
-     * Creates a LayoutResult with a specific success code and associated message
-     * @param code
-     * @param message
-     */
-    public LayoutResult(int code, String message) {
-        mSuccess = code;
-        mErrorMessage = message;
-        mRootView = null;
-        mImage = null;
-    }
-
-    public int getSuccess() {
-        return mSuccess;
-    }
-
-    public String getErrorMessage() {
-        return mErrorMessage;
-    }
-
-    public BufferedImage getImage() {
-        return mImage;
-    }
-
-    public ILayoutViewInfo getRootView() {
-        return mRootView;
-    }
-    
-    /**
-     * Implementation of {@link ILayoutResult.ILayoutViewInfo}
-     */
-    public static final class LayoutViewInfo implements ILayoutViewInfo {
-        private final Object mKey;
-        private final String mName;
-        private final int mLeft;
-        private final int mRight;
-        private final int mTop;
-        private final int mBottom;
-        private ILayoutViewInfo[] mChildren;
-
-        public LayoutViewInfo(String name, Object key, int left, int top, int right, int bottom) {
-            mName = name;
-            mKey = key;
-            mLeft = left;
-            mRight = right;
-            mTop = top;
-            mBottom = bottom;
-        }
-        
-        public void setChildren(ILayoutViewInfo[] children) {
-            mChildren = children;
-        }
-
-        public ILayoutViewInfo[] getChildren() {
-            return mChildren;
-        }
-
-        public Object getViewKey() {
-            return mKey;
-        }
-
-        public String getName() {
-            return mName;
-        }
-
-        public int getLeft() {
-            return mLeft;
-        }
-
-        public int getTop() {
-            return mTop;
-        }
-
-        public int getRight() {
-            return mRight;
-        }
-
-        public int getBottom() {
-            return mBottom;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/NinePatchDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/NinePatchDrawable.java
deleted file mode 100644
index abbf2f0..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/NinePatchDrawable.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import com.android.ninepatch.NinePatch;
-
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-
-public class NinePatchDrawable extends Drawable {
-
-    private NinePatch m9Patch;
-
-    NinePatchDrawable(NinePatch ninePatch) {
-        m9Patch = ninePatch;
-    }
-
-    @Override
-    public int getMinimumWidth() {
-        return m9Patch.getWidth();
-    }
-
-    @Override
-    public int getMinimumHeight() {
-        return m9Patch.getHeight();
-    }
-
-    /**
-     * Return the intrinsic width of the underlying drawable object.  Returns
-     * -1 if it has no intrinsic width, such as with a solid color.
-     */
-    @Override
-    public int getIntrinsicWidth() {
-        return m9Patch.getWidth();
-    }
-
-    /**
-     * Return the intrinsic height of the underlying drawable object. Returns
-     * -1 if it has no intrinsic height, such as with a solid color.
-     */
-    @Override
-    public int getIntrinsicHeight() {
-        return m9Patch.getHeight();
-    }
-
-    /**
-     * Return in padding the insets suggested by this Drawable for placing
-     * content inside the drawable's bounds. Positive values move toward the
-     * center of the Drawable (set Rect.inset). Returns true if this drawable
-     * actually has a padding, else false. When false is returned, the padding
-     * is always set to 0.
-     */
-    @Override
-    public boolean getPadding(Rect padding) {
-        int[] padd = new int[4];
-        m9Patch.getPadding(padd);
-        padding.left = padd[0];
-        padding.top = padd[1];
-        padding.right = padd[2];
-        padding.bottom = padd[3];
-        return true;
-    }
-
-    @Override
-    public void draw(Canvas canvas) {
-        Rect r = getBounds();
-        m9Patch.draw(canvas.getGraphics2d(), r.left, r.top, r.width(), r.height());
-
-        return;
-    }
-
-
-    // ----------- Not implemented methods ---------------
-
-
-    @Override
-    public int getOpacity() {
-        // FIXME
-        return 0xFF;
-    }
-
-    @Override
-    public void setAlpha(int arg0) {
-        // FIXME !
-    }
-
-    @Override
-    public void setColorFilter(ColorFilter arg0) {
-        // FIXME
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java
deleted file mode 100644
index f624753..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import com.android.layoutlib.api.IDensityBasedResourceValue;
-import com.android.layoutlib.api.IResourceValue;
-import com.android.layoutlib.api.IDensityBasedResourceValue.Density;
-import com.android.ninepatch.NinePatch;
-
-import org.kxml2.io.KXmlParser;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.util.TypedValue;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Helper class to provide various convertion method used in handling android resources.
- */
-public final class ResourceHelper {
-
-    private final static Pattern sFloatPattern = Pattern.compile("(-?[0-9]+(?:\\.[0-9]+)?)(.*)");
-    private final static float[] sFloatOut = new float[1];
-
-    private final static TypedValue mValue = new TypedValue();
-
-    /**
-     * Returns the color value represented by the given string value
-     * @param value the color value
-     * @return the color as an int
-     * @throw NumberFormatException if the conversion failed.
-     */
-    static int getColor(String value) {
-        if (value != null) {
-            if (value.startsWith("#") == false) {
-                throw new NumberFormatException();
-            }
-
-            value = value.substring(1);
-
-            // make sure it's not longer than 32bit
-            if (value.length() > 8) {
-                throw new NumberFormatException();
-            }
-
-            if (value.length() == 3) { // RGB format
-                char[] color = new char[8];
-                color[0] = color[1] = 'F';
-                color[2] = color[3] = value.charAt(0);
-                color[4] = color[5] = value.charAt(1);
-                color[6] = color[7] = value.charAt(2);
-                value = new String(color);
-            } else if (value.length() == 4) { // ARGB format
-                char[] color = new char[8];
-                color[0] = color[1] = value.charAt(0);
-                color[2] = color[3] = value.charAt(1);
-                color[4] = color[5] = value.charAt(2);
-                color[6] = color[7] = value.charAt(3);
-                value = new String(color);
-            } else if (value.length() == 6) {
-                value = "FF" + value;
-            }
-
-            // this is a RRGGBB or AARRGGBB value
-
-            // Integer.parseInt will fail to parse strings like "ff191919", so we use
-            // a Long, but cast the result back into an int, since we know that we're only
-            // dealing with 32 bit values.
-            return (int)Long.parseLong(value, 16);
-        }
-
-        throw new NumberFormatException();
-    }
-
-    /**
-     * Returns a drawable from the given value.
-     * @param value The value that contains a path to a 9 patch, a bitmap or a xml based drawable,
-     * or an hexadecimal color
-     * @param context
-     * @param isFramework indicates whether the resource is a framework resources.
-     * Framework resources are cached, and loaded only once.
-     */
-    public static Drawable getDrawable(IResourceValue value, BridgeContext context, boolean isFramework) {
-        Drawable d = null;
-
-        String stringValue = value.getValue();
-
-        String lowerCaseValue = stringValue.toLowerCase();
-
-        if (lowerCaseValue.endsWith(NinePatch.EXTENSION_9PATCH)) {
-            File file = new File(stringValue);
-            if (file.isFile()) {
-                NinePatch ninePatch = Bridge.getCached9Patch(stringValue,
-                        isFramework ? null : context.getProjectKey());
-
-                if (ninePatch == null) {
-                    try {
-                        ninePatch = NinePatch.load(file.toURL(), false /* convert */);
-
-                        Bridge.setCached9Patch(stringValue, ninePatch,
-                                isFramework ? null : context.getProjectKey());
-                    } catch (MalformedURLException e) {
-                        // URL is wrong, we'll return null below
-                    } catch (IOException e) {
-                        // failed to read the file, we'll return null below.
-                    }
-                }
-
-                if (ninePatch != null) {
-                    return new NinePatchDrawable(ninePatch);
-                }
-            }
-
-            return null;
-        } else if (lowerCaseValue.endsWith(".xml")) {
-            // create a blockparser for the file
-            File f = new File(stringValue);
-            if (f.isFile()) {
-                try {
-                    // let the framework inflate the Drawable from the XML file.
-                    KXmlParser parser = new KXmlParser();
-                    parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-                    parser.setInput(new FileReader(f));
-
-                    d = Drawable.createFromXml(context.getResources(),
-                            new BridgeXmlBlockParser(parser, context, isFramework));
-                    return d;
-                } catch (XmlPullParserException e) {
-                    context.getLogger().error(e);
-                } catch (FileNotFoundException e) {
-                    // will not happen, since we pre-check
-                } catch (IOException e) {
-                    context.getLogger().error(e);
-                }
-            }
-
-            return null;
-        } else {
-            File bmpFile = new File(stringValue);
-            if (bmpFile.isFile()) {
-                try {
-                    Bitmap bitmap = Bridge.getCachedBitmap(stringValue,
-                            isFramework ? null : context.getProjectKey());
-
-                    if (bitmap == null) {
-                        bitmap = new Bitmap(bmpFile);
-                        try {
-                            bitmap.setDensity(Density.MEDIUM.getValue());
-                        } catch (NoClassDefFoundError error) {
-                            // look like we're running in an older version of ADT that doesn't
-                            // include the new layoutlib_api. Let's just ignore this, the drawing
-                            // will just be wrong.
-                        }
-                        Bridge.setCachedBitmap(stringValue, bitmap,
-                                isFramework ? null : context.getProjectKey());
-                    }
-
-                    try {
-                        if (value instanceof IDensityBasedResourceValue) {
-                            Density density = ((IDensityBasedResourceValue)value).getDensity();
-                            if (density != Density.MEDIUM) {
-                                // create a copy of the bitmap
-                                bitmap = Bitmap.createBitmap(bitmap);
-
-                                // apply the density
-                                bitmap.setDensity(density.getValue());
-                            }
-                        }
-                    } catch (NoClassDefFoundError error) {
-                        // look like we're running in an older version of ADT that doesn't include
-                        // the new layoutlib_api. Let's just ignore this, the drawing will just be
-                        // wrong.
-                    }
-
-                    return new BitmapDrawable(context.getResources(), bitmap);
-                } catch (IOException e) {
-                    // we'll return null below
-                    // TODO: log the error.
-                }
-            } else {
-                // attempt to get a color from the value
-                try {
-                    int color = getColor(stringValue);
-                    return new ColorDrawable(color);
-                } catch (NumberFormatException e) {
-                    // we'll return null below.
-                    // TODO: log the error
-                }
-            }
-        }
-
-        return null;
-    }
-
-
-    // ------- TypedValue stuff
-    // This is taken from //device/libs/utils/ResourceTypes.cpp
-
-    private static final class UnitEntry {
-        String name;
-        int type;
-        int unit;
-        float scale;
-
-        UnitEntry(String name, int type, int unit, float scale) {
-            this.name = name;
-            this.type = type;
-            this.unit = unit;
-            this.scale = scale;
-        }
-    }
-
-    private final static UnitEntry[] sUnitNames = new UnitEntry[] {
-        new UnitEntry("px", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_PX, 1.0f),
-        new UnitEntry("dip", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_DIP, 1.0f),
-        new UnitEntry("dp", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_DIP, 1.0f),
-        new UnitEntry("sp", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_SP, 1.0f),
-        new UnitEntry("pt", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_PT, 1.0f),
-        new UnitEntry("in", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_IN, 1.0f),
-        new UnitEntry("mm", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_MM, 1.0f),
-        new UnitEntry("%", TypedValue.TYPE_FRACTION, TypedValue.COMPLEX_UNIT_FRACTION, 1.0f/100),
-        new UnitEntry("%p", TypedValue.TYPE_FRACTION, TypedValue.COMPLEX_UNIT_FRACTION_PARENT, 1.0f/100),
-    };
-
-    /**
-     * Returns the raw value from the given string.
-     * This object is only valid until the next call on to {@link ResourceHelper}.
-     */
-    public static TypedValue getValue(String s) {
-        if (stringToFloat(s, mValue)) {
-            return mValue;
-        }
-
-        return null;
-    }
-
-    /**
-     * Convert the string into a {@link TypedValue}.
-     * @param s
-     * @param outValue
-     * @return true if success.
-     */
-    public static boolean stringToFloat(String s, TypedValue outValue) {
-        // remove the space before and after
-        s.trim();
-        int len = s.length();
-
-        if (len <= 0) {
-            return false;
-        }
-
-        // check that there's no non ascii characters.
-        char[] buf = s.toCharArray();
-        for (int i = 0 ; i < len ; i++) {
-            if (buf[i] > 255) {
-                return false;
-            }
-        }
-
-        // check the first character
-        if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.') {
-            return false;
-        }
-
-        // now look for the string that is after the float...
-        Matcher m = sFloatPattern.matcher(s);
-        if (m.matches()) {
-            String f_str = m.group(1);
-            String end = m.group(2);
-
-            float f;
-            try {
-                f = Float.parseFloat(f_str);
-            } catch (NumberFormatException e) {
-                // this shouldn't happen with the regexp above.
-                return false;
-            }
-
-            if (end.length() > 0 && end.charAt(0) != ' ') {
-                // Might be a unit...
-                if (parseUnit(end, outValue, sFloatOut)) {
-
-                    f *= sFloatOut[0];
-                    boolean neg = f < 0;
-                    if (neg) {
-                        f = -f;
-                    }
-                    long bits = (long)(f*(1<<23)+.5f);
-                    int radix;
-                    int shift;
-                    if ((bits&0x7fffff) == 0) {
-                        // Always use 23p0 if there is no fraction, just to make
-                        // things easier to read.
-                        radix = TypedValue.COMPLEX_RADIX_23p0;
-                        shift = 23;
-                    } else if ((bits&0xffffffffff800000L) == 0) {
-                        // Magnitude is zero -- can fit in 0 bits of precision.
-                        radix = TypedValue.COMPLEX_RADIX_0p23;
-                        shift = 0;
-                    } else if ((bits&0xffffffff80000000L) == 0) {
-                        // Magnitude can fit in 8 bits of precision.
-                        radix = TypedValue.COMPLEX_RADIX_8p15;
-                        shift = 8;
-                    } else if ((bits&0xffffff8000000000L) == 0) {
-                        // Magnitude can fit in 16 bits of precision.
-                        radix = TypedValue.COMPLEX_RADIX_16p7;
-                        shift = 16;
-                    } else {
-                        // Magnitude needs entire range, so no fractional part.
-                        radix = TypedValue.COMPLEX_RADIX_23p0;
-                        shift = 23;
-                    }
-                    int mantissa = (int)(
-                        (bits>>shift) & TypedValue.COMPLEX_MANTISSA_MASK);
-                    if (neg) {
-                        mantissa = (-mantissa) & TypedValue.COMPLEX_MANTISSA_MASK;
-                    }
-                    outValue.data |=
-                        (radix<<TypedValue.COMPLEX_RADIX_SHIFT)
-                        | (mantissa<<TypedValue.COMPLEX_MANTISSA_SHIFT);
-                    return true;
-                }
-                return false;
-            }
-
-            // make sure it's only spaces at the end.
-            end = end.trim();
-
-            if (end.length() == 0) {
-                if (outValue != null) {
-                    outValue.type = TypedValue.TYPE_FLOAT;
-                    outValue.data = Float.floatToIntBits(f);
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    private static boolean parseUnit(String str, TypedValue outValue, float[] outScale) {
-        str = str.trim();
-
-        for (UnitEntry unit : sUnitNames) {
-            if (unit.name.equals(str)) {
-                outValue.type = unit.type;
-                outValue.data = unit.unit << TypedValue.COMPLEX_UNIT_SHIFT;
-                outScale[0] = unit.scale;
-
-                return true;
-            }
-        }
-
-        return false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceValue.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceValue.java
deleted file mode 100644
index 01a4871..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceValue.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import com.android.layoutlib.api.IResourceValue;
-
-/**
- * Basic implementation of IResourceValue.
- */
-class ResourceValue implements IResourceValue {
-    private final String mType;
-    private final String mName;
-    private String mValue = null;
-    
-    ResourceValue(String name) {
-        mType = null;
-        mName = name;
-    }
-
-    public ResourceValue(String type, String name, String value) {
-        mType = type;
-        mName = name;
-        mValue = value;
-    }
-
-    public String getType() {
-        return mType;
-    }
-
-    public final String getName() {
-        return mName;
-    }
-    
-    public final String getValue() {
-        return mValue;
-    }
-    
-    public final void setValue(String value) {
-        mValue = value;
-    }
-    
-    public void replaceWith(ResourceValue value) {
-        mValue = value.mValue;
-    }
-
-    public boolean isFramework() {
-        // ResourceValue object created directly in the framework are used to describe
-        // non resolvable coming from the XML. Since they will never be cached (as they can't
-        // be a value pointing to a bitmap, or they'd be resolvable.), the return value deoes
-        // not matter.
-        return false;
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeAssetManager.java
similarity index 89%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeAssetManager.java
index 71803fc..a825060 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeAssetManager.java
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
+
+import com.android.layoutlib.bridge.Bridge;
 
 import android.content.res.AssetManager;
 
@@ -28,7 +30,7 @@
      * <p/>
      * {@link Bridge} calls this method after setting up a new bridge.
      */
-    /*package*/ static AssetManager initSystem() {
+    /*package*/ public static AssetManager initSystem() {
         if (!(AssetManager.sSystem instanceof BridgeAssetManager)) {
             // Note that AssetManager() creates a system AssetManager and we override it
             // with our BridgeAssetManager.
@@ -42,7 +44,7 @@
      * Clears the static {@link AssetManager#sSystem} to make sure we don't leave objects
      * around that would prevent us from unloading the library.
      */
-    /*package*/ static void clearSystem() {
+    public static void clearSystem() {
         AssetManager.sSystem = null;
     }
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
new file mode 100644
index 0000000..3835378
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.android;
+
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentValues;
+import android.content.IContentProvider;
+import android.content.OperationApplicationException;
+import android.content.res.AssetFileDescriptor;
+import android.database.Cursor;
+import android.database.CursorWindow;
+import android.database.IBulkCursor;
+import android.database.IContentObserver;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+
+/**
+ * Mock implementation of {@link IContentProvider}.
+ *
+ * TODO: never return null when the method is not supposed to. Return fake data instead.
+ */
+public final class BridgeContentProvider implements IContentProvider {
+
+    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> arg0)
+            throws RemoteException, OperationApplicationException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public int bulkInsert(Uri arg0, ContentValues[] arg1) throws RemoteException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    public IBulkCursor bulkQuery(Uri arg0, String[] arg1, String arg2, String[] arg3,
+            String arg4, IContentObserver arg5, CursorWindow arg6) throws RemoteException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Bundle call(String arg0, String arg1, Bundle arg2) throws RemoteException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public int delete(Uri arg0, String arg1, String[] arg2) throws RemoteException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    public String getType(Uri arg0) throws RemoteException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Uri insert(Uri arg0, ContentValues arg1) throws RemoteException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public AssetFileDescriptor openAssetFile(Uri arg0, String arg1) throws RemoteException,
+            FileNotFoundException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public ParcelFileDescriptor openFile(Uri arg0, String arg1) throws RemoteException,
+            FileNotFoundException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4)
+            throws RemoteException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3)
+            throws RemoteException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    public IBinder asBinder() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public String[] getStreamTypes(Uri arg0, String arg1) throws RemoteException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public AssetFileDescriptor openTypedAssetFile(Uri arg0, String arg1, Bundle arg2)
+            throws RemoteException, FileNotFoundException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
new file mode 100644
index 0000000..0257686
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.android;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.IContentProvider;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Bundle;
+
+/**
+ * A mock content resolver for the LayoutLib Bridge.
+ * <p/>
+ * It won't serve any actual data but it's good enough for all
+ * the widgets which expect to have a content resolver available via
+ * {@link BridgeContext#getContentResolver()}.
+ */
+public class BridgeContentResolver extends ContentResolver {
+
+    private BridgeContentProvider mProvider = null;
+
+    public BridgeContentResolver(Context context) {
+        super(context);
+    }
+
+    @Override
+    public IContentProvider acquireProvider(Context c, String name) {
+        if (mProvider == null) {
+            mProvider = new BridgeContentProvider();
+        }
+
+        return mProvider;
+    }
+
+    @Override
+    public IContentProvider acquireExistingProvider(Context c, String name) {
+        if (mProvider == null) {
+            mProvider = new BridgeContentProvider();
+        }
+
+        return mProvider;
+    }
+
+    @Override
+    public boolean releaseProvider(IContentProvider icp) {
+        // ignore
+        return false;
+    }
+
+    /**
+     * Stub for the layoutlib bridge content resolver.
+     */
+    @Override
+    public void registerContentObserver(Uri uri, boolean notifyForDescendents,
+            ContentObserver observer) {
+        // pass
+    }
+
+    /**
+     * Stub for the layoutlib bridge content resolver.
+     */
+    @Override
+    public void unregisterContentObserver(ContentObserver observer) {
+        // pass
+    }
+
+    /**
+     * Stub for the layoutlib bridge content resolver.
+     */
+    @Override
+    public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
+        // pass
+    }
+
+    /**
+     * Stub for the layoutlib bridge content resolver.
+     */
+    @Override
+    public void startSync(Uri uri, Bundle extras) {
+        // pass
+    }
+
+    /**
+     * Stub for the layoutlib bridge content resolver.
+     */
+    @Override
+    public void cancelSync(Uri uri) {
+        // pass
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
new file mode 100644
index 0000000..c4eee17
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -0,0 +1,1131 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.android;
+
+import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.RenderResources;
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.ide.common.rendering.api.StyleResourceValue;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.impl.Stack;
+import com.android.resources.ResourceType;
+import com.android.util.Pair;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.ServiceConnection;
+import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.AssetManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.Resources.Theme;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+
+/**
+ * Custom implementation of Context/Activity to handle non compiled resources.
+ */
+public final class BridgeContext extends Activity {
+
+    private Resources mSystemResources;
+    private final HashMap<View, Object> mViewKeyMap = new HashMap<View, Object>();
+    private final Object mProjectKey;
+    private final DisplayMetrics mMetrics;
+    private final RenderResources mRenderResources;
+    private final ApplicationInfo mApplicationInfo;
+
+    private final Map<Object, Map<String, String>> mDefaultPropMaps =
+        new IdentityHashMap<Object, Map<String,String>>();
+
+    // maps for dynamically generated id representing style objects (StyleResourceValue)
+    private Map<Integer, StyleResourceValue> mDynamicIdToStyleMap;
+    private Map<StyleResourceValue, Integer> mStyleToDynamicIdMap;
+    private int mDynamicIdGenerator = 0x01030000; // Base id for framework R.style
+
+    // cache for TypedArray generated from IStyleResourceValue object
+    private Map<int[], Map<Integer, TypedArray>> mTypedArrayCache;
+    private BridgeInflater mBridgeInflater;
+
+    private final IProjectCallback mProjectCallback;
+    private BridgeContentResolver mContentResolver;
+
+    private final Stack<BridgeXmlBlockParser> mParserStack = new Stack<BridgeXmlBlockParser>();
+
+    /**
+     * @param projectKey An Object identifying the project. This is used for the cache mechanism.
+     * @param metrics the {@link DisplayMetrics}.
+     * @param themeName The name of the theme to use.
+     * @param projectResources the resources of the project. The map contains (String, map) pairs
+     * where the string is the type of the resource reference used in the layout file, and the
+     * map contains (String, {@link }) pairs where the key is the resource name,
+     * and the value is the resource value.
+     * @param frameworkResources the framework resources. The map contains (String, map) pairs
+     * where the string is the type of the resource reference used in the layout file, and the map
+     * contains (String, {@link ResourceValue}) pairs where the key is the resource name, and the
+     * value is the resource value.
+     * @param styleInheritanceMap
+     * @param projectCallback
+     * @param targetSdkVersion the targetSdkVersion of the application.
+     */
+    public BridgeContext(Object projectKey, DisplayMetrics metrics,
+            RenderResources renderResources,
+            IProjectCallback projectCallback,
+            int targetSdkVersion) {
+        mProjectKey = projectKey;
+        mMetrics = metrics;
+        mProjectCallback = projectCallback;
+
+        mRenderResources = renderResources;
+
+        mApplicationInfo = new ApplicationInfo();
+        mApplicationInfo.targetSdkVersion = targetSdkVersion;
+    }
+
+    /**
+     * Initializes the {@link Resources} singleton to be linked to this {@link Context}, its
+     * {@link DisplayMetrics}, {@link Configuration}, and {@link IProjectCallback}.
+     *
+     * @see #disposeResources()
+     */
+    public void initResources() {
+        AssetManager assetManager = AssetManager.getSystem();
+        Configuration config = new Configuration();
+
+        mSystemResources = BridgeResources.initSystem(
+                this,
+                assetManager,
+                mMetrics,
+                config,
+                mProjectCallback);
+        mTheme = mSystemResources.newTheme();
+    }
+
+    /**
+     * Disposes the {@link Resources} singleton.
+     */
+    public void disposeResources() {
+        BridgeResources.disposeSystem();
+    }
+
+    public void setBridgeInflater(BridgeInflater inflater) {
+        mBridgeInflater = inflater;
+    }
+
+    public void addViewKey(View view, Object viewKey) {
+        mViewKeyMap.put(view, viewKey);
+    }
+
+    public Object getViewKey(View view) {
+        return mViewKeyMap.get(view);
+    }
+
+    public Object getProjectKey() {
+        return mProjectKey;
+    }
+
+    public DisplayMetrics getMetrics() {
+        return mMetrics;
+    }
+
+    public IProjectCallback getProjectCallback() {
+        return mProjectCallback;
+    }
+
+    public RenderResources getRenderResources() {
+        return mRenderResources;
+    }
+
+    public Map<String, String> getDefaultPropMap(Object key) {
+        return mDefaultPropMaps.get(key);
+    }
+
+    /**
+     * Adds a parser to the stack.
+     * @param parser the parser to add.
+     */
+    public void pushParser(BridgeXmlBlockParser parser) {
+        mParserStack.push(parser);
+    }
+
+    /**
+     * Removes the parser at the top of the stack
+     */
+    public void popParser() {
+        mParserStack.pop();
+    }
+
+    /**
+     * Returns the current parser at the top the of the stack.
+     * @return a parser or null.
+     */
+    public BridgeXmlBlockParser getCurrentParser() {
+        return mParserStack.peek();
+    }
+
+    /**
+     * Returns the previous parser.
+     * @return a parser or null if there isn't any previous parser
+     */
+    public BridgeXmlBlockParser getPreviousParser() {
+        if (mParserStack.size() < 2) {
+            return null;
+        }
+        return mParserStack.get(mParserStack.size() - 2);
+    }
+
+    public boolean resolveThemeAttribute(int resid, TypedValue outValue, boolean resolveRefs) {
+        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(resid);
+        if (resourceInfo == null) {
+            resourceInfo = mProjectCallback.resolveResourceId(resid);
+        }
+
+        if (resourceInfo == null) {
+            return false;
+        }
+
+        ResourceValue value = mRenderResources.findItemInTheme(resourceInfo.getSecond());
+        if (resolveRefs) {
+            value = mRenderResources.resolveResValue(value);
+        }
+
+        // check if this is a style resource
+        if (value instanceof StyleResourceValue) {
+            // get the id that will represent this style.
+            outValue.resourceId = getDynamicIdByStyle((StyleResourceValue)value);
+            return true;
+        }
+
+
+        int a;
+        // if this is a framework value.
+        if (value.isFramework()) {
+            // look for idName in the android R classes.
+            // use 0 a default res value as it's not a valid id value.
+            a = getFrameworkResourceValue(value.getResourceType(), value.getName(), 0 /*defValue*/);
+        } else {
+            // look for idName in the project R class.
+            // use 0 a default res value as it's not a valid id value.
+            a = getProjectResourceValue(value.getResourceType(), value.getName(), 0 /*defValue*/);
+        }
+
+        if (a != 0) {
+            outValue.resourceId = a;
+            return true;
+        }
+
+        return false;
+    }
+
+
+    // ------------- Activity Methods
+
+    @Override
+    public LayoutInflater getLayoutInflater() {
+        return mBridgeInflater;
+    }
+
+    // ------------ Context methods
+
+    @Override
+    public Resources getResources() {
+        return mSystemResources;
+    }
+
+    @Override
+    public Theme getTheme() {
+        return mTheme;
+    }
+
+    @Override
+    public ClassLoader getClassLoader() {
+        return this.getClass().getClassLoader();
+    }
+
+    @Override
+    public Object getSystemService(String service) {
+        if (LAYOUT_INFLATER_SERVICE.equals(service)) {
+            return mBridgeInflater;
+        }
+
+        // AutoCompleteTextView and MultiAutoCompleteTextView want a window
+        // service. We don't have any but it's not worth an exception.
+        if (WINDOW_SERVICE.equals(service)) {
+            return null;
+        }
+
+        // needed by SearchView
+        if (INPUT_METHOD_SERVICE.equals(service)) {
+            return null;
+        }
+
+        throw new UnsupportedOperationException("Unsupported Service: " + service);
+    }
+
+
+    @Override
+    public final TypedArray obtainStyledAttributes(int[] attrs) {
+        return createStyleBasedTypedArray(mRenderResources.getCurrentTheme(), attrs);
+    }
+
+    @Override
+    public final TypedArray obtainStyledAttributes(int resid, int[] attrs)
+            throws Resources.NotFoundException {
+        // get the StyleResourceValue based on the resId;
+        StyleResourceValue style = getStyleByDynamicId(resid);
+
+        if (style == null) {
+            throw new Resources.NotFoundException();
+        }
+
+        if (mTypedArrayCache == null) {
+            mTypedArrayCache = new HashMap<int[], Map<Integer,TypedArray>>();
+
+            Map<Integer, TypedArray> map = new HashMap<Integer, TypedArray>();
+            mTypedArrayCache.put(attrs, map);
+
+            BridgeTypedArray ta = createStyleBasedTypedArray(style, attrs);
+            map.put(resid, ta);
+
+            return ta;
+        }
+
+        // get the 2nd map
+        Map<Integer, TypedArray> map = mTypedArrayCache.get(attrs);
+        if (map == null) {
+            map = new HashMap<Integer, TypedArray>();
+            mTypedArrayCache.put(attrs, map);
+        }
+
+        // get the array from the 2nd map
+        TypedArray ta = map.get(resid);
+
+        if (ta == null) {
+            ta = createStyleBasedTypedArray(style, attrs);
+            map.put(resid, ta);
+        }
+
+        return ta;
+    }
+
+    @Override
+    public final TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs) {
+        return obtainStyledAttributes(set, attrs, 0, 0);
+    }
+
+    @Override
+    public TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs,
+            int defStyleAttr, int defStyleRes) {
+
+        Map<String, String> defaultPropMap = null;
+        boolean isPlatformFile = true;
+
+        // Hint: for XmlPullParser, attach source //DEVICE_SRC/dalvik/libcore/xml/src/java
+        if (set instanceof BridgeXmlBlockParser) {
+            BridgeXmlBlockParser parser = null;
+            parser = (BridgeXmlBlockParser)set;
+
+            isPlatformFile = parser.isPlatformFile();
+
+            Object key = parser.getViewCookie();
+            if (key != null) {
+                defaultPropMap = mDefaultPropMaps.get(key);
+                if (defaultPropMap == null) {
+                    defaultPropMap = new HashMap<String, String>();
+                    mDefaultPropMaps.put(key, defaultPropMap);
+                }
+            }
+
+        } else if (set instanceof BridgeLayoutParamsMapAttributes) {
+            // this is only for temp layout params generated dynamically, so this is never
+            // platform content.
+            isPlatformFile = false;
+        } else if (set != null) { // null parser is ok
+            // really this should not be happening since its instantiated in Bridge
+            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                    "Parser is not a BridgeXmlBlockParser!", null /*data*/);
+            return null;
+        }
+
+        boolean[] frameworkAttributes = new boolean[1];
+        TreeMap<Integer, String> styleNameMap = searchAttrs(attrs, frameworkAttributes);
+
+        BridgeTypedArray ta = ((BridgeResources) mSystemResources).newTypeArray(attrs.length,
+                isPlatformFile);
+
+        // resolve the defStyleAttr value into a IStyleResourceValue
+        StyleResourceValue defStyleValues = null;
+
+        // look for a custom style.
+        String customStyle = null;
+        if (set != null) {
+            customStyle = set.getAttributeValue(null /* namespace*/, "style");
+        }
+        if (customStyle != null) {
+            ResourceValue item = mRenderResources.findResValue(customStyle,
+                    false /*forceFrameworkOnly*/);
+
+            // resolve it in case it links to something else
+            item = mRenderResources.resolveResValue(item);
+
+            if (item instanceof StyleResourceValue) {
+                defStyleValues = (StyleResourceValue)item;
+            }
+        }
+
+        if (defStyleValues == null) {
+            if (defStyleAttr != 0) {
+                // get the name from the int.
+                String defStyleName = searchAttr(defStyleAttr);
+
+                if (defaultPropMap != null) {
+                    defaultPropMap.put("style", defStyleName);
+                }
+
+                // look for the style in the current theme, and its parent:
+                ResourceValue item = mRenderResources.findItemInTheme(defStyleName);
+
+                if (item != null) {
+                    // item is a reference to a style entry. Search for it.
+                    item = mRenderResources.findResValue(item.getValue(),
+                            false /*forceFrameworkOnly*/);
+
+                    if (item instanceof StyleResourceValue) {
+                        defStyleValues = (StyleResourceValue)item;
+                    }
+                } else {
+                    Bridge.getLog().error(null,
+                            String.format(
+                                    "Failed to find style '%s' in current theme", defStyleName),
+                            null /*data*/);
+                }
+            } else if (defStyleRes != 0) {
+                Pair<ResourceType, String> value = Bridge.resolveResourceId(defStyleRes);
+                if (value == null) {
+                    value = mProjectCallback.resolveResourceId(defStyleRes);
+                }
+
+                if (value != null) {
+                    if (value.getFirst() == ResourceType.STYLE) {
+                        // look for the style in the current theme, and its parent:
+                        ResourceValue item = mRenderResources.findItemInTheme(value.getSecond());
+                        if (item != null) {
+                            if (item instanceof StyleResourceValue) {
+                                if (defaultPropMap != null) {
+                                    defaultPropMap.put("style", item.getName());
+                                }
+
+                                defStyleValues = (StyleResourceValue)item;
+                            }
+                        } else {
+                            Bridge.getLog().error(null,
+                                    String.format(
+                                            "Style with id 0x%x (resolved to '%s') does not exist.",
+                                            defStyleRes, value.getSecond()),
+                                    null /*data*/);
+                        }
+                    } else {
+                        Bridge.getLog().error(null,
+                                String.format(
+                                        "Resouce id 0x%x is not of type STYLE (instead %s)",
+                                        defStyleRes, value.getFirst().toString()),
+                                null /*data*/);
+                    }
+                } else {
+                    Bridge.getLog().error(null,
+                            String.format(
+                                    "Failed to find style with id 0x%x in current theme",
+                                    defStyleRes),
+                            null /*data*/);
+                }
+            }
+        }
+
+        String namespace = BridgeConstants.NS_RESOURCES;
+        if (frameworkAttributes[0] == false) {
+            // need to use the application namespace
+            namespace = mProjectCallback.getNamespace();
+        }
+
+        if (styleNameMap != null) {
+            for (Entry<Integer, String> styleAttribute : styleNameMap.entrySet()) {
+                int index = styleAttribute.getKey().intValue();
+
+                String name = styleAttribute.getValue();
+                String value = null;
+                if (set != null) {
+                    value = set.getAttributeValue(namespace, name);
+                }
+
+                // if there's no direct value for this attribute in the XML, we look for default
+                // values in the widget defStyle, and then in the theme.
+                if (value == null) {
+                    ResourceValue resValue = null;
+
+                    // look for the value in the defStyle first (and its parent if needed)
+                    if (defStyleValues != null) {
+                        resValue = mRenderResources.findItemInStyle(defStyleValues, name);
+                    }
+
+                    // if the item is not present in the defStyle, we look in the main theme (and
+                    // its parent themes)
+                    if (resValue == null) {
+                        resValue = mRenderResources.findItemInTheme(name);
+                    }
+
+                    // if we found a value, we make sure this doesn't reference another value.
+                    // So we resolve it.
+                    if (resValue != null) {
+                        // put the first default value, before the resolution.
+                        if (defaultPropMap != null) {
+                            defaultPropMap.put(name, resValue.getValue());
+                        }
+
+                        resValue = mRenderResources.resolveResValue(resValue);
+                    }
+
+                    ta.bridgeSetValue(index, name, resValue);
+                } else {
+                    // there is a value in the XML, but we need to resolve it in case it's
+                    // referencing another resource or a theme value.
+                    ta.bridgeSetValue(index, name,
+                            mRenderResources.resolveValue(null, name, value, isPlatformFile));
+                }
+            }
+        }
+
+        ta.sealArray();
+
+        return ta;
+    }
+
+    @Override
+    public Looper getMainLooper() {
+        return Looper.myLooper();
+    }
+
+
+    // ------------- private new methods
+
+    /**
+     * Creates a {@link BridgeTypedArray} by filling the values defined by the int[] with the
+     * values found in the given style.
+     * @see #obtainStyledAttributes(int, int[])
+     */
+    private BridgeTypedArray createStyleBasedTypedArray(StyleResourceValue style, int[] attrs)
+            throws Resources.NotFoundException {
+        TreeMap<Integer, String> styleNameMap = searchAttrs(attrs, null);
+
+        BridgeTypedArray ta = ((BridgeResources) mSystemResources).newTypeArray(attrs.length,
+                false /* platformResourceFlag */);
+
+        // loop through all the values in the style map, and init the TypedArray with
+        // the style we got from the dynamic id
+        for (Entry<Integer, String> styleAttribute : styleNameMap.entrySet()) {
+            int index = styleAttribute.getKey().intValue();
+
+            String name = styleAttribute.getValue();
+
+            // get the value from the style, or its parent styles.
+            ResourceValue resValue = mRenderResources.findItemInStyle(style, name);
+
+            // resolve it to make sure there are no references left.
+            ta.bridgeSetValue(index, name, mRenderResources.resolveResValue(resValue));
+        }
+
+        ta.sealArray();
+
+        return ta;
+    }
+
+
+    /**
+     * The input int[] attrs is one of com.android.internal.R.styleable fields where the name
+     * of the field is the style being referenced and the array contains one index per attribute.
+     * <p/>
+     * searchAttrs() finds all the names of the attributes referenced so for example if
+     * attrs == com.android.internal.R.styleable.View, this returns the list of the "xyz" where
+     * there's a field com.android.internal.R.styleable.View_xyz and the field value is the index
+     * that is used to reference the attribute later in the TypedArray.
+     *
+     * @param attrs An attribute array reference given to obtainStyledAttributes.
+     * @return A sorted map Attribute-Value to Attribute-Name for all attributes declared by the
+     *         attribute array. Returns null if nothing is found.
+     */
+    private TreeMap<Integer,String> searchAttrs(int[] attrs, boolean[] outFrameworkFlag) {
+        // get the name of the array from the framework resources
+        String arrayName = Bridge.resolveResourceId(attrs);
+        if (arrayName != null) {
+            // if we found it, get the name of each of the int in the array.
+            TreeMap<Integer,String> attributes = new TreeMap<Integer, String>();
+            for (int i = 0 ; i < attrs.length ; i++) {
+                Pair<ResourceType, String> info = Bridge.resolveResourceId(attrs[i]);
+                if (info != null) {
+                    attributes.put(i, info.getSecond());
+                } else {
+                    // FIXME Not sure what we should be doing here...
+                    attributes.put(i, null);
+                }
+            }
+
+            if (outFrameworkFlag != null) {
+                outFrameworkFlag[0] = true;
+            }
+
+            return attributes;
+        }
+
+        // if the name was not found in the framework resources, look in the project
+        // resources
+        arrayName = mProjectCallback.resolveResourceId(attrs);
+        if (arrayName != null) {
+            TreeMap<Integer,String> attributes = new TreeMap<Integer, String>();
+            for (int i = 0 ; i < attrs.length ; i++) {
+                Pair<ResourceType, String> info = mProjectCallback.resolveResourceId(attrs[i]);
+                if (info != null) {
+                    attributes.put(i, info.getSecond());
+                } else {
+                    // FIXME Not sure what we should be doing here...
+                    attributes.put(i, null);
+                }
+            }
+
+            if (outFrameworkFlag != null) {
+                outFrameworkFlag[0] = false;
+            }
+
+            return attributes;
+        }
+
+        return null;
+    }
+
+    /**
+     * Searches for the attribute referenced by its internal id.
+     *
+     * @param attr An attribute reference given to obtainStyledAttributes such as defStyle.
+     * @return The unique name of the attribute, if found, e.g. "buttonStyle". Returns null
+     *         if nothing is found.
+     */
+    public String searchAttr(int attr) {
+        Pair<ResourceType, String> info = Bridge.resolveResourceId(attr);
+        if (info != null) {
+            return info.getSecond();
+        }
+
+        info = mProjectCallback.resolveResourceId(attr);
+        if (info != null) {
+            return info.getSecond();
+        }
+
+        return null;
+    }
+
+    int getDynamicIdByStyle(StyleResourceValue resValue) {
+        if (mDynamicIdToStyleMap == null) {
+            // create the maps.
+            mDynamicIdToStyleMap = new HashMap<Integer, StyleResourceValue>();
+            mStyleToDynamicIdMap = new HashMap<StyleResourceValue, Integer>();
+        }
+
+        // look for an existing id
+        Integer id = mStyleToDynamicIdMap.get(resValue);
+
+        if (id == null) {
+            // generate a new id
+            id = Integer.valueOf(++mDynamicIdGenerator);
+
+            // and add it to the maps.
+            mDynamicIdToStyleMap.put(id, resValue);
+            mStyleToDynamicIdMap.put(resValue, id);
+        }
+
+        return id;
+    }
+
+    private StyleResourceValue getStyleByDynamicId(int i) {
+        if (mDynamicIdToStyleMap != null) {
+            return mDynamicIdToStyleMap.get(i);
+        }
+
+        return null;
+    }
+
+    int getFrameworkResourceValue(ResourceType resType, String resName, int defValue) {
+        Integer value = Bridge.getResourceId(resType, resName);
+        if (value != null) {
+            return value.intValue();
+        }
+
+        return defValue;
+    }
+
+    int getProjectResourceValue(ResourceType resType, String resName, int defValue) {
+        if (mProjectCallback != null) {
+            Integer value = mProjectCallback.getResourceId(resType, resName);
+            if (value != null) {
+                return value.intValue();
+            }
+        }
+
+        return defValue;
+    }
+
+    //------------ NOT OVERRIDEN --------------------
+
+    @Override
+    public boolean bindService(Intent arg0, ServiceConnection arg1, int arg2) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public int checkCallingOrSelfPermission(String arg0) {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int checkCallingOrSelfUriPermission(Uri arg0, int arg1) {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int checkCallingPermission(String arg0) {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int checkCallingUriPermission(Uri arg0, int arg1) {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int checkPermission(String arg0, int arg1, int arg2) {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3) {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public int checkUriPermission(Uri arg0, String arg1, String arg2, int arg3,
+            int arg4, int arg5) {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public void clearWallpaper() {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public Context createPackageContext(String arg0, int arg1) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String[] databaseList() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean deleteDatabase(String arg0) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean deleteFile(String arg0) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void enforceCallingOrSelfPermission(String arg0, String arg1) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void enforceCallingOrSelfUriPermission(Uri arg0, int arg1,
+            String arg2) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void enforceCallingPermission(String arg0, String arg1) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void enforceCallingUriPermission(Uri arg0, int arg1, String arg2) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void enforcePermission(String arg0, int arg1, int arg2, String arg3) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void enforceUriPermission(Uri arg0, int arg1, int arg2, int arg3,
+            String arg4) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void enforceUriPermission(Uri arg0, String arg1, String arg2,
+            int arg3, int arg4, int arg5, String arg6) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public String[] fileList() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public AssetManager getAssets() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public File getCacheDir() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public File getExternalCacheDir() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ContentResolver getContentResolver() {
+        if (mContentResolver == null) {
+            mContentResolver = new BridgeContentResolver(this);
+        }
+        return mContentResolver;
+    }
+
+    @Override
+    public File getDatabasePath(String arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public File getDir(String arg0, int arg1) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public File getFileStreamPath(String arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public File getFilesDir() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public File getExternalFilesDir(String type) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getPackageCodePath() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public PackageManager getPackageManager() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getPackageName() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ApplicationInfo getApplicationInfo() {
+        return mApplicationInfo;
+    }
+
+    @Override
+    public String getPackageResourcePath() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public File getSharedPrefsFile(String name) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public SharedPreferences getSharedPreferences(String arg0, int arg1) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Drawable getWallpaper() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getWallpaperDesiredMinimumWidth() {
+        return -1;
+    }
+
+    @Override
+    public int getWallpaperDesiredMinimumHeight() {
+        return -1;
+    }
+
+    @Override
+    public void grantUriPermission(String arg0, Uri arg1, int arg2) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public FileInputStream openFileInput(String arg0) throws FileNotFoundException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public FileOutputStream openFileOutput(String arg0, int arg1) throws FileNotFoundException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public SQLiteDatabase openOrCreateDatabase(String arg0, int arg1, CursorFactory arg2) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Drawable peekWallpaper() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Intent registerReceiver(BroadcastReceiver arg0, IntentFilter arg1,
+            String arg2, Handler arg3) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void removeStickyBroadcast(Intent arg0) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void revokeUriPermission(Uri arg0, int arg1) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void sendBroadcast(Intent arg0) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void sendBroadcast(Intent arg0, String arg1) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void sendOrderedBroadcast(Intent arg0, String arg1) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void sendOrderedBroadcast(Intent arg0, String arg1,
+            BroadcastReceiver arg2, Handler arg3, int arg4, String arg5,
+            Bundle arg6) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void sendStickyBroadcast(Intent arg0) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void sendStickyOrderedBroadcast(Intent intent,
+            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
+           Bundle initialExtras) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void setTheme(int arg0) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setWallpaper(Bitmap arg0) throws IOException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setWallpaper(InputStream arg0) throws IOException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void startActivity(Intent arg0) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void startIntentSender(IntentSender intent,
+            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
+            throws IntentSender.SendIntentException {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public boolean startInstrumentation(ComponentName arg0, String arg1,
+            Bundle arg2) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public ComponentName startService(Intent arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean stopService(Intent arg0) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void unbindService(ServiceConnection arg0) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void unregisterReceiver(BroadcastReceiver arg0) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public Context getApplicationContext() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isRestricted() {
+        return false;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
similarity index 74%
rename from tools/layoutlib/bridge/src/android/view/BridgeInflater.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
index 0910d79..cb8d8dd 100644
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
@@ -14,36 +14,42 @@
  * limitations under the License.
  */
 
-package android.view;
+package com.android.layoutlib.bridge.android;
 
-import com.android.layoutlib.api.IProjectCallback;
-import com.android.layoutlib.api.IResourceValue;
+import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.MergeCookie;
+import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.BridgeContext;
-import com.android.layoutlib.bridge.BridgeXmlBlockParser;
+import com.android.resources.ResourceType;
+import com.android.util.Pair;
 
 import org.kxml2.io.KXmlParser;
 import org.xmlpull.v1.XmlPullParser;
 
 import android.content.Context;
 import android.util.AttributeSet;
+import android.view.InflateException;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
 
 import java.io.File;
 import java.io.FileReader;
 
 /**
- * Custom implementation of {@link LayoutInflater} to handle custom views. 
+ * Custom implementation of {@link LayoutInflater} to handle custom views.
  */
 public final class BridgeInflater extends LayoutInflater {
-    
+
     private final IProjectCallback mProjectCallback;
+    private boolean mIsInMerge = false;
 
     /**
      * List of class prefixes which are tried first by default.
      * <p/>
      * This should match the list in com.android.internal.policy.impl.PhoneLayoutInflater.
-     */ 
+     */
     private static final String[] sClassPrefixList = {
         "android.widget.",
         "android.webkit."
@@ -53,10 +59,10 @@
         super(original, newContext);
         mProjectCallback = null;
     }
-    
+
     /**
      * Instantiate a new BridgeInflater with an {@link IProjectCallback} object.
-     * 
+     *
      * @param context The Android application context.
      * @param projectCallback the {@link IProjectCallback} object.
      */
@@ -82,7 +88,7 @@
                     // Ignore. We'll try again using the base class below.
                 }
             }
-    
+
             // Next try using the parent loader. This will most likely only work for
             // fully-qualified class names.
             try {
@@ -92,7 +98,7 @@
             } catch (ClassNotFoundException e) {
                 // Ignore. We'll try again using the custom view loader below.
             }
-    
+
             // Finally try again using the custom view loader
             try {
                 if (view == null) {
@@ -109,12 +115,12 @@
             ClassNotFoundException exception = new ClassNotFoundException("onCreateView", e);
             throw exception;
         }
-        
+
         setupViewInContext(view, attrs);
-        
+
         return view;
     }
-    
+
     @Override
     public View createViewFromTag(String name, AttributeSet attrs) {
         View view = null;
@@ -128,7 +134,7 @@
                 // Wrap the real exception in an InflateException so that the calling
                 // method can deal with it.
                 InflateException exception = new InflateException();
-                if (e2.getClass().equals(ClassNotFoundException.class) == false) { 
+                if (e2.getClass().equals(ClassNotFoundException.class) == false) {
                     exception.initCause(e2);
                 } else {
                     exception.initCause(e);
@@ -136,30 +142,30 @@
                 throw exception;
             }
         }
-        
+
         setupViewInContext(view, attrs);
-        
+
         return view;
     }
-    
+
     @Override
     public View inflate(int resource, ViewGroup root) {
         Context context = getContext();
         if (context instanceof BridgeContext) {
             BridgeContext bridgeContext = (BridgeContext)context;
-            
-            IResourceValue value = null;
 
-            String[] layoutInfo = Bridge.resolveResourceValue(resource);
+            ResourceValue value = null;
+
+            Pair<ResourceType, String> layoutInfo = Bridge.resolveResourceId(resource);
             if (layoutInfo != null) {
-                value = bridgeContext.getFrameworkResource(BridgeConstants.RES_LAYOUT,
-                        layoutInfo[0]);
+                value = bridgeContext.getRenderResources().getFrameworkResource(
+                        ResourceType.LAYOUT, layoutInfo.getSecond());
             } else {
-                layoutInfo = mProjectCallback.resolveResourceValue(resource);
-                
+                layoutInfo = mProjectCallback.resolveResourceId(resource);
+
                 if (layoutInfo != null) {
-                    value = bridgeContext.getProjectResource(BridgeConstants.RES_LAYOUT,
-                            layoutInfo[0]);
+                    value = bridgeContext.getRenderResources().getProjectResource(
+                            ResourceType.LAYOUT, layoutInfo.getSecond());
                 }
             }
 
@@ -170,21 +176,23 @@
                         KXmlParser parser = new KXmlParser();
                         parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
                         parser.setInput(new FileReader(f));
-                        
+
                         BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(
                                 parser, bridgeContext, false);
-                        
+
                         return inflate(bridgeParser, root);
                     } catch (Exception e) {
-                        bridgeContext.getLogger().error(e);
-                        // return null below.
+                        Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
+                                "Failed to parse file " + f.getAbsolutePath(), e, null /*data*/);
+
+                        return null;
                     }
                 }
             }
         }
         return null;
     }
-    
+
     private View loadCustomView(String name, AttributeSet attrs) throws ClassNotFoundException,
             Exception{
         if (mProjectCallback != null) {
@@ -192,12 +200,12 @@
             if (name.equals("view")) {
                 name = attrs.getAttributeValue(null, "class");
             }
-            
+
             mConstructorArgs[1] = attrs;
 
             Object customView = mProjectCallback.loadView(name, mConstructorSignature,
                     mConstructorArgs);
-            
+
             if (customView instanceof View) {
                 return (View)customView;
             }
@@ -205,21 +213,43 @@
 
         return null;
     }
-    
-    
-    
+
     private void setupViewInContext(View view, AttributeSet attrs) {
         if (getContext() instanceof BridgeContext) {
             BridgeContext bc = (BridgeContext) getContext();
             if (attrs instanceof BridgeXmlBlockParser) {
-                Object viewKey = ((BridgeXmlBlockParser) attrs).getViewKey();
+                BridgeXmlBlockParser parser = (BridgeXmlBlockParser) attrs;
+
+                // get the view key
+                Object viewKey = parser.getViewCookie();
+
+                // if there's no view key and the depth is 1 (ie this is the first tag), or 2
+                // (this is first item in included merge layout)
+                // look for a previous parser in the context, and check if this one has a viewkey.
+                int testDepth = mIsInMerge ? 2 : 1;
+                if (viewKey == null && parser.getDepth() == testDepth) {
+                    BridgeXmlBlockParser previousParser = bc.getPreviousParser();
+                    if (previousParser != null) {
+                        viewKey = previousParser.getViewCookie();
+                    }
+                }
+
                 if (viewKey != null) {
+                    if (testDepth == 2) {
+                        // include-merge case
+                        viewKey = new MergeCookie(viewKey);
+                    }
+
                     bc.addViewKey(view, viewKey);
                 }
             }
         }
     }
 
+    public void setIsInMerge(boolean isInMerge) {
+        mIsInMerge = isInMerge;
+    }
+
     @Override
     public LayoutInflater cloneInContext(Context newContext) {
         return new BridgeInflater(this, newContext);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java
new file mode 100644
index 0000000..d208408
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeLayoutParamsMapAttributes.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.android;
+
+import com.android.layoutlib.bridge.BridgeConstants;
+
+import android.util.AttributeSet;
+
+import java.util.Map;
+
+/**
+ * An implementation of the {@link AttributeSet} interface on top of a map of attribute in the form
+ * of (name, value).
+ *
+ * This is meant to be called only from {@link BridgeContext#obtainStyledAttributes(AttributeSet, int[], int, int)}
+ * in the case of LayoutParams and therefore isn't a full implementation.
+ */
+public class BridgeLayoutParamsMapAttributes implements AttributeSet {
+
+    private final Map<String, String> mAttributes;
+
+    public BridgeLayoutParamsMapAttributes(Map<String, String> attributes) {
+        mAttributes = attributes;
+    }
+
+    public String getAttributeValue(String namespace, String name) {
+        if (BridgeConstants.NS_RESOURCES.equals(namespace)) {
+            return mAttributes.get(name);
+        }
+
+        return null;
+    }
+
+    // ---- the following methods are not called from
+    // BridgeContext#obtainStyledAttributes(AttributeSet, int[], int, int)
+    // Should they ever be called, we'll just implement them on a need basis.
+
+    public int getAttributeCount() {
+        throw new UnsupportedOperationException();
+    }
+
+    public String getAttributeName(int index) {
+        throw new UnsupportedOperationException();
+    }
+
+    public String getAttributeValue(int index) {
+        throw new UnsupportedOperationException();
+    }
+
+    public String getPositionDescription() {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getAttributeNameResource(int index) {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getAttributeListValue(String namespace, String attribute,
+            String[] options, int defaultValue) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean getAttributeBooleanValue(String namespace, String attribute,
+            boolean defaultValue) {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getAttributeResourceValue(String namespace, String attribute,
+            int defaultValue) {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getAttributeIntValue(String namespace, String attribute,
+            int defaultValue) {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getAttributeUnsignedIntValue(String namespace, String attribute,
+            int defaultValue) {
+        throw new UnsupportedOperationException();
+    }
+
+    public float getAttributeFloatValue(String namespace, String attribute,
+            float defaultValue) {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getAttributeListValue(int index,
+            String[] options, int defaultValue) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getAttributeResourceValue(int index, int defaultValue) {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getAttributeIntValue(int index, int defaultValue) {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getAttributeUnsignedIntValue(int index, int defaultValue) {
+        throw new UnsupportedOperationException();
+    }
+
+    public float getAttributeFloatValue(int index, float defaultValue) {
+        throw new UnsupportedOperationException();
+    }
+
+    public String getIdAttribute() {
+        throw new UnsupportedOperationException();
+    }
+
+    public String getClassAttribute() {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getIdAttributeResourceValue(int defaultValue) {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getStyleAttribute() {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
similarity index 67%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
index 6358abb..5e5aeb1 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
@@ -14,10 +14,17 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
 
-import com.android.layoutlib.api.IProjectCallback;
-import com.android.layoutlib.api.IResourceValue;
+import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.impl.ResourceHelper;
+import com.android.ninepatch.NinePatch;
+import com.android.resources.ResourceType;
+import com.android.util.Pair;
 
 import org.kxml2.io.KXmlParser;
 import org.xmlpull.v1.XmlPullParser;
@@ -52,6 +59,35 @@
     private boolean[] mPlatformResourceFlag = new boolean[1];
 
     /**
+     * Simpler wrapper around FileInputStream. This is used when the input stream represent
+     * not a normal bitmap but a nine patch.
+     * This is useful when the InputStream is created in a method but used in another that needs
+     * to know whether this is 9-patch or not, such as BitmapFactory.
+     */
+    public class NinePatchInputStream extends FileInputStream {
+        private boolean mFakeMarkSupport = true;
+        public NinePatchInputStream(File file) throws FileNotFoundException {
+            super(file);
+        }
+
+        @Override
+        public boolean markSupported() {
+            if (mFakeMarkSupport) {
+                // this is needed so that BitmapFactory doesn't wrap this in a BufferedInputStream.
+                return true;
+            }
+
+            return super.markSupported();
+        }
+
+        public void disableFakeMarkSupport() {
+            // disable fake mark support so that in case codec actually try to use them
+            // we don't lie to them.
+            mFakeMarkSupport = false;
+        }
+    }
+
+    /**
      * This initializes the static field {@link Resources#mSystem} which is used
      * by methods who get global resources using {@link Resources#getSystem()}.
      * <p/>
@@ -64,21 +100,18 @@
             DisplayMetrics metrics,
             Configuration config,
             IProjectCallback projectCallback) {
-        if (!(Resources.mSystem instanceof BridgeResources)) {
-            Resources.mSystem = new BridgeResources(context,
-                    assets,
-                    metrics,
-                    config,
-                    projectCallback);
-        }
-        return Resources.mSystem;
+        return Resources.mSystem = new BridgeResources(context,
+                assets,
+                metrics,
+                config,
+                projectCallback);
     }
 
     /**
-     * Clears the static {@link Resources#mSystem} to make sure we don't leave objects
+     * Disposes the static {@link Resources#mSystem} to make sure we don't leave objects
      * around that would prevent us from unloading the library.
      */
-    /*package*/ static void clearSystem() {
+    /*package*/ static void disposeSystem() {
         if (Resources.mSystem instanceof BridgeResources) {
             ((BridgeResources)(Resources.mSystem)).mContext = null;
             ((BridgeResources)(Resources.mSystem)).mProjectCallback = null;
@@ -97,22 +130,24 @@
         return new BridgeTypedArray(this, mContext, numEntries, platformFile);
     }
 
-    private IResourceValue getResourceValue(int id, boolean[] platformResFlag_out) {
+    private ResourceValue getResourceValue(int id, boolean[] platformResFlag_out) {
         // first get the String related to this id in the framework
-        String[] resourceInfo = Bridge.resolveResourceValue(id);
+        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
 
         if (resourceInfo != null) {
             platformResFlag_out[0] = true;
-            return mContext.getFrameworkResource(resourceInfo[1], resourceInfo[0]);
+            return mContext.getRenderResources().getFrameworkResource(
+                    resourceInfo.getFirst(), resourceInfo.getSecond());
         }
 
         // didn't find a match in the framework? look in the project.
         if (mProjectCallback != null) {
-            resourceInfo = mProjectCallback.resolveResourceValue(id);
+            resourceInfo = mProjectCallback.resolveResourceId(id);
 
             if (resourceInfo != null) {
                 platformResFlag_out[0] = false;
-                return mContext.getProjectResource(resourceInfo[1], resourceInfo[0]);
+                return mContext.getRenderResources().getProjectResource(
+                        resourceInfo.getFirst(), resourceInfo.getSecond());
             }
         }
 
@@ -121,10 +156,10 @@
 
     @Override
     public Drawable getDrawable(int id) throws NotFoundException {
-        IResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
-            return ResourceHelper.getDrawable(value, mContext, value.isFramework());
+            return ResourceHelper.getDrawable(value, mContext);
         }
 
         // id was not found or not resolved. Throw a NotFoundException.
@@ -136,12 +171,14 @@
 
     @Override
     public int getColor(int id) throws NotFoundException {
-        IResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
             try {
                 return ResourceHelper.getColor(value.getValue());
             } catch (NumberFormatException e) {
+                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, e.getMessage(), e,
+                        null /*data*/);
                 return 0;
             }
         }
@@ -155,14 +192,12 @@
 
     @Override
     public ColorStateList getColorStateList(int id) throws NotFoundException {
-        IResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        ResourceValue resValue = getResourceValue(id, mPlatformResourceFlag);
 
-        if (value != null) {
-            try {
-                int color = ResourceHelper.getColor(value.getValue());
-                return ColorStateList.valueOf(color);
-            } catch (NumberFormatException e) {
-                return null;
+        if (resValue != null) {
+            ColorStateList stateList = ResourceHelper.getColorStateList(resValue, mContext);
+            if (stateList != null) {
+                return stateList;
             }
         }
 
@@ -175,7 +210,7 @@
 
     @Override
     public CharSequence getText(int id) throws NotFoundException {
-        IResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
             return value.getValue();
@@ -190,27 +225,76 @@
 
     @Override
     public XmlResourceParser getLayout(int id) throws NotFoundException {
-        IResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
-            File xml = new File(value.getValue());
-            if (xml.isFile()) {
-                // we need to create a pull parser around the layout XML file, and then
-                // give that to our XmlBlockParser
-                try {
-                    KXmlParser parser = new KXmlParser();
+            XmlPullParser parser = null;
+
+            try {
+                // check if the current parser can provide us with a custom parser.
+                BridgeXmlBlockParser currentParser = mContext.getCurrentParser();
+                if (currentParser != null) {
+                    parser = currentParser.getParser(value.getName());
+                }
+
+                // create a new one manually if needed.
+                if (parser == null) {
+                    File xml = new File(value.getValue());
+                    if (xml.isFile()) {
+                        // we need to create a pull parser around the layout XML file, and then
+                        // give that to our XmlBlockParser
+                        parser = new KXmlParser();
+                        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
+                        parser.setInput(new FileReader(xml));
+                    }
+                }
+
+                if (parser != null) {
+                    return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
+                }
+            } catch (XmlPullParserException e) {
+                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                        "Failed to configure parser for " + value.getValue(), e, null /*data*/);
+                // we'll return null below.
+            } catch (FileNotFoundException e) {
+                // this shouldn't happen since we check above.
+            }
+
+        }
+
+        // id was not found or not resolved. Throw a NotFoundException.
+        throwException(id);
+
+        // this is not used since the method above always throws
+        return null;
+    }
+
+    @Override
+    public XmlResourceParser getAnimation(int id) throws NotFoundException {
+        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+
+        if (value != null) {
+            XmlPullParser parser = null;
+
+            try {
+                File xml = new File(value.getValue());
+                if (xml.isFile()) {
+                    // we need to create a pull parser around the layout XML file, and then
+                    // give that to our XmlBlockParser
+                    parser = new KXmlParser();
                     parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
                     parser.setInput(new FileReader(xml));
 
                     return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
-                } catch (XmlPullParserException e) {
-                    mContext.getLogger().error(e);
-
-                    // we'll return null below.
-                } catch (FileNotFoundException e) {
-                    // this shouldn't happen since we check above.
                 }
+            } catch (XmlPullParserException e) {
+                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                        "Failed to configure parser for " + value.getValue(), e, null /*data*/);
+                // we'll return null below.
+            } catch (FileNotFoundException e) {
+                // this shouldn't happen since we check above.
             }
+
         }
 
         // id was not found or not resolved. Throw a NotFoundException.
@@ -233,7 +317,7 @@
 
     @Override
     public float getDimension(int id) throws NotFoundException {
-        IResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
             String v = value.getValue();
@@ -262,7 +346,7 @@
 
     @Override
     public int getDimensionPixelOffset(int id) throws NotFoundException {
-        IResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
             String v = value.getValue();
@@ -284,7 +368,7 @@
 
     @Override
     public int getDimensionPixelSize(int id) throws NotFoundException {
-        IResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
             String v = value.getValue();
@@ -306,7 +390,7 @@
 
     @Override
     public int getInteger(int id) throws NotFoundException {
-        IResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null && value.getValue() != null) {
             String v = value.getValue();
@@ -361,7 +445,7 @@
 
     @Override
     public String getString(int id) throws NotFoundException {
-        IResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null && value.getValue() != null) {
             return value.getValue();
@@ -377,7 +461,7 @@
     @Override
     public void getValue(int id, TypedValue outValue, boolean resolveRefs)
             throws NotFoundException {
-        IResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
             String v = value.getValue();
@@ -406,7 +490,7 @@
 
     @Override
     public XmlResourceParser getXml(int id) throws NotFoundException {
-        IResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
             String v = value.getValue();
@@ -470,16 +554,22 @@
 
     @Override
     public InputStream openRawResource(int id) throws NotFoundException {
-        IResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
-            String v = value.getValue();
+            String path = value.getValue();
 
-            if (v != null) {
+            if (path != null) {
                 // check this is a file
-                File f = new File(value.getValue());
+                File f = new File(path);
                 if (f.isFile()) {
                     try {
+                        // if it's a nine-patch return a custom input stream so that
+                        // other methods (mainly bitmap factory) can detect it's a 9-patch
+                        // and actually load it as a 9-patch instead of a normal bitmap
+                        if (path.toLowerCase().endsWith(NinePatch.EXTENSION_9PATCH)) {
+                            return new NinePatchInputStream(f);
+                        }
                         return new FileInputStream(f);
                     } catch (FileNotFoundException e) {
                         NotFoundException newE = new NotFoundException();
@@ -501,9 +591,17 @@
     public InputStream openRawResource(int id, TypedValue value) throws NotFoundException {
         getValue(id, value, true);
 
-        File f = new File(value.string.toString());
+        String path = value.string.toString();
+
+        File f = new File(path);
         if (f.isFile()) {
             try {
+                // if it's a nine-patch return a custom input stream so that
+                // other methods (mainly bitmap factory) can detect it's a 9-patch
+                // and actually load it as a 9-patch instead of a normal bitmap
+                if (path.toLowerCase().endsWith(NinePatch.EXTENSION_9PATCH)) {
+                    return new NinePatchInputStream(f);
+                }
                 return new FileInputStream(f);
             } catch (FileNotFoundException e) {
                 NotFoundException exception = new NotFoundException();
@@ -527,18 +625,18 @@
      */
     private void throwException(int id) throws NotFoundException {
         // first get the String related to this id in the framework
-        String[] resourceInfo = Bridge.resolveResourceValue(id);
+        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
 
         // if the name is unknown in the framework, get it from the custom view loader.
         if (resourceInfo == null && mProjectCallback != null) {
-            resourceInfo = mProjectCallback.resolveResourceValue(id);
+            resourceInfo = mProjectCallback.resolveResourceId(id);
         }
 
         String message = null;
         if (resourceInfo != null) {
             message = String.format(
                     "Could not find %1$s resource matching value 0x%2$X (resolved name: %3$s) in current configuration.",
-                    resourceInfo[1], id, resourceInfo[0]);
+                    resourceInfo.getFirst(), id, resourceInfo.getSecond());
         } else {
             message = String.format(
                     "Could not resolve resource value: 0x%1$X.", id);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
similarity index 71%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
index 70c5bd7..c1d7600 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
@@ -14,14 +14,21 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
 
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.RenderResources;
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.ide.common.rendering.api.StyleResourceValue;
 import com.android.internal.util.XmlUtils;
-import com.android.layoutlib.api.IResourceValue;
-import com.android.layoutlib.api.IStyleResourceValue;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.impl.ResourceHelper;
+import com.android.resources.ResourceType;
 
 import org.kxml2.io.KXmlParser;
 import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
 
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
@@ -33,39 +40,38 @@
 
 import java.io.File;
 import java.io.FileReader;
+import java.util.Arrays;
 import java.util.Map;
 
 /**
- * TODO: describe.
+ * Custom implementation of TypedArray to handle non compiled resources.
  */
 public final class BridgeTypedArray extends TypedArray {
 
-    @SuppressWarnings("hiding")
-    private BridgeResources mResources;
+    private BridgeResources mBridgeResources;
     private BridgeContext mContext;
-    @SuppressWarnings("hiding")
-    private IResourceValue[] mData;
+    private ResourceValue[] mResourceData;
     private String[] mNames;
     private final boolean mPlatformFile;
 
     public BridgeTypedArray(BridgeResources resources, BridgeContext context, int len,
             boolean platformFile) {
         super(null, null, null, 0);
-        mResources = resources;
+        mBridgeResources = resources;
         mContext = context;
         mPlatformFile = platformFile;
-        mData = new IResourceValue[len];
+        mResourceData = new ResourceValue[len];
         mNames = new String[len];
     }
 
     /** A bridge-specific method that sets a value in the type array */
-    public void bridgeSetValue(int index, String name, IResourceValue value) {
-        mData[index] = value;
+    public void bridgeSetValue(int index, String name, ResourceValue value) {
+        mResourceData[index] = value;
         mNames[index] = name;
     }
 
     /**
-     * Seals the array after all calls to {@link #bridgeSetValue(int, String, IResourceValue)} have
+     * Seals the array after all calls to {@link #bridgeSetValue(int, String, ResourceValue)} have
      * been done.
      * <p/>This allows to compute the list of non default values, permitting
      * {@link #getIndexCount()} to return the proper value.
@@ -74,7 +80,7 @@
         // fills TypedArray.mIndices which is used to implement getIndexCount/getIndexAt
         // first count the array size
         int count = 0;
-        for (IResourceValue data : mData) {
+        for (ResourceValue data : mResourceData) {
             if (data != null) {
                 count++;
             }
@@ -86,8 +92,8 @@
 
         // fill the array with the indices.
         int index = 1;
-        for (int i = 0 ; i < mData.length ; i++) {
-            if (mData[i] != null) {
+        for (int i = 0 ; i < mResourceData.length ; i++) {
+            if (mResourceData[i] != null) {
                 mIndices[index++] = i;
             }
         }
@@ -98,7 +104,7 @@
      */
     @Override
     public int length() {
-        return mData.length;
+        return mResourceData.length;
     }
 
     /**
@@ -106,7 +112,7 @@
      */
     @Override
     public Resources getResources() {
-        return mResources;
+        return mBridgeResources;
     }
 
     /**
@@ -119,9 +125,9 @@
      */
     @Override
     public CharSequence getText(int index) {
-        if (mData[index] != null) {
+        if (mResourceData[index] != null) {
             // FIXME: handle styled strings!
-            return mData[index].getValue();
+            return mResourceData[index].getValue();
         }
 
         return null;
@@ -137,8 +143,8 @@
      */
     @Override
     public String getString(int index) {
-        if (mData[index] != null) {
-            return mData[index].getValue();
+        if (mResourceData[index] != null) {
+            return mResourceData[index].getValue();
         }
 
         return null;
@@ -154,11 +160,11 @@
      */
     @Override
     public boolean getBoolean(int index, boolean defValue) {
-        if (mData[index] == null) {
+        if (mResourceData[index] == null) {
             return defValue;
         }
 
-        String s = mData[index].getValue();
+        String s = mResourceData[index].getValue();
         if (s != null) {
             return XmlUtils.convertValueToBoolean(s, defValue);
         }
@@ -176,11 +182,15 @@
      */
     @Override
     public int getInt(int index, int defValue) {
-        if (mData[index] == null) {
+        if (mResourceData[index] == null) {
             return defValue;
         }
 
-        String s = mData[index].getValue();
+        String s = mResourceData[index].getValue();
+
+        if (RenderResources.REFERENCE_NULL.equals(s)) {
+            return defValue;
+        }
 
         try {
             return (s == null) ? defValue : XmlUtils.convertValueToInt(s, defValue);
@@ -204,9 +214,10 @@
                 if (i != null) {
                     result |= i.intValue();
                 } else {
-                    mContext.getLogger().warning(String.format(
-                            "Unknown constant \"%s\" in attribute \"%2$s\"",
-                            keyword, mNames[index]));
+                    Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
+                            String.format(
+                                "\"%s\" in attribute \"%2$s\" is not a valid value",
+                                keyword, mNames[index]), null /*data*/);
                 }
             }
             return result;
@@ -224,19 +235,20 @@
      */
     @Override
     public float getFloat(int index, float defValue) {
-        if (mData[index] == null) {
+        if (mResourceData[index] == null) {
             return defValue;
         }
 
-        String s = mData[index].getValue();
+        String s = mResourceData[index].getValue();
 
         if (s != null) {
             try {
                 return Float.parseFloat(s);
             } catch (NumberFormatException e) {
-                mContext.getLogger().warning(String.format(
-                        "Unable to convert \"%s\" into a float in attribute \"%2$s\"",
-                        s, mNames[index]));
+                Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
+                        String.format(
+                            "\"%s\" in attribute \"%2$s\" cannot be converted to float.",
+                            s, mNames[index]), null /*data*/);
 
                 // we'll return the default value below.
             }
@@ -258,19 +270,14 @@
      */
     @Override
     public int getColor(int index, int defValue) {
-        if (mData[index] == null) {
+        if (mResourceData[index] == null) {
             return defValue;
         }
 
-        String s = mData[index].getValue();
-        try {
-            return ResourceHelper.getColor(s);
-        } catch (NumberFormatException e) {
-            mContext.getLogger().warning(String.format(
-                    "Unable to convert \"%s\" into a color in attribute \"%2$s\"",
-                    s, mNames[index]));
-
-            // we'll return the default value below.
+        ColorStateList colorStateList = ResourceHelper.getColorStateList(
+                mResourceData[index], mContext);
+        if (colorStateList != null) {
+            return colorStateList.getDefaultColor();
         }
 
         return defValue;
@@ -287,50 +294,57 @@
      */
     @Override
     public ColorStateList getColorStateList(int index) {
-        if (mData[index] == null) {
+        if (mResourceData[index] == null) {
             return null;
         }
 
-        String value = mData[index].getValue();
+        ResourceValue resValue = mResourceData[index];
+        String value = resValue.getValue();
 
         if (value == null) {
             return null;
         }
 
+        if (RenderResources.REFERENCE_NULL.equals(value)) {
+            return null;
+        }
+
+        // let the framework inflate the ColorStateList from the XML file.
+        File f = new File(value);
+        if (f.isFile()) {
+            try {
+                KXmlParser parser = new KXmlParser();
+                parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
+                parser.setInput(new FileReader(f));
+
+                BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
+                        parser, mContext, resValue.isFramework());
+                try {
+                    return ColorStateList.createFromXml(mContext.getResources(), blockParser);
+                } finally {
+                    blockParser.ensurePopped();
+                }
+            } catch (XmlPullParserException e) {
+                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                        "Failed to configure parser for " + value, e, null /*data*/);
+                return null;
+            } catch (Exception e) {
+                // this is an error and not warning since the file existence is checked before
+                // attempting to parse it.
+                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
+                        "Failed to parse file " + value, e, null /*data*/);
+
+                return null;
+            }
+        }
+
         try {
             int color = ResourceHelper.getColor(value);
             return ColorStateList.valueOf(color);
         } catch (NumberFormatException e) {
-            // if it's not a color value, we'll attempt to read the xml based color below.
+            Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, e.getMessage(), e, null /*data*/);
         }
 
-        // let the framework inflate the ColorStateList from the XML file.
-        try {
-            File f = new File(value);
-            if (f.isFile()) {
-                KXmlParser parser = new KXmlParser();
-                parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-                parser.setInput(new FileReader(f));
-
-                ColorStateList colorStateList = ColorStateList.createFromXml(
-                        mContext.getResources(),
-                        // FIXME: we need to know if this resource is platform or not
-                        new BridgeXmlBlockParser(parser, mContext, false));
-                return colorStateList;
-            }
-        } catch (Exception e) {
-            // this is an error and not warning since the file existence is checked before
-            // attempting to parse it.
-            mContext.getLogger().error(e);
-
-            // return null below.
-        }
-
-        // looks like were unable to resolve the color value.
-        mContext.getLogger().warning(String.format(
-                "Unable to resolve color value \"%1$s\" in attribute \"%2$s\"",
-                value, mNames[index]));
-
         return null;
     }
 
@@ -345,19 +359,20 @@
      */
     @Override
     public int getInteger(int index, int defValue) {
-        if (mData[index] == null) {
+        if (mResourceData[index] == null) {
             return defValue;
         }
 
-        String s = mData[index].getValue();
+        String s = mResourceData[index].getValue();
 
         if (s != null) {
             try {
                 return Integer.parseInt(s);
             } catch (NumberFormatException e) {
-                mContext.getLogger().warning(String.format(
-                        "Unable to convert \"%s\" into a integer in attribute \"%2$s\"",
-                        s, mNames[index]));
+                Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
+                        String.format(
+                            "\"%s\" in attribute \"%2$s\" cannont be converted to an integer.",
+                            s, mNames[index]), null /*data*/);
 
                 // The default value is returned below.
             }
@@ -384,11 +399,11 @@
      */
     @Override
     public float getDimension(int index, float defValue) {
-        if (mData[index] == null) {
+        if (mResourceData[index] == null) {
             return defValue;
         }
 
-        String s = mData[index].getValue();
+        String s = mResourceData[index].getValue();
 
         if (s == null) {
             return defValue;
@@ -399,14 +414,19 @@
             return LayoutParams.WRAP_CONTENT;
         }
 
+        if (RenderResources.REFERENCE_NULL.equals(s)) {
+            return defValue;
+        }
+
         if (ResourceHelper.stringToFloat(s, mValue)) {
-            return mValue.getDimension(mResources.mMetrics);
+            return mValue.getDimension(mBridgeResources.mMetrics);
         }
 
         // looks like we were unable to resolve the dimension value
-        mContext.getLogger().warning(String.format(
-                "Unable to resolve dimension value \"%1$s\" in attribute \"%2$s\"",
-                s, mNames[index]));
+        Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
+                String.format(
+                    "\"%1$s\" in attribute \"%2$s\" is not a valid format.",
+                    s, mNames[index]), null /*data*/);
 
         return defValue;
     }
@@ -453,11 +473,11 @@
      */
     @Override
     public int getDimensionPixelSize(int index, int defValue) {
-        if (mData[index] == null) {
+        if (mResourceData[index] == null) {
             return defValue;
         }
 
-        String s = mData[index].getValue();
+        String s = mResourceData[index].getValue();
 
         if (s == null) {
             return defValue;
@@ -468,6 +488,10 @@
             return LayoutParams.WRAP_CONTENT;
         }
 
+        if (RenderResources.REFERENCE_NULL.equals(s)) {
+            return defValue;
+        }
+
         // FIXME huh?
 
         float f = getDimension(index, defValue);
@@ -476,8 +500,11 @@
         if (f == 0) return 0;
         if (f > 0) return 1;
 
-        throw new UnsupportedOperationException("Can't convert to dimension: " +
-                Integer.toString(index));
+        Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
+                "Can't convert to dimension: " + Integer.toString(index),
+                null, null /*data*/);
+
+        return defValue;
     }
 
     /**
@@ -519,11 +546,11 @@
      */
     @Override
     public float getFraction(int index, int base, int pbase, float defValue) {
-        if (mData[index] == null) {
+        if (mResourceData[index] == null) {
             return defValue;
         }
 
-        String value = mData[index].getValue();
+        String value = mResourceData[index].getValue();
         if (value == null) {
             return defValue;
         }
@@ -533,9 +560,10 @@
         }
 
         // looks like we were unable to resolve the fraction value
-        mContext.getLogger().warning(String.format(
-                "Unable to resolve fraction value \"%1$s\" in attribute \"%2$s\"",
-                value, mNames[index]));
+        Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
+                String.format(
+                    "\"%1$s\" in attribute \"%2$s\" cannont be converted to a fraction.",
+                    value, mNames[index]), null /*data*/);
 
         return defValue;
     }
@@ -556,8 +584,8 @@
      */
     @Override
     public int getResourceId(int index, int defValue) {
-        // get the IResource for this index
-        IResourceValue resValue = mData[index];
+        // get the Resource for this index
+        ResourceValue resValue = mResourceData[index];
 
         // no data, return the default value.
         if (resValue == null) {
@@ -565,24 +593,30 @@
         }
 
         // check if this is a style resource
-        if (resValue instanceof IStyleResourceValue) {
+        if (resValue instanceof StyleResourceValue) {
             // get the id that will represent this style.
-            return mContext.getDynamicIdByStyle((IStyleResourceValue)resValue);
+            return mContext.getDynamicIdByStyle((StyleResourceValue)resValue);
         }
 
-        // if the attribute was a reference to an id, and not a declaration of an id (@+id), then
-        // the xml attribute value was "resolved" which leads us to a IResourceValue with
-        // getType() returning "id" and getName() returning the id name
+        if (RenderResources.REFERENCE_NULL.equals(resValue.getValue())) {
+            return defValue;
+        }
+
+        // if the attribute was a reference to a resource, and not a declaration of an id (@+id),
+        // then the xml attribute value was "resolved" which leads us to a ResourceValue with a
+        // valid getType() and getName() returning a resource name.
         // (and getValue() returning null!). We need to handle this!
-        if (resValue.getType() != null && resValue.getType().equals(BridgeConstants.RES_ID)) {
+        if (resValue.getResourceType() != null) {
             // if this is a framework id
             if (mPlatformFile || resValue.isFramework()) {
                 // look for idName in the android R classes
-                return mContext.getFrameworkIdValue(resValue.getName(), defValue);
+                return mContext.getFrameworkResourceValue(
+                        resValue.getResourceType(), resValue.getName(), defValue);
             }
 
             // look for idName in the project R class.
-            return mContext.getProjectIdValue(resValue.getName(), defValue);
+            return mContext.getProjectResourceValue(
+                    resValue.getResourceType(), resValue.getName(), defValue);
         }
 
         // else, try to get the value, and resolve it somehow.
@@ -619,29 +653,33 @@
             // if this is a framework id
             if (mPlatformFile || value.startsWith("@android") || value.startsWith("@+android")) {
                 // look for idName in the android R classes
-                return mContext.getFrameworkIdValue(idName, defValue);
+                return mContext.getFrameworkResourceValue(ResourceType.ID, idName, defValue);
             }
 
             // look for idName in the project R class.
-            return mContext.getProjectIdValue(idName, defValue);
+            return mContext.getProjectResourceValue(ResourceType.ID, idName, defValue);
         }
 
         // not a direct id valid reference? resolve it
         Integer idValue = null;
 
         if (resValue.isFramework()) {
-            idValue = Bridge.getResourceValue(resValue.getType(), resValue.getName());
+            idValue = Bridge.getResourceId(resValue.getResourceType(),
+                    resValue.getName());
         } else {
-            idValue = mContext.getProjectCallback().getResourceValue(
-                    resValue.getType(), resValue.getName());
+            idValue = mContext.getProjectCallback().getResourceId(
+                    resValue.getResourceType(), resValue.getName());
         }
 
         if (idValue != null) {
             return idValue.intValue();
         }
 
-        mContext.getLogger().warning(String.format(
-                "Unable to resolve id \"%1$s\" for attribute \"%2$s\"", value, mNames[index]));
+        Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_RESOLVE,
+                String.format(
+                    "Unable to resolve id \"%1$s\" for attribute \"%2$s\"", value, mNames[index]),
+                    resValue);
+
         return defValue;
     }
 
@@ -657,28 +695,17 @@
      */
     @Override
     public Drawable getDrawable(int index) {
-        if (mData[index] == null) {
+        if (mResourceData[index] == null) {
             return null;
         }
 
-        IResourceValue value = mData[index];
+        ResourceValue value = mResourceData[index];
         String stringValue = value.getValue();
-        if (stringValue == null || BridgeConstants.REFERENCE_NULL.equals(stringValue)) {
+        if (stringValue == null || RenderResources.REFERENCE_NULL.equals(stringValue)) {
             return null;
         }
 
-        Drawable d = ResourceHelper.getDrawable(value, mContext, mData[index].isFramework());
-
-        if (d != null) {
-            return d;
-        }
-
-        // looks like we were unable to resolve the drawable
-        mContext.getLogger().warning(String.format(
-                "Unable to resolve drawable \"%1$s\" in attribute \"%2$s\"", stringValue,
-                mNames[index]));
-
-        return null;
+        return ResourceHelper.getDrawable(value, mContext);
     }
 
 
@@ -694,18 +721,23 @@
      */
     @Override
     public CharSequence[] getTextArray(int index) {
-        if (mData[index] == null) {
+        if (mResourceData[index] == null) {
             return null;
         }
 
-        String value = mData[index].getValue();
+        String value = mResourceData[index].getValue();
         if (value != null) {
+            if (RenderResources.REFERENCE_NULL.equals(value)) {
+                return null;
+            }
+
             return new CharSequence[] { value };
         }
 
-        mContext.getLogger().warning(String.format(
-                String.format("Unknown value for getTextArray(%d) => %s", //DEBUG
-                index, mData[index].getName())));
+        Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
+                String.format(
+                    String.format("Unknown value for getTextArray(%d) => %s", //DEBUG
+                    index, mResourceData[index].getName())), null /*data*/);
 
         return null;
     }
@@ -721,11 +753,11 @@
      */
     @Override
     public boolean getValue(int index, TypedValue outValue) {
-        if (mData[index] == null) {
+        if (mResourceData[index] == null) {
             return false;
         }
 
-        String s = mData[index].getValue();
+        String s = mResourceData[index].getValue();
 
         return ResourceHelper.stringToFloat(s, outValue);
     }
@@ -739,7 +771,7 @@
      */
     @Override
     public boolean hasValue(int index) {
-        return mData[index] != null;
+        return mResourceData[index] != null;
     }
 
     /**
@@ -786,6 +818,6 @@
 
     @Override
     public String toString() {
-        return mData.toString();
+        return Arrays.toString(mResourceData);
     }
  }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
new file mode 100644
index 0000000..0efa102
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.android;
+
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.view.IWindow;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View.AttachInfo;
+
+/**
+ * Implementation of {@link IWindow} to pass to the {@link AttachInfo}.
+ */
+public final class BridgeWindow implements IWindow {
+
+    public void dispatchAppVisibility(boolean arg0) throws RemoteException {
+        // pass for now.
+    }
+
+    public void dispatchGetNewSurface() throws RemoteException {
+        // pass for now.
+    }
+
+    public void dispatchKey(KeyEvent arg0) throws RemoteException {
+        // pass for now.
+    }
+
+    public void dispatchPointer(MotionEvent arg0, long arg1, boolean arg2) throws RemoteException {
+        // pass for now.
+    }
+
+    public void dispatchTrackball(MotionEvent arg0, long arg1, boolean arg2)
+    throws RemoteException {
+        // pass for now.
+    }
+
+    public void executeCommand(String arg0, String arg1, ParcelFileDescriptor arg2)
+            throws RemoteException {
+        // pass for now.
+    }
+
+    public void resized(int arg0, int arg1, Rect arg2, Rect arg3, boolean arg4, Configuration arg5)
+            throws RemoteException {
+        // pass for now.
+    }
+
+    public void windowFocusChanged(boolean arg0, boolean arg1) throws RemoteException {
+        // pass for now.
+    }
+
+    public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
+            boolean sync) {
+        // pass for now.
+    }
+
+    public void dispatchWallpaperCommand(String action, int x, int y,
+            int z, Bundle extras, boolean sync) {
+        // pass for now.
+    }
+
+    public void closeSystemDialogs(String reason) {
+        // pass for now.
+    }
+
+    public void dispatchSystemUiVisibilityChanged(int visibility) {
+        // pass for now.
+    }
+
+    public IBinder asBinder() {
+        // pass for now.
+        return null;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
new file mode 100644
index 0000000..7866bfa
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.android;
+
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.view.IWindow;
+import android.view.IWindowSession;
+import android.view.InputChannel;
+import android.view.Surface;
+import android.view.SurfaceView;
+import android.view.WindowManager.LayoutParams;
+
+/**
+ * Implementation of {@link IWindowSession} so that mSession is not null in
+ * the {@link SurfaceView}.
+ */
+public final class BridgeWindowSession implements IWindowSession {
+
+    public int add(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3,
+            InputChannel outInputchannel)
+            throws RemoteException {
+        // pass for now.
+        return 0;
+    }
+
+    public int addWithoutInputChannel(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3)
+            throws RemoteException {
+        // pass for now.
+        return 0;
+    }
+
+    public void finishDrawing(IWindow arg0) throws RemoteException {
+        // pass for now.
+    }
+
+    public boolean getInTouchMode() throws RemoteException {
+        // pass for now.
+        return false;
+    }
+
+    public boolean performHapticFeedback(IWindow window, int effectId, boolean always) {
+        // pass for now.
+        return false;
+    }
+
+    public int relayout(IWindow arg0, LayoutParams arg1, int arg2, int arg3, int arg4,
+            boolean arg4_5, Rect arg5, Rect arg6, Rect arg7, Configuration arg7b, Surface arg8)
+            throws RemoteException {
+        // pass for now.
+        return 0;
+    }
+
+    public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
+        // pass for now.
+    }
+
+    public void remove(IWindow arg0) throws RemoteException {
+        // pass for now.
+    }
+
+    public void setInTouchMode(boolean arg0) throws RemoteException {
+        // pass for now.
+    }
+
+    public void setTransparentRegion(IWindow arg0, Region arg1) throws RemoteException {
+        // pass for now.
+    }
+
+    public void setWallpaperPosition(IBinder window, float x, float y,
+        float xStep, float yStep) {
+        // pass for now.
+    }
+
+    public void wallpaperOffsetsComplete(IBinder window) {
+        // pass for now.
+    }
+
+    public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
+            int z, Bundle extras, boolean sync) {
+        // pass for now.
+        return null;
+    }
+
+    public void wallpaperCommandComplete(IBinder window, Bundle result) {
+        // pass for now.
+    }
+
+    public IBinder asBinder() {
+        // pass for now.
+        return null;
+    }
+
+    public void setInsets(IWindow arg0, int arg1, Rect arg2, Rect arg3) throws RemoteException {
+        // TODO Auto-generated method stub
+
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlBlockParser.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
similarity index 90%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlBlockParser.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
index d842a66..2f54ae6 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlBlockParser.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
@@ -14,9 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
 
-import com.android.layoutlib.api.IXmlPullParser;
+
+import com.android.ide.common.rendering.api.ILayoutPullParser;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -36,14 +37,15 @@
  */
 public class BridgeXmlBlockParser implements XmlResourceParser {
 
-    private XmlPullParser mParser;
-    private XmlPullAttributes mAttrib;
+    private final XmlPullParser mParser;
+    private final XmlPullAttributes mAttrib;
+    private final BridgeContext mContext;
+    private final boolean mPlatformFile;
 
     private boolean mStarted = false;
-    private boolean mDecNextDepth = false;
-    private int mDepth = 0;
     private int mEventType = START_DOCUMENT;
-    private final boolean mPlatformFile;
+
+    private boolean mPopped = true; // default to true in case it's not pushed.
 
     /**
      * Builds a {@link BridgeXmlBlockParser}.
@@ -53,25 +55,45 @@
      */
     public BridgeXmlBlockParser(XmlPullParser parser, BridgeContext context, boolean platformFile) {
         mParser = parser;
+        mContext = context;
         mPlatformFile = platformFile;
         mAttrib = new BridgeXmlPullAttributes(parser, context, mPlatformFile);
+
+        if (mContext != null) {
+            mContext.pushParser(this);
+            mPopped = false;
+        }
     }
-    
+
     public boolean isPlatformFile() {
         return mPlatformFile;
     }
 
-    public Object getViewKey() {
-        if (mParser instanceof IXmlPullParser) {
-            return ((IXmlPullParser)mParser).getViewKey();
+    public ILayoutPullParser getParser(String layoutName) {
+        if (mParser instanceof ILayoutPullParser) {
+            return ((ILayoutPullParser)mParser).getParser(layoutName);
         }
 
         return null;
     }
-    
-    
+
+    public Object getViewCookie() {
+        if (mParser instanceof ILayoutPullParser) {
+            return ((ILayoutPullParser)mParser).getViewCookie();
+        }
+
+        return null;
+    }
+
+    public void ensurePopped() {
+        if (mContext != null && mPopped == false) {
+            mContext.popParser();
+            mPopped = true;
+        }
+    }
+
     // ------- XmlResourceParser implementation
-    
+
     public void setFeature(String name, boolean state)
             throws XmlPullParserException {
         if (FEATURE_PROCESS_NAMESPACES.equals(name) && state) {
@@ -145,7 +167,7 @@
     }
 
     public int getDepth() {
-        return mDepth;
+        return mParser.getDepth();
     }
 
     public String getText() {
@@ -236,17 +258,10 @@
             return START_DOCUMENT;
         }
         int ev = mParser.next();
-        if (mDecNextDepth) {
-            mDepth--;
-            mDecNextDepth = false;
-        }
-        switch (ev) {
-        case START_TAG:
-            mDepth++;
-            break;
-        case END_TAG:
-            mDecNextDepth = true;
-            break;
+
+        if (ev == END_TAG && mParser.getDepth() == 1) {
+            // done with parser remove it from the context stack.
+            ensurePopped();
         }
         mEventType = ev;
         return ev;
@@ -301,7 +316,7 @@
 
     // AttributeSet implementation
 
-    
+
     public void close() {
         // pass
     }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlPullAttributes.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlPullAttributes.java
similarity index 80%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlPullAttributes.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlPullAttributes.java
index d145ff6..ba856e0 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlPullAttributes.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlPullAttributes.java
@@ -14,9 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
 
-import com.android.layoutlib.api.IResourceValue;
+import com.android.ide.common.rendering.api.RenderResources;
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.resources.ResourceType;
 
 import org.xmlpull.v1.XmlPullParser;
 
@@ -55,7 +59,7 @@
         String ns = mParser.getAttributeNamespace(index);
 
         if (BridgeConstants.NS_RESOURCES.equals(ns)) {
-            Integer v = Bridge.getResourceValue(BridgeConstants.RES_ATTR, name);
+            Integer v = Bridge.getResourceId(ResourceType.ATTR, name);
             if (v != null) {
                 return v.intValue();
             }
@@ -66,8 +70,7 @@
         // this is not an attribute in the android namespace, we query the customviewloader, if
         // the namespaces match.
         if (mContext.getProjectCallback().getNamespace().equals(ns)) {
-            Integer v = mContext.getProjectCallback().getResourceValue(BridgeConstants.RES_ATTR,
-                    name);
+            Integer v = mContext.getProjectCallback().getResourceId(ResourceType.ATTR, name);
             if (v != null) {
                 return v.intValue();
             }
@@ -100,16 +103,17 @@
 
     private int resolveResourceValue(String value, int defaultValue) {
         // now look for this particular value
-        IResourceValue resource = mContext.resolveResValue(
-                mContext.findResValue(value, mPlatformFile));
+        RenderResources resources = mContext.getRenderResources();
+        ResourceValue resource = resources.resolveResValue(
+                resources.findResValue(value, mPlatformFile));
 
         if (resource != null) {
             Integer id = null;
             if (mPlatformFile || resource.isFramework()) {
-                id = Bridge.getResourceValue(resource.getType(), resource.getName());
+                id = Bridge.getResourceId(resource.getResourceType(), resource.getName());
             } else {
-                id = mContext.getProjectCallback().getResourceValue(
-                        resource.getType(), resource.getName());
+                id = mContext.getProjectCallback().getResourceId(
+                        resource.getResourceType(), resource.getName());
             }
 
             if (id != null) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
new file mode 100644
index 0000000..0c4b0d3
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.bars;
+
+import com.android.ide.common.rendering.api.RenderResources;
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.ide.common.rendering.api.StyleResourceValue;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
+import com.android.layoutlib.bridge.impl.ResourceHelper;
+import com.android.resources.Density;
+import com.android.resources.ResourceType;
+
+import org.kxml2.io.KXmlParser;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap_Delegate;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Base "bar" class for the window decor around the the edited layout.
+ * This is basically an horizontal layout that loads a given layout on creation (it is read
+ * through {@link Class#getResourceAsStream(String)}).
+ *
+ * The given layout should be a merge layout so that all the children belong to this class directly.
+ *
+ * It also provides a few utility methods to configure the content of the layout.
+ */
+abstract class CustomBar extends LinearLayout {
+
+    protected abstract TextView getStyleableTextView();
+
+    protected CustomBar(Context context, Density density, String layoutPath)
+            throws XmlPullParserException {
+        super(context);
+        setOrientation(LinearLayout.HORIZONTAL);
+        setGravity(Gravity.CENTER_VERTICAL);
+
+        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
+                Context.LAYOUT_INFLATER_SERVICE);
+
+        KXmlParser parser = new KXmlParser();
+        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
+        parser.setInput(
+                getClass().getResourceAsStream(layoutPath),
+                "UTF8");
+
+        BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(
+                parser, (BridgeContext) context, false /*platformFile*/);
+
+        try {
+            inflater.inflate(bridgeParser, this, true);
+        } finally {
+            bridgeParser.ensurePopped();
+        }
+    }
+
+    private InputStream getIcon(String iconName, Density[] densityInOut, String[] pathOut,
+            boolean tryOtherDensities) {
+        // current density
+        Density density = densityInOut[0];
+
+        // bitmap url relative to this class
+        pathOut[0] = "/bars/" + density.getResourceValue() + "/" + iconName;
+
+        InputStream stream = getClass().getResourceAsStream(pathOut[0]);
+        if (stream == null && tryOtherDensities) {
+            for (Density d : Density.values()) {
+                if (d != density) {
+                    densityInOut[0] = d;
+                    stream = getIcon(iconName, densityInOut, pathOut, false /*tryOtherDensities*/);
+                    if (stream != null) {
+                        return stream;
+                    }
+                }
+            }
+        }
+
+        return stream;
+    }
+
+    protected void loadIcon(int index, String iconName, Density density) {
+        View child = getChildAt(index);
+        if (child instanceof ImageView) {
+            ImageView imageView = (ImageView) child;
+
+            String[] pathOut = new String[1];
+            Density[] densityInOut = new Density[] { density };
+            InputStream stream = getIcon(iconName, densityInOut, pathOut,
+                    true /*tryOtherDensities*/);
+            density = densityInOut[0];
+
+            if (stream != null) {
+                // look for a cached bitmap
+                Bitmap bitmap = Bridge.getCachedBitmap(pathOut[0], true /*isFramework*/);
+                if (bitmap == null) {
+                    try {
+                        bitmap = Bitmap_Delegate.createBitmap(stream, false /*isMutable*/, density);
+                        Bridge.setCachedBitmap(pathOut[0], bitmap, true /*isFramework*/);
+                    } catch (IOException e) {
+                        return;
+                    }
+                }
+
+                if (bitmap != null) {
+                    BitmapDrawable drawable = new BitmapDrawable(getContext().getResources(),
+                            bitmap);
+                    imageView.setBackgroundDrawable(drawable);
+                }
+            }
+        }
+    }
+
+    protected void loadIcon(int index, String iconReference) {
+        ResourceValue value = getResourceValue(iconReference);
+        if (value != null) {
+            loadIcon(index, value);
+        }
+    }
+
+    protected Drawable loadIcon(int index, ResourceType type, String name) {
+        BridgeContext bridgeContext = (BridgeContext) mContext;
+        RenderResources res = bridgeContext.getRenderResources();
+
+        // find the resource
+        ResourceValue value = res.getFrameworkResource(type, name);
+
+        // resolve it if needed
+        value = res.resolveResValue(value);
+        return loadIcon(index, value);
+    }
+
+    private Drawable loadIcon(int index, ResourceValue value) {
+        View child = getChildAt(index);
+        if (child instanceof ImageView) {
+            ImageView imageView = (ImageView) child;
+
+            Drawable drawable = ResourceHelper.getDrawable(
+                    value, (BridgeContext) mContext);
+            if (drawable != null) {
+                imageView.setBackgroundDrawable(drawable);
+            }
+
+            return drawable;
+        }
+
+        return null;
+    }
+
+    protected TextView setText(int index, String stringReference) {
+        View child = getChildAt(index);
+        if (child instanceof TextView) {
+            TextView textView = (TextView) child;
+            ResourceValue value = getResourceValue(stringReference);
+            if (value != null) {
+                textView.setText(value.getValue());
+            } else {
+                textView.setText(stringReference);
+            }
+            return textView;
+        }
+
+        return null;
+    }
+
+    protected void setStyle(String themeEntryName) {
+
+        BridgeContext bridgeContext = (BridgeContext) mContext;
+        RenderResources res = bridgeContext.getRenderResources();
+
+        ResourceValue value = res.findItemInTheme(themeEntryName);
+        value = res.resolveResValue(value);
+
+        if (value instanceof StyleResourceValue == false) {
+            return;
+        }
+
+        StyleResourceValue style = (StyleResourceValue) value;
+
+        // get the background
+        ResourceValue backgroundValue = res.findItemInStyle(style, "background");
+        backgroundValue = res.resolveResValue(backgroundValue);
+        if (backgroundValue != null) {
+            Drawable d = ResourceHelper.getDrawable(backgroundValue, bridgeContext);
+            if (d != null) {
+                setBackgroundDrawable(d);
+            }
+        }
+
+        TextView textView = getStyleableTextView();
+        if (textView != null) {
+            // get the text style
+            ResourceValue textStyleValue = res.findItemInStyle(style, "titleTextStyle");
+            textStyleValue = res.resolveResValue(textStyleValue);
+            if (textStyleValue instanceof StyleResourceValue) {
+                StyleResourceValue textStyle = (StyleResourceValue) textStyleValue;
+
+                ResourceValue textSize = res.findItemInStyle(textStyle, "textSize");
+                textSize = res.resolveResValue(textSize);
+
+                if (textSize != null) {
+                    TypedValue out = new TypedValue();
+                    if (ResourceHelper.stringToFloat(textSize.getValue(), out)) {
+                        textView.setTextSize(
+                                out.getDimension(bridgeContext.getResources().mMetrics));
+                    }
+                }
+
+
+                ResourceValue textColor = res.findItemInStyle(textStyle, "textColor");
+                textColor = res.resolveResValue(textColor);
+                if (textColor != null) {
+                    ColorStateList stateList = ResourceHelper.getColorStateList(
+                            textColor, bridgeContext);
+                    if (stateList != null) {
+                        textView.setTextColor(stateList);
+                    }
+                }
+            }
+        }
+    }
+
+    private ResourceValue getResourceValue(String reference) {
+        BridgeContext bridgeContext = (BridgeContext) mContext;
+        RenderResources res = bridgeContext.getRenderResources();
+
+        // find the resource
+        ResourceValue value = res.findResValue(reference, false /*isFramework*/);
+
+        // resolve it if needed
+        return res.resolveResValue(value);
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java
new file mode 100644
index 0000000..5507ef9
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.bars;
+
+import com.android.resources.Density;
+import com.android.resources.ResourceType;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LevelListDrawable;
+import android.view.Gravity;
+import android.widget.TextView;
+
+public class PhoneSystemBar extends CustomBar {
+
+    public PhoneSystemBar(Context context, Density density) throws XmlPullParserException {
+        super(context, density, "/bars/phone_system_bar.xml");
+
+        setGravity(mGravity | Gravity.RIGHT);
+        setBackgroundColor(0xFF000000);
+
+        // Cannot access the inside items through id because no R.id values have been
+        // created for them.
+        // We do know the order though.
+        // 0 is the spacer.
+        loadIcon(1, "stat_sys_wifi_signal_4_fully.png", density);
+        Drawable drawable = loadIcon(2, ResourceType.DRAWABLE, "stat_sys_battery_charge");
+        if (drawable instanceof LevelListDrawable) {
+            ((LevelListDrawable) drawable).setLevel(100);
+        }
+    }
+
+    @Override
+    protected TextView getStyleableTextView() {
+        return null;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
new file mode 100644
index 0000000..d7401d9
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.bars;
+
+import com.android.resources.Density;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.Context;
+import android.widget.TextView;
+
+public class TitleBar extends CustomBar {
+
+    private TextView mTextView;
+
+    public TitleBar(Context context, Density density, String label)
+            throws XmlPullParserException {
+        super(context, density, "/bars/title_bar.xml");
+
+        // Cannot access the inside items through id because no R.id values have been
+        // created for them.
+        // We do know the order though.
+        mTextView = setText(0, label);
+
+        setStyle("windowTitleBackgroundStyle");
+    }
+
+    @Override
+    protected TextView getStyleableTextView() {
+        return mTextView;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
new file mode 100644
index 0000000..ae1217d
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.impl;
+
+import com.android.layoutlib.bridge.util.Debug;
+import com.android.layoutlib.bridge.util.SparseWeakArray;
+
+import android.util.SparseArray;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Manages native delegates.
+ *
+ * This is used in conjunction with layoublib_create: certain Android java classes are mere
+ * wrappers around a heavily native based implementation, and we need a way to run these classes
+ * in our Eclipse rendering framework without bringing all the native code from the Android
+ * platform.
+ *
+ * Thus we instruct layoutlib_create to modify the bytecode of these classes to replace their
+ * native methods by "delegate calls".
+ *
+ * For example, a native method android.graphics.Matrix.init(...) will actually become
+ * a call to android.graphics.Matrix_Delegate.init(...).
+ *
+ * The Android java classes that use native code uses an int (Java side) to reference native
+ * objects. This int is generally directly the pointer to the C structure counterpart.
+ * Typically a creation method will return such an int, and then this int will be passed later
+ * to a Java method to identify the C object to manipulate.
+ *
+ * Since we cannot use the Java object reference as the int directly, DelegateManager manages the
+ * int -> Delegate class link.
+ *
+ * Native methods usually always have the int as parameters. The first thing the delegate method
+ * will do is call {@link #getDelegate(int)} to get the Java object matching the int.
+ *
+ * Typical native init methods are returning a new int back to the Java class, so
+ * {@link #addNewDelegate(Object)} does the same.
+ *
+ * The JNI references are counted, so we do the same through a {@link WeakReference}. Because
+ * the Java object needs to count as a reference (even though it only holds an int), we use the
+ * following mechanism:
+ *
+ * - {@link #addNewDelegate(Object)} and {@link #removeJavaReferenceFor(int)} adds and removes
+ *   the delegate to/from a list. This list hold the reference and prevents the GC from reclaiming
+ *   the delegate.
+ *
+ * - {@link #addNewDelegate(Object)} also adds the delegate to a {@link SparseArray} that holds a
+ *   {@link WeakReference} to the delegate. This allows the delegate to be deleted automatically
+ *   when nothing references it. This means that any class that holds a delegate (except for the
+ *   Java main class) must not use the int but the Delegate class instead. The integers must
+ *   only be used in the API between the main Java class and the Delegate.
+ *
+ * @param <T> the delegate class to manage
+ */
+public final class DelegateManager<T> {
+    private final Class<T> mClass;
+    private final SparseWeakArray<T> mDelegates = new SparseWeakArray<T>();
+    /** list used to store delegates when their main object holds a reference to them.
+     * This is to ensure that the WeakReference in the SparseWeakArray doesn't get GC'ed
+     * @see #addNewDelegate(Object)
+     * @see #removeJavaReferenceFor(int)
+     */
+    private final List<T> mJavaReferences = new ArrayList<T>();
+    private int mDelegateCounter = 0;
+
+    public DelegateManager(Class<T> theClass) {
+        mClass = theClass;
+    }
+
+    /**
+     * Returns the delegate from the given native int.
+     * <p>
+     * If the int is zero, then this will always return null.
+     * <p>
+     * If the int is non zero and the delegate is not found, this will throw an assert.
+     *
+     * @param native_object the native int.
+     * @return the delegate or null if not found.
+     */
+    public T getDelegate(int native_object) {
+        if (native_object > 0) {
+            T delegate =  mDelegates.get(native_object);
+
+            if (Debug.DEBUG) {
+                if (delegate == null) {
+                    System.out.println("Unknown " + mClass.getSimpleName() + " with int " +
+                            native_object);
+                }
+            }
+
+            assert delegate != null;
+            return delegate;
+        }
+        return null;
+    }
+
+    /**
+     * Adds a delegate to the manager and returns the native int used to identify it.
+     * @param newDelegate the delegate to add
+     * @return a unique native int to identify the delegate
+     */
+    public int addNewDelegate(T newDelegate) {
+        int native_object = ++mDelegateCounter;
+        mDelegates.put(native_object, newDelegate);
+        assert !mJavaReferences.contains(newDelegate);
+        mJavaReferences.add(newDelegate);
+
+        if (Debug.DEBUG) {
+            System.out.println("New " + mClass.getSimpleName() + " with int " + native_object);
+        }
+
+        return native_object;
+    }
+
+    /**
+     * Removes the main reference on the given delegate.
+     * @param native_object the native integer representing the delegate.
+     */
+    public void removeJavaReferenceFor(int native_object) {
+        T delegate = getDelegate(native_object);
+
+        if (Debug.DEBUG) {
+            System.out.println("Removing main Java ref on " + mClass.getSimpleName() +
+                    " with int " + native_object);
+        }
+
+        mJavaReferences.remove(delegate);
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/FontLoader.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
similarity index 95%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/FontLoader.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
index 801503b..f62fad2 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/FontLoader.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.impl;
 
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
@@ -134,6 +134,15 @@
         return mFallBackFonts;
     }
 
+    /**
+     * Returns a {@link Font} object given a family name and a style value (constant in
+     * {@link Typeface}).
+     * @param family the family name
+     * @param style a 1-item array containing the requested style. Based on the font being read
+     *              the actual style may be different. The array contains the actual style after
+     *              the method returns.
+     * @return the font object or null if no match could be found.
+     */
     public synchronized Font getFont(String family, int[] style) {
         if (family == null) {
             return null;
@@ -154,7 +163,7 @@
             mTtfToFontMap.put(ttf, styleMap);
         }
 
-        Font f = styleMap.get(style);
+        Font f = styleMap.get(style[0]);
 
         if (f != null) {
             return f;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java
new file mode 100644
index 0000000..1cf64a8
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java
@@ -0,0 +1,796 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.impl;
+
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
+
+import android.graphics.Bitmap_Delegate;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Paint_Delegate;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Region;
+import android.graphics.Region_Delegate;
+import android.graphics.Shader_Delegate;
+import android.graphics.Xfermode_Delegate;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Area;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+
+/**
+ * Class representing a graphics context snapshot, as well as a context stack as a linked list.
+ * <p>
+ * This is based on top of {@link Graphics2D} but can operate independently if none are available
+ * yet when setting transforms and clip information.
+ * <p>
+ * This allows for drawing through {@link #draw(Drawable, Paint_Delegate)} and
+ * {@link #draw(Drawable, Paint_Delegate)}
+ *
+ * Handling of layers (created with {@link Canvas#saveLayer(RectF, Paint, int)}) is handled through
+ * a list of Graphics2D for each layers. The class actually maintains a list of {@link Layer}
+ * for each layer. Doing a save() will duplicate this list so that each graphics2D object
+ * ({@link Layer#getGraphics()}) is configured only for the new snapshot.
+ */
+public class GcSnapshot {
+
+    private final GcSnapshot mPrevious;
+    private final int mFlags;
+
+    /** list of layers. The first item in the list is always the  */
+    private final ArrayList<Layer> mLayers = new ArrayList<Layer>();
+
+    /** temp transform in case transformation are set before a Graphics2D exists */
+    private AffineTransform mTransform = null;
+    /** temp clip in case clipping is set before a Graphics2D exists */
+    private Area mClip = null;
+
+    // local layer data
+    /** a local layer created with {@link Canvas#saveLayer(RectF, Paint, int)}.
+     * If this is null, this does not mean there's no layer, just that the snapshot is not the
+     * one that created the layer.
+     * @see #getLayerSnapshot()
+     */
+    private final Layer mLocalLayer;
+    private final Paint_Delegate mLocalLayerPaint;
+    private final Rect mLayerBounds;
+
+    public interface Drawable {
+        void draw(Graphics2D graphics, Paint_Delegate paint);
+    }
+
+    /**
+     * Class containing information about a layer.
+     *
+     * This contains graphics, bitmap and layer information.
+     */
+    private static class Layer {
+        private final Graphics2D mGraphics;
+        private final Bitmap_Delegate mBitmap;
+        private final BufferedImage mImage;
+        /** the flags that were used to configure the layer. This is never changed, and passed
+         * as is when {@link #makeCopy()} is called */
+        private final int mFlags;
+        /** the original content of the layer when the next object was created. This is not
+         * passed in {@link #makeCopy()} and instead is recreated when a new layer is added
+         * (depending on its flags) */
+        private BufferedImage mOriginalCopy;
+
+        /**
+         * Creates a layer with a graphics and a bitmap. This is only used to create
+         * the base layer.
+         *
+         * @param graphics the graphics
+         * @param bitmap the bitmap
+         */
+        Layer(Graphics2D graphics, Bitmap_Delegate bitmap) {
+            mGraphics = graphics;
+            mBitmap = bitmap;
+            mImage = mBitmap.getImage();
+            mFlags = 0;
+        }
+
+        /**
+         * Creates a layer with a graphics and an image. If the image belongs to a
+         * {@link Bitmap_Delegate} (case of the base layer), then
+         * {@link Layer#Layer(Graphics2D, Bitmap_Delegate)} should be used.
+         *
+         * @param graphics the graphics the new graphics for this layer
+         * @param image the image the image from which the graphics came
+         * @param flags the flags that were used to save this layer
+         */
+        Layer(Graphics2D graphics, BufferedImage image, int flags) {
+            mGraphics = graphics;
+            mBitmap = null;
+            mImage = image;
+            mFlags = flags;
+        }
+
+        /** The Graphics2D, guaranteed to be non null */
+        Graphics2D getGraphics() {
+            return mGraphics;
+        }
+
+        /** The BufferedImage, guaranteed to be non null */
+        BufferedImage getImage() {
+            return mImage;
+        }
+
+        /** Returns the layer save flags. This is only valid for additional layers.
+         * For the base layer this will always return 0;
+         * For a given layer, all further copies of this {@link Layer} object in new snapshots
+         * will always return the same value.
+         */
+        int getFlags() {
+            return mFlags;
+        }
+
+        Layer makeCopy() {
+            if (mBitmap != null) {
+                return new Layer((Graphics2D) mGraphics.create(), mBitmap);
+            }
+
+            return new Layer((Graphics2D) mGraphics.create(), mImage, mFlags);
+        }
+
+        /** sets an optional copy of the original content to be used during restore */
+        void setOriginalCopy(BufferedImage image) {
+            mOriginalCopy = image;
+        }
+
+        BufferedImage getOriginalCopy() {
+            return mOriginalCopy;
+        }
+
+        /**
+         * Sets the clip for the graphics2D object associated with the layer.
+         * This should be used over the normal Graphics2D setClip method.
+         *
+         * @param clipShape the shape to use a the clip shape.
+         */
+        void setClip(Shape clipShape) {
+            // because setClip is only guaranteed to work with rectangle shape,
+            // first reset the clip to max and then intersect the current (empty)
+            // clip with the shap.
+            mGraphics.setClip(null);
+            mGraphics.clip(clipShape);
+        }
+
+        /**
+         * Clips the layer with the given shape. This performs an intersect between the current
+         * clip shape and the given shape.
+         * @param shape the new clip shape.
+         */
+        public void clip(Shape shape) {
+            mGraphics.clip(shape);
+        }
+    }
+
+    /**
+     * Creates the root snapshot associating it with a given bitmap.
+     * <p>
+     * If <var>bitmap</var> is null, then {@link GcSnapshot#setBitmap(Bitmap_Delegate)} must be
+     * called before the snapshot can be used to draw. Transform and clip operations are permitted
+     * before.
+     *
+     * @param image the image to associate to the snapshot or null.
+     * @return the root snapshot
+     */
+    public static GcSnapshot createDefaultSnapshot(Bitmap_Delegate bitmap) {
+        GcSnapshot snapshot = new GcSnapshot();
+        if (bitmap != null) {
+            snapshot.setBitmap(bitmap);
+        }
+
+        return snapshot;
+    }
+
+    /**
+     * Saves the current state according to the given flags and returns the new current snapshot.
+     * <p/>
+     * This is the equivalent of {@link Canvas#save(int)}
+     *
+     * @param flags the save flags.
+     * @return the new snapshot
+     *
+     * @see Canvas#save(int)
+     */
+    public GcSnapshot save(int flags) {
+        return new GcSnapshot(this, null /*layerbounds*/, null /*paint*/, flags);
+    }
+
+    /**
+     * Saves the current state and creates a new layer, and returns the new current snapshot.
+     * <p/>
+     * This is the equivalent of {@link Canvas#saveLayer(RectF, Paint, int)}
+     *
+     * @param layerBounds the layer bounds
+     * @param paint the Paint information used to blit the layer back into the layers underneath
+     *          upon restore
+     * @param flags the save flags.
+     * @return the new snapshot
+     *
+     * @see Canvas#saveLayer(RectF, Paint, int)
+     */
+    public GcSnapshot saveLayer(RectF layerBounds, Paint_Delegate paint, int flags) {
+        return new GcSnapshot(this, layerBounds, paint, flags);
+    }
+
+    /**
+     * Creates the root snapshot.
+     * {@link #setGraphics2D(Graphics2D)} will have to be called on it when possible.
+     */
+    private GcSnapshot() {
+        mPrevious = null;
+        mFlags = 0;
+        mLocalLayer = null;
+        mLocalLayerPaint = null;
+        mLayerBounds = null;
+    }
+
+    /**
+     * Creates a new {@link GcSnapshot} on top of another one, with a layer data to be restored
+     * into the main graphics when {@link #restore()} is called.
+     *
+     * @param previous the previous snapshot head.
+     * @param layerBounds the region of the layer. Optional, if null, this is a normal save()
+     * @param paint the Paint information used to blit the layer back into the layers underneath
+     *          upon restore
+     * @param flags the flags regarding what should be saved.
+     */
+    private GcSnapshot(GcSnapshot previous, RectF layerBounds, Paint_Delegate paint, int flags) {
+        assert previous != null;
+        mPrevious = previous;
+        mFlags = flags;
+
+        // make a copy of the current layers before adding the new one.
+        // This keeps the same BufferedImage reference but creates new Graphics2D for this
+        // snapshot.
+        // It does not copy whatever original copy the layers have, as they will be done
+        // only if the new layer doesn't clip drawing to itself.
+        for (Layer layer : mPrevious.mLayers) {
+            mLayers.add(layer.makeCopy());
+        }
+
+        if (layerBounds != null) {
+            // get the current transform
+            AffineTransform matrix = mLayers.get(0).getGraphics().getTransform();
+
+            // transform the layerBounds with the current transform and stores it into a int rect
+            RectF rect2 = new RectF();
+            mapRect(matrix, rect2, layerBounds);
+            mLayerBounds = new Rect();
+            rect2.round(mLayerBounds);
+
+            // get the base layer (always at index 0)
+            Layer baseLayer = mLayers.get(0);
+
+            // create the image for the layer
+            BufferedImage layerImage = new BufferedImage(
+                    baseLayer.getImage().getWidth(),
+                    baseLayer.getImage().getHeight(),
+                    (mFlags & Canvas.HAS_ALPHA_LAYER_SAVE_FLAG) != 0 ?
+                            BufferedImage.TYPE_INT_ARGB :
+                                BufferedImage.TYPE_INT_RGB);
+
+            // create a graphics for it so that drawing can be done.
+            Graphics2D layerGraphics = layerImage.createGraphics();
+
+            // because this layer inherits the current context for transform and clip,
+            // set them to one from the base layer.
+            AffineTransform currentMtx = baseLayer.getGraphics().getTransform();
+            layerGraphics.setTransform(currentMtx);
+
+            // create a new layer for this new layer and add it to the list at the end.
+            mLayers.add(mLocalLayer = new Layer(layerGraphics, layerImage, flags));
+
+            // set the clip on it.
+            Shape currentClip = baseLayer.getGraphics().getClip();
+            mLocalLayer.setClip(currentClip);
+
+            // if the drawing is not clipped to the local layer only, we save the current content
+            // of all other layers. We are only interested in the part that will actually
+            // be drawn, so we create as small bitmaps as we can.
+            // This is so that we can erase the drawing that goes in the layers below that will
+            // be coming from the layer itself.
+            if ((mFlags & Canvas.CLIP_TO_LAYER_SAVE_FLAG) == 0) {
+                int w = mLayerBounds.width();
+                int h = mLayerBounds.height();
+                for (int i = 0 ; i < mLayers.size() - 1 ; i++) {
+                    Layer layer = mLayers.get(i);
+                    BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
+                    Graphics2D graphics = image.createGraphics();
+                    graphics.drawImage(layer.getImage(),
+                            0, 0, w, h,
+                            mLayerBounds.left, mLayerBounds.top,
+                                    mLayerBounds.right, mLayerBounds.bottom,
+                            null);
+                    graphics.dispose();
+                    layer.setOriginalCopy(image);
+                }
+            }
+        } else {
+            mLocalLayer = null;
+            mLayerBounds = null;
+        }
+
+        mLocalLayerPaint  = paint;
+    }
+
+    public void dispose() {
+        for (Layer layer : mLayers) {
+            layer.getGraphics().dispose();
+        }
+
+        if (mPrevious != null) {
+            mPrevious.dispose();
+        }
+    }
+
+    /**
+     * Restores the top {@link GcSnapshot}, and returns the next one.
+     */
+    public GcSnapshot restore() {
+        return doRestore();
+    }
+
+    /**
+     * Restores the {@link GcSnapshot} to <var>saveCount</var>.
+     * @param saveCount the saveCount or -1 to only restore 1.
+     *
+     * @return the new head of the Gc snapshot stack.
+     */
+    public GcSnapshot restoreTo(int saveCount) {
+        return doRestoreTo(size(), saveCount);
+    }
+
+    public int size() {
+        if (mPrevious != null) {
+            return mPrevious.size() + 1;
+        }
+
+        return 1;
+    }
+
+    /**
+     * Link the snapshot to a Bitmap_Delegate.
+     * <p/>
+     * This is only for the case where the snapshot was created with a null image when calling
+     * {@link #createDefaultSnapshot(Bitmap_Delegate)}, and is therefore not yet linked to
+     * a previous snapshot.
+     * <p/>
+     * If any transform or clip information was set before, they are put into the Graphics object.
+     * @param bitmap the bitmap to link to.
+     */
+    public void setBitmap(Bitmap_Delegate bitmap) {
+        // create a new Layer for the bitmap. This will be the base layer.
+        Graphics2D graphics2D = bitmap.getImage().createGraphics();
+        Layer baseLayer = new Layer(graphics2D, bitmap);
+
+        // Set the current transform and clip which can either come from mTransform/mClip if they
+        // were set when there was no bitmap/layers or from the current base layers if there is
+        // one already.
+
+        graphics2D.setTransform(getTransform());
+        // reset mTransform in case there was one.
+        mTransform = null;
+
+        baseLayer.setClip(getClip());
+        // reset mClip in case there was one.
+        mClip = null;
+
+        // replace whatever current layers we have with this.
+        mLayers.clear();
+        mLayers.add(baseLayer);
+
+    }
+
+    public void translate(float dx, float dy) {
+        if (mLayers.size() > 0) {
+            for (Layer layer : mLayers) {
+                layer.getGraphics().translate(dx, dy);
+            }
+        } else {
+            if (mTransform == null) {
+                mTransform = new AffineTransform();
+            }
+            mTransform.translate(dx, dy);
+        }
+    }
+
+    public void rotate(double radians) {
+        if (mLayers.size() > 0) {
+            for (Layer layer : mLayers) {
+                layer.getGraphics().rotate(radians);
+            }
+        } else {
+            if (mTransform == null) {
+                mTransform = new AffineTransform();
+            }
+            mTransform.rotate(radians);
+        }
+    }
+
+    public void scale(float sx, float sy) {
+        if (mLayers.size() > 0) {
+            for (Layer layer : mLayers) {
+                layer.getGraphics().scale(sx, sy);
+            }
+        } else {
+            if (mTransform == null) {
+                mTransform = new AffineTransform();
+            }
+            mTransform.scale(sx, sy);
+        }
+    }
+
+    public AffineTransform getTransform() {
+        if (mLayers.size() > 0) {
+            // all graphics2D in the list have the same transform
+            return mLayers.get(0).getGraphics().getTransform();
+        } else {
+            if (mTransform == null) {
+                mTransform = new AffineTransform();
+            }
+            return mTransform;
+        }
+    }
+
+    public void setTransform(AffineTransform transform) {
+        if (mLayers.size() > 0) {
+            for (Layer layer : mLayers) {
+                layer.getGraphics().setTransform(transform);
+            }
+        } else {
+            if (mTransform == null) {
+                mTransform = new AffineTransform();
+            }
+            mTransform.setTransform(transform);
+        }
+    }
+
+    public boolean clip(Shape shape, int regionOp) {
+        // Simple case of intersect with existing layers.
+        // Because Graphics2D#setClip works a bit peculiarly, we optimize
+        // the case of clipping by intersection, as it's supported natively.
+        if (regionOp == Region.Op.INTERSECT.nativeInt && mLayers.size() > 0) {
+            for (Layer layer : mLayers) {
+                layer.clip(shape);
+            }
+
+            Shape currentClip = getClip();
+            return currentClip != null && currentClip.getBounds().isEmpty() == false;
+        }
+
+        Area area = null;
+
+        if (regionOp == Region.Op.REPLACE.nativeInt) {
+            area = new Area(shape);
+        } else {
+            area = Region_Delegate.combineShapes(getClip(), shape, regionOp);
+        }
+
+        assert area != null;
+
+        if (mLayers.size() > 0) {
+            if (area != null) {
+                for (Layer layer : mLayers) {
+                    layer.setClip(area);
+                }
+            }
+
+            Shape currentClip = getClip();
+            return currentClip != null && currentClip.getBounds().isEmpty() == false;
+        } else {
+            if (area != null) {
+                mClip = area;
+            } else {
+                mClip = new Area();
+            }
+
+            return mClip.getBounds().isEmpty() == false;
+        }
+    }
+
+    public boolean clipRect(float left, float top, float right, float bottom, int regionOp) {
+        return clip(new Rectangle2D.Float(left, top, right - left, bottom - top), regionOp);
+    }
+
+    /**
+     * Returns the current clip, or null if none have been setup.
+     */
+    public Shape getClip() {
+        if (mLayers.size() > 0) {
+            // they all have the same clip
+            return mLayers.get(0).getGraphics().getClip();
+        } else {
+            return mClip;
+        }
+    }
+
+    private GcSnapshot doRestoreTo(int size, int saveCount) {
+        if (size <= saveCount) {
+            return this;
+        }
+
+        // restore the current one first.
+        GcSnapshot previous = doRestore();
+
+        if (size == saveCount + 1) { // this was the only one that needed restore.
+            return previous;
+        } else {
+            return previous.doRestoreTo(size - 1, saveCount);
+        }
+    }
+
+    /**
+     * Executes the Drawable's draw method, with a null paint delegate.
+     * <p/>
+     * Note that the method can be called several times if there are more than one active layer.
+     * @param drawable
+     */
+    public void draw(Drawable drawable) {
+        draw(drawable, null, false /*compositeOnly*/, false /*forceSrcMode*/);
+    }
+
+    /**
+     * Executes the Drawable's draw method.
+     * <p/>
+     * Note that the method can be called several times if there are more than one active layer.
+     * @param drawable
+     * @param paint
+     * @param compositeOnly whether the paint is used for composite only. This is typically
+     *          the case for bitmaps.
+     * @param forceSrcMode if true, this overrides the composite to be SRC
+     */
+    public void draw(Drawable drawable, Paint_Delegate paint, boolean compositeOnly,
+            boolean forceSrcMode) {
+        // the current snapshot may not have a mLocalLayer (ie it was created on save() instead
+        // of saveLayer(), but that doesn't mean there's no layer.
+        // mLayers however saves all the information we need (flags).
+        if (mLayers.size() == 1) {
+            // no layer, only base layer. easy case.
+            drawInLayer(mLayers.get(0), drawable, paint, compositeOnly, forceSrcMode);
+        } else {
+            // draw in all the layers until the layer save flags tells us to stop (ie drawing
+            // in that layer is limited to the layer itself.
+            int flags;
+            int i = mLayers.size() - 1;
+
+            do {
+                Layer layer = mLayers.get(i);
+
+                drawInLayer(layer, drawable, paint, compositeOnly, forceSrcMode);
+
+                // then go to previous layer, only if there are any left, and its flags
+                // doesn't restrict drawing to the layer itself.
+                i--;
+                flags = layer.getFlags();
+            } while (i >= 0 && (flags & Canvas.CLIP_TO_LAYER_SAVE_FLAG) == 0);
+        }
+    }
+
+    private void drawInLayer(Layer layer, Drawable drawable, Paint_Delegate paint,
+            boolean compositeOnly, boolean forceSrcMode) {
+        Graphics2D originalGraphics = layer.getGraphics();
+        // get a Graphics2D object configured with the drawing parameters.
+        Graphics2D configuredGraphics2D =
+            paint != null ?
+                    createCustomGraphics(originalGraphics, paint, compositeOnly, forceSrcMode) :
+                        (Graphics2D) originalGraphics.create();
+
+        try {
+            drawable.draw(configuredGraphics2D, paint);
+        } finally {
+            // dispose Graphics2D object
+            configuredGraphics2D.dispose();
+        }
+    }
+
+    private GcSnapshot doRestore() {
+        if (mPrevious != null) {
+            if (mLocalLayer != null) {
+                // prepare to blit the layers in which we have draw, in the layer beneath
+                // them, starting with the top one (which is the current local layer).
+                int i = mLayers.size() - 1;
+                int flags;
+                do {
+                    Layer dstLayer = mLayers.get(i - 1);
+
+                    restoreLayer(dstLayer);
+
+                    flags = dstLayer.getFlags();
+                    i--;
+                } while (i > 0 && (flags & Canvas.CLIP_TO_LAYER_SAVE_FLAG) == 0);
+            }
+
+            // if this snapshot does not save everything, then set the previous snapshot
+            // to this snapshot content
+
+            // didn't save the matrix? set the current matrix on the previous snapshot
+            if ((mFlags & Canvas.MATRIX_SAVE_FLAG) == 0) {
+                AffineTransform mtx = getTransform();
+                for (Layer layer : mPrevious.mLayers) {
+                    layer.getGraphics().setTransform(mtx);
+                }
+            }
+
+            // didn't save the clip? set the current clip on the previous snapshot
+            if ((mFlags & Canvas.CLIP_SAVE_FLAG) == 0) {
+                Shape clip = getClip();
+                for (Layer layer : mPrevious.mLayers) {
+                    layer.setClip(clip);
+                }
+            }
+        }
+
+        for (Layer layer : mLayers) {
+            layer.getGraphics().dispose();
+        }
+
+        return mPrevious;
+    }
+
+    private void restoreLayer(Layer dstLayer) {
+
+        Graphics2D baseGfx = dstLayer.getImage().createGraphics();
+
+        // if the layer contains an original copy this means the flags
+        // didn't restrict drawing to the local layer and we need to make sure the
+        // layer bounds in the layer beneath didn't receive any drawing.
+        // so we use the originalCopy to erase the new drawings in there.
+        BufferedImage originalCopy = dstLayer.getOriginalCopy();
+        if (originalCopy != null) {
+            Graphics2D g = (Graphics2D) baseGfx.create();
+            g.setComposite(AlphaComposite.Src);
+
+            g.drawImage(originalCopy,
+                    mLayerBounds.left, mLayerBounds.top, mLayerBounds.right, mLayerBounds.bottom,
+                    0, 0, mLayerBounds.width(), mLayerBounds.height(),
+                    null);
+            g.dispose();
+        }
+
+        // now draw put the content of the local layer onto the layer,
+        // using the paint information
+        Graphics2D g = createCustomGraphics(baseGfx, mLocalLayerPaint,
+                true /*alphaOnly*/, false /*forceSrcMode*/);
+
+        g.drawImage(mLocalLayer.getImage(),
+                mLayerBounds.left, mLayerBounds.top, mLayerBounds.right, mLayerBounds.bottom,
+                mLayerBounds.left, mLayerBounds.top, mLayerBounds.right, mLayerBounds.bottom,
+                null);
+        g.dispose();
+
+        baseGfx.dispose();
+    }
+
+    /**
+     * Creates a new {@link Graphics2D} based on the {@link Paint} parameters.
+     * <p/>The object must be disposed ({@link Graphics2D#dispose()}) after being used.
+     */
+    private Graphics2D createCustomGraphics(Graphics2D original, Paint_Delegate paint,
+            boolean compositeOnly, boolean forceSrcMode) {
+        // make new one graphics
+        Graphics2D g = (Graphics2D) original.create();
+
+        // configure it
+
+        if (paint.isAntiAliased()) {
+            g.setRenderingHint(
+                    RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+            g.setRenderingHint(
+                    RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+        }
+
+        boolean customShader = false;
+
+        // get the shader first, as it'll replace the color if it can be used it.
+        if (compositeOnly == false) {
+            Shader_Delegate shaderDelegate = paint.getShader();
+            if (shaderDelegate != null) {
+                if (shaderDelegate.isSupported()) {
+                    java.awt.Paint shaderPaint = shaderDelegate.getJavaPaint();
+                    assert shaderPaint != null;
+                    if (shaderPaint != null) {
+                        g.setPaint(shaderPaint);
+                        customShader = true;
+                    }
+                } else {
+                    Bridge.getLog().fidelityWarning(LayoutLog.TAG_SHADER,
+                            shaderDelegate.getSupportMessage(),
+                            null /*throwable*/, null /*data*/);
+                }
+            }
+
+            // if no shader, use the paint color
+            if (customShader == false) {
+                g.setColor(new Color(paint.getColor(), true /*hasAlpha*/));
+            }
+
+            // set the stroke
+            g.setStroke(paint.getJavaStroke());
+        }
+
+        // the alpha for the composite. Always opaque if the normal paint color is used since
+        // it contains the alpha
+        int alpha = (compositeOnly || customShader) ? paint.getAlpha() : 0xFF;
+
+        if (forceSrcMode) {
+            g.setComposite(AlphaComposite.getInstance(
+                    AlphaComposite.SRC, (float) alpha / 255.f));
+        } else {
+            boolean customXfermode = false;
+            Xfermode_Delegate xfermodeDelegate = paint.getXfermode();
+            if (xfermodeDelegate != null) {
+                if (xfermodeDelegate.isSupported()) {
+                    Composite composite = xfermodeDelegate.getComposite(alpha);
+                    assert composite != null;
+                    if (composite != null) {
+                        g.setComposite(composite);
+                        customXfermode = true;
+                    }
+                } else {
+                    Bridge.getLog().fidelityWarning(LayoutLog.TAG_XFERMODE,
+                            xfermodeDelegate.getSupportMessage(),
+                            null /*throwable*/, null /*data*/);
+                }
+            }
+
+            // if there was no custom xfermode, but we have alpha (due to a shader and a non
+            // opaque alpha channel in the paint color), then we create an AlphaComposite anyway
+            // that will handle the alpha.
+            if (customXfermode == false && alpha != 0xFF) {
+                g.setComposite(AlphaComposite.getInstance(
+                        AlphaComposite.SRC_OVER, (float) alpha / 255.f));
+            }
+        }
+
+        return g;
+    }
+
+    private void mapRect(AffineTransform matrix, RectF dst, RectF src) {
+        // array with 4 corners
+        float[] corners = new float[] {
+                src.left, src.top,
+                src.right, src.top,
+                src.right, src.bottom,
+                src.left, src.bottom,
+        };
+
+        // apply the transform to them.
+        matrix.transform(corners, 0, corners, 0, 4);
+
+        // now put the result in the rect. We take the min/max of Xs and min/max of Ys
+        dst.left = Math.min(Math.min(corners[0], corners[2]), Math.min(corners[4], corners[6]));
+        dst.right = Math.max(Math.max(corners[0], corners[2]), Math.max(corners[4], corners[6]));
+
+        dst.top = Math.min(Math.min(corners[1], corners[3]), Math.min(corners[5], corners[7]));
+        dst.bottom = Math.max(Math.max(corners[1], corners[3]), Math.max(corners[5], corners[7]));
+    }
+
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
new file mode 100644
index 0000000..8e80c21
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.impl;
+
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_LOCK_INTERRUPTED;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_TIMEOUT;
+import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
+
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.RenderParams;
+import com.android.ide.common.rendering.api.RenderResources;
+import com.android.ide.common.rendering.api.Result;
+import com.android.ide.common.rendering.api.RenderResources.FrameworkResourceIdProvider;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.resources.ResourceType;
+
+import android.util.DisplayMetrics;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Base class for rendering action.
+ *
+ * It provides life-cycle methods to init and stop the rendering.
+ * The most important methods are:
+ * {@link #init(long)} and {@link #acquire(long)} to start a rendering and {@link #release()}
+ * after the rendering.
+ *
+ *
+ * @param <T> the {@link RenderParams} implementation
+ *
+ */
+public abstract class RenderAction<T extends RenderParams> extends FrameworkResourceIdProvider {
+
+    /**
+     * The current context being rendered. This is set through {@link #acquire(long)} and
+     * {@link #init(long)}, and unset in {@link #release()}.
+     */
+    private static BridgeContext sCurrentContext = null;
+
+    private final T mParams;
+
+    private BridgeContext mContext;
+
+    /**
+     * Creates a renderAction.
+     * <p>
+     * This <b>must</b> be followed by a call to {@link RenderAction#init()}, which act as a
+     * call to {@link RenderAction#acquire(long)}
+     *
+     * @param params the RenderParams. This must be a copy that the action can keep
+     *
+     */
+    protected RenderAction(T params) {
+        mParams = params;
+    }
+
+    /**
+     * Initializes and acquires the scene, creating various Android objects such as context,
+     * inflater, and parser.
+     *
+     * @param timeout the time to wait if another rendering is happening.
+     *
+     * @return whether the scene was prepared
+     *
+     * @see #acquire(long)
+     * @see #release()
+     */
+    public Result init(long timeout) {
+        // acquire the lock. if the result is null, lock was just acquired, otherwise, return
+        // the result.
+        Result result = acquireLock(timeout);
+        if (result != null) {
+            return result;
+        }
+
+        // setup the display Metrics.
+        DisplayMetrics metrics = new DisplayMetrics();
+        metrics.densityDpi = mParams.getDensity().getDpiValue();
+        metrics.density = metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT;
+        metrics.scaledDensity = metrics.density;
+        metrics.widthPixels = mParams.getScreenWidth();
+        metrics.heightPixels = mParams.getScreenHeight();
+        metrics.xdpi = mParams.getXdpi();
+        metrics.ydpi = mParams.getYdpi();
+
+        RenderResources resources = mParams.getResources();
+
+        // build the context
+        mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources,
+                mParams.getProjectCallback(), mParams.getTargetSdkVersion());
+
+        setUp();
+
+        return SUCCESS.createResult();
+    }
+
+    /**
+     * Prepares the scene for action.
+     * <p>
+     * This call is blocking if another rendering/inflating is currently happening, and will return
+     * whether the preparation worked.
+     *
+     * The preparation can fail if another rendering took too long and the timeout was elapsed.
+     *
+     * More than one call to this from the same thread will have no effect and will return
+     * {@link Result#SUCCESS}.
+     *
+     * After scene actions have taken place, only one call to {@link #release()} must be
+     * done.
+     *
+     * @param timeout the time to wait if another rendering is happening.
+     *
+     * @return whether the scene was prepared
+     *
+     * @see #release()
+     *
+     * @throws IllegalStateException if {@link #init(long)} was never called.
+     */
+    public Result acquire(long timeout) {
+        if (mContext == null) {
+            throw new IllegalStateException("After scene creation, #init() must be called");
+        }
+
+        // acquire the lock. if the result is null, lock was just acquired, otherwise, return
+        // the result.
+        Result result = acquireLock(timeout);
+        if (result != null) {
+            return result;
+        }
+
+        setUp();
+
+        return SUCCESS.createResult();
+    }
+
+    /**
+     * Acquire the lock so that the scene can be acted upon.
+     * <p>
+     * This returns null if the lock was just acquired, otherwise it returns
+     * {@link Result#SUCCESS} if the lock already belonged to that thread, or another
+     * instance (see {@link Result#getStatus()}) if an error occurred.
+     *
+     * @param timeout the time to wait if another rendering is happening.
+     * @return null if the lock was just acquire or another result depending on the state.
+     *
+     * @throws IllegalStateException if the current context is different than the one owned by
+     *      the scene.
+     */
+    private Result acquireLock(long timeout) {
+        ReentrantLock lock = Bridge.getLock();
+        if (lock.isHeldByCurrentThread() == false) {
+            try {
+                boolean acquired = lock.tryLock(timeout, TimeUnit.MILLISECONDS);
+
+                if (acquired == false) {
+                    return ERROR_TIMEOUT.createResult();
+                }
+            } catch (InterruptedException e) {
+                return ERROR_LOCK_INTERRUPTED.createResult();
+            }
+        } else {
+            // This thread holds the lock already. Checks that this wasn't for a different context.
+            // If this is called by init, mContext will be null and so should sCurrentContext
+            // anyway
+            if (mContext != sCurrentContext) {
+                throw new IllegalStateException("Acquiring different scenes from same thread without releases");
+            }
+            return SUCCESS.createResult();
+        }
+
+        return null;
+    }
+
+    /**
+     * Cleans up the scene after an action.
+     */
+    public void release() {
+        ReentrantLock lock = Bridge.getLock();
+
+        // with the use of finally blocks, it is possible to find ourself calling this
+        // without a successful call to prepareScene. This test makes sure that unlock() will
+        // not throw IllegalMonitorStateException.
+        if (lock.isHeldByCurrentThread()) {
+            tearDown();
+            lock.unlock();
+        }
+    }
+
+    /**
+     * Sets up the session for rendering.
+     * <p/>
+     * The counterpart is {@link #tearDown()}.
+     */
+    private void setUp() {
+        // make sure the Resources object references the context (and other objects) for this
+        // scene
+        mContext.initResources();
+        sCurrentContext = mContext;
+
+        LayoutLog currentLog = mParams.getLog();
+        Bridge.setLog(currentLog);
+        mContext.getRenderResources().setFrameworkResourceIdProvider(this);
+        mContext.getRenderResources().setLogger(currentLog);
+    }
+
+    /**
+     * Tear down the session after rendering.
+     * <p/>
+     * The counterpart is {@link #setUp()}.
+     */
+    private void tearDown() {
+        // Make sure to remove static references, otherwise we could not unload the lib
+        mContext.disposeResources();
+        sCurrentContext = null;
+
+        Bridge.setLog(null);
+        mContext.getRenderResources().setFrameworkResourceIdProvider(null);
+        mContext.getRenderResources().setLogger(null);
+    }
+
+    public static BridgeContext getCurrentContext() {
+        return sCurrentContext;
+    }
+
+    protected T getParams() {
+        return mParams;
+    }
+
+    protected BridgeContext getContext() {
+        return mContext;
+    }
+
+    /**
+     * Returns the log associated with the session.
+     * @return the log or null if there are none.
+     */
+    public LayoutLog getLog() {
+        if (mParams != null) {
+            return mParams.getLog();
+        }
+
+        return null;
+    }
+
+    /**
+     * Checks that the lock is owned by the current thread and that the current context is the one
+     * from this scene.
+     *
+     * @throws IllegalStateException if the current context is different than the one owned by
+     *      the scene, or if {@link #acquire(long)} was not called.
+     */
+    protected void checkLock() {
+        ReentrantLock lock = Bridge.getLock();
+        if (lock.isHeldByCurrentThread() == false) {
+            throw new IllegalStateException("scene must be acquired first. see #acquire(long)");
+        }
+        if (sCurrentContext != mContext) {
+            throw new IllegalStateException("Thread acquired a scene but is rendering a different one");
+        }
+    }
+
+    // --- FrameworkResourceIdProvider methods
+
+    @Override
+    public Integer getId(ResourceType resType, String resName) {
+        return Bridge.getResourceId(resType, resName);
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
new file mode 100644
index 0000000..10a4368
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.impl;
+
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
+
+import com.android.ide.common.rendering.api.DrawableParams;
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.ide.common.rendering.api.Result;
+import com.android.ide.common.rendering.api.Result.Status;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.android.BridgeWindow;
+import com.android.layoutlib.bridge.android.BridgeWindowSession;
+import com.android.resources.ResourceType;
+
+import android.graphics.Bitmap;
+import android.graphics.Bitmap_Delegate;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.view.View;
+import android.view.View.AttachInfo;
+import android.view.View.MeasureSpec;
+import android.widget.FrameLayout;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+/**
+ * Action to render a given Drawable provided through {@link DrawableParams#getDrawable()}.
+ *
+ * The class only provides a simple {@link #render()} method, but the full life-cycle of the
+ * action must be respected.
+ *
+ * @see RenderAction
+ *
+ */
+public class RenderDrawable extends RenderAction<DrawableParams> {
+
+    public RenderDrawable(DrawableParams params) {
+        super(new DrawableParams(params));
+    }
+
+    public Result render() {
+        checkLock();
+        try {
+            // get the drawable resource value
+            DrawableParams params = getParams();
+            ResourceValue drawableResource = params.getDrawable();
+
+            // resolve it
+            BridgeContext context = getContext();
+            drawableResource = context.getRenderResources().resolveResValue(drawableResource);
+
+            if (drawableResource == null ||
+                    drawableResource.getResourceType() != ResourceType.DRAWABLE) {
+                return Status.ERROR_NOT_A_DRAWABLE.createResult();
+            }
+
+            // create a simple FrameLayout
+            FrameLayout content = new FrameLayout(context);
+
+            // get the actual Drawable object to draw
+            Drawable d = ResourceHelper.getDrawable(drawableResource, context);
+            content.setBackgroundDrawable(d);
+
+            // set the AttachInfo on the root view.
+            AttachInfo info = new AttachInfo(new BridgeWindowSession(), new BridgeWindow(),
+                    new Handler(), null);
+            info.mHasWindowFocus = true;
+            info.mWindowVisibility = View.VISIBLE;
+            info.mInTouchMode = false; // this is so that we can display selections.
+            content.dispatchAttachedToWindow(info, 0);
+
+
+            // measure
+            int w = params.getScreenWidth();
+            int h = params.getScreenHeight();
+            int w_spec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY);
+            int h_spec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
+            content.measure(w_spec, h_spec);
+
+            // now do the layout.
+            content.layout(0, 0, w, h);
+
+            // preDraw setup
+            content.mAttachInfo.mTreeObserver.dispatchOnPreDraw();
+
+            // draw into a new image
+            BufferedImage image = getImage(w, h);
+
+            // create an Android bitmap around the BufferedImage
+            Bitmap bitmap = Bitmap_Delegate.createBitmap(image,
+                    true /*isMutable*/, params.getDensity());
+
+            // create a Canvas around the Android bitmap
+            Canvas canvas = new Canvas(bitmap);
+            canvas.setDensity(params.getDensity().getDpiValue());
+
+            // and draw
+            content.draw(canvas);
+
+            return Status.SUCCESS.createResult(image);
+        } catch (IOException e) {
+            return ERROR_UNKNOWN.createResult(e.getMessage(), e);
+        }
+    }
+
+    protected BufferedImage getImage(int w, int h) {
+        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
+        Graphics2D gc = image.createGraphics();
+        gc.setComposite(AlphaComposite.Src);
+
+        gc.setColor(new Color(0x00000000, true));
+        gc.fillRect(0, 0, w, h);
+
+        // done
+        gc.dispose();
+
+        return image;
+    }
+
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
new file mode 100644
index 0000000..cfc047f
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -0,0 +1,1007 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.impl;
+
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_VIEWGROUP_NO_CHILDREN;
+import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
+
+import com.android.ide.common.rendering.api.IAnimationListener;
+import com.android.ide.common.rendering.api.ILayoutPullParser;
+import com.android.ide.common.rendering.api.IProjectCallback;
+import com.android.ide.common.rendering.api.RenderParams;
+import com.android.ide.common.rendering.api.RenderResources;
+import com.android.ide.common.rendering.api.RenderSession;
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.ide.common.rendering.api.Result;
+import com.android.ide.common.rendering.api.SessionParams;
+import com.android.ide.common.rendering.api.ViewInfo;
+import com.android.ide.common.rendering.api.Result.Status;
+import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
+import com.android.internal.util.XmlUtils;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.android.BridgeInflater;
+import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes;
+import com.android.layoutlib.bridge.android.BridgeWindow;
+import com.android.layoutlib.bridge.android.BridgeWindowSession;
+import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
+import com.android.layoutlib.bridge.bars.PhoneSystemBar;
+import com.android.layoutlib.bridge.bars.TitleBar;
+import com.android.resources.ResourceType;
+import com.android.resources.ScreenSize;
+import com.android.util.Pair;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.graphics.Bitmap;
+import android.graphics.Bitmap_Delegate;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.AttachInfo;
+import android.view.View.MeasureSpec;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.TabHost;
+import android.widget.TabWidget;
+import android.widget.TabHost.TabSpec;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Class implementing the render session.
+ *
+ * A session is a stateful representation of a layout file. It is initialized with data coming
+ * through the {@link Bridge} API to inflate the layout. Further actions and rendering can then
+ * be done on the layout.
+ *
+ */
+public class RenderSessionImpl extends RenderAction<SessionParams> {
+
+    private static final int DEFAULT_TITLE_BAR_HEIGHT = 25;
+    private static final int DEFAULT_STATUS_BAR_HEIGHT = 25;
+
+    // scene state
+    private RenderSession mScene;
+    private BridgeXmlBlockParser mBlockParser;
+    private BridgeInflater mInflater;
+    private ResourceValue mWindowBackground;
+    private ViewGroup mViewRoot;
+    private FrameLayout mContentRoot;
+    private Canvas mCanvas;
+    private int mMeasuredScreenWidth = -1;
+    private int mMeasuredScreenHeight = -1;
+    private boolean mIsAlphaChannelImage;
+    private boolean mWindowIsFloating;
+
+    private int mStatusBarSize;
+    private int mTitleBarSize;
+
+
+    // information being returned through the API
+    private BufferedImage mImage;
+    private List<ViewInfo> mViewInfoList;
+
+    private static final class PostInflateException extends Exception {
+        private static final long serialVersionUID = 1L;
+
+        public PostInflateException(String message) {
+            super(message);
+        }
+    }
+
+    /**
+     * Creates a layout scene with all the information coming from the layout bridge API.
+     * <p>
+     * This <b>must</b> be followed by a call to {@link RenderSessionImpl#init()}, which act as a
+     * call to {@link RenderSessionImpl#acquire(long)}
+     *
+     * @see LayoutBridge#createScene(com.android.layoutlib.api.SceneParams)
+     */
+    public RenderSessionImpl(SessionParams params) {
+        super(new SessionParams(params));
+    }
+
+    /**
+     * Initializes and acquires the scene, creating various Android objects such as context,
+     * inflater, and parser.
+     *
+     * @param timeout the time to wait if another rendering is happening.
+     *
+     * @return whether the scene was prepared
+     *
+     * @see #acquire(long)
+     * @see #release()
+     */
+    @Override
+    public Result init(long timeout) {
+        Result result = super.init(timeout);
+        if (result.isSuccess() == false) {
+            return result;
+        }
+
+        SessionParams params = getParams();
+        BridgeContext context = getContext();
+
+        RenderResources resources = getParams().getResources();
+        DisplayMetrics metrics = getContext().getMetrics();
+
+        // use default of true in case it's not found to use alpha by default
+        mIsAlphaChannelImage  = getBooleanThemeValue(resources,
+                "windowIsFloating", true /*defaultValue*/);
+
+        mWindowIsFloating = getBooleanThemeValue(resources, "windowIsFloating",
+                true /*defaultValue*/);
+
+        findBackground(resources);
+        findStatusBar(resources, metrics);
+        findTitleBar(resources, metrics);
+
+        // build the inflater and parser.
+        mInflater = new BridgeInflater(context, params.getProjectCallback());
+        context.setBridgeInflater(mInflater);
+
+        mBlockParser = new BridgeXmlBlockParser(
+                params.getLayoutDescription(), context, false /* platformResourceFlag */);
+
+        return SUCCESS.createResult();
+    }
+
+    /**
+     * Inflates the layout.
+     * <p>
+     * {@link #acquire(long)} must have been called before this.
+     *
+     * @throws IllegalStateException if the current context is different than the one owned by
+     *      the scene, or if {@link #init(long)} was not called.
+     */
+    public Result inflate() {
+        checkLock();
+
+        try {
+
+            SessionParams params = getParams();
+            BridgeContext context = getContext();
+
+            // the view group that receives the window background.
+            ViewGroup backgroundView = null;
+
+            if (mWindowIsFloating || params.isForceNoDecor()) {
+                backgroundView = mViewRoot = mContentRoot = new FrameLayout(context);
+            } else {
+                /*
+                 * we're creating the following layout
+                 *
+                   +-------------------------------------------------+
+                   | System bar                                      |
+                   +-------------------------------------------------+
+                   | (Layout with background drawable)               |
+                   | +---------------------------------------------+ |
+                   | | Title (optional)                            | |
+                   | +---------------------------------------------+ |
+                   | | Content, vertical extending                 | |
+                   | |                                             | |
+                   | +---------------------------------------------+ |
+                   +-------------------------------------------------+
+
+                 */
+
+                LinearLayout topLayout = new LinearLayout(context);
+                mViewRoot = topLayout;
+                topLayout.setOrientation(LinearLayout.VERTICAL);
+
+                if (mStatusBarSize > 0) {
+                    // system bar
+                    try {
+                        PhoneSystemBar systemBar = new PhoneSystemBar(context,
+                                params.getDensity());
+                        systemBar.setLayoutParams(
+                                new LinearLayout.LayoutParams(
+                                        LayoutParams.MATCH_PARENT, mStatusBarSize));
+                        topLayout.addView(systemBar);
+                    } catch (XmlPullParserException e) {
+
+                    }
+                }
+
+                LinearLayout backgroundLayout = new LinearLayout(context);
+                backgroundView = backgroundLayout;
+                backgroundLayout.setOrientation(LinearLayout.VERTICAL);
+                LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
+                        LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+                layoutParams.weight = 1;
+                backgroundLayout.setLayoutParams(layoutParams);
+                topLayout.addView(backgroundLayout);
+
+
+                // if the theme says no title, then the size will be 0
+                if (mTitleBarSize > 0) {
+                    try {
+                        TitleBar titleBar = new TitleBar(context,
+                                params.getDensity(), params.getAppLabel());
+                        titleBar.setLayoutParams(
+                                new LinearLayout.LayoutParams(
+                                        LayoutParams.MATCH_PARENT, mTitleBarSize));
+                        backgroundLayout.addView(titleBar);
+                    } catch (XmlPullParserException e) {
+
+                    }
+                }
+
+                // content frame
+                mContentRoot = new FrameLayout(context);
+                layoutParams = new LinearLayout.LayoutParams(
+                        LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+                layoutParams.weight = 1;
+                mContentRoot.setLayoutParams(layoutParams);
+                backgroundLayout.addView(mContentRoot);
+            }
+
+
+            View view = mInflater.inflate(mBlockParser, mContentRoot);
+
+            // set the AttachInfo on the root view.
+            AttachInfo info = new AttachInfo(new BridgeWindowSession(), new BridgeWindow(),
+                    new Handler(), null);
+            info.mHasWindowFocus = true;
+            info.mWindowVisibility = View.VISIBLE;
+            info.mInTouchMode = false; // this is so that we can display selections.
+            mViewRoot.dispatchAttachedToWindow(info, 0);
+
+            // post-inflate process. For now this supports TabHost/TabWidget
+            postInflateProcess(view, params.getProjectCallback());
+
+            // get the background drawable
+            if (mWindowBackground != null && backgroundView != null) {
+                Drawable d = ResourceHelper.getDrawable(mWindowBackground, context);
+                backgroundView.setBackgroundDrawable(d);
+            }
+
+            return SUCCESS.createResult();
+        } catch (PostInflateException e) {
+            return ERROR_INFLATION.createResult(e.getMessage(), e);
+        } catch (Throwable e) {
+            // get the real cause of the exception.
+            Throwable t = e;
+            while (t.getCause() != null) {
+                t = t.getCause();
+            }
+
+            return ERROR_INFLATION.createResult(t.getMessage(), t);
+        }
+    }
+
+    /**
+     * Renders the scene.
+     * <p>
+     * {@link #acquire(long)} must have been called before this.
+     *
+     * @param freshRender whether the render is a new one and should erase the existing bitmap (in
+     *      the case where bitmaps are reused). This is typically needed when not playing
+     *      animations.)
+     *
+     * @throws IllegalStateException if the current context is different than the one owned by
+     *      the scene, or if {@link #acquire(long)} was not called.
+     *
+     * @see RenderParams#getRenderingMode()
+     * @see RenderSession#render(long)
+     */
+    public Result render(boolean freshRender) {
+        checkLock();
+
+        SessionParams params = getParams();
+
+        try {
+            if (mViewRoot == null) {
+                return ERROR_NOT_INFLATED.createResult();
+            }
+            // measure the views
+            int w_spec, h_spec;
+
+            RenderingMode renderingMode = params.getRenderingMode();
+
+            // only do the screen measure when needed.
+            boolean newRenderSize = false;
+            if (mMeasuredScreenWidth == -1) {
+                newRenderSize = true;
+                mMeasuredScreenWidth = params.getScreenWidth();
+                mMeasuredScreenHeight = params.getScreenHeight();
+
+                if (renderingMode != RenderingMode.NORMAL) {
+                    // measure the full size needed by the layout.
+                    w_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenWidth,
+                            renderingMode.isHorizExpand() ?
+                                    MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
+                                    : MeasureSpec.EXACTLY);
+                    h_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenHeight,
+                            renderingMode.isVertExpand() ?
+                                    MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
+                                    : MeasureSpec.EXACTLY);
+                    mViewRoot.measure(w_spec, h_spec);
+
+                    if (renderingMode.isHorizExpand()) {
+                        int neededWidth = mViewRoot.getChildAt(0).getMeasuredWidth();
+                        if (neededWidth > mMeasuredScreenWidth) {
+                            mMeasuredScreenWidth = neededWidth;
+                        }
+                    }
+
+                    if (renderingMode.isVertExpand()) {
+                        int neededHeight = mViewRoot.getChildAt(0).getMeasuredHeight();
+                        if (neededHeight > mMeasuredScreenHeight) {
+                            mMeasuredScreenHeight = neededHeight;
+                        }
+                    }
+                }
+            }
+
+            // remeasure with the size we need
+            // This must always be done before the call to layout
+            w_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenWidth, MeasureSpec.EXACTLY);
+            h_spec = MeasureSpec.makeMeasureSpec(mMeasuredScreenHeight, MeasureSpec.EXACTLY);
+            mViewRoot.measure(w_spec, h_spec);
+
+            // now do the layout.
+            mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
+
+            if (params.isLayoutOnly()) {
+                // delete the canvas and image to reset them on the next full rendering
+                mImage = null;
+                mCanvas = null;
+            } else {
+                mViewRoot.mAttachInfo.mTreeObserver.dispatchOnPreDraw();
+
+                // draw the views
+                // create the BufferedImage into which the layout will be rendered.
+                boolean newImage = false;
+                if (newRenderSize || mCanvas == null) {
+                    if (params.getImageFactory() != null) {
+                        mImage = params.getImageFactory().getImage(
+                                mMeasuredScreenWidth,
+                                mMeasuredScreenHeight);
+                    } else {
+                        mImage = new BufferedImage(
+                                mMeasuredScreenWidth,
+                                mMeasuredScreenHeight,
+                                BufferedImage.TYPE_INT_ARGB);
+                        newImage = true;
+                    }
+
+                    if (params.isBgColorOverridden()) {
+                        // since we override the content, it's the same as if it was a new image.
+                        newImage = true;
+                        Graphics2D gc = mImage.createGraphics();
+                        gc.setColor(new Color(params.getOverrideBgColor(), true));
+                        gc.setComposite(AlphaComposite.Src);
+                        gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
+                        gc.dispose();
+                    }
+
+                    // create an Android bitmap around the BufferedImage
+                    Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage,
+                            true /*isMutable*/, params.getDensity());
+
+                    // create a Canvas around the Android bitmap
+                    mCanvas = new Canvas(bitmap);
+                    mCanvas.setDensity(params.getDensity().getDpiValue());
+                }
+
+                if (freshRender && newImage == false) {
+                    Graphics2D gc = mImage.createGraphics();
+                    gc.setComposite(AlphaComposite.Src);
+
+                    gc.setColor(new Color(0x00000000, true));
+                    gc.fillRect(0, 0,
+                            mMeasuredScreenWidth, mMeasuredScreenHeight);
+
+                    // done
+                    gc.dispose();
+                }
+
+                mViewRoot.draw(mCanvas);
+            }
+
+            mViewInfoList = startVisitingViews(mViewRoot, 0);
+
+            // success!
+            return SUCCESS.createResult();
+        } catch (Throwable e) {
+            // get the real cause of the exception.
+            Throwable t = e;
+            while (t.getCause() != null) {
+                t = t.getCause();
+            }
+
+            return ERROR_UNKNOWN.createResult(t.getMessage(), t);
+        }
+    }
+
+    /**
+     * Insert a new child into an existing parent.
+     * <p>
+     * {@link #acquire(long)} must have been called before this.
+     *
+     * @throws IllegalStateException if the current context is different than the one owned by
+     *      the scene, or if {@link #acquire(long)} was not called.
+     *
+     * @see RenderSession#insertChild(Object, ILayoutPullParser, int, IAnimationListener)
+     */
+    public Result insertChild(final ViewGroup parentView, ILayoutPullParser childXml,
+            final int index, final IAnimationListener listener) {
+        checkLock();
+
+        BridgeContext context = getContext();
+
+        // create a block parser for the XML
+        BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
+                childXml, context, false /* platformResourceFlag */);
+
+        // inflate the child without adding it to the root since we want to control where it'll
+        // get added. We do pass the parentView however to ensure that the layoutParams will
+        // be created correctly.
+        final View child = mInflater.inflate(blockParser, parentView, false /*attachToRoot*/);
+        blockParser.ensurePopped();
+
+        invalidateRenderingSize();
+
+        if (listener != null) {
+            // there is no support for animating views in this API level, so we fake the animation
+            // through a no animation thread.
+            new Thread("not animated insertChild") {
+                @Override
+                public void run() {
+                    Result result = addView(parentView, child, index);
+                    if (result.isSuccess() == false) {
+                        listener.done(result);
+                    }
+
+                    // ready to do the work, acquire the scene.
+                    result = acquire(250);
+                    if (result.isSuccess() == false) {
+                        listener.done(result);
+                        return;
+                    }
+
+                    try {
+                        result = render(false /*freshRender*/);
+                        if (result.isSuccess()) {
+                            listener.onNewFrame(RenderSessionImpl.this.getSession());
+                        }
+                    } finally {
+                        release();
+                    }
+
+                    listener.done(result);
+                }
+            }.start();
+
+            // always return success since the real status will come through the listener.
+            return SUCCESS.createResult(child);
+        }
+
+        // add it to the parentView in the correct location
+        Result result = addView(parentView, child, index);
+        if (result.isSuccess() == false) {
+            return result;
+        }
+
+        result = render(false /*freshRender*/);
+        if (result.isSuccess()) {
+            result = result.getCopyWithData(child);
+        }
+
+        return result;
+    }
+
+    /**
+     * Adds a given view to a given parent at a given index.
+     *
+     * @param parent the parent to receive the view
+     * @param view the view to add to the parent
+     * @param index the index where to do the add.
+     *
+     * @return a Result with {@link Status#SUCCESS} or
+     *     {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
+     *     adding views.
+     */
+    private Result addView(ViewGroup parent, View view, int index) {
+        try {
+            parent.addView(view, index);
+            return SUCCESS.createResult();
+        } catch (UnsupportedOperationException e) {
+            // looks like this is a view class that doesn't support children manipulation!
+            return ERROR_VIEWGROUP_NO_CHILDREN.createResult();
+        }
+    }
+
+    /**
+     * Moves a view to a new parent at a given location
+     * <p>
+     * {@link #acquire(long)} must have been called before this.
+     *
+     * @throws IllegalStateException if the current context is different than the one owned by
+     *      the scene, or if {@link #acquire(long)} was not called.
+     *
+     * @see RenderSession#moveChild(Object, Object, int, Map, IAnimationListener)
+     */
+    public Result moveChild(final ViewGroup newParentView, final View childView, final int index,
+            Map<String, String> layoutParamsMap, final IAnimationListener listener) {
+        checkLock();
+
+        invalidateRenderingSize();
+
+        LayoutParams layoutParams = null;
+        if (layoutParamsMap != null) {
+            // need to create a new LayoutParams object for the new parent.
+            layoutParams = newParentView.generateLayoutParams(
+                    new BridgeLayoutParamsMapAttributes(layoutParamsMap));
+        }
+
+        // get the current parent of the view that needs to be moved.
+        final ViewGroup previousParent = (ViewGroup) childView.getParent();
+
+        if (listener != null) {
+            final LayoutParams params = layoutParams;
+
+            // there is no support for animating views in this API level, so we fake the animation
+            // through a no animation thread.
+            new Thread("not animated moveChild") {
+                @Override
+                public void run() {
+                    Result result = moveView(previousParent, newParentView, childView, index,
+                            params);
+                    if (result.isSuccess() == false) {
+                        listener.done(result);
+                    }
+
+                    // ready to do the work, acquire the scene.
+                    result = acquire(250);
+                    if (result.isSuccess() == false) {
+                        listener.done(result);
+                        return;
+                    }
+
+                    try {
+                        result = render(false /*freshRender*/);
+                        if (result.isSuccess()) {
+                            listener.onNewFrame(RenderSessionImpl.this.getSession());
+                        }
+                    } finally {
+                        release();
+                    }
+
+                    listener.done(result);
+                }
+            }.start();
+
+            // always return success since the real status will come through the listener.
+            return SUCCESS.createResult(layoutParams);
+        }
+
+        Result result = moveView(previousParent, newParentView, childView, index, layoutParams);
+        if (result.isSuccess() == false) {
+            return result;
+        }
+
+        result = render(false /*freshRender*/);
+        if (layoutParams != null && result.isSuccess()) {
+            result = result.getCopyWithData(layoutParams);
+        }
+
+        return result;
+    }
+
+    /**
+     * Moves a View from its current parent to a new given parent at a new given location, with
+     * an optional new {@link LayoutParams} instance
+     *
+     * @param previousParent the previous parent, still owning the child at the time of the call.
+     * @param newParent the new parent
+     * @param movedView the view to move
+     * @param index the new location in the new parent
+     * @param params an option (can be null) {@link LayoutParams} instance.
+     *
+     * @return a Result with {@link Status#SUCCESS} or
+     *     {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
+     *     adding views.
+     */
+    private Result moveView(ViewGroup previousParent, final ViewGroup newParent,
+            final View movedView, final int index, final LayoutParams params) {
+        try {
+            // standard code with no animation. pretty simple.
+            previousParent.removeView(movedView);
+
+            // add it to the parentView in the correct location
+            if (params != null) {
+                newParent.addView(movedView, index, params);
+            } else {
+                newParent.addView(movedView, index);
+            }
+
+            return SUCCESS.createResult();
+        } catch (UnsupportedOperationException e) {
+            // looks like this is a view class that doesn't support children manipulation!
+            return ERROR_VIEWGROUP_NO_CHILDREN.createResult();
+        }
+    }
+
+    /**
+     * Removes a child from its current parent.
+     * <p>
+     * {@link #acquire(long)} must have been called before this.
+     *
+     * @throws IllegalStateException if the current context is different than the one owned by
+     *      the scene, or if {@link #acquire(long)} was not called.
+     *
+     * @see RenderSession#removeChild(Object, IAnimationListener)
+     */
+    public Result removeChild(final View childView, final IAnimationListener listener) {
+        checkLock();
+
+        invalidateRenderingSize();
+
+        final ViewGroup parent = (ViewGroup) childView.getParent();
+
+        if (listener != null) {
+            // there is no support for animating views in this API level, so we fake the animation
+            // through a no animation thread.
+            new Thread("not animated moveChild") {
+                @Override
+                public void run() {
+                    Result result = removeView(parent, childView);
+                    if (result.isSuccess() == false) {
+                        listener.done(result);
+                    }
+
+                    // ready to do the work, acquire the scene.
+                    result = acquire(250);
+                    if (result.isSuccess() == false) {
+                        listener.done(result);
+                        return;
+                    }
+
+                    try {
+                        result = render(false /*freshRender*/);
+                        if (result.isSuccess()) {
+                            listener.onNewFrame(RenderSessionImpl.this.getSession());
+                        }
+                    } finally {
+                        release();
+                    }
+
+                    listener.done(result);
+                }
+            }.start();
+
+            // always return success since the real status will come through the listener.
+            return SUCCESS.createResult();
+        }
+
+        Result result = removeView(parent, childView);
+        if (result.isSuccess() == false) {
+            return result;
+        }
+
+        return render(false /*freshRender*/);
+    }
+
+    /**
+     * Removes a given view from its current parent.
+     *
+     * @param view the view to remove from its parent
+     *
+     * @return a Result with {@link Status#SUCCESS} or
+     *     {@link Status#ERROR_VIEWGROUP_NO_CHILDREN} if the given parent doesn't support
+     *     adding views.
+     */
+    private Result removeView(ViewGroup parent, View view) {
+        try {
+            parent.removeView(view);
+            return SUCCESS.createResult();
+        } catch (UnsupportedOperationException e) {
+            // looks like this is a view class that doesn't support children manipulation!
+            return ERROR_VIEWGROUP_NO_CHILDREN.createResult();
+        }
+    }
+
+
+    private void findBackground(RenderResources resources) {
+        if (getParams().isBgColorOverridden() == false) {
+            mWindowBackground = resources.findItemInTheme("windowBackground");
+            if (mWindowBackground != null) {
+                mWindowBackground = resources.resolveResValue(mWindowBackground);
+            }
+        }
+    }
+
+    private void findStatusBar(RenderResources resources, DisplayMetrics metrics) {
+        boolean windowFullscreen = getBooleanThemeValue(resources,
+                "windowFullscreen", false /*defaultValue*/);
+
+        if (windowFullscreen == false && mWindowIsFloating == false) {
+            // default value
+            mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT;
+
+            // get the real value
+            ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN,
+                    "status_bar_height");
+
+            if (value != null) {
+                TypedValue typedValue = ResourceHelper.getValue(value.getValue());
+                if (typedValue != null) {
+                    // compute the pixel value based on the display metrics
+                    mStatusBarSize = (int)typedValue.getDimension(metrics);
+                }
+            }
+        }
+    }
+
+    private void findTitleBar(RenderResources resources, DisplayMetrics metrics) {
+        if (mWindowIsFloating) {
+            return;
+        }
+
+        boolean windowNoTitle = getBooleanThemeValue(resources,
+                "windowNoTitle", false /*defaultValue*/);
+
+        if (windowNoTitle == false) {
+
+            // default size of the window title bar
+            mTitleBarSize = DEFAULT_TITLE_BAR_HEIGHT;
+
+            // get value from the theme.
+            ResourceValue value = resources.findItemInTheme("windowTitleSize");
+
+            // resolve it
+            value = resources.resolveResValue(value);
+
+            if (value != null) {
+                // get the numerical value, if available
+                TypedValue typedValue = ResourceHelper.getValue(value.getValue());
+                if (typedValue != null) {
+                    // compute the pixel value based on the display metrics
+                    mTitleBarSize = (int)typedValue.getDimension(metrics);
+                }
+            }
+        }
+    }
+
+    private boolean getBooleanThemeValue(RenderResources resources,
+            String name, boolean defaultValue) {
+
+        // get the title bar flag from the current theme.
+        ResourceValue value = resources.findItemInTheme(name);
+
+        // because it may reference something else, we resolve it.
+        value = resources.resolveResValue(value);
+
+        // if there's no value, return the default.
+        if (value == null || value.getValue() == null) {
+            return defaultValue;
+        }
+
+        return XmlUtils.convertValueToBoolean(value.getValue(), defaultValue);
+    }
+
+    /**
+     * Post process on a view hierachy that was just inflated.
+     * <p/>At the moment this only support TabHost: If {@link TabHost} is detected, look for the
+     * {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically
+     * based on the content of the {@link FrameLayout}.
+     * @param view the root view to process.
+     * @param projectCallback callback to the project.
+     */
+    private void postInflateProcess(View view, IProjectCallback projectCallback)
+            throws PostInflateException {
+        if (view instanceof TabHost) {
+            setupTabHost((TabHost)view, projectCallback);
+        } else if (view instanceof ViewGroup) {
+            ViewGroup group = (ViewGroup)view;
+            final int count = group.getChildCount();
+            for (int c = 0 ; c < count ; c++) {
+                View child = group.getChildAt(c);
+                postInflateProcess(child, projectCallback);
+            }
+        }
+    }
+
+    /**
+     * Sets up a {@link TabHost} object.
+     * @param tabHost the TabHost to setup.
+     * @param projectCallback The project callback object to access the project R class.
+     * @throws PostInflateException
+     */
+    private void setupTabHost(TabHost tabHost, IProjectCallback projectCallback)
+            throws PostInflateException {
+        // look for the TabWidget, and the FrameLayout. They have their own specific names
+        View v = tabHost.findViewById(android.R.id.tabs);
+
+        if (v == null) {
+            throw new PostInflateException(
+                    "TabHost requires a TabWidget with id \"android:id/tabs\".\n");
+        }
+
+        if ((v instanceof TabWidget) == false) {
+            throw new PostInflateException(String.format(
+                    "TabHost requires a TabWidget with id \"android:id/tabs\".\n" +
+                    "View found with id 'tabs' is '%s'", v.getClass().getCanonicalName()));
+        }
+
+        v = tabHost.findViewById(android.R.id.tabcontent);
+
+        if (v == null) {
+            // TODO: see if we can fake tabs even without the FrameLayout (same below when the framelayout is empty)
+            throw new PostInflateException(
+                    "TabHost requires a FrameLayout with id \"android:id/tabcontent\".");
+        }
+
+        if ((v instanceof FrameLayout) == false) {
+            throw new PostInflateException(String.format(
+                    "TabHost requires a FrameLayout with id \"android:id/tabcontent\".\n" +
+                    "View found with id 'tabcontent' is '%s'", v.getClass().getCanonicalName()));
+        }
+
+        FrameLayout content = (FrameLayout)v;
+
+        // now process the content of the framelayout and dynamically create tabs for it.
+        final int count = content.getChildCount();
+
+        // this must be called before addTab() so that the TabHost searches its TabWidget
+        // and FrameLayout.
+        tabHost.setup();
+
+        if (count == 0) {
+            // Create a dummy child to get a single tab
+            TabSpec spec = tabHost.newTabSpec("tag").setIndicator("Tab Label",
+                    tabHost.getResources().getDrawable(android.R.drawable.ic_menu_info_details))
+                    .setContent(new TabHost.TabContentFactory() {
+                        public View createTabContent(String tag) {
+                            return new LinearLayout(getContext());
+                        }
+                    });
+            tabHost.addTab(spec);
+            return;
+        } else {
+            // for each child of the framelayout, add a new TabSpec
+            for (int i = 0 ; i < count ; i++) {
+                View child = content.getChildAt(i);
+                String tabSpec = String.format("tab_spec%d", i+1);
+                int id = child.getId();
+                Pair<ResourceType, String> resource = projectCallback.resolveResourceId(id);
+                String name;
+                if (resource != null) {
+                    name = resource.getSecond();
+                } else {
+                    name = String.format("Tab %d", i+1); // default name if id is unresolved.
+                }
+                tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(name).setContent(id));
+            }
+        }
+    }
+
+    private List<ViewInfo> startVisitingViews(View view, int offset) {
+        if (view == null) {
+            return null;
+        }
+
+        // adjust the offset to this view.
+        offset += view.getTop();
+
+        if (view == mContentRoot) {
+            return visitAllChildren(mContentRoot, offset);
+        }
+
+        // otherwise, look for mContentRoot in the children
+        if (view instanceof ViewGroup) {
+            ViewGroup group = ((ViewGroup) view);
+
+            for (int i = 0; i < group.getChildCount(); i++) {
+                List<ViewInfo> list = startVisitingViews(group.getChildAt(i), offset);
+                if (list != null) {
+                    return list;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Visits a View and its children and generate a {@link ViewInfo} containing the
+     * bounds of all the views.
+     * @param view the root View
+     * @param offset an offset for the view bounds.
+     */
+    private ViewInfo visit(View view, int offset) {
+        if (view == null) {
+            return null;
+        }
+
+        ViewInfo result = new ViewInfo(view.getClass().getName(),
+                getContext().getViewKey(view),
+                view.getLeft(), view.getTop() + offset, view.getRight(), view.getBottom() + offset,
+                view, view.getLayoutParams());
+
+        if (view instanceof ViewGroup) {
+            ViewGroup group = ((ViewGroup) view);
+            result.setChildren(visitAllChildren(group, 0 /*offset*/));
+        }
+
+        return result;
+    }
+
+    /**
+     * Visits all the children of a given ViewGroup generate a list of {@link ViewInfo}
+     * containing the bounds of all the views.
+     * @param view the root View
+     * @param offset an offset for the view bounds.
+     */
+    private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, int offset) {
+        if (viewGroup == null) {
+            return null;
+        }
+
+        List<ViewInfo> children = new ArrayList<ViewInfo>();
+        for (int i = 0; i < viewGroup.getChildCount(); i++) {
+            children.add(visit(viewGroup.getChildAt(i), offset));
+        }
+        return children;
+    }
+
+
+    private void invalidateRenderingSize() {
+        mMeasuredScreenWidth = mMeasuredScreenHeight = -1;
+    }
+
+    public BufferedImage getImage() {
+        return mImage;
+    }
+
+    public boolean isAlphaChannelImage() {
+        return mIsAlphaChannelImage;
+    }
+
+    public List<ViewInfo> getViewInfos() {
+        return mViewInfoList;
+    }
+
+    public Map<String, String> getDefaultProperties(Object viewObject) {
+        return getContext().getDefaultPropMap(viewObject);
+    }
+
+    public void setScene(RenderSession session) {
+        mScene = session;
+    }
+
+    public RenderSession getSession() {
+        return mScene;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
new file mode 100644
index 0000000..69f46e6
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.impl;
+
+import com.android.ide.common.rendering.api.DensityBasedResourceValue;
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.RenderResources;
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
+import com.android.ninepatch.NinePatch;
+import com.android.ninepatch.NinePatchChunk;
+import com.android.resources.Density;
+
+import org.kxml2.io.KXmlParser;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.res.ColorStateList;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap_Delegate;
+import android.graphics.NinePatch_Delegate;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.NinePatchDrawable;
+import android.util.TypedValue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Helper class to provide various conversion method used in handling android resources.
+ */
+public final class ResourceHelper {
+
+    private final static Pattern sFloatPattern = Pattern.compile("(-?[0-9]+(?:\\.[0-9]+)?)(.*)");
+    private final static float[] sFloatOut = new float[1];
+
+    private final static TypedValue mValue = new TypedValue();
+
+    /**
+     * Returns the color value represented by the given string value
+     * @param value the color value
+     * @return the color as an int
+     * @throw NumberFormatException if the conversion failed.
+     */
+    public static int getColor(String value) {
+        if (value != null) {
+            if (value.startsWith("#") == false) {
+                throw new NumberFormatException(
+                        String.format("Color value '%s' must start with #", value));
+            }
+
+            value = value.substring(1);
+
+            // make sure it's not longer than 32bit
+            if (value.length() > 8) {
+                throw new NumberFormatException(String.format(
+                        "Color value '%s' is too long. Format is either" +
+                        "#AARRGGBB, #RRGGBB, #RGB, or #ARGB",
+                        value));
+            }
+
+            if (value.length() == 3) { // RGB format
+                char[] color = new char[8];
+                color[0] = color[1] = 'F';
+                color[2] = color[3] = value.charAt(0);
+                color[4] = color[5] = value.charAt(1);
+                color[6] = color[7] = value.charAt(2);
+                value = new String(color);
+            } else if (value.length() == 4) { // ARGB format
+                char[] color = new char[8];
+                color[0] = color[1] = value.charAt(0);
+                color[2] = color[3] = value.charAt(1);
+                color[4] = color[5] = value.charAt(2);
+                color[6] = color[7] = value.charAt(3);
+                value = new String(color);
+            } else if (value.length() == 6) {
+                value = "FF" + value;
+            }
+
+            // this is a RRGGBB or AARRGGBB value
+
+            // Integer.parseInt will fail to parse strings like "ff191919", so we use
+            // a Long, but cast the result back into an int, since we know that we're only
+            // dealing with 32 bit values.
+            return (int)Long.parseLong(value, 16);
+        }
+
+        throw new NumberFormatException();
+    }
+
+    public static ColorStateList getColorStateList(ResourceValue resValue, BridgeContext context) {
+        String value = resValue.getValue();
+        if (value != null) {
+            // first check if the value is a file (xml most likely)
+            File f = new File(value);
+            if (f.isFile()) {
+                try {
+                    // let the framework inflate the ColorStateList from the XML file, by
+                    // providing an XmlPullParser
+                    KXmlParser parser = new KXmlParser();
+                    parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
+                    parser.setInput(new FileReader(f));
+
+                    BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
+                            parser, context, resValue.isFramework());
+                    try {
+                        return ColorStateList.createFromXml(context.getResources(), blockParser);
+                    } finally {
+                        blockParser.ensurePopped();
+                    }
+                } catch (XmlPullParserException e) {
+                    Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                            "Failed to configure parser for " + value, e, null /*data*/);
+                    // we'll return null below.
+                } catch (Exception e) {
+                    // this is an error and not warning since the file existence is
+                    // checked before attempting to parse it.
+                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
+                            "Failed to parse file " + value, e, null /*data*/);
+
+                    return null;
+                }
+            } else {
+                // try to load the color state list from an int
+                try {
+                    int color = ResourceHelper.getColor(value);
+                    return ColorStateList.valueOf(color);
+                } catch (NumberFormatException e) {
+                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
+                            "Failed to convert " + value + " into a ColorStateList", e,
+                            null /*data*/);
+                    return null;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns a drawable from the given value.
+     * @param value The value that contains a path to a 9 patch, a bitmap or a xml based drawable,
+     * or an hexadecimal color
+     * @param context the current context
+     */
+    public static Drawable getDrawable(ResourceValue value, BridgeContext context) {
+        String stringValue = value.getValue();
+        if (RenderResources.REFERENCE_NULL.equals(stringValue)) {
+            return null;
+        }
+
+        String lowerCaseValue = stringValue.toLowerCase();
+
+        Density density = Density.MEDIUM;
+        if (value instanceof DensityBasedResourceValue) {
+            density =
+                ((DensityBasedResourceValue)value).getResourceDensity();
+        }
+
+
+        if (lowerCaseValue.endsWith(NinePatch.EXTENSION_9PATCH)) {
+            File file = new File(stringValue);
+            if (file.isFile()) {
+                try {
+                    return getNinePatchDrawable(
+                            new FileInputStream(file), density, value.isFramework(),
+                            stringValue, context);
+                } catch (IOException e) {
+                    // failed to read the file, we'll return null below.
+                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
+                            "Failed lot load " + file.getAbsolutePath(), e, null /*data*/);
+                }
+            }
+
+            return null;
+        } else if (lowerCaseValue.endsWith(".xml")) {
+            // create a block parser for the file
+            File f = new File(stringValue);
+            if (f.isFile()) {
+                try {
+                    // let the framework inflate the Drawable from the XML file.
+                    KXmlParser parser = new KXmlParser();
+                    parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
+                    parser.setInput(new FileReader(f));
+
+                    BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
+                            parser, context, value.isFramework());
+                    try {
+                        return Drawable.createFromXml(context.getResources(), blockParser);
+                    } finally {
+                        blockParser.ensurePopped();
+                    }
+                } catch (Exception e) {
+                    // this is an error and not warning since the file existence is checked before
+                    // attempting to parse it.
+                    Bridge.getLog().error(null, "Failed to parse file " + stringValue,
+                            e, null /*data*/);
+                }
+            } else {
+                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                        String.format("File %s does not exist (or is not a file)", stringValue),
+                        null /*data*/);
+            }
+
+            return null;
+        } else {
+            File bmpFile = new File(stringValue);
+            if (bmpFile.isFile()) {
+                try {
+                    Bitmap bitmap = Bridge.getCachedBitmap(stringValue,
+                            value.isFramework() ? null : context.getProjectKey());
+
+                    if (bitmap == null) {
+                        bitmap = Bitmap_Delegate.createBitmap(bmpFile, false /*isMutable*/,
+                                density);
+                        Bridge.setCachedBitmap(stringValue, bitmap,
+                                value.isFramework() ? null : context.getProjectKey());
+                    }
+
+                    return new BitmapDrawable(context.getResources(), bitmap);
+                } catch (IOException e) {
+                    // we'll return null below
+                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
+                            "Failed lot load " + bmpFile.getAbsolutePath(), e, null /*data*/);
+                }
+            } else {
+                // attempt to get a color from the value
+                try {
+                    int color = getColor(stringValue);
+                    return new ColorDrawable(color);
+                } catch (NumberFormatException e) {
+                    // we'll return null below.
+                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
+                            "Failed to convert " + stringValue + " into a drawable", e,
+                            null /*data*/);
+                }
+            }
+        }
+
+        return null;
+    }
+
+    private static Drawable getNinePatchDrawable(InputStream inputStream, Density density,
+            boolean isFramework, String cacheKey, BridgeContext context) throws IOException {
+        // see if we still have both the chunk and the bitmap in the caches
+        NinePatchChunk chunk = Bridge.getCached9Patch(cacheKey,
+                isFramework ? null : context.getProjectKey());
+        Bitmap bitmap = Bridge.getCachedBitmap(cacheKey,
+                isFramework ? null : context.getProjectKey());
+
+        // if either chunk or bitmap is null, then we reload the 9-patch file.
+        if (chunk == null || bitmap == null) {
+            try {
+                NinePatch ninePatch = NinePatch.load(inputStream, true /*is9Patch*/,
+                        false /* convert */);
+                if (ninePatch != null) {
+                    if (chunk == null) {
+                        chunk = ninePatch.getChunk();
+
+                        Bridge.setCached9Patch(cacheKey, chunk,
+                                isFramework ? null : context.getProjectKey());
+                    }
+
+                    if (bitmap == null) {
+                        bitmap = Bitmap_Delegate.createBitmap(ninePatch.getImage(),
+                                false /*isMutable*/,
+                                density);
+
+                        Bridge.setCachedBitmap(cacheKey, bitmap,
+                                isFramework ? null : context.getProjectKey());
+                    }
+                }
+            } catch (MalformedURLException e) {
+                // URL is wrong, we'll return null below
+            }
+        }
+
+        if (chunk != null && bitmap != null) {
+            int[] padding = chunk.getPadding();
+            Rect paddingRect = new Rect(padding[0], padding[1], padding[2], padding[3]);
+
+            return new NinePatchDrawable(context.getResources(), bitmap,
+                    NinePatch_Delegate.serialize(chunk),
+                    paddingRect, null);
+        }
+
+        return null;
+    }
+
+    // ------- TypedValue stuff
+    // This is taken from //device/libs/utils/ResourceTypes.cpp
+
+    private static final class UnitEntry {
+        String name;
+        int type;
+        int unit;
+        float scale;
+
+        UnitEntry(String name, int type, int unit, float scale) {
+            this.name = name;
+            this.type = type;
+            this.unit = unit;
+            this.scale = scale;
+        }
+    }
+
+    private final static UnitEntry[] sUnitNames = new UnitEntry[] {
+        new UnitEntry("px", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_PX, 1.0f),
+        new UnitEntry("dip", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_DIP, 1.0f),
+        new UnitEntry("dp", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_DIP, 1.0f),
+        new UnitEntry("sp", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_SP, 1.0f),
+        new UnitEntry("pt", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_PT, 1.0f),
+        new UnitEntry("in", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_IN, 1.0f),
+        new UnitEntry("mm", TypedValue.TYPE_DIMENSION, TypedValue.COMPLEX_UNIT_MM, 1.0f),
+        new UnitEntry("%", TypedValue.TYPE_FRACTION, TypedValue.COMPLEX_UNIT_FRACTION, 1.0f/100),
+        new UnitEntry("%p", TypedValue.TYPE_FRACTION, TypedValue.COMPLEX_UNIT_FRACTION_PARENT, 1.0f/100),
+    };
+
+    /**
+     * Returns the raw value from the given string.
+     * This object is only valid until the next call on to {@link ResourceHelper}.
+     */
+    public static TypedValue getValue(String s) {
+        if (stringToFloat(s, mValue)) {
+            return mValue;
+        }
+
+        return null;
+    }
+
+    /**
+     * Convert the string into a {@link TypedValue}.
+     * @param s
+     * @param outValue
+     * @return true if success.
+     */
+    public static boolean stringToFloat(String s, TypedValue outValue) {
+        // remove the space before and after
+        s = s.trim();
+        int len = s.length();
+
+        if (len <= 0) {
+            return false;
+        }
+
+        // check that there's no non ascii characters.
+        char[] buf = s.toCharArray();
+        for (int i = 0 ; i < len ; i++) {
+            if (buf[i] > 255) {
+                return false;
+            }
+        }
+
+        // check the first character
+        if (buf[0] < '0' && buf[0] > '9' && buf[0] != '.') {
+            return false;
+        }
+
+        // now look for the string that is after the float...
+        Matcher m = sFloatPattern.matcher(s);
+        if (m.matches()) {
+            String f_str = m.group(1);
+            String end = m.group(2);
+
+            float f;
+            try {
+                f = Float.parseFloat(f_str);
+            } catch (NumberFormatException e) {
+                // this shouldn't happen with the regexp above.
+                return false;
+            }
+
+            if (end.length() > 0 && end.charAt(0) != ' ') {
+                // Might be a unit...
+                if (parseUnit(end, outValue, sFloatOut)) {
+
+                    f *= sFloatOut[0];
+                    boolean neg = f < 0;
+                    if (neg) {
+                        f = -f;
+                    }
+                    long bits = (long)(f*(1<<23)+.5f);
+                    int radix;
+                    int shift;
+                    if ((bits&0x7fffff) == 0) {
+                        // Always use 23p0 if there is no fraction, just to make
+                        // things easier to read.
+                        radix = TypedValue.COMPLEX_RADIX_23p0;
+                        shift = 23;
+                    } else if ((bits&0xffffffffff800000L) == 0) {
+                        // Magnitude is zero -- can fit in 0 bits of precision.
+                        radix = TypedValue.COMPLEX_RADIX_0p23;
+                        shift = 0;
+                    } else if ((bits&0xffffffff80000000L) == 0) {
+                        // Magnitude can fit in 8 bits of precision.
+                        radix = TypedValue.COMPLEX_RADIX_8p15;
+                        shift = 8;
+                    } else if ((bits&0xffffff8000000000L) == 0) {
+                        // Magnitude can fit in 16 bits of precision.
+                        radix = TypedValue.COMPLEX_RADIX_16p7;
+                        shift = 16;
+                    } else {
+                        // Magnitude needs entire range, so no fractional part.
+                        radix = TypedValue.COMPLEX_RADIX_23p0;
+                        shift = 23;
+                    }
+                    int mantissa = (int)(
+                        (bits>>shift) & TypedValue.COMPLEX_MANTISSA_MASK);
+                    if (neg) {
+                        mantissa = (-mantissa) & TypedValue.COMPLEX_MANTISSA_MASK;
+                    }
+                    outValue.data |=
+                        (radix<<TypedValue.COMPLEX_RADIX_SHIFT)
+                        | (mantissa<<TypedValue.COMPLEX_MANTISSA_SHIFT);
+                    return true;
+                }
+                return false;
+            }
+
+            // make sure it's only spaces at the end.
+            end = end.trim();
+
+            if (end.length() == 0) {
+                if (outValue != null) {
+                    outValue.type = TypedValue.TYPE_FLOAT;
+                    outValue.data = Float.floatToIntBits(f);
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private static boolean parseUnit(String str, TypedValue outValue, float[] outScale) {
+        str = str.trim();
+
+        for (UnitEntry unit : sUnitNames) {
+            if (unit.name.equals(str)) {
+                outValue.type = unit.type;
+                outValue.data = unit.unit << TypedValue.COMPLEX_UNIT_SHIFT;
+                outScale[0] = unit.scale;
+
+                return true;
+            }
+        }
+
+        return false;
+    }
+}
+
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Stack.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Stack.java
new file mode 100644
index 0000000..9bd0015
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Stack.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.impl;
+
+import java.util.ArrayList;
+
+/**
+ * Custom Stack implementation on top of an {@link ArrayList} instead of
+ * using {@link java.util.Stack} which is on top of a vector.
+ *
+ * @param <T>
+ */
+public class Stack<T> extends ArrayList<T> {
+
+    private static final long serialVersionUID = 1L;
+
+    public Stack() {
+        super();
+    }
+
+    public Stack(int size) {
+        super(size);
+    }
+
+    /**
+     * Pushes the given object to the stack
+     * @param object the object to push
+     */
+    public void push(T object) {
+        add(object);
+    }
+
+    /**
+     * Remove the object at the top of the stack and returns it.
+     * @return the removed object or null if the stack was empty.
+     */
+    public T pop() {
+        if (size() > 0) {
+            return remove(size() - 1);
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the object at the top of the stack.
+     * @return the object at the top or null if the stack is empty.
+     */
+    public T peek() {
+        if (size() > 0) {
+            return get(size() - 1);
+        }
+
+        return null;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/Debug.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/Debug.java
new file mode 100644
index 0000000..82eab85
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/Debug.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.util;
+
+public class Debug {
+
+    public final static boolean DEBUG = false;
+
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
new file mode 100644
index 0000000..4d0c9ce
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.util;
+
+
+import com.android.internal.util.ArrayUtils;
+
+import android.util.SparseArray;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * This is a custom {@link SparseArray} that uses {@link WeakReference} around the objects added
+ * to it. When the array is compacted, not only deleted indices but also empty references
+ * are removed, making the array efficient at removing references that were reclaimed.
+ *
+ * The code is taken from {@link SparseArray} directly and adapted to use weak references.
+ *
+ * Because our usage means that we never actually call {@link #remove(int)} or {@link #delete(int)},
+ * we must manually check if there are reclaimed references to trigger an internal compact step
+ * (which is normally only triggered when an item is manually removed).
+ *
+ * SparseArrays map integers to Objects.  Unlike a normal array of Objects,
+ * there can be gaps in the indices.  It is intended to be more efficient
+ * than using a HashMap to map Integers to Objects.
+ */
+@SuppressWarnings("unchecked")
+public class SparseWeakArray<E> {
+
+    private static final Object DELETED_REF = new Object();
+    private static final WeakReference<?> DELETED = new WeakReference(DELETED_REF);
+    private boolean mGarbage = false;
+
+    /**
+     * Creates a new SparseArray containing no mappings.
+     */
+    public SparseWeakArray() {
+        this(10);
+    }
+
+    /**
+     * Creates a new SparseArray containing no mappings that will not
+     * require any additional memory allocation to store the specified
+     * number of mappings.
+     */
+    public SparseWeakArray(int initialCapacity) {
+        initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
+
+        mKeys = new int[initialCapacity];
+        mValues = new WeakReference[initialCapacity];
+        mSize = 0;
+    }
+
+    /**
+     * Gets the Object mapped from the specified key, or <code>null</code>
+     * if no such mapping has been made.
+     */
+    public E get(int key) {
+        return get(key, null);
+    }
+
+    /**
+     * Gets the Object mapped from the specified key, or the specified Object
+     * if no such mapping has been made.
+     */
+    public E get(int key, E valueIfKeyNotFound) {
+        int i = binarySearch(mKeys, 0, mSize, key);
+
+        if (i < 0 || mValues[i] == DELETED || mValues[i].get() == null) {
+            return valueIfKeyNotFound;
+        } else {
+            return (E) mValues[i].get();
+        }
+    }
+
+    /**
+     * Removes the mapping from the specified key, if there was any.
+     */
+    public void delete(int key) {
+        int i = binarySearch(mKeys, 0, mSize, key);
+
+        if (i >= 0) {
+            if (mValues[i] != DELETED) {
+                mValues[i] = DELETED;
+                mGarbage = true;
+            }
+        }
+    }
+
+    /**
+     * Alias for {@link #delete(int)}.
+     */
+    public void remove(int key) {
+        delete(key);
+    }
+
+    /**
+     * Removes the mapping at the specified index.
+     */
+    public void removeAt(int index) {
+        if (mValues[index] != DELETED) {
+            mValues[index] = DELETED;
+            mGarbage = true;
+        }
+    }
+
+    private void gc() {
+        int n = mSize;
+        int o = 0;
+        int[] keys = mKeys;
+        WeakReference<?>[] values = mValues;
+
+        for (int i = 0; i < n; i++) {
+            WeakReference<?> val = values[i];
+
+            // Don't keep any non DELETED values, but only the one that still have a valid
+            // reference.
+            if (val != DELETED && val.get() != null) {
+                if (i != o) {
+                    keys[o] = keys[i];
+                    values[o] = val;
+                }
+
+                o++;
+            }
+        }
+
+        mGarbage = false;
+        mSize = o;
+
+        int newSize = ArrayUtils.idealIntArraySize(mSize);
+        if (newSize < mKeys.length) {
+            int[] nkeys = new int[newSize];
+            WeakReference<?>[] nvalues = new WeakReference[newSize];
+
+            System.arraycopy(mKeys, 0, nkeys, 0, newSize);
+            System.arraycopy(mValues, 0, nvalues, 0, newSize);
+
+            mKeys = nkeys;
+            mValues = nvalues;
+        }
+    }
+
+    /**
+     * Adds a mapping from the specified key to the specified value,
+     * replacing the previous mapping from the specified key if there
+     * was one.
+     */
+    public void put(int key, E value) {
+        int i = binarySearch(mKeys, 0, mSize, key);
+
+        if (i >= 0) {
+            mValues[i] = new WeakReference(value);
+        } else {
+            i = ~i;
+
+            if (i < mSize && (mValues[i] == DELETED || mValues[i].get() == null)) {
+                mKeys[i] = key;
+                mValues[i] = new WeakReference(value);
+                return;
+            }
+
+            if (mSize >= mKeys.length && (mGarbage || hasReclaimedRefs())) {
+                gc();
+
+                // Search again because indices may have changed.
+                i = ~binarySearch(mKeys, 0, mSize, key);
+            }
+
+            if (mSize >= mKeys.length) {
+                int n = ArrayUtils.idealIntArraySize(mSize + 1);
+
+                int[] nkeys = new int[n];
+                WeakReference<?>[] nvalues = new WeakReference[n];
+
+                // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
+                System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+                System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+
+                mKeys = nkeys;
+                mValues = nvalues;
+            }
+
+            if (mSize - i != 0) {
+                // Log.e("SparseArray", "move " + (mSize - i));
+                System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
+                System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
+            }
+
+            mKeys[i] = key;
+            mValues[i] = new WeakReference(value);
+            mSize++;
+        }
+    }
+
+    /**
+     * Returns the number of key-value mappings that this SparseArray
+     * currently stores.
+     */
+    public int size() {
+        if (mGarbage) {
+            gc();
+        }
+
+        return mSize;
+    }
+
+    /**
+     * Given an index in the range <code>0...size()-1</code>, returns
+     * the key from the <code>index</code>th key-value mapping that this
+     * SparseArray stores.
+     */
+    public int keyAt(int index) {
+        if (mGarbage) {
+            gc();
+        }
+
+        return mKeys[index];
+    }
+
+    /**
+     * Given an index in the range <code>0...size()-1</code>, returns
+     * the value from the <code>index</code>th key-value mapping that this
+     * SparseArray stores.
+     */
+    public E valueAt(int index) {
+        if (mGarbage) {
+            gc();
+        }
+
+        return (E) mValues[index].get();
+    }
+
+    /**
+     * Given an index in the range <code>0...size()-1</code>, sets a new
+     * value for the <code>index</code>th key-value mapping that this
+     * SparseArray stores.
+     */
+    public void setValueAt(int index, E value) {
+        if (mGarbage) {
+            gc();
+        }
+
+        mValues[index] = new WeakReference(value);
+    }
+
+    /**
+     * Returns the index for which {@link #keyAt} would return the
+     * specified key, or a negative number if the specified
+     * key is not mapped.
+     */
+    public int indexOfKey(int key) {
+        if (mGarbage) {
+            gc();
+        }
+
+        return binarySearch(mKeys, 0, mSize, key);
+    }
+
+    /**
+     * Returns an index for which {@link #valueAt} would return the
+     * specified key, or a negative number if no keys map to the
+     * specified value.
+     * Beware that this is a linear search, unlike lookups by key,
+     * and that multiple keys can map to the same value and this will
+     * find only one of them.
+     */
+    public int indexOfValue(E value) {
+        if (mGarbage) {
+            gc();
+        }
+
+        for (int i = 0; i < mSize; i++)
+            if (mValues[i].get() == value)
+                return i;
+
+        return -1;
+    }
+
+    /**
+     * Removes all key-value mappings from this SparseArray.
+     */
+    public void clear() {
+        int n = mSize;
+        WeakReference<?>[] values = mValues;
+
+        for (int i = 0; i < n; i++) {
+            values[i] = null;
+        }
+
+        mSize = 0;
+        mGarbage = false;
+    }
+
+    /**
+     * Puts a key/value pair into the array, optimizing for the case where
+     * the key is greater than all existing keys in the array.
+     */
+    public void append(int key, E value) {
+        if (mSize != 0 && key <= mKeys[mSize - 1]) {
+            put(key, value);
+            return;
+        }
+
+        if (mSize >= mKeys.length && (mGarbage || hasReclaimedRefs())) {
+            gc();
+        }
+
+        int pos = mSize;
+        if (pos >= mKeys.length) {
+            int n = ArrayUtils.idealIntArraySize(pos + 1);
+
+            int[] nkeys = new int[n];
+            WeakReference<?>[] nvalues = new WeakReference[n];
+
+            // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);
+            System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+            System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+
+            mKeys = nkeys;
+            mValues = nvalues;
+        }
+
+        mKeys[pos] = key;
+        mValues[pos] = new WeakReference(value);
+        mSize = pos + 1;
+    }
+
+    private boolean hasReclaimedRefs() {
+        for (int i = 0 ; i < mSize ; i++) {
+            if (mValues[i].get() == null) { // DELETED.get() never returns null.
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private static int binarySearch(int[] a, int start, int len, int key) {
+        int high = start + len, low = start - 1, guess;
+
+        while (high - low > 1) {
+            guess = (high + low) / 2;
+
+            if (a[guess] < key)
+                low = guess;
+            else
+                high = guess;
+        }
+
+        if (high == start + len)
+            return ~(start + len);
+        else if (a[high] == key)
+            return high;
+        else
+            return ~high;
+    }
+
+    private int[] mKeys;
+    private WeakReference<?>[] mValues;
+    private int mSize;
+}
diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/AndroidGraphicsTests.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/AndroidGraphicsTests.java
index 6e14e82..ba3c51a 100644
--- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/AndroidGraphicsTests.java
+++ b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/AndroidGraphicsTests.java
@@ -17,8 +17,6 @@
 package com.android.layoutlib.bridge;
 
 import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics._Original_Paint;
 import android.text.TextPaint;
 
 import junit.framework.TestCase;
@@ -58,14 +56,6 @@
         }
     }
 
-    public void testPaint() {
-        _Original_Paint o = new _Original_Paint();
-        assertNotNull(o);
-
-        Paint p = new Paint();
-        assertNotNull(p);
-    }
-
     public void textTextPaint() {
         TextPaint p = new TextPaint();
         assertNotNull(p);
diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java
index 23351ab..a3219e7 100644
--- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java
+++ b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/NinePatchTest.java
@@ -48,5 +48,4 @@
         assertEquals(36, mPatch.getWidth());
         assertEquals(25, mPatch.getHeight());
     }
-
 }
diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/TestClassReplacement.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/TestClassReplacement.java
deleted file mode 100644
index e0dc55f..0000000
--- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/TestClassReplacement.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge;
-
-import java.lang.reflect.Method;
-
-import junit.framework.TestCase;
-
-public class TestClassReplacement extends TestCase {
-
-    public void testClassReplacements() {
-        // TODO: we want to test all the classes. For now only Paint passes the tests.
-//        final String[] classes = CreateInfo.RENAMED_CLASSES;
-        final String[] classes = new String[] {
-                "android.graphics.Paint",               "android.graphics._Original_Paint"
-        };
-        final int count = classes.length;
-        for (int i = 0 ; i < count ; i += 2) {
-            loadAndCompareClasses(classes[i], classes[i+1]);
-        }
-    }
-
-    private void loadAndCompareClasses(String newClassName, String oldClassName) {
-        // load the classes
-        try {
-            Class<?> newClass = TestClassReplacement.class.getClassLoader().loadClass(newClassName);
-            Class<?> oldClass = TestClassReplacement.class.getClassLoader().loadClass(oldClassName);
-
-            compare(newClass, oldClass);
-        } catch (ClassNotFoundException e) {
-            fail("Failed to load class: " + e.getMessage());
-        }
-    }
-
-    private void compare(Class<?> newClass, Class<?> oldClass) {
-        // first compare the methods.
-        Method[] newClassMethods = newClass.getDeclaredMethods();
-        Method[] oldClassMethods = oldClass.getDeclaredMethods();
-
-        for (Method oldMethod : oldClassMethods) {
-            // we ignore anything that starts with native
-            if (oldMethod.getName().startsWith("native")) {
-                continue;
-            }
-            boolean found = false;
-            for (Method newMethod : newClassMethods) {
-                if (compareMethods(newClass, newMethod, oldClass, oldMethod)) {
-                    found = true;
-                    break;
-                }
-            }
-
-            if (found == false) {
-                fail(String.format("Unable to find %1$s", oldMethod.toGenericString()));
-            }
-        }
-
-        // TODO: check (somehow?) that the methods that were removed from the original class
-        // have been put back in the new class!
-        // For this we need the original unmodified class (ie renamed, but w/o the methods removed)
-    }
-
-    private boolean compareMethods(Class<?> newClass, Method newMethod,
-            Class<?> oldClass, Method oldMethod) {
-        // first check the name of the method
-        if (newMethod.getName().equals(oldMethod.getName()) == false) {
-            return false;
-        }
-
-        // check the return value
-        Class<?> oldReturnType = oldMethod.getReturnType();
-        // if it's the old class, or if it's a inner class of the oldclass, we need to change this.
-        oldReturnType = adapt(oldReturnType, newClass, oldClass);
-
-        // compare the return types
-        Class<?> newReturnType = newMethod.getReturnType();
-        if (newReturnType.equals(oldReturnType) == false) {
-            return false;
-        }
-
-        // now check the parameters type.
-        Class<?>[] oldParameters = oldMethod.getParameterTypes();
-        Class<?>[] newParemeters = newMethod.getParameterTypes();
-        if (oldParameters.length != newParemeters.length) {
-            return false;
-        }
-
-        for (int i = 0 ; i < oldParameters.length ; i++) {
-            if (newParemeters[i].equals(adapt(oldParameters[i], newClass, oldClass)) == false) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Adapts a class to deal with renamed classes.
-     * <p/>For instance if old class is <code>android.graphics._Original_Paint</code> and the
-     * new class is <code>android.graphics.Paint</code> and the class to adapt is
-     * <code>android.graphics._Original_Paint$Cap</code>, then the method will return a
-     * {@link Class} object representing <code>android.graphics.Paint$Cap</code>.
-     * <p/>
-     * This method will also ensure that all renamed classes contains all the proper inner classes
-     * that they should be declaring.
-     * @param theClass the class to adapt
-     * @param newClass the new class object
-     * @param oldClass the old class object
-     * @return the adapted class.
-     * @throws ClassNotFoundException
-     */
-    private Class<?> adapt(Class<?> theClass, Class<?> newClass, Class<?> oldClass) {
-        // only look for a new class if it's not primitive as Class.forName() would fail otherwise.
-        if (theClass.isPrimitive() == false) {
-            String n = theClass.getName().replace(oldClass.getName(), newClass.getName());
-            try {
-                return Class.forName(n);
-            } catch (ClassNotFoundException e) {
-                fail("Missing class: " + n);
-            }
-        }
-
-        return theClass;
-    }
-}
diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/TestDelegates.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/TestDelegates.java
new file mode 100644
index 0000000..d3218db
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/TestDelegates.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge;
+
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+import com.android.tools.layoutlib.create.CreateInfo;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests that native delegate classes implement all the required methods.
+ *
+ * This looks at {@link CreateInfo#DELEGATE_CLASS_NATIVES} to get the list of classes that
+ * have their native methods reimplemented through a delegate.
+ *
+ * Since the reimplemented methods are not native anymore, we look for the annotation
+ * {@link LayoutlibDelegate}, and look for a matching method in the delegate (named the same
+ * as the modified class with _Delegate added as a suffix).
+ * If the original native method is not static, then we make sure the delegate method also
+ * include the original class as first parameter (to access "this").
+ *
+ */
+public class TestDelegates extends TestCase {
+
+    public void testNativeDelegates() {
+
+        final String[] classes = CreateInfo.DELEGATE_CLASS_NATIVES;
+        final int count = classes.length;
+        for (int i = 0 ; i < count ; i++) {
+            loadAndCompareClasses(classes[i], classes[i] + "_Delegate");
+        }
+    }
+
+    public void testMethodDelegates() {
+        final String[] methods = CreateInfo.DELEGATE_METHODS;
+        final int count = methods.length;
+        for (int i = 0 ; i < count ; i++) {
+            String methodName = methods[i];
+
+            // extract the class name
+            String className = methodName.substring(0, methodName.indexOf('#'));
+            String targetClassName = className.replace('$', '_') + "_Delegate";
+
+            loadAndCompareClasses(className, targetClassName);
+        }
+    }
+
+    private void loadAndCompareClasses(String originalClassName, String delegateClassName) {
+        // load the classes
+        try {
+            ClassLoader classLoader = TestDelegates.class.getClassLoader();
+            Class<?> originalClass = classLoader.loadClass(originalClassName);
+            Class<?> delegateClass = classLoader.loadClass(delegateClassName);
+
+            compare(originalClass, delegateClass);
+        } catch (ClassNotFoundException e) {
+           fail("Failed to load class: " + e.getMessage());
+        } catch (SecurityException e) {
+            fail("Failed to load class: " + e.getMessage());
+        }
+    }
+
+    private void compare(Class<?> originalClass, Class<?> delegateClass) throws SecurityException {
+        List<Method> checkedDelegateMethods = new ArrayList<Method>();
+
+        // loop on the methods of the original class, and for the ones that are annotated
+        // with @LayoutlibDelegate, look for a matching method in the delegate class.
+        // The annotation is automatically added by layoutlib_create when it replace a method
+        // by a call to a delegate
+        Method[] originalMethods = originalClass.getDeclaredMethods();
+        for (Method originalMethod : originalMethods) {
+            // look for methods that are delegated: they have the LayoutlibDelegate annotation
+            if (originalMethod.getAnnotation(LayoutlibDelegate.class) == null) {
+                continue;
+            }
+
+            // get the signature.
+            Class<?>[] parameters = originalMethod.getParameterTypes();
+
+            // if the method is not static, then the class is added as the first parameter
+            // (for "this")
+            if ((originalMethod.getModifiers() & Modifier.STATIC) == 0) {
+
+                Class<?>[] newParameters = new Class<?>[parameters.length + 1];
+                newParameters[0] = originalClass;
+                System.arraycopy(parameters, 0, newParameters, 1, parameters.length);
+                parameters = newParameters;
+            }
+
+            // if the original class is an inner class that's not static, then
+            // we add this on the enclosing class at the beginning
+            if (originalClass.getEnclosingClass() != null &&
+                    (originalClass.getModifiers() & Modifier.STATIC) == 0) {
+                Class<?>[] newParameters = new Class<?>[parameters.length + 1];
+                newParameters[0] = originalClass.getEnclosingClass();
+                System.arraycopy(parameters, 0, newParameters, 1, parameters.length);
+                parameters = newParameters;
+            }
+
+            try {
+                // try to load the method with the given parameter types.
+                Method delegateMethod = delegateClass.getDeclaredMethod(originalMethod.getName(),
+                        parameters);
+
+                // check that the method has the annotation
+                assertNotNull(
+                        String.format(
+                                "Delegate method %1$s for class %2$s does not have the @LayoutlibDelegate annotation",
+                                delegateMethod.getName(),
+                                originalClass.getName()),
+                        delegateMethod.getAnnotation(LayoutlibDelegate.class));
+
+                // check that the method is static
+                assertTrue(
+                        String.format(
+                                "Delegate method %1$s for class %2$s is not static",
+                                delegateMethod.getName(),
+                                originalClass.getName()),
+                        (delegateMethod.getModifiers() & Modifier.STATIC) == Modifier.STATIC);
+
+                // add the method as checked.
+                checkedDelegateMethods.add(delegateMethod);
+            } catch (NoSuchMethodException e) {
+                String name = getMethodName(originalMethod, parameters);
+                fail(String.format("Missing %1$s.%2$s", delegateClass.getName(), name));
+            }
+        }
+
+        // look for dead (delegate) code.
+        // This looks for all methods in the delegate class, and if they have the
+        // @LayoutlibDelegate annotation, make sure they have been previously found as a
+        // match for a method in the original class.
+        // If not, this means the method is a delegate for a method that either doesn't exist
+        // anymore or is not delegated anymore.
+        Method[] delegateMethods = delegateClass.getDeclaredMethods();
+        for (Method delegateMethod : delegateMethods) {
+            // look for methods that are delegates: they have the LayoutlibDelegate annotation
+            if (delegateMethod.getAnnotation(LayoutlibDelegate.class) == null) {
+                continue;
+            }
+
+            assertTrue(
+                    String.format(
+                            "Delegate method %1$s.%2$s is not used anymore and must be removed",
+                            delegateClass.getName(),
+                            getMethodName(delegateMethod)),
+                    checkedDelegateMethods.contains(delegateMethod));
+        }
+
+    }
+
+    private String getMethodName(Method method) {
+        return getMethodName(method, method.getParameterTypes());
+    }
+
+    private String getMethodName(Method method, Class<?>[] parameters) {
+        // compute a full class name that's long but not too long.
+        StringBuilder sb = new StringBuilder(method.getName() + "(");
+        for (int j = 0; j < parameters.length; j++) {
+            Class<?> theClass = parameters[j];
+            sb.append(theClass.getName());
+            int dimensions = 0;
+            while (theClass.isArray()) {
+                dimensions++;
+                theClass = theClass.getComponentType();
+            }
+            for (int i = 0; i < dimensions; i++) {
+                sb.append("[]");
+            }
+            if (j < (parameters.length - 1)) {
+                sb.append(",");
+            }
+        }
+        sb.append(")");
+
+        return sb.toString();
+    }
+}
diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
similarity index 96%
rename from tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java
rename to tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
index db1262f..3252fb4 100644
--- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java
+++ b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
+
+import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
 
 import org.kxml2.io.KXmlParser;
 import org.w3c.dom.Node;
diff --git a/tools/layoutlib/create/README.txt b/tools/layoutlib/create/README.txt
index 09b392b..65a64cd 100644
--- a/tools/layoutlib/create/README.txt
+++ b/tools/layoutlib/create/README.txt
@@ -4,68 +4,213 @@
 - Description -
 ---------------
 
-makeLayoutLib generates a library used by the Eclipse graphical layout editor
+Layoutlib_create generates a JAR library used by the Eclipse graphical layout editor
 to perform layout.
 
 
-
 - Usage -
 ---------
 
- ./makeLayoutLib path/to/android.jar destination.jar
+ ./layoutlib_create path/to/android.jar destination.jar
+
+
+- Design Overview -
+-------------------
+
+Layoutlib_create uses the "android.jar" containing all the Java code used by Android
+as generated by the Android build, right before the classes are converted to a DEX format.
+
+The Android JAR can't be used directly in Eclipse:
+- it contains references to native code (which we want to avoid in Eclipse),
+- some classes need to be overridden, for example all the drawing code that is
+  replaced by Java 2D calls in Eclipse.
+- some of the classes that need to be changed are final and/or we need access
+  to their private internal state.
+
+Consequently this tool:
+- parses the input JAR,
+- modifies some of the classes directly using some bytecode manipulation,
+- filters some packages and removes some that we don't want to end in the output JAR,
+- injects some new classes,
+- and generates a modified JAR file that is suitable for the Android plugin
+  for Eclipse to perform rendering.
+
+The ASM library is used to do the bytecode modification using its visitor pattern API.
+
+The layoutlib_create is *NOT* generic. There is no configuration file. Instead all the
+configuration is done in the main() method and the CreateInfo structure is expected to
+change with the Android platform as new classes are added, changed or removed.
+
+The resulting JAR is used by layoutlib_bridge (a.k.a. "the bridge"), also part of the
+platform, that provides all the necessary missing implementation for rendering graphics
+in Eclipse.
 
 
 
 - Implementation Notes -
 ------------------------
 
-The goal of makeLayoutLib is to list all the classes from the input jar and create a new
-jar that only keeps certain classes and create stubs for all their dependencies.
-
-First the input jar is parsed to find all the classes defined.
-
-In the Main(), the following list of classes are hardcoded (TODO config file later):
-- keep all classes that derive from android.view.View.
-- keep all classes in the android.view and android.widget packages (sub-packages excluded).
-- keep specific classes such as android.policy.PhoneLayoutInflater.
-
-For each class to keep, their dependencies are examined using BCEL.
-A dependency is defined as a class needed to instantiate the given class that should be kept,
-directly or indirectly. So a dependency is a class that is used by the input class, that is
-defined in the input jar and that is not part of the current JRE.
-
-Dependencies are computed recursively.
-
-Once all dependencies are found, the final jar can be created.
-There are three kind of classes to write:
-- classes that are to be kept as-is. They are just dumped in the new jar unchanged.
-- classes that are to be kept yet contain native methods or fields.
-- classes that are just dependencies. We don't want to expose their implementation in the final
-  jar.
-
-The implementation of native methods and all methods of mock classes is replaced by a stub
-that throws UnsupportedOperationException.
-
-Incidentally, the access level of native and mock classes needs to be changed in order for
-native methods to be later overridden. Methods that are "final private native" must become
-non-final, non-native and at most protected. Package-default access is changed to public.
-Classes that are final are made non-final. Abstract methods are left untouched.
+The tool works in two phases:
+- first analyze the input jar (AsmAnalyzer class)
+- then generate the output jar (AsmGenerator class),
 
 
+- Analyzer
+----------
 
-----
-20080617 Replace Class
+The goal of the analyzer is to create a graph of all the classes from the input JAR
+with their dependencies and then only keep the ones we want.
 
-Some classes are basically wrappers over native objects.
-Subclassing doesn't work as most methods are either static or we don't
-control object creation. In this scenario the idea is to be able to
-replace classes in the final jar.
+To do that, the analyzer is created with a list of base classes to keep -- everything
+that derives from these is kept. Currently the one such class is android.view.View:
+since we want to render layouts, anything that is sort of the view needs to be kept.
 
-Example: android.graphics.Paint would get renamed to OriginalPaint
-in the generated jar. Then in the bridge we'll introduce a replacement
-Paint class that derives from OriginalPaint.
+The analyzer is also given a list of class names to keep in the output.
+This is done using shell-like glob patterns that filter on the fully-qualified
+class names, for example "android.*.R**" ("*" does not matches dots whilst "**" does,
+and "." and "$" are interpreted as-is).
+In practice we almost but not quite request the inclusion of full packages.
+
+With this information, the analyzer parses the input zip to find all the classes.
+All classes deriving from the requested bases classes are kept.
+All classes which name matched the glob pattern are kept.
+The analysis then finds all the dependencies of the classes that are to be kept
+using an ASM visitor on the class, the field types, the method types and annotations types.
+Classes that belong to the current JRE are excluded.
+
+The output of the analyzer is a set of ASM ClassReader instances which are then
+fed to the generator.
+
+
+- Generator
+-----------
+
+The generator is constructed from a CreateInfo struct that acts as a config file
+and lists:
+- the classes to inject in the output JAR -- these classes are directly implemented
+  in layoutlib_create and will be used to interface with the renderer in Eclipse.
+- specific methods to override (see method stubs details below).
+- specific methods to remove based on their return type.
+- specific classes to rename.
+
+Each of these are specific strategies we use to be able to modify the Android code
+to fit within the Eclipse renderer. These strategies are explained beow.
+
+The core method of the generator is transform(): it takes an input ASM ClassReader
+and modifies it to produce a byte array suitable for the final JAR file.
+
+The first step of the transformation is changing the name of the class in case
+we requested the class to be renamed. This uses the RenameClassAdapter to also rename
+all inner classes and references in methods and types. Note that other classes are
+not transformed and keep referencing the original name.
+
+The TransformClassAdapter is then used to process the potentially renamed class.
+All protected or private classes are market as public.
+All classes are made non-final.
+Interfaces are left as-is.
+
+If a method has a return type that must be erased, the whole method is skipped.
+Methods are also changed from protected/private to public.
+The code of the methods is then kept as-is, except for native methods which are
+replaced by a stub. Methods that are to be overridden are also replaced by a stub.
+
+Finally fields are also visited and changed from protected/private to public.
+
+
+- Method stubs
+--------------
+
+As indicated above, all native and overridden methods are replaced by a stub.
+We don't have the code to replace with in layoutlib_create.
+Instead the StubMethodAdapter replaces the code of the method by a call to
+OverrideMethod.invokeX(). When using the final JAR, the bridge can register
+listeners from these overridden method calls based on the method signatures.
+
+The listeners are currently pretty basic: we only pass the signature of the
+method being called, its caller object and a flag indicating whether the
+method was native. We do not currently provide the parameters. The listener
+can however specify the return value of the overridden method.
+
+An extension being worked on is to actually replace these listeners by
+direct calls to a delegate class, complete with parameters.
+
+
+- Strategies
+------------
+
+We currently have 4 strategies to deal with overriding the rendering code
+and make it run in Eclipse. Most of these strategies are implemented hand-in-hand
+by the bridge (which runs in Eclipse) and the generator.
+
+
+1- Class Injection
+
+This is the easiest: we currently inject 4 classes, namely:
+- OverrideMethod and its associated MethodListener and MethodAdapter are used
+  to intercept calls to some specific methods that are stubbed out and change
+  their return value.
+- CreateInfo class, which configured the generator. Not used yet, but could
+  in theory help us track what the generator changed.
+
+
+2- Overriding methods
+
+As explained earlier, the creator doesn't have any replacement code for
+methods to override. Instead it removes the original code and replaces it
+by a call to a specific OveriddeMethod.invokeX(). The bridge then registers
+a listener on the method signature and can provide an implementation.
+
+
+3- Renaming classes
+
+This simply changes the name of a class in its definition, as well as all its
+references in internal inner classes and methods.
+Calls from other classes are not modified -- they keep referencing the original
+class name. This allows the bridge to literally replace an implementation.
+
+An example will make this easier: android.graphics.Paint is the main drawing
+class that we need to replace. To do so, the generator renames Paint to _original_Paint.
+Later the bridge provides its own replacement version of Paint which will be used
+by the rest of the Android stack. The replacement version of Paint can still use
+(either by inheritance or delegation) all the original non-native code of _original_Paint
+if it so desires.
+
+Some of the Android classes are basically wrappers over native objects and since
+we don't have the native code in Eclipse, we need to provide a full alternate
+implementation. Sub-classing doesn't work as some native methods are static and
+we don't control object creation.
 
 This won't rename/replace the inner static methods of a given class.
 
 
+4- Method erasure based on return type
 
+This is mostly an implementation detail of the bridge: in the Paint class
+mentioned above, some inner static classes are used to pass around
+attributes (e.g. FontMetrics, or the Style enum) and all the original implementation
+is native.
+
+In this case we have a strategy that tells the generator that anything returning, for
+example, the inner class Paint$Style in the Paint class should be discarded and the
+bridge will provide its own implementation.
+
+
+- References -
+--------------
+
+
+The JVM Specification 2nd edition:
+  http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html
+
+Understanding bytecode:
+  http://www.ibm.com/developerworks/ibm/library/it-haggar_bytecode/
+
+Bytecode opcode list:
+  http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
+
+ASM user guide:
+  http://download.forge.objectweb.org/asm/asm-guide.pdf
+
+
+--
+end
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/LayoutlibDelegate.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/LayoutlibDelegate.java
new file mode 100644
index 0000000..9a48ea6
--- /dev/null
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/LayoutlibDelegate.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Denotes a method that has been converted to a delegate by layoutlib_create.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface LayoutlibDelegate {
+}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/Nullable.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/Nullable.java
new file mode 100755
index 0000000..0689c92
--- /dev/null
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/Nullable.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Denotes a parameter or field can be null.
+ * <p/>
+ * When decorating a method call parameter, this denotes the parameter can
+ * legitimately be null and the method will gracefully deal with it. Typically used
+ * on optional parameters.
+ * <p/>
+ * When decorating a method, this denotes the method might legitimately return null.
+ * <p/>
+ * This is a marker annotation and it has no specific attributes.
+ */
+@Retention(RetentionPolicy.SOURCE)
+public @interface Nullable {
+}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/VisibleForTesting.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/VisibleForTesting.java
new file mode 100755
index 0000000..e4e016b
--- /dev/null
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/annotations/VisibleForTesting.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Denotes that the class, method or field has its visibility relaxed so
+ * that unit tests can access it.
+ * <p/>
+ * The <code>visibility</code> argument can be used to specific what the original
+ * visibility should have been if it had not been made public or package-private for testing.
+ * The default is to consider the element private.
+ */
+@Retention(RetentionPolicy.SOURCE)
+public @interface VisibleForTesting {
+    /**
+     * Intended visibility if the element had not been made public or package-private for
+     * testing.
+     */
+    enum Visibility {
+        /** The element should be considered protected. */
+        PROTECTED,
+        /** The element should be considered package-private. */
+        PACKAGE,
+        /** The element should be considered private. */
+        PRIVATE
+    }
+
+    /**
+     * Intended visibility if the element had not been made public or package-private for testing.
+     * If not specified, one should assume the element originally intended to be private.
+     */
+    Visibility visibility() default Visibility.PRIVATE;
+}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
index 7b55ed3e..a9ede26 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
@@ -28,9 +28,9 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 import java.util.TreeMap;
-import java.util.Map.Entry;
 import java.util.jar.JarEntry;
 import java.util.jar.JarOutputStream;
 
@@ -60,38 +60,56 @@
      *  old-FQCN to rename and they get erased as they get renamed. At the end, classes still
      *  left here are not in the code base anymore and thus were not renamed. */
     private HashSet<String> mClassesNotRenamed;
-    /** A map { FQCN => map { list of return types to delete from the FQCN } }. */
+    /** A map { FQCN => set { list of return types to delete from the FQCN } }. */
     private HashMap<String, Set<String>> mDeleteReturns;
+    /** A map { FQCN => set { method names } } of methods to rewrite as delegates.
+     *  The special name {@link DelegateClassAdapter#ALL_NATIVES} can be used as in internal set. */
+    private final HashMap<String, Set<String>> mDelegateMethods;
 
     /**
      * Creates a new generator that can generate the output JAR with the stubbed classes.
-     * 
+     *
      * @param log Output logger.
      * @param osDestJar The path of the destination JAR to create.
-     * @param injectClasses The list of class from layoutlib_create to inject in layoutlib.
-     * @param stubMethods The list of methods to stub out. Each entry must be in the form
-     *          "package.package.OuterClass$InnerClass#MethodName".
-     * @param renameClasses The list of classes to rename, must be an even list: the binary FQCN
-     *          of class to replace followed by the new FQCN.
-     * @param deleteReturns List of classes for which the methods returning them should be deleted.
-     * The array contains a list of null terminated section starting with the name of the class
-     * to rename in which the methods are deleted, followed by a list of return types identifying
-     * the methods to delete.
+     * @param createInfo Creation parameters. Must not be null.
      */
-    public AsmGenerator(Log log, String osDestJar,
-            Class<?>[] injectClasses,
-            String[] stubMethods,
-            String[] renameClasses, String[] deleteReturns) {
+    public AsmGenerator(Log log, String osDestJar, ICreateInfo createInfo) {
         mLog = log;
         mOsDestJar = osDestJar;
-        mInjectClasses = injectClasses != null ? injectClasses : new Class<?>[0];
-        mStubMethods = stubMethods != null ? new HashSet<String>(Arrays.asList(stubMethods)) :
-                                             new HashSet<String>();
+        mInjectClasses = createInfo.getInjectedClasses();
+        mStubMethods = new HashSet<String>(Arrays.asList(createInfo.getOverriddenMethods()));
+
+        // Create the map/set of methods to change to delegates
+        mDelegateMethods = new HashMap<String, Set<String>>();
+        for (String signature : createInfo.getDelegateMethods()) {
+            int pos = signature.indexOf('#');
+            if (pos <= 0 || pos >= signature.length() - 1) {
+                continue;
+            }
+            String className = binaryToInternalClassName(signature.substring(0, pos));
+            String methodName = signature.substring(pos + 1);
+            Set<String> methods = mDelegateMethods.get(className);
+            if (methods == null) {
+                methods = new HashSet<String>();
+                mDelegateMethods.put(className, methods);
+            }
+            methods.add(methodName);
+        }
+        for (String className : createInfo.getDelegateClassNatives()) {
+            className = binaryToInternalClassName(className);
+            Set<String> methods = mDelegateMethods.get(className);
+            if (methods == null) {
+                methods = new HashSet<String>();
+                mDelegateMethods.put(className, methods);
+            }
+            methods.add(DelegateClassAdapter.ALL_NATIVES);
+        }
 
         // Create the map of classes to rename.
         mRenameClasses = new HashMap<String, String>();
         mClassesNotRenamed = new HashSet<String>();
-        int n = renameClasses == null ? 0 : renameClasses.length;
+        String[] renameClasses = createInfo.getRenamedClasses();
+        int n = renameClasses.length;
         for (int i = 0; i < n; i += 2) {
             assert i + 1 < n;
             // The ASM class names uses "/" separators, whereas regular FQCN use "."
@@ -100,38 +118,37 @@
             mRenameClasses.put(oldFqcn, newFqcn);
             mClassesNotRenamed.add(oldFqcn);
         }
-        
+
         // create the map of renamed class -> return type of method to delete.
         mDeleteReturns = new HashMap<String, Set<String>>();
-        if (deleteReturns != null) {
-            Set<String> returnTypes = null;
-            String renamedClass = null;
-            for (String className : deleteReturns) {
-                // if we reach the end of a section, add it to the main map
-                if (className == null) {
-                    if (returnTypes != null) {
-                        mDeleteReturns.put(renamedClass, returnTypes);
-                    }
-                    
-                    renamedClass = null;
-                    continue;
+        String[] deleteReturns = createInfo.getDeleteReturns();
+        Set<String> returnTypes = null;
+        String renamedClass = null;
+        for (String className : deleteReturns) {
+            // if we reach the end of a section, add it to the main map
+            if (className == null) {
+                if (returnTypes != null) {
+                    mDeleteReturns.put(renamedClass, returnTypes);
                 }
-    
-                // if the renamed class is null, this is the beginning of a section
-                if (renamedClass == null) {
-                    renamedClass = binaryToInternalClassName(className);
-                    continue;
-                }
-    
-                // just a standard return type, we add it to the list.
-                if (returnTypes == null) {
-                    returnTypes = new HashSet<String>();
-                }
-                returnTypes.add(binaryToInternalClassName(className));
+
+                renamedClass = null;
+                continue;
             }
+
+            // if the renamed class is null, this is the beginning of a section
+            if (renamedClass == null) {
+                renamedClass = binaryToInternalClassName(className);
+                continue;
+            }
+
+            // just a standard return type, we add it to the list.
+            if (returnTypes == null) {
+                returnTypes = new HashSet<String>();
+            }
+            returnTypes.add(binaryToInternalClassName(className));
         }
     }
-    
+
     /**
      * Returns the list of classes that have not been renamed yet.
      * <p/>
@@ -163,12 +180,12 @@
     public void setDeps(Map<String, ClassReader> deps) {
         mDeps = deps;
     }
-    
+
     /** Gets the map of classes to output as-is, except if they have native methods */
     public Map<String, ClassReader> getKeep() {
         return mKeep;
     }
-    
+
     /** Gets the map of dependencies that must be completely stubbed */
     public Map<String, ClassReader> getDeps() {
         return mDeps;
@@ -177,7 +194,7 @@
     /** Generates the final JAR */
     public void generate() throws FileNotFoundException, IOException {
         TreeMap<String, byte[]> all = new TreeMap<String, byte[]>();
-        
+
         for (Class<?> clazz : mInjectClasses) {
             String name = classToEntryPath(clazz);
             InputStream is = ClassLoader.getSystemResourceAsStream(name);
@@ -186,7 +203,7 @@
             name = classNameToEntryPath(transformName(cr.getClassName()));
             all.put(name, b);
         }
-        
+
         for (Entry<String, ClassReader> entry : mDeps.entrySet()) {
             ClassReader cr = entry.getValue();
             byte[] b = transform(cr, true /* stubNativesOnly */);
@@ -211,8 +228,8 @@
 
     /**
      * Writes the JAR file.
-     * 
-     * @param outStream The file output stream were to write the JAR. 
+     *
+     * @param outStream The file output stream were to write the JAR.
      * @param all The map of all classes to output.
      * @throws IOException if an I/O error has occurred
      */
@@ -236,7 +253,7 @@
     String classNameToEntryPath(String className) {
         return className.replaceAll("\\.", "/").concat(".class");
     }
-    
+
     /**
      * Utility method to get the JAR entry path from a Class name.
      * e.g. it returns someting like "com/foo/OuterClass$InnerClass1$InnerClass2.class"
@@ -248,30 +265,32 @@
             name = "$" + clazz.getSimpleName() + name;
             clazz = parent;
         }
-        return classNameToEntryPath(clazz.getCanonicalName() + name);        
+        return classNameToEntryPath(clazz.getCanonicalName() + name);
     }
 
     /**
      * Transforms a class.
      * <p/>
      * There are 3 kind of transformations:
-     * 
+     *
      * 1- For "mock" dependencies classes, we want to remove all code from methods and replace
      * by a stub. Native methods must be implemented with this stub too. Abstract methods are
      * left intact. Modified classes must be overridable (non-private, non-final).
      * Native methods must be made non-final, non-private.
-     * 
+     *
      * 2- For "keep" classes, we want to rewrite all native methods as indicated above.
      * If a class has native methods, it must also be made non-private, non-final.
-     * 
+     *
      * Note that unfortunately static methods cannot be changed to non-static (since static and
      * non-static are invoked differently.)
      */
     byte[] transform(ClassReader cr, boolean stubNativesOnly) {
 
         boolean hasNativeMethods = hasNativeMethods(cr);
+
+        // Get the class name, as an internal name (e.g. com/android/SomeClass$InnerClass)
         String className = cr.getClassName();
-        
+
         String newName = transformName(className);
         // transformName returns its input argument if there's no need to rename the class
         if (newName != className) {
@@ -288,16 +307,28 @@
         // Rewrite the new class from scratch, without reusing the constant pool from the
         // original class reader.
         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
-        
+
         ClassVisitor rv = cw;
         if (newName != className) {
             rv = new RenameClassAdapter(cw, className, newName);
         }
-        
-        TransformClassAdapter cv = new TransformClassAdapter(mLog, mStubMethods, 
+
+        ClassVisitor cv = new TransformClassAdapter(mLog, mStubMethods,
                 mDeleteReturns.get(className),
                 newName, rv,
                 stubNativesOnly, stubNativesOnly || hasNativeMethods);
+
+        Set<String> delegateMethods = mDelegateMethods.get(className);
+        if (delegateMethods != null && !delegateMethods.isEmpty()) {
+            // If delegateMethods only contains one entry ALL_NATIVES and the class is
+            // known to have no native methods, just skip this step.
+            if (hasNativeMethods ||
+                    !(delegateMethods.size() == 1 &&
+                            delegateMethods.contains(DelegateClassAdapter.ALL_NATIVES))) {
+                cv = new DelegateClassAdapter(mLog, cv, className, delegateMethods);
+            }
+        }
+
         cr.accept(cv, 0 /* flags */);
         return cw.toByteArray();
     }
@@ -323,7 +354,7 @@
                 return newName + className.substring(pos);
             }
         }
-        
+
         return className;
     }
 
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java
index 5424efa..722dce2 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java
@@ -16,6 +16,9 @@
 
 package com.android.tools.layoutlib.create;
 
+import com.android.tools.layoutlib.annotations.VisibleForTesting;
+import com.android.tools.layoutlib.annotations.VisibleForTesting.Visibility;
+
 import org.objectweb.asm.AnnotationVisitor;
 import org.objectweb.asm.Attribute;
 import org.objectweb.asm.ClassVisitor;
@@ -27,13 +30,18 @@
  * Indicates if a class contains any native methods.
  */
 public class ClassHasNativeVisitor implements ClassVisitor {
-    
+
     private boolean mHasNativeMethods = false;
-    
+
     public boolean hasNativeMethods() {
         return mHasNativeMethods;
     }
 
+    @VisibleForTesting(visibility=Visibility.PRIVATE)
+    protected void setHasNativeMethods(boolean hasNativeMethods, String methodName) {
+        mHasNativeMethods = hasNativeMethods;
+    }
+
     public void visit(int version, int access, String name, String signature,
             String superName, String[] interfaces) {
         // pass
@@ -65,7 +73,9 @@
 
     public MethodVisitor visitMethod(int access, String name, String desc,
             String signature, String[] exceptions) {
-        mHasNativeMethods |= ((access & Opcodes.ACC_NATIVE) != 0);
+        if ((access & Opcodes.ACC_NATIVE) != 0) {
+            setHasNativeMethods(true, name);
+        }
         return null;
     }
 
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 2ed8641..4b62e43 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
@@ -16,51 +16,157 @@
 
 package com.android.tools.layoutlib.create;
 
-public class CreateInfo {
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Describes the work to be done by {@link AsmGenerator}.
+ */
+public final class CreateInfo implements ICreateInfo {
+
+    /**
+     * Returns the list of class from layoutlib_create to inject in layoutlib.
+     * The list can be empty but must not be null.
+     */
+    public Class<?>[] getInjectedClasses() {
+        return INJECTED_CLASSES;
+    }
+
+    /**
+     * Returns the list of methods to rewrite as delegates.
+     * The list can be empty but must not be null.
+     */
+    public String[] getDelegateMethods() {
+        return DELEGATE_METHODS;
+    }
+
+    /**
+     * Returns the list of classes on which to delegate all native methods.
+     * The list can be empty but must not be null.
+     */
+    public String[] getDelegateClassNatives() {
+        return DELEGATE_CLASS_NATIVES;
+    }
+
+    /**
+     * Returns The list of methods to stub out. Each entry must be in the form
+     * "package.package.OuterClass$InnerClass#MethodName".
+     * The list can be empty but must not be null.
+     */
+    public String[] getOverriddenMethods() {
+        return OVERRIDDEN_METHODS;
+    }
+
+    /**
+     * Returns the list of classes to rename, must be an even list: the binary FQCN
+     * of class to replace followed by the new FQCN.
+     * The list can be empty but must not be null.
+     */
+    public String[] getRenamedClasses() {
+        return RENAMED_CLASSES;
+    }
+
+    /**
+     * Returns the list of classes for which the methods returning them should be deleted.
+     * The array contains a list of null terminated section starting with the name of the class
+     * to rename in which the methods are deleted, followed by a list of return types identifying
+     * the methods to delete.
+     * The list can be empty but must not be null.
+     */
+    public String[] getDeleteReturns() {
+        return DELETE_RETURNS;
+    }
+
+    //-----
+
     /**
      * The list of class from layoutlib_create to inject in layoutlib.
      */
-    public final static Class<?>[] INJECTED_CLASSES = new Class<?>[] {
+    private final static Class<?>[] INJECTED_CLASSES = new Class<?>[] {
             OverrideMethod.class,
             MethodListener.class,
             MethodAdapter.class,
-            CreateInfo.class
+            ICreateInfo.class,
+            CreateInfo.class,
+            LayoutlibDelegate.class
         };
 
     /**
+     * The list of methods to rewrite as delegates.
+     */
+    private final static String[] DELEGATE_METHODS = new String[] {
+        "android.content.res.Resources$Theme#obtainStyledAttributes",
+        "android.content.res.Resources$Theme#resolveAttribute",
+        "android.graphics.BitmapFactory#finishDecode",
+        "android.os.Handler#sendMessageAtTime",
+        "android.os.Build#getString",
+        "android.view.LayoutInflater#parseInclude",
+        "android.view.View#isInEditMode",
+        "com.android.internal.util.XmlUtils#convertValueToInt",
+        // TODO: comment out once DelegateClass is working
+    };
+
+    /**
+     * The list of classes on which to delegate all native methods.
+     */
+    private final static String[] DELEGATE_CLASS_NATIVES = new String[] {
+        "android.graphics.AvoidXfermode",
+        "android.graphics.Bitmap",
+        "android.graphics.BitmapFactory",
+        "android.graphics.BitmapShader",
+        "android.graphics.BlurMaskFilter",
+        "android.graphics.Canvas",
+        "android.graphics.ColorFilter",
+        "android.graphics.ColorMatrixColorFilter",
+        "android.graphics.ComposePathEffect",
+        "android.graphics.ComposeShader",
+        "android.graphics.CornerPathEffect",
+        "android.graphics.DashPathEffect",
+        "android.graphics.DiscretePathEffect",
+        "android.graphics.DrawFilter",
+        "android.graphics.EmbossMaskFilter",
+        "android.graphics.LayerRasterizer",
+        "android.graphics.LightingColorFilter",
+        "android.graphics.LinearGradient",
+        "android.graphics.MaskFilter",
+        "android.graphics.Matrix",
+        "android.graphics.NinePatch",
+        "android.graphics.Paint",
+        "android.graphics.PaintFlagsDrawFilter",
+        "android.graphics.Path",
+        "android.graphics.PathDashPathEffect",
+        "android.graphics.PathEffect",
+        "android.graphics.PixelXorXfermode",
+        "android.graphics.PorterDuffColorFilter",
+        "android.graphics.PorterDuffXfermode",
+        "android.graphics.RadialGradient",
+        "android.graphics.Rasterizer",
+        "android.graphics.Region",
+        "android.graphics.Shader",
+        "android.graphics.SumPathEffect",
+        "android.graphics.SweepGradient",
+        "android.graphics.Typeface",
+        "android.graphics.Xfermode",
+        "android.os.SystemClock",
+        "android.util.FloatMath",
+    };
+
+    /**
      * The list of methods to stub out. Each entry must be in the form
      *  "package.package.OuterClass$InnerClass#MethodName".
      */
-    public final static String[] OVERRIDDEN_METHODS = new String[] {
-            "android.view.View#isInEditMode",
-            "android.content.res.Resources$Theme#obtainStyledAttributes",
-        };
+    private final static String[] OVERRIDDEN_METHODS = new String[] {
+    };
 
     /**
      *  The list of classes to rename, must be an even list: the binary FQCN
      *  of class to replace followed by the new FQCN.
      */
-    public final static String[] RENAMED_CLASSES =
+    private final static String[] RENAMED_CLASSES =
         new String[] {
-            "android.graphics.Bitmap",              "android.graphics._Original_Bitmap",
-            "android.graphics.BitmapFactory",       "android.graphics._Original_BitmapFactory",
-            "android.graphics.BitmapShader",        "android.graphics._Original_BitmapShader",
-            "android.graphics.Canvas",              "android.graphics._Original_Canvas",
-            "android.graphics.ComposeShader",       "android.graphics._Original_ComposeShader",
-            "android.graphics.DashPathEffect",       "android.graphics._Original_DashPathEffect",
-            "android.graphics.LinearGradient",      "android.graphics._Original_LinearGradient",
-            "android.graphics.Matrix",              "android.graphics._Original_Matrix",
-            "android.graphics.Paint",               "android.graphics._Original_Paint",
-            "android.graphics.Path",                "android.graphics._Original_Path",
-            "android.graphics.PorterDuffXfermode",  "android.graphics._Original_PorterDuffXfermode",
-            "android.graphics.RadialGradient",      "android.graphics._Original_RadialGradient",
-            "android.graphics.Shader",              "android.graphics._Original_Shader",
-            "android.graphics.SweepGradient",       "android.graphics._Original_SweepGradient",
-            "android.graphics.Typeface",            "android.graphics._Original_Typeface",
             "android.os.ServiceManager",            "android.os._Original_ServiceManager",
-            "android.util.FloatMath",               "android.util._Original_FloatMath",
             "android.view.SurfaceView",             "android.view._Original_SurfaceView",
             "android.view.accessibility.AccessibilityManager", "android.view.accessibility._Original_AccessibilityManager",
+            "android.webkit.WebView",               "android.webkit._Original_WebView",
         };
 
     /**
@@ -69,15 +175,8 @@
      * to rename in which the methods are deleted, followed by a list of return types identifying
      * the methods to delete.
      */
-    public final static String[] REMOVED_METHODS =
+    private final static String[] DELETE_RETURNS =
         new String[] {
-            "android.graphics.Paint",       // class to delete methods from
-            "android.graphics.Paint$Align", // list of type identifying methods to delete
-            "android.graphics.Paint$Style",
-            "android.graphics.Paint$Join",
-            "android.graphics.Paint$Cap",
-            "android.graphics.Paint$FontMetrics",
-            "android.graphics.Paint$FontMetricsInt",
             null };                         // separator, for next class/methods list.
 }
 
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java
new file mode 100644
index 0000000..9cba8a0
--- /dev/null
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.create;
+
+import org.objectweb.asm.ClassAdapter;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+import java.util.Set;
+
+/**
+ * A {@link DelegateClassAdapter} can transform some methods from a class into
+ * delegates that defer the call to an associated delegate class.
+ * <p/>
+ * This is used to override specific methods and or all native methods in classes.
+ */
+public class DelegateClassAdapter extends ClassAdapter {
+
+    public final static String ALL_NATIVES = "<<all_natives>>";
+
+    private final String mClassName;
+    private final Set<String> mDelegateMethods;
+    private final Log mLog;
+
+    /**
+     * Creates a new {@link DelegateClassAdapter} that can transform some methods
+     * from a class into delegates that defer the call to an associated delegate class.
+     * <p/>
+     * This is used to override specific methods and or all native methods in classes.
+     *
+     * @param log The logger object. Must not be null.
+     * @param cv the class visitor to which this adapter must delegate calls.
+     * @param className The internal class name of the class to visit,
+     *          e.g. <code>com/android/SomeClass$InnerClass</code>.
+     * @param delegateMethods The set of method names to modify and/or the
+     *          special constant {@link #ALL_NATIVES} to convert all native methods.
+     */
+    public DelegateClassAdapter(Log log,
+            ClassVisitor cv,
+            String className,
+            Set<String> delegateMethods) {
+        super(cv);
+        mLog = log;
+        mClassName = className;
+        mDelegateMethods = delegateMethods;
+    }
+
+    //----------------------------------
+    // Methods from the ClassAdapter
+
+    @Override
+    public MethodVisitor visitMethod(int access, String name, String desc,
+            String signature, String[] exceptions) {
+
+        boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
+        boolean isNative = (access & Opcodes.ACC_NATIVE) != 0;
+
+        boolean useDelegate = (isNative && mDelegateMethods.contains(ALL_NATIVES)) ||
+                              mDelegateMethods.contains(name);
+
+        if (useDelegate) {
+            // remove native
+            access = access & ~Opcodes.ACC_NATIVE;
+        }
+
+        MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
+        if (useDelegate) {
+            DelegateMethodAdapter a = new DelegateMethodAdapter(mLog, mw, mClassName,
+                                                                name, desc, isStatic);
+            if (isNative) {
+                // A native has no code to visit, so we need to generate it directly.
+                a.generateCode();
+            } else {
+                return a;
+            }
+        }
+        return mw;
+    }
+}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter.java
new file mode 100644
index 0000000..8d7f016
--- /dev/null
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter.java
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.create;
+
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+import java.util.ArrayList;
+
+/**
+ * This method adapter rewrites a method by discarding the original code and generating
+ * a call to a delegate. Original annotations are passed along unchanged.
+ * <p/>
+ * Calls are delegated to a class named <code>&lt;className&gt;_Delegate</code> with
+ * static methods matching the methods to be overridden here. The methods have the
+ * same return type. The argument type list is the same except the "this" reference is
+ * passed first for non-static methods.
+ * <p/>
+ * A new annotation is added.
+ * <p/>
+ * Note that native methods have, by definition, no code so there's nothing a visitor
+ * can visit. That means the caller must call {@link #generateCode()} directly for
+ * a native and use the visitor pattern for non-natives.
+ * <p/>
+ * Instances of this class are not re-usable. You need a new instance for each method.
+ */
+class DelegateMethodAdapter implements MethodVisitor {
+
+    /**
+     * Suffix added to delegate classes.
+     */
+    public static final String DELEGATE_SUFFIX = "_Delegate";
+
+    private static String CONSTRUCTOR = "<init>";
+    private static String CLASS_INIT = "<clinit>";
+
+    /** The parent method writer */
+    private MethodVisitor mParentVisitor;
+    /** Flag to output the first line number. */
+    private boolean mOutputFirstLineNumber = true;
+    /** The original method descriptor (return type + argument types.) */
+    private String mDesc;
+    /** True if the original method is static. */
+    private final boolean mIsStatic;
+    /** The internal class name (e.g. <code>com/android/SomeClass$InnerClass</code>.) */
+    private final String mClassName;
+    /** The method name. */
+    private final String mMethodName;
+    /** Logger object. */
+    private final Log mLog;
+    /** True if {@link #visitCode()} has been invoked. */
+    private boolean mVisitCodeCalled;
+
+    /**
+     * Creates a new {@link DelegateMethodAdapter} that will transform this method
+     * into a delegate call.
+     * <p/>
+     * See {@link DelegateMethodAdapter} for more details.
+     *
+     * @param log The logger object. Must not be null.
+     * @param mv the method visitor to which this adapter must delegate calls.
+     * @param className The internal class name of the class to visit,
+     *          e.g. <code>com/android/SomeClass$InnerClass</code>.
+     * @param methodName The simple name of the method.
+     * @param desc A method descriptor (c.f. {@link Type#getReturnType(String)} +
+     *          {@link Type#getArgumentTypes(String)})
+     * @param isStatic True if the method is declared static.
+     */
+    public DelegateMethodAdapter(Log log,
+            MethodVisitor mv,
+            String className,
+            String methodName,
+            String desc,
+            boolean isStatic) {
+        mLog = log;
+        mParentVisitor = mv;
+        mClassName = className;
+        mMethodName = methodName;
+        mDesc = desc;
+        mIsStatic = isStatic;
+
+        if (CONSTRUCTOR.equals(methodName) || CLASS_INIT.equals(methodName)) {
+            // We're going to simplify by not supporting constructors.
+            // The only trick with a constructor is to find the proper super constructor
+            // and call it (and deciding if we should mirror the original method call to
+            // a custom constructor or call a default one.)
+            throw new UnsupportedOperationException(
+                    String.format("Delegate doesn't support overriding constructor %1$s:%2$s(%3$s)",
+                            className, methodName, desc));
+        }
+    }
+
+    /**
+     * Generates the new code for the method.
+     * <p/>
+     * For native methods, this must be invoked directly by {@link DelegateClassAdapter}
+     * (since they have no code to visit).
+     * <p/>
+     * Otherwise for non-native methods the {@link DelegateClassAdapter} simply needs to
+     * return this instance of {@link DelegateMethodAdapter} and let the normal visitor pattern
+     * invoke it as part of the {@link ClassReader#accept(ClassVisitor, int)} workflow and then
+     * this method will be invoked from {@link MethodVisitor#visitEnd()}.
+     */
+    public void generateCode() {
+        /*
+         * The goal is to generate a call to a static delegate method.
+         * If this method is non-static, the first parameter will be 'this'.
+         * All the parameters must be passed and then the eventual return type returned.
+         *
+         * Example, let's say we have a method such as
+         *   public void method_1(int a, Object b, ArrayList<String> c) { ... }
+         *
+         * We'll want to create a body that calls a delegate method like this:
+         *   TheClass_Delegate.method_1(this, a, b, c);
+         *
+         * If the method is non-static and the class name is an inner class (e.g. has $ in its
+         * last segment), we want to push the 'this' of the outer class first:
+         *   OuterClass_InnerClass_Delegate.method_1(
+         *     OuterClass.this,
+         *     OuterClass$InnerClass.this,
+         *     a, b, c);
+         *
+         * Only one level of inner class is supported right now, for simplicity and because
+         * we don't need more.
+         *
+         * The generated class name is the current class name with "_Delegate" appended to it.
+         * One thing to realize is that we don't care about generics -- since generic types
+         * are erased at runtime, they have no influence on the method name being called.
+         */
+
+        // Add our annotation
+        AnnotationVisitor aw = mParentVisitor.visitAnnotation(
+                Type.getObjectType(Type.getInternalName(LayoutlibDelegate.class)).toString(),
+                true); // visible at runtime
+        aw.visitEnd();
+
+        if (!mVisitCodeCalled) {
+            // If this is a direct call to generateCode() as done by DelegateClassAdapter
+            // for natives, visitCode() hasn't been called yet.
+            mParentVisitor.visitCode();
+            mVisitCodeCalled = true;
+        }
+
+        ArrayList<Type> paramTypes = new ArrayList<Type>();
+        String delegateClassName = mClassName + DELEGATE_SUFFIX;
+        boolean pushedArg0 = false;
+        int maxStack = 0;
+
+        // For an instance method (e.g. non-static), push the 'this' preceded
+        // by the 'this' of any outer class, if any.
+        if (!mIsStatic) {
+            // Check if the last segment of the class name has inner an class.
+            // Right now we only support one level of inner classes.
+            int slash = mClassName.lastIndexOf('/');
+            int dol = mClassName.lastIndexOf('$');
+            if (dol != -1 && dol > slash && dol == mClassName.indexOf('$')) {
+                String outerClass = mClassName.substring(0, dol);
+                Type outerType = Type.getObjectType(outerClass);
+
+                // Change a delegate class name to "com/foo/Outer_Inner_Delegate"
+                delegateClassName = delegateClassName.replace('$', '_');
+
+                // The first-level inner class has a package-protected member called 'this$0'
+                // that points to the outer class.
+
+                // Push this.getField("this$0") on the call stack.
+                mParentVisitor.visitVarInsn(Opcodes.ALOAD, 0); // var 0 = this
+                mParentVisitor.visitFieldInsn(Opcodes.GETFIELD,
+                        mClassName,                 // class where the field is defined
+                        "this$0",                   // field name
+                        outerType.getDescriptor()); // type of the field
+                maxStack++;
+                paramTypes.add(outerType);
+            }
+
+            // Push "this" for the instance method, which is always ALOAD 0
+            mParentVisitor.visitVarInsn(Opcodes.ALOAD, 0);
+            maxStack++;
+            pushedArg0 = true;
+            paramTypes.add(Type.getObjectType(mClassName));
+        }
+
+        // Push all other arguments. Start at arg 1 if we already pushed 'this' above.
+        Type[] argTypes = Type.getArgumentTypes(mDesc);
+        int maxLocals = pushedArg0 ? 1 : 0;
+        for (Type t : argTypes) {
+            int size = t.getSize();
+            mParentVisitor.visitVarInsn(t.getOpcode(Opcodes.ILOAD), maxLocals);
+            maxLocals += size;
+            maxStack += size;
+            paramTypes.add(t);
+        }
+
+        // Construct the descriptor of the delegate based on the parameters
+        // we pushed on the call stack. The return type remains unchanged.
+        String desc = Type.getMethodDescriptor(
+                Type.getReturnType(mDesc),
+                paramTypes.toArray(new Type[paramTypes.size()]));
+
+        // Invoke the static delegate
+        mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
+                delegateClassName,
+                mMethodName,
+                desc);
+
+        Type returnType = Type.getReturnType(mDesc);
+        mParentVisitor.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
+
+        mParentVisitor.visitMaxs(maxStack, maxLocals);
+        mParentVisitor.visitEnd();
+
+        // For debugging now. Maybe we should collect these and store them in
+        // a text file for helping create the delegates. We could also compare
+        // the text file to a golden and break the build on unsupported changes
+        // or regressions. Even better we could fancy-print something that looks
+        // like the expected Java method declaration.
+        mLog.debug("Delegate: %1$s # %2$s %3$s", delegateClassName, mMethodName, desc);
+    }
+
+    /* Pass down to visitor writer. In this implementation, either do nothing. */
+    public void visitCode() {
+        mVisitCodeCalled = true;
+        mParentVisitor.visitCode();
+    }
+
+    /*
+     * visitMaxs is called just before visitEnd if there was any code to rewrite.
+     * Skip the original.
+     */
+    public void visitMaxs(int maxStack, int maxLocals) {
+    }
+
+    /**
+     * End of visiting. Generate the messaging code.
+     */
+    public void visitEnd() {
+        generateCode();
+    }
+
+    /* Writes all annotation from the original method. */
+    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+        return mParentVisitor.visitAnnotation(desc, visible);
+    }
+
+    /* Writes all annotation default values from the original method. */
+    public AnnotationVisitor visitAnnotationDefault() {
+        return mParentVisitor.visitAnnotationDefault();
+    }
+
+    public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
+            boolean visible) {
+        return mParentVisitor.visitParameterAnnotation(parameter, desc, visible);
+    }
+
+    /* Writes all attributes from the original method. */
+    public void visitAttribute(Attribute attr) {
+        mParentVisitor.visitAttribute(attr);
+    }
+
+    /*
+     * Only writes the first line number present in the original code so that source
+     * viewers can direct to the correct method, even if the content doesn't match.
+     */
+    public void visitLineNumber(int line, Label start) {
+        if (mOutputFirstLineNumber) {
+            mParentVisitor.visitLineNumber(line, start);
+            mOutputFirstLineNumber = false;
+        }
+    }
+
+    public void visitInsn(int opcode) {
+        // Skip original code.
+    }
+
+    public void visitLabel(Label label) {
+        // Skip original code.
+    }
+
+    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
+        // Skip original code.
+    }
+
+    public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+        // Skip original code.
+    }
+
+    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
+        // Skip original code.
+    }
+
+    public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
+        // Skip original code.
+    }
+
+    public void visitIincInsn(int var, int increment) {
+        // Skip original code.
+    }
+
+    public void visitIntInsn(int opcode, int operand) {
+        // Skip original code.
+    }
+
+    public void visitJumpInsn(int opcode, Label label) {
+        // Skip original code.
+    }
+
+    public void visitLdcInsn(Object cst) {
+        // Skip original code.
+    }
+
+    public void visitLocalVariable(String name, String desc, String signature,
+            Label start, Label end, int index) {
+        // Skip original code.
+    }
+
+    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
+        // Skip original code.
+    }
+
+    public void visitMultiANewArrayInsn(String desc, int dims) {
+        // Skip original code.
+    }
+
+    public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
+        // Skip original code.
+    }
+
+    public void visitTypeInsn(int opcode, String type) {
+        // Skip original code.
+    }
+
+    public void visitVarInsn(int opcode, int var) {
+        // Skip original code.
+    }
+
+}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
new file mode 100644
index 0000000..40c1706
--- /dev/null
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.create;
+
+/**
+ * Interface describing the work to be done by {@link AsmGenerator}.
+ */
+public interface ICreateInfo {
+
+    /**
+     * Returns the list of class from layoutlib_create to inject in layoutlib.
+     * The list can be empty but must not be null.
+     */
+    public abstract Class<?>[] getInjectedClasses();
+
+    /**
+     * Returns the list of methods to rewrite as delegates.
+     * The list can be empty but must not be null.
+     */
+    public abstract String[] getDelegateMethods();
+
+    /**
+     * Returns the list of classes on which to delegate all native methods.
+     * The list can be empty but must not be null.
+     */
+    public abstract String[] getDelegateClassNatives();
+
+    /**
+     * Returns The list of methods to stub out. Each entry must be in the form
+     * "package.package.OuterClass$InnerClass#MethodName".
+     * The list can be empty but must not be null.
+     */
+    public abstract String[] getOverriddenMethods();
+
+    /**
+     * Returns the list of classes to rename, must be an even list: the binary FQCN
+     * of class to replace followed by the new FQCN.
+     * The list can be empty but must not be null.
+     */
+    public abstract String[] getRenamedClasses();
+
+    /**
+     * Returns the list of classes for which the methods returning them should be deleted.
+     * The array contains a list of null terminated section starting with the name of the class
+     * to rename in which the methods are deleted, followed by a list of return types identifying
+     * the methods to delete.
+     * The list can be empty but must not be null.
+     */
+    public abstract String[] getDeleteReturns();
+
+}
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 b30e9e5..0fce7ef 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
@@ -21,7 +21,28 @@
 import java.util.Set;
 
 
-
+/**
+ * Entry point for the layoutlib_create tool.
+ * <p/>
+ * The tool does not currently rely on any external configuration file.
+ * Instead the configuration is mostly done via the {@link CreateInfo} class.
+ * <p/>
+ * For a complete description of the tool and its implementation, please refer to
+ * the "README.txt" file at the root of this project.
+ * <p/>
+ * For a quick test, invoke this as follows:
+ * <pre>
+ * $ make layoutlib
+ * </pre>
+ * which does:
+ * <pre>
+ * $ make layoutlib_create &lt;bunch of framework jars&gt;
+ * $ out/host/linux-x86/framework/bin/layoutlib_create \
+ *        out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar \
+ *        out/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jar \
+ *        out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
+ * </pre>
+ */
 public class Main {
 
     public static void main(String[] args) {
@@ -42,15 +63,12 @@
         }
 
         try {
-            AsmGenerator agen = new AsmGenerator(log, osDestJar[0],
-                    CreateInfo.INJECTED_CLASSES,
-                    CreateInfo.OVERRIDDEN_METHODS,
-                    CreateInfo.RENAMED_CLASSES,
-                    CreateInfo.REMOVED_METHODS
-            );
+            AsmGenerator agen = new AsmGenerator(log, osDestJar[0], new CreateInfo());
 
             AsmAnalyzer aa = new AsmAnalyzer(log, osJarPath, agen,
-                    new String[] { "android.view.View" },   // derived from
+                    new String[] {                          // derived from
+                        "android.view.View",
+                    },
                     new String[] {                          // include classes
                         "android.*", // for android.R
                         "android.util.*",
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
index e294d56..f2d9755 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
@@ -26,7 +26,7 @@
 import java.util.Set;
 
 /**
- * Class adapter that can stub some or all of the methods of the class. 
+ * Class adapter that can stub some or all of the methods of the class.
  */
 class TransformClassAdapter extends ClassAdapter {
 
@@ -41,12 +41,12 @@
 
     /**
      * Creates a new class adapter that will stub some or all methods.
-     * @param logger 
-     * @param stubMethods 
+     * @param logger
+     * @param stubMethods  list of method signatures to always stub out
      * @param deleteReturns list of types that trigger the deletion of methods returning them.
      * @param className The name of the class being modified
      * @param cv The parent class writer visitor
-     * @param stubNativesOnly True if only native methods should be stubbed. False if all 
+     * @param stubNativesOnly True if only native methods should be stubbed. False if all
      *                        methods should be stubbed.
      * @param hasNative True if the method has natives, in which case its access should be
      *                  changed.
@@ -67,10 +67,10 @@
     @Override
     public void visit(int version, int access, String name,
             String signature, String superName, String[] interfaces) {
-        
+
         // This class might be being renamed.
         name = mClassName;
-        
+
         // remove protected or private and set as public
         access = access & ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED);
         access |= Opcodes.ACC_PUBLIC;
@@ -82,7 +82,7 @@
         mIsInterface = ((access & Opcodes.ACC_INTERFACE) != 0);
         super.visit(version, access, name, signature, superName, interfaces);
     }
-    
+
     /* Visits the header of an inner class. */
     @Override
     public void visitInnerClass(String name, String outerName, String innerName, int access) {
@@ -101,7 +101,7 @@
     @Override
     public MethodVisitor visitMethod(int access, String name, String desc,
             String signature, String[] exceptions) {
-        
+
         if (mDeleteReturns != null) {
             Type t = Type.getReturnType(desc);
             if (t.getSort() == Type.OBJECT) {
@@ -130,16 +130,16 @@
             (mStubAll ||
              (access & Opcodes.ACC_NATIVE) != 0) ||
              mStubMethods.contains(methodSignature)) {
-            
+
             boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
             boolean isNative = (access & Opcodes.ACC_NATIVE) != 0;
 
             // remove abstract, final and native
             access = access & ~(Opcodes.ACC_ABSTRACT | Opcodes.ACC_FINAL | Opcodes.ACC_NATIVE);
-            
+
             String invokeSignature = methodSignature + desc;
             mLog.debug("  Stub: %s (%s)", invokeSignature, isNative ? "native" : "");
-            
+
             MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
             return new StubMethodAdapter(mw, name, returnType(desc), invokeSignature,
                     isStatic, isNative);
@@ -149,7 +149,7 @@
             return super.visitMethod(access, name, desc, signature, exceptions);
         }
     }
-    
+
     /* Visits a field. Makes it public. */
     @Override
     public FieldVisitor visitField(int access, String name, String desc, String signature,
@@ -157,7 +157,7 @@
         // change access to public
         access &= ~(Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE);
         access |= Opcodes.ACC_PUBLIC;
-        
+
         return super.visitField(access, name, desc, signature, value);
     }
 
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java
index 603284e..d6dba6a 100644
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java
+++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmAnalyzerTest.java
@@ -22,7 +22,6 @@
 import static org.junit.Assert.assertNotNull;
 
 import com.android.tools.layoutlib.create.AsmAnalyzer.DependencyVisitor;
-import com.android.tools.layoutlib.create.LogTest.MockLog;
 
 import org.junit.After;
 import org.junit.Before;
@@ -46,9 +45,9 @@
 
     @Before
     public void setUp() throws Exception {
-        mLog = new LogTest.MockLog();
+        mLog = new MockLog();
         URL url = this.getClass().getClassLoader().getResource("data/mock_android.jar");
-        
+
         mOsJarPath = new ArrayList<String>();
         mOsJarPath.add(url.getFile());
 
@@ -69,9 +68,9 @@
                 "mock_android.dummy.InnerTest$DerivingClass",
                 "mock_android.dummy.InnerTest$MyGenerics1",
                 "mock_android.dummy.InnerTest$MyIntEnum",
-                "mock_android.dummy.InnerTest$MyStaticInnerClass",   
-                "mock_android.dummy.InnerTest$NotStaticInner1", 
-                "mock_android.dummy.InnerTest$NotStaticInner2",  
+                "mock_android.dummy.InnerTest$MyStaticInnerClass",
+                "mock_android.dummy.InnerTest$NotStaticInner1",
+                "mock_android.dummy.InnerTest$NotStaticInner2",
                 "mock_android.view.View",
                 "mock_android.view.ViewGroup",
                 "mock_android.view.ViewGroup$LayoutParams",
@@ -83,7 +82,7 @@
             },
             map.keySet().toArray());
     }
-    
+
     @Test
     public void testFindClass() throws IOException, LogAbortException {
         Map<String, ClassReader> zipClasses = mAa.parseZip(mOsJarPath);
@@ -91,7 +90,7 @@
 
         ClassReader cr = mAa.findClass("mock_android.view.ViewGroup$LayoutParams",
                 zipClasses, found);
-        
+
         assertNotNull(cr);
         assertEquals("mock_android/view/ViewGroup$LayoutParams", cr.getClassName());
         assertArrayEquals(new String[] { "mock_android.view.ViewGroup$LayoutParams" },
@@ -172,14 +171,14 @@
                 "mock_android.widget.TableLayout",
             },
             found.keySet().toArray());
-        
+
         for (String key : found.keySet()) {
             ClassReader value = found.get(key);
             assertNotNull("No value for " + key, value);
             assertEquals(key, AsmAnalyzer.classReaderToClassName(value));
         }
     }
-    
+
     @Test
     public void testDependencyVisitor() throws IOException, LogAbortException {
         Map<String, ClassReader> zipClasses = mAa.parseZip(mOsJarPath);
@@ -190,7 +189,7 @@
 
         ClassReader cr = mAa.findClass("mock_android.widget.TableLayout", zipClasses, keep);
         DependencyVisitor visitor = mAa.getVisitor(zipClasses, keep, new_keep, in_deps, out_deps);
-        
+
         // get first level dependencies
         cr.accept(visitor, 0 /* flags */);
 
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java
index 7cdf79a..f4ff389 100644
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java
+++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java
@@ -20,8 +20,6 @@
 
 import static org.junit.Assert.assertArrayEquals;
 
-import com.android.tools.layoutlib.create.LogTest.MockLog;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -44,9 +42,9 @@
 
     @Before
     public void setUp() throws Exception {
-        mLog = new LogTest.MockLog();
+        mLog = new MockLog();
         URL url = this.getClass().getClassLoader().getResource("data/mock_android.jar");
-        
+
         mOsJarPath = new ArrayList<String>();
         mOsJarPath.add(url.getFile());
 
@@ -65,16 +63,41 @@
 
     @Test
     public void testClassRenaming() throws IOException, LogAbortException {
-        
-        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar,
-            null, // classes to inject in the final JAR
-            null,  // methods to force override
-            new String[] {  // classes to rename (so that we can replace them)
-                "mock_android.view.View", "mock_android.view._Original_View",
-                "not.an.actual.ClassName", "anoter.fake.NewClassName",
-            },
-            null // methods deleted from their return type.
-            );
+
+        ICreateInfo ci = new ICreateInfo() {
+            public Class<?>[] getInjectedClasses() {
+                // classes to inject in the final JAR
+                return new Class<?>[0];
+            }
+
+            public String[] getDelegateMethods() {
+                return new String[0];
+            }
+
+            public String[] getDelegateClassNatives() {
+                return new String[0];
+            }
+
+            public String[] getOverriddenMethods() {
+                // methods to force override
+                return new String[0];
+            }
+
+            public String[] getRenamedClasses() {
+                // classes to rename (so that we can replace them)
+                return new String[] {
+                        "mock_android.view.View", "mock_android.view._Original_View",
+                        "not.an.actual.ClassName", "anoter.fake.NewClassName",
+                };
+            }
+
+            public String[] getDeleteReturns() {
+                 // methods deleted from their return type.
+                return new String[0];
+            }
+        };
+
+        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
 
         AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
                 null,                 // derived from
@@ -83,7 +106,7 @@
                 });
         aa.analyze();
         agen.generate();
-        
+
         Set<String> notRenamed = agen.getClassesNotRenamed();
         assertArrayEquals(new String[] { "not/an/actual/ClassName" }, notRenamed.toArray());
     }
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java
new file mode 100644
index 0000000..0135c40
--- /dev/null
+++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/ClassHasNativeVisitorTest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.create;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+import org.objectweb.asm.ClassReader;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+
+/**
+ * Tests {@link ClassHasNativeVisitor}.
+ */
+public class ClassHasNativeVisitorTest {
+
+    @Test
+    public void testHasNative() throws IOException {
+        MockClassHasNativeVisitor cv = new MockClassHasNativeVisitor();
+        String className =
+                this.getClass().getCanonicalName() + "$" + ClassWithNative.class.getSimpleName();
+        ClassReader cr = new ClassReader(className);
+
+        cr.accept(cv, 0 /* flags */);
+        assertArrayEquals(new String[] { "native_method" }, cv.getMethodsFound());
+        assertTrue(cv.hasNativeMethods());
+    }
+
+    @Test
+    public void testHasNoNative() throws IOException {
+        MockClassHasNativeVisitor cv = new MockClassHasNativeVisitor();
+        String className =
+            this.getClass().getCanonicalName() + "$" + ClassWithoutNative.class.getSimpleName();
+        ClassReader cr = new ClassReader(className);
+
+        cr.accept(cv, 0 /* flags */);
+        assertArrayEquals(new String[0], cv.getMethodsFound());
+        assertFalse(cv.hasNativeMethods());
+    }
+
+    //-------
+
+    /**
+     * Overrides {@link ClassHasNativeVisitor} to collec the name of the native methods found.
+     */
+    private static class MockClassHasNativeVisitor extends ClassHasNativeVisitor {
+        private ArrayList<String> mMethodsFound = new ArrayList<String>();
+
+        public String[] getMethodsFound() {
+            return mMethodsFound.toArray(new String[mMethodsFound.size()]);
+        }
+
+        @Override
+        protected void setHasNativeMethods(boolean hasNativeMethods, String methodName) {
+            if (hasNativeMethods) {
+                mMethodsFound.add(methodName);
+            }
+            super.setHasNativeMethods(hasNativeMethods, methodName);
+        }
+    }
+
+    /**
+     * Dummy test class with a native method.
+     */
+    public static class ClassWithNative {
+        public ClassWithNative() {
+        }
+
+        public void callTheNativeMethod() {
+            native_method();
+        }
+
+        private native void native_method();
+    }
+
+    /**
+     * Dummy test class with no native method.
+     */
+    public static class ClassWithoutNative {
+        public ClassWithoutNative() {
+        }
+
+        public void someMethod() {
+        }
+    }
+}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java
new file mode 100644
index 0000000..e8b3ea8
--- /dev/null
+++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/DelegateClassAdapterTest.java
@@ -0,0 +1,409 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.create;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.tools.layoutlib.create.dataclass.ClassWithNative;
+import com.android.tools.layoutlib.create.dataclass.OuterClass;
+import com.android.tools.layoutlib.create.dataclass.OuterClass.InnerClass;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+public class DelegateClassAdapterTest {
+
+    private MockLog mLog;
+
+    private static final String NATIVE_CLASS_NAME = ClassWithNative.class.getCanonicalName();
+    private static final String OUTER_CLASS_NAME = OuterClass.class.getCanonicalName();
+    private static final String INNER_CLASS_NAME = OuterClass.class.getCanonicalName() + "$" +
+                                                   InnerClass.class.getSimpleName();
+
+    @Before
+    public void setUp() throws Exception {
+        mLog = new MockLog();
+        mLog.setVerbose(true); // capture debug error too
+    }
+
+    /**
+     * Tests that a class not being modified still works.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testNoOp() throws Throwable {
+        // create an instance of the class that will be modified
+        // (load the class in a distinct class loader so that we can trash its definition later)
+        ClassLoader cl1 = new ClassLoader(this.getClass().getClassLoader()) { };
+        Class<ClassWithNative> clazz1 = (Class<ClassWithNative>) cl1.loadClass(NATIVE_CLASS_NAME);
+        ClassWithNative instance1 = clazz1.newInstance();
+        assertEquals(42, instance1.add(20, 22));
+        try {
+            instance1.callNativeInstance(10, 3.1415, new Object[0] );
+            fail("Test should have failed to invoke callTheNativeMethod [1]");
+        } catch (UnsatisfiedLinkError e) {
+            // This is expected to fail since the native method is not implemented.
+        }
+
+        // Now process it but tell the delegate to not modify any method
+        ClassWriter cw = new ClassWriter(0 /*flags*/);
+
+        HashSet<String> delegateMethods = new HashSet<String>();
+        String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
+        DelegateClassAdapter cv = new DelegateClassAdapter(
+                mLog, cw, internalClassName, delegateMethods);
+
+        ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
+        cr.accept(cv, 0 /* flags */);
+
+        // Load the generated class in a different class loader and try it again
+
+        ClassLoader2 cl2 = null;
+        try {
+            cl2 = new ClassLoader2() {
+                @Override
+                public void testModifiedInstance() throws Exception {
+                    Class<?> clazz2 = loadClass(NATIVE_CLASS_NAME);
+                    Object i2 = clazz2.newInstance();
+                    assertNotNull(i2);
+                    assertEquals(42, callAdd(i2, 20, 22));
+
+                    try {
+                        callCallNativeInstance(i2, 10, 3.1415, new Object[0]);
+                        fail("Test should have failed to invoke callTheNativeMethod [2]");
+                    } catch (InvocationTargetException e) {
+                        // This is expected to fail since the native method has NOT been
+                        // overridden here.
+                        assertEquals(UnsatisfiedLinkError.class, e.getCause().getClass());
+                    }
+
+                    // Check that the native method does NOT have the new annotation
+                    Method[] m = clazz2.getDeclaredMethods();
+                    assertEquals("native_instance", m[2].getName());
+                    assertTrue(Modifier.isNative(m[2].getModifiers()));
+                    Annotation[] a = m[2].getAnnotations();
+                    assertEquals(0, a.length);
+                }
+            };
+            cl2.add(NATIVE_CLASS_NAME, cw);
+            cl2.testModifiedInstance();
+        } catch (Throwable t) {
+            throw dumpGeneratedClass(t, cl2);
+        }
+    }
+
+    /**
+     * {@link DelegateMethodAdapter} does not support overriding constructors yet,
+     * so this should fail with an {@link UnsupportedOperationException}.
+     *
+     * Although not tested here, the message of the exception should contain the
+     * constructor signature.
+     */
+    @Test(expected=UnsupportedOperationException.class)
+    public void testConstructorsNotSupported() throws IOException {
+        ClassWriter cw = new ClassWriter(0 /*flags*/);
+
+        String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
+
+        HashSet<String> delegateMethods = new HashSet<String>();
+        delegateMethods.add("<init>");
+        DelegateClassAdapter cv = new DelegateClassAdapter(
+                mLog, cw, internalClassName, delegateMethods);
+
+        ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
+        cr.accept(cv, 0 /* flags */);
+    }
+
+    @Test
+    public void testDelegateNative() throws Throwable {
+        ClassWriter cw = new ClassWriter(0 /*flags*/);
+        String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
+
+        HashSet<String> delegateMethods = new HashSet<String>();
+        delegateMethods.add(DelegateClassAdapter.ALL_NATIVES);
+        DelegateClassAdapter cv = new DelegateClassAdapter(
+                mLog, cw, internalClassName, delegateMethods);
+
+        ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
+        cr.accept(cv, 0 /* flags */);
+
+        // Load the generated class in a different class loader and try it
+        ClassLoader2 cl2 = null;
+        try {
+            cl2 = new ClassLoader2() {
+                @Override
+                public void testModifiedInstance() throws Exception {
+                    Class<?> clazz2 = loadClass(NATIVE_CLASS_NAME);
+                    Object i2 = clazz2.newInstance();
+                    assertNotNull(i2);
+
+                    // Use reflection to access inner methods
+                    assertEquals(42, callAdd(i2, 20, 22));
+
+                     Object[] objResult = new Object[] { null };
+                     int result = callCallNativeInstance(i2, 10, 3.1415, objResult);
+                     assertEquals((int)(10 + 3.1415), result);
+                     assertSame(i2, objResult[0]);
+
+                     // Check that the native method now has the new annotation and is not native
+                     Method[] m = clazz2.getDeclaredMethods();
+                     assertEquals("native_instance", m[2].getName());
+                     assertFalse(Modifier.isNative(m[2].getModifiers()));
+                     Annotation[] a = m[2].getAnnotations();
+                     assertEquals("LayoutlibDelegate", a[0].annotationType().getSimpleName());
+                }
+            };
+            cl2.add(NATIVE_CLASS_NAME, cw);
+            cl2.testModifiedInstance();
+        } catch (Throwable t) {
+            throw dumpGeneratedClass(t, cl2);
+        }
+    }
+
+    @Test
+    public void testDelegateInner() throws Throwable {
+        // We'll delegate the "get" method of both the inner and outer class.
+        HashSet<String> delegateMethods = new HashSet<String>();
+        delegateMethods.add("get");
+
+        // Generate the delegate for the outer class.
+        ClassWriter cwOuter = new ClassWriter(0 /*flags*/);
+        String outerClassName = OUTER_CLASS_NAME.replace('.', '/');
+        DelegateClassAdapter cvOuter = new DelegateClassAdapter(
+                mLog, cwOuter, outerClassName, delegateMethods);
+        ClassReader cr = new ClassReader(OUTER_CLASS_NAME);
+        cr.accept(cvOuter, 0 /* flags */);
+
+        // Generate the delegate for the inner class.
+        ClassWriter cwInner = new ClassWriter(0 /*flags*/);
+        String innerClassName = INNER_CLASS_NAME.replace('.', '/');
+        DelegateClassAdapter cvInner = new DelegateClassAdapter(
+                mLog, cwInner, innerClassName, delegateMethods);
+        cr = new ClassReader(INNER_CLASS_NAME);
+        cr.accept(cvInner, 0 /* flags */);
+
+        // Load the generated classes in a different class loader and try them
+        ClassLoader2 cl2 = null;
+        try {
+            cl2 = new ClassLoader2() {
+                @Override
+                public void testModifiedInstance() throws Exception {
+
+                    // Check the outer class
+                    Class<?> outerClazz2 = loadClass(OUTER_CLASS_NAME);
+                    Object o2 = outerClazz2.newInstance();
+                    assertNotNull(o2);
+
+                    // The original Outer.get returns 1+10+20,
+                    // but the delegate makes it return 4+10+20
+                    assertEquals(4+10+20, callGet(o2, 10, 20));
+
+                    // Check the inner class. Since it's not a static inner class, we need
+                    // to use the hidden constructor that takes the outer class as first parameter.
+                    Class<?> innerClazz2 = loadClass(INNER_CLASS_NAME);
+                    Constructor<?> innerCons = innerClazz2.getConstructor(
+                                                                new Class<?>[] { outerClazz2 });
+                    Object i2 = innerCons.newInstance(new Object[] { o2 });
+                    assertNotNull(i2);
+
+                    // The original Inner.get returns 3+10+20,
+                    // but the delegate makes it return 6+10+20
+                    assertEquals(6+10+20, callGet(i2, 10, 20));
+                }
+            };
+            cl2.add(OUTER_CLASS_NAME, cwOuter.toByteArray());
+            cl2.add(INNER_CLASS_NAME, cwInner.toByteArray());
+            cl2.testModifiedInstance();
+        } catch (Throwable t) {
+            throw dumpGeneratedClass(t, cl2);
+        }
+    }
+
+    //-------
+
+    /**
+     * A class loader than can define and instantiate our modified classes.
+     * <p/>
+     * The trick here is that this class loader will test our <em>modified</em> version
+     * of the classes, the one with the delegate calls.
+     * <p/>
+     * Trying to do so in the original class loader generates all sort of link issues because
+     * there are 2 different definitions of the same class name. This class loader will
+     * define and load the class when requested by name and provide helpers to access the
+     * instance methods via reflection.
+     */
+    private abstract class ClassLoader2 extends ClassLoader {
+
+        private final Map<String, byte[]> mClassDefs = new HashMap<String, byte[]>();
+
+        public ClassLoader2() {
+            super(null);
+        }
+
+        public ClassLoader2 add(String className, byte[] definition) {
+            mClassDefs.put(className, definition);
+            return this;
+        }
+
+        public ClassLoader2 add(String className, ClassWriter rewrittenClass) {
+            mClassDefs.put(className, rewrittenClass.toByteArray());
+            return this;
+        }
+
+        private Set<Entry<String, byte[]>> getByteCode() {
+            return mClassDefs.entrySet();
+        }
+
+        @SuppressWarnings("unused")
+        @Override
+        protected Class<?> findClass(String name) throws ClassNotFoundException {
+            try {
+                return super.findClass(name);
+            } catch (ClassNotFoundException e) {
+
+                byte[] def = mClassDefs.get(name);
+                if (def != null) {
+                    // Load the modified ClassWithNative from its bytes representation.
+                    return defineClass(name, def, 0, def.length);
+                }
+
+                try {
+                    // Load everything else from the original definition into the new class loader.
+                    ClassReader cr = new ClassReader(name);
+                    ClassWriter cw = new ClassWriter(0);
+                    cr.accept(cw, 0);
+                    byte[] bytes = cw.toByteArray();
+                    return defineClass(name, bytes, 0, bytes.length);
+
+                } catch (IOException ioe) {
+                    throw new RuntimeException(ioe);
+                }
+            }
+        }
+
+        /**
+         * Accesses {@link OuterClass#get()} or {@link InnerClass#get() }via reflection.
+         */
+        public int callGet(Object instance, int a, long b) throws Exception {
+            Method m = instance.getClass().getMethod("get",
+                    new Class<?>[] { int.class, long.class } );
+
+            Object result = m.invoke(instance, new Object[] { a, b });
+            return ((Integer) result).intValue();
+        }
+
+        /**
+         * Accesses {@link ClassWithNative#add(int, int)} via reflection.
+         */
+        public int callAdd(Object instance, int a, int b) throws Exception {
+            Method m = instance.getClass().getMethod("add",
+                    new Class<?>[] { int.class, int.class });
+
+            Object result = m.invoke(instance, new Object[] { a, b });
+            return ((Integer) result).intValue();
+        }
+
+        /**
+         * Accesses {@link ClassWithNative#callNativeInstance(int, double, Object[])}
+         * via reflection.
+         */
+        public int callCallNativeInstance(Object instance, int a, double d, Object[] o)
+                throws Exception {
+            Method m = instance.getClass().getMethod("callNativeInstance",
+                    new Class<?>[] { int.class, double.class, Object[].class });
+
+            Object result = m.invoke(instance, new Object[] { a, d, o });
+            return ((Integer) result).intValue();
+        }
+
+        public abstract void testModifiedInstance() throws Exception;
+    }
+
+    /**
+     * For debugging, it's useful to dump the content of the generated classes
+     * along with the exception that was generated.
+     *
+     * However to make it work you need to pull in the org.objectweb.asm.util.TraceClassVisitor
+     * class and associated utilities which are found in the ASM source jar. Since we don't
+     * want that dependency in the source code, we only put it manually for development and
+     * access the TraceClassVisitor via reflection if present.
+     *
+     * @param t The exception thrown by {@link ClassLoader2#testModifiedInstance()}
+     * @param cl2 The {@link ClassLoader2} instance with the generated bytecode.
+     * @return Either original {@code t} or a new wrapper {@link Throwable}
+     */
+    private Throwable dumpGeneratedClass(Throwable t, ClassLoader2 cl2) {
+        try {
+            // For debugging, dump the bytecode of the class in case of unexpected error
+            // if we can find the TraceClassVisitor class.
+            Class<?> tcvClass = Class.forName("org.objectweb.asm.util.TraceClassVisitor");
+
+            StringBuilder sb = new StringBuilder();
+            sb.append('\n').append(t.getClass().getCanonicalName());
+            if (t.getMessage() != null) {
+                sb.append(": ").append(t.getMessage());
+              }
+
+            for (Entry<String, byte[]> entry : cl2.getByteCode()) {
+                String className = entry.getKey();
+                byte[] bytes = entry.getValue();
+
+                StringWriter sw = new StringWriter();
+                PrintWriter pw = new PrintWriter(sw);
+                // next 2 lines do: TraceClassVisitor tcv = new TraceClassVisitor(pw);
+                Constructor<?> cons = tcvClass.getConstructor(new Class<?>[] { pw.getClass() });
+                Object tcv = cons.newInstance(new Object[] { pw });
+                ClassReader cr2 = new ClassReader(bytes);
+                cr2.accept((ClassVisitor) tcv, 0 /* flags */);
+
+                sb.append("\nBytecode dump: <").append(className).append(">:\n")
+                  .append(sw.toString());
+            }
+
+            // Re-throw exception with new message
+            RuntimeException ex = new RuntimeException(sb.toString(), t);
+            return ex;
+        } catch (Throwable ignore) {
+            // In case of problem, just throw the original exception as-is.
+            return t;
+        }
+    }
+
+}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java
index 3f13158..1a5f653 100644
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java
+++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/LogTest.java
@@ -24,33 +24,8 @@
 
 public class LogTest {
 
-    public static class MockLog extends Log {
-        StringBuilder mOut = new StringBuilder();
-        StringBuilder mErr = new StringBuilder();
-        
-        public String getOut() {
-            return mOut.toString();
-        }
-        
-        public String getErr() {
-            return mErr.toString();
-        }
-        
-        @Override
-        protected void outPrintln(String msg) {
-            mOut.append(msg);
-            mOut.append('\n');
-        }
-        
-        @Override
-        protected void errPrintln(String msg) {
-            mErr.append(msg);
-            mErr.append('\n');
-        }
-    }
-
     private MockLog mLog;
-    
+
     @Before
     public void setUp() throws Exception {
         mLog = new MockLog();
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/MockLog.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/MockLog.java
new file mode 100644
index 0000000..de750a3
--- /dev/null
+++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/MockLog.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.create;
+
+
+public class MockLog extends Log {
+    StringBuilder mOut = new StringBuilder();
+    StringBuilder mErr = new StringBuilder();
+
+    public String getOut() {
+        return mOut.toString();
+    }
+
+    public String getErr() {
+        return mErr.toString();
+    }
+
+    @Override
+    protected void outPrintln(String msg) {
+        mOut.append(msg);
+        mOut.append('\n');
+    }
+
+    @Override
+    protected void errPrintln(String msg) {
+        mErr.append(msg);
+        mErr.append('\n');
+    }
+}
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java
new file mode 100644
index 0000000..c314853
--- /dev/null
+++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.create.dataclass;
+
+import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
+
+/**
+ * Dummy test class with a native method.
+ * The native method is not defined and any attempt to invoke it will
+ * throw an {@link UnsatisfiedLinkError}.
+ *
+ * Used by {@link DelegateClassAdapterTest}.
+ */
+public class ClassWithNative {
+    public ClassWithNative() {
+    }
+
+    public int add(int a, int b) {
+        return a + b;
+    }
+
+    // Note: it's good to have a long or double for testing parameters since they take
+    // 2 slots in the stack/locals maps.
+
+    public int callNativeInstance(int a, double d, Object[] o) {
+        return native_instance(a, d, o);
+    }
+
+    private native int native_instance(int a, double d, Object[] o);
+}
+
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative_Delegate.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative_Delegate.java
new file mode 100644
index 0000000..a3d4dc6
--- /dev/null
+++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/ClassWithNative_Delegate.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.create.dataclass;
+
+import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
+
+/**
+ * The delegate that receives the call to {@link ClassWithNative_Delegate}'s overridden methods.
+ *
+ * Used by {@link DelegateClassAdapterTest}.
+ */
+public class ClassWithNative_Delegate {
+    public static int native_instance(ClassWithNative instance, int a, double d, Object[] o) {
+        if (o != null && o.length > 0) {
+            o[0] = instance;
+        }
+        return (int)(a + d);
+    }
+}
+
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass.java
new file mode 100644
index 0000000..9dc2f69
--- /dev/null
+++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.create.dataclass;
+
+import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
+
+/**
+ * Test class with an inner class.
+ *
+ * Used by {@link DelegateClassAdapterTest}.
+ */
+public class OuterClass {
+    private int mOuterValue = 1;
+    public OuterClass() {
+    }
+
+    // Outer.get returns 1 + a + b
+    // Note: it's good to have a long or double for testing parameters since they take
+    // 2 slots in the stack/locals maps.
+    public int get(int a, long b) {
+        return mOuterValue + a + (int) b;
+    }
+
+    public class InnerClass {
+        public InnerClass() {
+        }
+
+        // Inner.get returns 1+2=3 + a + b
+        public int get(int a, long b) {
+            return 2 + mOuterValue + a + (int) b;
+        }
+    }
+}
+
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_Delegate.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_Delegate.java
new file mode 100644
index 0000000..3252d87
--- /dev/null
+++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_Delegate.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.create.dataclass;
+
+import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
+
+/**
+ * Used by {@link DelegateClassAdapterTest}.
+ */
+public class OuterClass_Delegate {
+    // The delegate override of Outer.get returns 4 + a + b
+    public static int get(OuterClass instance, int a, long b) {
+        return 4 + a + (int) b;
+    }
+}
+
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_InnerClass_Delegate.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_InnerClass_Delegate.java
new file mode 100644
index 0000000..b472220
--- /dev/null
+++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/dataclass/OuterClass_InnerClass_Delegate.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tools.layoutlib.create.dataclass;
+
+import com.android.tools.layoutlib.create.DelegateClassAdapterTest;
+import com.android.tools.layoutlib.create.dataclass.OuterClass.InnerClass;
+
+/**
+ * Used by {@link DelegateClassAdapterTest}.
+ */
+public class OuterClass_InnerClass_Delegate {
+    // The delegate override of Inner.get return 6 + a + b
+    public static int get(OuterClass outer, InnerClass inner, int a, long b) {
+        return 6 + a + (int) b;
+    }
+}
