<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>src/com/google/wave/api/AbstractRobot.java</filename>
    </added>
    <added>
      <filename>src/com/google/wave/api/Capability.java</filename>
    </added>
    <added>
      <filename>src/com/google/wave/api/impl/JsonRpcConstant.java</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -166,4 +166,23 @@ public class Annotation {
 
     return name.equals(other.name) &amp;&amp; range.equals(other.range) &amp;&amp; value.equals(other.value);
   }
+  
+  @Override
+  public String toString() {
+    StringBuilder res = new StringBuilder(&quot;Annotation(&quot;);
+    if (name != null) {
+      res.append(name);
+      res.append(',');
+    }
+    if (value != null) {
+      res.append(value);
+      res.append(',');
+    }
+    if (range != null) {
+      res.append(range.toString());
+    }
+    res.append(')');
+    return res.toString();
+  }
+
 }</diff>
      <filename>src/com/google/wave/api/Annotation.java</filename>
    </modified>
    <modified>
      <diff>@@ -22,8 +22,8 @@ import java.util.Map;
  * Elements are non-text content within a document. What the represent is
  * generally abstracted from the Robot. Although a Robot can query the
  * properties of an element it can only interact with the specific types that
- * the element represents.  
- * 
+ * the element represents.
+ *
  * @author scovitz@google.com (Seth Covitz)
  * @author mprasetya@google.com (Marcel Prasetya)
  */
