diff --git a/nuxeo-platform-forms-layout-client/src/test/java/org/nuxeo/ecm/platform/layout/service/LayoutAutomaticGeneration.java b/nuxeo-platform-forms-layout-client/src/test/java/org/nuxeo/ecm/platform/layout/service/LayoutAutomaticGeneration.java
new file mode 100644
--- /dev/null
+++ b/nuxeo-platform-forms-layout-client/src/test/java/org/nuxeo/ecm/platform/layout/service/LayoutAutomaticGeneration.java
@@ -0,0 +1,152 @@
+/*
+ * (C) Copyright 2006-2009 Nuxeo SAS (http://nuxeo.com/) and contributors.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser General Public License
+ * (LGPL) version 2.1 which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Contributors:
+ *     Anahide Tchertchian
+ *
+ * $Id$
+ */
+
+package org.nuxeo.ecm.platform.layout.service;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentFactory;
+import org.dom4j.Element;
+import org.nuxeo.ecm.core.api.ClientException;
+import org.nuxeo.ecm.core.schema.SchemaManager;
+import org.nuxeo.ecm.core.schema.types.Field;
+import org.nuxeo.ecm.core.schema.types.Schema;
+import org.nuxeo.ecm.core.schema.types.Type;
+import org.nuxeo.ecm.core.schema.types.primitives.DateType;
+import org.nuxeo.ecm.core.schema.types.primitives.DoubleType;
+import org.nuxeo.ecm.core.schema.types.primitives.IntegerType;
+import org.nuxeo.ecm.core.schema.types.primitives.LongType;
+import org.nuxeo.ecm.core.schema.types.primitives.StringType;
+import org.nuxeo.ecm.platform.forms.layout.api.BuiltinModes;
+
+/**
+ * Helper to generate a layout xml output automatically from a schema
+ * definition.
+ *
+ * @author Anahide Tchertchian
+ *
+ */
+public class LayoutAutomaticGeneration {
+
+    public static Document generateLayoutOutput(SchemaManager sm,
+            String schemaName, boolean generateLabels) throws ClientException {
+        String layoutName = String.format("%s", schemaName);
+
+        Document document = DocumentFactory.getInstance().createDocument();
+        document.setName(layoutName);
+
+        Element component = document.addElement("component");
+        component.addAttribute("name", String.format(
+                "myproject.%s.generatedContrib", layoutName));
+
+        Element extension = component.addElement("extension");
+        extension.addAttribute("target",
+                "org.nuxeo.ecm.platform.forms.layout.WebLayoutManager");
+        extension.addAttribute("point", "layouts");
+
+        Element layout = extension.addElement("layout");
+        layout.addAttribute("name", layoutName);
+        Element rows = layout.addElement("rows");
+
+        Schema schema = sm.getSchema(schemaName);
+        String schemaPrefix = schema.getNamespace().prefix;
+
+        for (Field field : schema.getFields()) {
+            // add row element
+            Element row = rows.addElement("row");
+            Element rowWidget = row.addElement("widget");
+            String fieldName = field.getName().getLocalName();
+            rowWidget.setText(fieldName);
+
+            // add widget element
+            boolean widgetResolved = false;
+            if (field.getType().isSimpleType()) {
+                boolean needsInputStyleClass = false;
+                boolean needsDateFormat = false;
+                Type fieldType = field.getType();
+                String widgetType = null;
+                if (fieldType == StringType.INSTANCE) {
+                    widgetType = "text";
+                    needsInputStyleClass = true;
+                } else if (fieldType == LongType.INSTANCE
+                        || fieldType == IntegerType.INSTANCE
+                        || fieldType == DoubleType.INSTANCE) {
+                    widgetType = "int";
+                    needsInputStyleClass = true;
+                } else if (fieldType == DateType.INSTANCE) {
+                    widgetType = "datetime";
+                    needsDateFormat = true;
+                } else {
+                    break;
+                }
+
+                widgetResolved = true;
+
+                Element widget = layout.addElement("widget");
+                widget.addAttribute("name", fieldName);
+                widget.addAttribute("type", widgetType);
+
+                if (generateLabels) {
+                    Element labels = widget.addElement("labels");
+                    Element label = labels.addElement("label");
+                    label.addAttribute("mode", BuiltinModes.ANY);
+                    label.setText(String.format("label.widget.%s.%s",
+                            layoutName, fieldName));
+                }
+
+                Element fields = widget.addElement("fields");
+                Element fieldElement = fields.addElement("field");
+                if (schemaPrefix != null) {
+                    fieldElement.setText(field.getName().getPrefixedName());
+                } else {
+                    fieldElement.addAttribute("schema", schemaName);
+                    fieldElement.setText(fieldName);
+                }
+
+                if (needsDateFormat || needsInputStyleClass) {
+                    Element properties = widget.addElement("properties");
+                    if (needsDateFormat) {
+                        properties.addAttribute("mode", BuiltinModes.ANY);
+                        String defaultDatePattern = "#{nxu:basicDateFormater()}";
+                        Element patternProp = properties.addElement("property");
+                        patternProp.addAttribute("name", "pattern");
+                        patternProp.setText(defaultDatePattern);
+                        Element formatProp = properties.addElement("property");
+                        formatProp.addAttribute("name", "format");
+                        formatProp.setText(defaultDatePattern);
+                    }
+                    if (needsInputStyleClass) {
+                        properties.addAttribute("mode", BuiltinModes.EDIT);
+                        String defaultStyleClass = "dataInputText";
+                        Element styleClassProp = properties.addElement("property");
+                        styleClassProp.addAttribute("name", "styleClass");
+                        styleClassProp.setText(defaultStyleClass);
+                    }
+                }
+            }
+
+            if (!widgetResolved) {
+                // widget needs to be done by hand for now
+                layout.addComment(String.format("TODO: %s", fieldName));
+            }
+
+        }
+
+        return document;
+    }
+}
diff --git a/nuxeo-platform-forms-layout-client/src/test/java/org/nuxeo/ecm/platform/layout/service/TestHelpers.java b/nuxeo-platform-forms-layout-client/src/test/java/org/nuxeo/ecm/platform/layout/service/TestHelpers.java
--- a/nuxeo-platform-forms-layout-client/src/test/java/org/nuxeo/ecm/platform/layout/service/TestHelpers.java
+++ b/nuxeo-platform-forms-layout-client/src/test/java/org/nuxeo/ecm/platform/layout/service/TestHelpers.java
@@ -19,9 +19,23 @@
 
 package org.nuxeo.ecm.platform.layout.service;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.dom4j.Document;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.XMLWriter;
