Fixes https://jira.springsource.org/browse/ROO-1213 - Hide Property from public API, and https://jira.springsource.org/browse/ROO-1274 - Remove PropertyReference and Value.

Properties are now computed from the *Proxy classes and emitted into the generated *ProxyImpl classes.  Server side code will infer what the properties should be by reflecting over the *Proxy classes looking for bean-like property methods.  PropertyReference depends on Property so it was also removed from the public API.

Review at http://gwt-code-reviews.appspot.com/842803

Review by: amitmanjhi@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8780 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/shared/AddressProxy.java b/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/shared/AddressProxy.java
index ee85100..cdadf82 100644
--- a/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/shared/AddressProxy.java
+++ b/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/shared/AddressProxy.java
@@ -15,9 +15,8 @@
  */
 package com.google.gwt.sample.dynatablerf.shared;
 
-import com.google.gwt.requestfactory.shared.ProxyFor;
-import com.google.gwt.requestfactory.shared.Property;
 import com.google.gwt.requestfactory.shared.EntityProxy;
+import com.google.gwt.requestfactory.shared.ProxyFor;
 import com.google.gwt.sample.dynatablerf.domain.Address;
 
 /**
@@ -25,15 +24,6 @@
  */
 @ProxyFor(Address.class)
 public interface AddressProxy extends EntityProxy {
-  /*
-   * These property objects will soon no longer be necessary (and will no longer
-   * be public api).
-   */
-  Property<String> city = new Property<String>("city", "City", String.class);
-  Property<String> state = new Property<String>("state", "State", String.class);
-  Property<String> street = new Property<String>("street", "Street", String.class);
-  Property<Integer> zip = new Property<Integer>("zip", "Zip", Integer.class);
-
   String getCity();
 
   String getState();
diff --git a/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/shared/PersonProxy.java b/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/shared/PersonProxy.java
index 0e828b7..1000dd5 100644
--- a/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/shared/PersonProxy.java
+++ b/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/shared/PersonProxy.java
@@ -15,9 +15,8 @@
  */
 package com.google.gwt.sample.dynatablerf.shared;
 
-import com.google.gwt.requestfactory.shared.ProxyFor;
-import com.google.gwt.requestfactory.shared.Property;
 import com.google.gwt.requestfactory.shared.EntityProxy;
+import com.google.gwt.requestfactory.shared.ProxyFor;
 import com.google.gwt.sample.dynatablerf.domain.Person;
 
 /**
@@ -25,19 +24,6 @@
  */
 @ProxyFor(Person.class)
 public interface PersonProxy extends EntityProxy {
-  /*
-   * These property objects will soon no longer be necessary (and will no longer
-   * be public api).
-   */
-  Property<String> name = new Property<String>("name", "Name", String.class);
-  Property<String> description = new Property<String>("description",
-      "Description", String.class);
-  Property<String> schedule = new Property<String>("schedule", "Schedule",
-      String.class);
-  Property<String> note = new Property<String>("note", "Note", String.class);
-  Property<AddressProxy> address = new Property<AddressProxy>("address",
-      "Name", AddressProxy.class);
-
   AddressProxy getAddress();
 
   String getDescription();
@@ -53,5 +39,4 @@
   void setName(String name);
 
   void setNote(String note);
-
 }
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseDetails.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseDetails.java
index f2716db..9de125c 100644
--- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseDetails.java
+++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseDetails.java
@@ -16,6 +16,7 @@
 package com.google.gwt.sample.expenses.client;
 
 import com.google.gwt.cell.client.AbstractEditableCell;
+
 import com.google.gwt.cell.client.Cell;
 import com.google.gwt.cell.client.DateCell;
 import com.google.gwt.cell.client.FieldUpdater;
@@ -40,14 +41,12 @@
 import com.google.gwt.event.shared.EventBus;
 import com.google.gwt.i18n.client.DateTimeFormat;
 import com.google.gwt.i18n.client.NumberFormat;
-import com.google.gwt.requestfactory.shared.EntityProxy;
 import com.google.gwt.requestfactory.shared.EntityProxyChange;
 import com.google.gwt.requestfactory.shared.Receiver;
 import com.google.gwt.requestfactory.shared.RequestObject;
 import com.google.gwt.requestfactory.shared.SyncResult;
 import com.google.gwt.resources.client.ImageResource;
 import com.google.gwt.safehtml.client.SafeHtmlTemplates;
-import com.google.gwt.safehtml.client.SafeHtmlTemplates.Template;
 import com.google.gwt.safehtml.shared.SafeHtml;
 import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
 import com.google.gwt.safehtml.shared.SafeHtmlUtils;
@@ -545,15 +544,14 @@
     if (report != null && report.getId().equals(changed.getId())) {
       // Request the updated report.
       expensesRequestFactory.reportRequest().findReport(
-          report.getRef(ReportProxy.id)).with(ReportProxy.notes.getName()).fire(
-          new Receiver<ReportProxy>() {
-            @Override
-            public void onSuccess(ReportProxy response,
-                Set<SyncResult> syncResults) {
-              report = response;
-              setNotesEditState(false, false, response.getNotes());
-            }
-          });
+          report.getId()).fire(new Receiver<ReportProxy>() {
+        @Override
+        public void onSuccess(
+            ReportProxy response, Set<SyncResult> syncResults) {
+          report = response;
+          setNotesEditState(false, false, response.getNotes());
+        }
+      });
     }
   }
 
@@ -873,10 +871,8 @@
    * Get the columns displayed in the expense table.
    */
   private String[] getExpenseColumns() {
-    return new String[]{
-        ExpenseProxy.amount.getName(), ExpenseProxy.approval.getName(),
-        ExpenseProxy.category.getName(), ExpenseProxy.created.getName(),
-        ExpenseProxy.description.getName(), ExpenseProxy.reasonDenied.getName()};
+    return new String[]{ "amount", "approval", "category", "created", 
+        "description", "reasonDenied"};
   }
 
   /**
@@ -940,9 +936,9 @@
         refreshTimer.schedule(REFRESH_INTERVAL);
       }
     };
+
     expensesRequestFactory.expenseRequest().findExpensesByReport(
-        report.getRef(EntityProxy.id)).with(getExpenseColumns()).fire(
-        lastReceiver);
+        report.getId()).with(getExpenseColumns()).fire(lastReceiver);
   }
 
   /**
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseList.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseList.java
index e62adb3..a089a2f 100644
--- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseList.java
+++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseList.java
@@ -35,7 +35,6 @@
 import com.google.gwt.i18n.client.DateTimeFormat;
 import com.google.gwt.regexp.shared.RegExp;
 import com.google.gwt.requestfactory.shared.EntityProxyChange;
-import com.google.gwt.requestfactory.shared.Property;
 import com.google.gwt.requestfactory.shared.Receiver;
 import com.google.gwt.requestfactory.shared.SyncResult;
 import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
@@ -243,7 +242,7 @@
   /**
    * The field to sort by.
    */
-  private String orderBy = ReportProxy.purpose.getName();
+  private String orderBy = "purpose";
 
   /**
    * The set of Report keys that we have seen. When a new key is added, we
@@ -278,8 +277,7 @@
    * The columns to request with each report.
    */
   private final String[] reportColumns = new String[] {
-      ReportProxy.created.getName(), ReportProxy.purpose.getName(),
-      ReportProxy.notes.getName()};
+      "created", "purpose", "notes"};
 
   /**
    * The data provider that provides reports.
@@ -403,7 +401,7 @@
    */
   private <C> Column<ReportProxy, C> addColumn(final String text,
       final Cell<C> cell, final GetValue<ReportProxy, C> getter,
-      final Property<?> property) {
+      final String property) {
     final Column<ReportProxy, C> column = new Column<ReportProxy, C>(cell) {
       @Override
       public C getValue(ReportProxy object) {
@@ -414,10 +412,10 @@
     allHeaders.add(header);
 
     // Sort created by default.
-    if (property == ReportProxy.created) {
+    if ("created".equals(property)) {
       header.setSorted(true);
       header.setReverseSort(true);
-      orderBy = property.getName() + " DESC";
+      orderBy = "created" + " DESC";
     }
 
     header.setUpdater(new ValueUpdater<String>() {
@@ -434,7 +432,7 @@
         table.redrawHeaders();
 
         // Request sorted rows.
-        orderBy = property.getName();
+        orderBy = property;
         if (header.getReverseSort()) {
           orderBy += " DESC";
         }
@@ -484,7 +482,7 @@
           public String getValue(ReportProxy object) {
             return object.getPurpose();
           }
-        }, ReportProxy.purpose);
+        }, "purpose");
 
     // Notes column.
     addColumn("Notes", new HighlightCell(),
@@ -492,7 +490,7 @@
           public String getValue(ReportProxy object) {
             return object.getNotes();
           }
-        }, ReportProxy.notes);
+        }, "notes");
 
     // Department column.
     addColumn("Department", new TextCell(),
@@ -500,7 +498,7 @@
           public String getValue(ReportProxy object) {
             return object.getDepartment();
           }
-        }, ReportProxy.department);
+        }, "department");
 
     // Created column.
     addColumn("Created", new DateCell(DateTimeFormat.getFormat("MMM dd yyyy")),
@@ -508,7 +506,7 @@
           public Date getValue(ReportProxy object) {
             return object.getCreated();
           }
-        }, ReportProxy.created);
+        }, "created");
 
     // Spacer column.
     table.addColumn(new SpacerColumn<ReportProxy>());
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseTree.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseTree.java
index ae89ac0..b17a43e 100644
--- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseTree.java
+++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseTree.java
@@ -306,8 +306,6 @@
   }
 
   private String[] getEmployeeMenuProperties() {
-    return new String[]{
-        EmployeeProxy.displayName.getName(),
-        EmployeeProxy.userName.getName()};
+    return new String[]{"displayName", "userName"};
   }
 }
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobile.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobile.java
index 6e455ce..e2ae1bc 100644
--- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobile.java
+++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobile.java
@@ -25,7 +25,6 @@
 import com.google.gwt.requestfactory.shared.RequestEvent;
 import com.google.gwt.requestfactory.shared.SyncResult;
 import com.google.gwt.requestfactory.shared.UserInformationProxy;
-import com.google.gwt.requestfactory.shared.Value;
 import com.google.gwt.sample.expenses.client.request.EmployeeProxy;
 import com.google.gwt.sample.expenses.client.request.ExpensesRequestFactory;
 import com.google.gwt.user.client.Window;
@@ -102,7 +101,7 @@
     final ExpensesRequestFactory requestFactory = GWT.create(ExpensesRequestFactory.class);
     requestFactory.init(eventBus);
 
