Bugfix for Nested and Replaced FormFields
diff --git a/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/template/formfield/replace/levels/AbstractMainBox.java b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/template/formfield/replace/levels/AbstractMainBox.java
new file mode 100644
index 0000000..e1fdd79
--- /dev/null
+++ b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/template/formfield/replace/levels/AbstractMainBox.java
@@ -0,0 +1,16 @@
+package formdata.client.ui.template.formfield.replace.levels;
+
+import org.eclipse.scout.commons.annotations.FormData;
+import org.eclipse.scout.rt.client.ui.form.fields.groupbox.AbstractGroupBox;
+
+import formdata.shared.ui.template.formfield.replace.levels.AbstractMainBoxData;
+
+@FormData(value = AbstractMainBoxData.class, sdkCommand = FormData.SdkCommand.CREATE, defaultSubtypeSdkCommand = FormData.DefaultSubtypeSdkCommand.CREATE)
+public abstract class AbstractMainBox extends AbstractGroupBox {
+  public FirstLevel getFirstLevel() {
+    return getFieldByClass(FirstLevel.class);
+  }
+
+  public class FirstLevel extends AbstractTemplateField<Number> {
+  }
+}
diff --git a/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/template/formfield/replace/levels/AbstractTemplateField.java b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/template/formfield/replace/levels/AbstractTemplateField.java
new file mode 100644
index 0000000..1806cab
--- /dev/null
+++ b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/template/formfield/replace/levels/AbstractTemplateField.java
@@ -0,0 +1,35 @@
+package formdata.client.ui.template.formfield.replace.levels;
+
+import java.util.List;
+
+import org.eclipse.scout.commons.annotations.FormData;
+import org.eclipse.scout.commons.holders.IHolder;
+import org.eclipse.scout.rt.client.ui.basic.table.AbstractTable;
+import org.eclipse.scout.rt.client.ui.form.fields.tablefield.AbstractTableField;
+
+import formdata.shared.ui.template.formfield.replace.levels.AbstractTemplateFieldData;
+
+@FormData(value = AbstractTemplateFieldData.class, defaultSubtypeSdkCommand = FormData.DefaultSubtypeSdkCommand.CREATE, sdkCommand = FormData.SdkCommand.USE, genericOrdinal = 0)
+public abstract class AbstractTemplateField<T> extends AbstractTableField<AbstractTemplateField<T>.Table> implements IHolder<List<T>> {
+
+  public class Table extends AbstractTable {
+
+  }
+
+  @FormData
+  @Override
+  public List<T> getValue() {
+    return null;
+  }
+
+  @FormData
+  @Override
+  public void setValue(List<T> o) {
+  }
+
+  @FormData
+  @Override
+  public Class<List<T>> getHolderType() {
+    return null;
+  }
+}
diff --git a/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/template/formfield/replace/levels/FirstLevelForm.java b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/template/formfield/replace/levels/FirstLevelForm.java
new file mode 100644
index 0000000..cac6608
--- /dev/null
+++ b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/template/formfield/replace/levels/FirstLevelForm.java
@@ -0,0 +1,24 @@
+package formdata.client.ui.template.formfield.replace.levels;
+
+import org.eclipse.scout.commons.annotations.FormData;
+import org.eclipse.scout.commons.annotations.Order;
+import org.eclipse.scout.commons.exception.ProcessingException;
+import org.eclipse.scout.rt.client.ui.form.AbstractForm;
+import org.eclipse.scout.rt.client.ui.form.fields.groupbox.AbstractGroupBox;
+
+import formdata.shared.ui.template.formfield.replace.levels.FirstLevelFormData;
+
+@FormData(value = FirstLevelFormData.class, sdkCommand = FormData.SdkCommand.CREATE)
+public class FirstLevelForm extends AbstractForm {
+
+  public FirstLevelForm() throws ProcessingException {
+    super();
+  }
+
+  @Order(1000.0)
+  public class MainBox extends AbstractGroupBox {
+    public class FirstInnerBox extends AbstractMainBox {
+
+    }
+  }
+}
diff --git a/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/template/formfield/replace/levels/SecondLevelForm.java b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/template/formfield/replace/levels/SecondLevelForm.java
new file mode 100644
index 0000000..de1706a
--- /dev/null
+++ b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/template/formfield/replace/levels/SecondLevelForm.java
@@ -0,0 +1,31 @@
+package formdata.client.ui.template.formfield.replace.levels;
+
+import org.eclipse.scout.commons.annotations.FormData;
+import org.eclipse.scout.commons.annotations.Replace;
+import org.eclipse.scout.commons.exception.ProcessingException;
+
+import formdata.client.ui.template.formfield.replace.levels.FirstLevelForm.MainBox.FirstInnerBox;
+import formdata.shared.ui.template.formfield.replace.levels.SecondLevelFormData;
+
+@FormData(value = SecondLevelFormData.class, sdkCommand = FormData.SdkCommand.CREATE)
+public class SecondLevelForm extends FirstLevelForm {
+
+  public SecondLevelForm() throws ProcessingException {
+    super();
+  }
+
+  @Replace
+  public class SecondInnerBox extends FirstInnerBox {
+    public SecondInnerBox(FirstLevelForm.MainBox m) {
+      m.super();
+    }
+
+    @Replace
+    public class SecondLevel extends FirstLevelForm.MainBox.FirstInnerBox.FirstLevel {
+      public SecondLevel(FirstLevelForm.MainBox.FirstInnerBox m) {
+        m.super();
+      }
+    }
+  }
+
+}
diff --git a/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/template/formfield/replace/levels/ThirdLevelForm.java b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/template/formfield/replace/levels/ThirdLevelForm.java
new file mode 100644
index 0000000..b9a3c4b
--- /dev/null
+++ b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/template/formfield/replace/levels/ThirdLevelForm.java
@@ -0,0 +1,29 @@
+package formdata.client.ui.template.formfield.replace.levels;
+
+import org.eclipse.scout.commons.annotations.FormData;
+import org.eclipse.scout.commons.annotations.Replace;
+import org.eclipse.scout.commons.exception.ProcessingException;
+
+import formdata.shared.ui.template.formfield.replace.levels.ThirdLevelFormData;
+
+@FormData(value = ThirdLevelFormData.class, sdkCommand = FormData.SdkCommand.CREATE)
+public class ThirdLevelForm extends SecondLevelForm {
+
+  public ThirdLevelForm() throws ProcessingException {
+    super();
+  }
+
+  @Replace
+  public class ThirdInnerBox extends SecondInnerBox {
+    public ThirdInnerBox(FirstLevelForm.MainBox m) {
+      super(m);
+    }
+
+    @Replace
+    public class ThirdLevel extends SecondLevelForm.SecondInnerBox.SecondLevel {
+      public ThirdLevel(FirstLevelForm.MainBox.FirstInnerBox m) {
+        super(m);
+      }
+    }
+  }
+}
diff --git a/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/META-INF/MANIFEST.MF b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/META-INF/MANIFEST.MF
index 522d493..438992f 100644
--- a/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/META-INF/MANIFEST.MF
+++ b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/META-INF/MANIFEST.MF
@@ -10,7 +10,8 @@
  formdata.shared.services.pages,
  formdata.shared.services.process,
  formdata.shared.services.process.replace,
