Index: src/gwtTest/java/com/pietschy/gwt/pectin/client/bean/test/TestBean.java
===================================================================
--- src/gwtTest/java/com/pietschy/gwt/pectin/client/bean/test/TestBean.java	(revision 637)
+++ src/gwtTest/java/com/pietschy/gwt/pectin/client/bean/test/TestBean.java	(working copy)
@@ -25,7 +25,17 @@
    
    private AnotherBean nestedBean;
    private BeanWithCollections collections;
+   
+   private AbtractRootBean rootBean;
 
+   public AbtractRootBean getRootBean() {
+      return this.rootBean;
+   }
+
+   public void setRootBean(AbtractRootBean rootBean) {
+      this.rootBean = rootBean;
+   }
+
    public Object getObject()
    {
       return object;
Index: src/gwtTest/java/com/pietschy/gwt/pectin/client/bean/test/SonBean1.java
===================================================================
--- src/gwtTest/java/com/pietschy/gwt/pectin/client/bean/test/SonBean1.java	(revision 0)
+++ src/gwtTest/java/com/pietschy/gwt/pectin/client/bean/test/SonBean1.java	(revision 0)
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010 Benjamin Lerman
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you 
+ * may not use this file except in compliance with the License. You may 
+ * obtain a copy of the License at 
+ *      
+ *      http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
+ * implied. See the License for the specific language governing permissions 
+ * and limitations under the License. 
+ */
+package com.pietschy.gwt.pectin.client.bean.test;
+
+/**
+ * The first child.
+ */
+public class SonBean1 extends AbtractRootBean {
+
+    private String string1;
+
+    /**
+     * getter for the string1 property.
+     *
+     * @return the string1
+     */
+    public String getString1() {
+        return this.string1;
+    }
+
+    /**
+     * setter for the string1 property.
+     *
+     * @param string1 the string1 to set
+     */
+    public void setString1(String string1) {
+        this.string1 = string1;
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        return string1;
+    }
+}
Index: src/gwtTest/java/com/pietschy/gwt/pectin/client/bean/test/SonBean2.java
===================================================================
--- src/gwtTest/java/com/pietschy/gwt/pectin/client/bean/test/SonBean2.java	(revision 0)
+++ src/gwtTest/java/com/pietschy/gwt/pectin/client/bean/test/SonBean2.java	(revision 0)
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010 Benjamin Lerman
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you 
+ * may not use this file except in compliance with the License. You may 
+ * obtain a copy of the License at 
+ *      
+ *      http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
+ * implied. See the License for the specific language governing permissions 
+ * and limitations under the License. 
+ */
+package com.pietschy.gwt.pectin.client.bean.test;
+
+/**
+ * The second child.
+ */
+public class SonBean2 extends AbtractRootBean {
+
+    private String string2;
+
+    /**
+     * getter for the string2 property.
+     *
+     * @return the string2
+     */
+    public String getString2() {
+        return this.string2;
+    }
+
+    /**
+     * setter for the string2 property.
+     *
+     * @param string2 the string2 to set
+     */
+    public void setString2(String string2) {
+        this.string2 = string2;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        return string2;
+    }
+}
Index: src/gwtTest/java/com/pietschy/gwt/pectin/client/bean/test/AbtractRootBean.java
===================================================================
--- src/gwtTest/java/com/pietschy/gwt/pectin/client/bean/test/AbtractRootBean.java	(revision 0)
+++ src/gwtTest/java/com/pietschy/gwt/pectin/client/bean/test/AbtractRootBean.java	(revision 0)
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2010 Benjamin Lerman
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you 
+ * may not use this file except in compliance with the License. You may 
+ * obtain a copy of the License at 
+ *      
+ *      http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
+ * implied. See the License for the specific language governing permissions 
+ * and limitations under the License. 
+ */
+package com.pietschy.gwt.pectin.client.bean.test;
+
+/**
+ * An abstract class.
+ */
+public abstract class AbtractRootBean {
+
+}
Index: src/gwtTest/java/com/pietschy/gwt/pectin/client/bean/test/BeanDeclaration.java
===================================================================
--- src/gwtTest/java/com/pietschy/gwt/pectin/client/bean/test/BeanDeclaration.java	(revision 0)
+++ src/gwtTest/java/com/pietschy/gwt/pectin/client/bean/test/BeanDeclaration.java	(revision 0)
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2010 Benjamin Lerman
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you 
+ * may not use this file except in compliance with the License. You may 
+ * obtain a copy of the License at 
+ *      
+ *      http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
+ * implied. See the License for the specific language governing permissions 
+ * and limitations under the License. 
+ */
+package com.pietschy.gwt.pectin.client.bean.test;
+
+import com.pietschy.gwt.pectin.client.bean.Beans;
+
+/**
+ * interfaces used only to trigger metadata generation for beans.
+ */
+@Beans( { AnotherBean.class, BeanWithCollections.class, TestBean.class, AbtractRootBean.class, SonBean1.class, SonBean2.class })
+public interface BeanDeclaration {
+
+}
Index: src/gwtTest/java/com/pietschy/gwt/pectin/client/bean/BeanModelProviderFactoryTest.java
===================================================================
--- src/gwtTest/java/com/pietschy/gwt/pectin/client/bean/BeanModelProviderFactoryTest.java	(revision 0)
+++ src/gwtTest/java/com/pietschy/gwt/pectin/client/bean/BeanModelProviderFactoryTest.java	(revision 0)
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2010 Benjamin Lerman
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you 
+ * may not use this file except in compliance with the License. You may 
+ * obtain a copy of the License at 
+ *      
+ *      http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
+ * implied. See the License for the specific language governing permissions 
+ * and limitations under the License. 
+ */
+package com.pietschy.gwt.pectin.client.bean;
+
+import com.google.gwt.junit.client.GWTTestCase;
+import com.pietschy.gwt.pectin.client.bean.test.AbtractRootBean;
+import com.pietschy.gwt.pectin.client.bean.test.AnotherBean;
+import com.pietschy.gwt.pectin.client.bean.test.SonBean1;
+import com.pietschy.gwt.pectin.client.bean.test.SonBean2;
+import com.pietschy.gwt.pectin.client.bean.test.TestBean;
+import com.pietschy.gwt.pectin.client.value.MutableValueModel;
+
+public class BeanModelProviderFactoryTest extends GWTTestCase {
+    
+    public String getModuleName()
+    {
+       return "com.pietschy.gwt.pectin.PectinTest";
+    }
+    
+    private void testWithAbstractBean(AbtractRootBean rootBean, String propertyName) {
+        String nestedProperty = "rootBean." + propertyName;
+        BeanModelProvider<TestBean> provider = BeanModelProviderFactory.get().getBeanModelProvider(TestBean.class);
+
+        BeanPropertyAccessor accessor = provider.getBeanAccessorForPropertyPath(null);
+
+        TestBean tb = new TestBean();
+        tb.setRootBean(rootBean);
+        provider.setValue(tb);
+
+        accessor.writeProperty(tb, nestedProperty, "Hello");
+        assertEquals("Hello", accessor.readProperty(tb, nestedProperty));
+        assertEquals("Hello", rootBean.toString());
+        
+    }
+    
+    public void testInheritance() {
+        testWithAbstractBean(new SonBean1(), "string1");
+        testWithAbstractBean(new SonBean2(), "string2");
+    }
+    
+
+    public void testNestedProperties() {
+        BeanModelProvider<TestBean> provider = BeanModelProviderFactory.get().getBeanModelProvider(TestBean.class);
+        MutableValueModel<String> stringValueModel = provider.getValueModel("nestedBean.string", String.class); 
+        MutableValueModel<AnotherBean> anotherBeanValueModel = provider.getValueModel("nestedBean", AnotherBean.class); 
+        
+        TestBean tb = new TestBean();
+        AnotherBean ab = new AnotherBean();
+        ab.setString("value");
+        tb.setNestedBean(ab);
+        
+        BeanPropertyAccessor accessor = provider.getBeanAccessorForPropertyPath(null);
+        assertEquals(ab, accessor.readProperty(tb, "nestedBean"));
+        assertEquals("value", accessor.readProperty(tb, "nestedBean.string"));
+        accessor.writeProperty(tb, "nestedBean.string", "hello");
+        assertEquals("hello", ab.getString());
+        ab.setString("value");
+        
+        provider.setValue(tb);
+        
+        assertEquals(ab, anotherBeanValueModel.getValue());
+        assertEquals("value", stringValueModel.getValue());
+        stringValueModel.setValue("hello");
+        provider.commit();
+        assertEquals("hello", ab.getString());
+    }
+
+}
Index: src/gwtTest/java/com/pietschy/gwt/pectin/client/PectinTestSuite.java
===================================================================
--- src/gwtTest/java/com/pietschy/gwt/pectin/client/PectinTestSuite.java	(revision 637)
+++ src/gwtTest/java/com/pietschy/gwt/pectin/client/PectinTestSuite.java	(working copy)
@@ -16,14 +16,20 @@
 
 package com.pietschy.gwt.pectin.client;
 
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
 import com.google.gwt.junit.tools.GWTTestSuite;
-import com.pietschy.gwt.pectin.client.bean.*;
+import com.pietschy.gwt.pectin.client.bean.BeanModelProviderGeneralTest;
+import com.pietschy.gwt.pectin.client.bean.BeanModelProviderGeneratedAccessorTest;
+import com.pietschy.gwt.pectin.client.bean.BeanModelProviderGeneratedMethodsTest;
+import com.pietschy.gwt.pectin.client.bean.BeanModelProviderListModelTest;
+import com.pietschy.gwt.pectin.client.bean.BeanModelProviderFactoryTest;
+import com.pietschy.gwt.pectin.client.bean.BeanModelProviderValueModelTest;
 import com.pietschy.gwt.pectin.client.binding.FormBinderMetadataTest;
 import com.pietschy.gwt.pectin.client.binding.FormBinderUiCommandTest;
 import com.pietschy.gwt.pectin.client.metadata.binding.MetadataBinderTest;
 import com.pietschy.gwt.pectin.client.style.StyleBinderTest;
-import junit.framework.Test;
-import junit.framework.TestSuite;
 
 
 /**
@@ -48,6 +54,7 @@
       gwtTestSuite.addTestSuite(BeanModelProviderValueModelTest.class);
       gwtTestSuite.addTestSuite(BeanModelProviderListModelTest.class);
       gwtTestSuite.addTestSuite(BeanModelProviderGeneralTest.class);
+      gwtTestSuite.addTestSuite(BeanModelProviderFactoryTest.class);
 
       // Binder tests
       gwtTestSuite.addTestSuite(FormBinderUiCommandTest.class);
Index: src/main/java/com/pietschy/gwt/pectin/Pectin.gwt.xml
===================================================================
--- src/main/java/com/pietschy/gwt/pectin/Pectin.gwt.xml	(revision 637)
+++ src/main/java/com/pietschy/gwt/pectin/Pectin.gwt.xml	(working copy)
@@ -20,6 +20,10 @@
       <when-type-assignable class="com.pietschy.gwt.pectin.client.bean.BeanIntrospector"/>
    </generate-with>
 
+    <generate-with class="com.pietschy.gwt.pectin.rebind.BeanModelProviderFactoryGenerator">
+      <when-type-assignable class="com.pietschy.gwt.pectin.client.bean.BeanModelProviderFactory" />
+    </generate-with>
+
    <stylesheet src="pectin/Validation.css"/>
    <stylesheet src="pectin/Metadata.css"/>
 
Index: src/main/java/com/pietschy/gwt/pectin/rebind/BeanModelProviderFactoryGenerator.java
===================================================================
--- src/main/java/com/pietschy/gwt/pectin/rebind/BeanModelProviderFactoryGenerator.java	(revision 0)
+++ src/main/java/com/pietschy/gwt/pectin/rebind/BeanModelProviderFactoryGenerator.java	(revision 0)
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2010 Benjamin Lerman
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you 
+ * may not use this file except in compliance with the License. You may 
+ * obtain a copy of the License at 
+ *      
+ *      http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
+ * implied. See the License for the specific language governing permissions 
+ * and limitations under the License. 
+ */
+package com.pietschy.gwt.pectin.rebind;
+
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.gwt.core.ext.Generator;
+import com.google.gwt.core.ext.GeneratorContext;
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.NotFoundException;
+import com.google.gwt.core.ext.typeinfo.TypeOracle;
+import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
+import com.google.gwt.user.rebind.SourceWriter;
+import com.pietschy.gwt.pectin.client.bean.BeanIntrospector;
+import com.pietschy.gwt.pectin.client.bean.BeanModelProvider;
+import com.pietschy.gwt.pectin.client.bean.BeanModelProviderFactory;
+import com.pietschy.gwt.pectin.client.bean.Beans;
+import com.pietschy.gwt.pectin.client.bean.NestedBeanIntrospector;
+
+/**
+ * the {@link Generator} to generate the implementation of {@link BeanModelProviderFactory} as well as {@link BeanIntrospector} for all types that are
+ * declared through a {@link Beans} annotation.
+ */
+public class BeanModelProviderFactoryGenerator extends Generator {
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String generate(TreeLogger logger, GeneratorContext context, String typeName) throws UnableToCompleteException {
+        BeanModelProviderCreator binder = new BeanModelProviderCreator(logger, context, typeName);
+
+        try {
+            // final all beans that are marked by @Beans
+            Set<JClassType> beans = new HashSet<JClassType>();
+            JClassType[] types = context.getTypeOracle().getTypes();
+            for (JClassType type : types) {
+                beans.addAll(getDeclaredBean(context.getTypeOracle(), type));
+            }
+
+            final String genPackageName = BeanModelProviderFactory.class.getPackage().getName();
+            final String genClassName = "BeanModelProviderFactoryImpl";
+
+            ClassSourceFileComposerFactory composer = new ClassSourceFileComposerFactory(genPackageName, genClassName);
+            composer.setSuperclass(BeanModelProviderFactory.class.getCanonicalName());
+            composer.addImport(BeanIntrospector.class.getName());
+            composer.addImport(BeanModelProvider.class.getName());
+            composer.addImport(Map.class.getName());
+            composer.addImport(HashMap.class.getName());
+            composer.addImport(NestedBeanIntrospector.class.getName());
+
+            PrintWriter pw = context.tryCreate(logger, genPackageName, genClassName);
+
+            if (pw != null) {
+                SourceWriter sw = composer.createSourceWriter(context, pw);
+
+                sw.println("private Map<String, BeanIntrospector> cache;");
+                sw.println("public BeanIntrospector getBeanIntrospector(Class<?> klass) {");
+                sw.indent();
+                sw.println("String className = klass.getName();");
+                sw.println("if (cache == null) {");
+                sw.indentln("cache = new HashMap<String, BeanIntrospector>();");
+                sw.println("}");
+                sw.println("BeanIntrospector result = cache.get(className);");
+                sw.println("if (result == null) {");
+                sw.indent();
+                StringBuffer sb = new StringBuffer();
+                boolean start = true;
+                for (JClassType bean : beans) {
+                    String name = binder.createBeanIntrostpector(bean);
+
+                    if (!start) {
+                        sw.print(" else ");
+                    } else {
+                        start = false;
+                    }
+                    sw.println("if (" + bean.getQualifiedSourceName() + ".class.getName().equals(className)) {");
+                    sw.indentln("result = new NestedBeanIntrospector(new " + name + "());");
+                    sw.indentln("cache.put(" + bean.getQualifiedSourceName() + ".class.getName(), result);");
+                    sw.indentln("return result;");
+                    sw.println("}");
+                }
+                sw.outdent();
+                sw.println("} else {");
+                sw.indent();
+                sw.println("return result;");
+                sw.outdent();
+                sw.println("}");
+                sw.println("throw new IllegalStateException(\"Unable to find a BeanIntrospector for class \" + className);");
+                sw.outdent();
+                sw.println("}");
+                sw.println(sb.toString());
+                sw.commit(logger);
+            }
+
+            return composer.getCreatedClassName();
+
+        } catch (Exception e) {
+            logger.log(TreeLogger.ERROR, "Class " + typeName + " not found.", e);
+            throw new UnableToCompleteException();
+        }
+
+    }
+
+    /**
+     * returns all types that are declared with the {@link Beans} annotation on the given type.
+     * 
+     * @param oracle the {@link TypeOracle} to resolve the beans.
+     * @param type the type to inspect.
+     * @return all types that are declared with the {@link Beans} annotation on the given type.
+     * @throws NotFoundException if an error occured.
+     */
+    private Set<JClassType> getDeclaredBean(TypeOracle oracle, JClassType type) throws NotFoundException {
+        Set<JClassType> result = new HashSet<JClassType>();
+        Beans pojo = type.getAnnotation(Beans.class);
+        if (pojo != null) {
+            for (Class<?> klass : pojo.value()) {
+                result.add(oracle.getType(klass.getCanonicalName()));
+            }
+        }
+        return result;
+    }
+
+}
Index: src/main/java/com/pietschy/gwt/pectin/rebind/BeanModelProviderCreator.java
===================================================================
--- src/main/java/com/pietschy/gwt/pectin/rebind/BeanModelProviderCreator.java	(revision 637)
+++ src/main/java/com/pietschy/gwt/pectin/rebind/BeanModelProviderCreator.java	(working copy)
@@ -16,6 +16,12 @@
 
 package com.pietschy.gwt.pectin.rebind;
 
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
 import com.google.gwt.core.ext.GeneratorContext;
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.typeinfo.JClassType;
@@ -23,15 +29,10 @@
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
 import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
 import com.google.gwt.user.rebind.SourceWriter;
+import com.pietschy.gwt.pectin.client.bean.BeanIntrospector;
 import com.pietschy.gwt.pectin.client.bean.BeanPropertyAccessor;
 import com.pietschy.gwt.pectin.client.bean.NestedTypes;
 
-import java.io.PrintWriter;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
 /**
  * TODO: Improve error messages when a property is referenced that hasn't been annotated with @NestedBean.
  */
@@ -50,7 +51,45 @@
       this.typeOracle = context.getTypeOracle();
       this.typeName = typeName;
    }
