Automated import from //branches/master/...@142288,142288
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/DeclareStyleableInfo.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/DeclareStyleableInfo.java
index efa5981..7aad7c8 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/DeclareStyleableInfo.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/DeclareStyleableInfo.java
@@ -70,6 +70,18 @@
             mFormats = formats;
         }
 
+        /**
+         * @param name The XML Name of the attribute
+         * @param formats The formats of the attribute. Cannot be null.
+         *                Should have at least one format.
+         * @param javadoc Short javadoc (i.e. the first sentence).
+         */
+        public AttributeInfo(String name, Format[] formats, String javadoc) {
+            mName = name;
+            mFormats = formats;
+            mJavaDoc = javadoc;
+        }
+
         public AttributeInfo(AttributeInfo info) {
             mName = info.mName;
             mFormats = info.mFormats;
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ElementDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ElementDescriptor.java
index 5550155..6a9b7db 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ElementDescriptor.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ElementDescriptor.java
@@ -24,6 +24,7 @@
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.swt.graphics.Image;
 
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -221,6 +222,18 @@
         mChildren = newChildren;
     }
 
+    /** Sets the list of allowed children.
+     * <p/>
+     * This is just a convenience method that converts a Collection into an array and
+     * calls {@link #setChildren(ElementDescriptor[])}.
+     * <p/>
+     * This means a <em>copy</em> of the collection is made. The collection is not
+     * stored by the recipient and can thus be altered by the caller.
+     */
+    public void setChildren(Collection<ElementDescriptor> newChildren) {
+        setChildren(newChildren.toArray(new ElementDescriptor[newChildren.size()]));
+    }
+
     /**
      * Returns an optional tooltip. Will be null if not present.
      * <p/>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/descriptors/LayoutDescriptors.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/descriptors/LayoutDescriptors.java
index 5726d78..2c0f984 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/descriptors/LayoutDescriptors.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/descriptors/LayoutDescriptors.java
@@ -43,7 +43,7 @@
     public static final String ID_ATTR = "id"; //$NON-NLS-1$
 
     /** The document descriptor. Contains all layouts and views linked together. */
-    private DocumentDescriptor mDescriptor =
+    private DocumentDescriptor mRootDescriptor =
         new DocumentDescriptor("layout_doc", null); //$NON-NLS-1$
 
     /** The list of all known ViewLayout descriptors. */
@@ -60,7 +60,7 @@
     
     /** @return the document descriptor. Contains all layouts and views linked together. */
     public DocumentDescriptor getDescriptor() {
-        return mDescriptor;
+        return mRootDescriptor;
     }
     
     /** @return The read-only list of all known ViewLayout descriptors. */
@@ -74,7 +74,7 @@
     }
     
     public ElementDescriptor[] getRootElementDescriptors() {
-        return mDescriptor.getChildren();
+        return mRootDescriptor.getChildren();
     }
 
     /**
@@ -98,6 +98,10 @@
             }
         }
 
+        // Create <include> as a synthetic regular view.
+        // Note: ViewStub is already described by attrs.xml
+        insertInclude(newViews);
+
         ArrayList<ElementDescriptor> newLayouts = new ArrayList<ElementDescriptor>();
         if (layouts != null) {
             for (ViewClassInfo info : layouts) {
@@ -109,17 +113,22 @@
         ArrayList<ElementDescriptor> newDescriptors = new ArrayList<ElementDescriptor>();
         newDescriptors.addAll(newLayouts);
         newDescriptors.addAll(newViews);
-        ElementDescriptor[] newArray = newDescriptors.toArray(
-                new ElementDescriptor[newDescriptors.size()]);
 
         // Link all layouts to everything else here.. recursively
         for (ElementDescriptor layoutDesc : newLayouts) {
-            layoutDesc.setChildren(newArray);
+            layoutDesc.setChildren(newDescriptors);
         }
 
+        // The <merge> tag can only be a root tag, so it is added at the end.
+        // It gets everything else as children but it is not made a child itself.
+        ElementDescriptor mergeTag = createMerge();
+        mergeTag.setChildren(newDescriptors);  // mergeTag makes a copy of the list
+        newDescriptors.add(mergeTag);
+        newLayouts.add(mergeTag);
+
         mViewDescriptors = newViews;
         mLayoutDescriptors  = newLayouts;
-        mDescriptor.setChildren(newArray);
+        mRootDescriptor.setChildren(newDescriptors);
         
         mROLayoutDescriptors = Collections.unmodifiableList(mLayoutDescriptors);
         mROViewDescriptors = Collections.unmodifiableList(mViewDescriptors);
@@ -217,4 +226,91 @@
                 false /* mandatory */);
     }
 
