Add partial support for Record types as method parameters
- Currently, Record has to already have been persisted on the server
Added missing support for String as a RF method return type
Fixed bugs with cast exceptions in DevMode

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

Review by: rjrjr@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8572 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractBigDecimalRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractBigDecimalRequest.java
index a4fed52..1f82e1a 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractBigDecimalRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractBigDecimalRequest.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.requestfactory.client.impl;
 
+import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.valuestore.shared.SyncResult;
 
 import java.math.BigDecimal;
@@ -37,7 +38,8 @@
     super(requestFactory);
   }
 
-  public void handlePrimitiveResult(String responseText) {
+  public void handlePrimitiveResult(String responseText,
+      JavaScriptObject sideEffects) {
     receiver.onSuccess(new BigDecimal(responseText),
         Collections.<SyncResult> emptySet());
   }
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractBigIntegerRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractBigIntegerRequest.java
index 3f586e2..8bfd778 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractBigIntegerRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractBigIntegerRequest.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.requestfactory.client.impl;
 
+import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.valuestore.shared.SyncResult;
 
 import java.math.BigDecimal;
@@ -38,7 +39,8 @@
     super(requestFactory);
   }
 
-  public void handlePrimitiveResult(String responseText) {
+  public void handlePrimitiveResult(String responseText,
+      JavaScriptObject sideEffects) {
     receiver.onSuccess(new BigDecimal(responseText).toBigInteger(),
         Collections.<SyncResult> emptySet());
   }
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractBooleanRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractBooleanRequest.java
index 42c3c4c..29c39dc 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractBooleanRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractBooleanRequest.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.requestfactory.client.impl;
 
+import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.valuestore.shared.SyncResult;
 
 import java.util.Collections;
@@ -36,7 +37,8 @@
     super(requestFactory);
   }
 
-  public void handlePrimitiveResult(String responseText) {
+  public void handlePrimitiveResult(String responseText,
+      JavaScriptObject sideEffects) {
     receiver.onSuccess(Boolean.valueOf(responseText),
         Collections.<SyncResult> emptySet());
   }
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractByteRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractByteRequest.java
index 68a61ea..e1b0f46 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractByteRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractByteRequest.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.requestfactory.client.impl;
 
+import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.valuestore.shared.SyncResult;
 
 import java.util.Collections;
@@ -36,7 +37,8 @@
     super(requestFactory);
   }
 
-  public void handlePrimitiveResult(String responseText) {
+  public void handlePrimitiveResult(String responseText,
+      JavaScriptObject sideEffects) {
     receiver.onSuccess(Integer.valueOf(responseText).byteValue(),
         Collections.<SyncResult> emptySet());
   }
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractCharacterRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractCharacterRequest.java
index 11a3254..4ed98fe 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractCharacterRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractCharacterRequest.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.requestfactory.client.impl;
 
+import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.valuestore.shared.SyncResult;
 
 import java.util.Collections;
@@ -36,7 +37,8 @@
     super(requestFactory);
   }
 
-  public void handlePrimitiveResult(String responseText) {
+  public void handlePrimitiveResult(String responseText,
+      JavaScriptObject sideEffects) {
     receiver.onSuccess(responseText.charAt(0), 
         Collections.<SyncResult> emptySet());
   }
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractDateRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractDateRequest.java
index 551bb6f..d87264c 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractDateRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractDateRequest.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.requestfactory.client.impl;
 
+import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.valuestore.shared.SyncResult;
 
 import java.util.Collections;
@@ -37,7 +38,8 @@
     super(requestFactory);
   }
 
-  public void handlePrimitiveResult(String responseText) {
+  public void handlePrimitiveResult(String responseText,
+      JavaScriptObject sideEffects) {
     receiver.onSuccess(new Date(Long.valueOf(responseText)),
         Collections.<SyncResult> emptySet());
   }
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractDoubleRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractDoubleRequest.java
index c9f8dd8..52deeef 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractDoubleRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractDoubleRequest.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.requestfactory.client.impl;
 
+import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.valuestore.shared.SyncResult;
 
 import java.util.Collections;
@@ -36,7 +37,8 @@
     super(requestFactory);
   }
 