-    requestFactory.employeeRequest().findEmployee(Value.of(employeeId)).fire(
+    requestFactory.employeeRequest().findEmployee(employeeId).fire(
         new Receiver<EmployeeProxy>() {
           public void onSuccess(EmployeeProxy employee,
               Set<SyncResult> syncResults) {
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileExpenseDetails.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileExpenseDetails.java
index 4bdf00e..12c4d79 100644
--- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileExpenseDetails.java
+++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileExpenseDetails.java
@@ -16,12 +16,12 @@
 package com.google.gwt.sample.expenses.client;
 
 import com.google.gwt.core.client.GWT;
+
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.dom.client.Style.Display;
 import com.google.gwt.event.shared.EventBus;
 import com.google.gwt.i18n.client.DateTimeFormat;
 import com.google.gwt.requestfactory.shared.EntityProxyChange;
-import com.google.gwt.requestfactory.shared.PropertyReference;
 import com.google.gwt.requestfactory.shared.Receiver;
 import com.google.gwt.requestfactory.shared.SyncResult;
 import com.google.gwt.sample.expenses.client.request.ExpenseProxy;
@@ -107,10 +107,7 @@
   }
 
   public void onRefresh(boolean clear) {
-    PropertyReference<Long> idRef = new PropertyReference<Long>(expense,
-        ExpenseProxy.id);
-
-    requestFactory.expenseRequest().findExpense(idRef).fire(
+    requestFactory.expenseRequest().findExpense(expense.getId()).fire(
         new Receiver<List<ExpenseProxy>>() {
           public void onSuccess(List<ExpenseProxy> response, Set<SyncResult> syncResults) {
             assert response.size() == 1;
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileExpenseList.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileExpenseList.java
index d2413f8..0ff769e 100644
--- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileExpenseList.java
+++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileExpenseList.java
@@ -202,8 +202,7 @@
   }
 
   private String[] getExpenseColumns() {
-    return new String[]{
-        ExpenseProxy.description.getName(), ExpenseProxy.amount.getName()};
+    return new String[]{"description", "amount"};
   }
 
   /**
@@ -246,7 +245,7 @@
       }
     };
     requestFactory.expenseRequest().findExpensesByReport(
-        report.getRef(ReportProxy.id)).with(getExpenseColumns()).fire(
+        report.getId()).with(getExpenseColumns()).fire(
         lastReceiver);
   }
 }
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileReportList.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileReportList.java
index bb75159..a921747 100644
--- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileReportList.java
+++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileReportList.java
@@ -134,8 +134,7 @@
   }
 
   private String[] getReportColumns() {
-    return new String[]{
-        ReportProxy.created.getName(), ReportProxy.purpose.getName()};
+    return new String[]{"created", "purpose"};
   }
 
   private void requestReports() {
@@ -151,7 +150,7 @@
       }
     };
     requestFactory.reportRequest().findReportEntriesBySearch(employee.getId(),
-        "", "", ReportProxy.created.getName() + " DESC", 0, 25).with(
+        "", "", "created" + " DESC", 0, 25).with(
         getReportColumns()).fire(lastReceiver);
   }
 }
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/EmployeeProxy.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/EmployeeProxy.java
index ae6a8b2..64e00c1 100644
--- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/EmployeeProxy.java
+++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/EmployeeProxy.java
@@ -16,7 +16,7 @@
 package com.google.gwt.sample.expenses.client.request;
 
 import com.google.gwt.requestfactory.shared.ProxyFor;
-import com.google.gwt.requestfactory.shared.Property;
+
 import com.google.gwt.requestfactory.shared.EntityProxy;
 
 /**
@@ -27,16 +27,6 @@
  */
 @ProxyFor(com.google.gwt.sample.expenses.server.domain.Employee.class)
 public interface EmployeeProxy extends EntityProxy {
-
-  Property<String> userName = new Property<String>("userName", "User Name", String.class);
-  Property<String> displayName = new Property<String>("displayName", "Display Name",
-      String.class);
-  Property<String> password = new Property<String>("password", "Password", String.class);
-  Property<EmployeeProxy> supervisor = new Property<EmployeeProxy>("supervisor", "Supervisor",
-      EmployeeProxy.class);
-
-  Property<String> department = new Property<String>("department", "Department", String.class);
-
   String getDepartment();
 
   String getDisplayName();
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/EmployeeRequest.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/EmployeeRequest.java
index 4cf1f9e..2a9a13d 100644
--- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/EmployeeRequest.java
+++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/EmployeeRequest.java
@@ -16,7 +16,7 @@
 package com.google.gwt.sample.expenses.client.request;
 
 import com.google.gwt.requestfactory.shared.Instance;
-import com.google.gwt.requestfactory.shared.PropertyReference;
+
 import com.google.gwt.requestfactory.shared.ProxyListRequest;
 import com.google.gwt.requestfactory.shared.ProxyRequest;
 import com.google.gwt.requestfactory.shared.RequestObject;
@@ -52,7 +52,7 @@
   /**
    * @return a request object
    */
-  ProxyRequest<EmployeeProxy> findEmployee(PropertyReference<Long> id);
+  ProxyRequest<EmployeeProxy> findEmployee(Long id);
 
   /**
    * @return a request object
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ExpenseProxy.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ExpenseProxy.java
index e2b09c0..1ec0142 100644
--- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ExpenseProxy.java
+++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ExpenseProxy.java
@@ -16,7 +16,7 @@
 package com.google.gwt.sample.expenses.client.request;
 
 import com.google.gwt.requestfactory.shared.ProxyFor;
-import com.google.gwt.requestfactory.shared.Property;
+
 import com.google.gwt.requestfactory.shared.EntityProxy;
 
 import java.util.Date;
@@ -29,15 +29,6 @@
  */
 @ProxyFor(com.google.gwt.sample.expenses.server.domain.Expense.class)
 public interface ExpenseProxy extends EntityProxy {
-
-  Property<Double> amount = new Property<Double>("amount", "Amount", Double.class);
-  Property<String> approval = new Property<String>("approval", "Approval", String.class);
-  Property<String> category = new Property<String>("category", "Category", String.class);
-  Property<Date> created = new Property<Date>("created", "Created", Date.class);
-  Property<String> description = new Property<String>("description", "Description", String.class);
-  Property<String> reasonDenied = new Property<String>("reasonDenied", "Reason Denied", String.class);
-  Property<ReportProxy> report = new Property<ReportProxy>("report", "Report", ReportProxy.class);
-
   Double getAmount();
   
   String getApproval();
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ExpenseRequest.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ExpenseRequest.java
index ed9fd51..30f6a50 100644
--- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ExpenseRequest.java
+++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ExpenseRequest.java
@@ -16,7 +16,7 @@
 package com.google.gwt.sample.expenses.client.request;
 
 import com.google.gwt.requestfactory.shared.Instance;
-import com.google.gwt.requestfactory.shared.PropertyReference;
+
 import com.google.gwt.requestfactory.shared.ProxyListRequest;
 import com.google.gwt.requestfactory.shared.RequestObject;
 import com.google.gwt.requestfactory.shared.Service;
@@ -40,14 +40,12 @@
   /**
    * @return a request object
    */
-  ProxyListRequest<ExpenseProxy> findExpense(
-      PropertyReference<Long> id);
+  ProxyListRequest<ExpenseProxy> findExpense(Long id);
 
   /**
    * @return a request object
    */
-  ProxyListRequest<ExpenseProxy> findExpensesByReport(
-      PropertyReference<Long> reportId);
+  ProxyListRequest<ExpenseProxy> findExpensesByReport(Long id);
 
   /**
    * @return a request object
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ReportProxy.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ReportProxy.java
index 4b59199..d9293bd 100644
--- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ReportProxy.java
+++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ReportProxy.java
@@ -16,7 +16,7 @@
 package com.google.gwt.sample.expenses.client.request;
 
 import com.google.gwt.requestfactory.shared.ProxyFor;
-import com.google.gwt.requestfactory.shared.Property;
+
 import com.google.gwt.requestfactory.shared.EntityProxy;
 
 import java.util.Date;
@@ -29,16 +29,6 @@
  */
 @ProxyFor(com.google.gwt.sample.expenses.server.domain.Report.class)
 public interface ReportProxy extends EntityProxy {
-
-  Property<EmployeeProxy> approvedSupervisor = new Property<EmployeeProxy>("approvedSupervisor", "Approved Supervisor Key",
-      EmployeeProxy.class);
-  Property<Date> created = new Property<Date>("created", "Created", Date.class);
-  Property<String> department = new Property<String>("department", "Department", String.class);
-  Property<String> notes = new Property<String>("notes", "Notes", String.class);
-  Property<String> purpose = new Property<String>("purpose", "Purpose", String.class);
-  Property<EmployeeProxy> reporter = new Property<EmployeeProxy>("reporter", "Reporter",
-      EmployeeProxy.class);
-
   EmployeeProxy getApprovedSupervisor();
 
   Date getCreated();
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ReportRequest.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ReportRequest.java
index ecae945..62c4c78 100644
--- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ReportRequest.java
+++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ReportRequest.java
@@ -16,7 +16,6 @@
 package com.google.gwt.sample.expenses.client.request;
 
 import com.google.gwt.requestfactory.shared.Instance;
-import com.google.gwt.requestfactory.shared.PropertyReference;
 import com.google.gwt.requestfactory.shared.ProxyListRequest;
 import com.google.gwt.requestfactory.shared.ProxyRequest;
 import com.google.gwt.requestfactory.shared.RequestObject;
@@ -52,7 +51,7 @@
   /**
    * @return a request object
    */
-  ProxyRequest<ReportProxy> findReport(PropertyReference<Long> id);
+  ProxyRequest<ReportProxy> findReport(Long id);
 
   /**
    * @return a request object
@@ -70,8 +69,7 @@
   /**
    * @return a request object
    */
-  ProxyListRequest<ReportProxy> findReportsByEmployee(
-      PropertyReference<String> id);
+  ProxyListRequest<ReportProxy> findReportsByEmployee(Long employeeId);
 
   /**
    * @return a request object
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ui/employee/EmployeeListView.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ui/employee/EmployeeListView.java
index 0510ca5..b918184 100644
--- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ui/employee/EmployeeListView.java
+++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ui/employee/EmployeeListView.java
@@ -49,14 +49,14 @@
 
     List<PropertyColumn<EmployeeProxy, ?>> columns = new ArrayList<PropertyColumn<EmployeeProxy, ?>>();
 
-    columns.add(PropertyColumn.<EmployeeProxy> getStringPropertyColumn(EmployeeProxy.userName));
+    columns.add(PropertyColumn.<EmployeeProxy> getStringPropertyColumn("userName", "User Name"));
 
-    columns.add(PropertyColumn.<EmployeeProxy> getStringPropertyColumn(EmployeeProxy.displayName));
+    columns.add(PropertyColumn.<EmployeeProxy> getStringPropertyColumn("displayName", "Display Name"));
 
-    columns.add(PropertyColumn.<EmployeeProxy> getStringPropertyColumn(EmployeeProxy.password));
+    columns.add(PropertyColumn.<EmployeeProxy> getStringPropertyColumn("password", "Password"));
 
     columns.add(new PropertyColumn<EmployeeProxy, EmployeeProxy>(
-        EmployeeProxy.supervisor, EmployeeRenderer.instance()));
+        "supervisor", "Supervisor", EmployeeRenderer.instance()));
 
     return columns;
   }
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ui/report/ReportListView.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ui/report/ReportListView.java
index 66fe1f5..7d15040 100644
--- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ui/report/ReportListView.java
+++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ui/report/ReportListView.java
@@ -56,16 +56,16 @@
 
     List<PropertyColumn<ReportProxy, ?>> columns = new ArrayList<PropertyColumn<ReportProxy, ?>>();
 
-    columns.add(new PropertyColumn<ReportProxy, Date>(ReportProxy.created,
+    columns.add(new PropertyColumn<ReportProxy, Date>("created", "Created",
         new DateTimeFormatRenderer(DateTimeFormat.getShortDateFormat())));
 
-    columns.add(PropertyColumn.<ReportProxy> getStringPropertyColumn(ReportProxy.purpose));
+    columns.add(PropertyColumn.<ReportProxy> getStringPropertyColumn("purpose", "Purpose"));
 
     columns.add(new PropertyColumn<ReportProxy, EmployeeProxy>(
-        ReportProxy.reporter, EmployeeRenderer.instance()));
+        "reporter", "Reporter", EmployeeRenderer.instance()));
 
     columns.add(new PropertyColumn<ReportProxy, EmployeeProxy>(
-        ReportProxy.approvedSupervisor, EmployeeRenderer.instance()));
+        "approvedSupervisor", "Approved Supervisor Key", EmployeeRenderer.instance()));
 
     return columns;
   }
diff --git a/user/src/com/google/gwt/app/place/AbstractProxyEditActivity.java b/user/src/com/google/gwt/app/place/AbstractProxyEditActivity.java
index c130357..ac37c30 100644
--- a/user/src/com/google/gwt/app/place/AbstractProxyEditActivity.java
+++ b/user/src/com/google/gwt/app/place/AbstractProxyEditActivity.java
@@ -16,6 +16,7 @@
 package com.google.gwt.app.place;
 
 import com.google.gwt.app.place.ProxyPlace.Operation;
+
 import com.google.gwt.event.shared.EventBus;
 import com.google.gwt.requestfactory.shared.EntityProxy;
 import com.google.gwt.requestfactory.shared.EntityProxyId;
@@ -24,7 +25,6 @@
 import com.google.gwt.requestfactory.shared.RequestFactory;
 import com.google.gwt.requestfactory.shared.RequestObject;
 import com.google.gwt.requestfactory.shared.SyncResult;
-import com.google.gwt.requestfactory.shared.Value;
 import com.google.gwt.requestfactory.shared.Violation;
 import com.google.gwt.user.client.Window;
 import com.google.gwt.user.client.ui.AcceptsOneWidget;
@@ -167,7 +167,7 @@
       stableId = tempRecord.stableId();
       doStart(display, tempRecord);
     } else {
-      ProxyRequest<P> findRequest = getFindRequest(Value.of(getRecord().getId()));
+      ProxyRequest<P> findRequest = getFindRequest(getRecord().getId());
       findRequest.with(getView().getPaths()).fire(new Receiver<P>() {
         public void onSuccess(P record, Set<SyncResult> syncResults) {
           if (AbstractProxyEditActivity.this.display != null) {
@@ -199,7 +199,7 @@
   /**
    * Called to fetch the details of the edited record.
    */
-  protected abstract ProxyRequest<P> getFindRequest(Value<Long> id);
+  protected abstract ProxyRequest<P> getFindRequest(Long id);
 
   protected abstract RequestObject<Void> getPersistRequest(P record);
 
diff --git a/user/src/com/google/gwt/app/place/PropertyColumn.java b/user/src/com/google/gwt/app/place/PropertyColumn.java
index 8c73cf2..44ee42f 100644
--- a/user/src/com/google/gwt/app/place/PropertyColumn.java
+++ b/user/src/com/google/gwt/app/place/PropertyColumn.java
@@ -15,7 +15,7 @@
  */
 package com.google.gwt.app.place;
 
-import com.google.gwt.requestfactory.shared.Property;
+import com.google.gwt.requestfactory.client.impl.ProxyImpl;
 import com.google.gwt.requestfactory.shared.EntityProxy;
 import com.google.gwt.text.shared.PassthroughRenderer;
 import com.google.gwt.text.shared.Renderer;
@@ -36,29 +36,32 @@
  */
 public class PropertyColumn<R extends EntityProxy, T> extends TextColumn<R> {
   public static <R extends EntityProxy> PropertyColumn<R, String> getStringPropertyColumn(
-      Property<String> property) {
-    return new PropertyColumn<R, String>(property,
+      String property, String displayName) {
+    return new PropertyColumn<R, String>(property, displayName,
         PassthroughRenderer.instance());
   }
 
+  private String displayName;
   private final Renderer<T> renderer;
-  private final Property<T> property;
+  private final String property;
   private final String[] paths;
 
-  public PropertyColumn(Property<T> property, ProxyRenderer<T> renderer) {
+  public PropertyColumn(String property, String displayName, ProxyRenderer<T> renderer) {
+    this.displayName = displayName;
     this.property = property;
     this.renderer = renderer;
     this.paths = pathinate(property, renderer);
   }
 
-  public PropertyColumn(Property<T> property, Renderer<T> renderer) {
+  public PropertyColumn(String property, String displayName, Renderer<T> renderer) {
+    this.displayName = displayName;
     this.property = property;
     this.renderer = renderer;
-    this.paths = new String[] {property.getName()};
+    this.paths = new String[] {property};
   }
 
   public String getDisplayName() {
-    return property.getDisplayName();
+    return displayName;
   }
 
   public String[] getPaths() {
@@ -67,14 +70,15 @@
 
   @Override
   public String getValue(R object) {
-    return renderer.render(object.get(property));
+    ProxyImpl proxyImpl = (ProxyImpl) object;
+    return renderer.render(proxyImpl.<T>get(property, String.class));
   }
 
-  private String[] pathinate(Property<T> property, ProxyRenderer<T> renderer) {
+  private String[] pathinate(String property, ProxyRenderer<T> renderer) {
     String[] rtn = new String[renderer.getPaths().length];
     int i = 0;
     for (String rendererPath : renderer.getPaths()) {
-      rtn[i++] = property.getName() + "." + rendererPath;
+      rtn[i++] = property + "." + rendererPath;
     }
 
     return rtn;
diff --git a/user/src/com/google/gwt/app/rebind/EditorSupportGenerator.java b/user/src/com/google/gwt/app/rebind/EditorSupportGenerator.java
index 2ee5bee..08a2a42 100644
--- a/user/src/com/google/gwt/app/rebind/EditorSupportGenerator.java
+++ b/user/src/com/google/gwt/app/rebind/EditorSupportGenerator.java
@@ -30,7 +30,7 @@
 import com.google.gwt.dom.client.Style.FontWeight;
 import com.google.gwt.event.logical.shared.ValueChangeEvent;
 import com.google.gwt.event.logical.shared.ValueChangeHandler;
-import com.google.gwt.requestfactory.shared.Property;
+import com.google.gwt.requestfactory.client.impl.Property;
 import com.google.gwt.requestfactory.shared.EntityProxy;
 import com.google.gwt.uibinder.client.UiField;
 import com.google.gwt.user.client.TakesValue;
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequest.java
index 5832b5b..1d88738 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequest.java
@@ -20,7 +20,6 @@
 import com.google.gwt.requestfactory.client.impl.DeltaValueStoreJsonImpl.ReturnRecord;
 import com.google.gwt.requestfactory.shared.EntityProxy;
 import com.google.gwt.requestfactory.shared.EntityProxyId;
-import com.google.gwt.requestfactory.shared.Property;
 import com.google.gwt.requestfactory.shared.Receiver;
 import com.google.gwt.requestfactory.shared.RequestObject;
 import com.google.gwt.requestfactory.shared.ServerFailure;
@@ -202,4 +201,4 @@
       this.@com.google.gwt.requestfactory.client.impl.AbstractRequest::pushToValueStore(Ljava/lang/String;Lcom/google/gwt/core/client/JavaScriptObject;)(schemaAndId[0], jso);
     }
   }-*/;
-}
\ No newline at end of file
+}
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImpl.java b/user/src/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImpl.java
index 9ca8896..0bb6961 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImpl.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImpl.java
@@ -20,7 +20,6 @@
 import com.google.gwt.requestfactory.client.SyncResultImpl;
 import com.google.gwt.requestfactory.shared.EntityProxy;
 import com.google.gwt.requestfactory.shared.EntityProxyId;
-import com.google.gwt.requestfactory.shared.Property;
 import com.google.gwt.requestfactory.shared.SyncResult;
 import com.google.gwt.requestfactory.shared.WriteOperation;
 
@@ -164,7 +163,7 @@
         ProxyJsoImpl value = creates.get(futureKey);
         if (value != null) {
           copy.merge(value);
-          copy.set(EntityProxy.id, newRecord.getId());
+          copy.set(ProxyImpl.id, newRecord.getId());
         }
         ProxyJsoImpl masterRecord = master.records.get(futureKey);
         assert masterRecord == null;
diff --git a/user/src/com/google/gwt/requestfactory/shared/EnumProperty.java b/user/src/com/google/gwt/requestfactory/client/impl/EnumProperty.java
similarity index 96%
rename from user/src/com/google/gwt/requestfactory/shared/EnumProperty.java
rename to user/src/com/google/gwt/requestfactory/client/impl/EnumProperty.java
index ae356e8..e5b6059 100644
--- a/user/src/com/google/gwt/requestfactory/shared/EnumProperty.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/EnumProperty.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.requestfactory.shared;
+package com.google.gwt.requestfactory.client.impl;
 
 /**
  * <p>
diff --git a/user/src/com/google/gwt/requestfactory/shared/Property.java b/user/src/com/google/gwt/requestfactory/client/impl/Property.java
similarity index 96%
rename from user/src/com/google/gwt/requestfactory/shared/Property.java
rename to user/src/com/google/gwt/requestfactory/client/impl/Property.java
index ebcf906..805518a 100644
--- a/user/src/com/google/gwt/requestfactory/shared/Property.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/Property.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.requestfactory.shared;
+package com.google.gwt.requestfactory.client.impl;
 
 /**
  * <p>
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/ProxyImpl.java b/user/src/com/google/gwt/requestfactory/client/impl/ProxyImpl.java
index 1024858..b35287f 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/ProxyImpl.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/ProxyImpl.java
@@ -17,8 +17,6 @@
 
 import com.google.gwt.requestfactory.shared.EntityProxy;
 import com.google.gwt.requestfactory.shared.EntityProxyId;
-import com.google.gwt.requestfactory.shared.Property;
-import com.google.gwt.requestfactory.shared.PropertyReference;
 
 /**
  * <p>
@@ -35,6 +33,9 @@
  */
 public class ProxyImpl implements EntityProxy {
 
+  static final Property<Long> id = new Property<Long>("id", Long.class);
+  static final Property<Integer> version = new Property<Integer>("version", Integer.class);
+
   protected static String getWireFormatId(Long id, boolean isFuture,
       ProxySchema<?> schema) {
     return id + "-" + (isFuture ? "IS" : "NO") + "-" + schema.getToken();
@@ -44,7 +45,7 @@
   private final boolean isFuture;
 
   private DeltaValueStoreJsonImpl deltaValueStore;
-
+  
   /**
    * For use by generated subclasses only. Other code should use
    * {@link ProxySchema#create(ProxyJsoImpl, boolean)}, typically:
@@ -67,18 +68,28 @@
     return jso;
   }
 
+  /**
+   * Get this proxy's value for the given property. Behavior is undefined if
+   * the proxy has no such property, or if the property has never been set. It
+   * is unusual to call this method directly. Rather it is expected to be called
+   * by bean-style getter methods provided by implementing classes.
+   * 
+   * @param <V> the type of the property's value
+   * @param property the property to fetch
+   * @return the value
+   */
   public <V> V get(Property<V> property) {
     return jso.get(property);
   }
 
+  public <V> V get(String propertyName, Class<?> propertyType) {
+    return jso.get(propertyName, propertyType);
+  }
+  
   public Long getId() {
     return jso.getId();
   }
 
-  public <V> PropertyReference<V> getRef(Property<V> property) {
-    return jso.getRef(property);
-  }
-
   public ProxySchema<?> getSchema() {
     return jso.getSchema();
   }
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/ProxyJsoImpl.java b/user/src/com/google/gwt/requestfactory/client/impl/ProxyJsoImpl.java
index 7594258..4de4420 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/ProxyJsoImpl.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/ProxyJsoImpl.java
@@ -20,9 +20,6 @@
 import com.google.gwt.core.client.JsArray;
 import com.google.gwt.requestfactory.shared.EntityProxy;
 import com.google.gwt.requestfactory.shared.EntityProxyId;
-import com.google.gwt.requestfactory.shared.EnumProperty;
-import com.google.gwt.requestfactory.shared.Property;
-import com.google.gwt.requestfactory.shared.PropertyReference;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -65,17 +62,17 @@
   public static ProxyJsoImpl create(Long id, Integer version,
       ProxySchema<?> schema, RequestFactoryJsonImpl requestFactory) {
     ProxyJsoImpl rtn = createEmpty();
-    rtn.set(EntityProxy.id, id);
-    rtn.set(EntityProxy.version, version);
+    rtn.set(ProxyImpl.id, id);
+    rtn.set(ProxyImpl.version, version);
     return create(rtn, schema, requestFactory);
   }
 
   public static ProxyJsoImpl emptyCopy(ProxyJsoImpl jso) {
-    Long id = jso.get(EntityProxy.id);
-    Integer version = jso.get(EntityProxy.version);
+    Long tempId = jso.get(ProxyImpl.id);
+    Integer tempVersion = jso.get(ProxyImpl.version);
     ProxySchema<?> schema = jso.getSchema();
 
-    ProxyJsoImpl copy = create(id, version, schema, jso.getRequestFactory());
+    ProxyJsoImpl copy = create(tempId, tempVersion, schema, jso.getRequestFactory());
     return copy;
   }
 
@@ -93,51 +90,58 @@
     delete this[name];
   }-*/;
 
-  @SuppressWarnings("unchecked")
   public final <V> V get(Property<V> property) {
-    if (isNullOrUndefined(property.getName())) {
+    String name = property.getName();
+    Class<V> type = property.getType();
+    
+    return get(name, type);
+  }
+
+  @SuppressWarnings("unchecked")
+  public final <V> V get(String name, Class<?> type) {
+    if (isNullOrUndefined(name)) {
       return null;
     }
-
+    
     try {
-      if (Boolean.class.equals(property.getType())) {
-        return (V) Boolean.valueOf(getBoolean(property.getName()));
+      if (Boolean.class.equals(type)) {
+        return (V) Boolean.valueOf(getBoolean(name));
       }
-      if (Character.class.equals(property.getType())) {
-        return (V) Character.valueOf(String.valueOf(get(property.getName())).charAt(
+      if (Character.class.equals(type)) {
+        return (V) Character.valueOf(String.valueOf(get(name)).charAt(
             0));
       }
-      if (Byte.class.equals(property.getType())) {
-        return (V) Byte.valueOf((byte) getInt(property.getName()));
+      if (Byte.class.equals(type)) {
+        return (V) Byte.valueOf((byte) getInt(name));
       }
-      if (Short.class.equals(property.getType())) {
-        return (V) Short.valueOf((short) getInt(property.getName()));
+      if (Short.class.equals(type)) {
+        return (V) Short.valueOf((short) getInt(name));
       }
-      if (Float.class.equals(property.getType())) {
-        return (V) Float.valueOf((float) getDouble(property.getName()));
+      if (Float.class.equals(type)) {
+        return (V) Float.valueOf((float) getDouble(name));
       }
-      if (BigInteger.class.equals(property.getType())) {
-        return (V) new BigDecimal((String) get(property.getName())).toBigInteger();
+      if (BigInteger.class.equals(type)) {
+        return (V) new BigDecimal((String) get(name)).toBigInteger();
       }
-      if (BigDecimal.class.equals(property.getType())) {
-        return (V) new BigDecimal((String) get(property.getName()));
+      if (BigDecimal.class.equals(type)) {
+        return (V) new BigDecimal((String) get(name));
       }
-      if (Integer.class.equals(property.getType())) {
-        return (V) Integer.valueOf(getInt(property.getName()));
+      if (Integer.class.equals(type)) {
+        return (V) Integer.valueOf(getInt(name));
       }
-      if (Long.class.equals(property.getType())) {
-        return (V) Long.valueOf((String) get(property.getName()));
+      if (Long.class.equals(type)) {
+        return (V) Long.valueOf((String) get(name));
       }
-      if (Double.class.equals(property.getType())) {
-        if (!isDefined(property.getName())) {
+      if (Double.class.equals(type)) {
+        if (!isDefined(name)) {
           return (V) new Double(0.0);
         }
-        return (V) Double.valueOf(getDouble(property.getName()));
+        return (V) Double.valueOf(getDouble(name));
       }
-      if (Date.class.equals(property.getType())) {
+      if (Date.class.equals(type)) {
         double millis = new Date().getTime();
-        if (isDefined(property.getName())) {
-          millis = Double.parseDouble((String) get(property.getName()));
+        if (isDefined(name)) {
+          millis = Double.parseDouble((String) get(name));
         }
         if (GWT.isScript()) {
           return (V) dateForDouble(millis);
@@ -147,15 +151,15 @@
         }
       }
     } catch (final Exception ex) {
-      throw new IllegalStateException("Property  " + property.getName()
-          + " has invalid " + " value " + get(property.getName())
-          + " for type " + property.getType());
+      throw new IllegalStateException("Property  " + name
+          + " has invalid " + " value " + get(name)
+          + " for type " + type);
     }
 
-    if (property instanceof EnumProperty) {
-      EnumProperty<V> eProperty = (EnumProperty<V>) property;
-      Enum<?>[] values = (Enum[]) eProperty.getValues();
-      int ordinal = getInt(property.getName());
+    if (type.isEnum()) {
+      // TODO: Can't we just use Enum.valueOf()?
+      Enum<?>[] values = (Enum[]) type.getEnumConstants();
+      int ordinal = getInt(name);
       for (Enum<?> value : values) {
         if (ordinal == value.ordinal()) {
           return (V) value;
@@ -163,14 +167,14 @@
       }
     }
 
-    if (String.class == property.getType()) {
-      return (V) get(property.getName());
+    if (String.class == type) {
+      return (V) get(name);
     }
     // at this point, we checked all the known primitive/value types we support
     // TODO: handle embedded types, List, Set, Map
 
     // else, it must be a record type
-    String relatedId = (String) get(property.getName());
+    String relatedId = (String) get(name);
     if (relatedId == null) {
       return null;
     } else {
@@ -188,11 +192,7 @@
   }-*/;
 
   public final Long getId() {
-    return this.get(id);
-  }
-
-  public final <V> PropertyReference<V> getRef(Property<V> property) {
-    return new PropertyReference<V>(this, property);
+    return this.get(ProxyImpl.id);
   }
 
   public final native RequestFactoryJsonImpl getRequestFactory() /*-{
@@ -204,7 +204,7 @@
   }-*/;
   
   public final Integer getVersion() {
-    return this.get(version);
+    return this.get(ProxyImpl.version);
   }
 
   /**
@@ -216,7 +216,7 @@
 
   public final boolean isEmpty() {
     for (Property<?> property : getSchema().allProperties()) {
-      if ((property != EntityProxy.id) && (property != EntityProxy.version)
+      if ((property != ProxyImpl.id) && (property != ProxyImpl.version)
           && (isDefined(property.getName()))) {
         return false;
       }
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/ProxySchema.java b/user/src/com/google/gwt/requestfactory/client/impl/ProxySchema.java
index dcb5a3f..d6a3501 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/ProxySchema.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/ProxySchema.java
@@ -17,7 +17,6 @@
 
 import com.google.gwt.requestfactory.shared.EntityProxy;
 import com.google.gwt.requestfactory.shared.EntityProxyChange;
-import com.google.gwt.requestfactory.shared.Property;
 import com.google.gwt.requestfactory.shared.WriteOperation;
 
 import java.util.Collections;
@@ -46,8 +45,8 @@
   
   {
     Set<Property<?>> set = new HashSet<Property<?>>();
-    set.add(EntityProxy.id);
-    set.add(EntityProxy.version);
+    set.add(ProxyImpl.id);
+    set.add(ProxyImpl.version);
     allProperties = Collections.unmodifiableSet(set);
   }
   
diff --git a/user/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java b/user/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java
index 3158f18..50a05b4 100644
--- a/user/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java
+++ b/user/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java
@@ -20,10 +20,10 @@
 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.JField;
 import com.google.gwt.core.ext.typeinfo.JMethod;
 import com.google.gwt.core.ext.typeinfo.JParameter;
 import com.google.gwt.core.ext.typeinfo.JParameterizedType;
+import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
 import com.google.gwt.core.ext.typeinfo.JType;
 import com.google.gwt.core.ext.typeinfo.NotFoundException;
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
@@ -44,6 +44,8 @@
 import com.google.gwt.requestfactory.client.impl.AbstractShortRequest;
 import com.google.gwt.requestfactory.client.impl.AbstractStringRequest;
 import com.google.gwt.requestfactory.client.impl.AbstractVoidRequest;
+import com.google.gwt.requestfactory.client.impl.EnumProperty;
+import com.google.gwt.requestfactory.client.impl.Property;
 import com.google.gwt.requestfactory.client.impl.ProxyImpl;
 import com.google.gwt.requestfactory.client.impl.ProxyJsoImpl;
 import com.google.gwt.requestfactory.client.impl.ProxySchema;
@@ -52,8 +54,6 @@
 import com.google.gwt.requestfactory.server.ReflectionBasedOperationRegistry;
 import com.google.gwt.requestfactory.shared.EntityProxy;
 import com.google.gwt.requestfactory.shared.EntityProxyId;
-import com.google.gwt.requestfactory.shared.Property;
-import com.google.gwt.requestfactory.shared.PropertyReference;
 import com.google.gwt.requestfactory.shared.ProxyListRequest;
 import com.google.gwt.requestfactory.shared.ProxyRequest;
 import com.google.gwt.requestfactory.shared.RequestData;
@@ -62,13 +62,16 @@
 import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
 import com.google.gwt.user.rebind.SourceWriter;
 
+import java.beans.Introspector;
 import java.io.PrintWriter;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -83,6 +86,24 @@
  */
 public class RequestFactoryGenerator extends Generator {
 
+  private static class EntityProperty {
+    private final String name;
+    private final JType type;
+
+    public EntityProperty(String name, JType type) {
+      this.name = name;
+      this.type = type;
+    }
+
+    public String getName() {
+      return name;
+    }
+
+    public JType getType() {
+      return type;
+    }
+  }
+
   private final Set<JClassType> generatedProxyTypes = new HashSet<JClassType>();
 
   @Override
@@ -133,6 +154,36 @@
     return name.substring(0, 1).toUpperCase() + name.substring(1);
   }
 
+  /**
+   * Compute the list of EntityProperties from the given proxy type. Properties
+   * contributed from EntityProxy are excluded.
+   */
+  private List<EntityProperty> computeEntityPropertiesFromProxyType(
+      JClassType publicProxyType) {
+    List<EntityProperty> entityProperties = new ArrayList<RequestFactoryGenerator.EntityProperty>();
+    Set<String> propertyNames = new HashSet<String>();
+    JClassType entityProxyType = publicProxyType.getOracle().findType(
+        EntityProxy.class.getCanonicalName());
+
+    for (JMethod method : publicProxyType.getOverridableMethods()) {
+      if (method.getEnclosingType() == entityProxyType) {
+        // Properties on EntityProxy are handled by ProxyJsoImpl
+        continue;
+      }
+
+      EntityProperty entityProperty = maybeComputePropertyFromMethod(method);
+      if (entityProperty != null) {
+        String propertyName = entityProperty.getName();
+        if (!propertyNames.contains(propertyName)) {
+          propertyNames.add(propertyName);
+          entityProperties.add(entityProperty);
+        }
+      }
+    }
+
+    return entityProperties;
+  }
+
   private void ensureProxyType(TreeLogger logger,
       GeneratorContext generatorContext, String packageName,
       JClassType publicProxyType) throws UnableToCompleteException {
@@ -163,6 +214,7 @@
       f.addImport(AbstractJsonObjectRequest.class.getName());
       f.addImport(RequestFactoryJsonImpl.class.getName());
       f.addImport(Property.class.getName());
+      f.addImport(EnumProperty.class.getName());
       f.addImport(EntityProxy.class.getName());
       f.addImport(ProxyImpl.class.getName());
       f.addImport(ProxyJsoImpl.class.getName());
@@ -176,11 +228,35 @@
       f.setSuperclass(ProxyImpl.class.getSimpleName());
       f.addImplementedInterface(publicProxyType.getName());
 
+      List<EntityProperty> entityProperties = computeEntityPropertiesFromProxyType(publicProxyType);
+      for (EntityProperty entityProperty : entityProperties) {
+        JType type = entityProperty.getType();
+        if (type.isPrimitive() == null) {
+          f.addImport(type.getErasedType().getQualifiedSourceName());
+        }
+      }
+
       SourceWriter sw = f.createSourceWriter(generatorContext, pw);
       sw.println();
 
-      JClassType propertyType = printSchema(typeOracle, publicProxyType,
-          proxyImplTypeName, sw);
+      // write the Property fields
+      for (EntityProperty entityProperty : entityProperties) {
+        sw.println();
+        String name = entityProperty.getName();
+        if (entityProperty.getType().isEnum() != null) {
+          sw.println(String.format(
+              "private static final Property<%1$s> %2$s = new EnumProperty<%1$s>(\"%2$s\", %1$s.class, %1$s.values());",
+              entityProperty.getType().getSimpleSourceName(),
+              name));
+        } else {
+          sw.println(String.format(
+              "private static final Property<%1$s> %2$s = new Property<%1$s>(\"%2$s\", \"%3$s\", %1$s.class);",
+              entityProperty.getType().getSimpleSourceName(), name,
+              capitalize(name)));
+        }
+      }
+
+      printSchema(typeOracle, publicProxyType, proxyImplTypeName, sw);
 
       sw.println();
       String simpleImplName = publicProxyType.getSimpleSourceName() + "Impl";
@@ -201,55 +277,37 @@
       sw.println("}");
 
       // getter methods
-      for (JField field : publicProxyType.getFields()) {
-        JType fieldType = field.getType();
-        if (propertyType.getErasedType() == fieldType.getErasedType()) {
-          JParameterizedType parameterized = fieldType.isParameterized();
-          if (parameterized == null) {
-            logger.log(TreeLogger.ERROR, fieldType
-                + " must have its param type set.");
-            throw new UnableToCompleteException();
-          }
-          JClassType returnType = parameterized.getTypeArgs()[0];
-          sw.println();
-          sw.println(String.format("public %s get%s() {",
-              returnType.getQualifiedSourceName(), capitalize(field.getName())));
-          sw.indent();
-          sw.println(String.format("return get(%s);", field.getName()));
-          sw.outdent();
-          sw.println("}");
-          /*
-           * Because a Proxy A may relate to B which relates to C, we need to
-           * ensure transitively.
-           */
-          if (isProxyType(typeOracle, returnType)) {
-            transitiveDeps.add(returnType);
-          }
+      for (EntityProperty entityProperty : entityProperties) {
+        JClassType returnType = entityProperty.getType().isClassOrInterface();
+        sw.println();
+        sw.println(String.format("public %s get%s() {",
+            returnType.getQualifiedSourceName(),
+            capitalize(entityProperty.getName())));
+        sw.indent();
+        sw.println(String.format("return get(%s);", entityProperty.getName()));
+        sw.outdent();
+        sw.println("}");
+
+        /*
+         * Because a Proxy A may relate to B which relates to C, we need to
+         * ensure transitively.
+         */
+        if (isProxyType(typeOracle, returnType)) {
+          transitiveDeps.add(returnType);
         }
       }
 
       // setter methods
-      for (JField field : publicProxyType.getFields()) {
-        JType fieldType = field.getType();
-        if (propertyType.getErasedType() == fieldType.getErasedType()) {
-          JParameterizedType parameterized = fieldType.isParameterized();
-          if (parameterized == null) {
-            logger.log(TreeLogger.ERROR, fieldType
-                + " must have its param type set.");
-            throw new UnableToCompleteException();
-          }
-          JClassType returnType = parameterized.getTypeArgs()[0];
-          sw.println();
-          String varName = field.getName();
-          sw.println(String.format("public void set%s(%s %s) {",
-              capitalize(field.getName()), returnType.getQualifiedSourceName(),
-              varName));
-          sw.indent();
-          sw.println(String.format("set(this.%s, this, %s);", field.getName(),
-              varName));
-          sw.outdent();
-          sw.println("}");
-        }
+      for (EntityProperty entityProperty : entityProperties) {
+        JClassType returnType = entityProperty.getType().isClassOrInterface();
+        sw.println();
+        String varName = entityProperty.getName();
+        sw.println(String.format("public void set%s(%s %s) {",
+            capitalize(varName), returnType.getQualifiedSourceName(), varName));
+        sw.indent();
+        sw.println(String.format("set(this.%s, this, %s);", varName, varName));
+        sw.outdent();
+        sw.println("}");
       }
 
       sw.outdent();
@@ -302,9 +360,8 @@
       JType returnType = method.getReturnType();
       if (null == returnType) {
         logger.log(TreeLogger.ERROR, String.format(
-            "Illegal return type for %s. Methods of %s "
-                + "must return interfaces, found void", method.getName(),
-            interfaceType.getName()));
+            "Illegal return type for %s. Methods of %s must return interfaces, found void",
+                method.getName(), interfaceType.getName()));
         throw new UnableToCompleteException();
       }
       JClassType asInterface = returnType.isInterface();
@@ -648,8 +705,6 @@
       JClassType classType = parameter.getType().isClassOrInterface();
 
       JType paramType = parameter.getType();
-      boolean isRef = PropertyReference.class.getName().equals(
-          paramType.getQualifiedBinaryName());
       JParameterizedType params = paramType.isParameterized();
       if (params != null) {
         classType = params.getTypeArgs()[0];
@@ -659,12 +714,6 @@
         sb.append("((" + classType.getQualifiedBinaryName() + "Impl" + ")");
       }
       sb.append(parameter.getName());
-      // TODO No. This defeats the entire purpose of PropertyReference. It's
-      // supposed
-      // to be dereferenced server side, not client side.
-      if (isRef) {
-        sb.append(".get()");
-      }
       if (classType != null
           && classType.isAssignableTo(typeOracle.findType(EntityProxy.class.getName()))) {
         sb.append(").getWireFormatId()");
@@ -746,6 +795,34 @@
   }
 
   /**
+   * Returns an {@link EntityProperty} if the method looks like a bean property
+   * accessor or <code>null</code>.
+   */
+  private EntityProperty maybeComputePropertyFromMethod(JMethod method) {
+    String propertyName = null;
+    JType propertyType = null;
+    String methodName = method.getName();
+    if (methodName.startsWith("get")) {
+      propertyName = Introspector.decapitalize(methodName.substring(3));
+      propertyType = method.getReturnType();
+    } else if (methodName.startsWith("set")) {
+      propertyName = Introspector.decapitalize(methodName.substring(3));
+      JParameter[] parameters = method.getParameters();
+      if (parameters.length > 0) {
+        propertyType = parameters[parameters.length - 1].getType();
+      }
+    }
+
+    // TODO: handle boolean "is" getters, indexed properties?
+
+    if (propertyType != null && propertyType != JPrimitiveType.VOID) {
+      return new EntityProperty(propertyName, propertyType);
+    }
+
+    return null;
+  }
+
+  /**
    * Prints a ListRequestImpl or ObjectRequestImpl class.
    */
   private void printRequestImplClass(SourceWriter sw, JClassType returnType,
@@ -810,10 +887,9 @@
       throw new RuntimeException(e);
     }
 
-    for (JField field : publicProxyType.getFields()) {
-      if (propertyType.getErasedType() == field.getType().getErasedType()) {
-        sw.println(String.format("set.add(%s);", field.getName()));
-      }
+    List<EntityProperty> entityProperties = computeEntityPropertiesFromProxyType(publicProxyType);
+    for (EntityProperty entityProperty : entityProperties) {
+      sw.println(String.format("set.add(%s);", entityProperty.getName()));
     }
 
     sw.println("allProperties = Collections.unmodifiableSet(set);");
diff --git a/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java b/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java
index 21f0c21..2a2ad97 100644
--- a/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java
+++ b/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java
@@ -15,9 +15,8 @@
  */
 package com.google.gwt.requestfactory.server;
 
+import com.google.gwt.requestfactory.client.impl.Property;
 import com.google.gwt.requestfactory.shared.ProxyFor;
-import com.google.gwt.requestfactory.shared.Property;
-import com.google.gwt.requestfactory.shared.PropertyReference;
 import com.google.gwt.requestfactory.shared.EntityProxy;
 import com.google.gwt.requestfactory.shared.RequestData;
 import com.google.gwt.requestfactory.shared.WriteOperation;
@@ -26,11 +25,11 @@
 import org.json.JSONException;
 import org.json.JSONObject;
 
+import java.beans.Introspector;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -40,8 +39,10 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 import java.util.logging.Logger;
 
@@ -145,23 +146,23 @@
   private Map<EntityKey, SerializedEntity> beforeDataMap = new HashMap<EntityKey, SerializedEntity>();
   private Map<EntityKey, EntityData> afterDvsDataMap = new HashMap<EntityKey, EntityData>();
 
-  public Collection<Property<?>> allProperties(Class<? extends EntityProxy> clazz) throws IllegalArgumentException, IllegalAccessException {
+  @SuppressWarnings({"unchecked", "rawtypes"})
+  public Collection<Property<?>> allProperties(
+      Class<? extends EntityProxy> clazz) throws IllegalArgumentException {
     Set<Property<?>> rtn = new HashSet<Property<?>>();
-    for (Field f : clazz.getFields()) {
-      if (Modifier.isStatic(f.getModifiers())
-          && Property.class.isAssignableFrom(f.getType())) {
-        rtn.add((Property<?>) f.get(null));
-      }
+    Map<String, Class<?>> propertiesFromRecord = getPropertiesFromRecord(clazz);
+    for (Entry<String, Class<?>> property : propertiesFromRecord.entrySet()) {
+      rtn.add(new Property(property.getKey(), property.getValue()));
     }
     return rtn;
   }
 
   public String decodeAndInvokeRequest(String encodedRequest) throws RequestProcessingException {
     try {
-      Logger.getLogger(this.getClass().getName()).finest("Incoming request "
+      Logger.getLogger(this.getClass().getName()).finest("Incoming request " 
           + encodedRequest);
       String response = processJsonRequest(encodedRequest).toString();
-      Logger.getLogger(this.getClass().getName()).finest("Outgoing response "
+      Logger.getLogger(this.getClass().getName()).finest("Outgoing response " 
           + response);
       return response;
     } catch (Exception e) {
@@ -171,9 +172,9 @@
       } catch (JSONException jsonException) {
         throw new IllegalStateException(jsonException);
       }
-      throw new RequestProcessingException("Unexpected exception", e, 
+      throw new RequestProcessingException("Unexpected exception", e,
           exceptionResponse.toString());
-    } 
+    }
   }
 
   /**
@@ -187,17 +188,13 @@
    * @throws NullPointerException 
    */
   public Object decodeParameterValue(Type genericParameterType,
-      String parameterValue) throws SecurityException, JSONException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException {
+      String parameterValue) throws SecurityException, JSONException,
+      IllegalAccessException, InvocationTargetException, NoSuchMethodException,
+      InstantiationException {
     Class<?>parameterType = null;
     if (genericParameterType instanceof Class<?>) {
       parameterType = (Class<?>) genericParameterType;
     }
-    if (genericParameterType instanceof ParameterizedType) {
-      ParameterizedType pType = (ParameterizedType) genericParameterType;
-      if (PropertyReference.class == pType.getRawType()) {
-        parameterType = (Class<?>) pType.getActualTypeArguments()[0];
-      }
-    }
     if (parameterValue == null) {
       return null;
     }
@@ -259,7 +256,7 @@
     if (EntityProxy.class.isAssignableFrom(parameterType)) {
       /* TODO: 1. Don't resolve in this step, just get EntityKey. May need to
        * use DVS.
-       *
+       * 
        * 2. Merge the following and the object resolution code in getEntityKey.
        * 3. Update the involvedKeys set.
        */
@@ -269,16 +266,16 @@
         EntityKey entityKey = getEntityKey(parameterValue.toString());
 
         DvsData dvsData = dvsDataMap.get(entityKey);
-          if (dvsData != null) {
-            EntityData entityData = getEntityDataForRecord(entityKey,
-                dvsData.jsonObject, dvsData.writeOperation);
-            return entityData.entityInstance;
-          } else {
-            Method findMeth = sClass.getMethod(
-                getMethodNameFromPropertyName(sClass.getSimpleName(), "find"),
-                Long.class);
-            return findMeth.invoke(null, entityKey.id);
-          }
+        if (dvsData != null) {
+          EntityData entityData = getEntityDataForRecord(entityKey,
+              dvsData.jsonObject, dvsData.writeOperation);
+          return entityData.entityInstance;
+        } else {
+          Method findMeth = sClass.getMethod(
+              getMethodNameFromPropertyName(sClass.getSimpleName(), "find"),
+              Long.class);
+          return findMeth.invoke(null, entityKey.id);
+        }
       }
     }
     throw new IllegalArgumentException(
@@ -315,8 +312,8 @@
    */
   public Object encodePropertyValueFromDataStore(Object entityElement,
       Class<?> propertyType, String propertyName,
-      RequestProperty propertyContext)
-      throws SecurityException, NoSuchMethodException, IllegalAccessException,
+      RequestProperty propertyContext) 
+      throws SecurityException, NoSuchMethodException, IllegalAccessException, 
       InvocationTargetException, JSONException {
     String methodName = getMethodNameFromPropertyName(propertyName, "get");
     Method method = entityElement.getClass().getMethod(methodName);
@@ -328,7 +325,7 @@
       String keyRef = operationRegistry.getSecurityProvider().encodeClassType(
           propertyType)
           + "-" + id;
-      addRelatedObject(keyRef, returnValue,
+      addRelatedObject(keyRef, returnValue, 
           castToRecordClass(propertyType),
           propertyContext.getProperty(propertyName));
       // replace value with id reference
@@ -340,7 +337,7 @@
   /**
    * Generate an ID for a new record. The default behavior is to return null and
    * let the data store generate the ID automatically.
-   *
+   * 
    * @param key the key of the record field
    * @return the ID of the new record, or null to auto generate
    */
@@ -353,12 +350,12 @@
    * Returns the entityData for a record in the DeltaValueStore.
    * <p>
    * A <i>set</i> might have side-effects, but we don't handle that.
-   * @throws JSONException 
-   * @throws NoSuchMethodException 
-   * @throws InvocationTargetException 
-   * @throws IllegalAccessException 
-   * @throws SecurityException 
-   * @throws InstantiationException 
+   * @throws JSONException
+   * @throws NoSuchMethodException
+   * @throws InvocationTargetException
+   * @throws IllegalAccessException
+   * @throws SecurityException
+   * @throws InstantiationException
    */
   public EntityData getEntityDataForRecord(EntityKey entityKey,
       JSONObject recordObject, WriteOperation writeOperation) throws JSONException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException {
@@ -399,36 +396,36 @@
                propertiesToDTO.get(key));
             }
           } else {
-             propertyValue = getPropertyValueFromRequest(recordObject, key,
-               propertiesToDTO.get(key));
+            propertyValue = getPropertyValueFromRequest(recordObject, key,
+                propertiesToDTO.get(key));
           }
-          entity.getMethod(getMethodNameFromPropertyName(key, "set"),
+          entity.getMethod(getMethodNameFromPropertyName(key, "set"), 
               propertyType).invoke(entityInstance, propertyValue);
-        }
       }
+    }
 
-      Set<ConstraintViolation<Object>> violations = Collections.emptySet();
-      // validations check..
-      Validator validator = null;
-      try {
-        ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
-        validator = validatorFactory.getValidator();
-      } catch (Exception e) {
-        /*
-         * This is JBoss's clumsy way of telling us that the system has not been
-         * configured.
-         */
-        log.info(String.format(
-            "Ignoring exception caught initializing bean validation framework. "
-                + "It is probably unconfigured or misconfigured. [%s] %s ",
-            e.getClass().getName(), e.getLocalizedMessage()));
-      }
+    Set<ConstraintViolation<Object>> violations = Collections.emptySet();
+    // validations check..
+    Validator validator = null;
+    try {
+      ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
+      validator = validatorFactory.getValidator();
+    } catch (Exception e) {
+      /*
+       * This is JBoss's clumsy way of telling us that the system has not been
+       * configured.
+       */
+      log.info(String.format(
+          "Ignoring exception caught initializing bean validation framework. "
+              + "It is probably unconfigured or misconfigured. [%s] %s ",
+          e.getClass().getName(), e.getLocalizedMessage()));
+    }
 
-      if (validator != null) {
-        violations = validator.validate(entityInstance);
-      }
-      return new EntityData(entityInstance, (violations.isEmpty() ? null
-          : getViolationsAsJson(violations)));
+    if (validator != null) {
+      violations = validator.validate(entityInstance);
+    }
+    return new EntityData(entityInstance, (violations.isEmpty() ? null
+        : getViolationsAsJson(violations)));
   }
 
   @SuppressWarnings("unchecked")
@@ -457,9 +454,9 @@
 
   /**
    * Converts the returnValue of a 'get' method to a JSONArray.
-   *
-   * @param resultList     object returned by a 'get' method, must be of type
-   *                       List<?>
+   * 
+   * @param resultList object returned by a 'get' method, must be of type
+   *          List<?>
    * @param entityKeyClass the class type of the contained value
    * @return the JSONArray
    */
@@ -480,8 +477,8 @@
   }
 
   public JSONObject getJsonObject(Object entityElement,
-      Class<? extends EntityProxy> entityKeyClass, RequestProperty propertyContext)
-      throws JSONException, NoSuchMethodException, IllegalAccessException,
+      Class<? extends EntityProxy> entityKeyClass, RequestProperty propertyContext) 
+      throws JSONException, NoSuchMethodException, IllegalAccessException, 
       InvocationTargetException {
     JSONObject jsonObject = new JSONObject();
     for (Property<?> p : allProperties(entityKeyClass)) {
@@ -498,11 +495,11 @@
   /**
    * Returns methodName corresponding to the propertyName that can be invoked on
    * an entity.
-   *
+   * 
    * Example: "userName" returns prefix + "UserName". "version" returns prefix +
    * "Version"
    */
-  public String getMethodNameFromPropertyName(String propertyName,
+  public String getMethodNameFromPropertyName(String propertyName, 
       String prefix) {
     if (propertyName == null) {
       throw new NullPointerException("propertyName must not be null");
@@ -517,12 +514,12 @@
   /**
    * Returns Object[0][0] as the entityKey corresponding to the object instance
    * or null if it is a static method. Returns Object[1] as the params array.
-   * @throws InstantiationException 
-   * @throws NoSuchMethodException 
-   * @throws InvocationTargetException 
-   * @throws IllegalAccessException 
-   * @throws JSONException 
-   * @throws SecurityException 
+   * @throws InstantiationException
+   * @throws NoSuchMethodException
+   * @throws InvocationTargetException
+   * @throws IllegalAccessException
+   * @throws JSONException
+   * @throws SecurityException
    */
   public Object[][] getObjectsFromParameterMap(boolean isInstanceMethod,
       Map<String, String> parameterMap, Type parameterClasses[]) throws SecurityException, JSONException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException {
@@ -537,7 +534,7 @@
     } else {
       args[0][0] = null;
     }
-    
+
     // TODO: update the involvedKeys for other params
     int offset = (isInstanceMethod ? 1 : 0);
     args[1] = new Object[parameterClasses.length - offset];
@@ -579,14 +576,34 @@
    * Returns the property fields (name => type) for a record.
    */
   public Map<String, Class<?>> getPropertiesFromRecord(
-      Class<? extends EntityProxy> record) throws SecurityException,
-      IllegalAccessException, InvocationTargetException, NoSuchMethodException {
-    Map<String, Class<?>> properties = new HashMap<String, Class<?>>();
-    for (Field f : record.getFields()) {
-      if (Property.class.isAssignableFrom(f.getType())) {
-        Class<?> propertyType = (Class<?>) f.getType().getMethod("getType").invoke(
-            f.get(null));
-        properties.put(f.getName(), propertyType);
+      Class<? extends EntityProxy> record) throws SecurityException {
+    if (!EntityProxy.class.isAssignableFrom(record)) {
+      return Collections.emptyMap();
+    }
+    
+    Map<String, Class<?>> properties = new LinkedHashMap<String, Class<?>>();
+    Method[] methods = record.getMethods();
+    for (Method method : methods) {
+      String methodName = method.getName();
+      if (method.getDeclaringClass() == EntityProxy.class
+          && !methodName.equals("getId") && !methodName.equals("getVersion")) {
+        continue;
+      }
+
+      if (methodName.startsWith("get")) {
+        String propertyName = Introspector.decapitalize(methodName.substring(3));
+        if (propertyName.length() > 0) {
+          properties.put(propertyName, method.getReturnType());
+        }
+      } else if (methodName.startsWith("set")) {
+        String propertyName = Introspector.decapitalize(methodName.substring(3));
+        if (propertyName.length() > 0) {
+          Class<?>[] parameterTypes = method.getParameterTypes();
+          if (parameterTypes.length > 0) {
+            properties.put(propertyName,
+                parameterTypes[parameterTypes.length - 1]);
+          }
+        }
       }
     }
     return properties;
@@ -595,13 +612,13 @@
   /**
    * Returns the property value, in the specified type, from the request object.
    * The value is put in the DataStore.
-   * @throws InstantiationException 
-   * @throws NoSuchMethodException 
-   * @throws InvocationTargetException 
-   * @throws IllegalAccessException 
-   * @throws SecurityException 
+   * @throws InstantiationException
+   * @throws NoSuchMethodException
+   * @throws InvocationTargetException
+   * @throws IllegalAccessException
+   * @throws SecurityException
    */
-  public Object getPropertyValueFromRequest(JSONObject recordObject, String key,
+  public Object getPropertyValueFromRequest(JSONObject recordObject, String key, 
       Class<?> propertyType) throws JSONException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException {
     return decodeParameterValue(propertyType,
         recordObject.isNull(key) ? null : recordObject.get(key).toString());
@@ -610,7 +627,7 @@
   @SuppressWarnings("unchecked")
   public Class<EntityProxy> getRecordFromClassToken(String recordToken) {
     try {
-      Class<?> clazz = Class.forName(recordToken, false, 
+      Class<?> clazz = Class.forName(recordToken, false,
           getClass().getClassLoader());
       if (EntityProxy.class.isAssignableFrom(clazz)) {
         return (Class<EntityProxy>) clazz;
@@ -633,7 +650,7 @@
     return violationsAsJson;
   }
 
-  public Object invokeDomainMethod(Object domainObject, Method domainMethod, Object args[])
+  public Object invokeDomainMethod(Object domainObject, Method domainMethod, Object args[]) 
       throws IllegalAccessException, InvocationTargetException {
     return domainMethod.invoke(domainObject, args);
   }
@@ -665,7 +682,7 @@
     // get the domain object (for instance methods) and args.
     Object args[][] = getObjectsFromParameterMap(operation.isInstance(),
         getParameterMap(topLevelJsonObject), operation.getRequestParameterTypes());
-    // Construct beforeDataMap 
+    // Construct beforeDataMap
     constructBeforeDataMap();
     // Construct afterDvsDataMap.
     constructAfterDvsDataMap();
@@ -692,7 +709,7 @@
     Object result = invokeDomainMethod(args[0][0], domainMethod, args[1]);
 
     JSONObject sideEffects = getSideEffects();
-    
+
     if ((result instanceof List<?>) != operation.isReturnTypeList()) {
       throw new IllegalArgumentException(
           String.format("Type mismatch, expected %s%s, but %s returns %s",
@@ -773,7 +790,7 @@
       throws JSONException, IllegalAccessException, NoSuchMethodException,
       InvocationTargetException {
 
-    relatedObjects.put(keyRef, getJsonObject(returnValue, propertyType,
+    relatedObjects.put(keyRef, getJsonObject(returnValue, propertyType, 
         propertyContext));
   }
 
@@ -783,12 +800,12 @@
   }
 
   /**
-   * @throws InstantiationException 
-   * @throws NoSuchMethodException 
-   * @throws InvocationTargetException 
-   * @throws IllegalAccessException 
-   * @throws SecurityException 
-   * @throws JSONException 
+   * @throws InstantiationException
+   * @throws NoSuchMethodException
+   * @throws InvocationTargetException
+   * @throws IllegalAccessException
+   * @throws SecurityException
+   * @throws JSONException
    * 
    */
   private void constructAfterDvsDataMap() throws SecurityException, JSONException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException {
@@ -844,7 +861,7 @@
 
   /**
    * Decode deltaValueStore to populate involvedKeys and dvsDataMap.
-   * @throws JSONException 
+   * @throws JSONException
    */
   private void decodeDVS(String content) throws SecurityException, JSONException {
     JSONObject jsonObject = new JSONObject(content);
@@ -1032,7 +1049,7 @@
     }
     return violations;
   }
-  
+
   /**
    * returns true if the property has been requested. TODO: use the properties
    * that should be coming with the request.
@@ -1053,7 +1070,7 @@
   /**
    * Return the properties of an entityInstance, visible on the client, as a
    * JSONObject.
-   *<p>
+   * <p>
    * TODO: clean up the copy-paste from getJSONObject.
    */
   private JSONObject serializeEntity(Object entityInstance,
@@ -1076,7 +1093,7 @@
         Long id = (Long) idMethod.invoke(returnValue);
 
         propertyValue = id + "-NO-" + operationRegistry.getSecurityProvider().encodeClassType(
-            p.getType());
+                p.getType());
       } else {
         propertyValue = encodePropertyValue(returnValue);
       }
diff --git a/user/src/com/google/gwt/requestfactory/shared/EntityProxy.java b/user/src/com/google/gwt/requestfactory/shared/EntityProxy.java
index 9a2f77d..0f0e57e 100644
--- a/user/src/com/google/gwt/requestfactory/shared/EntityProxy.java
+++ b/user/src/com/google/gwt/requestfactory/shared/EntityProxy.java
@@ -24,38 +24,12 @@
  * A proxy for a server-side domain object.
  */
 public interface EntityProxy {
-  Property<Long> id = new Property<Long>("id", Long.class);
-                                                                                                                                            
-  Property<Integer> version = new Property<Integer>("version", Integer.class);
-
-  /**
-   * Get this proxy's value for the given property. Behavior is undefined if
-   * the proxy has no such property, or if the property has never been set. It
-   * is unusual to call this method directly. Rather it is expected to be called
-   * by bean-style getter methods provided by implementing classes.
-   * 
-   * @param <V> the type of the property's value
-   * @param property the property to fetch
-   * @return the value
-   */
-  <V> V get(Property<V> property);
-
   /**
    * @return the id of this Proxy.
    */
   Long getId();
 
   /**
-   * Get a "pointer" to value of this property in the receiver, useful for
-   * making rpc requests against values that have not yet reached the client.
-   * 
-   * @param <V> the type of the property value
-   * @param property the property referred to
-   * @return a reference to the receiver's value of this property
-   */
-  <V> PropertyReference<V> getRef(Property<V> property);
-
-  /**
    * @return the version of this Proxy.
    */
   Integer getVersion();
diff --git a/user/src/com/google/gwt/requestfactory/shared/Id.java b/user/src/com/google/gwt/requestfactory/shared/Id.java
index 51a0be9..cb9db03 100644
--- a/user/src/com/google/gwt/requestfactory/shared/Id.java
+++ b/user/src/com/google/gwt/requestfactory/shared/Id.java
@@ -21,8 +21,7 @@
  * development, and is very likely to be deleted. Use it at your own risk.
  * </span>
  * </p>
- * Marks the id {@link com.google.gwt.requestfactory.shared.Property Property} of an
- * entity.
+ * Marks the id property of an entity.
  */
 public @interface Id {
   // TODO prove the servlet will use this info
diff --git a/user/src/com/google/gwt/requestfactory/shared/PropertyReference.java b/user/src/com/google/gwt/requestfactory/shared/PropertyReference.java
deleted file mode 100644
index ab09f66..0000000
--- a/user/src/com/google/gwt/requestfactory/shared/PropertyReference.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- *
- * 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.google.gwt.requestfactory.shared;
-
-/**
- * <p>
- * <span style="color:red">Experimental API: This class is still under rapid
- * development, and is very likely to be deleted. Use it at your own risk.
- * </span>
- * </p>
- * A pointer to a particular property value.
- *
- * @param <V> Value type
- */
-public class PropertyReference<V> {
-  private final EntityProxy record;
-  private final Property<V> property;
-
-  public PropertyReference(EntityProxy record, Property<V> property) {
-    assert null != record;
-    assert null != property;
-
-    this.record = record;
-    this.property = property;
-  }
-  
-  protected PropertyReference() {
-    this.record = null;
-    this.property = null;
-  }
-
-  public V get() {
-    return record.get(property);
-  }
-
-  Property<V> getProperty() {
-    return property;
-  }
-}
diff --git a/user/src/com/google/gwt/requestfactory/shared/ProxyListRequest.java b/user/src/com/google/gwt/requestfactory/shared/ProxyListRequest.java
index 77f2c55..dc16bf5 100644
--- a/user/src/com/google/gwt/requestfactory/shared/ProxyListRequest.java
+++ b/user/src/com/google/gwt/requestfactory/shared/ProxyListRequest.java
@@ -15,8 +15,6 @@
  */
 package com.google.gwt.requestfactory.shared;
 
-
-import java.util.Collection;
 import java.util.List;
 
 /**
@@ -31,9 +29,4 @@
     extends RequestObject<List<P>> {
 
   ProxyListRequest<P> with(String... propertyRefs);
-
-  /**
-   * @deprecated use {@link #with(String...)} instead.
-   */
-  ProxyListRequest<P> forProperties(Collection<Property<?>> properties);
 }
diff --git a/user/src/com/google/gwt/requestfactory/shared/ProxyRequest.java b/user/src/com/google/gwt/requestfactory/shared/ProxyRequest.java
index af81e42..87b1d0d 100644
--- a/user/src/com/google/gwt/requestfactory/shared/ProxyRequest.java
+++ b/user/src/com/google/gwt/requestfactory/shared/ProxyRequest.java
@@ -15,9 +15,6 @@
  */
 package com.google.gwt.requestfactory.shared;
 
-
-import java.util.Collection;
-
 /**
  * <p>
  * <span style="color:red">Experimental API: This class is still under rapid
@@ -33,10 +30,4 @@
     RequestObject<P> {
 
   ProxyRequest<P> with(String... propertyRefs);
-
-  /**
-   * @deprecated use {@link #with(String...)} instead.
-   */
-  ProxyRequest<P> forProperties(Collection<Property<?>> properties);
-
 }
diff --git a/user/src/com/google/gwt/requestfactory/shared/UserInformationProxy.java b/user/src/com/google/gwt/requestfactory/shared/UserInformationProxy.java
index 8a27bb7..90fe1808 100644
--- a/user/src/com/google/gwt/requestfactory/shared/UserInformationProxy.java
+++ b/user/src/com/google/gwt/requestfactory/shared/UserInformationProxy.java
@@ -23,15 +23,6 @@
  */
 @ProxyFor(UserInformation.class)
 public interface UserInformationProxy extends EntityProxy  {
-  Property<String> email =
-    new Property<String>("email", "Email", String.class);
-  Property<String> loginUrl =
-    new Property<String>("loginUrl", "LoginUrl", String.class);
-  Property<String> logoutUrl =
-    new Property<String>("logoutUrl", "LogoutUrl", String.class);
-  Property<String> name =
-    new Property<String>("name", "Name", String.class);
-
   String getEmail();
   String getLoginUrl();
   String getLogoutUrl();
diff --git a/user/src/com/google/gwt/requestfactory/shared/Value.java b/user/src/com/google/gwt/requestfactory/shared/Value.java
deleted file mode 100644
index ab23e47..0000000
--- a/user/src/com/google/gwt/requestfactory/shared/Value.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * 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.google.gwt.requestfactory.shared;
-
-/**
- * <p>
- * <span style="color:red">Experimental API: This class is still under rapid
- * development, and is very likely to be deleted. Use it at your own risk.
- * </span>
- * </p>
- * @param <V> the type of the value
- */
-public class Value<V> extends PropertyReference<V> {
-
-  public static <V> Value<V> of(V value) {
-    return new Value<V>(value);
-  }
-
-  private final V value;
-  
-  private Value(V value) {
-    this.value = value;
-  }
-
-  @Override
-  public V get() {
-    return value;
-  }
-}
diff --git a/user/src/com/google/gwt/requestfactory/shared/Version.java b/user/src/com/google/gwt/requestfactory/shared/Version.java
index 0c03fcc..a28a139 100644
--- a/user/src/com/google/gwt/requestfactory/shared/Version.java
+++ b/user/src/com/google/gwt/requestfactory/shared/Version.java
@@ -21,8 +21,7 @@
  * development, and is very likely to be deleted. Use it at your own risk.
  * </span>
  * </p>
- * Marks the version {@link com.google.gwt.requestfactory.shared.Property Property}
- * of an entity.
+ * Marks the version property of an entity.
  */
 public @interface Version {
   // TODO prove the servlet will use this info
diff --git a/user/test/com/google/gwt/editor/rebind/model/EditorModelTest.java b/user/test/com/google/gwt/editor/rebind/model/EditorModelTest.java
index f0cc199..66e4482 100644
--- a/user/test/com/google/gwt/editor/rebind/model/EditorModelTest.java
+++ b/user/test/com/google/gwt/editor/rebind/model/EditorModelTest.java
@@ -38,8 +38,8 @@
 import com.google.gwt.editor.client.adapters.SimpleEditor;
 import com.google.gwt.event.shared.EventBus;
 import com.google.gwt.requestfactory.client.RequestFactoryEditorDriver;
+import com.google.gwt.requestfactory.client.impl.Property;
 import com.google.gwt.requestfactory.shared.EntityProxy;
-import com.google.gwt.requestfactory.shared.Property;
 import com.google.gwt.requestfactory.shared.RequestFactory;
 import com.google.gwt.requestfactory.shared.RequestObject;
 import com.google.gwt.user.client.TakesValue;
diff --git a/user/test/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImplTest.java b/user/test/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImplTest.java
index 79815a9..523d54e 100644
--- a/user/test/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImplTest.java
+++ b/user/test/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImplTest.java
@@ -64,12 +64,12 @@
     // add a proxy
     jso = ProxyJsoImpl.create(42L, 1, SimpleRequestFactoryInstance.schema(),
         SimpleRequestFactoryInstance.impl());
-    jso.set(SimpleFooProxy.userName, "bovik");
-    jso.set(SimpleFooProxy.password, "bovik");
-    jso.set(SimpleFooProxy.intId, 4);
-    jso.set(SimpleFooProxy.created, new Date());
-    jso.set(SimpleFooProxy.boolField, false);
-    jso.set(SimpleFooProxy.otherBoolField, true);
+    jso.set(SimpleFooProxyProperties.userName, "bovik");
+    jso.set(SimpleFooProxyProperties.password, "bovik");
+    jso.set(SimpleFooProxyProperties.intId, 4);
+    jso.set(SimpleFooProxyProperties.created, new Date());
+    jso.set(SimpleFooProxyProperties.boolField, false);
+    jso.set(SimpleFooProxyProperties.otherBoolField, true);
 
     valueStore.putInValueStore(jso);
   }
@@ -95,7 +95,7 @@
         valueStore, requestFactory);
     // DVS does not know about the created entity.
     assertFalse(deltaValueStore.isChanged());
-    deltaValueStore.set(SimpleFooProxy.userName, created, "harry");
+    deltaValueStore.set(SimpleFooProxyProperties.userName, created, "harry");
     assertTrue(deltaValueStore.isChanged());
     testAndGetChangeProxy(deltaValueStore.toJson(), WriteOperation.CREATE);
   }
@@ -106,26 +106,26 @@
         valueStore, requestFactory);
     // DVS does not know about the created entity.
     assertFalse(deltaValueStore.isChanged());
-    deltaValueStore.set(SimpleFooProxy.userName, created, "harry");
+    deltaValueStore.set(SimpleFooProxyProperties.userName, created, "harry");
     assertTrue(deltaValueStore.isChanged());
     JSONObject changeProxy = testAndGetChangeProxy(deltaValueStore.toJson(),
         WriteOperation.CREATE);
     assertEquals(
         "harry",
-        changeProxy.get(SimpleFooProxy.userName.getName()).isString().stringValue());
+        changeProxy.get(SimpleFooProxyProperties.userName.getName()).isString().stringValue());
   }
 
   public void testOperationAfterJson() {
     DeltaValueStoreJsonImpl deltaValueStore = new DeltaValueStoreJsonImpl(
         valueStore, requestFactory);
-    deltaValueStore.set(SimpleFooProxy.userName, new MyProxyImpl(jso),
+    deltaValueStore.set(SimpleFooProxyProperties.userName, new MyProxyImpl(jso),
         "newHarry");
     assertTrue(deltaValueStore.isChanged());
 
     deltaValueStore.toJson();
 
     try {
-      deltaValueStore.set(SimpleFooProxy.userName, new MyProxyImpl(jso),
+      deltaValueStore.set(SimpleFooProxyProperties.userName, new MyProxyImpl(jso),
           "harry");
       fail("Modifying DeltaValueStore after calling toJson should throw a RuntimeException");
     } catch (RuntimeException ex) {
@@ -133,7 +133,7 @@
     }
 
     deltaValueStore.clearUsed();
-    deltaValueStore.set(SimpleFooProxy.userName, new MyProxyImpl(jso),
+    deltaValueStore.set(SimpleFooProxyProperties.userName, new MyProxyImpl(jso),
         "harry");
   }
 
@@ -148,8 +148,8 @@
     DeltaValueStoreJsonImpl deltaValueStore = new DeltaValueStoreJsonImpl(
         valueStore, requestFactory);
 
-    deltaValueStore.set(SimpleFooProxy.userName, createProxy, "harry");
-    deltaValueStore.set(SimpleFooProxy.userName, mockProxy, "bovik");
+    deltaValueStore.set(SimpleFooProxyProperties.userName, createProxy, "harry");
+    deltaValueStore.set(SimpleFooProxyProperties.userName, mockProxy, "bovik");
     assertTrue(deltaValueStore.isChanged());
     String jsonString = deltaValueStore.toJson();
     JSONObject jsonObject = (JSONObject) JSONParser.parseLenient(jsonString);
@@ -162,27 +162,27 @@
     assertEquals(1, createOperationArray.size());
     assertEquals("harry", createOperationArray.get(0).isObject().get(
         SIMPLE_FOO_CLASS_NAME).isObject().get(
-        SimpleFooProxy.userName.getName()).isString().stringValue());
+            SimpleFooProxyProperties.userName.getName()).isString().stringValue());
 
     JSONArray updateOperationArray = jsonObject.get(
         WriteOperation.UPDATE.getUnObfuscatedEnumName()).isArray();
     assertEquals(1, updateOperationArray.size());
     assertEquals("bovik", updateOperationArray.get(0).isObject().get(
         SIMPLE_FOO_CLASS_NAME).isObject().get(
-        SimpleFooProxy.userName.getName()).isString().stringValue());
+            SimpleFooProxyProperties.userName.getName()).isString().stringValue());
   }
 
   public void testUpdate() {
     DeltaValueStoreJsonImpl deltaValueStore = new DeltaValueStoreJsonImpl(
         valueStore, requestFactory);
-    deltaValueStore.set(SimpleFooProxy.userName, new MyProxyImpl(jso),
+    deltaValueStore.set(SimpleFooProxyProperties.userName, new MyProxyImpl(jso),
         "harry");
     assertTrue(deltaValueStore.isChanged());
     JSONObject changeProxy = testAndGetChangeProxy(deltaValueStore.toJson(),
         WriteOperation.UPDATE);
     assertEquals(
         "harry",
-        changeProxy.get(SimpleFooProxy.userName.getName()).isString().stringValue());
+        changeProxy.get(SimpleFooProxyProperties.userName.getName()).isString().stringValue());
   }
 
   private JSONObject testAndGetChangeProxy(String jsonString,
diff --git a/user/test/com/google/gwt/requestfactory/client/impl/ProxyJsoImplTest.java b/user/test/com/google/gwt/requestfactory/client/impl/ProxyJsoImplTest.java
index 30badcd..4f42fa1 100644
--- a/user/test/com/google/gwt/requestfactory/client/impl/ProxyJsoImplTest.java
+++ b/user/test/com/google/gwt/requestfactory/client/impl/ProxyJsoImplTest.java
@@ -18,7 +18,6 @@
 import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.junit.client.GWTTestCase;
 import com.google.gwt.requestfactory.client.SimpleRequestFactoryInstance;
-import com.google.gwt.requestfactory.shared.SimpleFooProxy;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -34,13 +33,13 @@
     StringBuilder b = new StringBuilder();
     b.append("{");
 
-    String[] stringBits = new String[] {
+    String[] stringBits = new String[]{
         "userName", "bovik", "password", "bovik", "charField", "c",
         "longField", "1234567890", "bigDecimalField",
         "12345678901234.5678901234567890", "bigIntField",
         "123456789012345678901234567890", "created", "400", "id", "42"};
 
-    String[] literalBits = new String[] {
+    String[] literalBits = new String[]{
         "version", "1", "intId", "4", "shortField", "5", "byteField", "6",
         "floatField", "12.3456789", "doubleField", "12345.6789", "boolField",
         "false", "otherBoolField", "true"};
@@ -84,13 +83,13 @@
     return ProxyJsoImpl.create(42L, 1, SimpleRequestFactoryInstance.schema(),
         SimpleRequestFactoryInstance.impl());
   }
-
+  
   static ProxyJsoImpl getPopulatedJso() {
     ProxyJsoImpl jso = getMinimalJso();
-    jso.set(SimpleFooProxy.userName, "bovik");
-    jso.set(SimpleFooProxy.password, "bovik");
-    jso.set(SimpleFooProxy.intId, 4);
-    jso.set(SimpleFooProxy.created, new Date(400));
+    jso.set(SimpleFooProxyProperties.userName, "bovik");
+    jso.set(SimpleFooProxyProperties.password, "bovik");
+    jso.set(SimpleFooProxyProperties.intId, 4);
+    jso.set(SimpleFooProxyProperties.created, new Date(400));
     return jso;
   }
 
@@ -123,7 +122,7 @@
     
     ProxyJsoImpl minimalJsoCopy = getMinimalJso();
     assertFalse(minimalJso.hasChanged(minimalJsoCopy));
-    minimalJsoCopy.set(SimpleFooProxy.id, minimalJso.getId() + 42);
+    minimalJsoCopy.set(SimpleFooProxyProperties.id, minimalJso.getId() + 42);
     assertTrue(minimalJso.hasChanged(minimalJsoCopy));
   }
 
@@ -135,28 +134,28 @@
   public void testSet() {
     ProxyJsoImpl jso = getMinimalJso();
 
-    jso.set(SimpleFooProxy.userName, "bovik");
-    jso.set(SimpleFooProxy.password, "bovik");
+    jso.set(SimpleFooProxyProperties.userName, "bovik");
+    jso.set(SimpleFooProxyProperties.password, "bovik");
 
-    jso.set(SimpleFooProxy.charField, 'c');
+    jso.set(SimpleFooProxyProperties.charField, 'c');
 
-    jso.set(SimpleFooProxy.longField, 1234567890L);
-    jso.set(SimpleFooProxy.bigDecimalField, new BigDecimal(
+    jso.set(SimpleFooProxyProperties.longField, 1234567890L);
+    jso.set(SimpleFooProxyProperties.bigDecimalField, new BigDecimal(
         "12345678901234.5678901234567890"));
-    jso.set(SimpleFooProxy.bigIntField, new BigInteger(
+    jso.set(SimpleFooProxyProperties.bigIntField, new BigInteger(
         "123456789012345678901234567890"));
 
-    jso.set(SimpleFooProxy.intId, 4);
-    jso.set(SimpleFooProxy.shortField, (short) 5);
-    jso.set(SimpleFooProxy.byteField, (byte) 6);
+    jso.set(SimpleFooProxyProperties.intId, 4);
+    jso.set(SimpleFooProxyProperties.shortField, (short) 5);
+    jso.set(SimpleFooProxyProperties.byteField, (byte) 6);
 
-    jso.set(SimpleFooProxy.created, new Date(400));
+    jso.set(SimpleFooProxyProperties.created, new Date(400));
 
-    jso.set(SimpleFooProxy.doubleField, 12345.6789);
-    jso.set(SimpleFooProxy.floatField, 12.3456789f);
+    jso.set(SimpleFooProxyProperties.doubleField, 12345.6789);
+    jso.set(SimpleFooProxyProperties.floatField, 12.3456789f);
 
-    jso.set(SimpleFooProxy.boolField, false);
-    jso.set(SimpleFooProxy.otherBoolField, true);
+    jso.set(SimpleFooProxyProperties.boolField, false);
+    jso.set(SimpleFooProxyProperties.otherBoolField, true);
 
     testPopulatedJso(jso);
   }
@@ -178,30 +177,30 @@
 
   private void testEmptyJso(JavaScriptObject rawJso) {
     ProxyJsoImpl jso = ProxyJsoImpl.create(rawJso, null, null);
-    assertFalse(jso.isDefined(SimpleFooProxy.id.getName()));
-    assertFalse(jso.isDefined(SimpleFooProxy.version.getName()));
+    assertFalse(jso.isDefined(SimpleFooProxyProperties.id.getName()));
+    assertFalse(jso.isDefined(SimpleFooProxyProperties.version.getName()));
     assertEquals("{}", jso.toJson());
     testSchema(jso);
   }
 
   private void testMinimalJso(ProxyJsoImpl jso) {
-    for (String property : new String[] {"id", "version"}) {
+    for (String property : new String[]{"id", "version"}) {
       assertTrue(jso.isDefined(property));
     }
-    for (String property : new String[] {
+    for (String property : new String[]{
         "created", "intId", "userName", "password"}) {
       assertFalse(jso.isDefined(property));
       assertNull(jso.get(property));
     }
     assertEquals((Long) 42L, jso.getId());
     assertEquals(new Integer(1), jso.getVersion());
-    assertEquals(null, jso.get(SimpleFooProxy.longField));
-    assertEquals(null, jso.get(SimpleFooProxy.enumField));
+    assertEquals(null, jso.get(SimpleFooProxyProperties.longField));
+    assertEquals(null, jso.get(SimpleFooProxyProperties.enumField));
     testSchema(jso);
   }
 
   private void testPopulatedJso(ProxyJsoImpl jso) {
-    for (String property : new String[] {
+    for (String property : new String[]{
         "userName", "password", "charField", "longField", "bigDecimalField",
         "bigIntField", "intId", "shortField", "byteField", "created",
         "doubleField", "floatField", "boolField", "otherBoolField", "id",
@@ -209,31 +208,31 @@
       assertTrue("Expect " + property + " to be defined",
           jso.isDefined(property));
     }
-    assertEquals("bovik", jso.get(SimpleFooProxy.userName));
-    assertEquals("bovik", jso.get(SimpleFooProxy.password));
+    assertEquals("bovik", jso.get(SimpleFooProxyProperties.userName));
+    assertEquals("bovik", jso.get(SimpleFooProxyProperties.password));
 
-    assertEquals(new Character('c'), jso.get(SimpleFooProxy.charField));
+    assertEquals(new Character('c'), jso.get(SimpleFooProxyProperties.charField));
 
-    assertEquals(new Long(1234567890L), jso.get(SimpleFooProxy.longField));
+    assertEquals(new Long(1234567890L), jso.get(SimpleFooProxyProperties.longField));
     assertEquals(new BigDecimal("12345678901234.5678901234567890"),
-        jso.get(SimpleFooProxy.bigDecimalField));
+        jso.get(SimpleFooProxyProperties.bigDecimalField));
     assertEquals(new BigInteger("123456789012345678901234567890"),
-        jso.get(SimpleFooProxy.bigIntField));
+        jso.get(SimpleFooProxyProperties.bigIntField));
 
-    assertEquals(Integer.valueOf(4), jso.get(SimpleFooProxy.intId));
-    assertEquals(Short.valueOf((short) 5), jso.get(SimpleFooProxy.shortField));
-    assertEquals(Byte.valueOf((byte) 6), jso.get(SimpleFooProxy.byteField));
+    assertEquals(Integer.valueOf(4), jso.get(SimpleFooProxyProperties.intId));
+    assertEquals(Short.valueOf((short) 5), jso.get(SimpleFooProxyProperties.shortField));
+    assertEquals(Byte.valueOf((byte) 6), jso.get(SimpleFooProxyProperties.byteField));
 
-    assertEquals(new Date(400), jso.get(SimpleFooProxy.created));
+    assertEquals(new Date(400), jso.get(SimpleFooProxyProperties.created));
     assertEquals(Double.valueOf(12345.6789),
-        jso.get(SimpleFooProxy.doubleField));
+        jso.get(SimpleFooProxyProperties.doubleField));
 
     int expected = (int) (Float.valueOf(12.3456789f) * 1000);
-    int actual = (int) (jso.get(SimpleFooProxy.floatField) * 1000);
+    int actual = (int) (jso.get(SimpleFooProxyProperties.floatField) * 1000);
     assertEquals(expected, actual);
 
-    assertFalse(jso.get(SimpleFooProxy.boolField));
-    assertTrue(jso.get(SimpleFooProxy.otherBoolField));
+    assertFalse(jso.get(SimpleFooProxyProperties.boolField));
+    assertTrue(jso.get(SimpleFooProxyProperties.otherBoolField));
 
     assertEquals((Long) 42L, jso.getId());
     assertEquals(new Integer(1), jso.getVersion());
diff --git a/user/test/com/google/gwt/requestfactory/client/impl/SimpleBazProxyImpl.java b/user/test/com/google/gwt/requestfactory/client/impl/SimpleBazProxyImpl.java
index 8c5406f..5e131f7 100644
--- a/user/test/com/google/gwt/requestfactory/client/impl/SimpleBazProxyImpl.java
+++ b/user/test/com/google/gwt/requestfactory/client/impl/SimpleBazProxyImpl.java
@@ -16,7 +16,6 @@
 package com.google.gwt.requestfactory.client.impl;
 
 import com.google.gwt.requestfactory.shared.EntityProxy;
-import com.google.gwt.requestfactory.shared.Property;
 
 import java.util.Collections;
 import java.util.HashSet;
diff --git a/user/test/com/google/gwt/requestfactory/client/impl/SimpleFooProxyProperties.java b/user/test/com/google/gwt/requestfactory/client/impl/SimpleFooProxyProperties.java
new file mode 100644
index 0000000..3f7d3d0
--- /dev/null
+++ b/user/test/com/google/gwt/requestfactory/client/impl/SimpleFooProxyProperties.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * 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.google.gwt.requestfactory.client.impl;
+
+import com.google.gwt.requestfactory.shared.SimpleBarProxy;
+import com.google.gwt.requestfactory.shared.SimpleEnum;
+import com.google.gwt.requestfactory.shared.SimpleFooProxy;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+
+class SimpleFooProxyProperties {
+  static final Property<Long> id = new Property<Long>("id", "Id",
+      Long.class);
+  static final Property<String> version = new Property<String>("version", "Version",
+      String.class);
+
+  static final Property<String> userName = new Property<String>("userName", "User Name",
+      String.class);
+  static final Property<String> password = new Property<String>("password", "Password",
+      String.class);
+
+  static final Property<Character> charField = new Property<Character>("charField",
+      Character.class);
+
+  static final Property<Long> longField = new Property<Long>("longField", Long.class);
+  static final Property<BigDecimal> bigDecimalField = new Property<BigDecimal>(
+      "bigDecimalField", BigDecimal.class);
+  static final Property<BigInteger> bigIntField = new Property<BigInteger>("bigIntField",
+      BigInteger.class);
+
+  static final Property<Integer> intId = new Property<Integer>("intId", Integer.class);
+  static final Property<Short> shortField = new Property<Short>("shortField", Short.class);
+  static final Property<Byte> byteField = new Property<Byte>("byteField", Byte.class);
+
+  static final Property<Date> created = new Property<Date>("created", Date.class);
+
+  static final Property<Double> doubleField = new Property<Double>("doubleField",
+      Double.class);
+  static final Property<Float> floatField = new Property<Float>("floatField", Float.class);
+
+  static final Property<SimpleEnum> enumField = new EnumProperty<SimpleEnum>("enumField",
+      SimpleEnum.class, SimpleEnum.values());
+
+  static final Property<Boolean> boolField = new Property<Boolean>("boolField",
+      Boolean.class);
+  static final Property<Boolean> otherBoolField = new Property<Boolean>("otherBoolField",
+      Boolean.class);
+
+  static final Property<SimpleBarProxy> barField = new Property<SimpleBarProxy>(
+      "barField", SimpleBarProxy.class);
+
+  static final Property<SimpleFooProxy> fooField = new Property<SimpleFooProxy>(
+      "fooField", SimpleFooProxy.class);
+}
\ No newline at end of file
diff --git a/user/test/com/google/gwt/requestfactory/shared/SimpleBarProxy.java b/user/test/com/google/gwt/requestfactory/shared/SimpleBarProxy.java
index 23c7f12..d5f501c 100644
--- a/user/test/com/google/gwt/requestfactory/shared/SimpleBarProxy.java
+++ b/user/test/com/google/gwt/requestfactory/shared/SimpleBarProxy.java
@@ -23,10 +23,6 @@
  */
 @ProxyFor(SimpleBar.class)
 public interface SimpleBarProxy extends EntityProxy {
-
-  Property<String> userName = new Property<String>("userName", "User Name",
-      String.class);
-
   String getUserName();
 
   void setUserName(String userName);
diff --git a/user/test/com/google/gwt/requestfactory/shared/SimpleFooProxy.java b/user/test/com/google/gwt/requestfactory/shared/SimpleFooProxy.java
index b3851bf..6a22760 100644
--- a/user/test/com/google/gwt/requestfactory/shared/SimpleFooProxy.java
+++ b/user/test/com/google/gwt/requestfactory/shared/SimpleFooProxy.java
@@ -27,46 +27,6 @@
  */
 @ProxyFor(SimpleFoo.class)
 public interface SimpleFooProxy extends EntityProxy {
-
-  Property<String> userName = new Property<String>("userName", "User Name",
-      String.class);
-  Property<String> password = new Property<String>("password", "Password",
-      String.class);
-
-  Property<Character> charField = new Property<Character>("charField", Character.class);
-  
-  Property<Long> longField = new Property<Long>("longField", Long.class);
-  Property<BigDecimal> bigDecimalField = new Property<BigDecimal>("bigDecimalField", BigDecimal.class);
-  Property<BigInteger> bigIntField = new Property<BigInteger>("bigIntField", BigInteger.class);
-  
-  Property<Integer> intId = new Property<Integer>("intId", Integer.class);
-  Property<Short> shortField = new Property<Short>("shortField", Short.class);
-  Property<Byte> byteField = new Property<Byte>("byteField", Byte.class);
-  
-  Property<Date> created = new Property<Date>("created", Date.class);
-
-  Property<Double> doubleField = new Property<Double>("doubleField", Double.class);
-  Property<Float> floatField = new Property<Float>("floatField", Float.class);
-  
-  Property<SimpleEnum> enumField =
-      new EnumProperty<SimpleEnum>("enumField",
-          SimpleEnum.class, SimpleEnum.values());
-
-  Property<Boolean> boolField = new Property<Boolean>("boolField", Boolean.class);
-  Property<Boolean> otherBoolField = new Property<Boolean>("otherBoolField", Boolean.class);
-  
-  Property<SimpleBarProxy> barField = new Property<SimpleBarProxy>("barField",
-      SimpleBarProxy.class);
-
-  Property<SimpleBarProxy> barNullField = new Property<SimpleBarProxy>("barNullField",
-      SimpleBarProxy.class);
-
-  Property<SimpleFooProxy> fooField = new Property<SimpleFooProxy>("fooField",
-      SimpleFooProxy.class);
-
-  Property<String> nullField = new Property<String>("nullField", "A nullable field",
-      String.class);
-  
   SimpleBarProxy getBarField();
   
   SimpleBarProxy getBarNullField();