+    /**
+     * Creates a new <include> descriptor and adds it to the list of view descriptors.
+     * 
+     * @param newViews A list of view descriptors being populated. Also used to find the
+     *   View description and extract its layout attributes.
+     */
+    private void insertInclude(ArrayList<ElementDescriptor> newViews) {
+        String xml_name = "include";  //$NON-NLS-1$
+
+        // Create the include custom attributes
+        ArrayList<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>();
+        
+        // Note that the "layout" attribute does NOT have the Android namespace
+        DescriptorsUtils.appendAttribute(attributes,
+                null, //elementXmlName
+                null, //nsUri
+                new AttributeInfo(
+                        "layout",       //$NON-NLS-1$
+                        new AttributeInfo.Format[] { AttributeInfo.Format.REFERENCE }
+                        ),
+                true,  //required
+                null); //overrides
+
+        DescriptorsUtils.appendAttribute(attributes,
+                null, //elementXmlName
+                SdkConstants.NS_RESOURCES, //nsUri
+                new AttributeInfo(
+                        "id",           //$NON-NLS-1$
+                        new AttributeInfo.Format[] { AttributeInfo.Format.REFERENCE }
+                        ),
+                true,  //required
+                null); //overrides
+
+        // Find View and inherit all its layout attributes
+        AttributeDescriptor[] viewLayoutAttribs = findViewLayoutAttributes(newViews);
+
+        // Create the include descriptor
+        ViewElementDescriptor desc = new ViewElementDescriptor(xml_name,  // xml_name
+                xml_name, // ui_name
+                null,     // canonical class name, we don't have one
+                "Lets you statically include XML layouts inside other XML layouts.",  // tooltip
+                null, // sdk_url
+                attributes.toArray(new AttributeDescriptor[attributes.size()]),
+                viewLayoutAttribs,  // layout attributes
+                null, // children
+                false /* mandatory */);
+        
+        newViews.add(desc);
+    }
+
+    /**
+     * Finds the View descriptor and retrieves all its layout attributes.
+     */
+    private AttributeDescriptor[] findViewLayoutAttributes(
+            ArrayList<ElementDescriptor> newViews) {
+
+        for (ElementDescriptor desc : newViews) {
+            if (desc instanceof ViewElementDescriptor) {
+                ViewElementDescriptor viewDesc = (ViewElementDescriptor) desc;
+                if (AndroidConstants.CLASS_VIEW.equals(viewDesc.getCanonicalClassName())) {
+                    return viewDesc.getLayoutAttributes();
+                }
+            }
+        }
+        
+        return null;
+    }
+
+    /**
+     * Creates and return a new <merge> descriptor.
+     */
+    private ElementDescriptor createMerge() {
+        String xml_name = "merge";  //$NON-NLS-1$
+
+        // Create the include descriptor
+        ViewElementDescriptor desc = new ViewElementDescriptor(xml_name,  // xml_name
+                xml_name, // ui_name
+                null,     // canonical class name, we don't have one
+                "A root tag useful for XML layouts inflated using a ViewStub.",  // tooltip
+                null,  // sdk_url
+                null,  // attributes
+                null,  // layout attributes
+                null,  // children
+                false  /* mandatory */);
+
+        return desc;
+    }
 }