- formdata.shared.ui.forms
+ formdata.shared.ui.forms,
+ formdata.shared.ui.template.formfield.replace.levels
 Require-Bundle: org.eclipse.core.runtime,
  org.eclipse.scout.rt.shared;visibility:=reexport
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
diff --git a/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/ui/template/formfield/replace/levels/AbstractMainBoxData.java b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/ui/template/formfield/replace/levels/AbstractMainBoxData.java
new file mode 100644
index 0000000..b33a227
--- /dev/null
+++ b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/ui/template/formfield/replace/levels/AbstractMainBoxData.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package formdata.shared.ui.template.formfield.replace.levels;
+
+import javax.annotation.Generated;
+
+import org.eclipse.scout.rt.shared.data.form.fields.AbstractFormFieldData;
+
+/**
+ * <b>NOTE:</b><br>
+ * This class is auto generated by the Scout SDK. No manual modifications recommended.
+ * 
+ * @generated
+ */
+@Generated(value = "org.eclipse.scout.sdk.workspace.dto.formdata.FormDataDtoUpdateOperation", comments = "This class is auto generated by the Scout SDK. No manual modifications recommended.")
+public abstract class AbstractMainBoxData extends AbstractFormFieldData {
+
+  private static final long serialVersionUID = 1L;
+
+  public AbstractMainBoxData() {
+  }
+
+  public FirstLevel getFirstLevel() {
+    return getFieldByClass(FirstLevel.class);
+  }
+
+  public static class FirstLevel extends AbstractTemplateFieldData<Number> {
+
+    private static final long serialVersionUID = 1L;
+
+    public FirstLevel() {
+    }
+  }
+}
diff --git a/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/ui/template/formfield/replace/levels/AbstractTemplateFieldData.java b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/ui/template/formfield/replace/levels/AbstractTemplateFieldData.java
new file mode 100644
index 0000000..a290ee0
--- /dev/null
+++ b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/ui/template/formfield/replace/levels/AbstractTemplateFieldData.java
@@ -0,0 +1,19 @@
+package formdata.shared.ui.template.formfield.replace.levels;
+
+import java.util.List;
+
+import javax.annotation.Generated;
+
+import org.eclipse.scout.rt.shared.data.form.fields.AbstractValueFieldData;
+
+/**
+ * <b>NOTE:</b><br>
+ * This class is auto generated by the Scout SDK. No manual modifications recommended.
+ *
+ * @generated
+ */
+@Generated(value = "org.eclipse.scout.sdk.workspace.dto.formdata.FormDataDtoUpdateOperation", comments = "This class is auto generated by the Scout SDK. No manual modifications recommended.")
+public abstract class AbstractTemplateFieldData<T> extends AbstractValueFieldData<List<T>> {
+
+  private static final long serialVersionUID = -1551979337783469107L;
+}
diff --git a/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/ui/template/formfield/replace/levels/FirstLevelFormData.java b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/ui/template/formfield/replace/levels/FirstLevelFormData.java
new file mode 100644
index 0000000..15f0059
--- /dev/null
+++ b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/ui/template/formfield/replace/levels/FirstLevelFormData.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package formdata.shared.ui.template.formfield.replace.levels;
+
+import javax.annotation.Generated;
+
+import org.eclipse.scout.rt.shared.data.form.AbstractFormData;
+
+/**
+ * <b>NOTE:</b><br>
+ * This class is auto generated by the Scout SDK. No manual modifications recommended.
+ * 
+ * @generated
+ */
+@Generated(value = "org.eclipse.scout.sdk.workspace.dto.formdata.FormDataDtoUpdateOperation", comments = "This class is auto generated by the Scout SDK. No manual modifications recommended.")
+public class FirstLevelFormData extends AbstractFormData {
+
+  private static final long serialVersionUID = 1L;
+
+  public FirstLevelFormData() {
+  }
+
+  public FirstInnerBox getFirstInnerBox() {
+    return getFieldByClass(FirstInnerBox.class);
+  }
+
+  public static class FirstInnerBox extends AbstractMainBoxData {
+
+    private static final long serialVersionUID = 1L;
+
+    public FirstInnerBox() {
+    }
+  }
+}
diff --git a/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/ui/template/formfield/replace/levels/SecondLevelFormData.java b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/ui/template/formfield/replace/levels/SecondLevelFormData.java
new file mode 100644
index 0000000..2d3ff34
--- /dev/null
+++ b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/ui/template/formfield/replace/levels/SecondLevelFormData.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package formdata.shared.ui.template.formfield.replace.levels;
+
+import javax.annotation.Generated;
+
+import org.eclipse.scout.commons.annotations.Replace;
+
+/**
+ * <b>NOTE:</b><br>
+ * This class is auto generated by the Scout SDK. No manual modifications recommended.
+ * 
+ * @generated
+ */
+@Generated(value = "org.eclipse.scout.sdk.workspace.dto.formdata.FormDataDtoUpdateOperation", comments = "This class is auto generated by the Scout SDK. No manual modifications recommended.")
+public class SecondLevelFormData extends FirstLevelFormData {
+
+  private static final long serialVersionUID = 1L;
+
+  public SecondLevelFormData() {
+  }
+
+  public SecondInnerBox getSecondInnerBox() {
+    return getFieldByClass(SecondInnerBox.class);
+  }
+
+  @Replace
+  public static class SecondInnerBox extends FirstInnerBox {
+
+    private static final long serialVersionUID = 1L;
+
+    public SecondInnerBox() {
+    }
+
+    public SecondLevel getSecondLevel() {
+      return getFieldByClass(SecondLevel.class);
+    }
+
+    @Replace
+    public static class SecondLevel extends FirstLevel {
+
+      private static final long serialVersionUID = 1L;
+
+      public SecondLevel() {
+      }
+    }
+  }
+}
diff --git a/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/ui/template/formfield/replace/levels/ThirdLevelFormData.java b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/ui/template/formfield/replace/levels/ThirdLevelFormData.java
new file mode 100644
index 0000000..00dfab7
--- /dev/null
+++ b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/ui/template/formfield/replace/levels/ThirdLevelFormData.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package formdata.shared.ui.template.formfield.replace.levels;
+
+import javax.annotation.Generated;
+
+import org.eclipse.scout.commons.annotations.Replace;
+
+/**
+ * <b>NOTE:</b><br>
+ * This class is auto generated by the Scout SDK. No manual modifications recommended.
+ * 
+ * @generated
+ */
+@Generated(value = "org.eclipse.scout.sdk.workspace.dto.formdata.FormDataDtoUpdateOperation", comments = "This class is auto generated by the Scout SDK. No manual modifications recommended.")
+public class ThirdLevelFormData extends SecondLevelFormData {
+
+  private static final long serialVersionUID = 1L;
+
+  public ThirdLevelFormData() {
+  }
+
+  public ThirdInnerBox getThirdInnerBox() {
+    return getFieldByClass(ThirdInnerBox.class);
+  }
+
+  @Replace
+  public static class ThirdInnerBox extends SecondInnerBox {
+
+    private static final long serialVersionUID = 1L;
+
+    public ThirdInnerBox() {
+    }
+
+    public ThirdLevel getThirdLevel() {
+      return getFieldByClass(ThirdLevel.class);
+    }
+
+    @Replace
+    public static class ThirdLevel extends SecondLevel {
+
+      private static final long serialVersionUID = 1L;
+
+      public ThirdLevel() {
+      }
+    }
+  }
+}
diff --git a/org.eclipse.scout.sdk.test/src/org/eclipse/scout/sdk/internal/test/operation/formdata/NestedMultiLevelFormFieldTest.java b/org.eclipse.scout.sdk.test/src/org/eclipse/scout/sdk/internal/test/operation/formdata/NestedMultiLevelFormFieldTest.java
new file mode 100644
index 0000000..113ef3f
--- /dev/null
+++ b/org.eclipse.scout.sdk.test/src/org/eclipse/scout/sdk/internal/test/operation/formdata/NestedMultiLevelFormFieldTest.java
@@ -0,0 +1,314 @@
+/*******************************************************************************
+ * Copyright (c) 2013 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.sdk.internal.test.operation.formdata;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.scout.sdk.testing.SdkAssert;
+import org.eclipse.scout.sdk.workspace.dto.formdata.FormDataDtoUpdateOperation;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class NestedMultiLevelFormFieldTest extends AbstractSdkTestWithFormDataProject {
+  @Test
+  public void runTests() throws Exception {
+    checkAbstractMainBoxData();
+    checkAbstractTemplateFieldData();
+    checkFirstLevelFormData();
+    checkSecondLevelFormData();
+    checkThirdLevelFormData();
+  }
+
+  private void checkAbstractMainBoxData() throws Exception {
+    IType t = SdkAssert.assertTypeExists("formdata.shared.ui.template.formfield.replace.levels.AbstractMainBoxData");
+
+    IProject sharedProject = getProject("formdata.shared");
+    Assert.assertNotNull(sharedProject);
+
+    FormDataDtoUpdateOperation op = new FormDataDtoUpdateOperation(t);
+    executeBuildAssertNoCompileErrors(op);
+
+    testApiOfAbstractMainBoxData();
+  }
+
+  private void checkAbstractTemplateFieldData() throws Exception {
+    IType t = SdkAssert.assertTypeExists("formdata.shared.ui.template.formfield.replace.levels.AbstractTemplateFieldData");
+
+    IProject sharedProject = getProject("formdata.shared");
+    Assert.assertNotNull(sharedProject);
+
+    FormDataDtoUpdateOperation op = new FormDataDtoUpdateOperation(t);
+    executeBuildAssertNoCompileErrors(op);
+
+    testApiOfAbstractTemplateFieldData();
+  }
+
+  private void checkFirstLevelFormData() throws Exception {
+    IType t = SdkAssert.assertTypeExists("formdata.shared.ui.template.formfield.replace.levels.FirstLevelFormData");
+
+    IProject sharedProject = getProject("formdata.shared");
+    Assert.assertNotNull(sharedProject);
+
+    FormDataDtoUpdateOperation op = new FormDataDtoUpdateOperation(t);
+    executeBuildAssertNoCompileErrors(op);
+
+    testApiOfFirstLevelFormData();
+  }
+
+  private void checkSecondLevelFormData() throws Exception {
+    IType t = SdkAssert.assertTypeExists("formdata.shared.ui.template.formfield.replace.levels.SecondLevelFormData");
+
+    IProject sharedProject = getProject("formdata.shared");
+    Assert.assertNotNull(sharedProject);
+
+    FormDataDtoUpdateOperation op = new FormDataDtoUpdateOperation(t);
+    executeBuildAssertNoCompileErrors(op);
+
+    testApiOfSecondLevelFormData();
+  }
+
+  private void checkThirdLevelFormData() throws Exception {
+    IType t = SdkAssert.assertTypeExists("formdata.shared.ui.template.formfield.replace.levels.ThirdLevelFormData");
+
+    IProject sharedProject = getProject("formdata.shared");
+    Assert.assertNotNull(sharedProject);
+
+    FormDataDtoUpdateOperation op = new FormDataDtoUpdateOperation(t);
+    executeBuildAssertNoCompileErrors(op);
+
+    testApiOfThirdLevelFormData();
+  }
+
+  /**
+   * @Generated with org.eclipse.scout.sdk.testing.codegen.ApiTestGenerator
+   */
+  private void testApiOfAbstractMainBoxData() throws Exception {
+    // type AbstractMainBoxData
+    IType abstractMainBoxData = SdkAssert.assertTypeExists("formdata.shared.ui.template.formfield.replace.levels.AbstractMainBoxData");
+    SdkAssert.assertHasFlags(abstractMainBoxData, 1025);
+    SdkAssert.assertHasSuperTypeSignature(abstractMainBoxData, "QAbstractFormFieldData;");
+    SdkAssert.assertAnnotation(abstractMainBoxData, "javax.annotation.Generated");
+
+    // fields of AbstractMainBoxData
+    SdkAssert.assertEquals("field count of 'AbstractMainBoxData'", 1, abstractMainBoxData.getFields().length);
+    IField serialVersionUID = SdkAssert.assertFieldExist(abstractMainBoxData, "serialVersionUID");
+    SdkAssert.assertHasFlags(serialVersionUID, 26);
+    SdkAssert.assertFieldSignature(serialVersionUID, "J");
+
+    SdkAssert.assertEquals("method count of 'AbstractMainBoxData'", 2, abstractMainBoxData.getMethods().length);
+    IMethod abstractMainBoxData1 = SdkAssert.assertMethodExist(abstractMainBoxData, "AbstractMainBoxData", new String[]{});
+    SdkAssert.assertTrue(abstractMainBoxData1.isConstructor());
+    SdkAssert.assertMethodReturnTypeSignature(abstractMainBoxData1, "V");
+    IMethod getFirstLevel = SdkAssert.assertMethodExist(abstractMainBoxData, "getFirstLevel", new String[]{});
+    SdkAssert.assertMethodReturnTypeSignature(getFirstLevel, "QFirstLevel;");
+
+    SdkAssert.assertEquals("inner types count of 'AbstractMainBoxData'", 1, abstractMainBoxData.getTypes().length);
+    // type FirstLevel
+    IType firstLevel = SdkAssert.assertTypeExists(abstractMainBoxData, "FirstLevel");
+    SdkAssert.assertHasFlags(firstLevel, 9);
+    SdkAssert.assertHasSuperTypeSignature(firstLevel, "QAbstractTemplateFieldData<QNumber;>;");
+
+    // fields of FirstLevel
+    SdkAssert.assertEquals("field count of 'FirstLevel'", 1, firstLevel.getFields().length);
+    IField serialVersionUID1 = SdkAssert.assertFieldExist(firstLevel, "serialVersionUID");
+    SdkAssert.assertHasFlags(serialVersionUID1, 26);
+    SdkAssert.assertFieldSignature(serialVersionUID1, "J");
+
+    SdkAssert.assertEquals("method count of 'FirstLevel'", 1, firstLevel.getMethods().length);
+    IMethod firstLevel1 = SdkAssert.assertMethodExist(firstLevel, "FirstLevel", new String[]{});
+    SdkAssert.assertTrue(firstLevel1.isConstructor());
+    SdkAssert.assertMethodReturnTypeSignature(firstLevel1, "V");
+
+    SdkAssert.assertEquals("inner types count of 'FirstLevel'", 0, firstLevel.getTypes().length);
+  }
+
+  private void testApiOfAbstractTemplateFieldData() throws Exception {
+    // type AbstractTemplateFieldData
+    IType abstractTemplateFieldData = SdkAssert.assertTypeExists("formdata.shared.ui.template.formfield.replace.levels.AbstractTemplateFieldData");
+    SdkAssert.assertHasFlags(abstractTemplateFieldData, 1025);
+    SdkAssert.assertHasSuperTypeSignature(abstractTemplateFieldData, "QAbstractValueFieldData<QList<QT;>;>;");
+    SdkAssert.assertAnnotation(abstractTemplateFieldData, "javax.annotation.Generated");
+
+    // fields of AbstractTemplateFieldData
+    SdkAssert.assertEquals("field count of 'AbstractTemplateFieldData'", 1, abstractTemplateFieldData.getFields().length);
+    IField serialVersionUID = SdkAssert.assertFieldExist(abstractTemplateFieldData, "serialVersionUID");
+    SdkAssert.assertHasFlags(serialVersionUID, 26);
+    SdkAssert.assertFieldSignature(serialVersionUID, "J");
+
+    SdkAssert.assertEquals("method count of 'AbstractTemplateFieldData'", 0, abstractTemplateFieldData.getMethods().length);
+
+    SdkAssert.assertEquals("inner types count of 'AbstractTemplateFieldData'", 0, abstractTemplateFieldData.getTypes().length);
+  }
+
+  private void testApiOfFirstLevelFormData() throws Exception {
+    // type FirstLevelFormData
+    IType firstLevelFormData = SdkAssert.assertTypeExists("formdata.shared.ui.template.formfield.replace.levels.FirstLevelFormData");
+    SdkAssert.assertHasFlags(firstLevelFormData, 1);
+    SdkAssert.assertHasSuperTypeSignature(firstLevelFormData, "QAbstractFormData;");
+    SdkAssert.assertAnnotation(firstLevelFormData, "javax.annotation.Generated");
+
+    // fields of FirstLevelFormData
+    SdkAssert.assertEquals("field count of 'FirstLevelFormData'", 1, firstLevelFormData.getFields().length);
+    IField serialVersionUID = SdkAssert.assertFieldExist(firstLevelFormData, "serialVersionUID");
+    SdkAssert.assertHasFlags(serialVersionUID, 26);
+    SdkAssert.assertFieldSignature(serialVersionUID, "J");
+
+    SdkAssert.assertEquals("method count of 'FirstLevelFormData'", 2, firstLevelFormData.getMethods().length);
+    IMethod firstLevelFormData1 = SdkAssert.assertMethodExist(firstLevelFormData, "FirstLevelFormData", new String[]{});
+    SdkAssert.assertTrue(firstLevelFormData1.isConstructor());
+    SdkAssert.assertMethodReturnTypeSignature(firstLevelFormData1, "V");
+    IMethod getFirstInnerBox = SdkAssert.assertMethodExist(firstLevelFormData, "getFirstInnerBox", new String[]{});
+    SdkAssert.assertMethodReturnTypeSignature(getFirstInnerBox, "QFirstInnerBox;");
+
+    SdkAssert.assertEquals("inner types count of 'FirstLevelFormData'", 1, firstLevelFormData.getTypes().length);
+    // type FirstInnerBox
+    IType firstInnerBox = SdkAssert.assertTypeExists(firstLevelFormData, "FirstInnerBox");
+    SdkAssert.assertHasFlags(firstInnerBox, 9);
+    SdkAssert.assertHasSuperTypeSignature(firstInnerBox, "QAbstractMainBoxData;");
+
+    // fields of FirstInnerBox
+    SdkAssert.assertEquals("field count of 'FirstInnerBox'", 1, firstInnerBox.getFields().length);
+    IField serialVersionUID1 = SdkAssert.assertFieldExist(firstInnerBox, "serialVersionUID");
+    SdkAssert.assertHasFlags(serialVersionUID1, 26);
+    SdkAssert.assertFieldSignature(serialVersionUID1, "J");
+
+    SdkAssert.assertEquals("method count of 'FirstInnerBox'", 1, firstInnerBox.getMethods().length);
+    IMethod firstInnerBox1 = SdkAssert.assertMethodExist(firstInnerBox, "FirstInnerBox", new String[]{});
+    SdkAssert.assertTrue(firstInnerBox1.isConstructor());
+    SdkAssert.assertMethodReturnTypeSignature(firstInnerBox1, "V");
+
+    SdkAssert.assertEquals("inner types count of 'FirstInnerBox'", 0, firstInnerBox.getTypes().length);
+  }
+
+  private void testApiOfSecondLevelFormData() throws Exception {
+    // type SecondLevelFormData
+    IType secondLevelFormData = SdkAssert.assertTypeExists("formdata.shared.ui.template.formfield.replace.levels.SecondLevelFormData");
+    SdkAssert.assertHasFlags(secondLevelFormData, 1);
+    SdkAssert.assertHasSuperTypeSignature(secondLevelFormData, "QFirstLevelFormData;");
+    SdkAssert.assertAnnotation(secondLevelFormData, "javax.annotation.Generated");
+
+    // fields of SecondLevelFormData
+    SdkAssert.assertEquals("field count of 'SecondLevelFormData'", 1, secondLevelFormData.getFields().length);
+    IField serialVersionUID = SdkAssert.assertFieldExist(secondLevelFormData, "serialVersionUID");
+    SdkAssert.assertHasFlags(serialVersionUID, 26);
+    SdkAssert.assertFieldSignature(serialVersionUID, "J");
+
+    SdkAssert.assertEquals("method count of 'SecondLevelFormData'", 2, secondLevelFormData.getMethods().length);
+    IMethod secondLevelFormData1 = SdkAssert.assertMethodExist(secondLevelFormData, "SecondLevelFormData", new String[]{});
+    SdkAssert.assertTrue(secondLevelFormData1.isConstructor());
+    SdkAssert.assertMethodReturnTypeSignature(secondLevelFormData1, "V");
+    IMethod getSecondInnerBox = SdkAssert.assertMethodExist(secondLevelFormData, "getSecondInnerBox", new String[]{});
+    SdkAssert.assertMethodReturnTypeSignature(getSecondInnerBox, "QSecondInnerBox;");
+
+    SdkAssert.assertEquals("inner types count of 'SecondLevelFormData'", 1, secondLevelFormData.getTypes().length);
+    // type SecondInnerBox
+    IType secondInnerBox = SdkAssert.assertTypeExists(secondLevelFormData, "SecondInnerBox");
+    SdkAssert.assertHasFlags(secondInnerBox, 9);
+    SdkAssert.assertHasSuperTypeSignature(secondInnerBox, "QFirstInnerBox;");
+    SdkAssert.assertAnnotation(secondInnerBox, "org.eclipse.scout.commons.annotations.Replace");
+
+    // fields of SecondInnerBox
+    SdkAssert.assertEquals("field count of 'SecondInnerBox'", 1, secondInnerBox.getFields().length);
+    IField serialVersionUID1 = SdkAssert.assertFieldExist(secondInnerBox, "serialVersionUID");
+    SdkAssert.assertHasFlags(serialVersionUID1, 26);
+    SdkAssert.assertFieldSignature(serialVersionUID1, "J");
+
+    SdkAssert.assertEquals("method count of 'SecondInnerBox'", 2, secondInnerBox.getMethods().length);
+    IMethod secondInnerBox1 = SdkAssert.assertMethodExist(secondInnerBox, "SecondInnerBox", new String[]{});
+    SdkAssert.assertTrue(secondInnerBox1.isConstructor());
+    SdkAssert.assertMethodReturnTypeSignature(secondInnerBox1, "V");
+    IMethod getSecondLevel = SdkAssert.assertMethodExist(secondInnerBox, "getSecondLevel", new String[]{});
+    SdkAssert.assertMethodReturnTypeSignature(getSecondLevel, "QSecondLevel;");
+
+    SdkAssert.assertEquals("inner types count of 'SecondInnerBox'", 1, secondInnerBox.getTypes().length);
+    // type SecondLevel
+    IType secondLevel = SdkAssert.assertTypeExists(secondInnerBox, "SecondLevel");
+    SdkAssert.assertHasFlags(secondLevel, 9);
+    SdkAssert.assertHasSuperTypeSignature(secondLevel, "QFirstLevel;");
+    SdkAssert.assertAnnotation(secondLevel, "org.eclipse.scout.commons.annotations.Replace");
+
+    // fields of SecondLevel
+    SdkAssert.assertEquals("field count of 'SecondLevel'", 1, secondLevel.getFields().length);
+    IField serialVersionUID2 = SdkAssert.assertFieldExist(secondLevel, "serialVersionUID");
+    SdkAssert.assertHasFlags(serialVersionUID2, 26);
+    SdkAssert.assertFieldSignature(serialVersionUID2, "J");
+
+    SdkAssert.assertEquals("method count of 'SecondLevel'", 1, secondLevel.getMethods().length);
+    IMethod secondLevel1 = SdkAssert.assertMethodExist(secondLevel, "SecondLevel", new String[]{});
+    SdkAssert.assertTrue(secondLevel1.isConstructor());
+    SdkAssert.assertMethodReturnTypeSignature(secondLevel1, "V");
+
+    SdkAssert.assertEquals("inner types count of 'SecondLevel'", 0, secondLevel.getTypes().length);
+  }
+
+  private void testApiOfThirdLevelFormData() throws Exception {
+    // type ThirdLevelFormData
+    IType thirdLevelFormData = SdkAssert.assertTypeExists("formdata.shared.ui.template.formfield.replace.levels.ThirdLevelFormData");
+    SdkAssert.assertHasFlags(thirdLevelFormData, 1);
+    SdkAssert.assertHasSuperTypeSignature(thirdLevelFormData, "QSecondLevelFormData;");
+    SdkAssert.assertAnnotation(thirdLevelFormData, "javax.annotation.Generated");
+
+    // fields of ThirdLevelFormData
+    SdkAssert.assertEquals("field count of 'ThirdLevelFormData'", 1, thirdLevelFormData.getFields().length);
+    IField serialVersionUID = SdkAssert.assertFieldExist(thirdLevelFormData, "serialVersionUID");
+    SdkAssert.assertHasFlags(serialVersionUID, 26);
+    SdkAssert.assertFieldSignature(serialVersionUID, "J");
+
+    SdkAssert.assertEquals("method count of 'ThirdLevelFormData'", 2, thirdLevelFormData.getMethods().length);
+    IMethod thirdLevelFormData1 = SdkAssert.assertMethodExist(thirdLevelFormData, "ThirdLevelFormData", new String[]{});
+    SdkAssert.assertTrue(thirdLevelFormData1.isConstructor());
+    SdkAssert.assertMethodReturnTypeSignature(thirdLevelFormData1, "V");
+    IMethod getThirdInnerBox = SdkAssert.assertMethodExist(thirdLevelFormData, "getThirdInnerBox", new String[]{});
+    SdkAssert.assertMethodReturnTypeSignature(getThirdInnerBox, "QThirdInnerBox;");
+
+    SdkAssert.assertEquals("inner types count of 'ThirdLevelFormData'", 1, thirdLevelFormData.getTypes().length);
+    // type ThirdInnerBox
+    IType thirdInnerBox = SdkAssert.assertTypeExists(thirdLevelFormData, "ThirdInnerBox");
+    SdkAssert.assertHasFlags(thirdInnerBox, 9);
+    SdkAssert.assertHasSuperTypeSignature(thirdInnerBox, "QSecondInnerBox;");
+    SdkAssert.assertAnnotation(thirdInnerBox, "org.eclipse.scout.commons.annotations.Replace");
+
+    // fields of ThirdInnerBox
+    SdkAssert.assertEquals("field count of 'ThirdInnerBox'", 1, thirdInnerBox.getFields().length);
+    IField serialVersionUID1 = SdkAssert.assertFieldExist(thirdInnerBox, "serialVersionUID");
+    SdkAssert.assertHasFlags(serialVersionUID1, 26);
+    SdkAssert.assertFieldSignature(serialVersionUID1, "J");
+
+    SdkAssert.assertEquals("method count of 'ThirdInnerBox'", 2, thirdInnerBox.getMethods().length);
+    IMethod thirdInnerBox1 = SdkAssert.assertMethodExist(thirdInnerBox, "ThirdInnerBox", new String[]{});
+    SdkAssert.assertTrue(thirdInnerBox1.isConstructor());
+    SdkAssert.assertMethodReturnTypeSignature(thirdInnerBox1, "V");
+    IMethod getThirdLevel = SdkAssert.assertMethodExist(thirdInnerBox, "getThirdLevel", new String[]{});
+    SdkAssert.assertMethodReturnTypeSignature(getThirdLevel, "QThirdLevel;");
+
+    SdkAssert.assertEquals("inner types count of 'ThirdInnerBox'", 1, thirdInnerBox.getTypes().length);
+    // type ThirdLevel
+    IType thirdLevel = SdkAssert.assertTypeExists(thirdInnerBox, "ThirdLevel");
+    SdkAssert.assertHasFlags(thirdLevel, 9);
+    SdkAssert.assertHasSuperTypeSignature(thirdLevel, "QSecondLevel;");
+    SdkAssert.assertAnnotation(thirdLevel, "org.eclipse.scout.commons.annotations.Replace");
+
+    // fields of ThirdLevel
+    SdkAssert.assertEquals("field count of 'ThirdLevel'", 1, thirdLevel.getFields().length);
+    IField serialVersionUID2 = SdkAssert.assertFieldExist(thirdLevel, "serialVersionUID");
+    SdkAssert.assertHasFlags(serialVersionUID2, 26);
+    SdkAssert.assertFieldSignature(serialVersionUID2, "J");
+
+    SdkAssert.assertEquals("method count of 'ThirdLevel'", 1, thirdLevel.getMethods().length);
+    IMethod thirdLevel1 = SdkAssert.assertMethodExist(thirdLevel, "ThirdLevel", new String[]{});
+    SdkAssert.assertTrue(thirdLevel1.isConstructor());
+    SdkAssert.assertMethodReturnTypeSignature(thirdLevel1, "V");
+
+    SdkAssert.assertEquals("inner types count of 'ThirdLevel'", 0, thirdLevel.getTypes().length);
+  }
+}
diff --git a/org.eclipse.scout.sdk.test/src/org/eclipse/scout/sdk/internal/test/operation/formdata/_SuiteFormData.java b/org.eclipse.scout.sdk.test/src/org/eclipse/scout/sdk/internal/test/operation/formdata/_SuiteFormData.java
index fd45355..47fef29 100644
--- a/org.eclipse.scout.sdk.test/src/org/eclipse/scout/sdk/internal/test/operation/formdata/_SuiteFormData.java
+++ b/org.eclipse.scout.sdk.test/src/org/eclipse/scout/sdk/internal/test/operation/formdata/_SuiteFormData.java
@@ -22,21 +22,22 @@
  */
 @RunWith(Suite.class)
 @SuiteClasses({
-    AnnotationCopyTest.class,
-    ExternalCheckboxFieldTest.class,
-    ExternalGroupboxTest.class,
-    ExternalTableFieldTest.class,
-    FormPropertiesTest.class,
-    FormWithGroupboxesTest.class,
-    FormWithTemplateTest.class,
-    IgnoredFieldsFormTest.class,
-    ListBoxFormTest.class,
-    ReplaceFormFieldTest.class,
-    SimpleFormTest.class,
-    TableFieldBeanTest.class,
-    TableFieldFormTest.class,
-    TableFieldWithIgnoredColumnsTest.class,
-    MasterFieldFormDataTest.class
+  AnnotationCopyTest.class,
+  ExternalCheckboxFieldTest.class,
+  ExternalGroupboxTest.class,
+  ExternalTableFieldTest.class,
+  FormPropertiesTest.class,
+  FormWithGroupboxesTest.class,
+  FormWithTemplateTest.class,
+  IgnoredFieldsFormTest.class,
+  ListBoxFormTest.class,
+  ReplaceFormFieldTest.class,
+  SimpleFormTest.class,
+  TableFieldBeanTest.class,
+  TableFieldFormTest.class,
+  TableFieldWithIgnoredColumnsTest.class,
+  MasterFieldFormDataTest.class,
+  NestedMultiLevelFormFieldTest.class
 })
 public class _SuiteFormData {
 
diff --git a/org.eclipse.scout.sdk.util/src/org/eclipse/scout/sdk/util/type/TypeUtility.java b/org.eclipse.scout.sdk.util/src/org/eclipse/scout/sdk/util/type/TypeUtility.java
index 9cc566b..ce020d2 100644
--- a/org.eclipse.scout.sdk.util/src/org/eclipse/scout/sdk/util/type/TypeUtility.java
+++ b/org.eclipse.scout.sdk.util/src/org/eclipse/scout/sdk/util/type/TypeUtility.java
@@ -51,7 +51,6 @@
 import org.eclipse.jdt.core.dom.MethodDeclaration;
 import org.eclipse.scout.commons.CollectionUtility;
 import org.eclipse.scout.commons.CompareUtility;
-import org.eclipse.scout.commons.StringUtility;
 import org.eclipse.scout.commons.holders.Holder;
 import org.eclipse.scout.sdk.util.NamingUtility;
 import org.eclipse.scout.sdk.util.ScoutSdkUtilCore;
@@ -641,25 +640,32 @@
     return element != null && element.exists();
   }
 