+   
+   public String createBeanIntrostpector(JClassType beanType) throws Exception {
+       final String genPackageName = beanType.getPackage().getName();
+       final String genClassName = "BeanIntrospector_" + beanType.getQualifiedSourceName().replace(".", "_");
 
+       ClassSourceFileComposerFactory composer = new ClassSourceFileComposerFactory(genPackageName, genClassName);
+       composer.addImplementedInterface(BeanIntrospector.class.getCanonicalName());
+       PrintWriter pw = context.tryCreate(logger, genPackageName, genClassName);
+
+       if (pw != null) {
+         SourceWriter writer = composer.createSourceWriter(context, pw);
+
+         BeanInfo beanInfo = new BeanInfo(typeOracle, beanType, Collections.<Class>emptySet());
+
+         writer.indent();
+
+         generateGetPropertyTypeMethod(writer, beanInfo);
+
+         writer.println();
+
+         generateGetElementTypeMethod(writer, beanInfo);
+
+         writer.println();
+
+         generateGetBeanPropertyAccessorMethod(writer, beanInfo);
+
+         writer.println();
+
+         generateGetBeanPropertyAccessorByTypeMethod(writer, beanInfo);
+
+         writer.println();
+
+         writer.commit(logger);
+
+       }
+       return composer.getCreatedClassName();
+     }
+
+   
    public String createProvider()
    {
       try
Index: src/main/java/com/pietschy/gwt/pectin/client/bean/BeanModelProvider.java
===================================================================
--- src/main/java/com/pietschy/gwt/pectin/client/bean/BeanModelProvider.java	(revision 637)
+++ src/main/java/com/pietschy/gwt/pectin/client/bean/BeanModelProvider.java	(working copy)
@@ -194,7 +194,7 @@
       throws UnknownPropertyException, UnsupportedCollectionTypeException,
              IncorrectElementTypeException, NotCollectionPropertyException
    {
-      PropertyKey<T> key = new PropertyKey<T>(valueType, propertyPath);
+      PropertyKey<T> key = getPropertyKey(valueType, propertyPath);
       BeanPropertyListModel<T> listModel = registry.getListModel(key);
 
       if (listModel == null)
@@ -228,6 +228,18 @@
    {
       return new BeanPropertyListModel<T>(sourceModel, propertyKey, accessor, converter, autoCommit);
    }
+   
+   /**
+    * returns a {@link PropertyKey} for the given type and property path.
+    * 
+    * @param <T> the type of the model.
+    * @param modelType the class of the model.
+    * @param propertyPath the property path.
+    * @return a {@link PropertyKey} for the given type and property path.
+    */
+   protected <T> PropertyKey<T> getPropertyKey( Class<T> modelType, String propertyPath) {
+      return new PropertyKey<T>(modelType, propertyPath);
+   }
 
    /**
     * Gets a {@link com.pietschy.gwt.pectin.client.value.ValueModel} for the specified bean property and the specified type.  Multiple calls to this method
@@ -252,7 +264,7 @@
          throw new IncorrectPropertyTypeException(modelType, beanPropertyType);
       }
 
-      PropertyKey<T> key = new PropertyKey<T>(modelType, propertyPath);
+      PropertyKey<T> key = getPropertyKey(modelType, propertyPath);
 
       BeanPropertyValueModel<T> valueModel = registry.getValueModel(key);
 
Index: src/main/java/com/pietschy/gwt/pectin/client/bean/NestedBeanIntrospector.java
===================================================================
--- src/main/java/com/pietschy/gwt/pectin/client/bean/NestedBeanIntrospector.java	(revision 0)
+++ src/main/java/com/pietschy/gwt/pectin/client/bean/NestedBeanIntrospector.java	(revision 0)
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2010 Benjamin Lerman
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package com.pietschy.gwt.pectin.client.bean;
+
+/**
+ * a {@link BeanIntrospector} that will use the {@link BeanModelProviderFactory} to be able to resolved nested properties.
+ */
+public class NestedBeanIntrospector implements BeanIntrospector {
+
+    /**
+     * the base {@link BeanIntrospector}.
+     */
+    private final BeanIntrospector baseBeanIntrospector;
+
+    /**
+     * Constructor.
+     * 
+     * @param baseBeanIntrospector the base {@link BeanIntrospector}.
+     */
+    public NestedBeanIntrospector(BeanIntrospector baseBeanIntrospector) {
+        this.baseBeanIntrospector = baseBeanIntrospector;
+    }
+
+    /**
+     * the {@link BeanPropertyAccessor} to return.
+     */
+    private BeanPropertyAccessor beanPropertyAccessor = null;
+
+    /**
+     * a class that represents a context of a nested property resolution.
+     */
+    private static class Context {
+        /**
+         * the current {@link BeanIntrospector}.
+         */
+        public BeanIntrospector beanIntrospector;
+        /**
+         * the current bean.
+         */
+        public Object bean;
+    }
+
+    /**
+     * returns the context for the given bean following the given path of properties.
+     * 
+     * @param bean the bean to start the resolution from.
+     * @param propertiesPath the path of property to follow.
+     * @return the context for the given bean following the given path of properties.
+     */
+    private Context getContext(Object bean, final String[] propertiesPath) {
+        Context foo = new Context();
+        foo.beanIntrospector = baseBeanIntrospector;
+        foo.bean = bean;
+
+        for (int i = 0; i < propertiesPath.length - 1; i++) {
+            final String currentProperty = propertiesPath[i];
+            if (foo.bean != null) {
+                foo.bean = foo.beanIntrospector.getBeanAccessorForPropertyPath(currentProperty).readProperty(foo.bean, currentProperty);
+            }
+            foo.beanIntrospector = BeanModelProviderFactory.get().getBeanIntrospector(foo.bean == null ? foo.beanIntrospector.getPropertyType(currentProperty) : foo.bean.getClass());
+        }
+
+        return foo;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public BeanPropertyAccessor getBeanAccessorForPropertyPath(String doNotUse) throws UnknownPropertyException {
+        if (beanPropertyAccessor == null) {
+            beanPropertyAccessor = new BeanPropertyAccessor() {
+
+                /**
+                 * {@inheritDoc}
+                 */
+                public void writeProperty(Object bean, String property, final Object value) throws UnknownPropertyException,
+                                ImmutablePropertyException, TargetBeanIsNullException {
+                    final String[] propertiesPath = property.split("\\.");
+                    Context foo = getContext(bean, propertiesPath);
+                    final String finalProperty = propertiesPath[propertiesPath.length - 1];
+                    foo.beanIntrospector.getBeanAccessorForPropertyPath(finalProperty).writeProperty(foo.bean, finalProperty, value);
+                }
+
+                /**
+                 * {@inheritDoc}
+                 */
+                public Object readProperty(Object bean, String property) throws UnknownPropertyException {
+                    final String[] propertiesPath = property.split("\\.");
+                    Context foo = getContext(bean, propertiesPath);
+                    final String finalProperty = propertiesPath[propertiesPath.length - 1];
+                    return foo.beanIntrospector.getBeanAccessorForPropertyPath(finalProperty).readProperty(foo.bean, finalProperty);
+                }
+
+                /**
+                 * {@inheritDoc}
+                 */
+                public boolean isMutable(String property) throws UnknownPropertyException {
+                    final String[] propertiesPath = property.split("\\.");
+                    final String finalProperty = propertiesPath[propertiesPath.length - 1];
+                    Context foo = getContext(null, propertiesPath);
+                    return foo.beanIntrospector.getBeanAccessorForPropertyPath(finalProperty).isMutable(finalProperty);
+                }
+            };
+        }
+        return beanPropertyAccessor;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Class<?> getElementType(String propertyPath) throws UnknownPropertyException, NotCollectionPropertyException {
+        final String[] propertiesPath = propertyPath.split("\\.");
+        final String finalProperty = propertiesPath[propertiesPath.length - 1];
+        return getContext(null, propertiesPath).beanIntrospector.getElementType(finalProperty);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Class<?> getPropertyType(String propertyPath) throws UnknownPropertyException {
+        final String[] propertiesPath = propertyPath.split("\\.");
+        final String finalProperty = propertiesPath[propertiesPath.length - 1];
+        return getContext(null, propertiesPath).beanIntrospector.getPropertyType(finalProperty);
+    }
+
+}
Index: src/main/java/com/pietschy/gwt/pectin/client/bean/DelegatingBeanModelProvider.java
===================================================================
--- src/main/java/com/pietschy/gwt/pectin/client/bean/DelegatingBeanModelProvider.java	(revision 0)
+++ src/main/java/com/pietschy/gwt/pectin/client/bean/DelegatingBeanModelProvider.java	(revision 0)
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2010 Benjamin Lerman
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you 
+ * may not use this file except in compliance with the License. You may 
+ * obtain a copy of the License at 
+ *      
+ *      http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
+ * implied. See the License for the specific language governing permissions 
+ * and limitations under the License. 
+ */
+package com.pietschy.gwt.pectin.client.bean;
+
+/**
+ * A {@link BeanModelProvider} that use a given {@link BeanIntrospector}.
+ */
+public class DelegatingBeanModelProvider<B> extends BeanModelProvider<B> {
+
+    /**
+     * the {@link BeanIntrospector} to use.
+     */
+    private final BeanIntrospector beanIntrospector;
+
+    /**
+     * @see com.pietschy.gwt.pectin.client.bean.BeanIntrospector#getBeanAccessorForPropertyPath(java.lang.String)
+     */
+    public BeanPropertyAccessor getBeanAccessorForPropertyPath(String propertyPath) throws UnknownPropertyException {
+        return this.beanIntrospector.getBeanAccessorForPropertyPath(propertyPath);
+    }
+
+    /**
+     * @see com.pietschy.gwt.pectin.client.bean.BeanIntrospector#getElementType(java.lang.String)
+     */
+    public Class<?> getElementType(String propertyPath) throws UnknownPropertyException, NotCollectionPropertyException {
+        return this.beanIntrospector.getElementType(propertyPath);
+    }
+
+    /**
+     * @see com.pietschy.gwt.pectin.client.bean.BeanIntrospector#getPropertyType(java.lang.String)
+     */
+    public Class<?> getPropertyType(String propertyPath) throws UnknownPropertyException {
+        return this.beanIntrospector.getPropertyType(propertyPath);
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param beanIntrospector the {@link BeanIntrospector} to use.
+     */
+    protected DelegatingBeanModelProvider(final BeanIntrospector beanIntrospector) {
+        super();
+        this.beanIntrospector = beanIntrospector;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected <T> PropertyKey<T> getPropertyKey(Class<T> modelType, String propertyPath) {
+        /*
+         * One returns a PropertyKey that does not handle nested properties at all. This is handled naturally by the BeanIntrospector.
+         */
+        return new PropertyKey<T>(modelType, propertyPath) {
+            void parsePath(String propertyPath) {
+                parentPath = null;
+                propertyName = propertyPath;
+            };
+        };
+    }
+
+}
Index: src/main/java/com/pietschy/gwt/pectin/client/bean/Beans.java
===================================================================
--- src/main/java/com/pietschy/gwt/pectin/client/bean/Beans.java	(revision 0)
+++ src/main/java/com/pietschy/gwt/pectin/client/bean/Beans.java	(revision 0)
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2010 Benjamin Lerman
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you 
+ * may not use this file except in compliance with the License. You may 
+ * obtain a copy of the License at 
+ *      
+ *      http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
+ * implied. See the License for the specific language governing permissions 
+ * and limitations under the License. 
+ */
+package com.pietschy.gwt.pectin.client.bean;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation can be added to any class declarations
+ * to let the generator know types that should be exposed.
+ * <p>
+ * For example, the following usage will allows to use {@link BeanModelProviderFactory} with the Address class.
+ * <pre>
+ * &#064;Beans({Address.class})
+ * public interface BeanDeclaration{}
+ * </pre>
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface Beans
+{
+   Class<?>[] value();
+}
\ No newline at end of file
Index: src/main/java/com/pietschy/gwt/pectin/client/bean/BeanModelProviderFactory.java
===================================================================
--- src/main/java/com/pietschy/gwt/pectin/client/bean/BeanModelProviderFactory.java	(revision 0)
+++ src/main/java/com/pietschy/gwt/pectin/client/bean/BeanModelProviderFactory.java	(revision 0)
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2010 Benjamin Lerman
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you 
+ * may not use this file except in compliance with the License. You may 
+ * obtain a copy of the License at 
+ *      
+ *      http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
+ * implied. See the License for the specific language governing permissions 
+ * and limitations under the License. 
+ */
+package com.pietschy.gwt.pectin.client.bean;
+
+import com.google.gwt.core.client.GWT;
+
+/**
+ * Returns {@link BeanModelProvider} for java beans.
+ */
+public abstract class BeanModelProviderFactory {
+
+    private static BeanModelProviderFactory instance;
+
+    /**
+     * Returns the singleton bean model provider factory.
+     * 
+     * @return the singleton instance
+     */
+    public static BeanModelProviderFactory get() {
+        if (instance == null) {
+            if (GWT.isClient()) {
+                instance = GWT.create(BeanModelProviderFactory.class);
+            }
+        }
+        return instance;
+    }
+
+    /**
+     * Returns the {@link BeanModelProvider} for the given class.
+     * 
+     * @param bean the bean class
+     * @return the {@link BeanModelProvider}
+     */
+    public <B> BeanModelProvider<B> getBeanModelProvider(Class<B> beanClass) {
+        return new DelegatingBeanModelProvider<B>(getBeanIntrospector(beanClass));
+    }
+
+    /**
+     * Returns the {@link BeanIntrospector} for the given bean.
+     * 
+     * @param bean the bean class
+     * @return the {@link BeanIntrospector}
+     */
+    public abstract BeanIntrospector getBeanIntrospector(Class<?> beanClass);
+    
+    /**
+     * Returns the {@link BeanModelProvider} for the given bean.
+     * 
+     * @param bean the bean class
+     * @param autoCommit whether to autocommit the changes.
+     * 
+     * @return the {@link BeanModelProvider}
+     */
+    public <B> BeanModelProvider<B> getBeanModelProvider(Class<B> bean, boolean autoCommit) {
+        BeanModelProvider<B> result = getBeanModelProvider(bean);
+        result.setAutoCommit(true);
+        return result;
+    }
+
+}
Index: src/main/java/com/pietschy/gwt/pectin/client/bean/PropertyKey.java
===================================================================
--- src/main/java/com/pietschy/gwt/pectin/client/bean/PropertyKey.java	(revision 637)
+++ src/main/java/com/pietschy/gwt/pectin/client/bean/PropertyKey.java	(working copy)
@@ -11,8 +11,8 @@
 {
    private Class<T> type;
    private String fullPath;
-   private String propertyName;
-   private String parentPath;
+   String propertyName;
+   String parentPath;
 
 
    public PropertyKey(Class<T> type, String propertyPath)