-  public void handlePrimitiveResult(String responseText) {
+  public void handlePrimitiveResult(String responseText,
+      JavaScriptObject sideEffects) {
     receiver.onSuccess(Double.valueOf(responseText),
         Collections.<SyncResult> emptySet());
   }
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractEnumRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractEnumRequest.java
index c08a0c7..f25c997 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractEnumRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractEnumRequest.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.requestfactory.client.impl;
 
+import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.valuestore.shared.SyncResult;
 
 import java.util.Collections;
@@ -41,7 +42,8 @@
     this.enumValues = enumValues;
   }
 
-  public void handlePrimitiveResult(String responseText) {
+  public void handlePrimitiveResult(String responseText,
+      JavaScriptObject sideEffects) {
     int ordinal = Integer.valueOf(responseText);
     for (E e : enumValues) {
       if (ordinal == e.ordinal()) {
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractFloatRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractFloatRequest.java
index 2c279a2..a082a035 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractFloatRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractFloatRequest.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.requestfactory.client.impl;
 
+import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.valuestore.shared.SyncResult;
 
 import java.util.Collections;
@@ -36,7 +37,8 @@
     super(requestFactory);
   }
 
-  public void handlePrimitiveResult(String responseText) {
+  public void handlePrimitiveResult(String responseText,
+      JavaScriptObject sideEffects) {
     receiver.onSuccess(Float.valueOf(responseText),
         Collections.<SyncResult> emptySet());
   }
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractIntegerRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractIntegerRequest.java
index ac18103..fa091c4 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractIntegerRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractIntegerRequest.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.requestfactory.client.impl;
 
+import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.valuestore.shared.SyncResult;
 
 import java.util.Collections;
@@ -36,7 +37,8 @@
     super(requestFactory);
   }
 
-  public void handlePrimitiveResult(String responseText) {
+  public void handlePrimitiveResult(String responseText,
+      JavaScriptObject sideEffects) {
     receiver.onSuccess(Integer.valueOf(responseText),
         Collections.<SyncResult> emptySet());
   }
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractJsonListRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractJsonListRequest.java
index 10571cb..3880847 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractJsonListRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractJsonListRequest.java
@@ -50,9 +50,9 @@
     this.schema = schema;
   }
 
-  public void handleJsonResult(JavaScriptObject jsoResult) {
+  public void handleResult(Object jsoResult, JavaScriptObject sideEffects) {
 
-    JsArray<RecordJsoImpl> valueJsos = jsoResult.cast();
+    JsArray<RecordJsoImpl> valueJsos = (JsArray<RecordJsoImpl>) jsoResult;
     List<T> valueList = new ArrayList<T>(valueJsos.length());
     for (int i = 0; i < valueJsos.length(); i++) {
       RecordJsoImpl jso = valueJsos.get(i);
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractJsonObjectRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractJsonObjectRequest.java
index 0197276..7f9cc2b 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractJsonObjectRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractJsonObjectRequest.java
@@ -44,9 +44,9 @@
     this.schema = schema;
   }
 
-  public void handleJsonResult(JavaScriptObject jsoResult) {
+  public void handleResult(Object jsoResult, JavaScriptObject sideEffects) {
 
-    RecordJsoImpl jso = jsoResult.cast();
+    RecordJsoImpl jso = (RecordJsoImpl) jsoResult;
     jso.setSchema(schema);
 
     requestFactory.getValueStore().setRecord(jso, requestFactory);
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractLongRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractLongRequest.java
index 04fb0a1..d72fee2 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractLongRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractLongRequest.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.requestfactory.client.impl;
 
+import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.valuestore.shared.SyncResult;
 
 import java.util.Collections;
@@ -36,7 +37,8 @@
     super(requestFactory);
   }
 
-  public void handlePrimitiveResult(String responseText) {
+  public void handlePrimitiveResult(String responseText,
+      JavaScriptObject sideEffects) {
     receiver.onSuccess(Long.valueOf(responseText),
         Collections.<SyncResult> emptySet());
   }
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractPrimitiveRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractPrimitiveRequest.java
index 2595345..0e797ca 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractPrimitiveRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractPrimitiveRequest.java
@@ -36,9 +36,10 @@
     super(requestFactory);
   }
 
-  public void handleJsonResult(JavaScriptObject result) {
-    handlePrimitiveResult(asString(result));
+  public void handleResult(Object result, JavaScriptObject sideEffects) {
+    handlePrimitiveResult(asString(result), sideEffects);
   }
 
-  protected abstract void handlePrimitiveResult(String responseText);
+  protected abstract void handlePrimitiveResult(String responseText,
+      JavaScriptObject sideEffects);
 }
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 5ab7916..651b8c9 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractRequest.java
@@ -53,9 +53,9 @@
         requestFactory);
   }
 
-  public native String asString(JavaScriptObject jso) /*-{
-    return String(jso);
-  }-*/;
+  protected String asString(Object jso) {
+    return String.valueOf(jso);
+  }
 
   public void clearUsed() {
     deltaValueStore.clearUsed();
@@ -97,7 +97,7 @@
   public void handleResponseText(String responseText) {
      RecordJsoImpl.JsonResults results = RecordJsoImpl.fromResults(responseText);
     processRelated(results.getRelated());
-    handleJsonResult(results.getJavascriptResult());
+    handleResult(results.getResult(), results.getSideEffects());
   }
   
   public boolean isChanged() {
@@ -127,7 +127,8 @@
    */
   protected abstract R getThis();
 
-  protected abstract void handleJsonResult(JavaScriptObject result);
+  protected abstract void handleResult(Object result,
+      JavaScriptObject sideEffects);
 
   protected native void processRelated(JavaScriptObject related) /*-{
     for(var recordKey in related) {
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractShortRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractShortRequest.java
index da9a35b..9450caf 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractShortRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractShortRequest.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.requestfactory.client.impl;
 
+import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.valuestore.shared.SyncResult;
 
 import java.util.Collections;
@@ -36,7 +37,8 @@
     super(requestFactory);
   }
 
-  public void handlePrimitiveResult(String responseText) {
+  public void handlePrimitiveResult(String responseText,
+      JavaScriptObject sideEffects) {
     receiver.onSuccess(Short.valueOf(responseText),
         Collections.<SyncResult> emptySet());
   }
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractStringRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractStringRequest.java
new file mode 100644
index 0000000..c15cd1c
--- /dev/null
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractStringRequest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.core.client.JavaScriptObject;
+import com.google.gwt.valuestore.shared.SyncResult;
+
+import java.util.Collections;
+
+/**
+ * <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>
+ * Abstract implementation of
+ * {@link com.google.gwt.requestfactory.shared.RequestFactory.RequestObject
+ * RequestFactory.RequestObject} for requests that return String.
+ */
+public abstract class AbstractStringRequest extends
+    AbstractPrimitiveRequest<String, AbstractStringRequest> {
+
+  public AbstractStringRequest(RequestFactoryJsonImpl requestFactory) {
+    super(requestFactory);
+  }
+
+  public void handlePrimitiveResult(String responseText,
+      JavaScriptObject sideEffects) {
+    receiver.onSuccess(responseText,
+        Collections.<SyncResult> emptySet());
+  }
+
+  @Override
+  protected AbstractStringRequest getThis() {
+    return this;
+  }
+}
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/AbstractVoidRequest.java b/user/src/com/google/gwt/requestfactory/client/impl/AbstractVoidRequest.java
index ad657c2..2ac72e9 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/AbstractVoidRequest.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/AbstractVoidRequest.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.requestfactory.client.impl;
 
+import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.valuestore.shared.SyncResult;
 
 import java.util.Set;
@@ -36,8 +37,9 @@
     super(requestFactory);
   }
 
-  public void handlePrimitiveResult(String responseText) {
-    Set<SyncResult> syncResults = deltaValueStore.commit(responseText);
+  public void handlePrimitiveResult(String responseText,
+      JavaScriptObject sideEffects) {
+    Set<SyncResult> syncResults = deltaValueStore.commit(sideEffects);
     receiver.onSuccess(null, syncResults);
   }
 
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 f7cc91c..68aca5b 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImpl.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImpl.java
@@ -136,9 +136,8 @@
     used = false;
   }
 
-  public Set<SyncResult> commit(String response) {
+  public Set<SyncResult> commit(JavaScriptObject returnedJso) {
     Set<SyncResult> syncResults = new HashSet<SyncResult>();
-    JavaScriptObject returnedJso = ReturnRecord.getJsoResponse(response);
     HashSet<String> keys = new HashSet<String>();
     ReturnRecord.fillKeys(returnedJso, keys);
 
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/RecordJsoImpl.java b/user/src/com/google/gwt/requestfactory/client/impl/RecordJsoImpl.java
index 4cf57e4..e7082c9 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/RecordJsoImpl.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/RecordJsoImpl.java
@@ -43,10 +43,6 @@
     protected JsonResults() {
     }
 
-    public final native JavaScriptObject getJavascriptResult() /*-{
-      return this.result;
-    }-*/;
-
     public final native JsArray<RecordJsoImpl> getListResult() /*-{
       return this.result;
     }-*/;
@@ -58,6 +54,14 @@
     public final native JavaScriptObject getRelated() /*-{
       return this.related;
     }-*/;
+
+    public final native Object getResult() /*-{
+      return Object(this.result);
+    }-*/;
+
+    public final native JavaScriptObject getSideEffects() /*-{
+      return this.sideEffects;
+    }-*/;
   }
 
   public static native JsArray<RecordJsoImpl> arrayFromJson(String json) /*-{
diff --git a/user/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java b/user/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java
index c956745..2e43866 100644
--- a/user/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java
+++ b/user/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java
@@ -42,6 +42,7 @@
 import com.google.gwt.requestfactory.client.impl.AbstractJsonObjectRequest;
 import com.google.gwt.requestfactory.client.impl.AbstractLongRequest;
 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.RecordImpl;
 import com.google.gwt.requestfactory.client.impl.RecordJsoImpl;
@@ -531,6 +532,8 @@
         requestClassName = asInnerImplClass("ListRequestImpl", returnType);
       } else if (isRecordRequest(typeOracle, requestType)) {
         requestClassName = asInnerImplClass("ObjectRequestImpl", returnType);
+      } else if (isStringRequest(typeOracle, requestType)) {
+        requestClassName = AbstractStringRequest.class.getName();
       } else if (isLongRequest(typeOracle, requestType)) {
         requestClassName = AbstractLongRequest.class.getName();
       } else if (isIntegerRequest(typeOracle, requestType)) {
@@ -627,18 +630,29 @@
       if (sb.length() > 0) {
         sb.append(", ");
       }
+      JClassType classType = parameter.getType().isClassOrInterface();
+
+      JType paramType = parameter.getType();
+      boolean isRef =
+          "com.google.gwt.valuestore.shared.PropertyReference".equals(
+          paramType.getQualifiedBinaryName());
+      JParameterizedType params = paramType.isParameterized();
+      if (params != null) {
+        classType = params.getTypeArgs()[0];
+      }
+      if (classType != null
+          && classType.isAssignableTo(typeOracle.findType(Record.class.getName()))) {
+        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 ("com.google.gwt.valuestore.shared.PropertyReference".equals(
-          parameter.getType().getQualifiedBinaryName())) {
+      if (isRef) {
         sb.append(".get()");
       }
-      JClassType classType = parameter.getType().isClassOrInterface();
       if (classType != null
           && classType.isAssignableTo(typeOracle.findType(Record.class.getName()))) {
-        sb.insert(0, "((" + classType.getQualifiedBinaryName() + "Impl" + ")");
         sb.append(").getUniqueId()");
       }
     }
@@ -715,6 +729,11 @@
     return requestType.isParameterized().getTypeArgs()[0].isAssignableTo(typeOracle.findType(Short.class.getName()));
   }
 
+  private boolean isStringRequest(TypeOracle typeOracle,
+      JClassType requestType) {
+    return requestType.isParameterized().getTypeArgs()[0].isAssignableTo(typeOracle.findType(String.class.getName()));
+  }
+
   private boolean isVoidRequest(TypeOracle typeOracle, JClassType requestType) {
     return requestType.isParameterized().getTypeArgs()[0].isAssignableTo(typeOracle.findType(Void.class.getName()));
   }
diff --git a/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java b/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java
index 2ea103a..a530606 100644
--- a/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java
+++ b/user/src/com/google/gwt/requestfactory/server/JsonRequestProcessor.java
@@ -17,8 +17,8 @@
 
 import com.google.gwt.requestfactory.shared.DataTransferObject;
 import com.google.gwt.requestfactory.shared.RequestData;
-import com.google.gwt.requestfactory.shared.Service;
 import com.google.gwt.valuestore.shared.Property;
+import com.google.gwt.valuestore.shared.PropertyReference;
 import com.google.gwt.valuestore.shared.Record;
 import com.google.gwt.valuestore.shared.WriteOperation;
 
@@ -30,6 +30,8 @@
 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;
 import java.util.Collection;
@@ -195,8 +197,18 @@
   /**
    * Encodes parameter value.
    */
-  public Object decodeParameterValue(Class<?> parameterType,
+  public Object decodeParameterValue(Type genericParameterType,
       String parameterValue) {
+    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 (String.class == parameterType) {
       return parameterValue;
     }
@@ -272,18 +284,17 @@
        * 2. Merge the following and the object resolution code in getEntityKey.
        * 3. Update the involvedKeys set.
        */ 
-      // TODO(amitmanjhi): shouldn't this be DataTransferObject.class?
-      Service service = parameterType.getAnnotation(Service.class);
+      DataTransferObject service = parameterType.getAnnotation(DataTransferObject.class);
       if (service != null) {
         Class<?> sClass = service.value();
-        String schemaAndId[] = parameterValue.toString().split("-", 2);
+        String schemaAndId[] = parameterValue.toString().split("-", 3);
         // ignore schema for now and use Property type
         String findMeth = null;
         try {
           findMeth = getMethodNameFromPropertyName(sClass.getSimpleName(),
               "find");
           Method meth = sClass.getMethod(findMeth, Long.class);
-          return meth.invoke(null, Long.valueOf(schemaAndId[1]));
+          return meth.invoke(null, Long.valueOf(schemaAndId[0]));
         } catch (NoSuchMethodException e) {
           e.printStackTrace();
           throw new IllegalArgumentException(
@@ -522,7 +533,7 @@
    * or null if it is a static method. Returns Object[1] as the params array.
    */
   public Object[][] getObjectsFromParameterMap(boolean isInstanceMethod,
-      Map<String, String> parameterMap, Class<?> parameterClasses[]) {
+      Map<String, String> parameterMap, Type parameterClasses[]) {
     // TODO: create an EntityMethodCall (instance, args) instead.
     assert parameterClasses != null;
     Object args[][] = new Object[2][];
@@ -537,9 +548,9 @@
     
     // TODO: update the involvedKeys for other params
     int offset = (isInstanceMethod ? 1 : 0);
-    args[1] = new Object[parameterClasses.length];
-    for (int i = 0; i < parameterClasses.length; i++) {
-      args[1][i] = decodeParameterValue(parameterClasses[i],
+    args[1] = new Object[parameterClasses.length - offset];
+    for (int i = 0; i < parameterClasses.length - offset; i++) {
+      args[1][i] = decodeParameterValue(parameterClasses[i + offset],
           parameterMap.get(RequestData.PARAM_TOKEN + (i + offset)));
     }
     return args;
@@ -655,11 +666,8 @@
     }
     // get the domain object (for instance methods) and args.
     Object args[][] = getObjectsFromParameterMap(operation.isInstance(),
-        getParameterMap(topLevelJsonObject), domainMethod.getParameterTypes());
-
-    // the involvedKeys set is complete at this point.
-
-    // Construct beforeDataMap
+        getParameterMap(topLevelJsonObject), operation.getRequestParameterTypes());
+    // Construct beforeDataMap 
     constructBeforeDataMap();
     // Construct afterDvsDataMap.
     constructAfterDvsDataMap();
diff --git a/user/src/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistry.java b/user/src/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistry.java
index 1dc2734..fddd605 100644
--- a/user/src/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistry.java
+++ b/user/src/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistry.java
@@ -73,6 +73,10 @@
       return domainMethod.getParameterTypes();
     }
 
+    public Type[] getRequestParameterTypes() {
+      return requestMethod.getGenericParameterTypes();
+    }
+
     public Class<?> getReturnType() {
       Class<?> domainReturnType = getReturnTypeFromParameter(domainMethod,
           domainMethod.getGenericReturnType());
diff --git a/user/src/com/google/gwt/requestfactory/server/RequestDefinition.java b/user/src/com/google/gwt/requestfactory/server/RequestDefinition.java
index f0ec51c..0c707df 100644
--- a/user/src/com/google/gwt/requestfactory/server/RequestDefinition.java
+++ b/user/src/com/google/gwt/requestfactory/server/RequestDefinition.java
@@ -15,6 +15,8 @@
  */
 package com.google.gwt.requestfactory.server;
 
+import java.lang.reflect.Type;
+
 /**
  * <p>
  * <span style="color:red">Experimental API: This class is still under rapid
@@ -41,6 +43,8 @@
    */
   Class<?>[] getParameterTypes();
 
+  Type[] getRequestParameterTypes();
+
   /**
    * Returns the return type of the method to be invoked on the server.
    */
diff --git a/user/test/com/google/gwt/valuestore/client/RequestFactoryTest.java b/user/test/com/google/gwt/valuestore/client/RequestFactoryTest.java
index 5833934..1fa3c73 100644
--- a/user/test/com/google/gwt/valuestore/client/RequestFactoryTest.java
+++ b/user/test/com/google/gwt/valuestore/client/RequestFactoryTest.java
@@ -118,4 +118,28 @@
           }
         });
   }
-}
\ No newline at end of file
+
+  public void testRecordsAsInstanceMethodParams() {
+
+    final SimpleRequestFactory req = GWT.create(SimpleRequestFactory.class);
+    HandlerManager hm = new HandlerManager(null);
+    req.init(hm);
+    delayTestFinish(5000);
+    req.simpleFooRequest().findSimpleFooById(999L).fire(
+        new Receiver<SimpleFooRecord>() {
+          public void onSuccess(SimpleFooRecord response,
+              Set<SyncResult> syncResult) {
+            SimpleBarRecord bar = (SimpleBarRecord) req.create(SimpleBarRecord.class);
+            RequestObject<String> helloReq = req.simpleFooRequest().hello(response, bar);
+            bar = helloReq.edit(bar);
+            helloReq.fire(new Receiver<String>() {
+              public void onSuccess(String response,
+                  Set<SyncResult> syncResults) {
+                assertEquals("Greetings FOO from GWT", response);
+                finishTest();
+              }
+            });
+          }
+        });
+  }
+}
diff --git a/user/test/com/google/gwt/valuestore/server/SimpleFoo.java b/user/test/com/google/gwt/valuestore/server/SimpleFoo.java
index bd0a625..d7c6639 100644
--- a/user/test/com/google/gwt/valuestore/server/SimpleFoo.java
+++ b/user/test/com/google/gwt/valuestore/server/SimpleFoo.java
@@ -52,6 +52,10 @@
     return singleton;
   }
 
+  public String hello(SimpleBar bar) {
+    return "Greetings " + bar.getUserName() + " from " + getUserName();  
+  }
+
   public static void reset() {
     singleton = new SimpleFoo();
   }
diff --git a/user/test/com/google/gwt/valuestore/shared/SimpleFooRequest.java b/user/test/com/google/gwt/valuestore/shared/SimpleFooRequest.java
index b532b99..76ed88f 100644
--- a/user/test/com/google/gwt/valuestore/shared/SimpleFooRequest.java
+++ b/user/test/com/google/gwt/valuestore/shared/SimpleFooRequest.java
@@ -36,4 +36,7 @@
 
   @Instance
   RequestObject<Void> persist(SimpleFooRecord record);
+
+  @Instance
+  RequestObject<String> hello(SimpleFooRecord instance, SimpleBarRecord record);
 }