+import org.nuxeo.common.utils.FileUtils;
+import org.nuxeo.ecm.core.schema.SchemaManager;
 import org.nuxeo.ecm.platform.forms.layout.api.FieldDefinition;
 import org.nuxeo.ecm.platform.forms.layout.descriptors.FieldDescriptor;
 import org.nuxeo.ecm.platform.forms.layout.facelets.ValueExpressionHelper;
+import org.nuxeo.runtime.api.Framework;
 import org.nuxeo.runtime.test.NXRuntimeTestCase;
 
 /**
@@ -52,4 +66,65 @@ public class TestHelpers extends NXRunti
         assertEquals("#{document.dublincore.contributors[0].name}", expression);
     }
 
+    public static String getTestFile(String filePath)
+            throws UnsupportedEncodingException {
+        return FileUtils.getResourcePathFromContext(filePath);
+    }
+
+    protected byte[] getGeneratedInputStream(Document doc) throws Exception {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        OutputFormat format = OutputFormat.createPrettyPrint();
+        XMLWriter writer = null;
+        try {
+            writer = new XMLWriter(out, format);
+            writer.write(doc.getDocument());
+
+        } finally {
+            if (writer != null) {
+                writer.close();
+            }
+        }
+
+        byte[] res = out.toByteArray();
+
+        // for debug
+        File file = File.createTempFile("test", ".xml");
+        FileOutputStream fileOut = new FileOutputStream(file);
+        fileOut.write(res);
+
+        return res;
+    }
+
+    public void testLayoutAutomaticGeneration() throws Exception {
+        SchemaManager sm = Framework.getService(SchemaManager.class);
+        Document doc = LayoutAutomaticGeneration.generateLayoutOutput(sm,
+                "dublincore", false);
+
+        byte[] generated = getGeneratedInputStream(doc);
+
+        InputStream expected = new FileInputStream(
+                getTestFile("layouts-generated-contrib.xml"));
+
+        InputStream generatedStream = new ByteArrayInputStream(generated);
+
+        assertEquals(FileUtils.read(expected).replaceAll("\r?\n", ""),
+                FileUtils.read(generatedStream).replaceAll("\r?\n", ""));
+    }
+
+    public void testLayoutAutomaticGenerationWithLabel() throws Exception {
+        SchemaManager sm = Framework.getService(SchemaManager.class);
+        Document doc = LayoutAutomaticGeneration.generateLayoutOutput(sm,
+                "dublincore", true);
+
+        byte[] generated = getGeneratedInputStream(doc);
+
+        InputStream expected = new FileInputStream(
+                getTestFile("layouts-generated-with-labels-contrib.xml"));
+
+        InputStream generatedStream = new ByteArrayInputStream(generated);
+
+        assertEquals(FileUtils.read(expected).replaceAll("\r?\n", ""),
+                FileUtils.read(generatedStream).replaceAll("\r?\n", ""));
+    }
+
 }
diff --git a/nuxeo-platform-forms-layout-client/src/test/resources/layouts-generated-contrib.xml b/nuxeo-platform-forms-layout-client/src/test/resources/layouts-generated-contrib.xml
new file mode 100644
--- /dev/null
+++ b/nuxeo-platform-forms-layout-client/src/test/resources/layouts-generated-contrib.xml
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<component name="myproject.dublincore.generatedContrib">
+  <extension target="org.nuxeo.ecm.platform.forms.layout.WebLayoutManager" point="layouts">
+    <layout name="dublincore">
+      <rows>
+        <row>
+          <widget>valid</widget>
+        </row>
+        <row>
+          <widget>issued</widget>
+        </row>
+        <row>
+          <widget>coverage</widget>
+        </row>
+        <row>
+          <widget>title</widget>
+        </row>
+        <row>
+          <widget>modified</widget>
+        </row>
+        <row>
+          <widget>creator</widget>
+        </row>
+        <row>
+          <widget>subjects</widget>
+        </row>
+        <row>
+          <widget>rights</widget>
+        </row>
+        <row>
+          <widget>language</widget>
+        </row>
+        <row>
+          <widget>expired</widget>
+        </row>
+        <row>
+          <widget>contributors</widget>
+        </row>
+        <row>
+          <widget>created</widget>
+        </row>
+        <row>
+          <widget>source</widget>
+        </row>
+        <row>
+          <widget>description</widget>
+        </row>
+        <row>
+          <widget>format</widget>
+        </row>
+      </rows>
+      <widget name="valid" type="datetime">
+        <fields>
+          <field>dc:valid</field>
+        </fields>
+        <properties mode="any">
+          <property name="pattern">#{nxu:basicDateFormater()}</property>
+          <property name="format">#{nxu:basicDateFormater()}</property>
+        </properties>
+      </widget>
+      <widget name="issued" type="datetime">
+        <fields>
+          <field>dc:issued</field>
+        </fields>
+        <properties mode="any">
+          <property name="pattern">#{nxu:basicDateFormater()}</property>
+          <property name="format">#{nxu:basicDateFormater()}</property>
+        </properties>
+      </widget>
+      <widget name="coverage" type="text">
+        <fields>
+          <field>dc:coverage</field>
+        </fields>
+        <properties mode="edit">
+          <property name="styleClass">dataInputText</property>
+        </properties>
+      </widget>
+      <widget name="title" type="text">
+        <fields>
+          <field>dc:title</field>
+        </fields>
+        <properties mode="edit">
+          <property name="styleClass">dataInputText</property>
+        </properties>
+      </widget>
+      <widget name="modified" type="datetime">
+        <fields>
+          <field>dc:modified</field>
+        </fields>
+        <properties mode="any">
+          <property name="pattern">#{nxu:basicDateFormater()}</property>
+          <property name="format">#{nxu:basicDateFormater()}</property>
+        </properties>
+      </widget>
+      <widget name="creator" type="text">
+        <fields>
+          <field>dc:creator</field>
+        </fields>
+        <properties mode="edit">
+          <property name="styleClass">dataInputText</property>
+        </properties>
+      </widget>
+      <!--TODO: subjects-->
+      <widget name="rights" type="text">
+        <fields>
+          <field>dc:rights</field>
+        </fields>
+        <properties mode="edit">
+          <property name="styleClass">dataInputText</property>
+        </properties>
+      </widget>
+      <widget name="language" type="text">
+        <fields>
+          <field>dc:language</field>
+        </fields>
+        <properties mode="edit">
+          <property name="styleClass">dataInputText</property>
+        </properties>
+      </widget>
+      <widget name="expired" type="datetime">
+        <fields>
+          <field>dc:expired</field>
+        </fields>
+        <properties mode="any">
+          <property name="pattern">#{nxu:basicDateFormater()}</property>
+          <property name="format">#{nxu:basicDateFormater()}</property>
+        </properties>
+      </widget>
+      <!--TODO: contributors-->
+      <widget name="created" type="datetime">
+        <fields>
+          <field>dc:created</field>
+        </fields>
+        <properties mode="any">
+          <property name="pattern">#{nxu:basicDateFormater()}</property>
+          <property name="format">#{nxu:basicDateFormater()}</property>
+        </properties>
+      </widget>
+      <widget name="source" type="text">
+        <fields>
+          <field>dc:source</field>
+        </fields>
+        <properties mode="edit">
+          <property name="styleClass">dataInputText</property>
+        </properties>
+      </widget>
+      <widget name="description" type="text">
+        <fields>
+          <field>dc:description</field>
+        </fields>
+        <properties mode="edit">
+          <property name="styleClass">dataInputText</property>
+        </properties>
+      </widget>
+      <widget name="format" type="text">
+        <fields>
+          <field>dc:format</field>
+        </fields>
+        <properties mode="edit">
+          <property name="styleClass">dataInputText</property>
+        </properties>
+      </widget>
+    </layout>
+  </extension>
+</component>
diff --git a/nuxeo-platform-forms-layout-client/src/test/resources/layouts-generated-with-labels-contrib.xml b/nuxeo-platform-forms-layout-client/src/test/resources/layouts-generated-with-labels-contrib.xml
new file mode 100644
--- /dev/null
+++ b/nuxeo-platform-forms-layout-client/src/test/resources/layouts-generated-with-labels-contrib.xml
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<component name="myproject.dublincore.generatedContrib">
+  <extension target="org.nuxeo.ecm.platform.forms.layout.WebLayoutManager" point="layouts">
+    <layout name="dublincore">
+      <rows>
+        <row>
+          <widget>valid</widget>
+        </row>
+        <row>
+          <widget>issued</widget>
+        </row>
+        <row>
+          <widget>coverage</widget>
+        </row>
+        <row>
+          <widget>title</widget>
+        </row>
+        <row>
+          <widget>modified</widget>
+        </row>
+        <row>
+          <widget>creator</widget>
+        </row>
+        <row>
+          <widget>subjects</widget>
+        </row>
+        <row>
+          <widget>rights</widget>
+        </row>
+        <row>
+          <widget>language</widget>
+        </row>
+        <row>
+          <widget>expired</widget>
+        </row>
+        <row>
+          <widget>contributors</widget>
+        </row>
+        <row>
+          <widget>created</widget>
+        </row>
+        <row>
+          <widget>source</widget>
+        </row>
+        <row>
+          <widget>description</widget>
+        </row>
+        <row>
+          <widget>format</widget>
+        </row>
+      </rows>
+      <widget name="valid" type="datetime">
+        <labels>
+          <label mode="any">label.widget.dublincore.valid</label>
+        </labels>
+        <fields>
+          <field>dc:valid</field>
+        </fields>
+        <properties mode="any">
+          <property name="pattern">#{nxu:basicDateFormater()}</property>
+          <property name="format">#{nxu:basicDateFormater()}</property>
+        </properties>
+      </widget>
+      <widget name="issued" type="datetime">
+        <labels>
+          <label mode="any">label.widget.dublincore.issued</label>
+        </labels>
+        <fields>
+          <field>dc:issued</field>
+        </fields>
+        <properties mode="any">
+          <property name="pattern">#{nxu:basicDateFormater()}</property>
+          <property name="format">#{nxu:basicDateFormater()}</property>
+        </properties>
+      </widget>
+      <widget name="coverage" type="text">
+        <labels>
+          <label mode="any">label.widget.dublincore.coverage</label>
+        </labels>
+        <fields>
+          <field>dc:coverage</field>
+        </fields>
+        <properties mode="edit">
+          <property name="styleClass">dataInputText</property>
+        </properties>
+      </widget>
+      <widget name="title" type="text">
+        <labels>
+          <label mode="any">label.widget.dublincore.title</label>
+        </labels>
+        <fields>
+          <field>dc:title</field>
+        </fields>
+        <properties mode="edit">
+          <property name="styleClass">dataInputText</property>
+        </properties>
+      </widget>
+      <widget name="modified" type="datetime">
+        <labels>
+          <label mode="any">label.widget.dublincore.modified</label>
+        </labels>
+        <fields>
+          <field>dc:modified</field>
+        </fields>
+        <properties mode="any">
+          <property name="pattern">#{nxu:basicDateFormater()}</property>
+          <property name="format">#{nxu:basicDateFormater()}</property>
+        </properties>
+      </widget>
+      <widget name="creator" type="text">
+        <labels>
+          <label mode="any">label.widget.dublincore.creator</label>
+        </labels>
+        <fields>
+          <field>dc:creator</field>
+        </fields>
+        <properties mode="edit">
+          <property name="styleClass">dataInputText</property>
+        </properties>
+      </widget>
+      <!--TODO: subjects-->
+      <widget name="rights" type="text">
+        <labels>
+          <label mode="any">label.widget.dublincore.rights</label>
+        </labels>
+        <fields>
+          <field>dc:rights</field>
+        </fields>
+        <properties mode="edit">
+          <property name="styleClass">dataInputText</property>
+        </properties>
+      </widget>
+      <widget name="language" type="text">
+        <labels>
+          <label mode="any">label.widget.dublincore.language</label>
+        </labels>
+        <fields>
+          <field>dc:language</field>
+        </fields>
+        <properties mode="edit">
+          <property name="styleClass">dataInputText</property>
+        </properties>
+      </widget>
+      <widget name="expired" type="datetime">
+        <labels>
+          <label mode="any">label.widget.dublincore.expired</label>
+        </labels>
+        <fields>
+          <field>dc:expired</field>
+        </fields>
+        <properties mode="any">
+          <property name="pattern">#{nxu:basicDateFormater()}</property>
+          <property name="format">#{nxu:basicDateFormater()}</property>
+        </properties>
+      </widget>
+      <!--TODO: contributors-->
+      <widget name="created" type="datetime">
+        <labels>
+          <label mode="any">label.widget.dublincore.created</label>
+        </labels>
+        <fields>
+          <field>dc:created</field>
+        </fields>
+        <properties mode="any">
+          <property name="pattern">#{nxu:basicDateFormater()}</property>
+          <property name="format">#{nxu:basicDateFormater()}</property>
+        </properties>
+      </widget>
+      <widget name="source" type="text">
+        <labels>
+          <label mode="any">label.widget.dublincore.source</label>
+        </labels>
+        <fields>
+          <field>dc:source</field>
+        </fields>
+        <properties mode="edit">
+          <property name="styleClass">dataInputText</property>
+        </properties>
+      </widget>
+      <widget name="description" type="text">
+        <labels>
+          <label mode="any">label.widget.dublincore.description</label>
+        </labels>
+        <fields>
+          <field>dc:description</field>
+        </fields>
+        <properties mode="edit">
+          <property name="styleClass">dataInputText</property>
+        </properties>
+      </widget>
+      <widget name="format" type="text">
+        <labels>
+          <label mode="any">label.widget.dublincore.format</label>
+        </labels>
+        <fields>
+          <field>dc:format</field>
+        </fields>
+        <properties mode="edit">
+          <property name="styleClass">dataInputText</property>
+        </properties>
+      </widget>
+    </layout>
+  </extension>
+</component>
