Merge "More changes to the test projects."
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoring.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoring.java
index 0480cda..53b8f49 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoring.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoring.java
@@ -56,6 +56,7 @@
 import org.eclipse.text.edits.ReplaceEdit;
 import org.eclipse.text.edits.TextEdit;
 import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
+import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
 import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
@@ -283,6 +284,17 @@
 
         setAndroidAttribute(newTextElement, androidNsPrefix, drawableAttribute, src);
 
+        // If the removed LinearLayout is the root container, transfer its namespace
+        // declaration to the TextView
+        if (layout.getParentNode() instanceof Document) {
+            List<Attr> declarations = findNamespaceAttributes(layout);
+            for (Attr attribute : declarations) {
+                if (attribute instanceof IndexedRegion) {
+                    newTextElement.setAttribute(attribute.getName(), attribute.getValue());
+                }
+            }
+        }
+
         // Update any layout references to the layout to point to the text view
         String layoutId = getId(layout);
         if (layoutId.length() > 0) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoringTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoringTest.java
index 04b9b1a..c1a5ca4 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoringTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/UseCompoundDrawableRefactoringTest.java
@@ -57,6 +57,11 @@
         checkRefactoring("refactoring/usecompound/compound_all.xml", "@+id/layout3");
     }
 
+    public void test7() throws Exception {
+        // Test converting where a namespace needs to be migrated
+        checkRefactoring("refactoring/usecompound/compound5.xml", "@+id/layout");
+    }
+
     private void checkRefactoring(String basename, String id) throws Exception {
         IFile file = getLayoutFile(getProject(), basename);
         TestContext info = setupTestContext(file, basename);
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound5-expected-7.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound5-expected-7.xml
new file mode 100644
index 0000000..e909811
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound5-expected-7.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/TextView1"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:drawableBottom="@drawable/ic_launcher"
+    android:text="Hello World" >
+
+</TextView>
\ No newline at end of file
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound5.info b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound5.info
new file mode 100644
index 0000000..8eb5c4b
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound5.info
@@ -0,0 +1,3 @@
+android.widget.LinearLayout [0,74,480,800] <LinearLayout>
+    android.widget.TextView [0,0,107,26] <TextView>
+    android.widget.ImageView [0,26,72,98] <ImageView>
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound5.xml b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound5.xml
new file mode 100644
index 0000000..49c0594
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/layout/refactoring/testdata/refactoring/usecompound/compound5.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:id="@+id/layout"
+    android:orientation="vertical" >
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Hello World" />
+
+    <ImageView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/ic_launcher" />
+
+</LinearLayout>
diff --git a/files/tools_source.properties b/files/tools_source.properties
index f43d1e3..cd107f0 100644
--- a/files/tools_source.properties
+++ b/files/tools_source.properties
@@ -1,3 +1,3 @@
 Pkg.UserSrc=false
-Pkg.Revision=17
+Pkg.Revision=18
 Platform.MinPlatformToolsRev=11
diff --git a/lint/cli/src/com/android/tools/lint/HtmlReporter.java b/lint/cli/src/com/android/tools/lint/HtmlReporter.java
index 9cc9c6f..8b3e99e 100644
--- a/lint/cli/src/com/android/tools/lint/HtmlReporter.java
+++ b/lint/cli/src/com/android/tools/lint/HtmlReporter.java
@@ -28,6 +28,7 @@
 import com.android.tools.lint.detector.api.Position;
 import com.android.tools.lint.detector.api.Project;
 import com.android.tools.lint.detector.api.Severity;
+import com.google.common.annotations.Beta;
 import com.google.common.base.Charsets;
 import com.google.common.collect.Maps;
 import com.google.common.io.ByteStreams;
@@ -51,8 +52,12 @@
 
 /**
  * A reporter which emits lint results into an HTML report.
+ * <p>
+ * <b>NOTE: This is not a public or final API; if you rely on this be prepared
+ * to adjust your code for the next tools release.</b>
  */
-class HtmlReporter extends Reporter {
+@Beta
+public class HtmlReporter extends Reporter {
     private static boolean USE_HOLO_STYLE = true;
     private static final String CSS = USE_HOLO_STYLE
             ? "hololike.css" : "default.css"; //$NON-NLS-1$ //$NON-NLS-2$
@@ -72,13 +77,20 @@
     private String mStripPrefix;
     private String mFixUrl;
 
-    HtmlReporter(Main client, File output) throws IOException {
+    /**
+     * Creates a new {@link HtmlReporter}
+     *
+     * @param client the associated client
+     * @param output the output file
+     * @throws IOException if an error occurs
+     */
+    public HtmlReporter(Main client, File output) throws IOException {
         super(client, output);
         mWriter = new BufferedWriter(new FileWriter(output));
     }
 
     @Override
-    void write(int errorCount, int warningCount, List<Warning> issues) throws IOException {
+    public void write(int errorCount, int warningCount, List<Warning> issues) throws IOException {
         Map<Issue, String> missing = computeMissingIssues(issues);
 
         mWriter.write(
@@ -406,7 +418,7 @@
                     continue;
                 }
 
-                if (!issue.isEnabledByDefault()) {
+                if (!issue.isEnabledByDefault() && !mClient.isAllEnabled()) {
                     map.put(issue, "Default");
                     continue;
                 }
diff --git a/lint/cli/src/com/android/tools/lint/Main.java b/lint/cli/src/com/android/tools/lint/Main.java
index 1f2191b..6a40cb3 100644
--- a/lint/cli/src/com/android/tools/lint/Main.java
+++ b/lint/cli/src/com/android/tools/lint/Main.java
@@ -78,6 +78,7 @@
     private static final String ARG_CONFIG     = "--config";       //$NON-NLS-1$
     private static final String ARG_URL        = "--url";          //$NON-NLS-1$
     private static final String ARG_VERSION    = "--version";      //$NON-NLS-1$
+    private static final String ARG_EXITCODE   = "--exitcode";     //$NON-NLS-1$
 
     private static final String ARG_NOWARN2    = "--nowarn";       //$NON-NLS-1$
     // GCC style flag names for options
@@ -100,7 +101,8 @@
     private Set<String> mEnabled = new HashSet<String>();
     /** If non-null, only run the specified checks (possibly modified by enable/disables) */
     private Set<String> mCheck = null;
-    private boolean mFatal;
+    private boolean mHasErrors;
+    private boolean mSetExitCode;
     private boolean mFullPath;
     private int mErrorCount;
     private int mWarningCount;
@@ -228,6 +230,8 @@
                 mQuiet = true;
             } else if (arg.equals(ARG_NOLINES)) {
                 mShowLines = false;
+            } else if (arg.equals(ARG_EXITCODE)) {
+                mSetExitCode = true;
             } else if (arg.equals(ARG_VERSION)) {
                 printVersion();
                 System.exit(0);
@@ -489,7 +493,7 @@
             System.exit(ERRNO_INVALIDARGS);
         }
 
-        System.exit(mFatal ? ERRNO_ERRORS : 0);
+        System.exit(mSetExitCode ? (mHasErrors ? ERRNO_ERRORS : 0) : 0);
     }
 
     /**
@@ -805,8 +809,10 @@
             ARG_HELP + " <topic>", "Help on the given topic, such as \"suppress\".",
             ARG_LISTIDS, "List the available issue id's and exit.",
             ARG_VERSION, "Output version information and exit.",
+            ARG_EXITCODE, "Set the exit code to " + ERRNO_ERRORS + " if errors are found.",
             ARG_SHOW, "List available issues along with full explanations.",
             ARG_SHOW + " <ids>", "Show full explanations for the given list of issue id's.",
+
             "", "\nEnabled Checks:",
             ARG_DISABLE + " <list>", "Disable the list of categories or " +
                 "specific issue id's. The list should be a comma-separated list of issue " +
@@ -823,7 +829,9 @@
             ARG_CONFIG + " <filename>", "Use the given configuration file to " +
                     "determine whether issues are enabled or disabled. If a project contains " +
                     "a lint.xml file, then this config file will be used as a fallback.",
-                    "", "\nOutput Options:",
+
+
+            "", "\nOutput Options:",
             ARG_QUIET, "Don't show progress.",
             ARG_FULLPATH, "Use full paths in the error output.",
             ARG_SHOWALL, "Do not truncate long messages, lists of alternate locations, etc.",
@@ -840,15 +848,14 @@
                 "to files, use " + ARG_URL + " " + VALUE_NONE,
             ARG_SIMPLEHTML + " <filename>", "Create a simple HTML report",
             ARG_XML + " <filename>", "Create an XML report instead.",
-        });
 
-        out.println("\nExit Status:");
-        printUsage(out, new String[] {
-                Integer.toString(ERRNO_ERRORS),      "Lint errors detected.",
-                Integer.toString(ERRNO_USAGE),       "Lint usage.",
-                Integer.toString(ERRNO_EXISTS),      "Cannot clobber existing file.",
-                Integer.toString(ERRNO_HELP),        "Lint help.",
-                Integer.toString(ERRNO_INVALIDARGS), "Invalid command-line argument.",
+            "", "\nExit Status:",
+            "0",                                 "Success.",
+            Integer.toString(ERRNO_ERRORS),      "Lint errors detected.",
+            Integer.toString(ERRNO_USAGE),       "Lint usage.",
+            Integer.toString(ERRNO_EXISTS),      "Cannot clobber existing file.",
+            Integer.toString(ERRNO_HELP),        "Lint help.",
+            Integer.toString(ERRNO_INVALIDARGS), "Invalid command-line argument.",
         });
     }
 
@@ -936,12 +943,12 @@
         }
 
         if (severity == Severity.FATAL) {
-            mFatal = true;
             // From here on, treat the fatal error as an error such that we don't display
             // both "Fatal:" and "Error:" etc in the error output.
             severity = Severity.ERROR;
         }
         if (severity == Severity.ERROR) {
+            mHasErrors = true;
             mErrorCount++;
         } else {
             mWarningCount++;
@@ -1096,11 +1103,14 @@
                 // Detectors shouldn't be returning ignore as a default severity,
                 // but in case they do, force it up to warning here to ensure that
                 // it's run
-                if (severity == Severity.IGNORE && severity == issue.getDefaultSeverity()) {
-                    return Severity.WARNING;
-                } else {
-                    return severity;
+                if (severity == Severity.IGNORE) {
+                    severity = issue.getDefaultSeverity();
+                    if (severity == Severity.IGNORE) {
+                        severity = Severity.WARNING;
+                    }
                 }
+
+                return severity;
             }
 
             if (mCheck != null && issue != LINT_ERROR && issue != PARSER_ERROR) {
@@ -1162,6 +1172,11 @@
         return path;
     }
 
+    /** Returns whether all warnings are enabled, including those disabled by default */
+    boolean isAllEnabled() {
+        return mWarnAll;
+    }
+
     /** Returns the issue registry used by this client */
     IssueRegistry getRegistry() {
         return mRegistry;
diff --git a/lint/cli/src/com/android/tools/lint/MultiProjectHtmlReporter.java b/lint/cli/src/com/android/tools/lint/MultiProjectHtmlReporter.java
index db7b4fb..d039edc 100644
--- a/lint/cli/src/com/android/tools/lint/MultiProjectHtmlReporter.java
+++ b/lint/cli/src/com/android/tools/lint/MultiProjectHtmlReporter.java
@@ -37,17 +37,17 @@
  * "Multiplexing" reporter which allows output to be split up into a separate
  * report for each separate project. It also adds an overview index.
  */
-class MultiProjectHtmlReporter extends HtmlReporter {
+public class MultiProjectHtmlReporter extends HtmlReporter {
     private static final String INDEX_NAME = "index.html"; //$NON-NLS-1$
     private final File mDir;
 
-    MultiProjectHtmlReporter(Main client, File dir) throws IOException {
+    public MultiProjectHtmlReporter(Main client, File dir) throws IOException {
         super(client, new File(dir, INDEX_NAME));
         mDir = dir;
     }
 
     @Override
-    void write(int errorCount, int warningCount, List<Warning> allIssues) throws IOException {
+    public void write(int errorCount, int warningCount, List<Warning> allIssues) throws IOException {
         Map<Project, List<Warning>> projectToWarnings = new HashMap<Project, List<Warning>>();
         for (Warning warning : allIssues) {
             List<Warning> list = projectToWarnings.get(warning.project);
diff --git a/lint/cli/src/com/android/tools/lint/Reporter.java b/lint/cli/src/com/android/tools/lint/Reporter.java
index bee0eb4..2c86635 100644
--- a/lint/cli/src/com/android/tools/lint/Reporter.java
+++ b/lint/cli/src/com/android/tools/lint/Reporter.java
@@ -20,6 +20,7 @@
 import static com.android.tools.lint.detector.api.LintConstants.DOT_PNG;
 import static com.android.tools.lint.detector.api.LintUtils.endsWith;
 
+import com.google.common.annotations.Beta;
 import com.google.common.io.ByteStreams;
 import com.google.common.io.Closeables;
 import com.google.common.io.Files;
@@ -35,8 +36,13 @@
 import java.util.List;
 import java.util.Map;
 
-/** A reporter is an output generator for lint warnings */
-abstract class Reporter {
+/** A reporter is an output generator for lint warnings
+ * <p>
+ * <b>NOTE: This is not a public or final API; if you rely on this be prepared
+ * to adjust your code for the next tools release.</b>
+ */
+@Beta
+public abstract class Reporter {
     protected final Main mClient;
     protected final File mOutput;
     protected String mTitle = "Lint Report";
@@ -47,7 +53,16 @@
     protected Map<File, String> mResourceUrl = new HashMap<File, String>();
     protected Map<String, File> mNameToFile = new HashMap<String, File>();
 
-    abstract void write(int errorCount, int warningCount, List<Warning> issues) throws IOException;
+    /**
+     * Write the given warnings into the report
+     *
+     * @param errorCount the number of errors
+     * @param warningCount the number of warnings
+     * @param issues the issues to be reported
+     * @throws IOException if an error occurs
+     */
+    public abstract void write(int errorCount, int warningCount, List<Warning> issues)
+            throws IOException;
 
     protected Reporter(Main client, File output) {
         mClient = client;
@@ -59,12 +74,12 @@
      *
      * @param title the title of the report
      */
-    void setTitle(String title) {
+    public void setTitle(String title) {
         mTitle = title;
     }
 
     /** @return the title of the report */
-    String getTitle() {
+    public String getTitle() {
         return mTitle;
     }
 
@@ -75,7 +90,7 @@
      * @param bundleResources if true, copy images into a directory relative to
      *            the report
      */
-    void setBundleResources(boolean bundleResources) {
+    public void setBundleResources(boolean bundleResources) {
         mBundleResources = bundleResources;
         mSimpleFormat = false;
     }
@@ -86,7 +101,7 @@
      *
      * @param simpleFormat whether the formatting should be simple
      */
-    void setSimpleFormat(boolean simpleFormat) {
+    public void setSimpleFormat(boolean simpleFormat) {
         mSimpleFormat = simpleFormat;
     }
 
@@ -96,7 +111,7 @@
      *
      * @return whether the report should use simple formatting
      */
-    boolean isSimpleFormat() {
+    public boolean isSimpleFormat() {
         return mSimpleFormat;
     }
 
diff --git a/lint/cli/src/com/android/tools/lint/TextReporter.java b/lint/cli/src/com/android/tools/lint/TextReporter.java
index 47202d1..63ee857 100644
--- a/lint/cli/src/com/android/tools/lint/TextReporter.java
+++ b/lint/cli/src/com/android/tools/lint/TextReporter.java
@@ -18,22 +18,35 @@
 
 import com.android.tools.lint.detector.api.Location;
 import com.android.tools.lint.detector.api.Position;
+import com.google.common.annotations.Beta;
 
 import java.io.IOException;
 import java.io.Writer;
 import java.util.List;
 
-/** A reporter which emits lint warnings as plain text strings */
-class TextReporter extends Reporter {
+/**
+ * A reporter which emits lint warnings as plain text strings
+ * <p>
+ * <b>NOTE: This is not a public or final API; if you rely on this be prepared
+ * to adjust your code for the next tools release.</b>
+ */
+@Beta
+public class TextReporter extends Reporter {
     private final Writer mWriter;
 
-    TextReporter(Main client, Writer writer) {
+    /**
+     * Constructs a new {@link TextReporter}
+     *
+     * @param client the client
+     * @param writer the writer to write into
+     */
+    public TextReporter(Main client, Writer writer) {
         super(client, null);
         mWriter = writer;
     }
 
     @Override
-    void write(int errorCount, int warningCount, List<Warning> issues) throws IOException {
+    public void write(int errorCount, int warningCount, List<Warning> issues) throws IOException {
         boolean abbreviate = mClient.getDriver().isAbbreviating();
 
         StringBuilder output = new StringBuilder(issues.size() * 200);
diff --git a/lint/cli/src/com/android/tools/lint/XmlReporter.java b/lint/cli/src/com/android/tools/lint/XmlReporter.java
index 4de1dd7..03fc937 100644
--- a/lint/cli/src/com/android/tools/lint/XmlReporter.java
+++ b/lint/cli/src/com/android/tools/lint/XmlReporter.java
@@ -18,6 +18,7 @@
 
 import com.android.tools.lint.detector.api.Location;
 import com.android.tools.lint.detector.api.Position;
+import com.google.common.annotations.Beta;
 import com.google.common.base.Charsets;
 import com.google.common.io.Files;
 
@@ -29,17 +30,28 @@
 
 /**
  * A reporter which emits lint results into an XML report.
+ * <p>
+ * <b>NOTE: This is not a public or final API; if you rely on this be prepared
+ * to adjust your code for the next tools release.</b>
  */
-class XmlReporter extends Reporter {
+@Beta
+public class XmlReporter extends Reporter {
     private final Writer mWriter;
 
-    XmlReporter(Main client, File output) throws IOException {
+    /**
+     * Constructs a new {@link XmlReporter}
+     *
+     * @param client the client
+     * @param output the output file
+     * @throws IOException if an error occurs
+     */
+    public XmlReporter(Main client, File output) throws IOException {
         super(client, output);
         mWriter = new BufferedWriter(Files.newWriter(output, Charsets.UTF_8));
     }
 
     @Override
-    void write(int errorCount, int warningCount, List<Warning> issues) throws IOException {
+    public void write(int errorCount, int warningCount, List<Warning> issues) throws IOException {
         mWriter.write(
                 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +     //$NON-NLS-1$
                 "<issues>\n");                                       //$NON-NLS-1$
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiClass.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiClass.java
index 7223670..8c35b74 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiClass.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiClass.java
@@ -172,6 +172,17 @@
     }
 
     public void addMethod(String name, int since) {
+        // Strip off the method type at the end to ensure that the code which
+        // produces inherited methods doesn't get confused and end up multiple entries.
+        // For example, java/nio/Buffer has the method "array()Ljava/lang/Object;",
+        // and the subclass java/nio/ByteBuffer has the method "array()[B". We want
+        // the lookup on mMethods to associate the ByteBuffer array method to be
+        // considered overriding the Buffer method.
+        int index = name.indexOf(')');
+        if (index != -1) {
+            name = name.substring(0, index + 1);
+        }
+
         Integer i = mMethods.get(name);
         if (i == null || i.intValue() > since) {
             mMethods.put(name, Integer.valueOf(since));
@@ -204,23 +215,47 @@
     }
 
     /**
-     * Returns the set of all members (method and fields), including inherited
+     * Returns the set of all methods, including inherited
      * ones.
      *
      * @param info the api to look up super classes from
-     * @return a set containing all the members (methods and fields)
+     * @return a set containing all the members fields
      */
-    public Set<String> getAllMembers(Api info) {
+    public Set<String> getAllMethods(Api info) {
         Set<String> members = new HashSet<String>(100);
-        addAllMembers(info, members);
+        addAllMethods(info, members);
 
         return members;
     }
 
-    private void addAllMembers(Api info, Set<String> set) {
+    private void addAllMethods(Api info, Set<String> set) {
         for (String method : mMethods.keySet()) {
             set.add(method);
         }
+        for (Pair<String, Integer> superClass : mSuperClasses) {
+            ApiClass clz = info.getClass(superClass.getFirst());
+            assert clz != null : superClass.getSecond();
+            if (clz != null) {
+                clz.addAllMethods(info, set);
+            }
+        }
+    }
+
+    /**
+     * Returns the set of all fields, including inherited
+     * ones.
+     *
+     * @param info the api to look up super classes from
+     * @return a set containing all the fields
+     */
+    public Set<String> getAllFields(Api info) {
+        Set<String> members = new HashSet<String>(100);
+        addAllFields(info, members);
+
+        return members;
+    }
+
+    private void addAllFields(Api info, Set<String> set) {
         for (String field : mFields.keySet()) {
             set.add(field);
         }
@@ -228,8 +263,9 @@
             ApiClass clz = info.getClass(superClass.getFirst());
             assert clz != null : superClass.getSecond();
             if (clz != null) {
-                clz.addAllMembers(info, set);
+                clz.addAllFields(info, set);
             }
         }
     }
+
 }
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiLookup.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiLookup.java
index 5f9a1e3..306e6a2 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiLookup.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiLookup.java
@@ -73,7 +73,7 @@
     /** Relative path to the api-versions.xml database file within the Lint installation */
     private static final String XML_FILE_PATH = "platform-tools/api/api-versions.xml"; //$NON-NLS-1$
     private static final String FILE_HEADER = "API database used by Android lint\000";
-    private static final int BINARY_FORMAT_VERSION = 1;
+    private static final int BINARY_FORMAT_VERSION = 2;
     private static final boolean DEBUG_FORCE_REGENERATE_BINARY = false;
     private static final boolean DEBUG_SEARCH = false;
     private static final boolean WRITE_STATS = false;
@@ -336,7 +336,8 @@
             String className = entry.getKey();
             ApiClass apiClass = entry.getValue();
 
-            Set<String> allMembers = apiClass.getAllMembers(info);
+            Set<String> allMethods = apiClass.getAllMethods(info);
+            Set<String> allFields = apiClass.getAllFields(info);
 
             // Strip out all members that have been supported since version 1.
             // This makes the database *much* leaner (down from about 4M to about
@@ -345,14 +346,27 @@
             // requires a version *higher* than the minimum. If in the future the
             // database needs to answer queries about whether a method is public
             // or not, then we'd need to put this data back in.
-            List<String> members = new ArrayList<String>(allMembers.size());
-            for (String member : allMembers) {
-                Integer since;
-                if (member.indexOf('(') != -1) {
-                    since = apiClass.getMethod(member, info);
-                } else {
-                    since = apiClass.getField(member, info);
+            List<String> members = new ArrayList<String>(allMethods.size() + allFields.size());
+            for (String member : allMethods) {
+                Integer since = apiClass.getMethod(member, info);
+                assert since != null : className + ':' + member;
+                if (since == null) {
+                    since = 1;
                 }
+                if (since != 1) {
+                    members.add(member);
+                }
+            }
+
+            // Strip out all members that have been supported since version 1.
+            // This makes the database *much* leaner (down from about 4M to about
+            // 1.7M), and this just fills the table with entries that ultimately
+            // don't help the API checker since it just needs to know if something
+            // requires a version *higher* than the minimum. If in the future the
+            // database needs to answer queries about whether a method is public
+            // or not, then we'd need to put this data back in.
+            for (String member : allFields) {
+                Integer since = apiClass.getField(member, info);
                 assert since != null : className + ':' + member;
                 if (since == null) {
                     since = 1;
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/InefficientWeightDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/InefficientWeightDetector.java
index 4dd7eb1..dc65f26 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/InefficientWeightDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/InefficientWeightDetector.java
@@ -157,6 +157,7 @@
             }
             if (allChildrenAreLayouts) {
                 context.report(BASELINE_WEIGHTS,
+                        element,
                         context.getLocation(element),
                         "Set android:baselineAligned=\"false\" on this element for better performance",
                         null);
@@ -178,6 +179,7 @@
                         "Use a %1$s of 0dip instead of %2$s for better performance",
                         dimension, size);
                 context.report(INEFFICIENT_WEIGHT,
+                        element,
                         context.getLocation(sizeNode != null ? sizeNode : weightChild), msg, null);
 
             }
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypographyDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypographyDetector.java
index bda828d..c5a9302 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypographyDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypographyDetector.java
@@ -178,6 +178,9 @@
     private static final String FRACTION_MESSAGE =
             "Use fraction character %1$c (%2$s) instead of %3$s ?";
 
+    private static final String FRACTION_MESSAGE_PATTERN =
+            "Use fraction character (.+) \\((.+)\\) instead of (.+) \\?";
+
     private boolean mCheckDashes;
     private boolean mCheckQuotes;
     private boolean mCheckFractions;
@@ -477,6 +480,17 @@
                     edits.add(new ReplaceEdit(endOffset, 1, "\u2019"));  //$NON-NLS-1$
                 }
             }
+        } else {
+            Matcher matcher = Pattern.compile(FRACTION_MESSAGE_PATTERN).matcher(message);
+            if (matcher.find()) {
+                //  "Use fraction character %1$c (%2$s) instead of %3$s ?";
+                String replace = matcher.group(3);
+                int offset = text.indexOf(replace);
+                if (offset != -1) {
+                    String replaceWith = matcher.group(2);
+                    edits.add(new ReplaceEdit(offset, replace.length(), replaceWith));
+                }
+            }
         }
 
         return edits;
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/UseCompoundDrawableDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/UseCompoundDrawableDetector.java
index 8ded0e6..540a0f1 100644
--- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/UseCompoundDrawableDetector.java
+++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/UseCompoundDrawableDetector.java
@@ -17,6 +17,7 @@
 package com.android.tools.lint.checks;
 
 import static com.android.tools.lint.detector.api.LintConstants.ANDROID_URI;
+import static com.android.tools.lint.detector.api.LintConstants.ATTR_BACKGROUND;
 import static com.android.tools.lint.detector.api.LintConstants.ATTR_LAYOUT_WEIGHT;
 import static com.android.tools.lint.detector.api.LintConstants.IMAGE_VIEW;
 import static com.android.tools.lint.detector.api.LintConstants.LINEAR_LAYOUT;
@@ -86,6 +87,12 @@
                 ((second.getTagName().equals(IMAGE_VIEW) &&
                         first.getTagName().equals(TEXT_VIEW) &&
                         !second.hasAttributeNS(ANDROID_URI, ATTR_LAYOUT_WEIGHT)))) {
+                // If the layout has a background, ignore since it would disappear from
+                // the TextView
+                if (element.hasAttributeNS(ANDROID_URI, ATTR_BACKGROUND)) {
+                    return;
+                }
+
                 context.report(ISSUE, element, context.getLocation(element),
                         "This tag and its children can be replaced by one <TextView/> and " +
                                 "a compound drawable", null);
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiLookupTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiLookupTest.java
index a7c2de9..044778f 100644
--- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiLookupTest.java
+++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiLookupTest.java
@@ -57,6 +57,11 @@
         assertTrue(mDb.getCallVersion("java/lang/Object", "getClass", "()") <= 1);
     }
 
+    public void testIssue26467() {
+        assertTrue(mDb.getCallVersion("java/nio/ByteBuffer", "array", "()") <= 1);
+        assertEquals(9, mDb.getCallVersion("java/nio/Buffer", "array", "()"));
+    }
+
     @Override
     protected Detector getDetector() {
         fail("This is not used in the ApiDatabase test");
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/UseCompoundDrawableDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/UseCompoundDrawableDetectorTest.java
index 16aee19..6abfa71 100644
--- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/UseCompoundDrawableDetectorTest.java
+++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/UseCompoundDrawableDetectorTest.java
@@ -31,4 +31,11 @@
                         "<TextView/> and a compound drawable",
                 lintFiles("res/layout/compound.xml"));
     }
+
+    public void testCompound2() throws Exception {
+        // Ignore layouts that set a custom background
+        assertEquals(
+                "No warnings.",
+                lintFiles("res/layout/compound2.xml"));
+    }
 }
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/compound2.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/compound2.xml
new file mode 100644
index 0000000..24f45dc
--- /dev/null
+++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/compound2.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:background="@android:drawable/ic_dialog_alert"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ImageView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+</LinearLayout>
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonPackage.java
index a784b34..606775f 100755
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonPackage.java
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonPackage.java
@@ -16,6 +16,7 @@
 

 package com.android.sdklib.internal.repository;

 

+import com.android.annotations.NonNull;

 import com.android.annotations.VisibleForTesting;

 import com.android.annotations.VisibleForTesting.Visibility;

 import com.android.sdklib.AndroidVersion;

@@ -178,7 +179,8 @@
 

         // For a missing id, we simply use a sanitized version of the display vendor

         if (vendorId.length() == 0) {

-            vendorId = sanitizeDisplayToNameId(vendor.length() > 0 ? vendor : vendorDisp);

+            boolean hasVendor = vendor.length() > 0;

+            vendorId = sanitizeDisplayToNameId(hasVendor ? vendor : vendorDisp);

         }

 

         assert vendorId.length() > 0;

@@ -267,7 +269,8 @@
 

         // For a missing id, we simply use a sanitized version of the display vendor

         if (vendorId.length() == 0) {

-            vendorId = sanitizeDisplayToNameId(vendor.length() > 0 ? vendor : vendorDisp);

+            boolean hasVendor = vendor.length() > 0;

+            vendorId = sanitizeDisplayToNameId(hasVendor ? vendor : vendorDisp);

         }

 

         assert vendorId.length() > 0;

@@ -398,22 +401,22 @@
     }

 

     /** Returns the vendor id, a string, for add-on packages. */

-    public String getVendorId() {

+    public @NonNull String getVendorId() {

         return mVendorId;

     }

 

     /** Returns the vendor, a string for display purposes. */

-    public String getDisplayVendor() {

+    public @NonNull String getDisplayVendor() {

         return mVendorDisplay;

     }

 

     /** Returns the name id, a string, for add-on packages or for libraries. */

-    public String getNameId() {

+    public @NonNull String getNameId() {

         return mNameId;

     }

 

     /** Returns the name, a string for display purposes. */

-    public String getDisplayName() {

+    public @NonNull String getDisplayName() {

         return mDisplayName;

     }

 

@@ -423,12 +426,12 @@
      * An add-on has the same {@link AndroidVersion} as the platform it depends on.

      */

     @Override

-    public AndroidVersion getVersion() {

+    public @NonNull AndroidVersion getVersion() {

         return mVersion;

     }

 

     /** Returns the libs defined in this add-on. Can be an empty array but not null. */

-    public Lib[] getLibs() {

+    public @NonNull Lib[] getLibs() {

         return mLibs;

     }

 

@@ -445,7 +448,7 @@
      * @since sdk-addon-2.xsd

      */

     @Override

-    public Pair<Integer, Integer> getLayoutlibVersion() {

+    public @NonNull Pair<Integer, Integer> getLayoutlibVersion() {

         return mLayoutlibVersion.getLayoutlibVersion();

     }

 

@@ -456,7 +459,7 @@
      * {@inheritDoc}

      */

     @Override

-    public String installId() {

+    public @NonNull String installId() {

         return encodeAddonName();

     }

 

@@ -577,6 +580,14 @@
         String name = displayName.toLowerCase(Locale.US);

         name = name.replaceAll("[^a-z0-9_-]+", "_");      //$NON-NLS-1$ //$NON-NLS-2$

         name = name.replaceAll("_+", "_");                //$NON-NLS-1$ //$NON-NLS-2$

+

+        // Trim leading and trailing underscores

+        if (name.length() > 1) {

+            name = name.replaceAll("^_+", "");            //$NON-NLS-1$ //$NON-NLS-2$

+        }

+        if (name.length() > 1) {

+            name = name.replaceAll("_+$", "");            //$NON-NLS-1$ //$NON-NLS-2$

+        }

         return name;

     }

 

@@ -586,9 +597,20 @@
             AddonPackage newPkg = (AddonPackage)pkg;

 

             // check they are the same add-on.

-            return getNameId().equals(newPkg.getNameId()) &&

-                    getVendorId().equals(newPkg.getVendorId()) &&

-                    getVersion().equals(newPkg.getVersion());

+            if (getNameId().equals(newPkg.getNameId()) &&

+                    getVersion().equals(newPkg.getVersion())) {

+                // Check the vendor-id field.

+                if (getVendorId().equals(newPkg.getVendorId())) {

+                    return true;

+                }

+

+                // When loading addons from the v3 schema that only had a <vendor>

+                // field, the vendor field has been converted to vendor-display so

+                // as a transition mechanism we should test this also.

+                // TODO: in a couple iterations of the SDK Manager, remove this check

+                // and only compare using the vendor-id field.

+                return getDisplayVendor().equals(newPkg.getDisplayVendor());

+            }

         }

 

         return false;

diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-addon-4.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-4.xsd
similarity index 96%
rename from sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-addon-4.xsd
rename to sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-4.xsd
index ef92bde..564aaeb 100755
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-addon-4.xsd
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-4.xsd
@@ -41,9 +41,18 @@
             - <addon> element now has an optional <layoutlib> that indicates the API
               and revision of the layout library for this particular add-on, if any.
 
-         - v3 is used by the SDK Updater in Tools R14:
+         - v3 is used by the SDK Manager in Tools r14:
             - <extra> now has an <old-paths> element, a ;-separated list of old paths that
               should be detected and migrated to the new <path> for that package.
+
+         - v4 is used by the SDK Manager in Tools r18:
+            - <extra> and <addon> are not in the Repository XSD v6 anymore.
+            - <extra> get a new field <name-display>, which is used by the SDK Manager to
+              customize the name of the extra in the list display. The single <vendor>
+              field becomes <vendor-id> and <vendor-display>, the id being used internally
+              and the display in the UI.
+            - <addon> does the same, where <name> is replaced by <name-id> and <name-display>
+              and <vendor> is replaced by <vendor-id> and <vendor-display>.
     -->
 
     <xsd:element name="sdk-addon" type="sdk:repositoryType" />
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-repository-6.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-6.xsd
similarity index 98%
rename from sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-repository-6.xsd
rename to sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-6.xsd
index d4cc1cb..002a75b 100755
--- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/-sdk-repository-6.xsd
+++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-6.xsd
@@ -55,7 +55,7 @@
             - <platform> element now has a mandatory <layoutlib> that indicates the API
               and revision of that layout library for this particular platform.
 
-         - v5 is used by the SDK Updater in Tools R14:
+         - v5 is used by the SDK Manager in Tools r14:
             - <extra> now has an <old-paths> element, a ;-separated list of old paths that
               should be detected and migrated to the new <path> for that package.
             - <platform> has a new optional <abi-included> that describes the ABI of the
@@ -63,7 +63,11 @@
             - New <system-image> package type, to store system images outside of <platform>s.
             - New <source> package type.
 
-         - v6 removed 'extra' packages. They are served only by the addon XML.
+         - v6 is used by the SDK Manager in Tools r18:
+            - <extra> packages are removed. They are served only by the addon XML.
+            - <platform>, <system-image>, <source>, <tool>, <platform-tool>, <doc>
+              and <sample> get a new optional field <beta-rc> which can be used to indicate
+              the package is a Beta Release Candidate and not a final release. 
     -->
 
     <xsd:element name="sdk-repository" type="sdk:repositoryType" />
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackagesDiffLogic.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackagesDiffLogic.java
index 944dffb..3d7cdb0 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackagesDiffLogic.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackagesDiffLogic.java
@@ -16,6 +16,7 @@
 
 package com.android.sdkuilib.internal.repository.sdkman2;
 
+import com.android.sdklib.AndroidVersion;
 import com.android.sdklib.IAndroidTarget;
 import com.android.sdklib.SdkConstants;
 import com.android.sdklib.internal.repository.ExtraPackage;
@@ -609,7 +610,7 @@
             // Sort by API
 
             if (pkg instanceof IPackageVersion) {
-                return ((IPackageVersion) pkg).getVersion().getApiLevel();
+                return ((IPackageVersion) pkg).getVersion();
 
             } else if (pkg instanceof ToolPackage || pkg instanceof PlatformToolPackage) {
                 return PkgCategoryApi.KEY_TOOLS;
@@ -663,8 +664,11 @@
             // Create API category.
             PkgCategory cat = null;
 
-            assert catKey instanceof Integer;
-            int apiKey = ((Integer) catKey).intValue();
+            assert catKey instanceof AndroidVersion;
+            AndroidVersion key = (AndroidVersion) catKey;
+
+            // We should not be trying to recreate the tools or extra categories.
+            assert !key.equals(PkgCategoryApi.KEY_TOOLS) && !key.equals(PkgCategoryApi.KEY_EXTRA);
 
             // We need a label for the category.
             // If we have an API level, try to get the info from the SDK Manager.
@@ -672,19 +676,16 @@
             // locally in the SDK Manager), it's OK we'll try to find the first platform
             // package available.
             String platformName = null;
-            if (apiKey >= 1 && apiKey != PkgCategoryApi.KEY_TOOLS) {
-                for (IAndroidTarget target :
-                        mUpdaterData.getSdkManager().getTargets()) {
-                    if (target.isPlatform() &&
-                            target.getVersion().getApiLevel() == apiKey) {
-                        platformName = target.getVersionName();
-                        break;
-                    }
+            for (IAndroidTarget target :
+                    mUpdaterData.getSdkManager().getTargets()) {
+                if (target.isPlatform() && key.equals(target.getVersion())) {
+                    platformName = target.getVersionName();
+                    break;
                 }
             }
 
             cat = new PkgCategoryApi(
-                    apiKey,
+                    key,
                     platformName,
                     mUpdaterData.getImageFactory().getImageByName(PackagesPage.ICON_CAT_PLATFORM));
 
@@ -710,9 +711,11 @@
                     public int compare(PkgCategory cat1, PkgCategory cat2) {
                         assert cat1 instanceof PkgCategoryApi;
                         assert cat2 instanceof PkgCategoryApi;
-                        int api1 = ((Integer) cat1.getKey()).intValue();
-                        int api2 = ((Integer) cat2.getKey()).intValue();
-                        return api2 - api1;
+                        assert cat1.getKey() instanceof AndroidVersion;
+                        assert cat2.getKey() instanceof AndroidVersion;
+                        AndroidVersion v1 = (AndroidVersion) cat1.getKey();
+                        AndroidVersion v2 = (AndroidVersion) cat2.getKey();
+                        return v2.compareTo(v1);
                     }
                 });
             }
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackagesPage.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackagesPage.java
index d3dc7b6..d6eb73e 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackagesPage.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PackagesPage.java
@@ -1560,44 +1560,57 @@
 
         @Override
         public String getToolTipText(Object element) {
-            if (element instanceof PkgItem) {
-                element = ((PkgItem) element).getMainPackage();
+            PkgItem pi = element instanceof PkgItem ? (PkgItem) element : null;
+            if (pi != null) {
+                element = pi.getMainPackage();
             }
             if (element instanceof IDescription) {
-                String s = ((IDescription) element).getLongDescription();
-                if (element instanceof Package) {
-                    Package p = (Package) element;
+                String s = getTooltipDescription((IDescription) element);
 
-                    if (!p.isLocal()) {
-                        // For non-installed item, try to find a download size
-                        for (Archive a : p.getArchives()) {
-                            if (!a.isLocal() && a.isCompatible()) {
-                                s += '\n' + a.getSizeDescription();
-                                break;
-                            }
-                        }
-                    }
-
-                    // Display info about where this package comes/came from
-                    SdkSource src = p.getParentSource();
-                    if (src != null) {
-                        try {
-                            URL url = new URL(src.getUrl());
-                            String host = url.getHost();
-                            if (p.isLocal()) {
-                                s += String.format("\nInstalled from %1$s", host);
-                            } else {
-                                s += String.format("\nProvided by %1$s", host);
-                            }
-                        } catch (MalformedURLException ignore) {
-                        }
-                    }
+                if (pi != null && pi.hasUpdatePkg()) {
+                    s += "\n-----------------" +        //$NON-NLS-1$
+                         "\nUpdate Available:\n" +      //$NON-NLS-1$
+                         getTooltipDescription(pi.getUpdatePkg());
                 }
+
                 return s;
             }
             return super.getToolTipText(element);
         }
 
+        private String getTooltipDescription(IDescription element) {
+            String s = element.getLongDescription();
+            if (element instanceof Package) {
+                Package p = (Package) element;
+
+                if (!p.isLocal()) {
+                    // For non-installed item, try to find a download size
+                    for (Archive a : p.getArchives()) {
+                        if (!a.isLocal() && a.isCompatible()) {
+                            s += '\n' + a.getSizeDescription();
+                            break;
+                        }
+                    }
+                }
+
+                // Display info about where this package comes/came from
+                SdkSource src = p.getParentSource();
+                if (src != null) {
+                    try {
+                        URL url = new URL(src.getUrl());
+                        String host = url.getHost();
+                        if (p.isLocal()) {
+                            s += String.format("\nInstalled from %1$s", host);
+                        } else {
+                            s += String.format("\nProvided by %1$s", host);
+                        }
+                    } catch (MalformedURLException ignore) {
+                    }
+                }
+            }
+            return s;
+        }
+
         @Override
         public Point getToolTipShift(Object object) {
             return new Point(15, 5);
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PkgCategoryApi.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PkgCategoryApi.java
index 570883c..5bb4917 100755
--- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PkgCategoryApi.java
+++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/sdkman2/PkgCategoryApi.java
@@ -16,6 +16,8 @@
 
 package com.android.sdkuilib.internal.repository.sdkman2;
 
+import com.android.sdklib.AndroidVersion;
+
 
 class PkgCategoryApi extends PkgCategory {
 
@@ -23,15 +25,17 @@
     private String mPlatformName;
 
     // When sorting by Source, key is the hash of the source's name.
-    // When storing by API, key is the API level (>=1). Tools and extra have the
-    // special values so they get naturally sorted the way we want them.
-    // (Note: don't use max to avoid integers wrapping in comparisons. We can
+    // When storing by API, key is the AndroidVersion (API level >=1 + optional codename).
+    // We always want categories in order tools..platforms..extras; to achieve that tools
+    // and extras have the special values so they get "naturally" sorted the way we want
+    // them.
+    // (Note: don't use integer.max to avoid integers wrapping in comparisons. We can
     // revisit the day we get 2^30 platforms.)
-    public final static int KEY_TOOLS = Integer.MAX_VALUE / 2;
-    public final static int KEY_EXTRA = -1;
+    public final static AndroidVersion KEY_TOOLS = new AndroidVersion(Integer.MAX_VALUE / 2, null);;
+    public final static AndroidVersion KEY_EXTRA = new AndroidVersion(-1, null);
 
-    public PkgCategoryApi(int apiKey, String platformName, Object iconRef) {
-        super(apiKey, null /*label*/, iconRef);
+    public PkgCategoryApi(AndroidVersion version, String platformName, Object iconRef) {
+        super(version, null /*label*/, iconRef);
         setPlatformName(platformName);
     }
 
@@ -48,13 +52,13 @@
     }
 
     public String getApiLabel() {
-        int api = ((Integer) getKey()).intValue();
-        if (api == KEY_TOOLS) {
+        AndroidVersion key = (AndroidVersion) getKey();
+        if (key.equals(KEY_TOOLS)) {
             return "TOOLS";             //$NON-NLS-1$ // for internal debug use only
-        } else if (api == KEY_EXTRA) {
+        } else if (key.equals(KEY_EXTRA)) {
             return "EXTRAS";            //$NON-NLS-1$ // for internal debug use only
         } else {
-            return String.format("API %1$d", getKey());
+            return key.toString();
         }
     }
 
@@ -62,11 +66,11 @@
     public String getLabel() {
         String label = super.getLabel();
         if (label == null) {
-            int key = ((Integer) getKey()).intValue();
+            AndroidVersion key = (AndroidVersion) getKey();
 
-            if (key == KEY_TOOLS) {
+            if (key.equals(KEY_TOOLS)) {
                 label = "Tools";
-            } else if (key == KEY_EXTRA) {
+            } else if (key.equals(KEY_EXTRA)) {
                 label = "Extras";
             } else {
                 if (mPlatformName != null) {
diff --git a/testapps/gridlayoutTest/app/.classpath b/testapps/gridlayoutTest/app/.classpath
new file mode 100644
index 0000000..a4763d1
--- /dev/null
+++ b/testapps/gridlayoutTest/app/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="gen"/>
+	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+	<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+	<classpathentry kind="output" path="bin/classes"/>
+</classpath>
diff --git a/testapps/gridlayoutTest/app/.project b/testapps/gridlayoutTest/app/.project
new file mode 100644
index 0000000..9a73e09
--- /dev/null
+++ b/testapps/gridlayoutTest/app/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>gridlayouttest-app</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/testapps/gridlayoutTest/app/AndroidManifest.xml b/testapps/gridlayoutTest/app/AndroidManifest.xml
new file mode 100644
index 0000000..9c95ca2
--- /dev/null
+++ b/testapps/gridlayoutTest/app/AndroidManifest.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="com.android.test.gridlayout"
+      android:versionCode="1"
+      android:versionName="1.0">
+    <application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
+        <activity android:name="Main"
+                  android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/testapps/gridlayoutTest/app/ant.properties b/testapps/gridlayoutTest/app/ant.properties
new file mode 100644
index 0000000..b0971e8
--- /dev/null
+++ b/testapps/gridlayoutTest/app/ant.properties
@@ -0,0 +1,17 @@
+# This file is used to override default values used by the Ant build system.
+#
+# This file must be checked into Version Control Systems, as it is
+# integral to the build system of your project.
+
+# This file is only used by the Ant script.
+
+# You can use this to override default values such as
+#  'source.dir' for the location of your java source folder and
+#  'out.dir' for the location of your output folder.
+
+# You can also use it define how the release builds are signed by declaring
+# the following properties:
+#  'key.store' for the location of your keystore and
+#  'key.alias' for the name of the key to use.
+# The password will be asked during the build when you use the 'release' target.
+
diff --git a/testapps/gridlayoutTest/app/build.xml b/testapps/gridlayoutTest/app/build.xml
new file mode 100644
index 0000000..1160e8a
--- /dev/null
+++ b/testapps/gridlayoutTest/app/build.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="app" default="help">
+
+    <!-- The local.properties file is created and updated by the 'android' tool.
+         It contains the path to the SDK. It should *NOT* be checked into
+         Version Control Systems. -->
+    <property file="local.properties" />
+
+    <!-- The ant.properties file can be created by you. It is only edited by the
+         'android' tool to add properties to it.
+         This is the place to change some Ant specific build properties.
+         Here are some properties you may want to change/update:
+
+         source.dir
+             The name of the source directory. Default is 'src'.
+         out.dir
+             The name of the output directory. Default is 'bin'.
+
+         For other overridable properties, look at the beginning of the rules
+         files in the SDK, at tools/ant/build.xml
+
+         Properties related to the SDK location or the project target should
+         be updated using the 'android' tool with the 'update' action.
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems.
+
+         -->
+    <property file="ant.properties" />
+
+    <!-- The project.properties file is created and updated by the 'android'
+         tool, as well as ADT.
+
+         This contains project specific properties such as project target, and library
+         dependencies. Lower level build properties are stored in ant.properties
+         (or in .classpath for Eclipse projects).
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems. -->
+    <loadproperties srcFile="project.properties" />
+
+    <!-- quick check on sdk.dir -->
+    <fail
+            message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through an env var"
+            unless="sdk.dir"
+    />
+
+    <!--
+        Import per project custom build rules if present at the root of the project.
+        This is the place to put custom intermediary targets such as:
+            -pre-build
+            -pre-compile
+            -post-compile (This is typically used for code obfuscation.
+                           Compiled code location: ${out.classes.absolute.dir}
+                           If this is not done in place, override ${out.dex.input.absolute.dir})
+            -post-package
+            -post-build
+            -pre-clean
+    -->
+    <import file="custom_rules.xml" optional="true" />
+
+    <!-- Import the actual build file.
+
+         To customize existing targets, there are two options:
+         - Customize only one target:
+             - copy/paste the target into this file, *before* the
+               <import> task.
+             - customize it to your needs.
+         - Customize the whole content of build.xml
+             - copy/paste the content of the rules files (minus the top node)
+               into this file, replacing the <import> task.
+             - customize to your needs.
+
+         ***********************
+         ****** IMPORTANT ******
+         ***********************
+         In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+         in order to avoid having your file be overridden by tools such as "android update project"
+    -->
+    <!-- version-tag: 1 -->
+    <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>
diff --git a/testapps/gridlayoutTest/app/proguard-project.txt b/testapps/gridlayoutTest/app/proguard-project.txt
new file mode 100644
index 0000000..f2fe155
--- /dev/null
+++ b/testapps/gridlayoutTest/app/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/testapps/gridlayoutTest/app/project.properties b/testapps/gridlayoutTest/app/project.properties
new file mode 100644
index 0000000..5fe06bd
--- /dev/null
+++ b/testapps/gridlayoutTest/app/project.properties
@@ -0,0 +1,15 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-15
+android.library.reference.1=../v7-gridlayout
diff --git a/testapps/gridlayoutTest/app/res/drawable-hdpi/ic_launcher.png b/testapps/gridlayoutTest/app/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..8074c4c
--- /dev/null
+++ b/testapps/gridlayoutTest/app/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/testapps/gridlayoutTest/app/res/drawable-ldpi/ic_launcher.png b/testapps/gridlayoutTest/app/res/drawable-ldpi/ic_launcher.png
new file mode 100644
index 0000000..1095584
--- /dev/null
+++ b/testapps/gridlayoutTest/app/res/drawable-ldpi/ic_launcher.png
Binary files differ
diff --git a/testapps/gridlayoutTest/app/res/drawable-mdpi/ic_launcher.png b/testapps/gridlayoutTest/app/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..a07c69f
--- /dev/null
+++ b/testapps/gridlayoutTest/app/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/testapps/gridlayoutTest/app/res/layout/main.xml b/testapps/gridlayoutTest/app/res/layout/main.xml
new file mode 100644
index 0000000..75f5600
--- /dev/null
+++ b/testapps/gridlayoutTest/app/res/layout/main.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.v7.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    app:columnCount="6" >
+
+    <Button
+        android:id="@+id/button1"
+        app:layout_column="1"
+        app:layout_columnSpan="2"
+        app:layout_gravity="left"
+        app:layout_row="1"
+        android:text="Button" />
+
+    <CheckBox
+        android:id="@+id/checkBox1"
+        app:layout_column="4"
+        app:layout_gravity="left"
+        app:layout_row="2"
+        android:text="CheckBox" />
+
+    <Button
+        android:id="@+id/button2"
+        app:layout_column="5"
+        app:layout_gravity="left"
+        app:layout_row="3"
+        android:text="Button" />
+
+    <android.support.v7.widget.Space
+        android:layout_width="21dp"
+        android:layout_height="1dp"
+        app:layout_column="0"
+        app:layout_gravity="fill_horizontal"
+        app:layout_row="0" />
+
+    <android.support.v7.widget.Space
+        android:layout_width="1dp"
+        android:layout_height="21dp"
+        app:layout_column="0"
+        app:layout_gravity="fill_horizontal"
+        app:layout_row="0" />
+
+    <android.support.v7.widget.Space
+        android:layout_width="10dp"
+        android:layout_height="1dp"
+        app:layout_column="3"
+        app:layout_gravity="fill_horizontal"
+        app:layout_row="0" />
+
+    <android.support.v7.widget.Space
+        android:layout_width="122dp"
+        android:layout_height="1dp"
+        app:layout_column="4"
+        app:layout_gravity="fill_horizontal"
+        app:layout_row="0" />
+
+    <android.support.v7.widget.Space
+        android:layout_width="1dp"
+        android:layout_height="168dp"
+        app:layout_column="0"
+        app:layout_gravity="fill_horizontal"
+        app:layout_row="1" />
+
+    <android.support.v7.widget.Space
+        android:layout_width="1dp"
+        android:layout_height="168dp"
+        app:layout_column="0"
+        app:layout_gravity="fill_horizontal"
+        app:layout_row="2" />
+
+</android.support.v7.widget.GridLayout>
\ No newline at end of file
diff --git a/testapps/gridlayoutTest/app/res/values/strings.xml b/testapps/gridlayoutTest/app/res/values/strings.xml
new file mode 100644
index 0000000..549e4ea
--- /dev/null
+++ b/testapps/gridlayoutTest/app/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">Main</string>
+</resources>
diff --git a/testapps/gridlayoutTest/app/src/com/android/test/gridlayout/Main.java b/testapps/gridlayoutTest/app/src/com/android/test/gridlayout/Main.java
new file mode 100644
index 0000000..bf817df
--- /dev/null
+++ b/testapps/gridlayoutTest/app/src/com/android/test/gridlayout/Main.java
@@ -0,0 +1,15 @@
+package com.android.test.gridlayout;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class Main extends Activity
+{
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+    }
+}
diff --git a/testapps/gridlayoutTest/v7-gridlayout/.classpath b/testapps/gridlayoutTest/v7-gridlayout/.classpath
new file mode 100644
index 0000000..a4763d1
--- /dev/null
+++ b/testapps/gridlayoutTest/v7-gridlayout/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="gen"/>
+	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+	<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+	<classpathentry kind="output" path="bin/classes"/>
+</classpath>
diff --git a/testapps/gridlayoutTest/v7-gridlayout/.project b/testapps/gridlayoutTest/v7-gridlayout/.project
new file mode 100644
index 0000000..1e67516
--- /dev/null
+++ b/testapps/gridlayoutTest/v7-gridlayout/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>android-support-v7-gridlayout</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/testapps/gridlayoutTest/v7-gridlayout/AndroidManifest.xml b/testapps/gridlayoutTest/v7-gridlayout/AndroidManifest.xml
new file mode 100644
index 0000000..c3f7168
--- /dev/null
+++ b/testapps/gridlayoutTest/v7-gridlayout/AndroidManifest.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.support.v7.gridlayout"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk android:minSdkVersion="7" />
+
+</manifest>
diff --git a/testapps/gridlayoutTest/v7-gridlayout/build.xml b/testapps/gridlayoutTest/v7-gridlayout/build.xml
new file mode 100644
index 0000000..a03e2b6
--- /dev/null
+++ b/testapps/gridlayoutTest/v7-gridlayout/build.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="v7-gridlayout" default="help">
+
+    <!-- The local.properties file is created and updated by the 'android' tool.
+         It contains the path to the SDK. It should *NOT* be checked into
+         Version Control Systems. -->
+    <property file="local.properties" />
+
+    <!-- The ant.properties file can be created by you. It is only edited by the
+         'android' tool to add properties to it.
+         This is the place to change some Ant specific build properties.
+         Here are some properties you may want to change/update:
+
+         source.dir
+             The name of the source directory. Default is 'src'.
+         out.dir
+             The name of the output directory. Default is 'bin'.
+
+         For other overridable properties, look at the beginning of the rules
+         files in the SDK, at tools/ant/build.xml
+
+         Properties related to the SDK location or the project target should
+         be updated using the 'android' tool with the 'update' action.
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems.
+
+         -->
+    <property file="ant.properties" />
+
+    <!-- The project.properties file is created and updated by the 'android'
+         tool, as well as ADT.
+
+         This contains project specific properties such as project target, and library
+         dependencies. Lower level build properties are stored in ant.properties
+         (or in .classpath for Eclipse projects).
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems. -->
+    <loadproperties srcFile="project.properties" />
+
+    <!-- quick check on sdk.dir -->
+    <fail
+            message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through an env var"
+            unless="sdk.dir"
+    />
+
+    <!--
+        Import per project custom build rules if present at the root of the project.
+        This is the place to put custom intermediary targets such as:
+            -pre-build
+            -pre-compile
+            -post-compile (This is typically used for code obfuscation.
+                           Compiled code location: ${out.classes.absolute.dir}
+                           If this is not done in place, override ${out.dex.input.absolute.dir})
+            -post-package
+            -post-build
+            -pre-clean
+    -->
+    <import file="custom_rules.xml" optional="true" />
+
+    <!-- Import the actual build file.
+
+         To customize existing targets, there are two options:
+         - Customize only one target:
+             - copy/paste the target into this file, *before* the
+               <import> task.
+             - customize it to your needs.
+         - Customize the whole content of build.xml
+             - copy/paste the content of the rules files (minus the top node)
+               into this file, replacing the <import> task.
+             - customize to your needs.
+
+         ***********************
+         ****** IMPORTANT ******
+         ***********************
+         In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+         in order to avoid having your file be overridden by tools such as "android update project"
+    -->
+    <!-- version-tag: 1 -->
+    <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>
diff --git a/testapps/gridlayoutTest/v7-gridlayout/libs/android-support-v7-gridlayout.jar b/testapps/gridlayoutTest/v7-gridlayout/libs/android-support-v7-gridlayout.jar
new file mode 100644
index 0000000..00a946d
--- /dev/null
+++ b/testapps/gridlayoutTest/v7-gridlayout/libs/android-support-v7-gridlayout.jar
Binary files differ
diff --git a/testapps/gridlayoutTest/v7-gridlayout/proguard-project.txt b/testapps/gridlayoutTest/v7-gridlayout/proguard-project.txt
new file mode 100644
index 0000000..f2fe155
--- /dev/null
+++ b/testapps/gridlayoutTest/v7-gridlayout/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/testapps/gridlayoutTest/v7-gridlayout/project.properties b/testapps/gridlayoutTest/v7-gridlayout/project.properties
new file mode 100644
index 0000000..36f1594
--- /dev/null
+++ b/testapps/gridlayoutTest/v7-gridlayout/project.properties
@@ -0,0 +1,15 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-15
+android.library=true
diff --git a/testapps/gridlayoutTest/v7-gridlayout/res/values/attrs.xml b/testapps/gridlayoutTest/v7-gridlayout/res/values/attrs.xml
new file mode 100644
index 0000000..ad2ef4e
--- /dev/null
+++ b/testapps/gridlayoutTest/v7-gridlayout/res/values/attrs.xml
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <declare-styleable name="GridLayout">
+
+        <!--
+              support versions. All attributes not present in ViewGroup/View are
+              redefined in the support library namespace.
+        -->
+
+
+        <!--
+        The orientation property is not used during layout. It is only used to
+        allocate row and column parameters when they are not specified by its children's
+        layout parameters. GridLayout works like LinearLayout in this case;
+        putting all the components either in a single row or in a single column -
+        depending on the value of this flag. In the horizontal case, a columnCount
+        property may be additionally supplied to force new rows to be created when a
+        row is full. The rowCount attribute may be used similarly in the vertical case.
+        The default is horizontal.
+        -->
+        <attr name="orientation">
+
+            <!-- Defines an horizontal widget. -->
+            <enum name="horizontal" value="0" />
+            <!-- Defines a vertical widget. -->
+            <enum name="vertical" value="1" />
+        </attr>
+        <!-- The maximum number of rows to create when automatically positioning children. -->
+        <attr name="rowCount" format="integer" />
+        <!-- The maximum number of columns to create when automatically positioning children. -->
+        <attr name="columnCount" format="integer" />
+        <!--
+        When set to true, tells GridLayout to use default margins when none are specified
+        in a view's layout parameters.
+        The default value is false.
+        See {@link android.widget.GridLayout#setUseDefaultMargins(boolean)}.
+        -->
+        <attr name="useDefaultMargins" format="boolean" />
+        <!--
+        When set to alignMargins, causes alignment to take place between the outer
+        boundary of a view, as defined by its margins. When set to alignBounds,
+        causes alignment to take place between the edges of the view.
+        The default is alignMargins.
+        See {@link android.widget.GridLayout#setAlignmentMode(int)}.
+        -->
+        <attr name="alignmentMode">
+
+            <!--
+            Align the bounds of the children.
+            See {@link android.widget.GridLayout#ALIGN_BOUNDS}.
+            -->
+            <enum name="alignBounds" value="0" />
+            <!--
+            Align the margins of the children.
+            See {@link android.widget.GridLayout#ALIGN_MARGINS}.
+            -->
+            <enum name="alignMargins" value="1" />
+        </attr>
+        <!--
+        When set to true, forces row boundaries to appear in the same order
+        as row indices.
+        The default is true.
+        See {@link android.widget.GridLayout#setRowOrderPreserved(boolean)}.
+        -->
+        <attr name="rowOrderPreserved" format="boolean" />
+        <!--
+        When set to true, forces column boundaries to appear in the same order
+        as column indices.
+        The default is true.
+        See {@link android.widget.GridLayout#setColumnOrderPreserved(boolean)}.
+        -->
+        <attr name="columnOrderPreserved" format="boolean" />
+    </declare-styleable>
+    <declare-styleable name="GridLayout_Layout">
+
+        <!--
+              support versions. All attributes not present in MarginLayout are
+              redefined in the support library name space.
+        -->
+
+
+        <!-- START MarginLayout layoutparams -->
+
+        <attr name="android:layout_width" />
+        <attr name="android:layout_height" />
+        <!--
+              Specifies extra space on the left, top, right and bottom
+              sides of this view. This space is outside this view's bounds.
+        -->
+        <attr name="android:layout_margin" />
+        <!--
+              Specifies extra space on the left side of this view.
+              This space is outside this view's bounds.
+        -->
+        <attr name="android:layout_marginLeft" />
+        <!--
+              Specifies extra space on the top side of this view.
+              This space is outside this view's bounds.
+        -->
+        <attr name="android:layout_marginTop" />
+        <!--
+              Specifies extra space on the right side of this view.
+              This space is outside this view's bounds.
+        -->
+        <attr name="android:layout_marginRight" />
+        <!--
+              Specifies extra space on the bottom side of this view.
+              This space is outside this view's bounds.
+        -->
+        <attr name="android:layout_marginBottom" />
+        <!--
+              Specifies extra space on the start side of this view.
+              This space is outside this view's bounds.
+        -->
+        <attr name="android:layout_marginStart" />
+        <!--
+              Specifies extra space on the end side of this view.
+              This space is outside this view's bounds.
+        -->
+        <attr name="android:layout_marginEnd" />
+
+        <!-- END MarginLayout layoutparams -->
+
+
+        <!--
+        The row boundary delimiting the top of the group of cells
+        occupied by this view.
+        -->
+        <attr name="layout_row" format="integer" />
+        <!--
+        The row span: the difference between the bottom and top
+        boundaries delimiting the group of cells occupied by this view.
+        The default is one.
+        See {@link android.widget.GridLayout.Spec}.
+        -->
+        <attr name="layout_rowSpan" format="integer" min="1" />
+        <!--
+        The column boundary delimiting the left of the group of cells
+        occupied by this view.
+        -->
+        <attr name="layout_column" format="integer" />
+        <!--
+        The column span: the difference between the right and left
+        boundaries delimiting the group of cells occupied by this view.
+        The default is one.
+        See {@link android.widget.GridLayout.Spec}.
+        -->
+        <attr name="layout_columnSpan" format="integer" min="1" />
+        <!--
+        Gravity specifies how a component should be placed in its group of cells.
+        The default is LEFT | BASELINE.
+        See {@link android.widget.GridLayout.LayoutParams#setGravity(int)}.
+        -->
+        <attr name="layout_gravity">
+
+            <!-- Push object to the top of its container, not changing its size. -->
+            <flag name="top" value="0x30" />
+            <!-- Push object to the bottom of its container, not changing its size. -->
+            <flag name="bottom" value="0x50" />
+            <!-- Push object to the left of its container, not changing its size. -->
+            <flag name="left" value="0x03" />
+            <!-- Push object to the right of its container, not changing its size. -->
+            <flag name="right" value="0x05" />
+            <!-- Place object in the vertical center of its container, not changing its size. -->
+            <flag name="center_vertical" value="0x10" />
+            <!-- Grow the vertical size of the object if needed so it completely fills its container. -->
+            <flag name="fill_vertical" value="0x70" />
+            <!-- Place object in the horizontal center of its container, not changing its size. -->
+            <flag name="center_horizontal" value="0x01" />
+            <!-- Grow the horizontal size of the object if needed so it completely fills its container. -->
+            <flag name="fill_horizontal" value="0x07" />
+            <!-- Place the object in the center of its container in both the vertical and horizontal axis, not changing its size. -->
+            <flag name="center" value="0x11" />
+            <!-- Grow the horizontal and vertical size of the object if needed so it completely fills its container. -->
+            <flag name="fill" value="0x77" />
+            <!--
+             Additional option that can be set to have the top and/or bottom edges of
+             the child clipped to its container's bounds.
+             The clip will be based on the vertical gravity: a top gravity will clip the bottom
+             edge, a bottom gravity will clip the top edge, and neither will clip both edges.
+            -->
+            <flag name="clip_vertical" value="0x80" />
+            <!--
+             Additional option that can be set to have the left and/or right edges of
+             the child clipped to its container's bounds.
+             The clip will be based on the horizontal gravity: a left gravity will clip the right
+             edge, a right gravity will clip the left edge, and neither will clip both edges.
+            -->
+            <flag name="clip_horizontal" value="0x08" />
+            <!-- Push object to the beginning of its container, not changing its size. -->
+            <flag name="start" value="0x00800003" />
+            <!-- Push object to the end of its container, not changing its size. -->
+            <flag name="end" value="0x00800005" />
+        </attr>
+    </declare-styleable>
+
+</resources>
diff --git a/testapps/gridlayoutTest/v7-gridlayout/res/values/dimens.xml b/testapps/gridlayoutTest/v7-gridlayout/res/values/dimens.xml
new file mode 100644
index 0000000..fda3feb
--- /dev/null
+++ b/testapps/gridlayoutTest/v7-gridlayout/res/values/dimens.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <!-- The default gap between components in a layout. -->
+    <dimen name="default_gap">16dip</dimen>
+
+</resources>
diff --git a/testapps/gridlayoutTest/v7-gridlayout/src/.readme b/testapps/gridlayoutTest/v7-gridlayout/src/.readme
new file mode 100644
index 0000000..4bcebad
--- /dev/null
+++ b/testapps/gridlayoutTest/v7-gridlayout/src/.readme
@@ -0,0 +1,2 @@
+This hidden file is there to ensure there is an src folder.
+Once we support binary library this will go away.
\ No newline at end of file