[jbpm-commits] JBoss JBPM SVN: r2756 - in projects/gwt-console/trunk: rpc/src/main/java/org/jboss/bpm/console and 15 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Tue Nov 4 05:09:12 EST 2008


Author: heiko.braun at jboss.com
Date: 2008-11-04 05:09:12 -0500 (Tue, 04 Nov 2008)
New Revision: 2756

Added:
   projects/gwt-console/trunk/rpc/src/main/java/org/jboss/bpm/console/server/
   projects/gwt-console/trunk/rpc/src/main/java/org/jboss/bpm/console/server/gson/
   projects/gwt-console/trunk/rpc/src/main/java/org/jboss/bpm/console/server/gson/GsonFactory.java
   projects/gwt-console/trunk/rpc/src/main/java/org/jboss/bpm/console/server/gson/SQLDateTypeAdapter.java
   projects/gwt-console/trunk/war/src/main/java/com/
   projects/gwt-console/trunk/war/src/main/java/com/google/
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/CamelCaseSeparatorNamingPolicy.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/CompositionFieldNamingPolicy.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/DefaultTypeAdapters.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/DelegatingJsonElementVisitor.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/DisjunctionExclusionStrategy.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/Escaper.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/ExclusionStrategy.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/ExposeAnnotationBasedExclusionStrategy.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/FieldNamingPolicy.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/FieldNamingStrategy.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/GenericArrayTypeImpl.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/Gson.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/GsonBuilder.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/InnerClassExclusionStrategy.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/InstanceCreator.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JavaFieldNamingPolicy.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonArray.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonArrayDeserializationVisitor.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonCompactFormatter.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializationContext.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializationContextDefault.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializationVisitor.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializer.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializerExceptionWrapper.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonElement.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonElementVisitor.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonEscapingVisitor.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonFieldNameValidator.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonFormatter.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonNull.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonObject.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonObjectDeserializationVisitor.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonParseException.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonParser.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonParserConstants.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonParserTokenManager.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonPrimitive.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonPrimitiveDeserializationVisitor.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonPrintFormatter.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializationContext.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializationContextDefault.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializationVisitor.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializer.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializerExceptionWrapper.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonTreeNavigator.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/LowerCamelCaseSeparatorNamingPolicy.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/LowerCaseNamingPolicy.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/MappedObjectConstructor.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/MemoryRefStack.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/ModifierBasedExclusionStrategy.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/ModifyFirstLetterNamingPolicy.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/NullExclusionStrategy.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/ObjectConstructor.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/ObjectNavigator.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/ObjectNavigatorFactory.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/ParameterizedTypeHandlerMap.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/ParameterizedTypeImpl.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/ParseException.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/Preconditions.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/PrimitiveTypeAdapter.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/Primitives.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/RecursiveFieldNamingPolicy.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/SerializedNameAnnotationInterceptingNamingPolicy.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/SimpleCharStream.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/StringUnmarshaller.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/Token.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/TokenMgrError.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeAdapter.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeAdapterNotRequired.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeInfo.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeInfoArray.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeInfoFactory.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeInfoMap.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeUtils.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/UpperCaseNamingPolicy.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/VersionConstants.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/VersionExclusionStrategy.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/annotations/
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/annotations/Expose.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/annotations/SerializedName.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/annotations/Since.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/annotations/package-info.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/package-info.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/reflect/
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/reflect/TypeToken.java
   projects/gwt-console/trunk/war/src/main/java/com/google/gson/reflect/package-info.java
Removed:
   projects/gwt-console/trunk/server/src/main/java/org/jboss/bpm/console/server/gson/
Modified:
   projects/gwt-console/trunk/rpc/pom.xml
   projects/gwt-console/trunk/war/pom.xml
   projects/gwt-console/trunk/war/src/main/java/org/jboss/bpm/console/client/model/DTOParser.java
   projects/gwt-console/trunk/war/src/main/java/org/jboss/bpm/console/client/process/ProcessDefinitionList.java
   projects/gwt-console/trunk/war/src/main/java/org/jboss/bpm/console/client/process/ProcessDefinitionListEditor.java
   projects/gwt-console/trunk/war/src/main/java/org/jboss/bpm/console/client/widgets/RemoteListView.java
   projects/gwt-console/trunk/war/src/main/resources/org/jboss/bpm/console/Application.gwt.xml
   projects/gwt-console/trunk/war/src/test/java/org/jboss/bpm/console/client/GwtTestApplication.java
   projects/gwt-console/trunk/war/src/test/java/org/jboss/bpm/console/client/GwtTestDTOParser.java
Log:
Cleanup test cases

Modified: projects/gwt-console/trunk/rpc/pom.xml
===================================================================
--- projects/gwt-console/trunk/rpc/pom.xml	2008-11-01 21:27:26 UTC (rev 2755)
+++ projects/gwt-console/trunk/rpc/pom.xml	2008-11-04 10:09:12 UTC (rev 2756)
@@ -30,6 +30,10 @@
          <scope>provided</scope>
       </dependency>
       <dependency>
+         <groupId>com.google.code.gson</groupId>
+         <artifactId>gson</artifactId>
+      </dependency>
+      <dependency>
          <groupId>javax.xml.bind</groupId>
          <artifactId>jaxb-api</artifactId>
          <scope>provided</scope>

Added: projects/gwt-console/trunk/rpc/src/main/java/org/jboss/bpm/console/server/gson/GsonFactory.java
===================================================================
--- projects/gwt-console/trunk/rpc/src/main/java/org/jboss/bpm/console/server/gson/GsonFactory.java	                        (rev 0)
+++ projects/gwt-console/trunk/rpc/src/main/java/org/jboss/bpm/console/server/gson/GsonFactory.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,40 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.bpm.console.server.gson;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+/**
+ * @author Heiko.Braun <heiko.braun at jboss.com>
+ */
+public class GsonFactory
+{
+   public static Gson createInstance()
+   {
+      Gson gson = new GsonBuilder()
+        .setDateFormat("y-M-d HH:mm:ss")
+        .registerTypeAdapter(java.sql.Timestamp.class, new SQLDateTypeAdapter()) 
+        .create();
+      return gson;
+   }
+}

Added: projects/gwt-console/trunk/rpc/src/main/java/org/jboss/bpm/console/server/gson/SQLDateTypeAdapter.java
===================================================================
--- projects/gwt-console/trunk/rpc/src/main/java/org/jboss/bpm/console/server/gson/SQLDateTypeAdapter.java	                        (rev 0)
+++ projects/gwt-console/trunk/rpc/src/main/java/org/jboss/bpm/console/server/gson/SQLDateTypeAdapter.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,69 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.bpm.console.server.gson;
+
+import com.google.gson.*;
+
+import java.util.Date;
+import java.text.*;
+import java.lang.reflect.Type;
+
+
+/**
+ * A default type adapter for a {@link java.util.Date} object.<br>
+ * Create a GSON instance that can serialize/deserialize "java.util.Date" objects:
+ * <pre>
+ * Gson gson = new GsonBuilder()
+ * .registerTypeAdapter(new DateTypeAdapter())
+ * .create();
+ * </pre>
+ *
+ * @author Joel Leitch
+ */
+public class SQLDateTypeAdapter implements JsonSerializer<java.sql.Timestamp>, JsonDeserializer<Date>
+{
+   private final DateFormat format = new SimpleDateFormat("y-M-d HH:mm:ss");
+
+   public JsonElement serialize(java.sql.Timestamp src, Type typeOfSrc, JsonSerializationContext context)
+   {
+      String dateFormatAsString = format.format(src);
+      return new JsonPrimitive(dateFormatAsString);
+   }
+
+   public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+     throws JsonParseException
+   {
+      if (!(json instanceof JsonPrimitive)) {
+         throw new JsonParseException("The date should be a string value");
+      }
+
+      try
+      {
+         return format.parse(json.getAsString());
+      }
+      catch (ParseException e)
+      {
+         throw new JsonParseException(e);
+      }
+
+   }
+}

Modified: projects/gwt-console/trunk/war/pom.xml
===================================================================
--- projects/gwt-console/trunk/war/pom.xml	2008-11-01 21:27:26 UTC (rev 2755)
+++ projects/gwt-console/trunk/war/pom.xml	2008-11-04 10:09:12 UTC (rev 2756)
@@ -1,206 +1,205 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project>
-    <modelVersion>4.0.0</modelVersion>
-    <name>JBoss jBPM3 - GWT Console (WAR)</name>
-    <groupId>org.jbpm.jbpm3</groupId>
-    <artifactId>gwt-console</artifactId>
-    <packaging>war</packaging>
+   <modelVersion>4.0.0</modelVersion>
+   <name>JBoss jBPM3 - GWT Console (WAR)</name>
+   <groupId>org.jbpm.jbpm3</groupId>
+   <artifactId>gwt-console</artifactId>
+   <packaging>war</packaging>
 
-    <!-- Parent -->
-    <parent>
-        <groupId>org.jbpm.jbpm3</groupId>
-        <artifactId>gwt-console-parent</artifactId>
-        <version>1.0.0-SNAPSHOT</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
+   <!-- Parent -->
+   <parent>
+      <groupId>org.jbpm.jbpm3</groupId>
+      <artifactId>gwt-console-parent</artifactId>
+      <version>1.0.0-SNAPSHOT</version>
+      <relativePath>../pom.xml</relativePath>
+   </parent>
 
-    <!--  Dependencies -->
-    <dependencies>
+   <!--  Dependencies -->
+   <dependencies>
 
-        <dependency>
-            <groupId>org.jbpm.jbpm3</groupId>
-            <artifactId>gwt-console-rpc</artifactId>
-            <version>${version}</version>
-        </dependency>
+      <dependency>
+         <groupId>org.jbpm.jbpm3</groupId>
+         <artifactId>gwt-console-rpc</artifactId>
+         <version>${version}</version>
+      </dependency>
 
-        <dependency>
-            <groupId>com.google.gwt</groupId>
-            <artifactId>gwt-servlet</artifactId>
-            <version>${gwt.version}</version>
-            <scope>runtime</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.google.gwt</groupId>
-            <artifactId>gwt-user</artifactId>
-            <version>${gwt.version}</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.google.gwt</groupId>
-            <artifactId>gwt-dev</artifactId>
-            <version>${gwt.version}</version>
-            <classifier>${platform}-libs</classifier>
-            <type>zip</type>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.google.gwt</groupId>
-            <artifactId>gwt-dev</artifactId>
-            <version>${gwt.version}</version>
-            <classifier>${platform}</classifier>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.gwtext</groupId>
-            <artifactId>gwtext</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.google.gwt</groupId>
-            <artifactId>gchart</artifactId>
-        </dependency>
+      <dependency>
+         <groupId>com.google.gwt</groupId>
+         <artifactId>gwt-servlet</artifactId>
+         <version>${gwt.version}</version>
+         <scope>runtime</scope>
+      </dependency>
+      <dependency>
+         <groupId>com.google.gwt</groupId>
+         <artifactId>gwt-user</artifactId>
+         <version>${gwt.version}</version>
+         <scope>provided</scope>
+      </dependency>
+      <dependency>
+         <groupId>com.google.gwt</groupId>
+         <artifactId>gwt-dev</artifactId>
+         <version>${gwt.version}</version>
+         <classifier>${platform}-libs</classifier>
+         <type>zip</type>
+         <scope>provided</scope>
+      </dependency>
+      <dependency>
+         <groupId>com.google.gwt</groupId>
+         <artifactId>gwt-dev</artifactId>
+         <version>${gwt.version}</version>
+         <classifier>${platform}</classifier>
+         <scope>provided</scope>
+      </dependency>
+      <dependency>
+         <groupId>com.gwtext</groupId>
+         <artifactId>gwtext</artifactId>
+      </dependency>
+      <dependency>
+         <groupId>com.google.gwt</groupId>
+         <artifactId>gchart</artifactId>
+      </dependency>
 
-        <dependency>
-            <groupId>javax.xml.stream</groupId>
-            <artifactId>stax-api</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>javax.activation</groupId>
-            <artifactId>activation</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
+      <dependency>
+         <groupId>javax.xml.stream</groupId>
+         <artifactId>stax-api</artifactId>
+         <scope>provided</scope>
+      </dependency>
+      <dependency>
+         <groupId>javax.activation</groupId>
+         <artifactId>activation</artifactId>
+         <scope>provided</scope>
+      </dependency>
+      <dependency>
+         <groupId>junit</groupId>
+         <artifactId>junit</artifactId>
+         <scope>test</scope>
+      </dependency>
+   </dependencies>
 