-  public static IType findInnerType(IType type, String innerTypeName) {
-    if (type == null) {
+  /**
+   * Searches for an {@link IType} with a specific name within the given type recursively checking all inner types. The
+   * given {@link IType} itself is checked as well.
+   *
+   * @param type
+   *          The {@link IType} to start searching. All nested inner {@link IType}s are visited recursively.
+   * @param innerTypeName
+   *          The simple name (case sensitive) to search for.
+   * @return The first {@link IType} found in the nested {@link IType} tree below the given start type that has the
+   *         given simple name or <code>null</code> if nothing could be found.
+   * @throws JavaModelException
+   */
+  public static IType findInnerType(IType type, String innerTypeName) throws JavaModelException {
+    if (!TypeUtility.exists(type)) {
       return null;
     }
-    else if (StringUtility.equalsIgnoreCase(type.getElementName(), innerTypeName)) {
+    else if (CompareUtility.equals(type.getElementName(), innerTypeName)) {
       return type;
     }
     else {
-      try {
-        for (IType innerType : type.getTypes()) {
-          IType found = findInnerType(innerType, innerTypeName);
-          if (found != null) {
-            return found;
-          }
+      for (IType innerType : type.getTypes()) {
+        IType found = findInnerType(innerType, innerTypeName);
+        if (found != null) {
+          return found;
         }
       }
-      catch (JavaModelException e) {
-        SdkUtilActivator.logError("could not find inner type named '" + innerTypeName + "' in type '" + type.getFullyQualifiedName() + "'.", e);
-      }
     }
     return null;
   }
diff --git a/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/internal/workspace/dto/DtoUtility.java b/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/internal/workspace/dto/DtoUtility.java
index 1c7f3b7..409e75b 100644
--- a/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/internal/workspace/dto/DtoUtility.java
+++ b/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/internal/workspace/dto/DtoUtility.java
@@ -383,7 +383,7 @@
     }
 
     // search field data within form data
-    IType formDataType = primaryType.getType(formDataName);
+    IType formDataType = TypeUtility.findInnerType(primaryType, formDataName);
     if (TypeUtility.exists(formDataType)) {
       return formDataType;
     }