@@ -33,101 +33,118 @@ public class Element {
    * The type of an element.
    */
   private ElementType type;
-  
+
   /**
    * A map of properties representing details of the element.
    */
-  private Map&lt;String, Object&gt; properties;
+  private Map&lt;String, String&gt; properties;
 
   /**
    * Constructs an empty Element.
    */
   public Element() {
     this.type = null;
-    this.properties = new HashMap&lt;String, Object&gt;();
+    this.properties = new HashMap&lt;String, String&gt;();
   }
-  
+
   /**
    * Creates a copy of an element.
-   * 
+   *
    * @param element the element to copy.
    */
   public Element(Element element) {
     this.type = element.getType();
-    this.properties = new HashMap&lt;String, Object&gt;(element.getProperties());
+    this.properties = new HashMap&lt;String, String&gt;(element.getProperties());
   }
 
   /**
    * Returns the type of the element.
-   * 
+   *
    * @return the type of the element.
    */
   public ElementType getType() {
     return type;
   }
-  
+
   /**
    * Returns the map of properties for this element.
-   * 
+   *
    * @return the map of properties for this element.
    */
-  public Map&lt;String, Object&gt; getProperties() {
+  public Map&lt;String, String&gt; getProperties() {
     return properties;
   }
-  
+
   /**
    * Constructs an Element of the given type.
-   * 
+   *
    * @param type the type of elment to construct.
    */
   public Element(ElementType type) {
     this.type = type;
-    this.properties = new HashMap&lt;String, Object&gt;();
+    this.properties = new HashMap&lt;String, String&gt;();
   }
-  
+
   /**
    * Constructs an Element of the given type with an initial set of properties.
-   * 
+   *
    * @param type the type of the element.
    * @param properties the properties of the element.
    */
-  public Element(ElementType type, Map&lt;String, Object&gt; properties) {
+  public Element(ElementType type, Map&lt;String, String&gt; properties) {
     this.type = type;
     this.properties = properties;
   }
-  
+
   /**
    * Replaces the properties of this element with a new set of properties.
-   * 
+   *
    * @param properties the properties to be set on this element.
    */
-  public void setProperties(Map&lt;String, Object&gt; properties) {
+  public void setProperties(Map&lt;String, String&gt; properties) {
     this.properties = properties;
   }
-  
+
   /**
    * Creates/replaces a property with the given to a new value.
-   * 
+   *
    * @param name the name of the property to create/replace.
    * @param value the value to be set on this property.
    */
   public void setProperty(String name, String value) {
     this.properties.put(name, value);
   }
-  
+
   /**
    * Returns the named property of this element.
-   * 
+   *
    * @param name the name of the property.
    * @return the value of the property or null if the property was not found.
    */
-  public Object getProperty(String name) {
-    return this.properties.get(name);
+  public String getProperty(String name) {
+    return getProperty(name, null);
   }
-  
+
+  /**
+   * Returns the named property of this element, or the default value if the
+   * property was not found.
+   *
+   * @param name the name of the property.
+   * @param defaultValue the default value of the property.
+   * @return the value of the property or the default value if the property was
+   *     not found.
+   */
+  public String getProperty(String name, String defaultValue) {
+    String property = this.properties.get(name);
+    if (property != null) {
+      return property;
+    }
+    return defaultValue;
+  }
+
   /**
    * Sets the type of this Element.
-   * 
+   *
    * @param type the type of the element.
    */
   public void setType(ElementType type) {
@@ -136,7 +153,7 @@ public class Element {
 
   /**
    * Returns whether this element is a form element.
-   * 
+   *
    * @return true if the element is a form element, false otherwise.
    */
   public boolean isFormElement() {
@@ -150,31 +167,36 @@ public class Element {
         type == ElementType.RADIO_BUTTON_GROUP ||
         type == ElementType.TEXTAREA;
   }
-  
+
   /**
    * Returns whether this element is a gadget.
-   * 
+   *
    * @return true if the element is a gadget, false otherwise.
    */
   public boolean isGadget() {
     return type == ElementType.GADGET;
   }
-  
+
   /**
    * Returns whether this element is an inline blip.
-   * 
+   *
    * @return true if the element is an inline blip, false otherwise.
    */
   public boolean isInlineBlip() {
     return type == ElementType.INLINE_BLIP;
   }
-  
+
   /**
    * Returns whether this element is an image.
-   * 
+   *
    * @return true if the element is an image, false otherwise.
    */
   public boolean isImage() {
     return type == ElementType.IMAGE;
   }
+
+  @Override
+  public String toString() {
+    return &quot;{'type':'&quot; + type + &quot;','properties':&quot; + properties + &quot;}&quot;;
+  }
 }</diff>
      <filename>src/com/google/wave/api/Element.java</filename>
    </modified>
    <modified>
      <diff>@@ -44,9 +44,6 @@ public enum ElementType {
     this.text = text;
   }
   
-  /* (non-Javadoc)
-   * @see java.lang.Enum#toString()
-   */
   @Override
   public String toString() {
     return text;</diff>
      <filename>src/com/google/wave/api/ElementType.java</filename>
    </modified>
    <modified>
      <diff>@@ -18,56 +18,56 @@ package com.google.wave.api;
 /**
  * Form Elements allow users and robots to build forms for other users to
  * interact with. For each element you can specify its type, name, a default
- * value and a label. The current value of the element is stored with in.  
- * 
+ * value and a label. The current value of the element is stored with in.
+ *
  * @author scovitz@google.com (Seth Covitz)
  * @author mprasetya@google.com (Marcel Prasetya)
  */
 public class FormElement extends Element {
-  
+
   /**
    * Default Constructor
    */
   public FormElement() {
   }
-  
+
   /**
    * Constructs a form element of the given type.
    */
   public FormElement(ElementType type) {
     this(type, &quot;&quot;, &quot;&quot;, &quot;&quot;, &quot;&quot;);
   }
-  
+
   /**
    * Constructs a form element given a type and name.
    */
   public FormElement(ElementType type, String name) {
     this(type, &quot;&quot;, name, &quot;&quot;, &quot;&quot;);
   }
-  
+
   /**
    * Constructs a form element given a type, name and default value.
    */
   public FormElement(ElementType type, String name, String defaultValue) {
     this(type, &quot;&quot;, name, defaultValue, defaultValue);
   }
-  
+
   /**
    * Constructs a form element given a type, label, name and default value.
    */
   public FormElement(ElementType type, String label, String name, String defaultValue) {
     this(type, label, name, defaultValue, defaultValue);
   }
-  
+
   /**
    * Creates a copy of an existing form element.
    */
   public FormElement(FormElement formElement) {
     this(formElement.getType(),
-        (String) formElement.getProperty(&quot;label&quot;),
-        (String) formElement.getProperty(&quot;name&quot;),
-        (String) formElement.getProperty(&quot;defaultValue&quot;),
-        (String) formElement.getProperty(&quot;value&quot;));
+        formElement.getProperty(&quot;label&quot;),
+        formElement.getProperty(&quot;name&quot;),
+        formElement.getProperty(&quot;defaultValue&quot;),
+        formElement.getProperty(&quot;value&quot;));
   }
 
   /**
@@ -84,7 +84,7 @@ public class FormElement extends Element {
 
   /**
    * Returns the label for the form element.
-   * 
+   *
    * @return the label for the form element.
    */
   public String getLabel() {
@@ -93,7 +93,7 @@ public class FormElement extends Element {
 
   /**
    * Sets the label text for the form element.
-   * 
+   *
    * @param label the new label for the form element.
    */
   public void setLabel(String label) {
@@ -102,7 +102,7 @@ public class FormElement extends Element {
 
   /**
    * Returns the name of the form element.
-   * 
+   *
    * @return the name of the form element.
    */
   public String getName() {
@@ -110,13 +110,13 @@ public class FormElement extends Element {
   }
 
   private String getPropertyNullCheck(String name) {
-    String property = (String) getProperty(name);
+    String property = getProperty(name);
     return property == null ? &quot;&quot; : property;
   }
 
   /**
    * Sets the name of the form element.
-   * 
+   *
    * @param name the new name of the form element.
    */
   public void setName(String name) {
@@ -125,7 +125,7 @@ public class FormElement extends Element {
 
   /**
    * Returns the default value of the form element.
-   * 
+   *
    * @return the default value.
    */
   public String getDefaultValue() {
@@ -136,7 +136,7 @@ public class FormElement extends Element {
    * Sets the default value of the form element. The default value is used
    * to initialize the form element and to test whether or not it has been
    * modified.
-   * 
+   *
    * @param defaultValue the new default value of the form element.
    */
   public void setDefaultValue(String defaultValue) {
@@ -145,7 +145,7 @@ public class FormElement extends Element {
 
   /**
    * Returns the current value of the form element.
-   * 
+   *
    * @return the current value of the form element.
    */
   public String getValue() {
@@ -154,10 +154,10 @@ public class FormElement extends Element {
 
   /**
    * Sets the value of the form element.
-   * 
+   *
    * @param value the new value of the form element.
    */
   public void setValue(String value) {
     setProperty(&quot;value&quot;, value);
-  }  
+  }
 }</diff>
      <filename>src/com/google/wave/api/FormElement.java</filename>
    </modified>
    <modified>
      <diff>@@ -19,8 +19,8 @@ package com.google.wave.api;
  * Gadgets are external code that can be executed within a protected
  * environment within a Wave. Gadgets are indentified by the url that points to
  * their gadget specification. Gadgets can also maintain state that both they
- * and Robots can modify.  
- * 
+ * and Robots can modify.
+ *
  * @author scovitz@google.com (Seth Covitz)
  * @author mprasetya@google.com (Marcel Prasetya)
  */
@@ -33,10 +33,10 @@ public class Gadget extends Element {
     super(ElementType.GADGET);
     setUrl(&quot;&quot;);
   }
-  
+
   /**
    * Constructs a gadget for the specified url.
-   *  
+   *
    * @param url the url of the gadget specification.
    */
   public Gadget(String url) {
@@ -46,40 +46,40 @@ public class Gadget extends Element {
 
   /**
    * Returns the URL for the gadget.
-   * 
+   *
    * @return the URL for the gadget.
    */
   public String getUrl() {
-    return (String) getProperty(&quot;url&quot;);
+    return getProperty(&quot;url&quot;);
   }
-  
+
   /**
    * Changes the URL for the gadget to the given url. This will cause the new
    * gadget to be initialized and loaded.
-   * 
+   *
    * @param url the new gadget url.
    */
   public void setUrl(String url) {
     setProperty(&quot;url&quot;, url);
   }
-  
+
   /**
    * Deletes the field represented by the given key from the gadget's state.
-   * 
+   *
    * @param key The key that identifies the field.
    */
   public void deleteField(String key) {
     getProperties().remove(key);
   }
-  
+
   /**
    * Returns the value of the field with the given key.
-   * 
+   *
    * @param key The key that identifies the field.
    * @return The value of the field.
    */
   public String getField(String key) {
-    return (String) getProperty(key);
+    return getProperty(key);
   }
 
   /**</diff>
      <filename>src/com/google/wave/api/Gadget.java</filename>
    </modified>
    <modified>
      <diff>@@ -17,10 +17,10 @@ package com.google.wave.api;
 
 /**
  * Represents an image within a Wave. The image can either refer to an external
- * resource or a Wave attachment. An external image is defined by the 'url' 
+ * resource or a Wave attachment. An external image is defined by the 'url'
  * property, while the Wave attachment is defined by the 'attachmentId'
  * property.
- * 
+ *
  * @author scovitz@google.com (Seth Covitz)
  * @author mprasetya@google.com (Marcel Prasetya)
  */
@@ -32,10 +32,10 @@ public class Image extends Element {
   public Image() {
     super(ElementType.IMAGE);
   }
-  
+
   /**
    * Constructs a Wave image given an attachment id and a caption.
-   * 
+   *
    * @param attachmentId the attachment id of the wave image.
    * @param caption the captopm for the image.
    */
@@ -44,10 +44,10 @@ public class Image extends Element {
     setAttachmentId(attachmentId);
     setCaption(caption);
   }
-  
+
   /**
    * Constructs an external image given a url, image dimensions, and a caption.
-   * 
+   *
    * @param url the url for the external image.
    * @param width the width of the image.
    * @param height the height of the image.
@@ -60,95 +60,95 @@ public class Image extends Element {
     setHeight(height);
     setCaption(caption);
   }
-  
+
   /**
    * Returns the URL for the image.
-   * 
+   *
    * @return the URL for the image.
    */
   public String getUrl() {
-    return (String) getProperty(&quot;url&quot;);
+    return getProperty(&quot;url&quot;);
   }
-  
+
   /**
    * Changes the URL for the image to the given url. This will cause the new
    * image to be initialized and loaded.
-   * 
+   *
    * @param url the new image url.
    */
   public void setUrl(String url) {
     setProperty(&quot;url&quot;, url);
   }
-  
+
   /**
    * Sets the fixed width of the image to be displayed.
-   * 
+   *
    * @param width the fixed width of the image.
    */
   public void setWidth(int width) {
     setProperty(&quot;width&quot;, Integer.toString(width));
   }
-  
+
   /**
    * Returns the fixed width of the image.
-   * 
+   *
    * @return the fixed width of the image or -1 if no width was specified.
    */
   public int getWidth() {
-    return getProperty(&quot;width&quot;) == null ? -1 : Integer.parseInt((String) getProperty(&quot;width&quot;));
+    return getProperty(&quot;width&quot;) == null ? -1 : Integer.parseInt(getProperty(&quot;width&quot;));
   }
-  
+
   /**
    * Sets the fixed height of the image to be displayed.
-   * 
-   * @param height the fixed height of the image. 
+   *
+   * @param height the fixed height of the image.
    */
   public void setHeight(int height) {
     setProperty(&quot;height&quot;, Integer.toString(height));
   }
-  
+
   /**
    * Returns the fixed height of the image.
-   * 
+   *
    * @return the fixed height of the image or -1 if no height was specified.
    */
   public int getHeight() {
-    return getProperty(&quot;height&quot;) == null ? -1 : Integer.parseInt((String) getProperty(&quot;height&quot;));
+    return getProperty(&quot;height&quot;) == null ? -1 : Integer.parseInt(getProperty(&quot;height&quot;));
   }
-  
+
   /**
    * Sets the attacmentId for the Wave image.
-   * 
+   *
    * @param attachmentId the attachment id for the image.
    */
   public void setAttachmentId(String attachmentId) {
     setProperty(&quot;attachmentId&quot;, attachmentId);
   }
-  
+
   /**
    * Returns the attachmentId for the image.
-   * 
+   *
    * @return the attachmentId for the image.
    */
   public String getAttachmentId() {
-    return (String) getProperty(&quot;attachmentId&quot;); 
+    return getProperty(&quot;attachmentId&quot;);
   }
-  
+
   /**
    * Sets the caption for the image.
-   * 
+   *
    * @param caption the caption to display for the image.
    */
   public void setCaption(String caption) {
     setProperty(&quot;caption&quot;, caption);
   }
-  
+
   /**
    * Returns the caption for the image.
-   * 
+   *
    * @return the caption for the image.
    */
   public String getCaption() {
-    return (String) getProperty(&quot;caption&quot;);
+    return getProperty(&quot;caption&quot;);
   }
 }</diff>
      <filename>src/com/google/wave/api/Image.java</filename>
    </modified>
    <modified>
      <diff>@@ -47,13 +47,8 @@ public class Range {
    * @param end End of the range.
    */
   public Range(int start, int end) {
-    // TODO(scovitz): Figure out why Spelly generates zero length range here.
-//    if (end - start &lt;= 0) {
-//      throw new RuntimeException(&quot;Range length cannot be zero or negative.&quot;);
-//    } else {
-      this.start = start;
-      this.end = end;
-//    }
+    this.start = start;
+    this.end = end;
   }
 
   /**
@@ -118,4 +113,9 @@ public class Range {
     Range other = (Range) obj;
     return start == other.start &amp;&amp; end == other.end;
   }
+  
+  @Override
+  public String toString() {
+    return &quot;Range(&quot; + start + ',' + end + ')';
+  }
 }</diff>
      <filename>src/com/google/wave/api/Range.java</filename>
    </modified>
    <modified>
      <diff>@@ -34,7 +34,7 @@ import java.util.Map;
 
 /**
  * {@link Element} serialization/deserialization.
- * 
+ *
  * @author scovitz@google.com (Seth Covitz)
  */
 @SuppressWarnings(&quot;unchecked&quot;)
@@ -59,7 +59,7 @@ public class ElementSerializer extends AbstractSerializer {
     if (!(o instanceof Element)) {
       throw new MarshallException(&quot;Object is not of type Element.&quot;);
     }
-    
+
     JSONObject json = new JSONObject();
     Element element = (Element) o;
     try {
@@ -69,7 +69,7 @@ public class ElementSerializer extends AbstractSerializer {
     } catch (JSONException jsonx) {
       throw new MarshallException(&quot;Cannot marshall Element.&quot;);
     }
-    
+
     return json;
   }
 
@@ -84,16 +84,16 @@ public class ElementSerializer extends AbstractSerializer {
     if (!Element.class.isAssignableFrom(clazz)) {
       throw new UnmarshallException(clazz.getName() + &quot; is not assignable from Element&quot;);
     }
-    
+
     JSONObject jsonObject = (JSONObject) json;
     Element element = null;
     try {
       String javaname = jsonObject.isNull(&quot;name&quot;) ? &quot;&quot; : jsonObject.getString(&quot;name&quot;);
       element = (Element) clazz.newInstance();
       element.setType(ElementType.valueOf(jsonObject.getString(&quot;type&quot;)));
-      element.setProperties((Map&lt;String, Object&gt;) ser.unmarshall(state, Map.class,
+      element.setProperties((Map&lt;String, String&gt;) ser.unmarshall(state, Map.class,
           jsonObject.getJSONObject(&quot;properties&quot;)));
- 
+
     } catch (InstantiationException e) {
       e.printStackTrace();
     } catch (IllegalAccessException e) {
@@ -101,7 +101,7 @@ public class ElementSerializer extends AbstractSerializer {
     } catch (JSONException jsonx) {
       jsonx.printStackTrace();
     }
-    
+
     return element;
   }
 }</diff>
      <filename>src/com/google/wave/api/impl/ElementSerializer.java</filename>
    </modified>
    <modified>
      <diff>@@ -15,53 +15,96 @@
 
 package com.google.wave.api.impl;
 
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Logger;
+
 /**
  * The Operation types supported by Robots.
- * 
+ *
  * @author scovitz@google.com (Seth Covitz)
  * @author mprasetya@google.com (Marcel Prasetya)
  */
 public enum OperationType {
-  WAVELET_APPEND_BLIP(&quot;WAVELET_APPEND_BLIP&quot;),
-  WAVELET_ADD_PARTICIPANT(&quot;WAVELET_ADD_PARTICIPANT&quot;),
-  WAVELET_REMOVE_PARTICIPANT(&quot;WAVELET_REMOVE_PARTICIPANT&quot;),
-  WAVELET_CREATE(&quot;WAVELET_CREATE&quot;),
-  WAVELET_DATADOC_APPEND(&quot;WAVELET_DATADOC_APPEND&quot;),
-  WAVELET_DATADOC_SET(&quot;WAVELET_DATADOC_SET&quot;),
-  WAVELET_REMOVE_SELF(&quot;WAVELET_REMOVE_SELF&quot;),
-  WAVELET_SET_TITLE(&quot;WAVELET_SET_TITLE&quot;),
-  BLIP_CREATE_CHILD(&quot;BLIP_CREATE_CHILD&quot;),
-  BLIP_DELETE(&quot;BLIP_DELETE&quot;),
-  BLIP_SET_AUTHOR(&quot;BLIP_SET_AUTHOR&quot;),
-  BLIP_SET_CREATION_TIME(&quot;BLIP_SET_CREATION_TIME&quot;),
-  DOCUMENT_ANNOTATION_DELETE(&quot;DOCUMENT_ANNOTATION_DELETE&quot;),
-  DOCUMENT_ANNOTATION_SET(&quot;DOCUMENT_ANNOTATION_SET&quot;),
-  DOCUMENT_ANNOTATION_SET_NORANGE(&quot;DOCUMENT_ANNOTATION_SET_NORANGE&quot;),
-  DOCUMENT_APPEND(&quot;DOCUMENT_APPEND&quot;),
-  DOCUMENT_APPEND_MARKUP(&quot;DOCUMENT_APPEND_MARKUP&quot;),
-  DOCUMENT_APPEND_STYLED_TEXT(&quot;DOCUMENT_APPEND_STYLED_TEXT&quot;),
-  DOCUMENT_INSERT(&quot;DOCUMENT_INSERT&quot;),
-  DOCUMENT_DELETE(&quot;DOCUMENT_DELETE&quot;),
-  DOCUMENT_REPLACE(&quot;DOCUMENT_REPLACE&quot;),
-  DOCUMENT_ELEMENT_APPEND(&quot;DOCUMENT_ELEMENT_APPEND&quot;),
-  DOCUMENT_ELEMENT_DELETE(&quot;DOCUMENT_ELEMENT_DELETE&quot;),
-  DOCUMENT_ELEMENT_INSERT(&quot;DOCUMENT_ELEMENT_INSERT&quot;),
-  DOCUMENT_ELEMENT_INSERT_AFTER(&quot;DOCUMENT_ELEMENT_INSERT_AFTER&quot;),
-  DOCUMENT_ELEMENT_INSERT_BEFORE(&quot;DOCUMENT_ELEMENT_INSERT_BEFORE&quot;),
-  DOCUMENT_ELEMENT_REPLACE(&quot;DOCUMENT_ELEMENT_REPLACE&quot;),
-  DOCUMENT_INLINE_BLIP_APPEND(&quot;DOCUMENT_INLINE_BLIP_APPEND&quot;),
-  DOCUMENT_INLINE_BLIP_DELETE(&quot;DOCUMENT_INLINE_BLIP_DELETE&quot;),
-  DOCUMENT_INLINE_BLIP_INSERT(&quot;DOCUMENT_INLINE_BLIP_INSERT&quot;),
-  DOCUMENT_INLINE_BLIP_INSERT_AFTER_ELEMENT(&quot;DOCUMENT_INLINE_BLIP_INSERT_AFTER_ELEMENT&quot;);
-  
-  private final String text;
-  
-  private OperationType(String text) {
-    this.text = text;
+  WAVELET_APPEND_BLIP(&quot;wavelet.appendBlip&quot;),
+  WAVELET_CREATE(&quot;wavelet.create&quot;),
+  WAVELET_REMOVE_SELF(&quot;wavelet.removeSelf&quot;),
+  WAVELET_SET_TITLE(&quot;wavelet.setTitle&quot;),
+
+  WAVELET_ADD_PARTICIPANT(&quot;wavelet.participant.add&quot;),
+  WAVELET_REMOVE_PARTICIPANT(&quot;wavelet.participant.remove&quot;),
+
+  WAVELET_DATADOC_APPEND(&quot;wavelet.datadoc.append&quot;),
+  WAVELET_DATADOC_SET(&quot;wavelet.datadoc.set&quot;),
+
+  BLIP_CREATE_CHILD(&quot;blip.createChild&quot;),
+  BLIP_DELETE(&quot;blip.delete&quot;),
+  BLIP_SET_AUTHOR(&quot;blip.setAuthor&quot;),
+  BLIP_SET_CREATION_TIME(&quot;blip.setCreationTime&quot;),
+
+  DOCUMENT_ANNOTATION_DELETE(&quot;document.annotation.delete&quot;),
+  DOCUMENT_ANNOTATION_SET(&quot;document.annotation.set&quot;),
+  DOCUMENT_ANNOTATION_SET_NORANGE(&quot;document.annotation.setNoRange&quot;),
+
+  DOCUMENT_APPEND(&quot;document.append&quot;),
+  DOCUMENT_APPEND_MARKUP(&quot;document.appendMarkup&quot;),
+  DOCUMENT_APPEND_STYLED_TEXT(&quot;document.appendStyledText&quot;),
+  DOCUMENT_INSERT(&quot;document.insert&quot;),
+  DOCUMENT_DELETE(&quot;document.delete&quot;),
+  DOCUMENT_REPLACE(&quot;document.replace&quot;),
+
+  DOCUMENT_ELEMENT_APPEND(&quot;document.element.append&quot;),
+  DOCUMENT_ELEMENT_DELETE(&quot;document.element.delete&quot;),
+  DOCUMENT_ELEMENT_INSERT(&quot;document.element.insert&quot;),
+  DOCUMENT_ELEMENT_INSERT_AFTER(&quot;document.element.insertAfter&quot;),
+  DOCUMENT_ELEMENT_INSERT_BEFORE(&quot;document.element.insertBefore&quot;),
+  DOCUMENT_ELEMENT_MODIFY_ATTRS(&quot;document.element.modifyAttrs&quot;),
+  DOCUMENT_ELEMENT_REPLACE(&quot;document.element.replace&quot;),
+
+  DOCUMENT_INLINE_BLIP_APPEND(&quot;document.inlineBlip.append&quot;),
+  DOCUMENT_INLINE_BLIP_DELETE(&quot;document.inlineBlip.delete&quot;),
+  DOCUMENT_INLINE_BLIP_INSERT(&quot;document.inlineBlip.insert&quot;),
+  DOCUMENT_INLINE_BLIP_INSERT_AFTER_ELEMENT(&quot;document.inlineBlip.insertAfterElement&quot;),
+
+  ROBOT_NOTIFY_CAPABILITIES_HASH(&quot;robot.notifyCapabilitiesHash&quot;);
+
+  private static final Logger LOG = Logger.getLogger(OperationType.class.getName());
+
+  private static final Map&lt;String, OperationType&gt; reverseLookupMap =
+      new HashMap&lt;String, OperationType&gt;();
+
+  static {
+    for (OperationType operationType : OperationType.values()) {
+      if (reverseLookupMap.containsKey(operationType.method)) {
+        LOG.warning(&quot;Operation with method name &quot; + operationType.method + &quot; already exist.&quot;);
+      }
+      reverseLookupMap.put(operationType.method, operationType);
+    }
   }
-  
-  @Override
-  public String toString() {
-    return text;
+
+  private final String method;
+
+  private OperationType(String method) {
+    this.method = method;
+  }
+
+  /**
+   * Returns the method name of an operation type.
+   *
+   * @return The method name of an operation type.
+   */
+  public String method() {
+    return method;
+  }
+
+  /**
+   * Returns an {@link OperationType} enumeration that has the given method
+   * name.
+   *
+   * @param methodName The method name of an operation.
+   * @return An {@link OperationType} that has the given method name.
+   */
+  public static OperationType fromMethodName(String methodName) {
+    return reverseLookupMap.get(methodName);
   }
 }</diff>
      <filename>src/com/google/wave/api/impl/OperationType.java</filename>
    </modified>
    <modified>
      <diff>@@ -48,7 +48,7 @@ public class TextViewImpl implements TextView {
       return matchRange(annotation) &amp;&amp; matchContent(annotation);
     }
     
-    public boolean matchRange(Annotation annotation) {
+    public boolean matchRange(@SuppressWarnings(&quot;unused&quot;) Annotation annotation) {
       return true;
     }
     
@@ -135,7 +135,7 @@ public class TextViewImpl implements TextView {
     int start = range.getStart();
     int end = range.getEnd();
     
-    if (start &lt; 0 || end &gt;= blipData.getContent().length() || start &gt;= end) {
+    if (start &lt; 0 || end &gt; blipData.getContent().length() || start &gt;= end) {
       throw new IndexOutOfBoundsException(&quot;Invalid range &quot; + start + &quot; - &quot; + end);
     }
     
@@ -402,22 +402,16 @@ public class TextViewImpl implements TextView {
         length, element));
     
     blipData.addElement(length, element);
-    if (element.getType().equals(ElementType.INPUT)) {
-      blipData.setContent(blipData.getContent().concat(&quot; &quot;));
-      expandOrShiftAnnotations(length - 1, 1);
-    } else {
-      blipData.setContent(blipData.getContent().concat(&quot; \n&quot;));      
-      expandOrShiftAnnotations(length - 1, 2);
-    }
+    blipData.setContent(blipData.getContent().concat(&quot; &quot;));
+    expandOrShiftAnnotations(length - 1, 1);
   }
 
   @Override
   public List&lt;Element&gt; getElements() {
     if (blipData != null &amp;&amp; blipData.getElements() != null) {
       return new ArrayList&lt;Element&gt;(blipData.getElements().values());
-    } else {
-      return null;
     }
+    return null;
   }
 
   @Override</diff>
      <filename>src/com/google/wave/api/impl/TextViewImpl.java</filename>
    </modified>
    <modified>
      <diff>@@ -23,7 +23,7 @@ import java.util.Map;
 /**
  * The data representation of Wavelet metadata used to serialize and send to
  * the Robot.
- * 
+ *
  * @author scovitz@google.com (Seth Covitz)
  */
 public class WaveletData {
@@ -51,7 +51,7 @@ public class WaveletData {
     waveletId = null;
     dataDocuments = new HashMap&lt;String, String&gt;();
   }
-  
+
   public WaveletData(WaveletData wavelet) {
     this.creationTime = wavelet.getCreationTime();
     this.creator = wavelet.getCreator();
@@ -84,7 +84,7 @@ public class WaveletData {
   public String getRootBlipId() {
     return rootBlipId;
   }
-  
+
   public String getTitle() {
     return title;
   }
@@ -96,7 +96,7 @@ public class WaveletData {
   public String getWaveId() {
     return waveId;
   }
-  
+
   public String getWaveletId() {
     return waveletId;
   }
@@ -120,7 +120,7 @@ public class WaveletData {
   public void setRootBlipId(String rootBlipId) {
     this.rootBlipId = rootBlipId;
   }
-  
+
   public void setTitle(String title) {
     this.title = title;
   }
@@ -128,7 +128,7 @@ public class WaveletData {
   public void setVersion(long version) {
     this.version = version;
   }
-  
+
   public void setWaveId(String waveId) {
     this.waveId = waveId;
   }
@@ -148,7 +148,7 @@ public class WaveletData {
   public void setDataDocument(String name, String data) {
     dataDocuments.put(name, data);
   }
-  
+
   public String getDataDocument(String name) {
     if (dataDocuments == null) {
       return null;
@@ -156,4 +156,8 @@ public class WaveletData {
       return dataDocuments.get(name);
     }
   }
+
+  public void addParticipant(String participant) {
+    participants.add(participant);
+  }
 }</diff>
      <filename>src/com/google/wave/api/impl/WaveletData.java</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>0a83c47caad08fdebbaba9b9f1040f5301f780b4</id>
    </parent>
  </parents>
  <author>
    <name>mprasetya@google.com</name>
    <email>mprasetya@google.com@3ea8f464-4a4f-11de-b25d-9f9778916a3c</email>
  </author>
  <url>http://github.com/JackDanger/google-wave-robot-java-client/commit/6f5c30a2405819bc345408fa266ce9dbee9af946</url>
  <id>6f5c30a2405819bc345408fa266ce9dbee9af946</id>
  <committed-date>2009-09-16T00:49:47-07:00</committed-date>
  <authored-date>2009-09-16T00:49:47-07:00</authored-date>
  <message>New code for Google Wave Java robot API (Sept 16 2009).


git-svn-id: http://wave-robot-java-client.googlecode.com/svn/trunk@14 3ea8f464-4a4f-11de-b25d-9f9778916a3c</message>
  <tree>ca4b934d2e1492effa53740e58c7e988f8cfe79f</tree>
  <committer>
    <name>mprasetya@google.com</name>
    <email>mprasetya@google.com@3ea8f464-4a4f-11de-b25d-9f9778916a3c</email>
  </committer>
</commit>