-    <!-- Plugins -->
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>com.totsp.gwt</groupId>
-                <artifactId>maven-googlewebtoolkit2-plugin</artifactId>
-                <version>2.0-beta24</version>
-                <configuration>
-                    <logLevel>INFO</logLevel>
-                    <compileTargets><value>org.jboss.bpm.console.Application</value></compileTargets>
-                    <runTarget>org.jboss.bpm.console.Application/Application.html</runTarget>
-                    <style>DETAILED</style>
-                    <noServer>false</noServer>
-                    <extraJvmArgs>-Xmx256M -Xms256M</extraJvmArgs>
-                    <!--  this parameter is VERY important with automatic mode -
-                          has to match the version in your declared deps
-                          if this is set incorrect, or left out and default does not match
-                          (default is 1.5.2 for 2.0-beta23) you will have mysterious errors
-                    -->
-                    <gwtVersion>${gwt.version}</gwtVersion>
-                </configuration>
-                <executions>
-                    <execution>
-                        <goals>
-                            <goal>mergewebxml</goal>
-                            <goal>compile</goal>
-                            <goal>gwt</goal>
-                            <goal>test</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-            <!--  Use the dependency plugin to unpack gwt-dev-PLATFORM-libs.zip -->
-            <!--
-               (this is a replacement for the old "automatic" mode - useful if you
-               don't have GWT installed already, or you just want a maven way to
-               handle gwt deps)
-            -->
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-dependency-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>unpack</id>
-                        <phase>compile</phase>
-                        <goals>
-                            <goal>unpack</goal>
-                        </goals>
-                        <configuration>
-                            <artifactItems>
-                                <artifactItem>
-                                    <groupId>com.google.gwt</groupId>
-                                    <artifactId>gwt-dev</artifactId>
-                                    <version>${gwtVersion}</version>
-                                    <classifier>${platform}-libs</classifier>
-                                    <type>zip</type>
-                                    <overWrite>false</overWrite>
-                                    <outputDirectory>${settings.localRepository}/com/google/gwt/gwt-dev/${gwtVersion}</outputDirectory>
-                                </artifactItem>
-                            </artifactItems>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-            <!--
-               If you want to use the target/web.xml file mergewebxml produces,
-               tell the war plugin to use it
-            -->
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-war-plugin</artifactId>
-                <configuration>
-                    <webXml>target/web.xml</webXml>
-                    <warSourceExcludes>.gwt-tmp/**</warSourceExcludes>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <source>1.5</source>
-                    <target>1.5</target>
-                </configuration>
-            </plugin>
-        </plugins>
+   <!-- Plugins -->
+   <build>
+      <plugins>
+         <plugin>
+            <groupId>com.totsp.gwt</groupId>
+            <artifactId>maven-googlewebtoolkit2-plugin</artifactId>
+            <version>2.0-beta24</version>
+            <configuration>
+               <logLevel>INFO</logLevel>
+               <compileTargets><value>org.jboss.bpm.console.Application</value></compileTargets>
+               <runTarget>org.jboss.bpm.console.Application/Application.html</runTarget>
+               <style>DETAILED</style>
+               <noServer>false</noServer>
+               <extraJvmArgs>-Xmx256M -Xms256M</extraJvmArgs>
+               <!--  this parameter is VERY important with automatic mode -
+                     has to match the version in your declared deps
+                     if this is set incorrect, or left out and default does not match
+                     (default is 1.5.2 for 2.0-beta23) you will have mysterious errors
+               -->
+               <gwtVersion>${gwt.version}</gwtVersion>
+            </configuration>
+            <executions>
+               <execution>
+                  <goals>
+                     <goal>mergewebxml</goal>
+                     <goal>compile</goal>
+                     <goal>gwt</goal>
+                     <goal>test</goal>
+                  </goals>
+               </execution>
+            </executions>
+         </plugin>
+         <!--  Use the dependency plugin to unpack gwt-dev-PLATFORM-libs.zip -->
+         <!--
+            (this is a replacement for the old "automatic" mode - useful if you
+            don't have GWT installed already, or you just want a maven way to
+            handle gwt deps)
+         -->
+         <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-dependency-plugin</artifactId>
+            <executions>
+               <execution>
+                  <id>unpack</id>
+                  <phase>compile</phase>
+                  <goals>
+                     <goal>unpack</goal>
+                  </goals>
+                  <configuration>
+                     <artifactItems>
+                        <artifactItem>
+                           <groupId>com.google.gwt</groupId>
+                           <artifactId>gwt-dev</artifactId>
+                           <version>${gwtVersion}</version>
+                           <classifier>${platform}-libs</classifier>
+                           <type>zip</type>
+                           <overWrite>false</overWrite>
+                           <outputDirectory>${settings.localRepository}/com/google/gwt/gwt-dev/${gwtVersion}</outputDirectory>
+                        </artifactItem>
+                     </artifactItems>
+                  </configuration>
+               </execution>
+            </executions>
+         </plugin>
+         <!--
+            If you want to use the target/web.xml file mergewebxml produces,
+            tell the war plugin to use it
+         -->
+         <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-war-plugin</artifactId>
+            <configuration>
+               <webXml>target/web.xml</webXml>
+               <warSourceExcludes>.gwt-tmp/**</warSourceExcludes>
+            </configuration>
+         </plugin>
+         <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-compiler-plugin</artifactId>
+            <configuration>
+               <source>1.5</source>
+               <target>1.5</target>
+            </configuration>
+         </plugin>
+      </plugins>
+   </build>
 
-    </build>
-
-    <!--  profiles (with activation per platform) -->
-    <profiles>
-        <profile>
-            <id>gwt-dev-windows</id>
-            <properties>
-                <platform>windows</platform>
-            </properties>
-            <activation>
-                <activeByDefault>true</activeByDefault>
-                <os>
-                    <family>windows</family>
-                </os>
-            </activation>
-        </profile>
-        <profile>
-            <id>gwt-dev-mac</id>
-            <properties>
-                <platform>mac</platform>
-            </properties>
-            <activation>
-                <activeByDefault>false</activeByDefault>
-                <os>
-                    <family>mac</family>
-                </os>
-            </activation>
-        </profile>
-        <profile>
-            <id>gwt-dev-linux</id>
-            <properties>
-                <platform>linux</platform>
-            </properties>
-            <activation>
-                <activeByDefault>false</activeByDefault>
-                <os>
-                    <name>linux</name>
-                </os>
-            </activation>
-        </profile>
-    </profiles>
+   <!--  profiles (with activation per platform) -->
+   <profiles>
+      <profile>
+         <id>gwt-dev-windows</id>
+         <properties>
+            <platform>windows</platform>
+         </properties>
+         <activation>
+            <activeByDefault>true</activeByDefault>
+            <os>
+               <family>windows</family>
+            </os>
+         </activation>
+      </profile>
+      <profile>
+         <id>gwt-dev-mac</id>
+         <properties>
+            <platform>mac</platform>
+         </properties>
+         <activation>
+            <activeByDefault>false</activeByDefault>
+            <os>
+               <family>mac</family>
+            </os>
+         </activation>
+      </profile>
+      <profile>
+         <id>gwt-dev-linux</id>
+         <properties>
+            <platform>linux</platform>
+         </properties>
+         <activation>
+            <activeByDefault>false</activeByDefault>
+            <os>
+               <name>linux</name>
+            </os>
+         </activation>
+      </profile>
+   </profiles>
 </project>

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/CamelCaseSeparatorNamingPolicy.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/CamelCaseSeparatorNamingPolicy.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/CamelCaseSeparatorNamingPolicy.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+/**
+ * Converts the field name that uses camel-case define word separation into separate words that
+ * are separated by the provided {@code separatorString}.
+ *
+ * <p>The following is an example:</p>
+ * <pre>
+ * class IntWrapper {
+ *   public int integerField = 0;
+ * }
+ *
+ * CamelCaseSeparatorNamingPolicy policy = new CamelCaseSeparatorNamingPolicy("_");
+ * String translatedFieldName =
+ *     policy.translateName(IntWrapper.class.getField("integerField"));
+ *
+ * assert("integer_Field".equals(translatedFieldName));
+ * </pre>
+ *
+ * @author Joel Leitch
+ */
+final class CamelCaseSeparatorNamingPolicy extends RecursiveFieldNamingPolicy {
+  private final String separatorString;
+
+  /**
+   * Constructs a new CamelCaseSeparatorNamingPolicy object that will add the
+   * {@code separatorString} between each of the words separated by camel case.
+   *
+   * @param separatorString the string value to place between words
+   * @throws IllegalArgumentException thrown if the {@code separatorString} parameter
+   *         is null or purely whitespace.
+   */
+  public CamelCaseSeparatorNamingPolicy(String separatorString) {
+    Preconditions.checkNotNull(separatorString);
+    Preconditions.checkArgument(!"".equals(separatorString.trim()));
+    this.separatorString = separatorString;
+  }
+
+  @Override
+  protected String translateName(String target, Type fieldType, Annotation[] annnotations) {
+    StringBuilder translation = new StringBuilder();
+    for (int i = 0; i < target.length(); i++) {
+      char character = target.charAt(i);
+      if (Character.isUpperCase(character) && translation.length() != 0) {
+        translation.append(separatorString);
+      }
+      translation.append(character);
+    }
+
+    return translation.toString();
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/CompositionFieldNamingPolicy.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/CompositionFieldNamingPolicy.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/CompositionFieldNamingPolicy.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+/**
+ * Performs numerous field naming translations wrapped up as one object.
+ *
+ * @author Joel Leitch
+ */
+abstract class CompositionFieldNamingPolicy extends RecursiveFieldNamingPolicy {
+
+  private final RecursiveFieldNamingPolicy[] fieldPolicies;
+
+  public CompositionFieldNamingPolicy(RecursiveFieldNamingPolicy... fieldNamingPolicies) {
+    if (fieldNamingPolicies == null) {
+      throw new NullPointerException("naming policies can not be null.");
+    }
+    this.fieldPolicies = fieldNamingPolicies;
+  }
+
+  @Override
+  protected String translateName(String target, Type fieldType, Annotation[] annotations) {
+    for (RecursiveFieldNamingPolicy policy : fieldPolicies) {
+      target = policy.translateName(target, fieldType, annotations);
+    }
+    return target;
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/DefaultTypeAdapters.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/DefaultTypeAdapters.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/DefaultTypeAdapters.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+
+/**
+ * List of all the default type adapters ({@link JsonSerializer}s, {@link JsonDeserializer}s,
+ * and {@link InstanceCreator}s.
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+final class DefaultTypeAdapters {
+
+  private static final DefaultDateTypeAdapter DATE_TYPE_ADAPTER =
+    new DefaultDateTypeAdapter(DateFormat.getDateTimeInstance());
+  @SuppressWarnings("unchecked")
+  private static final EnumTypeAdapter ENUM_TYPE_ADAPTER = new EnumTypeAdapter();
+  private static final UrlTypeAdapter URL_TYPE_ADAPTER = new UrlTypeAdapter();
+  private static final UriTypeAdapter URI_TYPE_ADAPTER = new UriTypeAdapter();
+  private static final LocaleTypeAdapter LOCALE_TYPE_ADAPTER = new LocaleTypeAdapter();
+  private static final MapTypeAdapter MAP_TYPE_ADAPTER = new MapTypeAdapter();
+  private static final BigDecimalTypeAdapter BIG_DECIMAL_TYPE_ADAPTER = new BigDecimalTypeAdapter();
+  private static final BigIntegerTypeAdapter BIG_INTEGER_TYPE_ADAPTER = new BigIntegerTypeAdapter();
+
+  private static final BooleanCreator BOOLEAN_CREATOR = new BooleanCreator();
+  private static final ByteCreator BYTE_CREATOR = new ByteCreator();
+  private static final CharacterCreator CHARACTER_CREATOR = new CharacterCreator();
+  private static final DoubleCreator DOUBLE_CREATOR = new DoubleCreator();
+  private static final FloatCreator FLOAT_CREATOR = new FloatCreator();
+  private static final IntegerCreator INTEGER_CREATOR = new IntegerCreator();
+  private static final LongCreator LONG_CREATOR = new LongCreator();
+  private static final ShortCreator SHORT_CREATOR = new ShortCreator();
+  private static final LinkedListCreator LINKED_LIST_CREATOR = new LinkedListCreator();
+  private static final TreeSetCreator TREE_SET_CREATOR = new TreeSetCreator();
+
+  // The constants DEFAULT_SERIALIZERS, DEFAULT_DESERIALIZERS, and DEFAULT_INSTANCE_CREATORS
+  // must be defined after the constants for the type adapters. Otherwise, the type adapter
+  // constants will appear as nulls.
+  static final ParameterizedTypeHandlerMap<JsonSerializer<?>> DEFAULT_SERIALIZERS =
+    getDefaultSerializers();
+  static final ParameterizedTypeHandlerMap<JsonDeserializer<?>> DEFAULT_DESERIALIZERS =
+    getDefaultDeserializers();
+  static final ParameterizedTypeHandlerMap<InstanceCreator<?>> DEFAULT_INSTANCE_CREATORS =
+    getDefaultInstanceCreators();
+
+  private static ParameterizedTypeHandlerMap<JsonSerializer<?>> getDefaultSerializers() {
+    ParameterizedTypeHandlerMap<JsonSerializer<?>> map =
+      new ParameterizedTypeHandlerMap<JsonSerializer<?>>();
+
+    map.register(Enum.class, wrapSerializer(ENUM_TYPE_ADAPTER));
+    map.register(URL.class, wrapSerializer(URL_TYPE_ADAPTER));
+    map.register(URI.class, wrapSerializer(URI_TYPE_ADAPTER));
+    map.register(Locale.class, wrapSerializer(LOCALE_TYPE_ADAPTER));
+    map.register(Map.class, wrapSerializer(MAP_TYPE_ADAPTER));
+    map.register(Date.class, wrapSerializer(DATE_TYPE_ADAPTER));
+    map.register(BigDecimal.class, wrapSerializer(BIG_DECIMAL_TYPE_ADAPTER));
+    map.register(BigInteger.class, wrapSerializer(BIG_INTEGER_TYPE_ADAPTER));
+    map.makeUnmodifiable();
+    return map;
+  }
+
+  private static ParameterizedTypeHandlerMap<JsonDeserializer<?>> getDefaultDeserializers() {
+    ParameterizedTypeHandlerMap<JsonDeserializer<?>> map =
+      new ParameterizedTypeHandlerMap<JsonDeserializer<?>>();
+    map.register(Enum.class, wrapDeserializer(ENUM_TYPE_ADAPTER));
+    map.register(URL.class, wrapDeserializer(URL_TYPE_ADAPTER));
+    map.register(URI.class, wrapDeserializer(URI_TYPE_ADAPTER));
+    map.register(Locale.class, wrapDeserializer(LOCALE_TYPE_ADAPTER));
+    map.register(Map.class, wrapDeserializer(MAP_TYPE_ADAPTER));
+    map.register(Date.class, wrapDeserializer(DATE_TYPE_ADAPTER));
+    map.register(BigDecimal.class, wrapDeserializer(BIG_DECIMAL_TYPE_ADAPTER));
+    map.register(BigInteger.class, wrapDeserializer(BIG_INTEGER_TYPE_ADAPTER));
+    map.makeUnmodifiable();
+    return map;
+  }
+
+  private static ParameterizedTypeHandlerMap<InstanceCreator<?>> getDefaultInstanceCreators() {
+    ParameterizedTypeHandlerMap<InstanceCreator<?>> map =
+      new ParameterizedTypeHandlerMap<InstanceCreator<?>>();
+    map.register(Enum.class, ENUM_TYPE_ADAPTER);
+    map.register(URL.class, URL_TYPE_ADAPTER);
+    map.register(Locale.class, LOCALE_TYPE_ADAPTER);
+    map.register(Map.class, MAP_TYPE_ADAPTER);
+    map.register(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER);
+    map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER);
+
+    // Add primitive instance creators
+    map.register(Boolean.class, BOOLEAN_CREATOR);
+    map.register(boolean.class, BOOLEAN_CREATOR);
+    map.register(Byte.class, BYTE_CREATOR);
+    map.register(byte.class, BYTE_CREATOR);
+    map.register(Character.class, CHARACTER_CREATOR);
+    map.register(char.class, CHARACTER_CREATOR);
+    map.register(Double.class, DOUBLE_CREATOR);
+    map.register(double.class, DOUBLE_CREATOR);
+    map.register(Float.class, FLOAT_CREATOR);
+    map.register(float.class, FLOAT_CREATOR);
+    map.register(Integer.class, INTEGER_CREATOR);
+    map.register(int.class, INTEGER_CREATOR);
+    map.register(Long.class, LONG_CREATOR);
+    map.register(long.class, LONG_CREATOR);
+    map.register(Short.class, SHORT_CREATOR);
+    map.register(short.class, SHORT_CREATOR);
+
+    map.register(Collection.class, LINKED_LIST_CREATOR);
+    map.register(List.class, LINKED_LIST_CREATOR);
+    map.register(Queue.class, LINKED_LIST_CREATOR);
+
+    map.register(Set.class, TREE_SET_CREATOR);
+    map.register(SortedSet.class, TREE_SET_CREATOR);
+    map.makeUnmodifiable();
+    return map;
+  }
+
+  @SuppressWarnings("unchecked")
+  private static JsonSerializer<?> wrapSerializer(JsonSerializer<?> serializer) {
+    return new JsonSerializerExceptionWrapper(serializer);
+  }
+
+  @SuppressWarnings("unchecked")
+  private static JsonDeserializer<?> wrapDeserializer(JsonDeserializer<?> deserializer) {
+    return new JsonDeserializerExceptionWrapper(deserializer);
+  }
+
+  static class DefaultDateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
+
+    private final DateFormat format;
+
+    public DefaultDateTypeAdapter(String datePattern) {
+      this.format = new SimpleDateFormat(datePattern);
+    }
+    
+    DefaultDateTypeAdapter(DateFormat format) {
+      this.format = format;
+    }
+
+    public DefaultDateTypeAdapter(int style) {
+      this.format = DateFormat.getDateInstance(style);
+    }
+
+    public DefaultDateTypeAdapter(int dateStyle, int timeStyle) {
+      this.format = DateFormat.getDateTimeInstance(dateStyle, timeStyle);
+    }
+
+    public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
+      String dateFormatAsString = format.format(src);
+      return new JsonPrimitive(dateFormatAsString);
+    }
+
+    public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+        throws JsonParseException {
+      if (!(json instanceof JsonPrimitive)) {
+        throw new JsonParseException("The date should be a string value");
+      }
+
+      try {
+        return format.parse(json.getAsString());
+      } catch (ParseException e) {
+        throw new JsonParseException(e);
+      }
+    }
+    
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder();
+      sb.append(DefaultDateTypeAdapter.class.getSimpleName());
+      sb.append('(').append(format.getClass().getSimpleName()).append(')');
+      return sb.toString();
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  private static class EnumTypeAdapter<T extends Enum<T>> implements JsonSerializer<T>,
+      JsonDeserializer<T>, InstanceCreator<Enum<?>> {
+    public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) {
+      return new JsonPrimitive(src.name());
+    }
+    @SuppressWarnings("cast")
+    public T deserialize(JsonElement json, Type classOfT, JsonDeserializationContext context)
+        throws JsonParseException {
+      return (T) Enum.valueOf((Class<T>)classOfT, json.getAsString());
+    }
+    public Enum<?> createInstance(Type type) {
+      Class<Enum<?>> enumClass = (Class<Enum<?>>) type;
+      try {
+        Method valuesMethod = enumClass.getMethod("values");
+        Enum<?>[] enums = (Enum<?>[]) valuesMethod.invoke(null);
+        return enums[0];
+      } catch (NoSuchMethodException e) {
+        throw new RuntimeException(e);
+      } catch (IllegalAccessException e) {
+        throw new RuntimeException(e);
+      } catch (InvocationTargetException e) {
+        throw new RuntimeException(e);
+      }
+    }
+    @Override
+    public String toString() {
+      return EnumTypeAdapter.class.getSimpleName();
+    }
+  }
+
+  private static class UrlTypeAdapter implements JsonSerializer<URL>, JsonDeserializer<URL>,
+      InstanceCreator<URL> {
+    public JsonElement serialize(URL src, Type typeOfSrc, JsonSerializationContext context) {
+      return new JsonPrimitive(src.toExternalForm());
+    }
+    public URL deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+        throws JsonParseException {
+      try {
+        return new URL(json.getAsString());
+      } catch (MalformedURLException e) {
+        throw new JsonParseException(e);
+      }
+    }
+    public URL createInstance(Type type) {
+      try {
+        return new URL("http://google.com/");
+      } catch (MalformedURLException e) {
+        throw new RuntimeException(e);
+      }
+    }
+    @Override
+    public String toString() {
+      return UrlTypeAdapter.class.getSimpleName();
+    }    
+  }
+
+  private static class UriTypeAdapter implements JsonSerializer<URI>, JsonDeserializer<URI> {
+    public JsonElement serialize(URI src, Type typeOfSrc, JsonSerializationContext context) {
+      return new JsonPrimitive(src.toASCIIString());
+    }
+    public URI deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+    throws JsonParseException {
+      try {
+        return new URI(json.getAsString());
+      } catch (URISyntaxException e) {
+        throw new JsonParseException(e);
+      }
+    }
+    @Override
+    public String toString() {
+      return UriTypeAdapter.class.getSimpleName();
+    }
+  }
+
+  private static class LocaleTypeAdapter implements JsonSerializer<Locale>,
+      JsonDeserializer<Locale>, InstanceCreator<Locale> {
+    public JsonElement serialize(Locale src, Type typeOfSrc, JsonSerializationContext context) {
+      return new JsonPrimitive(src.toString());
+    }
+    public Locale deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+        throws JsonParseException {
+      String locale = json.getAsString();
+      StringTokenizer tokenizer = new StringTokenizer(locale, "_");
+      String language = null;
+      String country = null;
+      String variant = null;
+      if (tokenizer.hasMoreElements()) {
+        language = tokenizer.nextToken();
+      }
+      if (tokenizer.hasMoreElements()) {
+        country = tokenizer.nextToken();
+      }
+      if (tokenizer.hasMoreElements()) {
+        variant = tokenizer.nextToken();
+      }
+      if (country == null && variant == null) {
+        return new Locale(language);
+      } else if (variant == null) {
+        return new Locale(language, country);
+      } else {
+        return new Locale(language, country, variant);
+      }
+    }
+    public Locale createInstance(Type type) {
+      return new Locale("en_US");
+    }
+    @Override
+    public String toString() {
+      return LocaleTypeAdapter.class.getSimpleName();
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  static class MapTypeAdapter implements JsonSerializer<Map>, JsonDeserializer<Map>,
+      InstanceCreator<Map> {
+    public JsonElement serialize(Map src, Type typeOfSrc, JsonSerializationContext context) {
+      JsonObject map = new JsonObject();
+      Type childType = new TypeInfoMap(typeOfSrc).getValueType();
+      for (Iterator iterator = src.entrySet().iterator(); iterator.hasNext(); ) {
+        Map.Entry entry = (Map.Entry) iterator.next();
+        JsonElement valueElement = context.serialize(entry.getValue(), childType);
+        map.add(entry.getKey().toString(), valueElement);
+      }
+      return map;
+    }
+    public Map deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+        throws JsonParseException {
+      // Using linked hash map to preserve order in which elements are entered
+      Map<String, Object> map = new LinkedHashMap<String, Object>();
+      Type childType = new TypeInfoMap(typeOfT).getValueType();
+      for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
+        Object value = context.deserialize(entry.getValue(), childType);
+        map.put(entry.getKey(), value);
+      }
+      return map;
+    }
+    public Map createInstance(Type type) {
+      return new LinkedHashMap();
+    }
+    @Override
+    public String toString() {
+      return MapTypeAdapter.class.getSimpleName();
+    }
+  }
+
+  private static class BigDecimalTypeAdapter implements JsonSerializer<BigDecimal>,
+      JsonDeserializer<BigDecimal>, InstanceCreator<BigDecimal> {
+
+    public JsonElement serialize(BigDecimal src, Type typeOfSrc, JsonSerializationContext context) {
+      return new JsonPrimitive(src);
+    }
+
+    public BigDecimal deserialize(JsonElement json, Type typeOfT,
+        JsonDeserializationContext context) throws JsonParseException {
+      return json.getAsBigDecimal();
+    }
+
+    public BigDecimal createInstance(Type type) {
+      return new BigDecimal(0);
+    }
+    @Override
+    public String toString() {
+      return BigDecimalTypeAdapter.class.getSimpleName();
+    }
+  }
+
+  private static class BigIntegerTypeAdapter implements JsonSerializer<BigInteger>,
+      JsonDeserializer<BigInteger>, InstanceCreator<BigInteger> {
+
+    public JsonElement serialize(BigInteger src, Type typeOfSrc, JsonSerializationContext context) {
+      return new JsonPrimitive(src);
+    }
+
+    public BigInteger deserialize(JsonElement json, Type typeOfT,
+        JsonDeserializationContext context) throws JsonParseException {
+      return json.getAsBigInteger();
+    }
+
+    public BigInteger createInstance(Type type) {
+      return new BigInteger("0");
+    }
+    @Override
+    public String toString() {
+      return BigIntegerTypeAdapter.class.getSimpleName();
+    }
+  }
+
+  private static class LongCreator implements InstanceCreator<Long> {
+    public Long createInstance(Type type) {
+      return new Long(0L);
+    }
+    @Override
+    public String toString() {
+      return LongCreator.class.getSimpleName();
+    }
+  }
+
+  private static class IntegerCreator implements InstanceCreator<Integer> {
+    public Integer createInstance(Type type) {
+      return new Integer(0);
+    }
+    @Override
+    public String toString() {
+      return IntegerCreator.class.getSimpleName();
+    }
+  }
+
+  private static class ShortCreator implements InstanceCreator<Short> {
+    public Short createInstance(Type type) {
+      return new Short((short) 0);
+    }
+    @Override
+    public String toString() {
+      return ShortCreator.class.getSimpleName();
+    }
+  }
+
+  private static class ByteCreator implements InstanceCreator<Byte> {
+    public Byte createInstance(Type type) {
+      return new Byte((byte) 0);
+    }
+    @Override
+    public String toString() {
+      return ByteCreator.class.getSimpleName();
+    }
+  }
+
+  private static class FloatCreator implements InstanceCreator<Float> {
+    public Float createInstance(Type type) {
+      return new Float(0F);
+    }
+    @Override
+    public String toString() {
+      return FloatCreator.class.getSimpleName();
+    }
+  }
+
+  private static class DoubleCreator implements InstanceCreator<Double> {
+    public Double createInstance(Type type) {
+      return new Double(0D);
+    }
+    @Override
+    public String toString() {
+      return DoubleCreator.class.getSimpleName();
+    }
+  }
+
+  private static class CharacterCreator implements InstanceCreator<Character> {
+    public Character createInstance(Type type) {
+      return new Character((char) 0);
+    }
+    @Override
+    public String toString() {
+      return CharacterCreator.class.getSimpleName();
+    }
+  }
+
+  private static class BooleanCreator implements InstanceCreator<Boolean> {
+    public Boolean createInstance(Type type) {
+      return new Boolean(false);
+    }
+    @Override
+    public String toString() {
+      return BooleanCreator.class.getSimpleName();
+    }
+  }
+
+  private static class LinkedListCreator implements InstanceCreator<LinkedList<?>> {
+    public LinkedList<?> createInstance(Type type) {
+      return new LinkedList<Object>();
+    }
+    @Override
+    public String toString() {
+      return LinkedListCreator.class.getSimpleName();
+    }
+  }
+
+  private static class TreeSetCreator implements InstanceCreator<TreeSet<?>> {
+    public TreeSet<?> createInstance(Type type) {
+      return new TreeSet<Object>();
+    }
+    @Override
+    public String toString() {
+      return TreeSetCreator.class.getSimpleName();
+    }
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/DelegatingJsonElementVisitor.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/DelegatingJsonElementVisitor.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/DelegatingJsonElementVisitor.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+/**
+ * A simple implementation of the {@link JsonElementVisitor} that simply delegates the method
+ * invocation onto a {@code delegate} instance of the {@link JsonElementVisitor}.  This object
+ * can be used to build a chain of visitors such that each Visitor instance can perform some
+ * operation on the {@link JsonElement} and then pass on the input to the delegate.  This kind
+ * of pattern is sometimes referred as a "Chain of Responsibility".
+ *
+ * <p>The following is an example use case:
+ *
+ * <pre>
+ * class JsonEscapingVisitor extends DelegatingJsonElementVisitor {
+ *   public JsonEscapingVisitor(JsonElementVisitor) {
+ *     super(visitor);
+ *   }
+ *
+ *   public void visitPrimitive(JsonPrimitive primitive) {
+ *     JsonPrimitive escapedPrimitive = escapePrimitiveObject(primitive);
+ *     super.visitPrimitive(escapedPrimitive);
+ *   }
+ * }
+ *
+ * JsonElementVisitor visitor = new JsonEscapingVisitor(new FormattingVisitor());
+ * </pre></p>
+ *
+ * @author Joel Leitch
+ */
+class DelegatingJsonElementVisitor implements JsonElementVisitor {
+  private final JsonElementVisitor delegate;
+
+  protected DelegatingJsonElementVisitor(JsonElementVisitor delegate) {
+    Preconditions.checkNotNull(delegate);
+    this.delegate = delegate;
+  }
+
+  public void endArray(JsonArray array) {
+    delegate.endArray(array);
+  }
+
+  public void endObject(JsonObject object) {
+    delegate.endObject(object);
+  }
+
+  public void startArray(JsonArray array) {
+    delegate.startArray(array);
+  }
+
+  public void startObject(JsonObject object) {
+    delegate.startObject(object);
+  }
+
+  public void visitArrayMember(JsonArray parent, JsonPrimitive member, boolean isFirst) {
+    delegate.visitArrayMember(parent, member, isFirst);
+  }
+
+  public void visitArrayMember(JsonArray parent, JsonArray member, boolean isFirst) {
+    delegate.visitArrayMember(parent, member, isFirst);
+  }
+
+  public void visitArrayMember(JsonArray parent, JsonObject member, boolean isFirst) {
+    delegate.visitArrayMember(parent, member, isFirst);
+  }
+
+  public void visitObjectMember(
+      JsonObject parent, String memberName, JsonPrimitive member, boolean isFirst) {
+    delegate.visitObjectMember(parent, memberName, member, isFirst);
+  }
+
+  public void visitObjectMember(
+      JsonObject parent, String memberName, JsonArray member, boolean isFirst) {
+    delegate.visitObjectMember(parent, memberName, member, isFirst);
+  }
+
+  public void visitObjectMember(
+      JsonObject parent, String memberName, JsonObject member, boolean isFirst) {
+    delegate.visitObjectMember(parent, memberName, member, isFirst);
+  }
+
+  public void visitNullObjectMember(JsonObject parent, String memberName, boolean isFirst) {
+    delegate.visitNullObjectMember(parent, memberName, isFirst);
+  }
+
+  public void visitPrimitive(JsonPrimitive primitive) {
+    delegate.visitPrimitive(primitive);
+  }
+
+  public void visitNull() {
+    delegate.visitNull();
+  }
+
+  public void visitNullArrayMember(JsonArray parent, boolean isFirst) {
+    delegate.visitNullArrayMember(parent, isFirst);
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/DisjunctionExclusionStrategy.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/DisjunctionExclusionStrategy.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/DisjunctionExclusionStrategy.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.LinkedList;
+
+/**
+ * A wrapper class used to collect numerous {@link ExclusionStrategy} objects
+ * and perform a short-circuited OR operation.
+ *
+ * @author Joel Leitch
+ */
+final class DisjunctionExclusionStrategy implements ExclusionStrategy {
+  private final Collection<ExclusionStrategy> strategies;
+
+  public DisjunctionExclusionStrategy(ExclusionStrategy... strategies) {
+    Preconditions.checkNotNull(strategies);
+    Preconditions.checkArgument(strategies.length > 0);
+
+    this.strategies = new LinkedList<ExclusionStrategy>();
+    for (ExclusionStrategy strategy : strategies) {
+      this.strategies.add(strategy);
+    }
+  }
+
+  public DisjunctionExclusionStrategy(Collection<ExclusionStrategy> strategies) {
+    Preconditions.checkNotNull(strategies);
+    Preconditions.checkArgument(!strategies.isEmpty());
+
+    this.strategies = new LinkedList<ExclusionStrategy>();
+    this.strategies.addAll(strategies);
+  }
+
+  public boolean shouldSkipField(Field f) {
+    for (ExclusionStrategy strategy : strategies) {
+      if (strategy.shouldSkipField(f)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public boolean shouldSkipClass(Class<?> clazz) {
+    for (ExclusionStrategy strategy : strategies) {
+      if (strategy.shouldSkipClass(clazz)) {
+        return true;
+      }
+    }
+    return false;
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/Escaper.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/Escaper.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/Escaper.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A utility class that is used to perform JSON escaping so that ", <, >, etc. characters are
+ * properly encoded in the JSON string representation before returning to the client code.
+ *
+ * <p>This class contains a single method to escape a passed in string value:
+ * <pre>
+ *   String jsonStringValue = "beforeQuote\"afterQuote";
+ *   String escapedValue = Escaper.escapeJsonString(jsonStringValue);
+ * </pre></p>
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+class Escaper {
+
+  static final char[] HEX_CHARS = {
+    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+  };
+
+  private static final Set<Character> JS_ESCAPE_CHARS;
+
+  static {
+    Set<Character> tmpSet = new HashSet<Character>();
+    tmpSet.add('\u0000');
+    tmpSet.add('\r');
+    tmpSet.add('\n');
+    tmpSet.add('\u2028');
+    tmpSet.add('\u2029');
+    tmpSet.add('\u0085');
+    tmpSet.add('\'');
+    tmpSet.add('"');
+    tmpSet.add('<');
+    tmpSet.add('>');
+    tmpSet.add('&');
+    tmpSet.add('=');
+    tmpSet.add('\\');
+    JS_ESCAPE_CHARS = Collections.unmodifiableSet(tmpSet);
+  }
+
+  public static String escapeJsonString(CharSequence plainText) {
+    StringBuffer escapedString = new StringBuffer(plainText.length() + 20);
+    try {
+      escapeJsonString(plainText, escapedString);
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+    return escapedString.toString();
+  }
+
+  private static void escapeJsonString(CharSequence plainText, StringBuffer out) throws IOException {
+    int pos = 0;  // Index just past the last char in plainText written to out.
+    int len = plainText.length();
+     for (int charCount, i = 0; i < len; i += charCount) {
+       int codePoint = Character.codePointAt(plainText, i);
+       charCount = Character.charCount(codePoint);
+
+         if (!((codePoint < 0x20 || codePoint >= 0x7f)
+               || mustEscapeCharInJsString(codePoint))) {
+            continue;
+         }
+
+         out.append(plainText, pos, i);
+         pos = i + charCount;
+         switch (codePoint) {
+           case '\b':
+             out.append("\\b");
+             break;
+           case '\t':
+             out.append("\\t");
+             break;
+           case '\n':
+             out.append("\\n");
+             break;
+           case '\f':
+             out.append("\\f");
+             break;
+           case '\r':
+             out.append("\\r");
+             break;
+           case '\\':
+             out.append("\\\\");
+             break;
+           case '"':
+             out.append('\\').append((char) codePoint);
+             break;
+           case '\'':
+             out.append((char) codePoint);
+             break;
+           default:
+             appendHexJavaScriptRepresentation(codePoint, out);
+             break;
+         }
+     }
+     out.append(plainText, pos, len);
+  }
+
+  private static void appendHexJavaScriptRepresentation(int codePoint, Appendable out)
+      throws IOException {
+    if (Character.isSupplementaryCodePoint(codePoint)) {
+      // Handle supplementary unicode values which are not representable in
+      // javascript.  We deal with these by escaping them as two 4B sequences
+      // so that they will round-trip properly when sent from java to javascript
+      // and back.
+      char[] surrogates = Character.toChars(codePoint);
+      appendHexJavaScriptRepresentation(surrogates[0], out);
+      appendHexJavaScriptRepresentation(surrogates[1], out);
+      return;
+    }
+    out.append("\\u")
+        .append(HEX_CHARS[(codePoint >>> 12) & 0xf])
+        .append(HEX_CHARS[(codePoint >>> 8) & 0xf])
+        .append(HEX_CHARS[(codePoint >>> 4) & 0xf])
+        .append(HEX_CHARS[codePoint & 0xf]);
+  }
+
+  private static boolean mustEscapeCharInJsString(int codepoint) {
+    if (!Character.isSupplementaryCodePoint(codepoint)) {
+      return JS_ESCAPE_CHARS.contains((char)codepoint);
+    } else {
+      return false;
+    }
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/ExclusionStrategy.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/ExclusionStrategy.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/ExclusionStrategy.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Field;
+
+/**
+ * A strategy definition that is used by the {@link ObjectNavigator} to
+ * determine whether or not the field of the object should be ignored during
+ * navigation.
+ *
+ * As well, for now this class is also responsible for excluding entire
+ * classes.  This is somewhat a mixing of concerns for this object, but
+ * it will suffice for now.  We can always break it down into two
+ * different strategies later.
+ *
+ * @author Joel Leitch
+ */
+interface ExclusionStrategy {
+
+  /**
+   * @param f the field object that is under test
+   * @return true if the field should be ignored otherwise false
+   */
+  public boolean shouldSkipField(Field f);
+
+  /**
+   * @param clazz the class object that is under test
+   * @return true if the class should be ignored otherwise false
+   */
+  public boolean shouldSkipClass(Class<?> clazz);
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/ExposeAnnotationBasedExclusionStrategy.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/ExposeAnnotationBasedExclusionStrategy.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/ExposeAnnotationBasedExclusionStrategy.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import com.google.gson.annotations.Expose;
+
+import java.lang.reflect.Field;
+
+/**
+ * Excludes fields that do not have the {@link Expose} annotation
+ * 
+ * @author Inderjeet Singh
+ */
+class ExposeAnnotationBasedExclusionStrategy implements ExclusionStrategy {
+
+  public boolean shouldSkipClass(Class<?> clazz) {
+    return false;
+  }
+
+  public boolean shouldSkipField(Field f) {
+    return f.getAnnotation(Expose.class) == null;
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/FieldNamingPolicy.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/FieldNamingPolicy.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/FieldNamingPolicy.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+/**
+ * An enumeration that defines a few standard naming conventions for JSON field names.
+ * This enumeration should be used in conjunction with {@link com.google.gson.GsonBuilder}
+ * to configure a {@link com.google.gson.Gson} instance to properly translate Java field
+ * names into the desired JSON field names.
+ *
+ * @author Joel Leitch
+ */
+public enum FieldNamingPolicy {
+  /**
+   * Using this naming policy with Gson will ensure that the first "letter" of the Java
+   * field name is capitalized when serialized to its JSON form.
+   *
+   * <p>Here's a few examples of the form "Java Field Name" ---> "JSON Field Name":</p>
+   * <ul>
+   *   <li>someFieldName ---> SomeFieldName</li>
+   *   <li>_someFieldName ---> _SomeFieldName</li>
+   * </ul>
+   */
+  UPPER_CAMEL_CASE(new ModifyFirstLetterNamingPolicy(
+      ModifyFirstLetterNamingPolicy.LetterModifier.UPPER)),
+
+  /**
+   * Using this naming policy with Gson will modify the Java Field name from its camel cased
+   * form to a lower case field name where each word is separated by an underscore (_).
+   *
+   * <p>Here's a few examples of the form "Java Field Name" ---> "JSON Field Name":</p>
+   * <ul>
+   *   <li>someFieldName ---> some_field_name</li>
+   *   <li>_someFieldName ---> _some_field_name</li>
+   *   <li>aStringField ---> a_string_field</li>
+   *   <li>aURL ---> a_u_r_l</li>
+   * </ul>
+   */
+  LOWER_CASE_WITH_UNDERSCORES(new LowerCamelCaseSeparatorNamingPolicy("_"));
+
+  private final FieldNamingStrategy namingPolicy;
+
+  private FieldNamingPolicy(FieldNamingStrategy namingPolicy) {
+    this.namingPolicy = namingPolicy;
+  }
+
+  FieldNamingStrategy getFieldNamingPolicy() {
+    return namingPolicy;
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/FieldNamingStrategy.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/FieldNamingStrategy.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/FieldNamingStrategy.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Field;
+
+/**
+ * A mechanism for providing custom field naming in Gson.  This allows the client code to translate
+ * field names into a particular convention that is not supported as a normal Java field
+ * declaration rules.  For example, Java does not support "-" characters in a field name.
+ *
+ * @author Joel Leitch
+ */
+interface FieldNamingStrategy {
+
+  /**
+   * Translates the field name into its JSON field name representation.
+   *
+   * @param f the field object that we are translating
+   * @return the translated field name.
+   */
+  public String translateName(Field f);
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/GenericArrayTypeImpl.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/GenericArrayTypeImpl.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/GenericArrayTypeImpl.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Type;
+
+/**
+ * An simple pojo-like immutable instance of the {@link GenericArrayType}.  This object provides
+ * us the ability to create reflective types on demand.  This object is required for support
+ * object similar to the one defined below:
+ * <pre>
+ * class Foo<T> {
+ *   private final List<T>[] arrayOfListT;
+ *
+ *   Foo(List<T>[] arrayList) {
+ *     this.arrayOfListT = arrayList;
+ *   }
+ * }
+ * </pre>
+ *
+ * <p>During parsing or serialization, we know the real variable type parameter {@code T},
+ * so we can build a new {@code GenericTypeArray} with the "real" type parameters and
+ * pass that object along instead.
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+final class GenericArrayTypeImpl implements GenericArrayType {
+
+  private final Type genericComponentType;
+
+  public GenericArrayTypeImpl(Type genericComponentType) {
+    this.genericComponentType = genericComponentType;
+  }
+
+  public Type getGenericComponentType() {
+    return genericComponentType;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (!(o instanceof  GenericArrayType)) {
+      return false;
+    } else {
+      GenericArrayType that = (GenericArrayType) o;
+      Type thatComponentType = that.getGenericComponentType();
+      return genericComponentType == null ?
+          thatComponentType == null : genericComponentType.equals(thatComponentType);
+    }
+  }
+
+  @Override
+  public int hashCode() {
+    return (genericComponentType == null) ? 0 : genericComponentType.hashCode();
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/Gson.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/Gson.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/Gson.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+/**
+ * This is the main class for using Gson. Gson is typically used by first constructing a
+ * Gson instance and then invoking {@link #toJson(Object)} or {@link #fromJson(String, Class)}
+ * methods on it.
+ *
+ * <p>You can create a Gson instance by invoking {@code new Gson()} if the default configuration
+ * is all you need. You can also use {@link GsonBuilder} to build a Gson instance with various
+ * configuration options such as versioning support, pretty printing, custom
+ * {@link JsonSerializer}s, {@link JsonDeserializer}s, and {@link InstanceCreator}s.</p>
+ *
+ * <p>Here is an example of how Gson is used for a simple Class:
+ *
+ * <pre>
+ * Gson gson = new Gson(); // Or use new GsonBuilder().create();
+ * MyType target = new MyType();
+ * String json = gson.toJson(target); // serializes target to Json
+ * MyType target2 = gson.fromJson(json, MyType.class); // deserializes json into target2
+ * </pre></p>
+ *
+ * <p>If the object that your are serializing/deserializing is a {@code ParameterizedType}
+ * (i.e. contains at least one type parameter and may be an array) then you must use the
+ * {@link #toJson(Object, Type)} or {@link #fromJson(String, Type)} method.  Here is an
+ * example for serializing and deserialing a {@code ParameterizedType}:
+ *
+ * <pre>
+ * Type listType = new TypeToken<List<String>>() {}.getType();
+ * List<String> target = new LinkedList<String>();
+ * target.add("blah");
+ *
+ * Gson gson = new Gson();
+ * String json = gson.toJson(target, listType);
+ * List<String> target2 = gson.fromJson(json, listType);
+ * </pre></p>
+ *
+ * <p>See the <a href="https://sites.google.com/site/gson/gson-user-guide">Gson User Guide</a>
+ * for a more complete set of examples.</p>
+ *
+ * @see com.google.gson.reflect.TypeToken
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+public final class Gson {
+
+  //TODO(inder): get rid of all the registerXXX methods and take all such parameters in the
+  // constructor instead. At the minimum, mark those methods private.
+
+  private static final String NULL_STRING = "null";
+  // Default instances of plug-ins
+  static final TypeAdapter DEFAULT_TYPE_ADAPTER =
+      new TypeAdapterNotRequired(new PrimitiveTypeAdapter());
+  static final ModifierBasedExclusionStrategy DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY =
+      new ModifierBasedExclusionStrategy(true, new int[] { Modifier.TRANSIENT, Modifier.STATIC });
+  static final JsonFormatter DEFAULT_JSON_FORMATTER = new JsonCompactFormatter();
+  static final FieldNamingStrategy DEFAULT_NAMING_POLICY =
+      new SerializedNameAnnotationInterceptingNamingPolicy(new JavaFieldNamingPolicy());
+
+  static final Logger logger = Logger.getLogger(Gson.class.getName());
+
+  private final ObjectNavigatorFactory navigatorFactory;
+  private final MappedObjectConstructor objectConstructor;
+  private final TypeAdapter typeAdapter;
+
+  /** Map containing Type or Class objects as keys */
+  private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers;
+
+  /** Map containing Type or Class objects as keys */
+  private final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers;
+
+  private final JsonFormatter formatter;
+  private final boolean serializeNulls;
+
+  /**
+   * Constructs a Gson object with default configuration. The default configuration has the
+   * following settings:
+   * <ul>
+   *   <li>The JSON generated by <code>toJson</code> methods is in compact representation. This
+   *   means that all the unneeded white-space is removed. You can change this behavior with
+   *   {@link GsonBuilder#setPrettyPrinting()}. </li>
+   *   <li>The generated JSON omits all the fields that are null. Note that nulls in arrays are
+   *   kept as is since an array is an ordered list. Moreover, if a field is not null, but its
+   *   generated JSON is empty, the field is kept. You can configure Gson to serialize null values
+   *   by setting {@link GsonBuilder#serializeNulls()}.</li>
+   *   <li>Gson provides default serialization and deserialization for Enums, {@link Map},
+   *   {@link java.net.URL}, {@link java.net.URI}, {@link java.util.Locale}, {@link java.util.Date},
+   *   {@link java.math.BigDecimal}, and {@link java.math.BigInteger} classes. If you would prefer
+   *   to change the default representation, you can do so by registering a type adapter through
+   *   {@link GsonBuilder#registerTypeAdapter(Type, Object)}. </li>
+   *   <li>The default Date format is same as {@link java.text.DateFormat#DEFAULT}. This format 
+   *   ignores the millisecond portion of the date during serialization. You can change
+   *   this by invoking {@link GsonBuilder#setDateFormat(int)} or
+   *   {@link GsonBuilder#setDateFormat(String)}. </li>
+   *   <li>By default, Gson ignores the {@link com.google.gson.annotations.Expose} annotation.
+   *   You can enable Gson to serialize/deserialize only those fields marked with this annotation
+   *   through {@link GsonBuilder#excludeFieldsWithoutExposeAnnotation()}. </li>
+   *   <li>By default, Gson ignores the {@link com.google.gson.annotations.Since} annotation. You
+   *   can enable Gson to use this annotation through {@link GsonBuilder#setVersion(double)}.</li>
+   *   <li>The default field naming policy for the output Json is same as in Java. So, a Java class
+   *   field <code>versionNumber</code> will be output as <code>&quot;versionNumber at quot;</code> in
+   *   Json. The same rules are applied for mapping incoming Json to the Java classes. You can
+   *   change this policy through {@link GsonBuilder#setFieldNamingPolicy(FieldNamingPolicy)}.</li>
+   *   <li>By default, Gson excludes <code>transient</code> or <code>static</code> fields from
+   *   consideration for serialization and deserialization. You can change this behavior through
+   *   {@link GsonBuilder#excludeFieldsWithModifiers(int...)}.</li>
+   * </ul>
+   */
+  public Gson() {
+    this(createDefaultObjectNavigatorFactory());
+  }
+
+  /**
+   * Constructs a Gson object with the specified version and the mode of operation while
+   * encountering inner class references.
+   *
+   * @param factory the object navigator factory to use when creating a new {@link ObjectNavigator}
+   * instance
+   */
+  Gson(ObjectNavigatorFactory factory) {
+    this(factory, createObjectConstructor(DefaultTypeAdapters.DEFAULT_INSTANCE_CREATORS),
+        DEFAULT_TYPE_ADAPTER, DEFAULT_JSON_FORMATTER, false,
+        DefaultTypeAdapters.DEFAULT_SERIALIZERS, DefaultTypeAdapters.DEFAULT_DESERIALIZERS);
+  }
+
+  Gson(ObjectNavigatorFactory factory, MappedObjectConstructor objectConstructor,
+      TypeAdapter typeAdapter, JsonFormatter formatter, boolean serializeNulls,
+      ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
+      ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers) {
+    this.navigatorFactory = factory;
+    this.objectConstructor = objectConstructor;
+    this.typeAdapter = typeAdapter;
+    this.formatter = formatter;
+    this.serializeNulls = serializeNulls;
+    this.serializers = serializers;
+    this.deserializers = deserializers;
+  }
+
+  static MappedObjectConstructor createObjectConstructor(
+      ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreators) {
+    MappedObjectConstructor objectConstructor = new MappedObjectConstructor();
+    for (Map.Entry<Type, InstanceCreator<?>> entry : instanceCreators.entrySet()) {
+      objectConstructor.register(entry.getKey(), entry.getValue());
+    }
+    return objectConstructor;
+  }
+
+  private static ObjectNavigatorFactory createDefaultObjectNavigatorFactory() {
+    return new ObjectNavigatorFactory(
+        createExclusionStrategy(VersionConstants.IGNORE_VERSIONS), DEFAULT_NAMING_POLICY);
+  }
+
+  private static ExclusionStrategy createExclusionStrategy(double version) {
+    List<ExclusionStrategy> strategies = new LinkedList<ExclusionStrategy>();
+    strategies.add(new InnerClassExclusionStrategy());
+    strategies.add(DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY);
+    if (version != VersionConstants.IGNORE_VERSIONS) {
+      strategies.add(new VersionExclusionStrategy(version));
+    }
+    return new DisjunctionExclusionStrategy(strategies);
+  }
+
+  /**
+   * This method serializes the specified object into its equivalent Json representation.
+   * This method should be used when the specified object is not a generic type. This method uses
+   * {@link Class#getClass()} to get the type for the specified object, but the
+   * {@code getClass()} loses the generic type information because of the Type Erasure feature
+   * of Java. Note that this method works fine if the any of the object fields are of generic type,
+   * just the object itself should not be of a generic type. If the object is of generic type, use
+   * {@link #toJson(Object, Type)} instead. If you want to write out the object to a
+   * {@link Writer}, use {@link #toJson(Object, Writer)} instead.
+   *
+   * @param src the object for which Json representation is to be created setting for Gson
+   * @return Json representation of {@code src}.
+   */
+  public String toJson(Object src) {
+    if (src == null) {
+      return serializeNulls ? NULL_STRING : "";
+    }
+    return toJson(src, src.getClass());
+  }
+
+  /**
+   * This method serializes the specified object, including those of generic types, into its
+   * equivalent Json representation. This method must be used if the specified object is a generic
+   * type. For non-generic objects, use {@link #toJson(Object)} instead. If you want to write out
+   * the object to a {@link Writer}, use {@link #toJson(Object, Type, Writer)} instead.
+   *
+   * @param src the object for which JSON representation is to be created
+   * @param typeOfSrc The specific genericized type of src. You can obtain
+   * this type by using the {@link com.google.gson.reflect.TypeToken} class. For example,
+   * to get the type for {@code Collection<Foo>}, you should use:
+   * <pre>
+   * Type typeOfSrc = new TypeToken&lt;Collection&lt;Foo&gt;&gt;(){}.getType();
+   * </pre>
+   * @return Json representation of {@code src}
+   */
+  public String toJson(Object src, Type typeOfSrc) {
+    StringWriter writer = new StringWriter();
+    toJson(src, typeOfSrc, writer);
+    return writer.toString();
+  }
+
+  /**
+   * This method serializes the specified object into its equivalent Json representation.
+   * This method should be used when the specified object is not a generic type. This method uses
+   * {@link Class#getClass()} to get the type for the specified object, but the
+   * {@code getClass()} loses the generic type information because of the Type Erasure feature
+   * of Java. Note that this method works fine if the any of the object fields are of generic type,
+   * just the object itself should not be of a generic type. If the object is of generic type, use
+   * {@link #toJson(Object, Type, Writer)} instead.
+   *
+   * @param src the object for which Json representation is to be created setting for Gson
+   * @param writer Writer to which the Json representation needs to be written
+   * @since 1.2
+   */
+  public void toJson(Object src, Writer writer) {
+    if (src != null) {
+      toJson(src, src.getClass(), writer);
+    } else if (serializeNulls) {
+      writeOutNullString(writer);
+    }
+  }
+
+  /**
+   * This method serializes the specified object, including those of generic types, into its
+   * equivalent Json representation. This method must be used if the specified object is a generic
+   * type. For non-generic objects, use {@link #toJson(Object, Writer)} instead.
+   *
+   * @param src the object for which JSON representation is to be created
+   * @param typeOfSrc The specific genericized type of src. You can obtain
+   * this type by using the {@link com.google.gson.reflect.TypeToken} class. For example,
+   * to get the type for {@code Collection<Foo>}, you should use:
+   * <pre>
+   * Type typeOfSrc = new TypeToken&lt;Collection&lt;Foo&gt;&gt;(){}.getType();
+   * </pre>
+   * @param writer Writer to which the Json representation of src needs to be written.
+   * @since 1.2
+   */
+  public void toJson(Object src, Type typeOfSrc, Writer writer) {
+    if (src != null) {
+      JsonSerializationContext context =
+          new JsonSerializationContextDefault(navigatorFactory, serializeNulls, serializers);
+      JsonElement jsonElement = context.serialize(src, typeOfSrc);
+
+      //TODO(Joel): instead of navigating the "JsonElement" inside the formatter, do it here.
+      formatter.format(jsonElement, new PrintWriter(writer), serializeNulls);
+    } else {
+      if (serializeNulls) {
+        writeOutNullString(writer);
+      }
+    }
+  }
+
+  /**
+   * This method deserializes the specified Json into an object of the specified class. It is not
+   * suitable to use if the specified class is a generic type since it will not have the generic
+   * type information because of the Type Erasure feature of Java. Therefore, this method should not
+   * be used if the desired type is a generic type. Note that this method works fine if the any of
+   * the fields of the specified object are generics, just the object itself should not be a
+   * generic type. For the cases when the object is of generic type, invoke
+   * {@link #fromJson(String, Type)}. If you have the Json in a {@link Reader} instead of
+   * a String, use {@link #fromJson(Reader, Class)} instead.
+   *
+   * @param <T> the type of the desired object
+   * @param json the string from which the object is to be deserialized
+   * @param classOfT the class of T
+   * @return an object of type T from the string
+   * @throws JsonParseException if json is not a valid representation for an object of type
+   * classOfT
+   */
+  @SuppressWarnings("unchecked")
+  public <T> T fromJson(String json, Class<T> classOfT) throws JsonParseException {
+    T target = (T) fromJson(json, (Type) classOfT);
+    return target;
+  }
+
+  /**
+   * This method deserializes the specified Json into an object of the specified type. This method
+   * is useful if the specified object is a generic type. For non-generic objects, use
+   * {@link #fromJson(String, Class)} instead. If you have the Json in a {@link Reader} instead of
+   * a String, use {@link #fromJson(Reader, Type)} instead.
+   *
+   * @param <T> the type of the desired object
+   * @param json the string from which the object is to be deserialized
+   * @param typeOfT The specific genericized type of src. You can obtain this type by using the
+   * {@link com.google.gson.reflect.TypeToken} class. For example, to get the type for
+   * {@code Collection<Foo>}, you should use:
+   * <pre>
+   * Type typeOfT = new TypeToken&lt;Collection&lt;Foo&gt;&gt;(){}.getType();
+   * </pre>
+   * @return an object of type T from the string
+   * @throws JsonParseException if json is not a valid representation for an object of type typeOfT
+   */
+  @SuppressWarnings("unchecked")
+  public <T> T fromJson(String json, Type typeOfT) throws JsonParseException {
+    StringReader reader = new StringReader(json);
+    T target = (T) fromJson(reader, typeOfT);
+    return target;
+  }
+
+  /**
+   * This method deserializes the Json read from the specified reader into an object of the
+   * specified class. It is not suitable to use if the specified class is a generic type since it
+   * will not have the generic type information because of the Type Erasure feature of Java.
+   * Therefore, this method should not be used if the desired type is a generic type. Note that
+   * this method works fine if the any of the fields of the specified object are generics, just the
+   * object itself should not be a generic type. For the cases when the object is of generic type,
+   * invoke {@link #fromJson(Reader, Type)}. If you have the Json in a String form instead of a
+   * {@link Reader}, use {@link #fromJson(String, Class)} instead.
+   *
+   * @param <T> the type of the desired object
+   * @param json the reader producing the Json from which the object is to be deserialized.
+   * @param classOfT the class of T
+   * @return an object of type T from the string
+   * @throws JsonParseException if json is not a valid representation for an object of type
+   * classOfT
+   * @since 1.2
+   */
+  public <T> T fromJson(Reader json, Class<T> classOfT) throws JsonParseException {
+    T target = classOfT.cast(fromJson(json, (Type) classOfT));
+    return target;
+  }
+
+  /**
+   * This method deserializes the Json read from the specified reader into an object of the
+   * specified type. This method is useful if the specified object is a generic type. For
+   * non-generic objects, use {@link #fromJson(Reader, Class)} instead. If you have the Json in a
+   * String form instead of a {@link Reader}, use {@link #fromJson(String, Type)} instead.
+   *
+   * @param <T> the type of the desired object
+   * @param json the reader producing Json from which the object is to be deserialized
+   * @param typeOfT The specific genericized type of src. You can obtain this type by using the
+   * {@link com.google.gson.reflect.TypeToken} class. For example, to get the type for
+   * {@code Collection<Foo>}, you should use:
+   * <pre>
+   * Type typeOfT = new TypeToken&lt;Collection&lt;Foo&gt;&gt;(){}.getType();
+   * </pre>
+   * @return an object of type T from the json
+   * @throws JsonParseException if json is not a valid representation for an object of type typeOfT
+   * @since 1.2
+   */
+  @SuppressWarnings("unchecked")
+  public <T> T fromJson(Reader json, Type typeOfT) throws JsonParseException {
+    try {
+      JsonParser parser = new JsonParser(json);
+      JsonElement root = parser.parse();
+      JsonDeserializationContext context = new JsonDeserializationContextDefault(navigatorFactory,
+          deserializers, objectConstructor, typeAdapter);
+      T target = (T) context.deserialize(root, typeOfT);
+      return target;
+    } catch (TokenMgrError e) {
+      throw new JsonParseException("Failed parsing JSON source: " + json + " to Json", e);
+    } catch (ParseException e) {
+      throw new JsonParseException("Failed parsing JSON source: " + json + " to Json", e);
+    } catch (StackOverflowError e) {
+      throw new JsonParseException("Failed parsing JSON source: " + json + " to Json", e);
+    } catch (OutOfMemoryError e) {
+      throw new JsonParseException("Failed parsing JSON source: " + json + " to Json", e);
+    }
+  }
+
+  /**
+   * Appends the {@link #NULL_STRING} to the {@code writer} object.
+   *
+   * @param writer the object to append the null value to
+   */
+  private void writeOutNullString(Writer writer) {
+    try {
+      writer.append(NULL_STRING);
+    } catch (IOException e) {
+      // Should this be a different exception???
+      throw new JsonParseException(e);
+    }
+  }
+  
+  @Override 
+  public String toString() {
+	StringBuilder sb = new StringBuilder("{");
+    sb.append("serializeNulls:").append(serializeNulls);
+	sb.append(",serializers:").append(serializers);
+	sb.append(",deserializers:").append(deserializers);
+	// using the name instanceCreator instead of ObjectConstructor since the users of Gson are 
+	// more familiar with the concept of Instance Creators. Moreover, the objectConstructor is
+	// just a utility class around instance creators, and its toString() only displays them.
+    sb.append(",instanceCreators:").append(objectConstructor);
+	sb.append("}");
+	return sb.toString();
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/GsonBuilder.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/GsonBuilder.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/GsonBuilder.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,382 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import com.google.gson.DefaultTypeAdapters.DefaultDateTypeAdapter;
+
+import java.lang.reflect.Type;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * <p>Use this builder to construct a {@link Gson} instance when you need to set configuration
+ * options other than the default. For {@link Gson} with default configuration, it is simpler to
+ * use {@code new Gson()}. {@code GsonBuilder} is best used by creating it, and then invoking its
+ * various configuration methods, and finally calling create.</p>
+ *
+ * <p>The following is an example shows how to use the {@code GsonBuilder} to construct a Gson
+ * instance:
+ *
+ * <pre>
+ * Gson gson = new GsonBuilder()
+ *     .registerTypeAdapter(Id.class, new IdTypeAdapter())
+ *     .serializeNulls()
+ *     .setDateFormat(DateFormat.LONG)
+ *     .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
+ *     .setPrettyPrinting()
+ *     .setVersion(1.0)
+ *     .create();
+ * </pre></p>
+ *
+ * <p>NOTE: the order of invocation of configuration methods does not matter.</p>
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+public final class GsonBuilder {
+
+  private double ignoreVersionsAfter;
+  private ModifierBasedExclusionStrategy modifierBasedExclusionStrategy;
+  private final InnerClassExclusionStrategy innerClassExclusionStrategy;
+  private boolean excludeFieldsWithoutExposeAnnotation;
+  private final TypeAdapter typeAdapter;
+  private JsonFormatter formatter;
+  private FieldNamingStrategy fieldNamingPolicy;
+  private final ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreators;
+  private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers;
+  private final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers;
+  private boolean serializeNulls;
+  private String datePattern;
+  private int dateStyle;
+  private int timeStyle;
+
+  /**
+   * Creates a GsonBuilder instance that can be used to build Gson with various configuration
+   * settings. GsonBuilder follows the builder pattern, and it is typically used by first
+   * invoking various configuration methods to set desired options, and finally calling
+   * {@link #create()}.
+   */
+  public GsonBuilder() {
+    // setup default values
+    ignoreVersionsAfter = VersionConstants.IGNORE_VERSIONS;
+    innerClassExclusionStrategy = new InnerClassExclusionStrategy();
+    modifierBasedExclusionStrategy = Gson.DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY;
+    excludeFieldsWithoutExposeAnnotation = false;
+    typeAdapter = Gson.DEFAULT_TYPE_ADAPTER;
+    formatter = Gson.DEFAULT_JSON_FORMATTER;
+    fieldNamingPolicy = Gson.DEFAULT_NAMING_POLICY;
+    instanceCreators = new ParameterizedTypeHandlerMap<InstanceCreator<?>>();
+    serializers = new ParameterizedTypeHandlerMap<JsonSerializer<?>>();
+    deserializers = new ParameterizedTypeHandlerMap<JsonDeserializer<?>>();
+    serializeNulls = false;
+    dateStyle = DateFormat.DEFAULT;
+    timeStyle = DateFormat.DEFAULT;
+  }
+
+  /**
+   * Configures Gson to enable versioning support.
+   *
+   * @param ignoreVersionsAfter any field or type marked with a version higher than this value
+   * are ignored during serialization or deserialization.
+   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
+   */
+  public GsonBuilder setVersion(double ignoreVersionsAfter) {
+    this.ignoreVersionsAfter = ignoreVersionsAfter;
+    return this;
+  }
+
+  /**
+   * Configures Gson to excludes all class fields that have the specified modifiers. By default,
+   * Gson will exclude all fields marked transient or static. This method will override that
+   * behavior.
+   *
+   * @param modifiers the field modifiers. You must use the modifiers specified in the
+   * {@link java.lang.reflect.Modifier} class. For example,
+   * {@link java.lang.reflect.Modifier#TRANSIENT},
+   * {@link java.lang.reflect.Modifier#STATIC}.
+   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
+   */
+  public GsonBuilder excludeFieldsWithModifiers(int... modifiers) {
+    boolean skipSynthetics = true;
+    modifierBasedExclusionStrategy = new ModifierBasedExclusionStrategy(skipSynthetics, modifiers);
+    return this;
+  }
+
+  /**
+   * Configures Gson to exclude all fields from consideration for serialization or deserialization
+   * that do not have the {@link com.google.gson.annotations.Expose} annotation.
+   *
+   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
+   */
+  public GsonBuilder excludeFieldsWithoutExposeAnnotation() {
+    excludeFieldsWithoutExposeAnnotation = true;
+    return this;
+  }
+
+  /**
+   * Configure Gson to serialize null fields. By default, Gson omits all fields that are null
+   * during serialization.
+   *
+   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
+   * @since 1.2
+   */
+  public GsonBuilder serializeNulls() {
+    this.serializeNulls = true;
+    return this;
+  }
+  /**
+   * Configures Gson to apply a specific naming policy to an object's field during serialization
+   * and deserialization.
+   *
+   * @param namingConvention the JSON field naming convention to use for serialization and
+   * deserialization.
+   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
+   */
+  public GsonBuilder setFieldNamingPolicy(FieldNamingPolicy namingConvention) {
+    return setFieldNamingStrategy(namingConvention.getFieldNamingPolicy());
+  }
+
+  /**
+   * Configures Gson to apply a specific naming policy strategy to an object's field during
+   * serialization and deserialization.
+   *
+   * @param fieldNamingPolicy the actual naming strategy to apply to the fields
+   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
+   */
+  private GsonBuilder setFieldNamingStrategy(FieldNamingStrategy fieldNamingPolicy) {
+    this.fieldNamingPolicy = new SerializedNameAnnotationInterceptingNamingPolicy(fieldNamingPolicy);
+    return this;
+  }
+
+  /**
+   * Configures Gson to output Json that fits in a page for pretty printing. This option only
+   * affects Json serialization.
+   *
+   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
+   */
+  public GsonBuilder setPrettyPrinting() {
+    setFormatter(new JsonPrintFormatter());
+    return this;
+  }
+
+  /**
+   * Configures Gson with a new formatting strategy other than the default strategy. The default
+   * strategy is to provide a compact representation that eliminates all unneeded white-space.
+   *
+   * @param formatter the new formatter to use.
+   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
+   * @see JsonPrintFormatter
+   */
+  GsonBuilder setFormatter(JsonFormatter formatter) {
+    this.formatter = formatter;
+    return this;
+  }
+
+  /**
+   * Configures Gson to serialize {@code Date} objects according to the pattern provided. You can
+   * call this method or {@link #setDateFormat(int)} multiple times, but only the last invocation
+   * will be used to decide the serialization format.
+   *
+   * <p>Note that this pattern must abide by the convention provided by {@code SimpleDateFormat}
+   * class. See the documentation in {@link java.text.SimpleDateFormat} for more information on
+   * valid date and time patterns.</p>
+   *
+   * @param pattern the pattern that dates will be serialized/deserialized to/from
+   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
+   * @since 1.2
+   */
+  public GsonBuilder setDateFormat(String pattern) {
+    // TODO(Joel): Make this fail fast if it is an invalid date format
+    this.datePattern = pattern;
+    return this;
+  }
+
+  /**
+   * Configures Gson to to serialize {@code Date} objects according to the style value provided.
+   * You can call this method or {@link #setDateFormat(String)} multiple times, but only the last
+   * invocation will be used to decide the serialization format.
+   *
+   * <p>Note that this style value should be one of the predefined constants in the
+   * {@code DateFormat} class. See the documentation in {@link java.text.DateFormat} for more
+   * information on the valid style constants.</p>
+   *
+   * @param style the predefined date style that date objects will be serialized/deserialized
+   * to/from
+   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
+   * @since 1.2
+   */
+  public GsonBuilder setDateFormat(int style) {
+    this.dateStyle = style;
+    this.datePattern = null;
+    return this;
+  }
+
+  /**
+   * Configures Gson to to serialize {@code Date} objects according to the style value provided.
+   * You can call this method or {@link #setDateFormat(String)} multiple times, but only the last
+   * invocation will be used to decide the serialization format.
+   *
+   * <p>Note that this style value should be one of the predefined constants in the
+   * {@code DateFormat} class. See the documentation in {@link java.text.DateFormat} for more
+   * information on the valid style constants.</p>
+   *
+   * @param dateStyle the predefined date style that date objects will be serialized/deserialized
+   * to/from
+   * @param timeStyle the predefined style for the time portion of the date objects
+   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
+   * @since 1.2
+   */
+  public GsonBuilder setDateFormat(int dateStyle, int timeStyle) {
+    this.dateStyle = dateStyle;
+    this.timeStyle = timeStyle;
+    this.datePattern = null;
+    return this;
+  }
+  
+  /**
+   * Configures Gson for custom serialization or deserialization. This method combines the
+   * registration of an {@link InstanceCreator}, {@link JsonSerializer}, and a
+   * {@link JsonDeserializer}. It is best used when a single object {@code typeAdapter} implements
+   * all the required interfaces for custom serialization with Gson. If an instance creator,
+   * serializer or deserializer was previously registered for the specified {@code type}, it is
+   * overwritten.
+   *
+   * @param type the type definition for the type adapter being registered
+   * @param typeAdapter This object must implement at least one of the {@link InstanceCreator},
+   * {@link JsonSerializer}, and a {@link JsonDeserializer} interfaces.
+   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
+   */
+  public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) {
+    Preconditions.checkArgument(typeAdapter instanceof JsonSerializer
+        || typeAdapter instanceof JsonDeserializer || typeAdapter instanceof InstanceCreator);
+    if (typeAdapter instanceof InstanceCreator) {
+      registerInstanceCreator(type, (InstanceCreator<?>) typeAdapter);
+    }
+    if (typeAdapter instanceof JsonSerializer) {
+      registerSerializer(type, (JsonSerializer<?>) typeAdapter);
+    }
+    if (typeAdapter instanceof JsonDeserializer) {
+      registerDeserializer(type, (JsonDeserializer<?>) typeAdapter);
+    }
+    return this;
+  }
+
+  /**
+   * Configures Gson to use a custom {@link InstanceCreator} for the specified type. If an instance
+   * creator was previously registered for the specified class, it is overwritten. Since this method
+   * takes a type instead of a Class object, it can be used to register a specific handler for a
+   * generic type corresponding to a raw type.
+   *
+   * @param <T> the type for which instance creator is being registered
+   * @param typeOfT The Type definition for T
+   * @param instanceCreator the instance creator for T
+   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
+   */
+  private <T> GsonBuilder registerInstanceCreator(Type typeOfT,
+      InstanceCreator<? extends T> instanceCreator) {
+    instanceCreators.register(typeOfT, instanceCreator);
+    return this;
+  }
+
+  /**
+   * Configures Gson to use a custom JSON serializer for the specified type. You should use this
+   * method if you want to register different serializers for different generic types corresponding
+   * to a raw type.
+   *
+   * @param <T> the type for which the serializer is being registered
+   * @param typeOfT The type definition for T
+   * @param serializer the custom serializer
+   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
+   */
+  private <T> GsonBuilder registerSerializer(Type typeOfT, final JsonSerializer<T> serializer) {
+    serializers.register(typeOfT, new JsonSerializerExceptionWrapper<T>(serializer));
+    return this;
+  }
+
+  /**
+   * Configures Gson to use a custom JSON deserializer for the specified type. You should use this
+   * method if you want to register different deserializers for different generic types
+   * corresponding to a raw type.
+   *
+   * @param <T> the type for which the deserializer is being registered
+   * @param typeOfT The type definition for T
+   * @param deserializer the custom deserializer
+   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
+   */
+  private <T> GsonBuilder registerDeserializer(Type typeOfT, JsonDeserializer<T> deserializer) {
+    deserializers.register(typeOfT, new JsonDeserializerExceptionWrapper<T>(deserializer));
+    return this;
+  }
+
+  /**
+   * Creates a {@link Gson} instance based on the current configuration. This method is free of
+   * side-effects to this {@code GsonBuilder} instance and hence can be called multiple times.
+   *
+   * @return an instance of Gson configured with the options currently set in this builder
+   */
+  public Gson create() {
+    List<ExclusionStrategy> strategies = new LinkedList<ExclusionStrategy>();
+    strategies.add(innerClassExclusionStrategy);
+    strategies.add(modifierBasedExclusionStrategy);
+    if (ignoreVersionsAfter != VersionConstants.IGNORE_VERSIONS) {
+      strategies.add(new VersionExclusionStrategy(ignoreVersionsAfter));
+    }
+    if (excludeFieldsWithoutExposeAnnotation) {
+      strategies.add(new ExposeAnnotationBasedExclusionStrategy());
+    }
+    ExclusionStrategy exclusionStrategy = new DisjunctionExclusionStrategy(strategies);
+    ObjectNavigatorFactory objectNavigatorFactory =
+        new ObjectNavigatorFactory(exclusionStrategy, fieldNamingPolicy);
+
+    ParameterizedTypeHandlerMap<JsonSerializer<?>> customSerializers = serializers.copyOf();
+    ParameterizedTypeHandlerMap<JsonDeserializer<?>> customDeserializers = deserializers.copyOf();
+
+    addTypeAdaptersForDate(datePattern, dateStyle, timeStyle, customSerializers, 
+        customDeserializers);
+    customSerializers.registerIfAbsent(DefaultTypeAdapters.DEFAULT_SERIALIZERS);
+    customDeserializers.registerIfAbsent(DefaultTypeAdapters.DEFAULT_DESERIALIZERS);
+
+    ParameterizedTypeHandlerMap<InstanceCreator<?>> customInstanceCreators =
+      instanceCreators.copyOf();
+    customInstanceCreators.registerIfAbsent(DefaultTypeAdapters.DEFAULT_INSTANCE_CREATORS);
+    MappedObjectConstructor objConstructor = Gson.createObjectConstructor(customInstanceCreators);
+
+    Gson gson = new Gson(objectNavigatorFactory, objConstructor, typeAdapter, formatter,
+        serializeNulls, customSerializers, customDeserializers);
+    return gson;
+  }
+
+  private static void addTypeAdaptersForDate(String datePattern, int dateStyle, int timeStyle,
+      ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
+      ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers) {
+    // NOTE: if a date pattern exists, then that style takes priority
+    DefaultDateTypeAdapter dateTypeAdapter = null;
+    if (datePattern != null && !"".equals(datePattern.trim())) {
+      dateTypeAdapter = new DefaultDateTypeAdapter(datePattern);
+    } else if (dateStyle != DateFormat.DEFAULT && timeStyle != DateFormat.DEFAULT) {
+      dateTypeAdapter = new DefaultDateTypeAdapter(dateStyle, timeStyle);
+    }
+    if (dateTypeAdapter != null
+        && !serializers.hasAnyHandlerFor(Date.class)
+        && !deserializers.hasAnyHandlerFor(Date.class)) {
+      serializers.register(Date.class, dateTypeAdapter);
+      deserializers.register(Date.class, dateTypeAdapter);
+    }
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/InnerClassExclusionStrategy.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/InnerClassExclusionStrategy.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/InnerClassExclusionStrategy.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Field;
+
+/**
+ * Strategy for excluding inner classes.
+ *
+ * @author Joel Leitch
+ */
+final class InnerClassExclusionStrategy implements ExclusionStrategy {
+
+  public boolean shouldSkipField(Field f) {
+    return isAnonymousOrLocal(f.getType());
+  }
+
+  public boolean shouldSkipClass(Class<?> clazz) {
+    return isAnonymousOrLocal(clazz);
+  }
+
+  private boolean isAnonymousOrLocal(Class<?> clazz) {
+    return clazz.isAnonymousClass() || clazz.isLocalClass();
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/InstanceCreator.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/InstanceCreator.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/InstanceCreator.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Type;
+
+/**
+ * This interface is implemented to create instances of a class that does not define a no-args
+ * constructor. If you can modify the class, you should instead add a private, or public
+ * no-args constructor. However, that is not possible for library classes, such as JDK classes, or
+ * a third-party library that you do not have source-code of. In such cases, you should define an
+ * instance creator for the class. Implementations of this interface should be registered with
+ * {@link GsonBuilder#registerTypeAdapter(Type, Object)} method before Gson will be able to use
+ * them.
+ * <p>Let us look at an example where defining an InstanceCreator might be useful. The
+ * {@code Id} class defined below does not have a default no-args constructor.</p>
+ *
+ * <pre>
+ * public class Id&lt;T&gt; {
+ *   private final Class&lt;T&gt; clazz;
+ *   private final long value;
+ *   public Id(Class&lt;T&gt; clazz, long value) {
+ *     this.clazz = clazz;
+ *     this.value = value;
+ *   }
+ * }
+ * </pre>
+ *
+ * <p>If Gson encounters an object of type {@code Id} during deserialization, it will throw an
+ * exception. The easiest way to solve this problem will be to add a (public or private) no-args
+ * constructor as follows:</p>
+ *
+ * <pre>
+ * private Id() {
+ *   this(Object.class, 0L);
+ * }
+ * </pre>
+ *
+ * <p>However, let us assume that the developer does not have access to the source-code of the
+ * {@code Id} class, or does not want to define a no-args constructor for it. The developer
+ * can solve this problem by defining an {@code InstanceCreator} for {@code Id}:</p>
+ *
+ * <pre>
+ * class IdInstanceCreator implements InstanceCreator&lt;Id&gt; {
+ *   public Id createInstance(Type type) {
+ *     return new Id(Object.class, 0L);
+ *   }
+ * }
+ * </pre>
+ *
+ * <p>Note that it does not matter what the fields of the created instance contain since Gson will
+ * overwrite them with the deserialized values specified in Json. You should also ensure that a
+ * <i>new</i> object is returned, not a common object since its fields will be overwritten.
+ * The developer will need to register {@code IdInstanceCreator} with Gson as follows:</p>
+ *
+ * <pre>
+ * Gson gson = new GsonBuilder().registerTypeAdapter(Id.class, new IdInstanceCreator()).create();
+ * </pre>
+ *
+ * @param <T> the type of object that will be created by this implementation.
+ *
+ * @author Joel Leitch
+ */
+public interface InstanceCreator<T> {
+
+  /**
+   * Gson invokes this call-back method during deserialization to create an instance of the
+   * specified type. The fields of the returned instance are overwritten with the data present
+   * in the Json. Since the prior contents of the object are destroyed and overwritten, do not
+   * return an instance that is useful elsewhere. In particular, do not return a common instance,
+   * always use {@code new} to create a new instance.
+   *
+   * @param type the parameterized T represented as a {@link Type}.
+   * @return a default object instance of type T.
+   */
+  public T createInstance(Type type);
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JavaFieldNamingPolicy.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JavaFieldNamingPolicy.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JavaFieldNamingPolicy.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+/**
+ * A simple implementation of the {@link FieldNamingStrategy} interface such that it does not
+ * perform any string translation of the incoming field name.
+ *
+ * <p>The following is an example:</p>
+ *
+ * <pre>
+ * class IntWrapper {
+ *   public int integerField = 0;
+ * }
+ *
+ * JavaFieldNamingPolicy policy = new JavaFieldNamingPolicy();
+ * String translatedFieldName =
+ *     policy.translateName(IntWrapper.class.getField("integerField"));
+ *
+ * assert("integerField".equals(translatedFieldName));
+ * </pre>
+ *
+ * <p>This is the default {@link FieldNamingStrategy} used by Gson.</p>
+ *
+ * @author Joel Leitch
+ */
+class JavaFieldNamingPolicy extends RecursiveFieldNamingPolicy {
+
+  @Override
+  protected String translateName(String target, Type fieldType, Annotation[] annotations) {
+    return target;
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonArray.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonArray.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonArray.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * A class representing an array type in Json. An array is a list of {@link JsonElement}s each of
+ * which can be of a different type. This is an ordered list, meaning that the order in which
+ * elements are added is preserved.
+ *
+ * @author Inderjeet Singh
+ */
+public final class JsonArray extends JsonElement implements Iterable<JsonElement> {
+  private final List<JsonElement> elements;
+
+  /**
+   * Creates an empty JsonArray.
+   */
+  public JsonArray() {
+    elements = new LinkedList<JsonElement>();
+  }
+
+  /**
+   * Adds the specified element to self.
+   *
+   * @param element the element that needs to be added to the array.
+   */
+  public void add(JsonElement element) {
+    elements.add(element);
+  }
+
+  /**
+   * Adds all the elements of the specified array to self.
+   *
+   * @param array the array whose elements need to be added to the array.
+   */
+  public void addAll(JsonArray array) {
+    elements.addAll(array.elements);
+  }
+
+  /**
+   * Reverses the elements of the array.
+   */
+  void reverse() {
+    Collections.reverse(elements);
+  }
+
+  /**
+   * Returns the number of elements in the array.
+   *
+   * @return the number of elements in the array.
+   */
+  public int size() {
+    return elements.size();
+  }
+
+  /**
+   * Returns an iterator to navigate the elemetns of the array. Since the array is an ordered list,
+   * the iterator navigates the elements in the order they were inserted.
+   *
+   * @return an iterator to navigate the elements of the array.
+   */
+  public Iterator<JsonElement> iterator() {
+    return elements.iterator();
+  }
+
+  /**
+   * Returns the ith element of the array.
+   *
+   * @param i the index of the element that is being sought.
+   * @return the element present at the ith index.
+   * @throws IndexOutOfBoundsException if i is negative or greater than or equal to the
+   * {@link #size()} of the array.
+   */
+  public JsonElement get(int i) {
+    return elements.get(i);
+  }
+
+  /**
+   * convenience method to get this array as a {@link Number} if it contains a single element.
+   *
+   * @return get this element as a number if it is single element array.
+   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
+   * is not a valid Number.
+   * @throws IllegalStateException if the array has more than one element.
+   */
+  @Override
+  public Number getAsNumber() {
+    if (elements.size() == 1) {
+      return elements.get(0).getAsNumber();
+    }
+    throw new IllegalStateException();
+  }
+
+  /**
+   * convenience method to get this array as a {@link String} if it contains a single element.
+   *
+   * @return get this element as a String if it is single element array.
+   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
+   * is not a valid String.
+   * @throws IllegalStateException if the array has more than one element.
+   */
+  @Override
+  public String getAsString() {
+    if (elements.size() == 1) {
+      return elements.get(0).getAsString();
+    }
+    throw new IllegalStateException();
+  }
+
+  /**
+   * convenience method to get this array as a double if it contains a single element.
+   *
+   * @return get this element as a double if it is single element array.
+   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
+   * is not a valid double.
+   * @throws IllegalStateException if the array has more than one element.
+   */
+  @Override
+  public double getAsDouble() {
+    if (elements.size() == 1) {
+      return elements.get(0).getAsDouble();
+    }
+    throw new IllegalStateException();
+  }
+
+  /**
+   * convenience method to get this array as a {@link BigDecimal} if it contains a single element.
+   *
+   * @return get this element as a {@link BigDecimal} if it is single element array.
+   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive}.
+   * @throws NumberFormatException if the element at index 0 is not a valid {@link BigDecimal}.
+   * @throws IllegalStateException if the array has more than one element.
+   * @since 1.2
+   */
+  @Override
+  public BigDecimal getAsBigDecimal() {
+    if (elements.size() == 1) {
+      return elements.get(0).getAsBigDecimal();
+    }
+    throw new IllegalStateException();
+  }
+
+  /**
+   * convenience method to get this array as a {@link BigInteger} if it contains a single element.
+   *
+   * @return get this element as a {@link BigInteger} if it is single element array.
+   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive}.
+   * @throws NumberFormatException if the element at index 0 is not a valid {@link BigInteger}.
+   * @throws IllegalStateException if the array has more than one element.
+   * @since 1.2
+   */
+  @Override
+  public BigInteger getAsBigInteger() {
+    if (elements.size() == 1) {
+      return elements.get(0).getAsBigInteger();
+    }
+    throw new IllegalStateException();
+  }
+
+  /**
+   * convenience method to get this array as a float if it contains a single element.
+   *
+   * @return get this element as a float if it is single element array.
+   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
+   * is not a valid float.
+   * @throws IllegalStateException if the array has more than one element.
+   */
+  @Override
+  public float getAsFloat() {
+    if (elements.size() == 1) {
+      return elements.get(0).getAsFloat();
+    }
+    throw new IllegalStateException();
+  }
+
+  /**
+   * convenience method to get this array as a long if it contains a single element.
+   *
+   * @return get this element as a long if it is single element array.
+   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
+   * is not a valid long.
+   * @throws IllegalStateException if the array has more than one element.
+   */
+  @Override
+  public long getAsLong() {
+    if (elements.size() == 1) {
+      return elements.get(0).getAsLong();
+    }
+    throw new IllegalStateException();
+  }
+
+  /**
+   * convenience method to get this array as an integer if it contains a single element.
+   *
+   * @return get this element as an integer if it is single element array.
+   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
+   * is not a valid integer.
+   * @throws IllegalStateException if the array has more than one element.
+   */
+  @Override
+  public int getAsInt() {
+    if (elements.size() == 1) {
+      return elements.get(0).getAsInt();
+    }
+    throw new IllegalStateException();
+  }
+
+  /**
+   * convenience method to get this array as a primitive short if it contains a single element.
+   *
+   * @return get this element as a primitive short if it is single element array.
+   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
+   * is not a valid short.
+   * @throws IllegalStateException if the array has more than one element.
+   */
+  @Override
+  public short getAsShort() {
+    if (elements.size() == 1) {
+      return elements.get(0).getAsShort();
+    }
+    throw new IllegalStateException();
+  }
+
+  /**
+   * convenience method to get this array as a boolean if it contains a single element.
+   *
+   * @return get this element as a boolean if it is single element array.
+   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
+   * is not a valid boolean.
+   * @throws IllegalStateException if the array has more than one element.
+   */
+  @Override
+  public boolean getAsBoolean() {
+    if (elements.size() == 1) {
+      return elements.get(0).getAsBoolean();
+    }
+    throw new IllegalStateException();
+  }
+
+  /**
+   * convenience method to get this array as an Object if it contains a single element.
+   *
+   * @return get this element as an Object if it is single element array.
+   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
+   * is not a valid Object.
+   * @throws IllegalStateException if the array has more than one element.
+   */
+  @Override
+  Object getAsObject() {
+    if (elements.size() == 1) {
+      return elements.get(0).getAsObject();
+    }
+    throw new IllegalStateException();
+  }
+
+  @Override
+  protected void toString(StringBuilder sb) {
+    sb.append('[');
+    boolean first = true;
+    for (JsonElement element : elements) {
+      if (first) {
+        first = false;
+      } else {
+        sb.append(',');
+      }
+      element.toString(sb);
+    }
+    sb.append(']');
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonArrayDeserializationVisitor.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonArrayDeserializationVisitor.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonArrayDeserializationVisitor.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+import java.util.Collection;
+
+/**
+ * A visitor that populates fields of an object with data from its equivalent
+ * JSON representation
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+final class JsonArrayDeserializationVisitor<T> extends JsonDeserializationVisitor<T> {
+  private final Class<?> componentType;
+
+  JsonArrayDeserializationVisitor(JsonArray jsonArray, Type arrayType,
+      ObjectNavigatorFactory factory, ObjectConstructor objectConstructor,
+      TypeAdapter typeAdapter, ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
+      JsonDeserializationContext context) {
+    super(jsonArray, arrayType, factory, objectConstructor, typeAdapter, deserializers, context);
+    this.componentType = TypeUtils.toRawClass(arrayType);
+  }
+
+  @Override
+  @SuppressWarnings("unchecked")
+  protected T constructTarget() {
+
+    TypeInfo typeInfo = new TypeInfo(targetType);
+
+    JsonArray jsonArray = json.getAsJsonArray();
+    if (typeInfo.isPrimitiveOrStringAndNotAnArray()) {
+      if (jsonArray.size() != 1) {
+        throw new IllegalArgumentException(
+            "Primitives should be an array of length 1, but was: " + jsonArray);
+      }
+      return (T) objectConstructor.construct(typeInfo.getWrappedClass());
+    } else if (typeInfo.isArray()) {
+      TypeInfoArray arrayTypeInfo = TypeInfoFactory.getTypeInfoForArray(targetType);
+      // We know that we are getting back an array of the required type, so
+      // this typecasting is safe.
+      return (T) objectConstructor.constructArray(arrayTypeInfo.getSecondLevelType(),
+          jsonArray.size());
+    } else { // is a collection
+      return (T) objectConstructor.construct(typeInfo.getRawClass());
+    }
+  }
+
+  public void visitArray(Object array, Type arrayType) {
+    JsonArray jsonArray = json.getAsJsonArray();
+    TypeInfoArray arrayTypeInfo = TypeInfoFactory.getTypeInfoForArray(arrayType);
+    for (int i = 0; i < jsonArray.size(); i++) {
+      JsonElement jsonChild = jsonArray.get(i);
+      Object child;
+
+      if (jsonChild == null) {
+        child = null;
+      } else if (jsonChild instanceof JsonObject) {
+        child = visitChildAsObject(arrayTypeInfo.getComponentRawType(), jsonChild);
+      } else if (jsonChild instanceof JsonArray) {
+        child = visitChildAsArray(arrayTypeInfo.getSecondLevelType(), jsonChild.getAsJsonArray());
+      } else if (jsonChild instanceof JsonPrimitive) {
+        child = visitChildAsPrimitive(arrayTypeInfo.getComponentRawType(),
+            jsonChild.getAsJsonPrimitive());
+      } else {
+        throw new IllegalStateException();
+      }
+      Array.set(array, i, child);
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void visitCollection(Collection collection, Type collectionType) {
+    Type childType = TypeUtils.getActualTypeForFirstTypeVariable(collectionType);
+    for (JsonElement jsonChild : json.getAsJsonArray()) {
+      if (childType == Object.class) {
+        throw new JsonParseException(collection +
+            " must not be a raw collection. Try making it genericized instead.");
+      }
+      Object child = visitChild(childType, jsonChild);
+      collection.add(child);
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void visitPrimitiveValue(Object obj) {
+    target = (T) typeAdapter.adaptType(json.getAsJsonArray().get(0).getAsObject(), componentType);
+  }
+
+  // We should not implement any other method from Visitor interface since
+  // all other methods should be invoked on JsonObjectDeserializationVisitor
+  // instead.
+
+  public void endVisitingObject(Object node) {
+    throw new UnsupportedOperationException();
+  }
+
+  public void startVisitingObject(Object node) {
+    throw new UnsupportedOperationException();
+  }
+
+  public void visitArrayField(Field f, Type typeOfF, Object obj) {
+    throw new UnsupportedOperationException();
+  }
+
+  public void visitCollectionField(Field f, Type typeOfF, Object obj) {
+    throw new UnsupportedOperationException();
+  }
+
+  public void visitObjectField(Field f, Type typeOfF, Object obj) {
+    throw new UnsupportedOperationException();
+  }
+
+  public void visitPrimitiveField(Field f, Type typeOfF, Object obj) {
+    throw new UnsupportedOperationException();
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonCompactFormatter.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonCompactFormatter.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonCompactFormatter.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.io.PrintWriter;
+
+/**
+ * Formats Json in a compact way eliminating all unnecessary whitespace.
+ *
+ * @author Inderjeet Singh
+ */
+final class JsonCompactFormatter implements JsonFormatter {
+
+  private static class FormattingVisitor implements JsonElementVisitor {
+    private final PrintWriter writer;
+    private final boolean serializeNulls;
+
+    FormattingVisitor(PrintWriter writer, boolean serializeNulls) {
+      this.writer = writer;
+      this.serializeNulls = serializeNulls;
+    }
+
+    public void visitPrimitive(JsonPrimitive primitive) {
+      writer.append(primitive.toString());
+    }
+
+    public void visitNull() {
+      writer.append("null");
+    }
+    
+    public void startArray(JsonArray array) {
+      writer.append('[');
+    }
+
+    public void visitArrayMember(JsonArray parent, JsonPrimitive member, boolean isFirst) {
+      if (!isFirst) {
+        writer.append(',');
+      }
+      writer.append(member.toString());
+    }
+
+    public void visitArrayMember(JsonArray parent, JsonArray member, boolean isFirst) {
+      if (!isFirst) {
+        writer.append(',');
+      }
+    }
+
+    public void visitArrayMember(JsonArray parent, JsonObject member, boolean isFirst) {
+      if (!isFirst) {
+        writer.append(',');
+      }
+    }
+
+    public void visitNullArrayMember(JsonArray parent, boolean isFirst) {
+      if (!isFirst) {
+        writer.append(',');
+      }
+    }
+
+    public void endArray(JsonArray array) {
+      writer.append(']');
+    }
+
+    public void startObject(JsonObject object) {
+      writer.append('{');
+    }
+
+    public void visitObjectMember(JsonObject parent, String memberName, JsonPrimitive member,
+        boolean isFirst) {
+      if (!isFirst) {
+        writer.append(',');
+      }
+      writer.append('"');
+      writer.append(memberName);
+      writer.append("\":");
+      writer.append(member.toString());
+    }
+
+    public void visitObjectMember(JsonObject parent, String memberName, JsonArray member,
+        boolean isFirst) {
+      if (!isFirst) {
+        writer.append(',');
+      }
+      writer.append('"');
+      writer.append(memberName);
+      writer.append("\":");
+    }
+
+    public void visitObjectMember(JsonObject parent, String memberName, JsonObject member,
+        boolean isFirst) {
+      if (!isFirst) {
+        writer.append(',');
+      }
+      writer.append('"');
+      writer.append(memberName);
+      writer.append("\":");
+    }
+
+    public void visitNullObjectMember(JsonObject parent, String memberName, boolean isFirst) {
+      if (serializeNulls) {
+        visitObjectMember(parent, memberName, (JsonObject) null, isFirst);
+      }      
+    }
+    
+    public void endObject(JsonObject object) {
+      writer.append('}');
+    }
+  }
+
+  public void format(JsonElement root, PrintWriter writer, boolean serializeNulls) {
+    if (root == null) {
+      return;
+    }
+    JsonElementVisitor visitor = 
+      new JsonEscapingVisitor(new FormattingVisitor(writer, serializeNulls));
+    JsonTreeNavigator navigator = new JsonTreeNavigator(visitor, serializeNulls);
+    navigator.navigate(root);
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializationContext.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializationContext.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializationContext.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Type;
+
+/**
+ * Context for deserialization that is passed to a custom deserializer during invocation of its 
+ * {@link JsonDeserializer#deserialize(JsonElement, Type, JsonDeserializationContext)}
+ * method. 
+ * 
+ * @author Inderjeet Singh
+ */
+public interface JsonDeserializationContext {
+  
+  /**
+   * Invokes default deserialization on the specified object. It should never be invoked on 
+   * the element received as a parameter of the 
+   * {@link JsonDeserializer#deserialize(JsonElement, Type, JsonDeserializationContext)} method. Doing
+   * so will result in an infinite loop since Gson will in-turn call the custom deserializer again. 
+
+   * @param json the parse tree.
+   * @param typeOfT type of the expected return value.
+   * @param <T> The type of the deserialized object.
+   * @return An object of type typeOfT.
+   * @throws JsonParseException if the parse tree does not contain expected data.
+   */
+  public <T> T deserialize(JsonElement json, Type typeOfT) throws JsonParseException;
+}
\ No newline at end of file

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializationContextDefault.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializationContextDefault.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializationContextDefault.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Type;
+
+/**
+ * implementation of a deserialization context for Gson
+ *
+ * @author Inderjeet Singh
+ */
+final class JsonDeserializationContextDefault implements JsonDeserializationContext {
+
+  private final ObjectNavigatorFactory navigatorFactory;
+  private final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers;
+  private final MappedObjectConstructor objectConstructor;
+  private final TypeAdapter typeAdapter;
+
+  JsonDeserializationContextDefault(ObjectNavigatorFactory navigatorFactory,
+      ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
+      MappedObjectConstructor objectConstructor, TypeAdapter typeAdapter) {
+    this.navigatorFactory = navigatorFactory;
+    this.deserializers = deserializers;
+    this.objectConstructor = objectConstructor;
+    this.typeAdapter = typeAdapter;
+  }
+
+  @SuppressWarnings("unchecked")
+  public <T> T deserialize(JsonElement json, Type typeOfT) throws JsonParseException {
+    if (json.isJsonArray()) {
+      return (T) fromJsonArray(typeOfT, json.getAsJsonArray(), this);
+    } else if (json.isJsonObject()) {
+      return (T) fromJsonObject(typeOfT, json.getAsJsonObject(), this);
+    } else if (json.isJsonPrimitive()) {
+      return (T) fromJsonPrimitive(typeOfT, json.getAsJsonPrimitive(), this);
+    } else if (json.isJsonNull()) {
+      return null;
+    } else {
+      throw new JsonParseException("Failed parsing JSON source: " + json + " to Json");
+    }
+  }
+
+  private <T> T fromJsonArray(Type arrayType, JsonArray jsonArray,
+      JsonDeserializationContext context) throws JsonParseException {
+    JsonArrayDeserializationVisitor<T> visitor = new JsonArrayDeserializationVisitor<T>(
+        jsonArray, arrayType, navigatorFactory, objectConstructor, typeAdapter, deserializers,
+        context);
+    Object target = visitor.getTarget();
+    ObjectNavigator on = navigatorFactory.create(target, arrayType);
+    on.accept(visitor);
+    return visitor.getTarget();
+  }
+
+  private <T> T fromJsonObject(Type typeOfT, JsonObject jsonObject,
+      JsonDeserializationContext context) throws JsonParseException {
+    JsonObjectDeserializationVisitor<T> visitor = new JsonObjectDeserializationVisitor<T>(
+        jsonObject, typeOfT, navigatorFactory, objectConstructor, typeAdapter, deserializers,
+        context);
+    Object target = visitor.getTarget();
+    ObjectNavigator on = navigatorFactory.create(target, typeOfT);
+    on.accept(visitor);
+    return visitor.getTarget();
+  }
+
+  @SuppressWarnings("unchecked")
+  private <T> T fromJsonPrimitive(Type typeOfT, JsonPrimitive json,
+      JsonDeserializationContext context) throws JsonParseException {
+    JsonPrimitiveDeserializationVisitor<T> visitor = new JsonPrimitiveDeserializationVisitor<T>(
+        json, typeOfT, navigatorFactory, objectConstructor, typeAdapter, deserializers, context);
+    Object target = visitor.getTarget();
+    ObjectNavigator on = navigatorFactory.create(target, typeOfT);
+    on.accept(visitor);
+    target = visitor.getTarget();
+    if (typeOfT instanceof Class) {
+      target = typeAdapter.adaptType(target, (Class) typeOfT);
+    }
+    return (T) target;
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializationVisitor.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializationVisitor.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializationVisitor.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Type;
+import java.util.logging.Logger;
+
+/**
+ * Abstract data value container for the {@link ObjectNavigator.Visitor}
+ * implementations.  This class exposes the {@link #getTarget()} method
+ * which returns the class that was visited by this object.
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+abstract class JsonDeserializationVisitor<T> implements ObjectNavigator.Visitor {
+
+  protected static Logger logger = Logger.getLogger(JsonDeserializationVisitor.class.getName());
+
+  protected final ObjectNavigatorFactory factory;
+  protected final ObjectConstructor objectConstructor;
+  protected final TypeAdapter typeAdapter;
+  protected final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers;
+  protected T target;
+  protected final JsonElement json;
+  protected final Type targetType;
+  private final JsonDeserializationContext context;
+
+  public JsonDeserializationVisitor(JsonElement json, Type targetType,
+      ObjectNavigatorFactory factory, ObjectConstructor objectConstructor, TypeAdapter typeAdapter,
+      ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
+      JsonDeserializationContext context) {
+    Preconditions.checkNotNull(json);
+    this.targetType = targetType;
+    this.factory = factory;
+    this.objectConstructor = objectConstructor;
+    this.typeAdapter = typeAdapter;
+    this.deserializers = deserializers;
+    this.json = json;
+    this.context = context;
+  }
+
+  T getTarget() {
+    if (target == null) {
+      target = constructTarget();
+    }
+    return target;
+  }
+
+  protected abstract T constructTarget();
+
+  @SuppressWarnings("unchecked")
+  public final void visitEnum(Object obj, Type objType) {
+    JsonDeserializer<T> deserializer = (JsonDeserializer<T>) deserializers.getHandlerFor(objType);
+    if (deserializer == null) {
+      deserializer =  (JsonDeserializer<T>) deserializers.getHandlerFor(Enum.class);
+    }
+    if (deserializer == null) {
+      throw new RuntimeException("Register a JsonDeserializer for Enum or "
+          + obj.getClass().getName());
+    }
+    target = deserializer.deserialize(json, objType, context);
+  }
+
+  @SuppressWarnings("unchecked")
+  public final boolean visitUsingCustomHandler(Object obj, Type objType) {
+    JsonDeserializer<T> deserializer = (JsonDeserializer<T>) deserializers.getHandlerFor(objType);
+    if (deserializer != null) {
+      target = deserializer.deserialize(json, objType, context);
+      return true;
+    }
+    return false;
+  }
+
+  final Object visitChildAsObject(Type childType, JsonElement jsonChild) {
+    JsonDeserializationVisitor<?> childVisitor =
+      new JsonObjectDeserializationVisitor<Object>(jsonChild, childType,
+          factory, objectConstructor, typeAdapter, deserializers, context);
+    return visitChild(childType, childVisitor);
+  }
+
+  final Object visitChildAsArray(Type childType, JsonArray jsonChild) {
+    JsonDeserializationVisitor<?> childVisitor =
+      new JsonArrayDeserializationVisitor<Object>(jsonChild.getAsJsonArray(), childType,
+          factory, objectConstructor, typeAdapter, deserializers, context);
+    return visitChild(childType, childVisitor);
+  }
+
+  final Object visitChildAsPrimitive(Type childType, JsonPrimitive jsonChild) {
+    Preconditions.checkNotNull(jsonChild);
+    Class<?> childClass;
+    if (childType instanceof Class) {
+      childClass = (Class<?>) childType;
+    } else {
+      childClass = TypeUtils.toRawClass(childType);
+    }
+    return typeAdapter.adaptType(jsonChild.getAsObject(), childClass);
+  }
+
+  final Object visitChild(Type childType, JsonElement jsonChild) {
+    if (jsonChild == null) {
+      return null;
+    } else if (jsonChild instanceof JsonArray) {
+      return visitChildAsArray(childType, jsonChild.getAsJsonArray());
+    } else if (jsonChild instanceof JsonObject) {
+      return visitChildAsObject(childType, jsonChild);
+    } else if (jsonChild instanceof JsonPrimitive) {
+      return visitChildAsPrimitive(childType, jsonChild.getAsJsonPrimitive());
+    } else {
+      throw new IllegalStateException();
+    }
+  }
+
+  private Object visitChild(Type type, JsonDeserializationVisitor<?> childVisitor) {
+    Object child = childVisitor.getTarget();
+    ObjectNavigator on = factory.create(child, type);
+    on.accept(childVisitor);
+    // the underlying object may have changed during the construction phase
+    // This happens primarily because of custom deserializers
+    return childVisitor.getTarget();
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializer.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializer.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializer.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Type;
+
+/**
+ * <p>Interface representing a custom deserializer for Json. You should write a custom
+ * deserializer, if you are not happy with the default deserialization done by Gson. You will
+ * also need to register this deserializer through
+ * {@link GsonBuilder#registerTypeAdapter(Type, Object)}.</p>
+ *
+ * <p>Let us look at example where defining a deserializer will be useful. The {@code Id} class
+ * defined below has two fields: {@code clazz} and {@code value}.</p>
+ *
+ * <pre>
+ * public class Id&lt;T&gt; {
+ *   private final Class&lt;T&gt; clazz;
+ *   private final long value;
+ *   public Id(Class&lt;T&gt; clazz, long value) {
+ *     this.clazz = clazz;
+ *     this.value = value;
+ *   }
+ *   public long getValue() {
+ *     return value;
+ *   }
+ * }
+ * </pre>
+ *
+ * <p>The default deserialization of {@code Id(com.foo.MyObject.class, 20L)} will require the
+ * Json string to be <code>{"clazz":com.foo.MyObject,"value":20}</code>. Suppose, you already know
+ * the type of the field that the {@code Id} will be deserialized into, and hence just want to
+ * deserialize it from a Json string {@code 20}. You can achieve that by writing a custom
+ * deserializer:</p>
+ *
+ * <pre>
+ * class IdDeserializer implements JsonDeserializer&lt;Id&gt;() {
+ *   public Id fromJson(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+ *       throws JsonParseException {
+ *     return (Id) new Id((Class)typeOfT, id.getValue());
+ *   }
+ * </pre>
+ *
+ * <p>You will also need to register {@code IdDeserializer} with Gson as follows:</p>
+ *
+ * <pre>
+ * Gson gson = new GsonBuilder().registerTypeAdapter(Id.class, new IdDeserializer()).create();
+ * </pre>
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ *
+ * @param <T> type for which the deserializer is being registered. It is possible that a
+ * deserializer may be asked to deserialize a specific generic type of the T.
+ */
+public interface JsonDeserializer<T> {
+
+  /**
+   * Gson invokes this call-back method during deserialization when it encounters a field of the
+   * specified type.
+   * <p>In the implementation of this call-back method, you should consider invoking
+   * {@link JsonDeserializationContext#deserialize(JsonElement, Type)} method to create objects
+   * for any non-trivial field of the returned object. However, you should never invoke it on the
+   * the same type passing {@code json} since that will cause an infinite loop (Gson will call your
+   * call-back method again).
+   *
+   * @param json The Json data being deserialized
+   * @param typeOfT The type of the Object to deserialize to
+   * @return a deserialized object of the specified type typeOfT which is a subclass of {@code T}
+   * @throws JsonParseException if json is not in the expected format of {@code typeofT}
+   */
+  public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+      throws JsonParseException;
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializerExceptionWrapper.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializerExceptionWrapper.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonDeserializerExceptionWrapper.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Type;
+
+/**
+ * Decorators a {@code JsonDeserializer} instance with exception handling.  This wrapper class
+ * ensures that a {@code JsonDeserializer} will not propagate any exception other than a
+ * {@link JsonParseException}.
+ *
+ * @param <T> type of the deserializer being wrapped.
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+class JsonDeserializerExceptionWrapper<T> implements JsonDeserializer<T> {
+
+  private final JsonDeserializer<T> delegate;
+
+  /**
+   * Returns a wrapped {@link JsonDeserializer} object that has been decorated with
+   * {@link JsonParseException} handling.
+   *
+   * @param delegate the {@code JsonDeserializer} instance to be wrapped.
+   * @throws IllegalArgumentException if {@code delegate} is {@code null}.
+   */
+  JsonDeserializerExceptionWrapper(JsonDeserializer<T> delegate) {
+    Preconditions.checkNotNull(delegate);
+    this.delegate = delegate;
+  }
+
+  public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+      throws JsonParseException {
+    try {
+      return delegate.deserialize(json, typeOfT, context);
+    } catch (JsonParseException e) {
+      // just rethrow the exception
+      throw e;
+    } catch (Exception e) {
+      // rethrow as a JsonParseException
+      StringBuilder errorMsg = new StringBuilder()
+          .append("The JsonDeserializer ")
+          .append(delegate)
+          .append(" failed to deserialized json object ")
+          .append(json)
+          .append(" given the type ")
+          .append(typeOfT);
+      throw new JsonParseException(errorMsg.toString(), e);
+    }
+  }
+  
+  @Override
+  public String toString() {
+    return delegate.toString();
+  }
+}
\ No newline at end of file

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonElement.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonElement.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonElement.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * A class representing an element of Json. It could either be a {@link JsonObject}, a
+ * {@link JsonArray}, a {@link JsonPrimitive} or a {@link JsonNull}.
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+public abstract class JsonElement {
+
+  /**
+   * provides check for verifying if this element is an array or not.
+   *
+   * @return true if this element is of type {@link JsonArray}, false otherwise.
+   */
+  public boolean isJsonArray() {
+    return this instanceof JsonArray;
+  }
+
+  /**
+   * provides check for verifying if this element is a Json object or not.
+   *
+   * @return true if this element is of type {@link JsonObject}, false otherwise.
+   */
+  public boolean isJsonObject() {
+    return this instanceof JsonObject;
+  }
+
+  /**
+   * provides check for verifying if this element is a primitive or not.
+   *
+   * @return true if this element is of type {@link JsonPrimitive}, false otherwise.
+   */
+  public boolean isJsonPrimitive() {
+    return this instanceof JsonPrimitive;
+  }
+
+  /**
+   * provides check for verifying if this element represents a null value or not.
+   *
+   * @return true if this element is of type {@link JsonNull}, false otherwise.
+   * @since 1.2
+   */
+  public boolean isJsonNull() {
+    return this instanceof JsonNull;
+  }
+
+  /**
+   * convenience method to get this element as a {@link JsonObject}. If the element is of some
+   * other type, a {@link ClassCastException} will result. Hence it is best to use this method
+   * after ensuring that this element is of the desired type by calling {@link #isJsonObject()}
+   * first.
+   *
+   * @return get this element as a {@link JsonObject}.
+   * @throws ClassCastException if the element is of another type.
+   */
+  public JsonObject getAsJsonObject() {
+    return (JsonObject) this;
+  }
+
+  /**
+   * convenience method to get this element as a {@link JsonArray}. If the element is of some
+   * other type, a {@link ClassCastException} will result. Hence it is best to use this method
+   * after ensuring that this element is of the desired type by calling {@link #isJsonArray()}
+   * first.
+   *
+   * @return get this element as a {@link JsonArray}.
+   * @throws ClassCastException if the element is of another type.
+   */
+  public JsonArray getAsJsonArray() {
+    return (JsonArray) this;
+  }
+
+  /**
+   * convenience method to get this element as a {@link JsonPrimitive}. If the element is of some
+   * other type, a {@link ClassCastException} will result. Hence it is best to use this method
+   * after ensuring that this element is of the desired type by calling {@link #isJsonPrimitive()}
+   * first.
+   *
+   * @return get this element as a {@link JsonPrimitive}.
+   * @throws ClassCastException if the element is of another type.
+   */
+  public JsonPrimitive getAsJsonPrimitive() {
+    return (JsonPrimitive) this;
+  }
+
+  /**
+   * convenience method to get this element as a {@link JsonNull}. If the element is of some
+   * other type, a {@link ClassCastException} will result. Hence it is best to use this method
+   * after ensuring that this element is of the desired type by calling {@link #isJsonNull()}
+   * first.
+   *
+   * @return get this element as a {@link JsonNull}.
+   * @throws ClassCastException if the element is of another type.
+   * @since 1.2
+   */
+  public JsonNull getAsJsonNull() {
+    return (JsonNull) this;
+  }
+
+  /**
+   * convenience method to get this element as a boolean value.
+   *
+   * @return get this element as a primitive boolean value.
+   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
+   * boolean value.
+   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
+   * more than a single element.
+   */
+  public boolean getAsBoolean() {
+    throw new UnsupportedOperationException();
+  }
+
+  /**
+   * convenience method to get this element as a {@link Boolean} value.
+   *
+   * @return get this element as a {@link Boolean} value.
+   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
+   * boolean value.
+   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
+   * more than a single element.
+   */
+  Boolean getAsBooleanWrapper() {
+    throw new UnsupportedOperationException();
+  }
+
+  /**
+   * convenience method to get this element as a {@link Number}.
+   *
+   * @return get this element as a {@link Number}.
+   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
+   * number.
+   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
+   * more than a single element.
+   */
+  public Number getAsNumber() {
+    throw new UnsupportedOperationException();
+  }
+
+  /**
+   * convenience method to get this element as a string value.
+   *
+   * @return get this element as a string value.
+   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
+   * string value.
+   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
+   * more than a single element.
+   */
+  public String getAsString() {
+    throw new UnsupportedOperationException();
+  }
+
+  /**
+   * convenience method to get this element as a primitive double value.
+   *
+   * @return get this element as a primitive double value.
+   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
+   * double value.
+   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
+   * more than a single element.
+   */
+  public double getAsDouble() {
+    throw new UnsupportedOperationException();
+  }
+
+  /**
+   * convenience method to get this element as a primitive float value.
+   *
+   * @return get this element as a primitive float value.
+   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
+   * float value.
+   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
+   * more than a single element.
+   */
+  public float getAsFloat() {
+    throw new UnsupportedOperationException();
+  }
+
+  /**
+   * convenience method to get this element as a primitive long value.
+   *
+   * @return get this element as a primitive long value.
+   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
+   * long value.
+   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
+   * more than a single element.
+   */
+  public long getAsLong() {
+    throw new UnsupportedOperationException();
+  }
+
+  /**
+   * convenience method to get this element as a primitive integer value.
+   *
+   * @return get this element as a primitive integer value.
+   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
+   * integer value.
+   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
+   * more than a single element.
+   */
+  public int getAsInt() {
+    throw new UnsupportedOperationException();
+  }
+
+  /**
+   * convenience method to get this element as a {@link BigDecimal}.
+   *
+   * @return get this element as a {@link BigDecimal}.
+   * @throws ClassCastException if the element is of not a {@link JsonPrimitive}.
+   * * @throws NumberFormatException if the element is not a valid {@link BigDecimal}.
+   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
+   * more than a single element.
+   * @since 1.2
+   */
+  public BigDecimal getAsBigDecimal() {
+    throw new UnsupportedOperationException();
+  }
+
+  /**
+   * convenience method to get this element as a {@link BigInteger}.
+   *
+   * @return get this element as a {@link BigInteger}.
+   * @throws ClassCastException if the element is of not a {@link JsonPrimitive}.
+   * @throws NumberFormatException if the element is not a valid {@link BigInteger}.
+   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
+   * more than a single element.
+   * @since 1.2
+   */
+  public BigInteger getAsBigInteger() {
+    throw new UnsupportedOperationException();
+  }
+
+  /**
+   * convenience method to get this element as a primitive short value.
+   *
+   * @return get this element as a primitive short value.
+   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
+   * short value.
+   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
+   * more than a single element.
+   */
+  public short getAsShort() {
+    throw new UnsupportedOperationException();
+  }
+
+  /**
+   * convenience method to get this element as an {@link Object} value.
+   *
+   * @return get this element as an Object value.
+   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
+   * Object value.
+   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
+   * more than a single element.
+   */
+  Object getAsObject() {
+    throw new UnsupportedOperationException();
+  }
+
+  /**
+   * Returns a String representation of this element.
+   *
+   * @return String the string representation of this element. The output is valid Json.
+   */
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder();
+    toString(sb);
+    return sb.toString();
+  }
+
+  protected abstract void toString(StringBuilder sb);
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonElementVisitor.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonElementVisitor.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonElementVisitor.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+/**
+ * Definition of a visitor for a JsonElement tree.
+ * 
+ * @author Inderjeet Singh
+ */
+interface JsonElementVisitor {
+  void visitPrimitive(JsonPrimitive primitive);
+  void visitNull();
+
+  void startArray(JsonArray array);
+  void visitArrayMember(JsonArray parent, JsonPrimitive member, boolean isFirst);
+  void visitArrayMember(JsonArray parent, JsonArray member, boolean isFirst);
+  void visitArrayMember(JsonArray parent, JsonObject member, boolean isFirst);
+  void visitNullArrayMember(JsonArray parent, boolean isFirst);
+  void endArray(JsonArray array);
+  
+  void startObject(JsonObject object);
+  void visitObjectMember(JsonObject parent, String memberName, JsonPrimitive member, 
+      boolean isFirst);
+  void visitObjectMember(JsonObject parent, String memberName, JsonArray member, boolean isFirst);
+  void visitObjectMember(JsonObject parent, String memberName, JsonObject member, boolean isFirst);
+  void visitNullObjectMember(JsonObject parent, String memberName, boolean isFirst);
+  void endObject(JsonObject object);
+}
\ No newline at end of file

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonEscapingVisitor.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonEscapingVisitor.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonEscapingVisitor.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+/**
+ * Performs JSON escaping and passes on the new escaped value to the delegate
+ * {@link JsonElementVisitor}.
+ *
+ * @author Joel Leitch
+ */
+class JsonEscapingVisitor extends DelegatingJsonElementVisitor {
+
+  /**
+   * Constructs a Visitor that will properly escape any JSON primitive values.
+   *
+   * @param delegate the JsonElementVisitor that this instance will use for delegation
+   */
+  protected JsonEscapingVisitor(JsonElementVisitor delegate) {
+    super(delegate);
+  }
+
+  @Override
+  public void visitArrayMember(JsonArray parent, JsonPrimitive member, boolean isFirst) {
+    super.visitArrayMember(parent, escapeJsonPrimitive(member), isFirst);
+  }
+
+  @Override
+  public void visitObjectMember(
+      JsonObject parent, String memberName, JsonPrimitive member, boolean isFirst) {
+    super.visitObjectMember(parent, memberName, escapeJsonPrimitive(member), isFirst);
+  }
+
+  @Override
+  public void visitPrimitive(JsonPrimitive primitive) {
+    super.visitPrimitive(escapeJsonPrimitive(primitive));
+  }
+
+  private JsonPrimitive escapeJsonPrimitive(JsonPrimitive member) {
+    if (member.isString()) {
+      String memberValue = member.getAsString();
+      String escapedValue = Escaper.escapeJsonString(memberValue);
+      if (!escapedValue.equals(memberValue)) {
+        member.setValue(escapedValue);
+      }
+    }
+    return member;
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonFieldNameValidator.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonFieldNameValidator.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonFieldNameValidator.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * This class can be used to check the validity of a JSON field name.
+ *
+ * <p>The primary use of this object is to ensure that any Java fields that use the
+ * {@link com.google.gson.annotations.SerializedName} annotation is providing valid JSON
+ * field names.  This will make the code fail-fast rather than letting the invalid
+ * field name propagate to the client and it fails to parse.</p>
+ *
+ * @author Joel Leitch
+ */
+class JsonFieldNameValidator {
+  private static final String[] JS_KEYWORDS = {
+    "break", "case", "catch", "class", "comment", "const", "continue", "debugger", "default", "delete", "do",
+    "else", "enum", "export", "extends", "finally", "for", "function", "if", "import", "in", "label", "new",
+    "return", "super", "switch", "this", "throw", "try", "typeof", "var", "void", "while", "with"
+  };
+
+  private static final Pattern JSON_FIELD_NAME_PATTERN =
+      Pattern.compile("(^[a-zA-Z][a-zA-Z0-9\\$_]*$)|(^[\\$_][a-zA-Z][a-zA-Z0-9\\$_]*$)");
+
+  private static final Set<String> KEYWORDS = Collections.unmodifiableSet(
+      new HashSet<String>(Arrays.asList(JS_KEYWORDS)));
+
+  /**
+   * Performs validation on the JSON field name to ensure it is a valid field name.
+   *
+   * @param fieldName the name of the field to validate
+   * @return {@code fieldName} if it is a valid JSON field name
+   * @throws IllegalArgumentException if the field name is an invalid JSON field name
+   */
+  public String validate(String fieldName) {
+    Preconditions.checkNotNull(fieldName);
+    Preconditions.checkArgument(!"".equals(fieldName.trim()));
+    Preconditions.checkArgument(!KEYWORDS.contains(fieldName));
+
+    Matcher matcher = JSON_FIELD_NAME_PATTERN.matcher(fieldName);
+    if (!matcher.matches()) {
+      throw new IllegalArgumentException(fieldName + " is not a valid JSON field name.");
+    } else {
+      return fieldName;
+    }
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonFormatter.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonFormatter.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonFormatter.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.io.PrintWriter;
+
+/**
+ * Common interface for a formatter for Json. 
+ * 
+ * @author Inderjeet Singh
+ */
+interface JsonFormatter {
+
+  /**
+   * Writes a formatted version of the Json corresponding to 
+   * the specified Json.  
+   * 
+   * @param root the root of the Json tree. 
+   * @param writer the writer to output the formatter JSON to.
+   * @param serializeNulls serialize null values in the output.
+   */
+  public void format(JsonElement root, PrintWriter writer, boolean serializeNulls);
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonNull.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonNull.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonNull.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+/**
+ * A class representing a Json null value.
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ * @since 1.2
+ */
+public final class JsonNull extends JsonElement {
+
+  @Override
+  protected void toString(StringBuilder sb) {
+    sb.append("null");
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonObject.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonObject.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonObject.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+/**
+ * A class representing an object type in Json. An object consists of name-value pairs where names 
+ * are strings, and values are any other type of {@link JsonElement}. This allows for a creating a 
+ * tree of JsonElements. The member elements of this object are maintained in order they were added. 
+ * 
+ * @author Inderjeet Singh
+ */
+public final class JsonObject extends JsonElement {
+  // We are using a linked hash map because it is important to preserve
+  // the order in which elements are inserted. This is needed to ensure
+  // that the fields of an object are inserted in the order they were 
+  // defined in the class. 
+  private final Map<String, JsonElement> members;
+
+  /**
+   * Creates an empty JsonObject.
+   */
+  public JsonObject() {
+    members = new LinkedHashMap<String, JsonElement>();
+  }
+  
+  /**
+   * Adds a member, which is a name-value pair, to self. The name must be a String, but the value
+   * can be an arbitrary JsonElement, thereby allowing you to build a full tree of JsonElements
+   * rooted at this node. 
+   *   
+   * @param property name of the member.
+   * @param value the member object.
+   */
+  public void add(String property, JsonElement value) {
+    members.put(property, value);
+  }
+  
+  /**
+   * Convenience method to add a primitive member. The specified value is converted to a 
+   * JsonPrimitive of String. 
+   *  
+   * @param property name of the member.
+   * @param value the string value associated with the member.
+   */
+  public void addProperty(String property, String value) {
+    members.put(property, new JsonPrimitive(value));
+  }
+  
+  /**
+   * Convenience method to add a primitive member. The specified value is converted to a 
+   * JsonPrimitive of Number. 
+   *  
+   * @param property name of the member.
+   * @param value the number value associated with the member.
+   */
+  public void addProperty(String property, Number value) {
+    members.put(property, new JsonPrimitive(value));
+  }
+
+  /**
+   * Returns a set of members of this object. The set is ordered, and the order is in which the 
+   * elements were added. 
+   *  
+   * @return a set of members of this object. 
+   */
+  public Set<Entry<String, JsonElement>> entrySet() {
+    return members.entrySet();
+  }
+  
+  /**
+   * Convenience method to check if a member with the specified name is present in this object. 
+   * 
+   * @param memberName name of the member that is being checked for presence.
+   * @return true if there is a member with the specified name, false otherwise. 
+   */
+  public boolean has(String memberName) {
+    return members.containsKey(memberName);
+  }
+  
+  /**
+   * Returns the member with the specified name. 
+   * 
+   * @param memberName name of the member that is being requested.
+   * @return the member matching the name. Null if no such member exists. 
+   */
+  public JsonElement get(String memberName) {
+    return members.get(memberName);
+  }
+  
+  /**
+   * Convenience method to get the specified member as a JsonPrimitive element. 
+   * 
+   * @param memberName name of the member being requested. 
+   * @return the JsonPrimitive corresponding to the specified member. 
+   */
+  public JsonPrimitive getAsJsonPrimitive(String memberName) {
+    return (JsonPrimitive) members.get(memberName);
+  }
+  
+  /**
+   * Convenience method to get the specified member as a JsonArray.
+   * 
+   * @param memberName name of the member being requested. 
+   * @return the JsonArray corresponding to the specified member.
+   */
+  public JsonArray getAsJsonArray(String memberName) {
+    return (JsonArray) members.get(memberName);
+  }
+
+  /**
+   * Convenience method to get the specified member as a JsonObject.
+   * 
+   * @param memberName name of the member being requested. 
+   * @return the JsonObject corresponding to the specified member.
+   */
+  public JsonObject getAsJsonObject(String memberName) {
+    return (JsonObject) members.get(memberName);
+  }
+
+  @Override
+  protected void toString(StringBuilder sb) {
+    sb.append('{');
+    boolean first = true;
+    for (Map.Entry<String, JsonElement> entry : members.entrySet()) {
+      if (first) {
+        first = false;
+      } else {
+        sb.append(',');
+      }
+      sb.append('\"');
+      sb.append(entry.getKey());
+      sb.append("\":");
+      entry.getValue().toString(sb);
+    }
+    sb.append('}');
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonObjectDeserializationVisitor.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonObjectDeserializationVisitor.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonObjectDeserializationVisitor.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+import java.util.Collection;
+
+/**
+ * A visitor that populates fields of an object with data from its equivalent
+ * JSON representation
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+final class JsonObjectDeserializationVisitor<T> extends JsonDeserializationVisitor<T> {
+
+  JsonObjectDeserializationVisitor(JsonElement json, Type type,
+      ObjectNavigatorFactory factory, ObjectConstructor objectConstructor,
+      TypeAdapter typeAdapter, ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
+      JsonDeserializationContext context) {
+    super(json, type, factory, objectConstructor, typeAdapter, deserializers, context);
+  }
+
+  @Override
+  @SuppressWarnings("unchecked")
+  protected T constructTarget() {
+    return (T) objectConstructor.construct(targetType);
+  }
+
+  public void startVisitingObject(Object node) {
+    // do nothing
+  }
+
+  public void endVisitingObject(Object node) {
+    // do nothing
+  }
+
+  public void visitCollection(@SuppressWarnings("unchecked")Collection collection,
+      Type componentType) {
+    // should not be called since this case should invoke JsonArrayDeserializationVisitor
+    throw new IllegalStateException();
+  }
+
+  public void visitArray(Object array, Type componentType) {
+    // should not be called since this case should invoke JsonArrayDeserializationVisitor
+    throw new IllegalStateException();
+  }
+
+  public void visitPrimitiveValue(Object obj) {
+    // should not be called since this case should invoke JsonPrimitiveDeserializationVisitor
+    throw new IllegalStateException();
+  }
+
+  public void visitObjectField(Field f, Type typeOfF, Object obj) {
+    try {
+      JsonObject jsonObject = json.getAsJsonObject();
+      String fName = getFieldName(f);
+      JsonElement jsonChild = jsonObject.get(fName);
+      if (jsonChild != null) {
+        Object child = visitChildAsObject(typeOfF, jsonChild);
+        f.set(obj, child);
+      } else {
+        f.set(obj, null);
+      }
+    } catch (IllegalAccessException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void visitCollectionField(Field f, Type typeOfF, Object obj) {
+    try {
+      JsonObject jsonObject = json.getAsJsonObject();
+      String fName = getFieldName(f);
+      JsonArray jsonArray = (JsonArray) jsonObject.get(fName);
+      if (jsonArray != null) {
+        Collection collection = (Collection) objectConstructor.construct(typeOfF);
+        f.set(obj, collection);
+        Type childType = TypeUtils.getActualTypeForFirstTypeVariable(typeOfF);
+        for (JsonElement jsonChild : jsonArray) {
+          Object child = visitChild(childType, jsonChild);
+          if (childType == Object.class) {
+            throw new JsonParseException(fName +
+                " can not be a raw collection. Try making it a genericized collection instead");
+          }
+          collection.add(child);
+        }
+      } else {
+        f.set(obj, null);
+      }
+    } catch (IllegalAccessException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public void visitArrayField(Field f, Type typeOfF, Object obj) {
+    try {
+      JsonObject jsonObject = json.getAsJsonObject();
+      String fName = getFieldName(f);
+      JsonArray jsonChild = (JsonArray) jsonObject.get(fName);
+      if (jsonChild != null) {
+        Object array = visitChildAsArray(typeOfF, jsonChild);
+        f.set(obj, array);
+      } else {
+        f.set(obj, null);
+      }
+    } catch (IllegalAccessException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public void visitPrimitiveField(Field f, Type typeOfF, Object obj) {
+    try {
+      JsonObject jsonObject = json.getAsJsonObject();
+      String fName = getFieldName(f);
+      JsonPrimitive value = jsonObject.getAsJsonPrimitive(fName);
+      if (value != null) {
+        f.set(obj, typeAdapter.adaptType(value.getAsObject(), TypeUtils.toRawClass(typeOfF)));
+      } else {
+        // For Strings, we need to set the field to null
+        // For other primitive types, any value created during default construction is fine
+        if (f.getType() == String.class) {
+          f.set(obj, null);
+        }
+      }
+    } catch (IllegalAccessException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  private String getFieldName(Field f) {
+    FieldNamingStrategy namingPolicy = factory.getFieldNamingPolicy();
+    return namingPolicy.translateName(f);
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonParseException.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonParseException.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonParseException.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+/**
+ * This exception is raised if there is a serious issue that occurs during parsing of a Json
+ * string.  One of the main usages for this class is for the Gson infrastructure.  If the incoming
+ * Json is bad/malicious, an instance of this exception is raised.
+ *
+ * <p>This exception is a {@link RuntimeException} because it is exposed to the client.  Using a
+ * {@link RuntimeException} avoids bad coding practices on the client side where they catch the
+ * exception and do nothing.  It is often the case that you want to blow up if there is a parsing
+ * error (i.e. often clients do not know how to recover from a {@link JsonParseException}.</p>
+ *
+ * @author Joel Leitch
+ */
+public final class JsonParseException extends RuntimeException {
+  static final long serialVersionUID = -4086729973971783390L;
+
+  /**
+   * Creates exception with the specified message. If you are wrapping another exception, consider
+   * using {@link #JsonParseException(String, Throwable)} instead.
+   *
+   * @param msg error message describing a possible cause of this exception.
+   */
+  public JsonParseException(String msg) {
+    super(msg);
+  }
+
+  /**
+   * Creates exception with the specified message and cause.
+   *
+   * @param msg error message describing what happened.
+   * @param cause root exception that caused this exception to be thrown.
+   */
+  public JsonParseException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+
+  /**
+   * Creates exception with the specified cause. Consider using
+   * {@link #JsonParseException(String, Throwable)} instead if you can describe what happened.
+   *
+   * @param cause root exception that caused this exception to be thrown.
+   */
+  public JsonParseException(Throwable cause) {
+    super(cause);
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonParser.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonParser.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonParser.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,444 @@
+/* Generated By:JavaCC: Do not edit this line. JsonParser.java */
+package com.google.gson;
+
+ at SuppressWarnings("all")
+final class JsonParser implements JsonParserConstants {
+
+  final public JsonElement parse() throws ParseException {
+  JsonElement json = null;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 20:
+      json = JsonObject();
+      break;
+    case 25:
+      json = JsonArray();
+      break;
+    case DIGITS:
+    case SINGLE_QUOTE_LITERAL:
+    case DOUBLE_QUOTE_LITERAL:
+    case 27:
+    case 28:
+    case 29:
+      json = JsonPrimitive();
+      break;
+    case 22:
+      json = JsonNull();
+      break;
+    default:
+      jj_la1[0] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) return json;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final private JsonObject JsonObject() throws ParseException {
+  JsonObject o = new JsonObject();
+    jj_consume_token(20);
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case SINGLE_QUOTE_LITERAL:
+    case DOUBLE_QUOTE_LITERAL:
+      Members(o);
+      break;
+    default:
+      jj_la1[1] = jj_gen;
+      ;
+    }
+    jj_consume_token(21);
+    {if (true) return o;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final private JsonNull JsonNull() throws ParseException {
+  JsonNull json = new JsonNull();
+    jj_consume_token(22);
+    {if (true) return json;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final private void Members(JsonObject o) throws ParseException {
+    Pair(o);
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 23:
+      jj_consume_token(23);
+      Members(o);
+      break;
+    default:
+      jj_la1[2] = jj_gen;
+      ;
+    }
+  }
+
+  final private void Pair(JsonObject o) throws ParseException {
+  JsonPrimitive property;
+  JsonElement value;
+    property = JsonString();
+    jj_consume_token(24);
+    value = JsonValue();
+    o.add(property.getAsString(), value);
+  }
+
+  final private JsonArray JsonArray() throws ParseException {
+  JsonArray array = new JsonArray();
+    jj_consume_token(25);
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case DIGITS:
+    case SINGLE_QUOTE_LITERAL:
+    case DOUBLE_QUOTE_LITERAL:
+    case 20:
+    case 22:
+    case 25:
+    case 27:
+    case 28:
+    case 29:
+      Elements(array);
+      break;
+    default:
+      jj_la1[3] = jj_gen;
+      ;
+    }
+    jj_consume_token(26);
+    array.reverse();
+    {if (true) return array;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final private void Elements(JsonArray array) throws ParseException {
+  JsonElement element;
+    element = JsonValue();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 23:
+      jj_consume_token(23);
+      Elements(array);
+      break;
+    default:
+      jj_la1[4] = jj_gen;
+      ;
+    }
+    array.add(element);
+  }
+
+  final private JsonElement JsonValue() throws ParseException {
+  JsonElement o = null;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case SINGLE_QUOTE_LITERAL:
+    case DOUBLE_QUOTE_LITERAL:
+      o = JsonString();
+      break;
+    case DIGITS:
+    case 29:
+      o = JsonNumber();
+      break;
+    case 20:
+      o = JsonObject();
+      break;
+    case 25:
+      o = JsonArray();
+      break;
+    case 27:
+      jj_consume_token(27);
+             o = new JsonPrimitive(true);
+      break;
+    case 28:
+      jj_consume_token(28);
+              o = new JsonPrimitive(false);
+      break;
+    case 22:
+      jj_consume_token(22);
+      break;
+    default:
+      jj_la1[5] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) return o;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final private JsonPrimitive JsonPrimitive() throws ParseException {
+  JsonPrimitive value;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case SINGLE_QUOTE_LITERAL:
+    case DOUBLE_QUOTE_LITERAL:
+      value = JsonString();
+                          {if (true) return value;}
+      break;
+    case DIGITS:
+    case 29:
+      value = JsonNumber();
+                          {if (true) return value;}
+      break;
+    case 27:
+      jj_consume_token(27);
+             {if (true) return new JsonPrimitive(true);}
+      break;
+    case 28:
+      jj_consume_token(28);
+              {if (true) return new JsonPrimitive(false);}
+      break;
+    default:
+      jj_la1[6] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final private JsonPrimitive JsonNumber() throws ParseException {
+  String intpart = null,
+         fracpart = null,
+         exppart = null;
+    intpart = JsonInt();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 30:
+      fracpart = JsonFrac();
+      break;
+    default:
+      jj_la1[7] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case E:
+      exppart = JsonExp();
+      break;
+    default:
+      jj_la1[8] = jj_gen;
+      ;
+    }
+    Number n;
+    if (exppart != null) {
+      n = new java.math.BigDecimal(intpart + fracpart + exppart);
+    } else if (fracpart != null) {
+      n = new Double(intpart + fracpart);
+    } else {
+      // See if the number fits in an integer, or long
+      // Use BigInteger only if it is big enough.
+      if (intpart.length() < 10) {
+        n = new Integer(intpart);
+      } else if (intpart.length() < 19) {
+        n = new Long(intpart);
+      } else {
+        n = new java.math.BigInteger(intpart);
+      }
+    }
+    {if (true) return new JsonPrimitive(n);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final private String JsonInt() throws ParseException {
+  String digits;
+  boolean negative = false;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 29:
+      jj_consume_token(29);
+         negative = true;
+      break;
+    default:
+      jj_la1[9] = jj_gen;
+      ;
+    }
+    digits = Digits();
+    if(negative)
+      {if (true) return "-" + digits;}
+    {if (true) return digits;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final private String JsonFrac() throws ParseException {
+  String digits;
+    jj_consume_token(30);
+    digits = Digits();
+    {if (true) return "." + digits;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final private String JsonExp() throws ParseException {
+  Token t;
+  String digits;
+    t = jj_consume_token(E);
+    digits = Digits();
+    {if (true) return t.image + digits;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final private String Digits() throws ParseException {
+  Token t;
+    t = jj_consume_token(DIGITS);
+    {if (true) return t.image;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final private JsonPrimitive JsonString() throws ParseException {
+  Token t;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case SINGLE_QUOTE_LITERAL:
+      t = jj_consume_token(SINGLE_QUOTE_LITERAL);
+      break;
+    case DOUBLE_QUOTE_LITERAL:
+      t = jj_consume_token(DOUBLE_QUOTE_LITERAL);
+      break;
+    default:
+      jj_la1[10] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    String value = StringUnmarshaller.unmarshall(t.image);
+    {if (true) return new JsonPrimitive(value);}
+    throw new Error("Missing return statement in function");
+  }
+
+  public JsonParserTokenManager token_source;
+  SimpleCharStream jj_input_stream;
+  public Token token, jj_nt;
+  private int jj_ntk;
+  private int jj_gen;
+  final private int[] jj_la1 = new int[11];
+  static private int[] jj_la1_0;
+  static {
+      jj_la1_0();
+   }
+   private static void jj_la1_0() {
+      jj_la1_0 = new int[] {0x3a500c40,0xc00,0x800000,0x3a500c40,0x800000,0x3a500c40,0x38000c40,0x40000000,0x20,0x20000000,0xc00,};
+   }
+
+  public JsonParser(java.io.InputStream stream) {
+     this(stream, null);
+  }
+  public JsonParser(java.io.InputStream stream, String encoding) {
+    try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
+    token_source = new JsonParserTokenManager(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 11; i++) jj_la1[i] = -1;
+  }
+
+  public void ReInit(java.io.InputStream stream) {
+     ReInit(stream, null);
+  }
+  public void ReInit(java.io.InputStream stream, String encoding) {
+    try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
+    token_source.ReInit(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 11; i++) jj_la1[i] = -1;
+  }
+
+  public JsonParser(java.io.Reader stream) {
+    jj_input_stream = new SimpleCharStream(stream, 1, 1);
+    token_source = new JsonParserTokenManager(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 11; i++) jj_la1[i] = -1;
+  }
+
+  public void ReInit(java.io.Reader stream) {
+    jj_input_stream.ReInit(stream, 1, 1);
+    token_source.ReInit(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 11; i++) jj_la1[i] = -1;
+  }
+
+  public JsonParser(JsonParserTokenManager tm) {
+    token_source = tm;
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 11; i++) jj_la1[i] = -1;
+  }
+
+  public void ReInit(JsonParserTokenManager tm) {
+    token_source = tm;
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 11; i++) jj_la1[i] = -1;
+  }
+
+  final private Token jj_consume_token(int kind) throws ParseException {
+    Token oldToken;
+    if ((oldToken = token).next != null) token = token.next;
+    else token = token.next = token_source.getNextToken();
+    jj_ntk = -1;
+    if (token.kind == kind) {
+      jj_gen++;
+      return token;
+    }
+    token = oldToken;
+    jj_kind = kind;
+    throw generateParseException();
+  }
+
+  final public Token getNextToken() {
+    if (token.next != null) token = token.next;
+    else token = token.next = token_source.getNextToken();
+    jj_ntk = -1;
+    jj_gen++;
+    return token;
+  }
+
+  final public Token getToken(int index) {
+    Token t = token;
+    for (int i = 0; i < index; i++) {
+      if (t.next != null) t = t.next;
+      else t = t.next = token_source.getNextToken();
+    }
+    return t;
+  }
+
+  final private int jj_ntk() {
+    if ((jj_nt=token.next) == null)
+      return (jj_ntk = (token.next=token_source.getNextToken()).kind);
+    else
+      return (jj_ntk = jj_nt.kind);
+  }
+
+  private java.util.Vector jj_expentries = new java.util.Vector();
+  private int[] jj_expentry;
+  private int jj_kind = -1;
+
+  public ParseException generateParseException() {
+    jj_expentries.removeAllElements();
+    boolean[] la1tokens = new boolean[31];
+    for (int i = 0; i < 31; i++) {
+      la1tokens[i] = false;
+    }
+    if (jj_kind >= 0) {
+      la1tokens[jj_kind] = true;
+      jj_kind = -1;
+    }
+    for (int i = 0; i < 11; i++) {
+      if (jj_la1[i] == jj_gen) {
+        for (int j = 0; j < 32; j++) {
+          if ((jj_la1_0[i] & (1<<j)) != 0) {
+            la1tokens[j] = true;
+          }
+        }
+      }
+    }
+    for (int i = 0; i < 31; i++) {
+      if (la1tokens[i]) {
+        jj_expentry = new int[1];
+        jj_expentry[0] = i;
+        jj_expentries.addElement(jj_expentry);
+      }
+    }
+    int[][] exptokseq = new int[jj_expentries.size()][];
+    for (int i = 0; i < jj_expentries.size(); i++) {
+      exptokseq[i] = (int[])jj_expentries.elementAt(i);
+    }
+    return new ParseException(token, exptokseq, tokenImage);
+  }
+
+  final public void enable_tracing() {
+  }
+
+  final public void disable_tracing() {
+  }
+
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonParserConstants.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonParserConstants.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonParserConstants.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,60 @@
+/* Generated By:JavaCC: Do not edit this line. JsonParserConstants.java */
+package com.google.gson;
+
+interface JsonParserConstants {
+
+  int EOF = 0;
+  int E = 5;
+  int DIGITS = 6;
+  int HEX_CHAR = 7;
+  int UNICODE_CHAR = 8;
+  int ESCAPE_CHAR = 9;
+  int SINGLE_QUOTE_LITERAL = 10;
+  int DOUBLE_QUOTE_LITERAL = 11;
+  int QUOTE = 12;
+  int ENDQUOTE = 14;
+  int CHAR = 15;
+  int CNTRL_ESC = 16;
+  int HEX = 18;
+  int HEX_ESC = 19;
+
+  int DEFAULT = 0;
+  int STRING_STATE = 1;
+  int ESC_STATE = 2;
+  int HEX_STATE = 3;
+
+  String[] tokenImage = {
+    "<EOF>",
+    "\" \"",
+    "\"\\t\"",
+    "\"\\n\"",
+    "\"\\r\"",
+    "<E>",
+    "<DIGITS>",
+    "<HEX_CHAR>",
+    "<UNICODE_CHAR>",
+    "<ESCAPE_CHAR>",
+    "<SINGLE_QUOTE_LITERAL>",
+    "<DOUBLE_QUOTE_LITERAL>",
+    "\"\\\"\"",
+    "\"\\\\\"",
+    "<ENDQUOTE>",
+    "<CHAR>",
+    "<CNTRL_ESC>",
+    "\"u\"",
+    "<HEX>",
+    "<HEX_ESC>",
+    "\"{\"",
+    "\"}\"",
+    "\"null\"",
+    "\",\"",
+    "\":\"",
+    "\"[\"",
+    "\"]\"",
+    "\"true\"",
+    "\"false\"",
+    "\"-\"",
+    "\".\"",
+  };
+
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonParserTokenManager.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonParserTokenManager.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonParserTokenManager.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,1004 @@
+/* Generated By:JavaCC: Do not edit this line. JsonParserTokenManager.java */
+package com.google.gson;
+
+ at SuppressWarnings("all")
+final class JsonParserTokenManager implements JsonParserConstants
+{
+  public  java.io.PrintStream debugStream = System.out;
+  public  void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
+private final int jjMoveStringLiteralDfa0_3()
+{
+   return jjMoveNfa_3(0, 0);
+}
+private final void jjCheckNAdd(int state)
+{
+   if (jjrounds[state] != jjround)
+   {
+      jjstateSet[jjnewStateCnt++] = state;
+      jjrounds[state] = jjround;
+   }
+}
+private final void jjAddStates(int start, int end)
+{
+   do {
+      jjstateSet[jjnewStateCnt++] = jjnextStates[start];
+   } while (start++ != end);
+}
+private final void jjCheckNAddTwoStates(int state1, int state2)
+{
+   jjCheckNAdd(state1);
+   jjCheckNAdd(state2);
+}
+private final void jjCheckNAddStates(int start, int end)
+{
+   do {
+      jjCheckNAdd(jjnextStates[start]);
+   } while (start++ != end);
+}
+private final void jjCheckNAddStates(int start)
+{
+   jjCheckNAdd(jjnextStates[start]);
+   jjCheckNAdd(jjnextStates[start + 1]);
+}
+private final int jjMoveNfa_3(int startState, int curPos)
+{
+   int[] nextStates;
+   int startsAt = 0;
+   jjnewStateCnt = 4;
+   int i = 1;
+   jjstateSet[0] = startState;
+   int j, kind = 0x7fffffff;
+   for (;;)
+   {
+      if (++jjround == 0x7fffffff)
+         ReInitRounds();
+      if (curChar < 64)
+      {
+         long l = 1L << curChar;
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 1;
+                  break;
+               case 1:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 2;
+                  break;
+               case 2:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 3;
+                  break;
+               case 3:
+                  if ((0x3ff000000000000L & l) != 0L && kind > 19)
+                     kind = 19;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 1;
+                  break;
+               case 1:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 2;
+                  break;
+               case 2:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 3;
+                  break;
+               case 3:
+                  if ((0x7e0000007eL & l) != 0L && kind > 19)
+                     kind = 19;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int hiByte = (int)(curChar >> 8);
+         int i1 = hiByte >> 6;
+         long l1 = 1L << (hiByte & 077);
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 4 - (jjnewStateCnt = startsAt)))
+         return curPos;
+      try { curChar = input_stream.readChar(); }
+      catch(java.io.IOException e) { return curPos; }
+   }
+}
+private final int jjStopStringLiteralDfa_0(int pos, long active0)
+{
+   switch (pos)
+   {
+      case 0:
+         if ((active0 & 0x1000L) != 0L)
+            return 31;
+         return -1;
+      default :
+         return -1;
+   }
+}
+private final int jjStartNfa_0(int pos, long active0)
+{
+   return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
+}
+private final int jjStopAtPos(int pos, int kind)
+{
+   jjmatchedKind = kind;
+   jjmatchedPos = pos;
+   return pos + 1;
+}
+private final int jjStartNfaWithStates_0(int pos, int kind, int state)
+{
+   jjmatchedKind = kind;
+   jjmatchedPos = pos;
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) { return pos + 1; }
+   return jjMoveNfa_0(state, pos + 1);
+}
+private final int jjMoveStringLiteralDfa0_0()
+{
+   switch(curChar)
+   {
+      case 34:
+         return jjStartNfaWithStates_0(0, 12, 31);
+      case 44:
+         return jjStopAtPos(0, 23);
+      case 45:
+         return jjStopAtPos(0, 29);
+      case 46:
+         return jjStopAtPos(0, 30);
+      case 58:
+         return jjStopAtPos(0, 24);
+      case 91:
+         return jjStopAtPos(0, 25);
+      case 93:
+         return jjStopAtPos(0, 26);
+      case 102:
+         return jjMoveStringLiteralDfa1_0(0x10000000L);
+      case 110:
+         return jjMoveStringLiteralDfa1_0(0x400000L);
+      case 116:
+         return jjMoveStringLiteralDfa1_0(0x8000000L);
+      case 123:
+         return jjStopAtPos(0, 20);
+      case 125:
+         return jjStopAtPos(0, 21);
+      default :
+         return jjMoveNfa_0(0, 0);
+   }
+}
+private final int jjMoveStringLiteralDfa1_0(long active0)
+{
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(0, active0);
+      return 1;
+   }
+   switch(curChar)
+   {
+      case 97:
+         return jjMoveStringLiteralDfa2_0(active0, 0x10000000L);
+      case 114:
+         return jjMoveStringLiteralDfa2_0(active0, 0x8000000L);
+      case 117:
+         return jjMoveStringLiteralDfa2_0(active0, 0x400000L);
+      default :
+         break;
+   }
+   return jjStartNfa_0(0, active0);
+}
+private final int jjMoveStringLiteralDfa2_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjStartNfa_0(0, old0); 
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(1, active0);
+      return 2;
+   }
+   switch(curChar)
+   {
+      case 108:
+         return jjMoveStringLiteralDfa3_0(active0, 0x10400000L);
+      case 117:
+         return jjMoveStringLiteralDfa3_0(active0, 0x8000000L);
+      default :
+         break;
+   }
+   return jjStartNfa_0(1, active0);
+}
+private final int jjMoveStringLiteralDfa3_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjStartNfa_0(1, old0); 
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(2, active0);
+      return 3;
+   }
+   switch(curChar)
+   {
+      case 101:
+         if ((active0 & 0x8000000L) != 0L)
+            return jjStopAtPos(3, 27);
+         break;
+      case 108:
+         if ((active0 & 0x400000L) != 0L)
+            return jjStopAtPos(3, 22);
+         break;
+      case 115:
+         return jjMoveStringLiteralDfa4_0(active0, 0x10000000L);
+      default :
+         break;
+   }
+   return jjStartNfa_0(2, active0);
+}
+private final int jjMoveStringLiteralDfa4_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjStartNfa_0(2, old0); 
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(3, active0);
+      return 4;
+   }
+   switch(curChar)
+   {
+      case 101:
+         if ((active0 & 0x10000000L) != 0L)
+            return jjStopAtPos(4, 28);
+         break;
+      default :
+         break;
+   }
+   return jjStartNfa_0(3, active0);
+}
+static final long[] jjbitVec0 = {
+   0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec2 = {
+   0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+private final int jjMoveNfa_0(int startState, int curPos)
+{
+   int[] nextStates;
+   int startsAt = 0;
+   jjnewStateCnt = 31;
+   int i = 1;
+   jjstateSet[0] = startState;
+   int j, kind = 0x7fffffff;
+   for (;;)
+   {
+      if (++jjround == 0x7fffffff)
+         ReInitRounds();
+      if (curChar < 64)
+      {
+         long l = 1L << curChar;
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 31:
+                  if ((0xfffffffbffffdbffL & l) != 0L)
+                     jjCheckNAddStates(0, 3);
+                  else if (curChar == 34)
+                  {
+                     if (kind > 11)
+                        kind = 11;
+                  }
+                  break;
+               case 0:
+                  if ((0x3ff000000000000L & l) != 0L)
+                  {
+                     if (kind > 6)
+                        kind = 6;
+                     jjCheckNAdd(2);
+                  }
+                  else if (curChar == 34)
+                     jjCheckNAddStates(0, 3);
+                  else if (curChar == 39)
+                     jjCheckNAddStates(4, 7);
+                  break;
+               case 1:
+                  if ((0x280000000000L & l) != 0L && kind > 5)
+                     kind = 5;
+                  break;
+               case 2:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 6)
+                     kind = 6;
+                  jjCheckNAdd(2);
+                  break;
+               case 4:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 5;
+                  break;
+               case 5:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 6;
+                  break;
+               case 6:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 7;
+                  break;
+               case 7:
+                  if ((0x3ff000000000000L & l) != 0L && kind > 8)
+                     kind = 8;
+                  break;
+               case 9:
+                  if (curChar == 39)
+                     jjCheckNAddStates(4, 7);
+                  break;
+               case 10:
+                  if ((0xffffff7fffffdbffL & l) != 0L)
+                     jjCheckNAddStates(4, 7);
+                  break;
+               case 12:
+                  if ((0x8400000000L & l) != 0L)
+                     jjCheckNAddStates(4, 7);
+                  break;
+               case 14:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 15;
+                  break;
+               case 15:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 16;
+                  break;
+               case 16:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 17;
+                  break;
+               case 17:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddStates(4, 7);
+                  break;
+               case 19:
+                  if (curChar == 39 && kind > 10)
+                     kind = 10;
+                  break;
+               case 20:
+                  if (curChar == 34)
+                     jjCheckNAddStates(0, 3);
+                  break;
+               case 21:
+                  if ((0xfffffffbffffdbffL & l) != 0L)
+                     jjCheckNAddStates(0, 3);
+                  break;
+               case 23:
+                  if ((0x8400000000L & l) != 0L)
+                     jjCheckNAddStates(0, 3);
+                  break;
+               case 25:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 26;
+                  break;
+               case 26:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 27;
+                  break;
+               case 27:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 28;
+                  break;
+               case 28:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddStates(0, 3);
+                  break;
+               case 30:
+                  if (curChar == 34 && kind > 11)
+                     kind = 11;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 31:
+                  if ((0xffffffffefffffffL & l) != 0L)
+                     jjCheckNAddStates(0, 3);
+                  else if (curChar == 92)
+                     jjstateSet[jjnewStateCnt++] = 24;
+                  if (curChar == 92)
+                     jjstateSet[jjnewStateCnt++] = 23;
+                  break;
+               case 0:
+                  if ((0x2000000020L & l) != 0L)
+                  {
+                     if (kind > 5)
+                        kind = 5;
+                     jjstateSet[jjnewStateCnt++] = 1;
+                  }
+                  else if (curChar == 92)
+                     jjstateSet[jjnewStateCnt++] = 3;
+                  break;
+               case 3:
+                  if (curChar == 117)
+                     jjstateSet[jjnewStateCnt++] = 4;
+                  break;
+               case 4:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 5;
+                  break;
+               case 5:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 6;
+                  break;
+               case 6:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 7;
+                  break;
+               case 7:
+                  if ((0x7e0000007eL & l) != 0L && kind > 8)
+                     kind = 8;
+                  break;
+               case 8:
+                  if (curChar == 92)
+                     jjstateSet[jjnewStateCnt++] = 3;
+                  break;
+               case 10:
+                  if ((0xffffffffefffffffL & l) != 0L)
+                     jjCheckNAddStates(4, 7);
+                  break;
+               case 11:
+                  if (curChar == 92)
+                     jjstateSet[jjnewStateCnt++] = 12;
+                  break;
+               case 12:
+                  if ((0x14404410000000L & l) != 0L)
+                     jjCheckNAddStates(4, 7);
+                  break;
+               case 13:
+                  if (curChar == 117)
+                     jjstateSet[jjnewStateCnt++] = 14;
+                  break;
+               case 14:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 15;
+                  break;
+               case 15:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 16;
+                  break;
+               case 16:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 17;
+                  break;
+               case 17:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjCheckNAddStates(4, 7);
+                  break;
+               case 18:
+                  if (curChar == 92)
+                     jjstateSet[jjnewStateCnt++] = 13;
+                  break;
+               case 21:
+                  if ((0xffffffffefffffffL & l) != 0L)
+                     jjCheckNAddStates(0, 3);
+                  break;
+               case 22:
+                  if (curChar == 92)
+                     jjstateSet[jjnewStateCnt++] = 23;
+                  break;
+               case 23:
+                  if ((0x14404410000000L & l) != 0L)
+                     jjCheckNAddStates(0, 3);
+                  break;
+               case 24:
+                  if (curChar == 117)
+                     jjstateSet[jjnewStateCnt++] = 25;
+                  break;
+               case 25:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 26;
+                  break;
+               case 26:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 27;
+                  break;
+               case 27:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 28;
+                  break;
+               case 28:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjCheckNAddStates(0, 3);
+                  break;
+               case 29:
+                  if (curChar == 92)
+                     jjstateSet[jjnewStateCnt++] = 24;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int hiByte = (int)(curChar >> 8);
+         int i1 = hiByte >> 6;
+         long l1 = 1L << (hiByte & 077);
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 31:
+               case 21:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     jjCheckNAddStates(0, 3);
+                  break;
+               case 10:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     jjAddStates(4, 7);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 31 - (jjnewStateCnt = startsAt)))
+         return curPos;
+      try { curChar = input_stream.readChar(); }
+      catch(java.io.IOException e) { return curPos; }
+   }
+}
+private final int jjStopStringLiteralDfa_2(int pos, long active0)
+{
+   switch (pos)
+   {
+      default :
+         return -1;
+   }
+}
+private final int jjStartNfa_2(int pos, long active0)
+{
+   return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1);
+}
+private final int jjStartNfaWithStates_2(int pos, int kind, int state)
+{
+   jjmatchedKind = kind;
+   jjmatchedPos = pos;
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) { return pos + 1; }
+   return jjMoveNfa_2(state, pos + 1);
+}
+private final int jjMoveStringLiteralDfa0_2()
+{
+   switch(curChar)
+   {
+      case 117:
+         return jjStopAtPos(0, 17);
+      default :
+         return jjMoveNfa_2(0, 0);
+   }
+}
+private final int jjMoveNfa_2(int startState, int curPos)
+{
+   int[] nextStates;
+   int startsAt = 0;
+   jjnewStateCnt = 1;
+   int i = 1;
+   jjstateSet[0] = startState;
+   int j, kind = 0x7fffffff;
+   for (;;)
+   {
+      if (++jjround == 0x7fffffff)
+         ReInitRounds();
+      if (curChar < 64)
+      {
+         long l = 1L << curChar;
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if ((0x800400000000L & l) != 0L)
+                     kind = 16;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if ((0x14404410000000L & l) != 0L)
+                     kind = 16;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int hiByte = (int)(curChar >> 8);
+         int i1 = hiByte >> 6;
+         long l1 = 1L << (hiByte & 077);
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 1 - (jjnewStateCnt = startsAt)))
+         return curPos;
+      try { curChar = input_stream.readChar(); }
+      catch(java.io.IOException e) { return curPos; }
+   }
+}
+private final int jjStopStringLiteralDfa_1(int pos, long active0)
+{
+   switch (pos)
+   {
+      default :
+         return -1;
+   }
+}
+private final int jjStartNfa_1(int pos, long active0)
+{
+   return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1);
+}
+private final int jjStartNfaWithStates_1(int pos, int kind, int state)
+{
+   jjmatchedKind = kind;
+   jjmatchedPos = pos;
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) { return pos + 1; }
+   return jjMoveNfa_1(state, pos + 1);
+}
+private final int jjMoveStringLiteralDfa0_1()
+{
+   switch(curChar)
+   {
+      case 92:
+         return jjStopAtPos(0, 13);
+      default :
+         return jjMoveNfa_1(0, 0);
+   }
+}
+private final int jjMoveNfa_1(int startState, int curPos)
+{
+   int[] nextStates;
+   int startsAt = 0;
+   jjnewStateCnt = 2;
+   int i = 1;
+   jjstateSet[0] = startState;
+   int j, kind = 0x7fffffff;
+   for (;;)
+   {
+      if (++jjround == 0x7fffffff)
+         ReInitRounds();
+      if (curChar < 64)
+      {
+         long l = 1L << curChar;
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if ((0xfffffffbffffffffL & l) != 0L)
+                  {
+                     if (kind > 15)
+                        kind = 15;
+                  }
+                  else if (curChar == 34)
+                  {
+                     if (kind > 14)
+                        kind = 14;
+                  }
+                  break;
+               case 1:
+                  if ((0xfffffffbffffffffL & l) != 0L)
+                     kind = 15;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if ((0xffffffffefffffffL & l) != 0L)
+                     kind = 15;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int hiByte = (int)(curChar >> 8);
+         int i1 = hiByte >> 6;
+         long l1 = 1L << (hiByte & 077);
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         MatchLoop: do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 15)
+                     kind = 15;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 2 - (jjnewStateCnt = startsAt)))
+         return curPos;
+      try { curChar = input_stream.readChar(); }
+      catch(java.io.IOException e) { return curPos; }
+   }
+}
+static final int[] jjnextStates = {
+   21, 22, 29, 30, 10, 11, 18, 19, 
+};
+private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2)
+{
+   switch(hiByte)
+   {
+      case 0:
+         return ((jjbitVec2[i2] & l2) != 0L);
+      default : 
+         if ((jjbitVec0[i1] & l1) != 0L)
+            return true;
+         return false;
+   }
+}
+public static final String[] jjstrLiteralImages = {
+"", null, null, null, null, null, null, null, null, null, null, null, "\42", 
+null, null, null, null, null, null, null, "\173", "\175", "\156\165\154\154", "\54", 
+"\72", "\133", "\135", "\164\162\165\145", "\146\141\154\163\145", "\55", "\56", };
+public static final String[] lexStateNames = {
+   "DEFAULT", 
+   "STRING_STATE", 
+   "ESC_STATE", 
+   "HEX_STATE", 
+};
+public static final int[] jjnewLexState = {
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 0, -1, 1, 3, -1, 1, -1, -1, -1, -1, -1, 
+   -1, -1, -1, -1, -1, -1, 
+};
+static final long[] jjtoToken = {
+   0x7ff9dd61L, 
+};
+static final long[] jjtoSkip = {
+   0x1eL, 
+};
+static final long[] jjtoMore = {
+   0x22000L, 
+};
+protected SimpleCharStream input_stream;
+private final int[] jjrounds = new int[31];
+private final int[] jjstateSet = new int[62];
+protected char curChar;
+public JsonParserTokenManager(SimpleCharStream stream){
+   if (SimpleCharStream.staticFlag)
+      throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
+   input_stream = stream;
+}
+public JsonParserTokenManager(SimpleCharStream stream, int lexState){
+   this(stream);
+   SwitchTo(lexState);
+}
+public void ReInit(SimpleCharStream stream)
+{
+   jjmatchedPos = jjnewStateCnt = 0;
+   curLexState = defaultLexState;
+   input_stream = stream;
+   ReInitRounds();
+}
+private final void ReInitRounds()
+{
+   int i;
+   jjround = 0x80000001;
+   for (i = 31; i-- > 0;)
+      jjrounds[i] = 0x80000000;
+}
+public void ReInit(SimpleCharStream stream, int lexState)
+{
+   ReInit(stream);
+   SwitchTo(lexState);
+}
+public void SwitchTo(int lexState)
+{
+   if (lexState >= 4 || lexState < 0)
+      throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
+   else
+      curLexState = lexState;
+}
+
+protected Token jjFillToken()
+{
+   Token t = Token.newToken(jjmatchedKind);
+   t.kind = jjmatchedKind;
+   String im = jjstrLiteralImages[jjmatchedKind];
+   t.image = (im == null) ? input_stream.GetImage() : im;
+   t.beginLine = input_stream.getBeginLine();
+   t.beginColumn = input_stream.getBeginColumn();
+   t.endLine = input_stream.getEndLine();
+   t.endColumn = input_stream.getEndColumn();
+   return t;
+}
+
+int curLexState = 0;
+int defaultLexState = 0;
+int jjnewStateCnt;
+int jjround;
+int jjmatchedPos;
+int jjmatchedKind;
+
+public Token getNextToken() 
+{
+  int kind;
+  Token specialToken = null;
+  Token matchedToken;
+  int curPos = 0;
+
+  EOFLoop :
+  for (;;)
+  {   
+   try   
+   {     
+      curChar = input_stream.BeginToken();
+   }     
+   catch(java.io.IOException e)
+   {        
+      jjmatchedKind = 0;
+      matchedToken = jjFillToken();
+      return matchedToken;
+   }
+
+   for (;;)
+   {
+     switch(curLexState)
+     {
+       case 0:
+         try { input_stream.backup(0);
+            while (curChar <= 32 && (0x100002600L & (1L << curChar)) != 0L)
+               curChar = input_stream.BeginToken();
+         }
+         catch (java.io.IOException e1) { continue EOFLoop; }
+         jjmatchedKind = 0x7fffffff;
+         jjmatchedPos = 0;
+         curPos = jjMoveStringLiteralDfa0_0();
+         break;
+       case 1:
+         jjmatchedKind = 0x7fffffff;
+         jjmatchedPos = 0;
+         curPos = jjMoveStringLiteralDfa0_1();
+         break;
+       case 2:
+         jjmatchedKind = 0x7fffffff;
+         jjmatchedPos = 0;
+         curPos = jjMoveStringLiteralDfa0_2();
+         break;
+       case 3:
+         jjmatchedKind = 0x7fffffff;
+         jjmatchedPos = 0;
+         curPos = jjMoveStringLiteralDfa0_3();
+         break;
+     }
+     if (jjmatchedKind != 0x7fffffff)
+     {
+        if (jjmatchedPos + 1 < curPos)
+           input_stream.backup(curPos - jjmatchedPos - 1);
+        if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+        {
+           matchedToken = jjFillToken();
+       if (jjnewLexState[jjmatchedKind] != -1)
+         curLexState = jjnewLexState[jjmatchedKind];
+           return matchedToken;
+        }
+        else if ((jjtoSkip[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+        {
+         if (jjnewLexState[jjmatchedKind] != -1)
+           curLexState = jjnewLexState[jjmatchedKind];
+           continue EOFLoop;
+        }
+      if (jjnewLexState[jjmatchedKind] != -1)
+        curLexState = jjnewLexState[jjmatchedKind];
+        curPos = 0;
+        jjmatchedKind = 0x7fffffff;
+        try {
+           curChar = input_stream.readChar();
+           continue;
+        }
+        catch (java.io.IOException e1) { }
+     }
+     int error_line = input_stream.getEndLine();
+     int error_column = input_stream.getEndColumn();
+     String error_after = null;
+     boolean EOFSeen = false;
+     try { input_stream.readChar(); input_stream.backup(1); }
+     catch (java.io.IOException e1) {
+        EOFSeen = true;
+        error_after = curPos <= 1 ? "" : input_stream.GetImage();
+        if (curChar == '\n' || curChar == '\r') {
+           error_line++;
+           error_column = 0;
+        }
+        else
+           error_column++;
+     }
+     if (!EOFSeen) {
+        input_stream.backup(1);
+        error_after = curPos <= 1 ? "" : input_stream.GetImage();
+     }
+     throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
+   }
+  }
+}
+
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonPrimitive.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonPrimitive.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonPrimitive.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * A class representing a Json primitive value. A primitive value
+ * is either a String, a Java primitive, or a Java primitive
+ * wrapper type.
+ *
+ * @author Inderjeet Singh
+ */
+public final class JsonPrimitive extends JsonElement {
+
+  private Object value;
+
+  /**
+   * Create a primitive containing a boolean value.
+   *
+   * @param bool the value to create the primitive with.
+   */
+  public JsonPrimitive(Boolean bool) {
+    this.value = bool;
+  }
+
+  /**
+   * Create a primitive containing a {@link Number}.
+   *
+   * @param number the value to create the primitive with.
+   */
+  public JsonPrimitive(Number number) {
+    this.value = number;
+  }
+
+  /**
+   * Create a primitive containing a String value.
+   *
+   * @param string the value to create the primitive with.
+   */
+  public JsonPrimitive(String string) {
+    this.value = string;
+  }
+
+  /**
+   * Create a primitive containing a character. The character is turned into a one character String
+   * since Json only supports String.
+   *
+   * @param c the value to create the primitive with.
+   */
+  public JsonPrimitive(Character c) {
+    this.value = String.valueOf(c);
+  }
+
+  /**
+   * Create a primitive containing a character. The character is turned into a one character String
+   * since Json only supports String.
+   *
+   * @param c the value to create the primitive with.
+   */
+  public JsonPrimitive(char c) {
+    this.value = String.valueOf(c);
+  }
+
+  /**
+   * Create a primitive using the specified Object. It must be an instance of {@link Number}, a
+   * Java primitive type, or a String.
+   *
+   * @param primitive the value to create the primitive with.
+   */
+  JsonPrimitive(Object primitive) {
+    setValue(primitive);
+  }
+
+  void setValue(Object primitive) {
+    if (primitive instanceof Character) {
+      // convert characters to strings since in JSON, characters are represented as a single
+      // character string
+      char c = ((Character)primitive).charValue();
+      this.value = String.valueOf(c);
+    } else {
+      Preconditions.checkArgument(primitive instanceof Number
+          || ObjectNavigator.isPrimitiveOrString(primitive));
+      this.value = primitive;
+    }
+  }
+
+  /**
+   * Check whether this primitive contains a boolean value.
+   *
+   * @return true if this primitive contains a boolean value, false otherwise.
+   */
+  public boolean isBoolean() {
+    return value instanceof Boolean;
+  }
+
+  /**
+   * convenience method to get this element as a {@link Boolean}.
+   *
+   * @return get this element as a {@link Boolean}.
+   * @throws ClassCastException if the value contained is not a valid boolean value.
+   */
+  @Override
+  Boolean getAsBooleanWrapper() {
+    return (Boolean) value;
+  }
+
+  /**
+   * convenience method to get this element as a boolean value.
+   *
+   * @return get this element as a primitive boolean value.
+   * @throws ClassCastException if the value contained is not a valid boolean value.
+   */
+  @Override
+  public boolean getAsBoolean() {
+    return ((Boolean) value).booleanValue();
+  }
+
+  /**
+   * Check whether this primitive contains a Number.
+   *
+   * @return true if this primitive contains a Number, false otherwise.
+   */
+  public boolean isNumber() {
+    return value instanceof Number;
+  }
+
+  /**
+   * convenience method to get this element as a Number.
+   *
+   * @return get this element as a Number.
+   * @throws ClassCastException if the value contained is not a valid Number.
+   */
+  @Override
+  public Number getAsNumber() {
+    return (Number) value;
+  }
+
+  /**
+   * Check whether this primitive contains a String value.
+   *
+   * @return true if this primitive contains a String value, false otherwise.
+   */
+  public boolean isString() {
+    return value instanceof String;
+  }
+
+  /**
+   * convenience method to get this element as a String.
+   *
+   * @return get this element as a String.
+   * @throws ClassCastException if the value contained is not a valid String.
+   */
+  @Override
+  public String getAsString() {
+    return (String) value;
+  }
+
+  /**
+   * convenience method to get this element as a primitive double.
+   *
+   * @return get this element as a primitive double.
+   * @throws ClassCastException if the value contained is not a valid double.
+   */
+  @Override
+  public double getAsDouble() {
+    return ((Number) value).doubleValue();
+  }
+
+  /**
+   * convenience method to get this element as a {@link BigDecimal}.
+   *
+   * @return get this element as a {@link BigDecimal}.
+   * @throws NumberFormatException if the value contained is not a valid {@link BigDecimal}.
+   */
+  @Override
+  public BigDecimal getAsBigDecimal() {
+    if (value instanceof BigDecimal) {
+      return (BigDecimal) value;
+    } else {
+      return new BigDecimal(value.toString());
+    }
+  }
+
+  /**
+   * convenience method to get this element as a {@link BigInteger}.
+   *
+   * @return get this element as a {@link BigInteger}.
+   * @throws NumberFormatException if the value contained is not a valid {@link BigInteger}.
+   */
+  @Override
+  public BigInteger getAsBigInteger() {
+    if (value instanceof BigInteger) {
+      return (BigInteger) value;
+    } else {
+      return new BigInteger(value.toString());
+    }
+  }
+
+  /**
+   * convenience method to get this element as a float.
+   *
+   * @return get this element as a float.
+   * @throws ClassCastException if the value contained is not a valid float.
+   */
+  @Override
+  public float getAsFloat() {
+    return ((Number) value).floatValue();
+  }
+
+  /**
+   * convenience method to get this element as a primitive long.
+   *
+   * @return get this element as a primitive long.
+   * @throws ClassCastException if the value contained is not a valid long.
+   */
+  @Override
+  public long getAsLong() {
+    return ((Number) value).longValue();
+  }
+
+  /**
+   * convenience method to get this element as a primitive short.
+   *
+   * @return get this element as a primitive short.
+   * @throws ClassCastException if the value contained is not a valid short value.
+   */
+ @Override
+  public short getAsShort() {
+    return ((Number) value).shortValue();
+  }
+
+ /**
+  * convenience method to get this element as a primitive integer.
+  *
+  * @return get this element as a primitive integer.
+  * @throws ClassCastException if the value contained is not a valid integer.
+  */
+  @Override
+  public int getAsInt() {
+    return ((Number) value).intValue();
+  }
+
+  /**
+   * convenience method to get this element as an Object.
+   *
+   * @return get this element as an Object that can be converted to a suitable value.
+   */
+  @Override
+  Object getAsObject() {
+    return value;
+  }
+
+  @Override
+  protected void toString(StringBuilder sb) {
+    if (value != null) {
+      if (value instanceof String) {
+        sb.append('"');
+        sb.append(value);
+        sb.append('"');
+
+      } else {
+        sb.append(value);
+      }
+    }
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonPrimitiveDeserializationVisitor.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonPrimitiveDeserializationVisitor.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonPrimitiveDeserializationVisitor.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+import java.util.Collection;
+
+/**
+ * A visitor that populates a primitive value from its JSON representation
+ *
+ * @author Inderjeet Singh
+ */
+final class JsonPrimitiveDeserializationVisitor<T> extends JsonDeserializationVisitor<T> {
+
+  JsonPrimitiveDeserializationVisitor(JsonPrimitive json, Type type,
+      ObjectNavigatorFactory factory, ObjectConstructor objectConstructor,
+      TypeAdapter typeAdapter, ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
+      JsonDeserializationContext context) {
+    super(json, type, factory, objectConstructor, typeAdapter, deserializers, context);
+  }
+
+  @Override
+  @SuppressWarnings("unchecked")
+  protected T constructTarget() {
+    return (T) objectConstructor.construct(targetType);
+  }
+
+  public void startVisitingObject(Object node) {
+    // do nothing
+  }
+
+  public void endVisitingObject(Object node) {
+    // do nothing
+  }
+
+  public void visitCollection(@SuppressWarnings("unchecked")Collection collection,
+      Type componentType) {
+    // should not be called since this case should invoke JsonArrayDeserializationVisitor
+    throw new IllegalStateException();
+  }
+
+  public void visitArray(Object array, Type componentType) {
+    // should not be called since this case should invoke JsonArrayDeserializationVisitor
+    throw new IllegalStateException();
+  }
+
+  @SuppressWarnings("unchecked")
+  public void visitPrimitiveValue(Object obj) {
+    JsonPrimitive jsonPrimitive = json.getAsJsonPrimitive();
+    if (jsonPrimitive.isBoolean()) {
+      target = (T) jsonPrimitive.getAsBooleanWrapper();
+    } else if (jsonPrimitive.isNumber()) {
+      target = (T) jsonPrimitive.getAsNumber();
+    } else if (jsonPrimitive.isString()) {
+      target = (T) jsonPrimitive.getAsString();
+    } else {
+      throw new IllegalStateException();
+    }
+  }
+
+  public void visitObjectField(Field f, Type typeOfF, Object obj) {
+    // should not be called since this case should invoke JsonArrayDeserializationVisitor
+    throw new IllegalStateException();
+  }
+
+  public void visitCollectionField(Field f, Type typeOfF, Object obj) {
+    // should not be called since this case should invoke JsonArrayDeserializationVisitor
+    throw new IllegalStateException();
+  }
+
+  public void visitArrayField(Field f, Type typeOfF, Object obj) {
+    // should not be called since this case should invoke JsonArrayDeserializationVisitor
+    throw new IllegalStateException();
+  }
+
+  public void visitPrimitiveField(Field f, Type fType, Object obj) {
+    // should not be called since this case should invoke JsonArrayDeserializationVisitor
+    throw new IllegalStateException();
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonPrintFormatter.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonPrintFormatter.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonPrintFormatter.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Formats Json in a nicely indented way with a specified print margin.
+ * This printer tries to keep elements on the same line as much as possible
+ * while respecting right margin.
+ *
+ * @author Inderjeet Singh
+ */
+final class JsonPrintFormatter implements JsonFormatter {
+
+  private final int printMargin;
+  private final int indentationSize;
+  private final int rightMargin;
+
+  public static final int DEFAULT_PRINT_MARGIN = 80;
+  public static final int DEFAULT_INDENTATION_SIZE = 2;
+  public static final int DEFAULT_RIGHT_MARGIN = 4;
+
+  public JsonPrintFormatter() {
+    this(DEFAULT_PRINT_MARGIN, DEFAULT_INDENTATION_SIZE, DEFAULT_RIGHT_MARGIN);
+  }
+
+  public JsonPrintFormatter(int printMargin, int indentationSize, int rightMargin) {
+    this.printMargin = printMargin;
+    this.indentationSize = indentationSize;
+    this.rightMargin = rightMargin;
+  }
+
+  private class JsonWriter {
+    private final PrintWriter writer;
+    private StringBuilder line;
+    private int level;
+    JsonWriter(PrintWriter writer) {
+      this.writer = writer;
+      level = 0;
+      line = new StringBuilder();
+    }
+
+    void key(String key) {
+      getLine().append('"');
+      getLine().append(key);
+      getLine().append('"');
+    }
+
+    void value(String value) {
+      getLine().append(value);
+    }
+
+    void fieldSeparator() {
+      getLine().append(':');
+      breakLineIfNeeded();
+    }
+
+    void elementSeparator() {
+      getLine().append(',');
+      breakLineIfNeeded();
+    }
+
+    void beginObject() {
+      ++level;
+      breakLineIfNeeded();
+      getLine().append('{');
+    }
+
+    void endObject() {
+      getLine().append('}');
+      --level;
+    }
+
+    void beginArray() {
+      ++level;
+      breakLineIfNeeded();
+      getLine().append('[');
+    }
+
+    void endArray() {
+      getLine().append(']');
+      --level;
+    }
+
+    private void breakLineIfNeeded() {
+      if (getLine().length() > printMargin - rightMargin) {
+        finishLine();
+      }
+    }
+
+    private void finishLine() {
+      if (line != null) {
+        writer.append(line).append("\n");
+      }
+      line = null;
+    }
+
+    private StringBuilder getLine() {
+      if (line == null) {
+        createNewLine();
+      }
+      return line;
+    }
+
+    private void createNewLine() {
+      line = new StringBuilder();
+      for (int i = 0; i < level; ++i) {
+        for (int j = 0; j < indentationSize; ++j) {
+          line.append(' ');
+        }
+      }
+    }
+  }
+
+  private class PrintFormattingVisitor implements JsonElementVisitor {
+    private final Map<Integer, Boolean> firstArrayElement;
+    private final Map<Integer, Boolean> firstObjectMember;
+    private final JsonWriter writer;
+    private final boolean serializeNulls;
+    private int level = 0;
+
+    PrintFormattingVisitor(JsonWriter writer, boolean serializeNulls) {
+      this.writer = writer;
+      this.serializeNulls = serializeNulls;
+      this.firstArrayElement = new HashMap<Integer, Boolean>();
+      this.firstObjectMember = new HashMap<Integer, Boolean>();
+    }
+
+    private void addCommaCheckingFirst(Map<Integer, Boolean> first) {
+      if (first.get(level) != Boolean.FALSE) {
+        first.put(level, false);
+      } else {
+        writer.elementSeparator();
+      }
+    }
+
+    public void startArray(JsonArray array) {
+      firstArrayElement.put(++level, true);
+      writer.beginArray();
+    }
+
+    public void visitArrayMember(JsonArray parent, JsonPrimitive member, boolean isFirst) {
+      addCommaCheckingFirst(firstArrayElement);
+      writer.value(member.toString());
+    }
+
+    public void visitArrayMember(JsonArray parent, JsonArray member, boolean first) {
+      addCommaCheckingFirst(firstArrayElement);
+    }
+
+    public void visitArrayMember(JsonArray parent, JsonObject member, boolean first) {
+      addCommaCheckingFirst(firstArrayElement);
+    }
+
+    public void visitNullArrayMember(JsonArray parent, boolean isFirst) {
+      addCommaCheckingFirst(firstArrayElement);
+    }
+
+    public void endArray(JsonArray array) {
+      level--;
+      writer.endArray();
+    }
+
+    public void startObject(JsonObject object) {
+      firstObjectMember.put(level, true);
+      writer.beginObject();
+    }
+
+    public void visitObjectMember(JsonObject parent, String memberName, JsonPrimitive member, 
+        boolean isFirst) {
+      addCommaCheckingFirst(firstObjectMember);
+      writer.key(memberName);
+      writer.fieldSeparator();
+      writer.value(member.toString());
+    }
+
+    public void visitObjectMember(JsonObject parent, String memberName, JsonArray member, 
+        boolean isFirst) {
+      addCommaCheckingFirst(firstObjectMember);
+      writer.key(memberName);
+      writer.fieldSeparator();
+    }
+
+    public void visitObjectMember(JsonObject parent, String memberName, JsonObject member, 
+        boolean isFirst) {
+      addCommaCheckingFirst(firstObjectMember);
+      writer.key(memberName);
+      writer.fieldSeparator();
+    }
+
+    public void visitNullObjectMember(JsonObject parent, String memberName, boolean isFirst) {
+      if (serializeNulls) {
+        visitObjectMember(parent, memberName, (JsonObject) null, isFirst);
+      }
+    }
+    
+    public void endObject(JsonObject object) {
+      writer.endObject();
+    }
+
+    public void visitPrimitive(JsonPrimitive primitive) {
+      writer.value(primitive.toString());
+    }
+
+    public void visitNull() {
+      writer.value("null");
+    }
+  }
+
+  public void format(JsonElement root, PrintWriter writer, boolean serializeNulls) {
+    if (root == null) {
+      return;
+    }
+    JsonWriter jsonWriter = new JsonWriter(writer);
+    JsonElementVisitor visitor = 
+      new JsonEscapingVisitor(new PrintFormattingVisitor(jsonWriter, serializeNulls));    
+    JsonTreeNavigator navigator = new JsonTreeNavigator(visitor, serializeNulls);
+    navigator.navigate(root);
+    jsonWriter.finishLine();
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializationContext.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializationContext.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializationContext.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Type;
+
+/**
+ * Context for serialization that is passed to a custom serializer during invocation of its
+ * {@link JsonSerializer#serialize(Object, Type, JsonSerializationContext)} method.
+ *
+ * @author Inderjeet Singh
+ */
+public interface JsonSerializationContext {
+
+  /**
+   * Invokes default serialization on the specified object.
+   *
+   * @param src the object that needs to be serialized.
+   * @return a tree of {@link JsonElement}s corresponding to the serialized form of {@code src}.
+   */
+  public JsonElement serialize(Object src);
+
+  /**
+   * Invokes default serialization on the specified object passing the specific type information.
+   * It should never be invoked on the element received as a parameter of the
+   * {@link JsonSerializer#serialize(Object, Type, JsonSerializationContext)} method. Doing
+   * so will result in an infinite loop since Gson will in-turn call the custom serializer again.
+   *
+   * @param src the object that needs to be serialized.
+   * @param typeOfSrc the actual genericized type of src object.
+   * @return a tree of {@link JsonElement}s corresponding to the serialized form of {@code src}.
+   */
+  public JsonElement serialize(Object src, Type typeOfSrc);
+}
\ No newline at end of file

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializationContextDefault.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializationContextDefault.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializationContextDefault.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Type;
+
+/**
+ * An implementation of serialization context for Gson.
+ *
+ * @author Inderjeet Singh
+ */
+final class JsonSerializationContextDefault implements JsonSerializationContext {
+
+  private final ObjectNavigatorFactory factory;
+  private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers;
+  private final boolean serializeNulls;
+
+  JsonSerializationContextDefault(ObjectNavigatorFactory factory, boolean serializeNulls,
+      ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers) {
+    this.factory = factory;
+    this.serializeNulls = serializeNulls;
+    this.serializers = serializers;
+  }
+
+  public JsonElement serialize(Object src) {
+    return serialize(src, src.getClass());
+  }
+
+  public JsonElement serialize(Object src, Type typeOfSrc) {
+    ObjectNavigator on = factory.create(src, typeOfSrc);
+    JsonSerializationVisitor visitor =
+      new JsonSerializationVisitor(factory, serializeNulls, serializers, this);
+    on.accept(visitor);
+    return visitor.getJsonElement();
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializationVisitor.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializationVisitor.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializationVisitor.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * A visitor that adds JSON elements corresponding to each field of an object
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
+
+  private final ObjectNavigatorFactory factory;
+  private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers;
+  private final boolean serializeNulls;
+
+  private final JsonSerializationContext context;
+
+  private JsonElement root;
+
+  JsonSerializationVisitor(ObjectNavigatorFactory factory, boolean serializeNulls,
+      ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
+      JsonSerializationContext context) {
+    this.factory = factory;
+    this.serializeNulls = serializeNulls;
+    this.serializers = serializers;
+    this.context = context;
+  }
+
+  public void endVisitingObject(Object node) {
+    // nothing to be done here
+  }
+
+  public void startVisitingObject(Object node) {
+    assignToRoot(new JsonObject());
+  }
+
+  public void visitArray(Object array, Type arrayType) {
+    assignToRoot(new JsonArray());
+    int length = Array.getLength(array);
+    TypeInfoArray fieldTypeInfo = TypeInfoFactory.getTypeInfoForArray(arrayType);
+    Type componentType = fieldTypeInfo.getSecondLevelType();
+    for (int i = 0; i < length; ++i) {
+      Object child = Array.get(array, i);
+      addAsArrayElement(componentType, child);
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void visitCollection(Collection collection, Type collectionType) {
+    assignToRoot(new JsonArray());
+    for (Object child : collection) {
+      Type childType = TypeUtils.getActualTypeForFirstTypeVariable(collectionType);
+      if (childType == Object.class && child != null) {
+        // Try our luck some other way
+        childType = child.getClass();
+      }
+      addAsArrayElement(childType, child);
+    }
+  }
+
+  public void visitArrayField(Field f, Type typeOfF, Object obj) {
+    if (isFieldNull(f, obj)) {
+      if (serializeNulls) {
+        addChildAsElement(f, new JsonNull());
+      }
+    } else {
+      Object array = getFieldValue(f, obj);
+      addAsChildOfObject(f, typeOfF, array);
+    }
+  }
+
+  public void visitCollectionField(Field f, Type typeOfF, Object obj) {
+    if (isFieldNull(f, obj)) {
+      if (serializeNulls) {
+        addChildAsElement(f, new JsonNull());
+      }
+    } else {
+      if (typeOfF == null) {
+        throw new RuntimeException("Can not handle non-generic collections");
+      }
+      Object collection = getFieldValue(f, obj);
+      addAsChildOfObject(f, typeOfF, collection);
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void visitEnum(Object obj, Type objType) {
+    JsonSerializer serializer = serializers.getHandlerFor(objType);
+    if (serializer == null) {
+      serializer = serializers.getHandlerFor(Enum.class);
+    }
+    if (serializer == null) {
+      throw new RuntimeException("Register a JsonSerializer for Enum or "
+          + obj.getClass().getName());
+    }
+    assignToRoot(serializer.serialize(obj, objType, context));
+  }
+
+  public void visitObjectField(Field f, Type typeOfF, Object obj) {
+    if (isFieldNull(f, obj)) {
+      if (serializeNulls) {
+        addChildAsElement(f, new JsonNull());
+      }
+    } else {
+      Object fieldValue = getFieldValue(f, obj);
+      // This takes care of situations where the field was declared as an Object, but the
+      // actual value contains something more specific. See Issue 54.
+      if (fieldValue != null && typeOfF == Object.class) {
+        typeOfF = fieldValue.getClass();
+      }
+      addAsChildOfObject(f, typeOfF, fieldValue);
+    }
+  }
+
+  private void addAsChildOfObject(Field f, Type fieldType, Object fieldValue) {
+    JsonElement childElement = getJsonElementForChild(fieldType, fieldValue);
+    addChildAsElement(f, childElement);
+  }
+
+  private void addChildAsElement(Field f, JsonElement childElement) {
+    FieldNamingStrategy namingPolicy = factory.getFieldNamingPolicy();
+    root.getAsJsonObject().add(namingPolicy.translateName(f), childElement);
+  }
+
+  private void addAsArrayElement(Type elementType, Object elementValue) {
+    if (elementValue == null) {
+      addNullAsArrayElement();
+    } else {
+      JsonElement childElement = getJsonElementForChild(elementType, elementValue);
+      root.getAsJsonArray().add(childElement);
+    }
+  }
+
+  private void addNullAsArrayElement() {
+    root.getAsJsonArray().add(null);
+  }
+
+  private JsonElement getJsonElementForChild(Type fieldType, Object fieldValue) {
+    ObjectNavigator on = factory.create(fieldValue, fieldType);
+    JsonSerializationVisitor childVisitor =
+        new JsonSerializationVisitor(factory, serializeNulls, serializers, context);
+    on.accept(childVisitor);
+    return childVisitor.getJsonElement();
+  }
+
+  public void visitPrimitiveField(Field f, Type typeOfF, Object obj) {    
+    if (isFieldNull(f, obj)) {
+      if (serializeNulls) {
+        addChildAsElement(f, new JsonNull());
+      }      
+    } else {
+      TypeInfo typeInfo = new TypeInfo(typeOfF);
+      if (typeInfo.isPrimitiveOrStringAndNotAnArray()) {
+        Object fieldValue = getFieldValue(f, obj);
+        addAsChildOfObject(f, typeOfF, fieldValue);
+      } else {
+        throw new IllegalArgumentException("Not a primitive type");
+      }
+    }
+  }
+
+  public void visitPrimitiveValue(Object obj) {
+    assignToRoot(new JsonPrimitive(obj));
+  }
+
+  @SuppressWarnings("unchecked")
+  public boolean visitUsingCustomHandler(Object obj, Type objType) {
+    JsonSerializer serializer = serializers.getHandlerFor(objType);
+    if (serializer == null && obj instanceof Map) {
+      serializer = serializers.getHandlerFor(Map.class);
+    }
+    if (serializer != null) {
+      assignToRoot(serializer.serialize(obj, objType, context));
+      return true;
+    }
+    return false;
+  }
+
+  private void assignToRoot(JsonElement newRoot) {
+    Preconditions.checkArgument(root == null);
+    root = newRoot;
+  }
+
+  private boolean isFieldNull(Field f, Object obj) {
+    return getFieldValue(f, obj) == null;
+  }
+
+  private Object getFieldValue(Field f, Object obj) {
+    try {
+      return f.get(obj);
+    } catch (IllegalAccessException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public JsonElement getJsonElement() {
+    return root;
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializer.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializer.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializer.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Type;
+
+/**
+ * Interface representing a custom serializer for Json. You should write a custom serializer, if
+ * you are not happy with the default serialization done by Gson. You will also need to register
+ * this serializer through {@link com.google.gson.GsonBuilder#registerTypeAdapter(Type, Object)}.
+ *
+ * <p>Let us look at example where defining a serializer will be useful. The {@code Id} class
+ * defined below has two fields: {@code clazz} and {@code value}.</p>
+ *
+ * <p><pre>
+ * public class Id&lt;T&gt; {
+ *   private final Class&lt;T&gt; clazz;
+ *   private final long value;
+ *
+ *   public Id(Class&lt;T&gt; clazz, long value) {
+ *     this.clazz = clazz;
+ *     this.value = value;
+ *   }
+ *
+ *   public long getValue() {
+ *     return value;
+ *   }
+ * }
+ * </pre></p>
+ *
+ * <p>The default serialization of {@code Id(com.foo.MyObject.class, 20L)} will be
+ * <code>{"clazz":com.foo.MyObject,"value":20}</code>. Suppose, you just want the output to be
+ * the value instead, which is {@code 20} in this case. You can achieve that by writing a custom
+ * serializer:</p>
+ *
+ * <p><pre>
+ * class IdSerializer implements JsonSerializer&lt;Id&gt;() {
+ *   public JsonElement toJson(Id id, Type typeOfId, JsonSerializationContext context) {
+ *     return new JsonPrimitive(id.getValue());
+ *   }
+ * }
+ * </pre></p>
+ *
+ * <p>You will also need to register {@code IdSerializer} with Gson as follows:</p>
+ * <pre>
+ * Gson gson = new GsonBuilder().registerTypeAdapter(Id.class, new IdSerializer()).create();
+ * </pre>
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ *
+ * @param <T> type for which the serializer is being registered. It is possible that a serializer
+ *        may be asked to serialize a specific generic type of the T.
+ */
+public interface JsonSerializer<T> {
+
+  /**
+   * Gson invokes this call-back method during serialization when it encounters a field of the
+   * specified type.
+   *
+   * <p>In the implementation of this call-back method, you should consider invoking
+   * {@link JsonSerializationContext#serialize(Object, Type)} method to create JsonElements for any
+   * non-trivial field of the {@code src} object. However, you should never invoke it on the
+   * {@code src} object itself since that will cause an infinite loop (Gson will call your
+   * call-back method again).</p>
+   *
+   * @param src the object that needs to be converted to Json.
+   * @param typeOfSrc the actual type (fully genericized version) of the source object.
+   * @return a JsonElement corresponding to the specified object.
+   */
+  public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context);
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializerExceptionWrapper.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializerExceptionWrapper.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonSerializerExceptionWrapper.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Type;
+
+/**
+ * Decorators a {@code JsonSerializer} instance with exception handling.  This wrapper class
+ * ensures that a {@code JsonSerializer} will not propagate any exception other than a
+ * {@link JsonParseException}.
+ *
+ * @param <T> type of the serializer being wrapped.
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+class JsonSerializerExceptionWrapper<T> implements JsonSerializer<T> {
+  private final JsonSerializer<T> delegate;
+
+  /**
+   * Returns a wrapped {@link JsonSerializer} object that has been decorated with
+   * {@link JsonParseException} handling.
+   *
+   * @param delegate the {@code JsonSerializer} instance to be wrapped
+   * @throws IllegalArgumentException if {@code delegate} is {@code null}.
+   */
+  JsonSerializerExceptionWrapper(JsonSerializer<T> delegate) {
+    Preconditions.checkNotNull(delegate);
+    this.delegate = delegate;
+  }
+
+  public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) {
+    try {
+      return delegate.serialize(src, typeOfSrc, context);
+    } catch (JsonParseException e) {
+      // just rethrow the exception
+      throw e;
+    } catch (Exception e) {
+      // throw as a JsonParseException
+      StringBuilder errorMsg = new StringBuilder()
+          .append("The JsonSerializer ")
+          .append(delegate)
+          .append(" failed to serialized object ")
+          .append(src)
+          .append(" given the type ")
+          .append(typeOfSrc);
+      throw new JsonParseException(errorMsg.toString(), e);
+    }
+  }
+  
+  @Override
+  public String toString() {
+    return delegate.toString();
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonTreeNavigator.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonTreeNavigator.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/JsonTreeNavigator.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.util.Map;
+
+/**
+ * A navigator to navigate a tree of JsonElement nodes in Depth-first order
+ * 
+ * @author Inderjeet Singh
+ */
+final class JsonTreeNavigator {
+  private final JsonElementVisitor visitor;
+  private final boolean visitNulls;
+
+  JsonTreeNavigator(JsonElementVisitor visitor, boolean visitNulls) {
+    this.visitor = visitor;
+    this.visitNulls = visitNulls;
+  }
+  
+  public void navigate(JsonElement element) {
+    if (element == null || element.isJsonNull()) {
+      visitor.visitNull();
+    } else if (element.isJsonArray()) {
+      JsonArray array = element.getAsJsonArray();
+      visitor.startArray(array);
+      boolean isFirst = true;
+      for (JsonElement child : array) {
+        visitChild(array, child, isFirst);
+        if (isFirst) {
+          isFirst = false;
+        }
+      }
+      visitor.endArray(array);
+    } else if (element.isJsonObject()){
+      JsonObject object = element.getAsJsonObject();
+      visitor.startObject(object);
+      boolean isFirst = true;
+      for (Map.Entry<String, JsonElement> member : object.entrySet()) {
+        visitChild(object, member.getKey(), member.getValue(), isFirst);
+        if (isFirst) {
+          isFirst = false;
+        }
+      }
+      visitor.endObject(object);
+    } else { // must be JsonPrimitive
+      visitor.visitPrimitive(element.getAsJsonPrimitive());
+    }    
+  }
+
+  private void visitChild(JsonObject parent, String childName, JsonElement child, boolean isFirst) {
+    if (child != null) { 
+      if (child.isJsonNull()) {
+        if (visitNulls) {
+          visitor.visitNullObjectMember(parent, childName, isFirst);
+          navigate(child.getAsJsonNull());
+        }
+      } else if (child.isJsonArray()) {
+        JsonArray childAsArray = child.getAsJsonArray();
+        visitor.visitObjectMember(parent, childName, childAsArray, isFirst);
+        navigate(childAsArray);
+      } else if (child.isJsonObject()) {
+        JsonObject childAsObject = child.getAsJsonObject();
+        visitor.visitObjectMember(parent, childName, childAsObject, isFirst);
+        navigate(childAsObject);
+      } else { // is a JsonPrimitive
+        visitor.visitObjectMember(parent, childName, child.getAsJsonPrimitive(), isFirst);          
+      }
+    }
+  }
+
+  private void visitChild(JsonArray parent, JsonElement child, boolean isFirst) {
+    if (child == null || child.isJsonNull()) {
+      visitor.visitNullArrayMember(parent, isFirst);
+      navigate(null);
+	} else if (child.isJsonArray()) {
+      JsonArray childAsArray = child.getAsJsonArray();
+      visitor.visitArrayMember(parent, childAsArray, isFirst);
+      navigate(childAsArray);
+    } else if (child.isJsonObject()) {
+      JsonObject childAsObject = child.getAsJsonObject();
+      visitor.visitArrayMember(parent, childAsObject, isFirst);
+      navigate(childAsObject);
+    } else { // is a JsonPrimitive
+      visitor.visitArrayMember(parent, child.getAsJsonPrimitive(), isFirst);          
+    }
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/LowerCamelCaseSeparatorNamingPolicy.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/LowerCamelCaseSeparatorNamingPolicy.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/LowerCamelCaseSeparatorNamingPolicy.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+/**
+ * A {@link FieldNamingStrategy} that ensures the JSON field names consist of only
+ * lower case letters and are separated by a particular {@code separatorString}.
+ *
+ *<p>The following is an example:</p>
+ * <pre>
+ * class StringWrapper {
+ *   public String AStringField = "abcd";
+ * }
+ *
+ * LowerCamelCaseSeparatorNamingPolicy policy = new LowerCamelCaseSeparatorNamingPolicy("_");
+ * String translatedFieldName =
+ *     policy.translateName(StringWrapper.class.getField("AStringField"));
+ *
+ * assert("a_string_field".equals(translatedFieldName));
+ * </pre>
+ *
+ * @author Joel Leitch
+ */
+class LowerCamelCaseSeparatorNamingPolicy extends CompositionFieldNamingPolicy {
+
+  public LowerCamelCaseSeparatorNamingPolicy(String separatorString) {
+    super(new CamelCaseSeparatorNamingPolicy(separatorString), new LowerCaseNamingPolicy());
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/LowerCaseNamingPolicy.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/LowerCaseNamingPolicy.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/LowerCaseNamingPolicy.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+/**
+ * A {@link FieldNamingStrategy} that ensures the JSON field names consist of only
+ * lower case letters.
+ *
+ *<p>The following is an example:</p>
+ * <pre>
+ * class IntWrapper {
+ *   public int integerField = 0;
+ * }
+ *
+ * LowerCaseNamingPolicy policy = new LowerCaseNamingPolicy();
+ * String translatedFieldName =
+ *     policy.translateName(IntWrapper.class.getField("integerField"));
+ *
+ * assert("integerfield".equals(translatedFieldName));
+ * </pre>
+ *
+ * @author Joel Leitch
+ */
+class LowerCaseNamingPolicy extends RecursiveFieldNamingPolicy {
+
+  @Override
+  protected String translateName(String target, Type fieldType, Annotation[] annotations) {
+    return target.toLowerCase();
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/MappedObjectConstructor.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/MappedObjectConstructor.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/MappedObjectConstructor.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Type;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class contains a mapping of all the application specific
+ * {@link InstanceCreator} instances.  Registering an {@link InstanceCreator}
+ * with this class will override the default object creation that is defined
+ * by the ObjectConstructor that this class is wrapping.  Using this class
+ * with the JSON framework provides the application with "pluggable" modules
+ * to customize framework to suit the application's needs.
+ *
+ * @author Joel Leitch
+ */
+final class MappedObjectConstructor implements ObjectConstructor {
+  private final Logger log = Logger.getLogger(getClass().getName());
+
+  private final ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreatorMap =
+    new ParameterizedTypeHandlerMap<InstanceCreator<?>>();
+
+  @SuppressWarnings("unchecked")
+  public <T> T construct(Type typeOfT) {
+    if (instanceCreatorMap.hasAnyHandlerFor(typeOfT)) {
+      InstanceCreator<T> creator = (InstanceCreator<T>) instanceCreatorMap.getHandlerFor(typeOfT);
+      return creator.createInstance(typeOfT);
+    }
+    TypeInfo typeInfo = new TypeInfo(typeOfT);
+    if (typeInfo.isEnum()) {
+      InstanceCreator<T> creator =
+        (InstanceCreator<T>) instanceCreatorMap.getHandlerFor(Enum.class);
+      return creator.createInstance(typeOfT);
+    }
+    return (T) constructWithNoArgConstructor(typeOfT);
+  }
+
+  public Object constructArray(Type type, int length) {
+    return Array.newInstance(TypeUtils.toRawClass(type), length);
+  }
+
+  private <T> T constructWithNoArgConstructor(Type typeOfT) {
+    try {
+      Constructor<T> constructor = getNoArgsConstructor(typeOfT);
+      if (constructor == null) {
+        throw new RuntimeException(("No-args constructor for " + typeOfT + " does not exist. "
+            + "Register an InstanceCreator with Gson for this type to fix this problem."));
+      }
+      return constructor.newInstance();
+    } catch (InstantiationException e) {
+      throw new RuntimeException(("Unable to invoke no-args constructor for " + typeOfT + ". "
+          + "Register an InstanceCreator with Gson for this type may fix this problem."), e);
+    } catch (IllegalAccessException e) {
+      throw new RuntimeException(("Unable to invoke no-args constructor for " + typeOfT + ". "
+          + "Register an InstanceCreator with Gson for this type may fix this problem."), e);
+    } catch (InvocationTargetException e) {
+      throw new RuntimeException(("Unable to invoke no-args constructor for " + typeOfT + ". "
+          + "Register an InstanceCreator with Gson for this type may fix this problem."), e);
+    }
+  }
+
+  @SuppressWarnings({"unchecked", "cast"})
+  private <T> Constructor<T> getNoArgsConstructor(Type typeOfT) {
+    TypeInfo typeInfo = new TypeInfo(typeOfT);
+    Class<T> clazz = (Class<T>) typeInfo.getRawClass();
+    Constructor<T>[] declaredConstructors = (Constructor<T>[]) clazz.getDeclaredConstructors();
+    AccessibleObject.setAccessible(declaredConstructors, true);
+    for (Constructor<T> constructor : declaredConstructors) {
+      if (constructor.getParameterTypes().length == 0) {
+        return constructor;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Use this methods to register an {@link InstanceCreator} for a new type.
+   *
+   * @param <T> the type of class to be mapped with its "creator"
+   * @param typeOfT the instance type that will be created
+   * @param creator the {@link InstanceCreator} instance to register
+   */
+  <T> void register(Type typeOfT, InstanceCreator<? extends T> creator) {
+    if (instanceCreatorMap.hasSpecificHandlerFor(typeOfT)) {
+      log.log(Level.WARNING, "Overriding the existing InstanceCreator for " + typeOfT);
+    }
+    instanceCreatorMap.register(typeOfT, creator);
+  }
+  
+  @Override
+  public String toString() {
+    return instanceCreatorMap.toString();
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/MemoryRefStack.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/MemoryRefStack.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/MemoryRefStack.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.util.Stack;
+
+/**
+ * A stack data structure that only does a memory reference comparison
+ * when looking for a particular item in the stack.  This stack does
+ * not allow {@code null} values to be added.
+ *
+ * @author Joel Leitch
+ */
+final class MemoryRefStack<T> {
+  private final Stack<T> stack = new Stack<T>();
+
+  /**
+   * Adds a new element to the top of the stack.
+   *
+   * @param obj the object to add to the stack
+   * @return the object that was added
+   */
+  public T push(T obj) {
+    Preconditions.checkNotNull(obj);
+
+    return stack.push(obj);
+  }
+
+  /**
+   * Removes the top element from the stack.
+   *
+   * @return the element being removed from the stack
+   * @throws java.util.EmptyStackException thrown if the stack is empty
+   */
+  public T pop() {
+    return stack.pop();
+  }
+
+  /**
+   * Retrieves the item from the top of the stack, but does not remove it.
+   *
+   * @return the item from the top of the stack
+   * @throws java.util.EmptyStackException thrown if the stack is empty
+   */
+  public T peek() {
+    return stack.peek();
+  }
+
+  /**
+   * Performs a memory reference check to see it the {@code obj} exists in
+   * the stack.
+   *
+   * @param obj the object to search for in the stack
+   * @return true if this object is already in the stack otherwise false
+   */
+  public boolean contains(T obj) {
+    if (obj == null) {
+      return false;
+    }
+
+    for (T stackObject : stack) {
+      if (obj == stackObject) {
+        return true;
+      }
+    }
+    return false;
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/ModifierBasedExclusionStrategy.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/ModifierBasedExclusionStrategy.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/ModifierBasedExclusionStrategy.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.HashSet;
+
+/**
+ * Exclude fields based on particular field modifiers.  For a list of possible
+ * modifiers, see {@link java.lang.reflect.Modifier}.
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+final class ModifierBasedExclusionStrategy implements ExclusionStrategy {
+  private final boolean skipSyntheticField;
+  private final Collection<Integer> modifiers;
+
+  public ModifierBasedExclusionStrategy(boolean skipSyntheticFields, int... modifiers) {
+    this.skipSyntheticField = skipSyntheticFields;
+    this.modifiers = new HashSet<Integer>();
+    if (modifiers != null) {
+      for (int modifier : modifiers) {
+        this.modifiers.add(modifier);
+      }
+    }
+  }
+
+  public boolean shouldSkipField(Field f) {
+    if (skipSyntheticField && f.isSynthetic()) {
+      return true;
+    }
+    int objectModifiers = f.getModifiers();
+    for (int modifier : modifiers) {
+      if ((objectModifiers & modifier) != 0) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public boolean shouldSkipClass(Class<?> clazz) {
+    return false;
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/ModifyFirstLetterNamingPolicy.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/ModifyFirstLetterNamingPolicy.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/ModifyFirstLetterNamingPolicy.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+/**
+ * A {@link FieldNamingStrategy} that ensures the JSON field names begins with
+ * an upper case letter.
+ *
+ *<p>The following is an example:</p>
+ * <pre>
+ * class StringWrapper {
+ *   public String stringField = "abcd";
+ *   public String _stringField = "efg";
+ * }
+ *
+ * ModifyFirstLetterNamingPolicy policy =
+ *     new ModifyFirstLetterNamingPolicy(LetterModifier.UPPER);
+ * String translatedFieldName =
+ *     policy.translateName(StringWrapper.class.getField("stringField"));
+ *
+ * assert("StringField".equals(translatedFieldName));
+ *
+ * String translatedFieldName =
+ *     policy.translateName(StringWrapper.class.getField("_stringField"));
+ *
+ * assert("_StringField".equals(translatedFieldName));
+ * </pre>
+ *
+ * @author Joel Leitch
+ */
+class ModifyFirstLetterNamingPolicy extends RecursiveFieldNamingPolicy {
+
+  public enum LetterModifier {
+    UPPER,
+    LOWER;
+  }
+
+  private final LetterModifier letterModifier;
+
+  /**
+   * Creates a new ModifyFirstLetterNamingPolicy that will either modify the first letter of the
+   * target name to either UPPER case or LOWER case depending on the {@code modifier} parameter.
+   *
+   * @param modifier the type of modification that should be performed
+   * @throws IllegalArgumentException if {@code modifier} is null
+   */
+  public ModifyFirstLetterNamingPolicy(LetterModifier modifier) {
+    Preconditions.checkNotNull(modifier);
+    this.letterModifier = modifier;
+  }
+
+  @Override
+  protected String translateName(String target, Type fieldType, Annotation[] annotations) {
+    StringBuilder fieldNameBuilder = new StringBuilder();
+    int index = 0;
+    char firstCharacter = target.charAt(index);
+
+    while (index < target.length() - 1) {
+      if (Character.isLetter(firstCharacter)) {
+        break;
+      }
+
+      fieldNameBuilder.append(firstCharacter);
+      firstCharacter = target.charAt(++index);
+    }
+
+    if (index == target.length()) {
+      return fieldNameBuilder.toString();
+    }
+
+    boolean capitalizeFirstLetter = (letterModifier == LetterModifier.UPPER);
+    if (capitalizeFirstLetter && !Character.isUpperCase(firstCharacter)) {
+      String modifiedTarget = modifyString(Character.toUpperCase(firstCharacter), target, ++index);
+      return fieldNameBuilder.append(modifiedTarget).toString();
+    } else if (!capitalizeFirstLetter && Character.isUpperCase(firstCharacter)) {
+      String modifiedTarget = modifyString(Character.toLowerCase(firstCharacter), target, ++index);
+      return fieldNameBuilder.append(modifiedTarget).toString();
+    } else {
+      return target;
+    }
+  }
+
+  private String modifyString(char firstCharacter, String srcString, int indexOfSubstring) {
+    if (indexOfSubstring < srcString.length()) {
+      return firstCharacter + srcString.substring(indexOfSubstring);
+    } else {
+      return String.valueOf(firstCharacter);
+    }
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/NullExclusionStrategy.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/NullExclusionStrategy.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/NullExclusionStrategy.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Field;
+
+/**
+ * This acts as a "Null Object" pattern for the {@link ExclusionStrategy}.
+ * Passing an instance of this class into the {@link ObjectNavigator} will
+ * make the {@link ObjectNavigator} parse/visit every field of the object
+ * being navigated.
+ *
+ * @author Joel Leitch
+ */
+final class NullExclusionStrategy implements ExclusionStrategy {
+
+  public boolean shouldSkipField(Field f) {
+    return false;
+  }
+
+  public boolean shouldSkipClass(Class<?> clazz) {
+    return false;
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/ObjectConstructor.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/ObjectConstructor.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/ObjectConstructor.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Type;
+
+/**
+ * Defines a generic object construction factory.  The purpose of this class
+ * is to construct a default instance of a class that can be used for object
+ * navigation while deserialization from its JSON representation.
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+interface ObjectConstructor {
+
+  /**
+   * Creates a new instance of the given type.
+   *
+   * @param typeOfT the class type that should be instantiated
+   * @return a default instance of the provided class.
+   */
+  public <T> T construct(Type typeOfT);
+
+  /**
+   * Constructs an array type of the provided length.
+   *
+   * @param typeOfArrayElements type of objects in the array
+   * @param length size of the array
+   * @return new array of size length
+   */
+  public Object constructArray(Type typeOfArrayElements, int length);
+}
\ No newline at end of file

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/ObjectNavigator.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/ObjectNavigator.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/ObjectNavigator.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+import java.util.Collection;
+
+/**
+ * Provides ability to apply a visitor to an object and all of its fields recursively.
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+final class ObjectNavigator {
+
+  public interface Visitor {
+    /**
+     * This is called before the object navigator starts visiting the current object
+     */
+    void startVisitingObject(Object node);
+
+    /**
+     * This is called after the object navigator finishes visiting the current object
+     */
+    void endVisitingObject(Object node);
+
+    /**
+     * This is called to visit the current object if it is an iterable
+     *
+     * @param componentType the type of each element of the component
+     */
+    void visitCollection(@SuppressWarnings("unchecked") Collection collection, Type componentType);
+
+    /**
+     * This is called to visit the current object if it is an array
+     */
+    void visitArray(Object array, Type componentType);
+
+    /**
+     * This is called to visit the current object if it is a primitive
+     */
+    void visitPrimitiveValue(Object obj);
+
+    /**
+     * This is called to visit an object field of the current object
+     */
+    void visitObjectField(Field f, Type typeOfF, Object obj);
+
+    /**
+     * This is called to visit a field of type Collection of the current object
+     */
+    void visitCollectionField(Field f, Type typeOfF, Object obj);
+
+    /**
+     * This is called to visit an array field of the current object
+     */
+    void visitArrayField(Field f, Type typeOfF, Object obj);
+
+    /**
+     * This is called to visit a primitive field of the current object
+     */
+    void visitPrimitiveField(Field f, Type typeOfF, Object obj);
+
+    /**
+     * This is called to visit an enum object
+     */
+    public void visitEnum(Object obj, Type objType);
+
+    /**
+     * This is called to visit an object using a custom handler
+     * @return true if a custom handler exists, false otherwise
+     */
+    public boolean visitUsingCustomHandler(Object obj, Type objType);
+  }
+
+  private final ExclusionStrategy exclusionStrategy;
+  private final MemoryRefStack<Object> ancestors;
+  private final Object obj;
+  private final Type objType;
+
+  /**
+   * @param obj The object being navigated
+   * @param objType The (fully genericized) type of the object being navigated
+   * @param exclusionStrategy the concrete strategy object to be used to
+   *        filter out fields of an object.
+   */
+  ObjectNavigator(Object obj, Type objType, ExclusionStrategy exclusionStrategy,
+      MemoryRefStack<Object> ancestors) {
+    Preconditions.checkNotNull(exclusionStrategy);
+    Preconditions.checkNotNull(ancestors);
+
+    this.obj = obj;
+    this.objType = objType;
+    this.exclusionStrategy = exclusionStrategy;
+    this.ancestors = ancestors;
+  }
+
+  /**
+   * Navigate all the fields of the specified object.
+   * If a field is null, it does not get visited.
+   */
+  public void accept(Visitor visitor) {
+    if (obj == null) {
+      return;
+    }
+    TypeInfo objTypeInfo = new TypeInfo(objType);
+    if (exclusionStrategy.shouldSkipClass(objTypeInfo.getRawClass())) {
+      return;
+    }
+
+    if (ancestors.contains(obj)) {
+      throw new IllegalStateException("Circular reference found: " + obj);
+    }
+    ancestors.push(obj);
+
+    try {
+      if (objTypeInfo.isCollectionOrArray()) {
+        if (objTypeInfo.isArray()) {
+          visitor.visitArray(obj, objType);
+        } else { // must be a collection
+          visitor.visitCollection((Collection<?>) obj, objType);
+        }
+      } else if (objTypeInfo.isEnum()) {
+        visitor.visitEnum(obj, objType);
+      } else if (objTypeInfo.isPrimitiveOrStringAndNotAnArray()) {
+        visitor.visitPrimitiveValue(obj);
+      } else {
+        if (!visitor.visitUsingCustomHandler(obj, objType)) {
+          visitor.startVisitingObject(obj);
+          // For all classes in the inheritance hierarchy (including the current class),
+          // visit all fields
+          for (Class<?> curr = objTypeInfo.getRawClass();
+              curr != null && !curr.equals(Object.class); curr = curr.getSuperclass()) {
+            if (!curr.isSynthetic()) {
+              navigateClassFields(obj, curr, visitor);
+            }
+          }
+          visitor.endVisitingObject(obj);
+        }
+      }
+    } finally {
+      ancestors.pop();
+    }
+  }
+
+  private void navigateClassFields(Object obj, Class<?> clazz, Visitor visitor) {
+    Field[] fields = clazz.getDeclaredFields();
+    AccessibleObject.setAccessible(fields, true);
+    for (Field f : fields) {
+      TypeInfo fieldTypeInfo = TypeInfoFactory.getTypeInfoForField(f, objType);
+      Type actualTypeOfField = fieldTypeInfo.getActualType();
+      if (exclusionStrategy.shouldSkipField(f)) {
+        continue; // skip
+      } else if (fieldTypeInfo.isCollectionOrArray()) {
+        if (fieldTypeInfo.isArray()) {
+          visitor.visitArrayField(f, actualTypeOfField, obj);
+        } else { // must be Collection
+          visitor.visitCollectionField(f, actualTypeOfField, obj);
+        }
+      } else if (fieldTypeInfo.isPrimitiveOrStringAndNotAnArray()) {
+        visitor.visitPrimitiveField(f, actualTypeOfField, obj);
+      } else {
+        visitor.visitObjectField(f, actualTypeOfField, obj);
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  private static final Class[] PRIMITIVE_TYPES = { int.class, long.class, short.class, float.class,
+      double.class, byte.class, boolean.class, Integer.class, Long.class, Short.class, Float.class,
+      Double.class, Byte.class, Boolean.class };
+
+  @SuppressWarnings("unchecked")
+  static boolean isPrimitiveOrString(Object target) {
+    if (target instanceof String) {
+      return true;
+    }
+    Class<?> classOfPrimitive = target.getClass();
+    for (Class standardPrimitive : PRIMITIVE_TYPES) {
+      if (standardPrimitive.isAssignableFrom(classOfPrimitive)) {
+        return true;
+      }
+    }
+    return false;
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/ObjectNavigatorFactory.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/ObjectNavigatorFactory.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/ObjectNavigatorFactory.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Type;
+
+/**
+ * A factory class used to simplify {@link ObjectNavigator} creation.
+ * This object holds on to a reference of the {@link ExclusionStrategy}
+ * that you'd like to use with the {@link ObjectNavigator}.
+ *
+ * @author Joel Leitch
+ */
+final class ObjectNavigatorFactory {
+  private final ExclusionStrategy strategy;
+  private final FieldNamingStrategy fieldNamingPolicy;
+  private final MemoryRefStack<Object> stack;
+
+  /**
+   * Creates a factory object that will be able to create new
+   * {@link ObjectNavigator}s with the provided {@code strategy}
+   *
+   * @param strategy the exclusion strategy to use with every instance that
+   *        is created by this factory instance.
+   * @param fieldNamingPolicy the naming policy that should be applied to field
+   *        names
+   */
+  public ObjectNavigatorFactory(ExclusionStrategy strategy, FieldNamingStrategy fieldNamingPolicy) {
+    Preconditions.checkNotNull(fieldNamingPolicy);
+    this.strategy = (strategy == null ? new NullExclusionStrategy() : strategy);
+    this.fieldNamingPolicy = fieldNamingPolicy;
+    this.stack = new MemoryRefStack<Object>();
+  }
+
+  /**
+   * Creates a new {@link ObjectNavigator} for this {@code srcObject}.
+   *
+   * @see #create(Object, Type)
+   * @param srcObject object to navigate
+   * @return a new instance of a {@link ObjectNavigator} ready to navigate the
+   *         {@code srcObject}.
+   */
+  public ObjectNavigator create(Object srcObject) {
+    return create(srcObject, srcObject.getClass());
+  }
+
+  /**
+   * Creates a new {@link ObjectNavigator} for this {@code srcObject},
+   * {@code type} pair.
+   *
+   * @param srcObject object to navigate
+   * @param type the "actual" type of this {@code srcObject}.  NOTE: this can
+   *        be a {@link java.lang.reflect.ParameterizedType} rather than a {@link Class}.
+   * @return a new instance of a {@link ObjectNavigator} ready to navigate the
+   *         {@code srcObject} while taking into consideration the
+   *         {@code type}.
+   */
+  public ObjectNavigator create(Object srcObject, Type type) {
+    return new ObjectNavigator(srcObject, type, strategy, stack);
+  }
+
+  FieldNamingStrategy getFieldNamingPolicy() {
+    return fieldNamingPolicy;
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/ParameterizedTypeHandlerMap.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/ParameterizedTypeHandlerMap.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/ParameterizedTypeHandlerMap.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+
+/**
+ * A map that provides ability to associate handlers for a specific type or all of its sub-types
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ *
+ * @param <T> The handler that will be looked up by type
+ */
+final class ParameterizedTypeHandlerMap<T> {
+
+  private final Map<Type, T> map = new HashMap<Type, T>();
+  private boolean modifiable = true;
+
+  public synchronized void register(Type typeOfT, T value) {
+    if (!modifiable) {
+      throw new IllegalStateException("Attempted to modify an unmodifiable map.");
+    }
+    if (hasSpecificHandlerFor(typeOfT)) {
+      Gson.logger.log(Level.WARNING, "Overriding the existing type handler for " + typeOfT);
+    }
+    map.put(typeOfT, value);
+  }
+
+  public synchronized void registerIfAbsent(ParameterizedTypeHandlerMap<T> other) {
+    if (!modifiable) {
+      throw new IllegalStateException("Attempted to modify an unmodifiable map.");
+    }
+    for (Map.Entry<Type, T> entry : other.entrySet()) {
+      if (!map.containsKey(entry.getKey())) {
+        register(entry.getKey(), entry.getValue());
+      }
+    }
+  }
+
+  public synchronized void makeUnmodifiable() {
+    modifiable = false;
+  }
+
+  public synchronized T getHandlerFor(Type type) {
+    T handler = map.get(type);
+    if (handler == null && type instanceof ParameterizedType) {
+      // a handler for a non-generic version is registered, so use that
+      Type rawType = ((ParameterizedType)type).getRawType();
+      handler = map.get(rawType);
+    }
+    return handler;
+  }
+
+  public synchronized boolean hasAnyHandlerFor(Type type) {
+    return getHandlerFor(type) != null;
+  }
+
+  public synchronized boolean hasSpecificHandlerFor(Type type) {
+    return map.containsKey(type);
+  }
+
+  public synchronized ParameterizedTypeHandlerMap<T> copyOf() {
+    ParameterizedTypeHandlerMap<T> copy = new ParameterizedTypeHandlerMap<T>();
+    for (Map.Entry<Type, T> entry : map.entrySet()) {
+      copy.register(entry.getKey(), entry.getValue());
+    }
+    return copy;
+  }
+
+  public synchronized Set<Map.Entry<Type, T>> entrySet() {
+    return map.entrySet();
+  }
+  
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("{");
+    boolean first = true;
+    for (Map.Entry<Type, T> entry : map.entrySet()) {
+      if (first) {
+        first = false;
+      } else {
+        sb.append(',');
+      }
+      sb.append(typeToString(entry.getKey())).append(':');
+      sb.append(entry.getValue());
+    }
+    return sb.toString();
+  }
+  
+  private String typeToString(Type type) {
+    return TypeUtils.toRawClass(type).getSimpleName();
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/ParameterizedTypeImpl.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/ParameterizedTypeImpl.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/ParameterizedTypeImpl.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+
+/**
+ * An immutable implementation of the {@link ParameterizedType} interface.  This object allows
+ * us to build a reflective {@link Type} objects on demand.  This object is used to support
+ * serialization and deserialization of classes with an {@code ParameterizedType} field where
+ * as least one of the actual type parameters is a {@code TypeVariable}.
+ *
+ * <p>Here's an example class:
+ * <pre>
+ * class Foo<T> {
+ *   private List<T> someList;
+ *
+ *   Foo(List<T> list) {
+ *     this.someList = list;
+ *   }
+ * }
+ * </pre>
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+final class ParameterizedTypeImpl implements ParameterizedType {
+
+  private final Type rawType;
+  private final Type[] actualTypeArguments;
+  private final Type owner;
+
+  public ParameterizedTypeImpl(Type rawType, Type[] actualTypeArguments, Type owner) {
+    this.rawType = rawType;
+    this.actualTypeArguments = actualTypeArguments;
+    this.owner = owner;
+  }
+
+  public Type getRawType() {
+    return rawType;
+  }
+
+  public Type[] getActualTypeArguments() {
+    return actualTypeArguments;
+  }
+
+  public Type getOwnerType() {
+    return owner;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (!(o instanceof  ParameterizedType)) {
+      return false;
+    } else {
+      // Check that information is equivalent
+      ParameterizedType that = (ParameterizedType) o;
+      if (this  == that)
+      return true;
+
+      Type thatOwner = that.getOwnerType();
+      Type thatRawType = that.getRawType();
+
+      return (owner == null ? thatOwner == null : owner.equals(thatOwner))
+          && (rawType == null ? thatRawType == null : rawType.equals(thatRawType))
+          && Arrays.equals(actualTypeArguments, that.getActualTypeArguments());
+    }
+  }
+
+  @Override
+  public int hashCode() {
+    return Arrays.hashCode(actualTypeArguments)
+        ^ (owner == null ? 0 : owner.hashCode())
+        ^ (rawType == null ? 0 : rawType.hashCode());
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/ParseException.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/ParseException.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/ParseException.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,193 @@
+/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.0 */
+package com.google.gson;
+
+/**
+ * This exception is thrown when parse errors are encountered.
+ * You can explicitly create objects of this exception type by
+ * calling the method generateParseException in the generated
+ * parser.
+ *
+ * You can modify this class to customize your error reporting
+ * mechanisms so long as you retain the public fields.
+ */
+ at SuppressWarnings("all")
+final class ParseException extends Exception {
+
+  /**
+   * This constructor is used by the method "generateParseException"
+   * in the generated parser.  Calling this constructor generates
+   * a new object of this type with the fields "currentToken",
+   * "expectedTokenSequences", and "tokenImage" set.  The boolean
+   * flag "specialConstructor" is also set to true to indicate that
+   * this constructor was used to create this object.
+   * This constructor calls its super class with the empty string
+   * to force the "toString" method of parent class "Throwable" to
+   * print the error message in the form:
+   *     ParseException: <result of getMessage>
+   */
+  public ParseException(Token currentTokenVal,
+                        int[][] expectedTokenSequencesVal,
+                        String[] tokenImageVal
+                       )
+  {
+    super("");
+    specialConstructor = true;
+    currentToken = currentTokenVal;
+    expectedTokenSequences = expectedTokenSequencesVal;
+    tokenImage = tokenImageVal;
+  }
+
+  /**
+   * The following constructors are for use by you for whatever
+   * purpose you can think of.  Constructing the exception in this
+   * manner makes the exception behave in the normal way - i.e., as
+   * documented in the class "Throwable".  The fields "errorToken",
+   * "expectedTokenSequences", and "tokenImage" do not contain
+   * relevant information.  The JavaCC generated code does not use
+   * these constructors.
+   */
+
+  public ParseException() {
+    super();
+    specialConstructor = false;
+  }
+
+  public ParseException(String message) {
+    super(message);
+    specialConstructor = false;
+  }
+
+  /**
+   * This variable determines which constructor was used to create
+   * this object and thereby affects the semantics of the
+   * "getMessage" method (see below).
+   */
+  protected boolean specialConstructor;
+
+  /**
+   * This is the last token that has been consumed successfully.  If
+   * this object has been created due to a parse error, the token
+   * followng this token will (therefore) be the first error token.
+   */
+  public Token currentToken;
+
+  /**
+   * Each entry in this array is an array of integers.  Each array
+   * of integers represents a sequence of tokens (by their ordinal
+   * values) that is expected at this point of the parse.
+   */
+  public int[][] expectedTokenSequences;
+
+  /**
+   * This is a reference to the "tokenImage" array of the generated
+   * parser within which the parse error occurred.  This array is
+   * defined in the generated ...Constants interface.
+   */
+  public String[] tokenImage;
+
+  /**
+   * This method has the standard behavior when this object has been
+   * created using the standard constructors.  Otherwise, it uses
+   * "currentToken" and "expectedTokenSequences" to generate a parse
+   * error message and returns it.  If this object has been created
+   * due to a parse error, and you do not catch it (it gets thrown
+   * from the parser), then this method is called during the printing
+   * of the final stack trace, and hence the correct error message
+   * gets displayed.
+   */
+  public String getMessage() {
+    if (!specialConstructor) {
+      return super.getMessage();
+    }
+    StringBuffer expected = new StringBuffer();
+    int maxSize = 0;
+    for (int i = 0; i < expectedTokenSequences.length; i++) {
+      if (maxSize < expectedTokenSequences[i].length) {
+        maxSize = expectedTokenSequences[i].length;
+      }
+      for (int j = 0; j < expectedTokenSequences[i].length; j++) {
+        expected.append(tokenImage[expectedTokenSequences[i][j]]).append(" ");
+      }
+      if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
+        expected.append("...");
+      }
+      expected.append(eol).append("    ");
+    }
+    String retval = "Encountered \"";
+    Token tok = currentToken.next;
+    for (int i = 0; i < maxSize; i++) {
+      if (i != 0) retval += " ";
+      if (tok.kind == 0) {
+        retval += tokenImage[0];
+        break;
+      }
+      retval += add_escapes(tok.image);
+      tok = tok.next; 
+    }
+    retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
+    retval += "." + eol;
+    if (expectedTokenSequences.length == 1) {
+      retval += "Was expecting:" + eol + "    ";
+    } else {
+      retval += "Was expecting one of:" + eol + "    ";
+    }
+    retval += expected.toString();
+    return retval;
+  }
+
+  /**
+   * The end of line string for this machine.
+   */
+  protected String eol = System.getProperty("line.separator", "\n");
+ 
+  /**
+   * Used to convert raw characters to their escaped version
+   * when these raw version cannot be used as part of an ASCII
+   * string literal.
+   */
+  protected String add_escapes(String str) {
+      StringBuffer retval = new StringBuffer();
+      char ch;
+      for (int i = 0; i < str.length(); i++) {
+        switch (str.charAt(i))
+        {
+           case 0 :
+              continue;
+           case '\b':
+              retval.append("\\b");
+              continue;
+           case '\t':
+              retval.append("\\t");
+              continue;
+           case '\n':
+              retval.append("\\n");
+              continue;
+           case '\f':
+              retval.append("\\f");
+              continue;
+           case '\r':
+              retval.append("\\r");
+              continue;
+           case '\"':
+              retval.append("\\\"");
+              continue;
+           case '\'':
+              retval.append("\\\'");
+              continue;
+           case '\\':
+              retval.append("\\\\");
+              continue;
+           default:
+              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+                 String s = "0000" + Integer.toString(ch, 16);
+                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+              } else {
+                 retval.append(ch);
+              }
+              continue;
+        }
+      }
+      return retval.toString();
+   }
+
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/Preconditions.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/Preconditions.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/Preconditions.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+/**
+ * A simple utility class used to check method Preconditions.
+ *
+ * <pre>
+ * public long divideBy(long value) {
+ *   Preconditions.checkArgument(value != 0);
+ *   return this.value / value;
+ * }
+ * </pre>
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+final class Preconditions {
+  public static void checkNotNull(Object obj) {
+    checkArgument(obj != null);
+  }
+
+  public static void checkArgument(boolean condition) {
+    if (!condition) {
+      throw new IllegalArgumentException("condition failed: " + condition);
+    }
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/PrimitiveTypeAdapter.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/PrimitiveTypeAdapter.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/PrimitiveTypeAdapter.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Handles type conversion from some object to some primitive (or primitive
+ * wrapper instance).
+ *
+ * @author Joel Leitch
+ */
+final class PrimitiveTypeAdapter implements TypeAdapter {
+
+  @SuppressWarnings({"unchecked"})
+  public <T> T adaptType(Object from, Class<T> to) {
+    Class<?> aClass = Primitives.wrap(to);
+    if (Primitives.isWrapperType(aClass)) {
+      if (aClass == Character.class) {
+        String value = from.toString();
+        if (value.length() == 1) {
+          return (T) (Character) from.toString().charAt(0);
+        } else {
+          throw new JsonParseException("The value: " + value + " contains more than a character.");
+        }
+      }
+
+      try {
+        Constructor<?> constructor = aClass.getConstructor(String.class);
+        return (T) constructor.newInstance(from.toString());
+      } catch (NoSuchMethodException e) {
+        throw new JsonParseException(e);
+      } catch (IllegalAccessException e) {
+        throw new JsonParseException(e);
+      } catch (InvocationTargetException e) {
+        throw new JsonParseException(e);
+      } catch (InstantiationException e) {
+        throw new JsonParseException(e);
+      }
+    } else if (Enum.class.isAssignableFrom(to)) {
+      // Case where the type being adapted to is an Enum
+      // We will try to convert from.toString() to the enum
+      try {
+        Method valuesMethod = to.getMethod("valueOf", String.class);
+        return (T) valuesMethod.invoke(null, from.toString());
+      } catch (NoSuchMethodException e) {
+        throw new RuntimeException(e);
+      } catch (IllegalAccessException e) {
+        throw new RuntimeException(e);
+      } catch (InvocationTargetException e) {
+        throw new RuntimeException(e);
+      }
+    } else {
+      throw new JsonParseException(
+          "Can not adapt type " + from.getClass() + " to " + to);
+    }
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/Primitives.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/Primitives.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/Primitives.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Contains static utility methods pertaining to primitive types and their
+ * corresponding wrapper types.
+ *
+ * @author Kevin Bourrillion
+ */
+final class Primitives {
+  private Primitives() {}
+
+  /** A map from primitive types to their corresponding wrapper types. */
+  public static final Map<Class<?>, Class<?>> PRIMITIVE_TO_WRAPPER_TYPE;
+
+  /** A map from wrapper types to their corresponding primitive types. */
+  public static final Map<Class<?>, Class<?>> WRAPPER_TO_PRIMITIVE_TYPE;
+
+  // Sad that we can't use a BiMap. :(
+  
+  static {
+    Map<Class<?>, Class<?>> primToWrap = new HashMap<Class<?>, Class<?>>(16);
+    Map<Class<?>, Class<?>> wrapToPrim = new HashMap<Class<?>, Class<?>>(16);
+
+    add(primToWrap, wrapToPrim, boolean.class, Boolean.class);
+    add(primToWrap, wrapToPrim, byte.class, Byte.class);
+    add(primToWrap, wrapToPrim, char.class, Character.class);
+    add(primToWrap, wrapToPrim, double.class, Double.class);
+    add(primToWrap, wrapToPrim, float.class, Float.class);
+    add(primToWrap, wrapToPrim, int.class, Integer.class);
+    add(primToWrap, wrapToPrim, long.class, Long.class);
+    add(primToWrap, wrapToPrim, short.class, Short.class);
+    add(primToWrap, wrapToPrim, void.class, Void.class);
+
+    PRIMITIVE_TO_WRAPPER_TYPE = Collections.unmodifiableMap(primToWrap);
+    WRAPPER_TO_PRIMITIVE_TYPE = Collections.unmodifiableMap(wrapToPrim);
+  }
+
+  private static void add(Map<Class<?>, Class<?>> forward,
+      Map<Class<?>, Class<?>> backward, Class<?> key, Class<?> value) {
+    forward.put(key, value);
+    backward.put(value, key);
+  }
+
+  /**
+   * Returns {@code true} if {@code type} is one of the nine
+   * primitive-wrapper types, such as {@link Integer}.
+   *
+   * @see Class#isPrimitive
+   */
+  public static boolean isWrapperType(Class<?> type) {
+    return WRAPPER_TO_PRIMITIVE_TYPE.containsKey(checkNotNull(type));
+  }
+
+  private static Class<?> checkNotNull(Class<?> type) {
+    Preconditions.checkNotNull(type);
+    return type;
+  }
+
+  /**
+   * Returns the corresponding wrapper type of {@code type} if it is a primitive
+   * type; otherwise returns {@code type} itself. Idempotent.
+   * <pre>
+   *     wrap(int.class) == Integer.class
+   *     wrap(Integer.class) == Integer.class
+   *     wrap(String.class) == String.class
+   * </pre>
+   */
+  public static <T> Class<T> wrap(Class<T> type) {
+    checkNotNull(type);
+
+    // cast is safe: long.class and Long.class are both of type Class<Long>
+    @SuppressWarnings("unchecked")
+    Class<T> wrapped = (Class<T>) PRIMITIVE_TO_WRAPPER_TYPE.get(type);
+    return (wrapped == null) ? type : wrapped;
+  }
+
+  /**
+   * Returns the corresponding primitive type of {@code type} if it is a
+   * wrapper type; otherwise returns {@code type} itself. Idempotent.
+   * <pre>
+   *     unwrap(Integer.class) == int.class
+   *     unwrap(int.class) == int.class
+   *     unwrap(String.class) == String.class
+   * </pre>
+   */
+  public static <T> Class<T> unwrap(Class<T> type) {
+    checkNotNull(type);
+
+    // cast is safe: long.class and Long.class are both of type Class<Long>
+    @SuppressWarnings("unchecked")
+    Class<T> unwrapped = (Class<T>) WRAPPER_TO_PRIMITIVE_TYPE.get(type);
+    return (unwrapped == null) ? type : unwrapped;
+  }  
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/RecursiveFieldNamingPolicy.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/RecursiveFieldNamingPolicy.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/RecursiveFieldNamingPolicy.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+
+/**
+ * A mechanism for providing custom field naming in Gson.  This allows the client code to translate
+ * field names into a particular convention that is not supported as a normal Java field
+ * declaration rules.  For example, Java does not support "-" characters in a field name.
+ *
+ * @author Joel Leitch
+ */
+abstract class RecursiveFieldNamingPolicy implements FieldNamingStrategy {
+
+  public final String translateName(Field f) {
+    Preconditions.checkNotNull(f);
+    return translateName(f.getName(), f.getGenericType(), f.getAnnotations());
+  }
+
+  /**
+   * Performs the specific string translation.
+   *
+   * @param target the string object that will be manipulation/translated
+   * @param fieldType the actual type value of the field
+   * @param annotations the annotations set on the field
+   * @return the translated field name
+   */
+  protected abstract String translateName(String target, Type fieldType, Annotation[] annotations);
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/SerializedNameAnnotationInterceptingNamingPolicy.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/SerializedNameAnnotationInterceptingNamingPolicy.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/SerializedNameAnnotationInterceptingNamingPolicy.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.lang.reflect.Field;
+
+/**
+ * A {@link FieldNamingStrategy} that acts as a chain of responsibility.  If the
+ * {@link com.google.gson.annotations.SerializedName} annotation is applied to a field then this
+ * strategy will translate the name to the {@code serializedName.value()}; otherwise it delegates
+ * to the wrapped {@link FieldNamingStrategy}.
+ *
+ * <p>NOTE: this class performs JSON field name validation for any of the fields marked with
+ * an {@code @SerializedName} annotation.</p>
+ *
+ * @see SerializedName
+ *
+ * @author Joel Leitch
+ */
+class SerializedNameAnnotationInterceptingNamingPolicy implements FieldNamingStrategy {
+  private static final JsonFieldNameValidator fieldNameValidator = new JsonFieldNameValidator();
+  private final FieldNamingStrategy delegate;
+
+  public SerializedNameAnnotationInterceptingNamingPolicy(FieldNamingStrategy delegate) {
+    this.delegate = delegate;
+  }
+
+  public String translateName(Field f) {
+    Preconditions.checkNotNull(f);
+    SerializedName serializedName = f.getAnnotation(SerializedName.class);
+    if (serializedName != null) {
+      return fieldNameValidator.validate(serializedName.value());
+    } else {
+      return delegate.translateName(f);
+    }
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/SimpleCharStream.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/SimpleCharStream.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/SimpleCharStream.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,440 @@
+/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 4.0 */
+package com.google.gson;
+
+/**
+ * An implementation of interface CharStream, where the stream is assumed to
+ * contain only ASCII characters (without unicode processing).
+ */
+
+ at SuppressWarnings("all")
+final class SimpleCharStream
+{
+  public static final boolean staticFlag = false;
+  int bufsize;
+  int available;
+  int tokenBegin;
+  public int bufpos = -1;
+  protected int bufline[];
+  protected int bufcolumn[];
+
+  protected int column = 0;
+  protected int line = 1;
+
+  protected boolean prevCharIsCR = false;
+  protected boolean prevCharIsLF = false;
+
+  protected java.io.Reader inputStream;
+
+  protected char[] buffer;
+  protected int maxNextCharInd = 0;
+  protected int inBuf = 0;
+  protected int tabSize = 8;
+
+  protected void setTabSize(int i) { tabSize = i; }
+  protected int getTabSize(int i) { return tabSize; }
+
+
+  protected void ExpandBuff(boolean wrapAround)
+  {
+     char[] newbuffer = new char[bufsize + 2048];
+     int newbufline[] = new int[bufsize + 2048];
+     int newbufcolumn[] = new int[bufsize + 2048];
+
+     try
+     {
+        if (wrapAround)
+        {
+           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+           System.arraycopy(buffer, 0, newbuffer,
+                                             bufsize - tokenBegin, bufpos);
+           buffer = newbuffer;
+
+           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+           System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
+           bufline = newbufline;
+
+           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+           System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
+           bufcolumn = newbufcolumn;
+
+           maxNextCharInd = (bufpos += (bufsize - tokenBegin));
+        }
+        else
+        {
+           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+           buffer = newbuffer;
+
+           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+           bufline = newbufline;
+
+           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+           bufcolumn = newbufcolumn;
+
+           maxNextCharInd = (bufpos -= tokenBegin);
+        }
+     }
+     catch (Throwable t)
+     {
+        throw new Error(t.getMessage());
+     }
+
+
+     bufsize += 2048;
+     available = bufsize;
+     tokenBegin = 0;
+  }
+
+  protected void FillBuff() throws java.io.IOException
+  {
+     if (maxNextCharInd == available)
+     {
+        if (available == bufsize)
+        {
+           if (tokenBegin > 2048)
+           {
+              bufpos = maxNextCharInd = 0;
+              available = tokenBegin;
+           }
+           else if (tokenBegin < 0)
+              bufpos = maxNextCharInd = 0;
+           else
+              ExpandBuff(false);
+        }
+        else if (available > tokenBegin)
+           available = bufsize;
+        else if ((tokenBegin - available) < 2048)
+           ExpandBuff(true);
+        else
+           available = tokenBegin;
+     }
+
+     int i;
+     try {
+        if ((i = inputStream.read(buffer, maxNextCharInd,
+                                    available - maxNextCharInd)) == -1)
+        {
+           inputStream.close();
+           throw new java.io.IOException();
+        }
+        else
+           maxNextCharInd += i;
+        return;
+     }
+     catch(java.io.IOException e) {
+        --bufpos;
+        backup(0);
+        if (tokenBegin == -1)
+           tokenBegin = bufpos;
+        throw e;
+     }
+  }
+
+  public char BeginToken() throws java.io.IOException
+  {
+     tokenBegin = -1;
+     char c = readChar();
+     tokenBegin = bufpos;
+
+     return c;
+  }
+
+  protected void UpdateLineColumn(char c)
+  {
+     column++;
+
+     if (prevCharIsLF)
+     {
+        prevCharIsLF = false;
+        line += (column = 1);
+     }
+     else if (prevCharIsCR)
+     {
+        prevCharIsCR = false;
+        if (c == '\n')
+        {
+           prevCharIsLF = true;
+        }
+        else
+           line += (column = 1);
+     }
+
+     switch (c)
+     {
+        case '\r' :
+           prevCharIsCR = true;
+           break;
+        case '\n' :
+           prevCharIsLF = true;
+           break;
+        case '\t' :
+           column--;
+           column += (tabSize - (column % tabSize));
+           break;
+        default :
+           break;
+     }
+
+     bufline[bufpos] = line;
+     bufcolumn[bufpos] = column;
+  }
+
+  public char readChar() throws java.io.IOException
+  {
+     if (inBuf > 0)
+     {
+        --inBuf;
+
+        if (++bufpos == bufsize)
+           bufpos = 0;
+
+        return buffer[bufpos];
+     }
+
+     if (++bufpos >= maxNextCharInd)
+        FillBuff();
+
+     char c = buffer[bufpos];
+
+     UpdateLineColumn(c);
+     return (c);
+  }
+
+  /**
+   * @deprecated 
+   * @see #getEndColumn
+   */
+
+  public int getColumn() {
+     return bufcolumn[bufpos];
+  }
+
+  /**
+   * @deprecated 
+   * @see #getEndLine
+   */
+
+  public int getLine() {
+     return bufline[bufpos];
+  }
+
+  public int getEndColumn() {
+     return bufcolumn[bufpos];
+  }
+
+  public int getEndLine() {
+     return bufline[bufpos];
+  }
+
+  public int getBeginColumn() {
+     return bufcolumn[tokenBegin];
+  }
+
+  public int getBeginLine() {
+     return bufline[tokenBegin];
+  }
+
+  public void backup(int amount) {
+
+    inBuf += amount;
+    if ((bufpos -= amount) < 0)
+       bufpos += bufsize;
+  }
+
+  public SimpleCharStream(java.io.Reader dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
+
+    available = bufsize = buffersize;
+    buffer = new char[buffersize];
+    bufline = new int[buffersize];
+    bufcolumn = new int[buffersize];
+  }
+
+  public SimpleCharStream(java.io.Reader dstream, int startline,
+                          int startcolumn)
+  {
+     this(dstream, startline, startcolumn, 4096);
+  }
+
+  public SimpleCharStream(java.io.Reader dstream)
+  {
+     this(dstream, 1, 1, 4096);
+  }
+  public void ReInit(java.io.Reader dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
+
+    if (buffer == null || buffersize != buffer.length)
+    {
+      available = bufsize = buffersize;
+      buffer = new char[buffersize];
+      bufline = new int[buffersize];
+      bufcolumn = new int[buffersize];
+    }
+    prevCharIsLF = prevCharIsCR = false;
+    tokenBegin = inBuf = maxNextCharInd = 0;
+    bufpos = -1;
+  }
+
+  public void ReInit(java.io.Reader dstream, int startline,
+                     int startcolumn)
+  {
+     ReInit(dstream, startline, startcolumn, 4096);
+  }
+
+  public void ReInit(java.io.Reader dstream)
+  {
+     ReInit(dstream, 1, 1, 4096);
+  }
+  public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
+  int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
+  {
+     this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
+  }
+
+  public SimpleCharStream(java.io.InputStream dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+     this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
+  }
+
+  public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
+                          int startcolumn) throws java.io.UnsupportedEncodingException
+  {
+     this(dstream, encoding, startline, startcolumn, 4096);
+  }
+
+  public SimpleCharStream(java.io.InputStream dstream, int startline,
+                          int startcolumn)
+  {
+     this(dstream, startline, startcolumn, 4096);
+  }
+
+  public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
+  {
+     this(dstream, encoding, 1, 1, 4096);
+  }
+
+  public SimpleCharStream(java.io.InputStream dstream)
+  {
+     this(dstream, 1, 1, 4096);
+  }
+
+  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
+                          int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
+  {
+     ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
+  }
+
+  public void ReInit(java.io.InputStream dstream, int startline,
+                          int startcolumn, int buffersize)
+  {
+     ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
+  }
+
+  public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
+  {
+     ReInit(dstream, encoding, 1, 1, 4096);
+  }
+
+  public void ReInit(java.io.InputStream dstream)
+  {
+     ReInit(dstream, 1, 1, 4096);
+  }
+  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
+                     int startcolumn) throws java.io.UnsupportedEncodingException
+  {
+     ReInit(dstream, encoding, startline, startcolumn, 4096);
+  }
+  public void ReInit(java.io.InputStream dstream, int startline,
+                     int startcolumn)
+  {
+     ReInit(dstream, startline, startcolumn, 4096);
+  }
+  public String GetImage()
+  {
+     if (bufpos >= tokenBegin)
+        return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
+     else
+        return new String(buffer, tokenBegin, bufsize - tokenBegin) +
+                              new String(buffer, 0, bufpos + 1);
+  }
+
+  public char[] GetSuffix(int len)
+  {
+     char[] ret = new char[len];
+
+     if ((bufpos + 1) >= len)
+        System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
+     else
+     {
+        System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
+                                                          len - bufpos - 1);
+        System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
+     }
+
+     return ret;
+  }
+
+  public void Done()
+  {
+     buffer = null;
+     bufline = null;
+     bufcolumn = null;
+  }
+
+  /**
+   * Method to adjust line and column numbers for the start of a token.
+   */
+  public void adjustBeginLineColumn(int newLine, int newCol)
+  {
+     int start = tokenBegin;
+     int len;
+
+     if (bufpos >= tokenBegin)
+     {
+        len = bufpos - tokenBegin + inBuf + 1;
+     }
+     else
+     {
+        len = bufsize - tokenBegin + bufpos + 1 + inBuf;
+     }
+
+     int i = 0, j = 0, k = 0;
+     int nextColDiff = 0, columnDiff = 0;
+
+     while (i < len &&
+            bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
+     {
+        bufline[j] = newLine;
+        nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
+        bufcolumn[j] = newCol + columnDiff;
+        columnDiff = nextColDiff;
+        i++;
+     } 
+
+     if (i < len)
+     {
+        bufline[j] = newLine++;
+        bufcolumn[j] = newCol + columnDiff;
+
+        while (i++ < len)
+        {
+           if (bufline[j = start % bufsize] != bufline[++start % bufsize])
+              bufline[j] = newLine++;
+           else
+              bufline[j] = newLine;
+        }
+     }
+
+     line = bufline[j];
+     column = bufcolumn[j];
+  }
+
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/StringUnmarshaller.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/StringUnmarshaller.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/StringUnmarshaller.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,71 @@
+package com.google.gson;
+
+final class StringUnmarshaller {
+  static String unmarshall(String str) {
+    str = str.substring(1, str.length()-1);
+    
+    int len = str.length();    
+    StringBuilder sb = new StringBuilder(len);    
+    int i = 0;    
+    while (i < len) {
+      char c = str.charAt(i);      
+      ++i;
+      if (c == '\\') {
+        char c1 = str.charAt(i);
+        ++i;
+        if (c1 == 'u') { // This is a unicode escape
+          // TODO(inder): Handle the case where code points are of size bigger than 4 
+          int codePoint = getCodePoint(str, i);
+          sb.appendCodePoint(codePoint);
+          i += 4;           
+        } else {
+          char escapedChar = getEscapedChar(str, c1);
+          sb.append(escapedChar);
+        }
+      } else {
+        sb.append(c);
+      }
+    }
+    return sb.toString();
+  }
+
+  private static int getCodePoint(String str, int i) {
+//    int codePoint = Character.codePointAt(str, i);
+    String s = str.substring(i, i+4);
+    int codePoint = Integer.parseInt(s, 16);
+    return codePoint;
+  }
+
+  private static char getEscapedChar(String str, char c) {
+    char ch;
+    switch (c) {
+      case 'n':
+        ch = '\n';
+        break;
+      case 'b':
+        ch = '\b';
+        break;
+      case 'f':
+        ch = '\f';
+        break;
+      case 't':
+        ch = '\t';
+        break;
+      case 'r':
+        ch = '\r';
+        break;
+      case '\"':
+        ch = '\"';
+        break;
+      case '\'':
+        ch = '\'';
+        break;
+      case '\\':
+        ch = '\\';
+        break;
+      default:
+        throw new IllegalStateException("Unexpected character: " + c + " in " + str);
+    }
+    return ch;
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/Token.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/Token.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/Token.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,82 @@
+/* Generated By:JavaCC: Do not edit this line. Token.java Version 3.0 */
+package com.google.gson;
+
+/**
+ * Describes the input token stream.
+ */
+
+ at SuppressWarnings("all")
+final class Token {
+
+  /**
+   * An integer that describes the kind of this token.  This numbering
+   * system is determined by JavaCCParser, and a table of these numbers is
+   * stored in the file ...Constants.java.
+   */
+  public int kind;
+
+  /**
+   * beginLine and beginColumn describe the position of the first character
+   * of this token; endLine and endColumn describe the position of the
+   * last character of this token.
+   */
+  public int beginLine, beginColumn, endLine, endColumn;
+
+  /**
+   * The string image of the token.
+   */
+  public String image;
+
+  /**
+   * A reference to the next regular (non-special) token from the input
+   * stream.  If this is the last token from the input stream, or if the
+   * token manager has not read tokens beyond this one, this field is
+   * set to null.  This is true only if this token is also a regular
+   * token.  Otherwise, see below for a description of the contents of
+   * this field.
+   */
+  public Token next;
+
+  /**
+   * This field is used to access special tokens that occur prior to this
+   * token, but after the immediately preceding regular (non-special) token.
+   * If there are no such special tokens, this field is set to null.
+   * When there are more than one such special token, this field refers
+   * to the last of these special tokens, which in turn refers to the next
+   * previous special token through its specialToken field, and so on
+   * until the first special token (whose specialToken field is null).
+   * The next fields of special tokens refer to other special tokens that
+   * immediately follow it (without an intervening regular token).  If there
+   * is no such token, this field is null.
+   */
+  public Token specialToken;
+
+  /**
+   * Returns the image.
+   */
+  public String toString()
+  {
+     return image;
+  }
+
+  /**
+   * Returns a new Token object, by default. However, if you want, you
+   * can create and return subclass objects based on the value of ofKind.
+   * Simply add the cases to the switch for all those special cases.
+   * For example, if you have a subclass of Token called IDToken that
+   * you want to create if ofKind is ID, simlpy add something like :
+   *
+   *    case MyParserConstants.ID : return new IDToken();
+   *
+   * to the following switch statement. Then you can cast matchedToken
+   * variable to the appropriate type and use it in your lexical actions.
+   */
+  public static final Token newToken(int ofKind)
+  {
+     switch(ofKind)
+     {
+       default : return new Token();
+     }
+  }
+
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/TokenMgrError.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/TokenMgrError.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/TokenMgrError.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,134 @@
+/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 3.0 */
+package com.google.gson;
+
+ at SuppressWarnings("all")
+final class TokenMgrError extends Error
+{
+   /*
+    * Ordinals for various reasons why an Error of this type can be thrown.
+    */
+
+   /**
+    * Lexical error occured.
+    */
+   static final int LEXICAL_ERROR = 0;
+
+   /**
+    * An attempt wass made to create a second instance of a static token manager.
+    */
+   static final int STATIC_LEXER_ERROR = 1;
+
+   /**
+    * Tried to change to an invalid lexical state.
+    */
+   static final int INVALID_LEXICAL_STATE = 2;
+
+   /**
+    * Detected (and bailed out of) an infinite loop in the token manager.
+    */
+   static final int LOOP_DETECTED = 3;
+
+   /**
+    * Indicates the reason why the exception is thrown. It will have
+    * one of the above 4 values.
+    */
+   int errorCode;
+
+   /**
+    * Replaces unprintable characters by their espaced (or unicode escaped)
+    * equivalents in the given string
+    */
+   protected static final String addEscapes(String str) {
+      StringBuffer retval = new StringBuffer();
+      char ch;
+      for (int i = 0; i < str.length(); i++) {
+        switch (str.charAt(i))
+        {
+           case 0 :
+              continue;
+           case '\b':
+              retval.append("\\b");
+              continue;
+           case '\t':
+              retval.append("\\t");
+              continue;
+           case '\n':
+              retval.append("\\n");
+              continue;
+           case '\f':
+              retval.append("\\f");
+              continue;
+           case '\r':
+              retval.append("\\r");
+              continue;
+           case '\"':
+              retval.append("\\\"");
+              continue;
+           case '\'':
+              retval.append("\\\'");
+              continue;
+           case '\\':
+              retval.append("\\\\");
+              continue;
+           default:
+              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+                 String s = "0000" + Integer.toString(ch, 16);
+                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+              } else {
+                 retval.append(ch);
+              }
+              continue;
+        }
+      }
+      return retval.toString();
+   }
+
+   /**
+    * Returns a detailed message for the Error when it is thrown by the
+    * token manager to indicate a lexical error.
+    * Parameters : 
+    *    EOFSeen     : indicates if EOF caused the lexicl error
+    *    curLexState : lexical state in which this error occured
+    *    errorLine   : line number when the error occured
+    *    errorColumn : column number when the error occured
+    *    errorAfter  : prefix that was seen before this error occured
+    *    curchar     : the offending character
+    * Note: You can customize the lexical error message by modifying this method.
+    */
+   protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
+      return("Lexical error at line " +
+           errorLine + ", column " +
+           errorColumn + ".  Encountered: " +
+           (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
+           "after : \"" + addEscapes(errorAfter) + "\"");
+   }
+
+   /**
+    * You can also modify the body of this method to customize your error messages.
+    * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+    * of end-users concern, so you can return something like : 
+    *
+    *     "Internal Error : Please file a bug report .... "
+    *
+    * from this method for such cases in the release version of your parser.
+    */
+   public String getMessage() {
+      return super.getMessage();
+   }
+
+   /*
+    * Constructors of various flavors follow.
+    */
+
+   public TokenMgrError() {
+   }
+
+   public TokenMgrError(String message, int reason) {
+      super(message);
+      errorCode = reason;
+   }
+
+   public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
+      this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
+   }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeAdapter.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeAdapter.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeAdapter.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+/**
+ * This class is responsible for adapting/converting an particular "from"
+ * instance to an instance of type "to".
+ *
+ * @author Joel Leitch
+ */
+interface TypeAdapter {
+
+  /**
+   * Adapts an object instance "from" to and instance of type "to".
+   *
+   * @param from the object to adapt
+   * @param to the Type/Class which this will convert to
+   * @return the converted "from" instance to type "to"
+   */
+  public <T> T adaptType(Object from, Class<T> to);
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeAdapterNotRequired.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeAdapterNotRequired.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeAdapterNotRequired.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+/**
+ * This class implements the {@link TypeAdapter} interface; however, if the
+ * from instance type is the same as the to type then this object will
+ * terminate the chain early and return the "from" object to the calling
+ * class.
+ *
+ * If the incoming object does need some kind of conversion then this object
+ * will delegate to the {@link TypeAdapter} that it is wrapping.
+ *
+ * @author Joel Leitch
+ */
+final class TypeAdapterNotRequired implements TypeAdapter {
+
+  private final TypeAdapter delegate;
+
+  /**
+   * Constructs a TypeAdapterNotRequired that will wrap the delegate instance
+   * that is passed in.
+   *
+   * @param delegate the TypeConverter to delegate to if this instance can
+   *        not handle the type adapting (can not be null)
+   */
+  TypeAdapterNotRequired(TypeAdapter delegate) {
+    Preconditions.checkNotNull(delegate);
+    this.delegate = delegate;
+  }
+
+  @SuppressWarnings("unchecked")
+  public <T> T adaptType(Object from, Class<T> to) {
+    if (to.isAssignableFrom(from.getClass())) {
+      return (T) from;
+    }
+    return delegate.adaptType(from, to);
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeInfo.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeInfo.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeInfo.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Type;
+import java.util.Collection;
+
+/**
+ * Class that provides information relevant to different parts of a type.
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+class TypeInfo {
+  protected final Type actualType;
+  protected final Class<?> rawClass;
+
+  TypeInfo(Type actualType) {
+    this.actualType = actualType;
+    rawClass = TypeUtils.toRawClass(actualType);
+  }
+
+  public final Type getActualType() {
+    return actualType;
+  }
+
+  /**
+   * Returns the corresponding wrapper type of {@code type} if it is a primitive
+   * type; otherwise returns {@code type} itself. Idempotent.
+   * <pre>
+   *     wrap(int.class) == Integer.class
+   *     wrap(Integer.class) == Integer.class
+   *     wrap(String.class) == String.class
+   * </pre>
+   */
+  public final Class<?> getWrappedClass() {
+    return Primitives.wrap(rawClass);
+  }
+
+  /**
+   * @return the raw class associated with this type
+   */
+  public final Class<?> getRawClass() {
+    return rawClass;
+  }
+
+  public final boolean isCollectionOrArray() {
+    return Collection.class.isAssignableFrom(rawClass) || isArray();
+  }
+
+  public final boolean isArray() {
+    return TypeUtils.isArray(rawClass);
+  }
+
+  public final boolean isEnum() {
+    return rawClass.isEnum();
+  }
+
+  public final boolean isPrimitive() {
+    return Primitives.isWrapperType(Primitives.wrap(rawClass));
+  }
+
+  public final boolean isString() {
+    return rawClass == String.class;
+  }
+
+  public final boolean isPrimitiveOrStringAndNotAnArray() {
+    return (isPrimitive() || isString()) && !isArray();
+  }
+}
\ No newline at end of file

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeInfoArray.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeInfoArray.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeInfoArray.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Type;
+
+/**
+ * Class to extract information about types used to define a generic array.
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+final class TypeInfoArray extends TypeInfo {
+  private final Class<?> componentRawType;
+  private final Type secondLevel;
+
+  TypeInfoArray(Type type) {
+    super(type);
+    Class<?> rootComponentType = rawClass;
+    while (rootComponentType.isArray()) {
+      rootComponentType = rootComponentType.getComponentType();
+    }
+    this.componentRawType = rootComponentType;
+    this.secondLevel = extractSecondLevelType(actualType, rawClass);
+  }
+
+  private static Type extractSecondLevelType(Type actualType, Class<?> rawClass) {
+    if (actualType instanceof GenericArrayType) {
+      GenericArrayType castedType = (GenericArrayType) actualType;
+      return castedType.getGenericComponentType();
+    } else {
+      return rawClass.getComponentType();
+    }
+  }
+
+  /**
+   * @return the raw type unwrapped of the second level of array.
+   * If the object is (single-dimensional or multi-dimensional) array, it is the class of the
+   * elements of the array. For example, this method returns Foo.class for Foo[].
+   * It will return Foo[].class for Foo[][].  For Foo&lt;String&gt;[][] types, it will return the 
+   * type representing Foo&lt;String&gt;[] 
+   * (i.e. <code>new TypeToken<Foo<String>[]>() {}.getType()</code>).
+   */
+  public Type getSecondLevelType() {
+    return secondLevel;
+  }
+
+  /**
+   * @return the raw type of the root component.
+   * If the object is a single-dimensional array then the component type is the class of an
+   * element of the array.
+   * If the object is a multi-dimensional array then the component type is the class of the
+   * inner-most array element. For example, the This method will return Foo.class for Foo[][][].
+   */
+  public Class<?> getComponentRawType() {
+    return componentRawType;
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeInfoFactory.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeInfoFactory.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeInfoFactory.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+
+/**
+ * A static factory class used to construct the "TypeInfo" objects.
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+final class TypeInfoFactory {
+
+  private TypeInfoFactory() {
+    // Not instantiable since it provides factory methods only.
+  }
+
+  public static TypeInfoArray getTypeInfoForArray(Type type) {
+    Preconditions.checkArgument(TypeUtils.isArray(type));
+    return new TypeInfoArray(type);
+  }
+
+  /**
+   * Evaluates the "actual" type for the field.  If the field is a "TypeVariable" or has a
+   * "TypeVariable" in a parameterized type then it evaluates the real type.
+   *
+   * @param f the actual field object to retrieve the type from
+   * @param typeDefiningF the type that contains the field {@code f}
+   * @return the type information for the field
+   */
+  public static TypeInfo getTypeInfoForField(Field f, Type typeDefiningF) {
+    Class<?> classDefiningF = TypeUtils.toRawClass(typeDefiningF);
+    Type type = f.getGenericType();
+    Type actualType = getActualType(type, typeDefiningF, classDefiningF);
+    return new TypeInfo(actualType);
+  }
+
+  private static Type getActualType(
+      Type typeToEvaluate, Type parentType, Class<?> rawParentClass) {
+    if (typeToEvaluate instanceof Class) {
+      return typeToEvaluate;
+    } else if (typeToEvaluate instanceof ParameterizedType) {
+      ParameterizedType castedType = (ParameterizedType) typeToEvaluate;
+      Type owner = castedType.getOwnerType();
+      Type[] actualTypeParameters =
+          extractRealTypes(castedType.getActualTypeArguments(), parentType, rawParentClass);
+      Type rawType = castedType.getRawType();
+      return new ParameterizedTypeImpl(rawType, actualTypeParameters, owner);
+    } else if (typeToEvaluate instanceof GenericArrayType) {
+      GenericArrayType castedType = (GenericArrayType) typeToEvaluate;
+      Type componentType = castedType.getGenericComponentType();
+      Type actualType = getActualType(componentType, parentType, rawParentClass);
+      if (componentType.equals(actualType)) {
+        return castedType;
+      } else {
+        if (actualType instanceof Class) {
+          return TypeUtils.wrapWithArray(TypeUtils.toRawClass(actualType));
+        } else {
+          return new GenericArrayTypeImpl(actualType);
+        }
+      }
+    } else if (typeToEvaluate instanceof TypeVariable) {
+      // The class definition has the actual types used for the type variables.
+      // Find the matching actual type for the Type Variable used for the field.
+      // For example, class Foo<A> { A a; }
+      // new Foo<Integer>(); defines the actual type of A to be Integer.
+      // So, to find the type of the field a, we will have to look at the class'
+      // actual type arguments.
+      TypeVariable<?> fieldTypeVariable = (TypeVariable<?>) typeToEvaluate;
+      TypeVariable<?>[] classTypeVariables = rawParentClass.getTypeParameters();
+      ParameterizedType objParameterizedType = (ParameterizedType) parentType;
+      int indexOfActualTypeArgument = getIndex(classTypeVariables, fieldTypeVariable);
+      Type[] actualTypeArguments = objParameterizedType.getActualTypeArguments();
+      return actualTypeArguments[indexOfActualTypeArgument];
+    } else if (typeToEvaluate instanceof WildcardType) {
+      WildcardType castedType = (WildcardType) typeToEvaluate;
+      return getActualType(castedType.getUpperBounds()[0], parentType, rawParentClass);
+    } else {
+      throw new IllegalArgumentException("Type \'" + typeToEvaluate + "\' is not a Class, "
+          + "ParameterizedType, GenericArrayType or TypeVariable. Can't extract type.");
+    }
+  }
+
+  private static Type[] extractRealTypes(
+      Type[] actualTypeArguments, Type parentType, Class<?> rawParentClass) {
+    Preconditions.checkNotNull(actualTypeArguments);
+
+    Type[] retTypes = new Type[actualTypeArguments.length];
+    for (int i = 0; i < actualTypeArguments.length; ++i) {
+      retTypes[i] = getActualType(actualTypeArguments[i], parentType, rawParentClass);
+    }
+    return retTypes;
+  }
+
+  private static int getIndex(TypeVariable<?>[] types, TypeVariable<?> type) {
+    for (int i = 0; i < types.length; ++i) {
+      if (type.equals(types[i])) {
+        return i;
+      }
+    }
+    throw new IllegalStateException(
+        "How can the type variable not be present in the class declaration!");
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeInfoMap.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeInfoMap.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeInfoMap.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Map;
+
+/**
+ * A convenience object for retrieving the map type information.
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+final class TypeInfoMap {
+  private final ParameterizedType mapType;
+
+  public TypeInfoMap(Type mapType) {
+    if (!(mapType instanceof ParameterizedType)) {
+      throw new IllegalArgumentException(
+          "Map objects need to be parameterized unless you use a custom serializer. "
+              + "Use the com.google.gson.reflect.TypeToken to extract the ParameterizedType.");
+    }
+    TypeInfo rawType = new TypeInfo(mapType);
+    Preconditions.checkArgument(Map.class.isAssignableFrom(rawType.getRawClass()));
+    this.mapType = (ParameterizedType) mapType;
+  }
+
+  public Type getKeyType() {
+    return mapType.getActualTypeArguments()[0];
+  }
+
+  public Type getValueType() {
+    return mapType.getActualTypeArguments()[1];
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeUtils.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeUtils.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/TypeUtils.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+/**
+ * Utility class containing some methods for obtaining information on types.
+ *
+ * @author Inderjeet Singh
+ * @author Joel Leitch
+ */
+final class TypeUtils {
+
+  /**
+   * Returns the actual type matching up with the first type variable.
+   * So, for a {@code typeInfo} instance defined as:
+   * <pre>
+   *   class Foo<A, B> {
+   *   }
+   *   Type fooType = new TypeToken<Foo<Integer, String>>() {}.getType();
+   * </pre>
+   * <code>TypeUtils.getActualTypeForFirstTypeVariable(fooType)</code> will return Integer.class.
+   */
+  static Type getActualTypeForFirstTypeVariable(Type type) {
+    if (type instanceof Class) {
+      return Object.class;
+    } else if (type instanceof ParameterizedType) {
+      return ((ParameterizedType)type).getActualTypeArguments()[0];
+    } else if (type instanceof GenericArrayType) {
+      return getActualTypeForFirstTypeVariable(((GenericArrayType)type).getGenericComponentType());
+    } else {
+      throw new IllegalArgumentException("Type \'" + type + "\' is not a Class, "
+          + "ParameterizedType, or GenericArrayType. Can't extract class.");
+    }
+  }
+
+  static boolean isArray(Type type) {
+    if (type instanceof Class) {
+      return ((Class<?>)type).isArray();
+    } else if (type instanceof GenericArrayType) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  /**
+   * This method returns the actual raw class associated with the specified type.
+   */
+  static Class<?> toRawClass(Type type) {
+    if (type instanceof Class) {
+      return (Class<?>) type;
+    } else if (type instanceof ParameterizedType) {
+      ParameterizedType actualType = (ParameterizedType)type;
+      return toRawClass(actualType.getRawType());
+    } else if (type instanceof GenericArrayType) {
+      GenericArrayType actualType = (GenericArrayType) type;
+      Class<?> rawClass = toRawClass(actualType.getGenericComponentType());
+      return wrapWithArray(rawClass);
+    } else {
+      throw new IllegalArgumentException("Type \'" + type + "\' is not a Class, "
+          + "ParameterizedType, or GenericArrayType. Can't extract class.");
+    }
+  }
+
+  static Class<?> wrapWithArray(Class<?> rawClass) {
+    return Array.newInstance(rawClass, 0).getClass();
+  }
+
+  private TypeUtils() {
+    // Class with just some static utility methods, should not be instantiated
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/UpperCaseNamingPolicy.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/UpperCaseNamingPolicy.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/UpperCaseNamingPolicy.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+/**
+ * A {@link FieldNamingStrategy} that ensures the JSON field names consist of only
+ * upper case letters.
+ *
+ * <p>The following is an example:</p>
+ * <pre>
+ * class IntWrapper {
+ *   public int integerField = 0;
+ * }
+ *
+ * UpperCaseNamingPolicy policy = new UpperCaseNamingPolicy();
+ * String translatedFieldName =
+ *     policy.translateName(IntWrapper.class.getField("integerField"));
+ *
+ * assert("INTEGERFIELD".equals(translatedFieldName));
+ * </pre>
+ *
+ * @author Joel Leitch
+ */
+class UpperCaseNamingPolicy extends RecursiveFieldNamingPolicy {
+
+  @Override
+  protected String translateName(String target, Type fieldType, Annotation[] annotations) {
+    return target.toUpperCase();
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/VersionConstants.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/VersionConstants.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/VersionConstants.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+/**
+ * Class contain all constants for versioning support.
+ *
+ * @author Joel Leitch
+ */
+final class VersionConstants {
+  // Prevent instantiation
+  private VersionConstants() { }
+
+  static final double IGNORE_VERSIONS = -1D;
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/VersionExclusionStrategy.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/VersionExclusionStrategy.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/VersionExclusionStrategy.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008 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.gson;
+
+import com.google.gson.annotations.Since;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+
+/**
+ * This strategy will exclude any files and/or class that are passed the
+ * {@link #version} value.
+ *
+ * @author Joel Leitch
+ */
+final class VersionExclusionStrategy implements ExclusionStrategy {
+  private final double version;
+
+  public VersionExclusionStrategy(double version) {
+    Preconditions.checkArgument(version >= 0.0D);
+    this.version = version;
+  }
+
+  public boolean shouldSkipField(Field f) {
+    return !isValidVersion(f.getAnnotations());
+  }
+
+  public boolean shouldSkipClass(Class<?> clazz) {
+    return !isValidVersion(clazz.getAnnotations());
+  }
+
+  private boolean isValidVersion(Annotation[] annotations) {
+    for (Annotation annotation : annotations) {
+      if (annotation instanceof Since) {
+        double annotationVersion = ((Since) annotation).value();
+        if (annotationVersion > version) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/annotations/Expose.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/annotations/Expose.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/annotations/Expose.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2008 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.gson.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * An annotation that indicates this member should be exposed for JSON
+ * serialization or deserialization.
+ *
+ * <p>This annotation has no effect unless you build {@link com.google.gson.Gson}
+ * with a {@link com.google.gson.GsonBuilder} and invoke
+ * {@link com.google.gson.GsonBuilder#excludeFieldsWithoutExposeAnnotation()}
+ * method.</p>
+ *
+ * <p>Here is an example of how this annotation is meant to be used:
+ * <p><pre>
+ * public class User {
+ *   &#64Expose private String firstName;
+ *   &#64Expose private String lastName;
+ *   &#64Expose private String emailAddress;
+ *   private String password;
+ * }
+ * </pre></p>
+ * If you created Gson with {@code new Gson()}, the {@code toJson()} and {@code fromJson()}
+ * methods will use the {@code password} field along-with {@code firstName}, {@code lastName},
+ * and {@code emailAddress} for serialization and deserialization. However, if you created Gson
+ * with {@code Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()}
+ * then the {@code toJson()} and {@code fromJson()} methods of Gson will exclude the
+ * {@code password} field. This is because the {@code password} field is not marked with the
+ * {@code @Expose} annotation.
+ *
+ * <p>Note that another way to achieve the same effect would have been to just mark the
+ * {@code password} field as {@code transient}, and Gson would have excluded it even with default
+ * settings. The {@code @Expose} annotation is useful in a style of programming where you want to
+ * explicitly specify all fields that should get considered for serialization or deserialization.
+ *
+ * @author Inderjeet Singh
+ */
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target(ElementType.FIELD)
+public @interface Expose {
+  // This is a marker annotation with no additional properties
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/annotations/SerializedName.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/annotations/SerializedName.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/annotations/SerializedName.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2008 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.gson.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * An annotation that indicates this member should be serialized to JSON with
+ * the provided name value as its field name.
+ *
+ * <p>This annotation will override any {@link com.google.gson.FieldNamingPolicy}, including
+ * the default field naming policy, that may have been set on the {@link com.google.gson.Gson}
+ * instance.  A different naming policy can set using the {@code GsonBuilder} class.  See
+ * {@link com.google.gson.GsonBuilder#setFieldNamingPolicy(com.google.gson.FieldNamingPolicy)}
+ * for more information.</p>
+ *
+ * <p>Here is an example of how this annotation is meant to be used:</p>
+ * <pre>
+ * public class SomeClassWithFields {
+ *   &#64SerializedName("name") private final String someField;
+ *   private final String someOtherField;
+ *
+ *   public SomeClassWithFields(String a, String b) {
+ *     this.someField = a;
+ *     this.someOtherField = b;
+ *   }
+ * }
+ * </pre>
+ *
+ * <p>The following shows the output that is generated when serializing an instance of the
+ * above example class:</p>
+ * <pre>
+ * SomeClassWithFields objectToSerialize = new SomeClassWithFields("a", "b");
+ * Gson gson = new Gson();
+ * String jsonRepresentation = gson.toJson(objectToSerialize);
+ * System.out.println(jsonRepresentation);
+ *
+ * ===== OUTPUT =====
+ * {"name":"a","someOtherField":"b"}
+ * </pre>
+ *
+ * <p>NOTE: The value you specify in this annotation must be a valid JSON field name.</p>
+ *
+ * @see com.google.gson.FieldNamingPolicy
+ *
+ * @author Joel Leitch
+ */
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target(ElementType.FIELD)
+public @interface SerializedName {
+
+  /**
+   * @return the desired name of the field when it is serialized
+   */
+  String value();
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/annotations/Since.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/annotations/Since.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/annotations/Since.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 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.gson.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * An annotation that indicates the version number since a member or a type has been present.
+ * This annotation is useful to manage versioning of your Json classes for a web-service.
+ *
+ * <p>
+ * This annotation has no effect unless you build {@link com.google.gson.Gson} with a
+ * {@link com.google.gson.GsonBuilder} and invoke
+ * {@link com.google.gson.GsonBuilder#setVersion(double)} method.
+ *
+ * <p>Here is an example of how this annotation is meant to be used:</p>
+ * <pre>
+ * public class User {
+ *   private String firstName;
+ *   private String lastName;
+ *   &#64Since(1.0) private String emailAddress;
+ *   &#64Since(1.0) private String password;
+ *   &#64Since(1.1) private Address address;
+ * }
+ * </pre>
+ *
+ * <p>If you created Gson with {@code new Gson()}, the {@code toJson()} and {@code fromJson()}
+ * methods will use all the fields for serialization and deserialization. However, if you created
+ * Gson with {@code Gson gson = new GsonBuilder().setVersion(1.0).create()} the the
+ * {@code toJson()} and {@code fromJson()} methods of Gson will exclude the {@code address} field
+ * since it's version number is set to {@code 1.1}.</p>
+ *
+ * @author Inderjeet Singh
+ */
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target({ElementType.FIELD, ElementType.TYPE})
+public @interface Since {
+  /**
+   * the value indicating a version number since this member
+   * or type has been present.
+   */
+  double value();
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/annotations/package-info.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/annotations/package-info.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/annotations/package-info.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,6 @@
+/**
+ * This package provides annotations that can be used with {@link com.google.gson.Gson}.
+ * 
+ * @author Inderjeet Singh, Joel Leitch
+ */
+package com.google.gson.annotations;
\ No newline at end of file

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/package-info.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/package-info.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/package-info.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,11 @@
+/**
+ * This package provides the {@link com.google.gson.Gson} class to convert Json to Java and
+ * vice-versa.
+ *
+ * <p>The primary class to use is {@link com.google.gson.Gson} which can be constructed with
+ * {@code new Gson()} (using default settings) or by using {@link com.google.gson.GsonBuilder}
+ * (to configure various options such as using versioning and so on).</p>
+ *
+ * @author Inderjeet Singh, Joel Leitch
+ */
+package com.google.gson;
\ No newline at end of file

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/reflect/TypeToken.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/reflect/TypeToken.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/reflect/TypeToken.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2008 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.gson.reflect;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Represents a generic type {@code T}.
+ *
+ * You can use this class to get the generic type for a class. For example,
+ * to get the generic type for <code>Collection&lt;Foo&gt;</code>, you can use:
+ * <p>
+ * <code>Type typeOfCollectionOfFoo = new TypeToken&lt;Collection&lt;Foo&gt;&gt;(){}.getType()
+ * </code>
+ * 
+ * <p>Assumes {@code Type} implements {@code equals()} and {@code hashCode()}
+ * as a value (as opposed to identity) comparison.
+ *
+ * Also implements {@link #isAssignableFrom(Type)} to check type-safe
+ * assignability.
+ *
+ * @author Bob Lee
+ * @author Sven Mawson
+ */
+public abstract class TypeToken<T> {
+
+  final Class<? super T> rawType;
+  final Type type;
+
+  /**
+   * Constructs a new type token. Derives represented class from type
+   * parameter.
+   *
+   * <p>Clients create an empty anonymous subclass. Doing so embeds the type
+   * parameter in the anonymous class's type hierarchy so we can reconstitute
+   * it at runtime despite erasure.
+   *
+   * <p>For example:
+   * <code>
+   * {@literal TypeToken<List<String>> t = new TypeToken<List<String>>}(){}
+   * </code>
+   */
+  @SuppressWarnings("unchecked")
+  protected TypeToken() {
+    this.type = getSuperclassTypeParameter(getClass());
+    this.rawType = (Class<? super T>) getRawType(type);
+  }
+
+  /**
+   * Unsafe. Constructs a type token manually.
+   */
+  @SuppressWarnings({"unchecked"})
+  private TypeToken(Type type) {
+    this.rawType = (Class<? super T>) getRawType(nonNull(type, "type"));
+    this.type = type;
+  }
+
+  private static <T> T nonNull(T o, String message) {
+    if (o == null) {
+      throw new NullPointerException(message);
+    }
+    return o;
+  }
+  
+  /**
+   * Gets type from super class's type parameter.
+   */
+  static Type getSuperclassTypeParameter(Class<?> subclass) {
+    Type superclass = subclass.getGenericSuperclass();
+    if (superclass instanceof Class) {
+      throw new RuntimeException("Missing type parameter.");
+    }
+    return ((ParameterizedType) superclass).getActualTypeArguments()[0];
+  }
+
+  /**
+   * Gets type token from super class's type parameter.
+   */
+  static TypeToken<?> fromSuperclassTypeParameter(Class<?> subclass) {
+    return new SimpleTypeToken<Object>(subclass);
+  }
+
+  private static Class<?> getRawType(Type type) {
+    if (type instanceof Class<?>) {
+      // type is a normal class.
+      return (Class<?>) type;
+    } else if (type instanceof ParameterizedType) {
+      ParameterizedType parameterizedType = (ParameterizedType) type;
+
+      // I'm not exactly sure why getRawType() returns Type instead of Class.
+      // Neal isn't either but suspects some pathological case related
+      // to nested classes exists.
+      Type rawType = parameterizedType.getRawType();
+      if (rawType instanceof Class<?>) {
+        return (Class<?>) rawType;
+      }
+      throw buildUnexpectedTypeError(rawType, Class.class);
+    } else if (type instanceof GenericArrayType) {
+      GenericArrayType genericArrayType = (GenericArrayType) type;
+
+      // TODO(jleitch): This is not the most efficient way to handle generic
+      // arrays, but is there another way to extract the array class in a
+      // non-hacky way (i.e. using String value class names- "[L...")?
+      Object rawArrayType = Array.newInstance(
+          getRawType(genericArrayType.getGenericComponentType()), 0);
+      return rawArrayType.getClass();
+    } else {
+      throw buildUnexpectedTypeError(
+          type, ParameterizedType.class, GenericArrayType.class);
+    }
+  }
+
+  /**
+   * Gets the raw type.
+   */
+  public Class<? super T> getRawType() {
+    return rawType;
+  }
+
+  /**
+   * Gets underlying {@code Type} instance.
+   */
+  public Type getType() {
+    return type;
+  }
+
+  /**
+   * Check if this type is assignable from the given class object.
+   */
+  public boolean isAssignableFrom(Class<?> cls) {
+    return isAssignableFrom((Type) cls);
+  }
+
+  /**
+   * Check if this type is assignable from the given Type.
+   */
+  public boolean isAssignableFrom(Type from) {
+    if (from == null) {
+      return false;
+    }
+
+    if (type.equals(from)) {
+      return true;
+    }
+
+    if (type instanceof Class) {
+      return rawType.isAssignableFrom(getRawType(from));
+    } else if (type instanceof ParameterizedType) {
+      return isAssignableFrom(from, (ParameterizedType) type,
+          new HashMap<String, Type>());
+    } else if (type instanceof GenericArrayType) {
+      return rawType.isAssignableFrom(getRawType(from))
+          && isAssignableFrom(from, (GenericArrayType) type);
+    } else {
+      throw buildUnexpectedTypeError(
+          type, Class.class, ParameterizedType.class, GenericArrayType.class);
+    }
+  }
+
+  /**
+   * Check if this type is assignable from the given type token.
+   */
+  public boolean isAssignableFrom(TypeToken<?> token) {
+    return isAssignableFrom(token.getType());
+  }
+
+  /**
+   * Private helper function that performs some assignability checks for
+   * the provided GenericArrayType.
+   */
+  private static boolean isAssignableFrom(Type from, GenericArrayType to) {
+    Type toGenericComponentType = to.getGenericComponentType();
+    if (toGenericComponentType instanceof ParameterizedType) {
+      Type t = from;
+      if (from instanceof GenericArrayType) {
+        t = ((GenericArrayType) from).getGenericComponentType();
+      } else if (from instanceof Class) {
+        Class<?> classType = (Class<?>) from;
+        while (classType.isArray()) {
+          classType = classType.getComponentType();
+        }
+        t = classType;
+      }
+      return isAssignableFrom(t, (ParameterizedType) toGenericComponentType,
+          new HashMap<String, Type>());
+    }
+    // No generic defined on "to"; therefore, return true and let other
+    // checks determine assignability
+    return true;
+  }
+
+  /**
+   * Private recursive helper function to actually do the type-safe checking
+   * of assignability.
+   */
+  private static boolean isAssignableFrom(Type from, ParameterizedType to,
+      Map<String, Type> typeVarMap) {
+
+    if (from == null) {
+      return false;
+    }
+
+    if (to.equals(from)) {
+      return true;
+    }
+
+    // First figure out the class and any type information.
+    Class<?> clazz = getRawType(from);
+    ParameterizedType ptype = null;
+    if (from instanceof ParameterizedType) {
+      ptype = (ParameterizedType) from;
+    }
+
+    // Load up parameterized variable info if it was parameterized.
+    if (ptype != null) {
+      Type[] tArgs = ptype.getActualTypeArguments();
+      TypeVariable<?>[] tParams = clazz.getTypeParameters();
+      for (int i = 0; i < tArgs.length; i++) {
+        Type arg = tArgs[i];
+        TypeVariable<?> var = tParams[i];
+        while (arg instanceof TypeVariable) {
+          TypeVariable<?> v = (TypeVariable<?>) arg;
+          arg = typeVarMap.get(v.getName());
+        }
+        typeVarMap.put(var.getName(), arg);
+      }
+
+      // check if they are equivalent under our current mapping.
+      if (typeEquals(ptype, to, typeVarMap)) {
+        return true;
+      }
+    }
+
+    for (Type itype : clazz.getGenericInterfaces()) {
+      if (isAssignableFrom(itype, to, new HashMap<String, Type>(typeVarMap))) {
+        return true;
+      }
+    }
+
+    // Interfaces didn't work, try the superclass.
+    Type sType = clazz.getGenericSuperclass();
+    if (isAssignableFrom(sType, to, new HashMap<String, Type>(typeVarMap))) {
+      return true;
+    }
+
+    return false;
+  }
+
+  /**
+   * Checks if two parameterized types are exactly equal, under the variable
+   * replacement described in the typeVarMap.
+   */
+  private static boolean typeEquals(ParameterizedType from,
+      ParameterizedType to, Map<String, Type> typeVarMap) {
+    if (from.getRawType().equals(to.getRawType())) {
+      Type[] fromArgs = from.getActualTypeArguments();
+      Type[] toArgs = to.getActualTypeArguments();
+      for (int i = 0; i < fromArgs.length; i++) {
+        if (!matches(fromArgs[i], toArgs[i], typeVarMap)) {
+          return false;
+        }
+      }
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * Checks if two types are the same or are equivalent under a variable mapping
+   * given in the type map that was provided.
+   */
+  private static boolean matches(Type from, Type to,
+      Map<String, Type> typeMap) {
+    if (to.equals(from)) return true;
+
+    if (from instanceof TypeVariable) {
+      return to.equals(typeMap.get(((TypeVariable<?>)from).getName()));
+    }
+
+    return false;
+  }
+
+  /**
+   * Hashcode for this object.
+   * @return hashcode for this object.
+   */
+  @Override public int hashCode() {
+    return type.hashCode();
+  }
+
+  /**
+   * Method to test equality. 
+   * 
+   * @return true if this object is logically equal to the specified object, false otherwise.
+   */
+  @Override public boolean equals(Object o) {
+    if (o == this) {
+      return true;
+    }
+    if (!(o instanceof TypeToken<?>)) {
+      return false;
+    }
+    TypeToken<?> t = (TypeToken<?>) o;
+    return type.equals(t.type);
+  }
+
+  /**
+   * Returns a string representation of this object.
+   * @return a string representation of this object.
+   */
+  @Override public String toString() {
+    return type instanceof Class<?>
+        ? ((Class<?>) type).getName()
+        : type.toString();
+  }
+
+  private static AssertionError buildUnexpectedTypeError(
+      Type token, Class<?>... expected) {
+
+    // Build exception message
+    StringBuilder exceptionMessage =
+        new StringBuilder("Unexpected type. Expected one of: ");
+    for (Class<?> clazz : expected) {
+      exceptionMessage.append(clazz.getName()).append(", ");
+    }
+    exceptionMessage.append("but got: ").append(token.getClass().getName())
+        .append(", for type token: ").append(token.toString()).append('.');
+
+    return new AssertionError(exceptionMessage.toString());
+  }
+
+  /**
+   * Gets type token for the given {@code Type} instance.
+   */
+  public static TypeToken<?> get(Type type) {
+    return new SimpleTypeToken<Object>(type);
+  }
+
+  /**
+   * Gets type token for the given {@code Class} instance.
+   */
+  public static <T> TypeToken<T> get(Class<T> type) {
+    return new SimpleTypeToken<T>(type);
+  }
+
+  /**
+   * Private static class to not create more anonymous classes than
+   * necessary.
+   */
+  private static class SimpleTypeToken<T> extends TypeToken<T> {
+    public SimpleTypeToken(Type type) {
+      super(type);
+    }
+  }
+}

Added: projects/gwt-console/trunk/war/src/main/java/com/google/gson/reflect/package-info.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/com/google/gson/reflect/package-info.java	                        (rev 0)
+++ projects/gwt-console/trunk/war/src/main/java/com/google/gson/reflect/package-info.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -0,0 +1,6 @@
+/**
+ * This package provides utility classes for finding type information for generic types.
+ *  
+ * @author Inderjeet Singh, Joel Leitch
+ */
+package com.google.gson.reflect;
\ No newline at end of file

Modified: projects/gwt-console/trunk/war/src/main/java/org/jboss/bpm/console/client/model/DTOParser.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/org/jboss/bpm/console/client/model/DTOParser.java	2008-11-01 21:27:26 UTC (rev 2755)
+++ projects/gwt-console/trunk/war/src/main/java/org/jboss/bpm/console/client/model/DTOParser.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -25,6 +25,7 @@
 import org.jboss.bpm.console.client.model.forms.FieldDef;
 import org.jboss.bpm.console.client.model.forms.FormDef;
 import org.jboss.bpm.console.client.util.JSONWalk;
+import org.jboss.bpm.console.server.gson.GsonFactory;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -127,12 +128,10 @@
    }
 
    public static FormDef parseFormDef(JSONValue root)
-   {
-
-
+   { 
       // {"formName":"taskform-15",
       // "fields":[
-      //    {"varname":"amount","required":true,"inputType":"TEXT",
+      //    {"varname":"amount","label":"FirstName","required":true,"inputType":"TEXT",
       //    "dataTypeClass":"java.lang.String","defaults":[]}
       // ]}
 

Modified: projects/gwt-console/trunk/war/src/main/java/org/jboss/bpm/console/client/process/ProcessDefinitionList.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/org/jboss/bpm/console/client/process/ProcessDefinitionList.java	2008-11-01 21:27:26 UTC (rev 2755)
+++ projects/gwt-console/trunk/war/src/main/java/org/jboss/bpm/console/client/process/ProcessDefinitionList.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -25,6 +25,8 @@
 import com.gwtext.client.data.*;
 import com.gwtext.client.widgets.MessageBox;
 import com.gwtext.client.widgets.MessageBoxConfig;
+import com.gwtext.client.widgets.Component;
+import com.gwtext.client.widgets.event.PanelListenerAdapter;
 import com.gwtext.client.widgets.grid.ColumnConfig;
 import com.gwtext.client.widgets.grid.ColumnModel;
 import org.jboss.bpm.console.client.MainView;

Modified: projects/gwt-console/trunk/war/src/main/java/org/jboss/bpm/console/client/process/ProcessDefinitionListEditor.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/org/jboss/bpm/console/client/process/ProcessDefinitionListEditor.java	2008-11-01 21:27:26 UTC (rev 2755)
+++ projects/gwt-console/trunk/war/src/main/java/org/jboss/bpm/console/client/process/ProcessDefinitionListEditor.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -49,7 +49,7 @@
  */
 public class ProcessDefinitionListEditor extends Editor
 {
-   public final static String ID = "org.jboss.bpm.process.ProcessList";
+   public final static String ID = "org.jboss.bpm.process.ProcessDefinitionListEditor";
 
    private ProcessDefinitionList processDefinitionList;
 

Modified: projects/gwt-console/trunk/war/src/main/java/org/jboss/bpm/console/client/widgets/RemoteListView.java
===================================================================
--- projects/gwt-console/trunk/war/src/main/java/org/jboss/bpm/console/client/widgets/RemoteListView.java	2008-11-01 21:27:26 UTC (rev 2755)
+++ projects/gwt-console/trunk/war/src/main/java/org/jboss/bpm/console/client/widgets/RemoteListView.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -107,6 +107,7 @@
       {
          public boolean doBeforeRender(Component component)
          {
+            System.out.println("Reload store trigger");
             reloadStore();
             return true;
          }

Modified: projects/gwt-console/trunk/war/src/main/resources/org/jboss/bpm/console/Application.gwt.xml
===================================================================
--- projects/gwt-console/trunk/war/src/main/resources/org/jboss/bpm/console/Application.gwt.xml	2008-11-01 21:27:26 UTC (rev 2755)
+++ projects/gwt-console/trunk/war/src/main/resources/org/jboss/bpm/console/Application.gwt.xml	2008-11-04 10:09:12 UTC (rev 2756)
@@ -14,6 +14,7 @@
   <!-- Specify a css to load into your gwt application -->  
   <stylesheet src='console.css' />
   <stylesheet src="js/ext/resources/css/ext-all.css" />
+   
   <script src="js/ext/adapter/ext/ext-base.js" />
   <script src="js/ext/ext-all.js" />
   

Modified: projects/gwt-console/trunk/war/src/test/java/org/jboss/bpm/console/client/GwtTestApplication.java
===================================================================
--- projects/gwt-console/trunk/war/src/test/java/org/jboss/bpm/console/client/GwtTestApplication.java	2008-11-01 21:27:26 UTC (rev 2755)
+++ projects/gwt-console/trunk/war/src/test/java/org/jboss/bpm/console/client/GwtTestApplication.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -95,10 +95,8 @@
       final MainView view = application.getConsoleView();
       assertNotNull("View not initialized", view);
 
+      Timer verification = new Timer(){
 
-
-      Timer pdlTimer = new Timer(){
-
          public void run()
          {
             System.out.println("Verify process definition list");
@@ -107,16 +105,16 @@
 
             ProcessDefinitionList list = editor.getProcessDefinitionList();
 
-            System.out.println("Got " + list.getAvailableProcessDefinitions().size() + " definitions");
-            assertFalse("No process definitions loaded",
-                  list.getAvailableProcessDefinitions().isEmpty()
+            System.out.println("! Got " + list.getAvailableProcessDefinitions().size() + " definitions");
+            assertTrue("No process definitions loaded",
+                  list.getAvailableProcessDefinitions().size() != 0
             );
 
             finishTest();
          }
       };
 
-      Timer pdlLoadTimer = new Timer(){
+      Timer loading = new Timer(){
 
          public void run()
          {
@@ -129,7 +127,7 @@
          }
       };
 
-      Timer authTimer = new Timer()
+      Timer authentication = new Timer()
       {
          public void run()
          {
@@ -141,10 +139,10 @@
          }
       };
 
-      authTimer.schedule(200);
-      pdlLoadTimer.schedule(400);
-      pdlTimer.schedule(600);
+      authentication.schedule(500);
+      loading.schedule(1000);
+      verification.schedule(1500);
 
-      delayTestFinish(800);
+      delayTestFinish(2000);
    }
 }

Modified: projects/gwt-console/trunk/war/src/test/java/org/jboss/bpm/console/client/GwtTestDTOParser.java
===================================================================
--- projects/gwt-console/trunk/war/src/test/java/org/jboss/bpm/console/client/GwtTestDTOParser.java	2008-11-01 21:27:26 UTC (rev 2755)
+++ projects/gwt-console/trunk/war/src/test/java/org/jboss/bpm/console/client/GwtTestDTOParser.java	2008-11-04 10:09:12 UTC (rev 2756)
@@ -59,9 +59,23 @@
    {
       // {"formName":"taskform-15","fields":[{"varname":"amount","required":true,"inputType":"TEXT","dataTypeClass":"java.lang.String","defaults":[]},{"varname":"reason","required":true,"inputType":"TEXTAREA","dataTypeClass":"java.lang.String","defaults":[]}]}
 
-      String json = "{\"formName\":\"taskform-15\",\"fields\":[{\"varname\":\"amount\",\"required\":true,\"inputType\":\"TEXT\",\"dataTypeClass\":\"java.lang.String\",\"defaults\":[]},{\"varname\":\"reason\",\"required\":true,\"inputType\":\"TEXTAREA\",\"dataTypeClass\":\"java.lang.String\",\"defaults\":[]}]}";
+      String json = "{\"formName\":\"taskform-14\",\"fields\":[{\"label\":\"Amount:\",\"varname\":\"amount\",\"required\":true,\"inputType\":\"TEXT\",\"dataTypeClass\":\"java.lang.String\",\"defaults\":[]}]}";
+
+      /*
+      TODO: clean source code imports into GWT
+
+      FormDef form = new FormDef("myform-14");
+      form.getFields().add( new FieldDef(
+            "FirstName", "firstname",
+            FieldDef.InputType.TEXT, String.class.getName(),
+            true
+      ) );
+
+      String json = getGSONParser().toJson(form);
+      System.out.println("!!! " + json);
+      */
+
       FormDef formDef = DTOParser.parseFormDef(json);
-      System.out.println("!!!" + formDef.getFormName());
       System.out.println(formDef.getFields());
    }
 }




More information about the jbpm-commits mailing list