http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/wave/client/common/util/SequenceMapAdapter.java
----------------------------------------------------------------------
diff --git 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/SequenceMapAdapter.java
 
b/wave/src/main/java/org/waveprotocol/wave/client/common/util/SequenceMapAdapter.java
deleted file mode 100644
index e1812c1..0000000
--- 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/SequenceMapAdapter.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.waveprotocol.wave.client.common.util;
-
-import org.waveprotocol.wave.model.util.Preconditions;
-
-/**
- * Presents a sequence that is backed by a {@link SequenceMap}.
- *
- * In particular, this class removes the inconvenient parts of the
- * {@link SequenceMap} API (sequence elements are exposed, circularity,
- * map-ness), presenting a nice, simple, sequence.
- *
- */
-public final class SequenceMapAdapter<T extends VolatileComparable<T>> 
implements
-    Sequence<T> {
-
-  /** Underlying doodad map. */
-  private final SequenceMap<T, T> map;
-
-  private SequenceMapAdapter(SequenceMap<T, T> map) {
-    this.map = map;
-  }
-
-  public static <T extends VolatileComparable<T>> SequenceMapAdapter<T> create(
-      SequenceMap<T, T> maps) {
-    return new SequenceMapAdapter<T>(maps);
-  }
-
-  @Override
-  public T getFirst() {
-    SequenceElement<T> first = map.getFirst();
-    return first != null ? first.value() : null;
-  }
-
-  @Override
-  public T getLast() {
-    SequenceElement<T> last = map.getLast();
-    return last != null ? last.value() : null;
-  }
-
-  @Override
-  public T getNext(T item) {
-    SequenceElement<T> node = map.getElement(item);
-    Preconditions.checkArgument(node != null, "item not in this sequence");
-    return node != map.getLast() ? node.getNext().value() : null;
-  }
-
-  @Override
-  public T getPrevious(T item) {
-    SequenceElement<T> node = map.getElement(item);
-    Preconditions.checkArgument(node != null, "item not in this sequence");
-    return node != map.getFirst() ? node.getPrev().value() : null;
-  }
-
-  @Override
-  public boolean isEmpty() {
-    return map.isEmpty();
-  }
-
-  @Override
-  public boolean contains(T x) {
-    return x != null && map.get(x) != null;
-  }
-
-  public void add(T x) {
-    map.put(x, x);
-  }
-
-  public void remove(T x) {
-    map.remove(x);
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/wave/client/common/util/SignalEvent.java
----------------------------------------------------------------------
diff --git 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/SignalEvent.java 
b/wave/src/main/java/org/waveprotocol/wave/client/common/util/SignalEvent.java
deleted file mode 100644
index 91dff61..0000000
--- 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/SignalEvent.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.waveprotocol.wave.client.common.util;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.dom.client.NativeEvent;
-import com.google.gwt.user.client.Event;
-
-/**
- * Attempts to bring sanity to the incredibly complex and inconsistent world of
- * browser events, especially with regards to key events.
- *
- * {@link SignalEventImpl}
- *
- * @author danila...@google.com (Daniel Danilatos)
- */
-public interface SignalEvent {
-
-  /**
-   * The "type" of key signal. The type is defined by us, based on a convenient
-   * classification of these events.
-   */
-  public enum KeySignalType {
-    /**
-     * Typing in the form of inputting text
-     *
-     * NOTE: "TAB" is treated as INPUT.
-     */
-    INPUT,
-    /** Moving around */
-    NAVIGATION,
-    /** Deleting text (Backspace + Delete) */
-    DELETE,
-    /** Other, like ESC or F3, that by themselves will do nothing to the 
document */
-    NOEFFECT,
-    /** Sentinal for debugging purposes only */
-    SENTINAL
-  }
-
-  /**
-   * The "movement unit" of this event. For example, on windows and linux,
-   * holding down CTRL whilst navigating left and right with the arrow
-   * keys moves a word at a time. Even more importantly, move units
-   * are used for deleting text.
-   */
-  public enum MoveUnit {
-    /** A character at a time */
-    CHARACTER,
-    /** A word at a time */
-    WORD,
-    /** To the start or end of the line */
-    LINE,
-    /** A "page" at a time */
-    PAGE,
-    /** To the start or end of the document */
-    DOCUMENT
-  }
-
-  /**
-   * These are the currently supported modifier combinations
-   *
-   * Supporting more requires tricky, browser-specific code. Go to the 
experiment harness
-   * and have a look at the wonders....
-   */
-  public enum KeyModifier {
-    /** No modifiers are pressed */
-    NONE {
-      @Override
-      public boolean check(SignalEvent event) {
-        return !event.getShiftKey() && !event.getAltKey()
-            && !event.getCtrlKey() && !event.getMetaKey();
-      }
-    },
-    /** Only shift is pressed */
-    SHIFT {
-      @Override
-      public boolean check(SignalEvent event) {
-        return event.getShiftKey() && !event.getAltKey()
-            && !event.getCtrlKey() && !event.getMetaKey();
-      }
-    },
-    /** Only ctrl is pressed */
-    CTRL {
-      @Override
-      public boolean check(SignalEvent event) {
-        return !event.getShiftKey() && !event.getAltKey()
-            && event.getCtrlKey() && !event.getMetaKey();
-      }
-    },
-    /** Only alt is pressed */
-    ALT {
-      @Override
-      public boolean check(SignalEvent event) {
-        return !event.getShiftKey() && event.getAltKey()
-            && !event.getCtrlKey() && !event.getMetaKey();
-      }
-    },
-    /** Only the meta key is pressed */
-    META {
-      @Override
-      public boolean check(SignalEvent event) {
-        return !event.getShiftKey() && !event.getAltKey()
-            && !event.getCtrlKey() && event.getMetaKey();
-      }
-    },
-    /**
-     * Only the "command" key is pressed
-     * @see SignalEvent#COMMAND_IS_CTRL
-     */
-    COMMAND {
-      @Override
-      public boolean check(SignalEvent event) {
-        return COMMAND_IS_CTRL ? CTRL.check(event) : META.check(event);
-      }
-    },
-    /** Both ctrl and alt, but no others, are pressed */
-    CTRL_ALT {
-      @Override
-      public boolean check(SignalEvent event) {
-        return !event.getShiftKey() && event.getAltKey()
-            && event.getCtrlKey() && !event.getMetaKey();
-      }
-    },
-    /** Both "command" and shift, but no others, are pressed */
-    COMMAND_SHIFT {
-      @Override
-      public boolean check(SignalEvent event) {
-        // The ctrl/meta key which is NOT the command key
-        boolean notCommandKey = COMMAND_IS_CTRL ? event.getMetaKey() : 
event.getCtrlKey();
-        return event.getShiftKey() && !event.getAltKey()
-            && event.getCommandKey() && !notCommandKey;
-      }
-    }
-    ;
-
-    /**
-     * Whether the "command" key is the control key (as opposed to the meta 
key).
-     */
-    // TODO(danilatos): Reconcile this with the value in SignalKeyLogic.
-    private static final boolean COMMAND_IS_CTRL = !UserAgent.isMac();
-
-    /**
-     * Check if the given event has the enum value's modifiers pressed.
-     * @param event
-     * @return true if they are pressed
-     */
-    public abstract boolean check(SignalEvent event);
-  }
-
-
-  /**
-   * @return Event type as a string, e.g. "keypress"
-   */
-  String getType();
-
-  /**
-   * @return The target element of the event
-   */
-  Element getTarget();
-
-  /**
-   * @return true if the event is a key event
-   * TODO(danilatos): Have a top level EventSignalType enum
-   */
-  boolean isKeyEvent();
-
-  /**
-   * @return true if it is an IME composition event
-   */
-  boolean isCompositionEvent();
-
-  /**
-   * Returns true if the key event is an IME input event.
-   * Only makes sense to call this method if this is a key signal.
-   * Does not work on FF. (TODO(danilatos): Can it be done? Tricks
-   * with dom mutation events?)
-   *
-   * @return true if this is an IME input event
-   */
-  boolean isImeKeyEvent();
-
-  /**
-   * @return true if this is a mouse event
-   * TODO(danilatos): Have a top level EventSignalType enum
-   */
-  boolean isMouseEvent();
-
-  /**
-   * TODO(danilatos): Click + drag? I.e. return true for mouse move, if the
-   * button is pressed? (this might be useful for tracking changing selections
-   * as the user holds & drags)
-   * @return true if this is an event involving some use of mouse buttons
-   */
-  boolean isMouseButtonEvent();
-
-  /**
-   * @return true if this is a mouse event but not {@link 
#isMouseButtonEvent()}
-   */
-  boolean isMouseButtonlessEvent();
-
-  /**
-   * @return true if this is a "click" event
-   */
-  boolean isClickEvent();
-
-  /**
-   * @return True if this is a dom mutation event
-   */
-  boolean isMutationEvent();
-
-  /**
-   * @return true if this is any sort of clipboard event
-   */
-  boolean isClipboardEvent();
-
-  /**
-   * @return If this is a focus event
-   */
-  boolean isFocusEvent();
-
-  /**
-   * @return true if this is a paste event
-   * TODO(danilatos): Make a ClipboardSignalType enum instead
-   */
-  boolean isPasteEvent();
-
-  /**
-   * @return true if this is a cut event
-   * TODO(danilatos): Make a ClipboardSignalType enum instead
-   */
-  boolean isCutEvent();
-
-  /**
-   * @return true if this is a copy event
-   * TODO(danilatos): Make a ClipboardSignalType enum instead
-   */
-  boolean isCopyEvent();
-
-  /**
-   * @return true if the command key is depressed
-   * @see #COMMAND_IS_CTRL
-   */
-  boolean getCommandKey();
-
-  /**
-   * @return true if the ctrl key is depressed
-   */
-  boolean getCtrlKey();
-
-  /**
-   * @return true if the meta key is depressed
-   */
-  boolean getMetaKey();
-
-  /**
-   * @return true if the alt key is depressed
-   */
-  boolean getAltKey();
-
-  /**
-   * @return true if the shift key is depressed
-   */
-  boolean getShiftKey();
-
-  /**
-   * TODO(user): Deprecate this, as it breaks abstraction. Also prevent people
-   * from casting back and forth.
-   *
-   * @return The underlying event view of this event
-   */
-  Event asEvent();
-
-  /**
-   * Only valid for key events.
-   * Currently only implemented for deleting, not actual navigating.
-   * @return The move unit of this event
-   */
-  MoveUnit getMoveUnit();
-
-  /**
-   * @return True if the event is the key combo for "undo"
-   * NOTE(danilatos): This is the best we have at detecting undo events :(
-   * We need even more special handling for undo done via the menu :( :(
-   */
-  boolean isUndoCombo();
-
-  /**
-   * @return True if the event is the key combo for "redo"
-   */
-  boolean isRedoCombo();
-
-  /**
-   * @param letter Treated case-insensitive, including things like '1' vs '!'
-   *    User may provide either, but upper case for letters and unshifted for
-   *    other keys is recommended
-   * @param modifier
-   * @return True if the given letter is pressed, and only the given modifiers.
-   */
-  boolean isCombo(int letter, KeyModifier modifier);
-
-  /**
-   * @param letter
-   * @return true, if the given letter was pressed without modifiers. Takes 
into
-   *         account the caps lock key being pressed (it will be as if it
-   *         weren't pressed)
-   */
-  boolean isOnly(int letter);
-
-  /**
-   * @return The gwtKeyCode of this event, with some minor compatibility
-   *         adjustments
-   */
-  int getKeyCode();
-
-  /**
-   * @return the mouse button bit field for this event.  The masks used to 
extract
-   *   individual buttons from the field are {@link NativeEvent#BUTTON_LEFT},
-   *   {@link NativeEvent#BUTTON_MIDDLE}, and {@link NativeEvent#BUTTON_RIGHT}.
-   */
-  int getMouseButton();
-
-  /**
-   * @return The key signal type of this even, or null if it is not a key event
-   * @see KeySignalType
-   */
-  KeySignalType getKeySignalType();
-
-  /**
-   * Prevent this event from propagating or, if that is impossible, ensures 
that
-   * {@link SignalEventImpl#create(Event, boolean)} will subsequently return 
null
-   * for the same corresponding event object.
-   */
-  void stopPropagation();
-
-  /**
-   * Prevents the browser from taking its default action for the given event.
-   * Under some circumstances (see {@link 
SignalEventImpl#isPreventDefaultEffective}
-   * this may also stop propagation.
-   *
-   * See also {@link #stopPropagation()}.
-   */
-  public void preventDefault();
-}

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/wave/client/common/util/SignalEventImpl.java
----------------------------------------------------------------------
diff --git 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/SignalEventImpl.java
 
b/wave/src/main/java/org/waveprotocol/wave/client/common/util/SignalEventImpl.java
deleted file mode 100644
index 5d70221..0000000
--- 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/SignalEventImpl.java
+++ /dev/null
@@ -1,668 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.waveprotocol.wave.client.common.util;
-
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.user.client.Event;
-
-import org.waveprotocol.wave.client.common.util.SignalKeyLogic.OperatingSystem;
-import org.waveprotocol.wave.client.common.util.SignalKeyLogic.UserAgentType;
-import org.waveprotocol.wave.model.util.CollectionUtils;
-import org.waveprotocol.wave.model.util.StringSet;
-
-/**
- * Attempts to bring sanity to the incredibly complex and inconsistent world of
- * browser events, especially with regards to key events.
- *
- * A new concept of the "signal" is introduced. A signal is basically an event,
- * but an event that we actually care about, with the information we care 
about.
- * Redundant events are merged into a single signal. For key events, a signal
- * corresponds to the key-repeat signal we get from the keyboard. For normal
- * typing input, this will always be the keypress event. For other types of key
- * events, it depends on the browser. For clipboard events, the "beforeXYZ" and
- * "XYZ" events are merged into a single one, the one that actually happens
- * right before the action (browser dependent). Key events are also classified
- * into subtypes identified by KeySignalType. This reflects the intended usage
- * of the event, not something to do with the event data itself.
- *
- * Currently the "filtering" needs to be done manually - simply construct a
- * signal from an event using {@link #create(Event, boolean)}, and if it 
returns null,
- * drop the event and do nothing with it (cancelling bubbling might be a good
- * idea though).
- *
- * NOTE(danilatos): getting the physical key pressed, even on a key down, is
- * inherently not possible without a big lookup table, because of international
- * input methods. e.g. press 'b' but in greek mode on safari on osx. nothing in
- * any of the events you receive will tell you it was a 'b', instead, you'll 
get
- * a beta for the keypress and 0 (zero) for the keydown. mmm, useful!
- *
- * TODO(danilatos): Hook this into the application's event plumbing in a more
- * invasive manner.
- *
- * @author danila...@google.com (Daniel Danilatos)
- */
-public class SignalEventImpl implements SignalEvent {
-
-  public interface SignalEventFactory<T extends SignalEventImpl> {
-    T create();
-  }
-
-  public static SignalEventFactory<SignalEventImpl> DEFAULT_FACTORY =
-    new SignalEventFactory<SignalEventImpl>() {
-      @Override public SignalEventImpl create() {
-        return new SignalEventImpl();
-      }
-    };
-
-  interface NativeEvent {
-    String getType();
-    int getButton();
-    boolean getCtrlKey();
-    boolean getMetaKey();
-    boolean getAltKey();
-    boolean getShiftKey();
-    void preventDefault();
-    void stopPropagation();
-  }
-
-  /**
-   * @param event
-   * @return True if the given event is a key event
-   */
-  public static boolean isKeyEvent(Event event) {
-    return KEY_EVENTS.contains(event.getType());
-  }
-
-  private static final UserAgentType currentUserAgent =
-      (UserAgent.isWebkit() ? UserAgentType.WEBKIT : (
-          UserAgent.isFirefox() ? UserAgentType.GECKO : UserAgentType.IE));
-  private static final OperatingSystem currentOs =
-      (UserAgent.isWin() ? OperatingSystem.WINDOWS : (
-          UserAgent.isMac() ? OperatingSystem.MAC : OperatingSystem.LINUX));
-  private static final SignalKeyLogic logic = new SignalKeyLogic(
-      currentUserAgent, currentOs, 
QuirksConstants.COMMAND_COMBO_DOESNT_GIVE_KEYPRESS);
-
-  /**
-   * This variable will be filled with mappings of unshifted keys to their 
shifted versions.
-   */
-  private static final int[] shiftMappings = new int[128];
-  static {
-    for (int a = 'A'; a <= 'Z'; a++) {
-      shiftMappings[a] = a + 'a' - 'A';
-    }
-    // TODO(danilatos): Who knows what these mappings should be on other
-    // keyboard layouts... e.g. pound signs? euros? etc? argh!
-    shiftMappings['1'] = '!';
-    shiftMappings['2'] = '@';
-    shiftMappings['3'] = '#';
-    shiftMappings['4'] = '$';
-    shiftMappings['5'] = '%';
-    shiftMappings['6'] = '^';
-    shiftMappings['7'] = '&';
-    shiftMappings['8'] = '*';
-    shiftMappings['9'] = '(';
-    shiftMappings['0'] = ')';
-    shiftMappings['`'] = '~';
-    shiftMappings['-'] = '_';
-    shiftMappings['='] = '+';
-    shiftMappings['['] = '{';
-    shiftMappings[']'] = '}';
-    shiftMappings['\\'] = '|';
-    shiftMappings[';'] = ':';
-    shiftMappings['\''] = '"';
-    shiftMappings[','] = '<';
-    shiftMappings['.'] = '>';
-    shiftMappings['/'] = '?';
-    // invalidate the inverse mappings
-    for (int i = 1; i < shiftMappings.length; i++) {
-      int m = shiftMappings[i];
-      if (m > 0) {
-        shiftMappings[m] = i;
-      }
-    }
-  }
-
-  private static final StringSet KEY_EVENTS = 
CollectionUtils.createStringSet();
-  private static final StringSet COMPOSITION_EVENTS = 
CollectionUtils.createStringSet();
-  private static final StringSet MOUSE_EVENTS = 
CollectionUtils.createStringSet();
-  private static final StringSet MOUSE_BUTTON_EVENTS = 
CollectionUtils.createStringSet();
-  private static final StringSet MOUSE_BUTTONLESS_EVENTS = 
CollectionUtils.createStringSet();
-  private static final StringSet FOCUS_EVENTS = 
CollectionUtils.createStringSet();
-  private static final StringSet CLIPBOARD_EVENTS = 
CollectionUtils.createStringSet();
-
-  /**
-   * Events affected by
-   * {@link 
QuirksConstants#CANCEL_BUBBLING_CANCELS_IME_COMPOSITION_AND_CONTEXTMENU}.
-   */
-  private static final StringSet CANCEL_BUBBLE_QUIRKS = 
CollectionUtils.createStringSet();
-
-  static {
-    for (String e : new String[]{"keydown", "keypress", "keyup"}) {
-      KEY_EVENTS.add(e);
-    }
-    for (String e : new String[]{
-        "compositionstart", "compositionend", "compositionupdate", "text"}) {
-      COMPOSITION_EVENTS.add(e);
-      CANCEL_BUBBLE_QUIRKS.add(e);
-    }
-    COMPOSITION_EVENTS.add("textInput");
-    CANCEL_BUBBLE_QUIRKS.add("contextmenu");
-    for (String e : new String[]{
-        "mousewheel", "DOMMouseScroll", "mousemove", "mouseover", "mouseout",
-        /* not strictly a mouse event*/ "contextmenu"}) {
-      MOUSE_BUTTONLESS_EVENTS.add(e);
-      MOUSE_EVENTS.add(e);
-    }
-    for (String e : new String[]{
-        "mousedown", "mouseup", "click", "dblclick"}) {
-      MOUSE_BUTTON_EVENTS.add(e);
-      MOUSE_EVENTS.add(e);
-    }
-    for (String e : new String[]{"focus", "blur", "beforeeditfocus"}) {
-      FOCUS_EVENTS.add(e);
-    }
-    for (String e : new String[]{"cut", "copy", "paste"}) {
-      CLIPBOARD_EVENTS.add(e);
-      CLIPBOARD_EVENTS.add("before" + e);
-    }
-  }
-
-  protected NativeEvent nativeEvent;
-  private KeySignalType keySignalType = null;
-  private int cachedKeyCode = -1;
-  private boolean hasBeenConsumed = false;
-
-  protected SignalEventImpl() {
-  }
-
-  static class JsoNativeEvent extends Event implements NativeEvent {
-    protected JsoNativeEvent() {}
-  }
-
-  /**
-   * Create a signal from an event, possibly filtering the event
-   * if it is deemed redundant.
-   *
-   * If the event is to be filtered, null is returned, and bubbling
-   * is cancelled if cancelBubbleIfNullified is true.
-   * (but the default is not prevented).
-   *
-   * NOTE(danilatos): So far, for key events, the following have been tested:
-   * - Safari 3.1 OS/X (incl. num pad, with USB keyboard)
-   * - Safari 3.0 OS/X, hosted mode only (so no ctrl+c, etc)
-   * - Firefox 3, OS/X, WinXP
-   * - IE7, WinXP
-   * Needs testing:
-   * - FF3 linux, Safari 3.0/3.1 Windows
-   * - All kinds of weirdo keyboards (mac, international)
-   * - Linux IME
-   *
-   * Currently, only key events have serious logic applied to them.
-   * Maybe some logic for copy/paste, and mouse events?
-   *
-   * @param event Raw Event JSO
-   * @param cancelBubbleIfNullified stops propagation if the event is nullified
-   * @return SignalEvent mapping, or null, if the event is to be discarded
-   */
-  public static SignalEventImpl create(Event event, boolean 
cancelBubbleIfNullified) {
-    return create(DEFAULT_FACTORY, event, cancelBubbleIfNullified);
-  }
-
-  public static <T extends SignalEventImpl> T create(SignalEventFactory<T> 
factory,
-      Event event, boolean cancelBubbleIfNullified) {
-    if (hasBeenConsumed(event)) {
-      return null;
-    } else {
-      T signal = createInner(factory, event);
-      if (cancelBubbleIfNullified && signal == null) {
-        event.stopPropagation();
-      }
-      return signal;
-    }
-  }
-
-  private static boolean hasBeenConsumed(Event event) {
-    SignalEventImpl existing = getFor(null, event);
-    return existing != null && existing.hasBeenConsumed();
-  }
-
-  private static final String EVENT_PROP = "$se";
-  @SuppressWarnings("unchecked")
-  private static <T extends SignalEventImpl> T getFor(SignalEventFactory<T> 
factory, Event event) {
-    return (T) (SignalEventImpl) event.<JsoView>cast().getObject(EVENT_PROP);
-  }
-
-  private static <T extends SignalEventImpl> T createFor(
-      SignalEventFactory<T> factory, Event event) {
-
-    T signal = factory.create();
-    event.<JsoView>cast().setObject(EVENT_PROP, signal);
-    return signal;
-  }
-
-  /** This would be a static local variable if java allowed it. Grouping it 
here. */
-  private static final SignalKeyLogic.Result computeKeySignalTypeResult =
-      new SignalKeyLogic.Result();
-
-  private static <T extends SignalEventImpl> T createInner(
-      SignalEventFactory<T> factory, Event event) {
-
-    SignalKeyLogic.Result keySignalResult;
-    if (isKeyEvent(event)) {
-      keySignalResult = computeKeySignalTypeResult;
-
-      String keyIdentifier = getKeyIdentifier(event);
-
-      logic.computeKeySignalType(keySignalResult,
-          event.getType(), getNativeKeyCode(event), getWhich(event), 
keyIdentifier,
-          event.getMetaKey(), event.getCtrlKey(), event.getAltKey(), 
event.getShiftKey());
-
-    } else {
-      keySignalResult = null;
-    }
-
-    return createInner(createFor(factory, event), 
event.<JsoNativeEvent>cast(), keySignalResult);
-  }
-
-  /**
-   * Populate a SignalEventImpl with the necessary information
-   *
-   * @param ret
-   * @param keySignalResult only required if it's a key event
-   * @return the signal, or null if it is to be ignored.
-   */
-  protected static <T extends SignalEventImpl> T createInner(T ret,
-      NativeEvent event, SignalKeyLogic.Result keySignalResult) {
-    ret.nativeEvent = event;
-    if (ret.isKeyEvent()) {
-      KeySignalType type = keySignalResult.type;
-
-      if (type != null) {
-        ret.cacheKeyCode(keySignalResult.keyCode);
-        ret.setup(type);
-      } else {
-        ret = null;
-      }
-
-    } else if ((UserAgent.isIE() ? "paste" : 
"beforepaste").equals(event.getType())) {
-      // Only want 'beforepaste' for ie and 'paste' for everything else.
-      // TODO(danilatos): Generalise clipboard events
-      ret = null;
-    }
-
-    // TODO: return null if it's something we should ignore.
-    return ret;
-  }
-
-  public static native int getNativeKeyCode(Event event) /*-{
-    return event.keyCode || 0;
-  }-*/;
-
-  public static native int getWhich(Event event) /*-{
-    return event.which || 0;
-  }-*/;
-
-  public static native String getKeyIdentifier(Event event) /*-{
-    return event.keyIdentifier
-  }-*/;
-
-  /**
-   * @return Event type as a string, e.g. "keypress"
-   */
-  public final String getType() {
-    return nativeEvent.getType();
-  }
-
-  /**
-   * @return The target element of the event
-   */
-  public Element getTarget() {
-    return asEvent().getTarget();
-  }
-
-  /**
-   * @return true if the event is a key event
-   * TODO(danilatos): Have a top level EventSignalType enum
-   */
-  public final boolean isKeyEvent() {
-    return KEY_EVENTS.contains(nativeEvent.getType());
-  }
-
-  /**
-   * @return true if it is an IME composition event
-   */
-  public final boolean isCompositionEvent() {
-    return COMPOSITION_EVENTS.contains(getType());
-  }
-
-  /**
-   * Returns true if the key event is an IME input event.
-   * Only makes sense to call this method if this is a key signal.
-   * Does not work on FF. (TODO(danilatos): Can it be done? Tricks
-   * with dom mutation events?)
-   *
-   * @return true if this is an IME input event
-   */
-  public final boolean isImeKeyEvent() {
-    return getKeyCode() == SignalKeyLogic.IME_CODE;
-  }
-
-  /**
-   * @return true if this is a mouse event
-   * TODO(danilatos): Have a top level EventSignalType enum
-   */
-  public final boolean isMouseEvent() {
-    return MOUSE_EVENTS.contains(getType());
-  }
-
-  /**
-   * TODO(danilatos): Click + drag? I.e. return true for mouse move, if the
-   * button is pressed? (this might be useful for tracking changing selections
-   * as the user holds & drags)
-   * @return true if this is an event involving some use of mouse buttons
-   */
-  public final boolean isMouseButtonEvent() {
-    return MOUSE_BUTTON_EVENTS.contains(getType());
-  }
-
-  /**
-   * @return true if this is a mouse event but not {@link 
#isMouseButtonEvent()}
-   */
-  public final boolean isMouseButtonlessEvent() {
-    return MOUSE_BUTTONLESS_EVENTS.contains(getType());
-  }
-
-  /**
-   * @return true if this is a "click" event
-   */
-  public final boolean isClickEvent() {
-    return "click".equals(getType());
-  }
-
-  /**
-   * @return True if this is a dom mutation event
-   */
-  public final boolean isMutationEvent() {
-    // What about DOMMouseScroll?
-    return getType().startsWith("DOM");
-  }
-
-  /**
-   * @return true if this is any sort of clipboard event
-   */
-  public final boolean isClipboardEvent() {
-    return CLIPBOARD_EVENTS.contains(getType());
-  }
-
-  /**
-   * @return If this is a focus event
-   */
-  public final boolean isFocusEvent() {
-    return FOCUS_EVENTS.contains(getType());
-  }
-
-  /**
-   * @return true if this is a paste event
-   * TODO(danilatos): Make a ClipboardSignalType enum instead
-   */
-  public final boolean isPasteEvent() {
-    return (UserAgent.isIE() ? "beforepaste" : 
"paste").equals(nativeEvent.getType());
-  }
-
-  /**
-   * @return true if this is a cut event
-   * TODO(danilatos): Make a ClipboardSignalType enum instead
-   */
-  public final boolean isCutEvent() {
-    return (UserAgent.isIE() ? "beforecut" : 
"cut").equals(nativeEvent.getType());
-  }
-
-  /**
-   * @return true if this is a copy event
-   * TODO(danilatos): Make a ClipboardSignalType enum instead
-   */
-  public final boolean isCopyEvent() {
-    return "copy".equals(nativeEvent.getType());
-  }
-
-  /**
-   * @return true if the command key is depressed
-   * @see SignalKeyLogic#commandIsCtrl()
-   */
-  public final boolean getCommandKey() {
-    return logic.commandIsCtrl() ? getCtrlKey() : getMetaKey();
-  }
-
-  public static boolean getCommandKey(com.google.gwt.dom.client.NativeEvent 
event) {
-    return logic.commandIsCtrl() ? event.getCtrlKey() : event.getMetaKey();
-  }
-
-  /**
-   * @return true if the ctrl key is depressed
-   */
-  public final boolean getCtrlKey() {
-    return nativeEvent.getCtrlKey();
-  }
-
-  /**
-   * @return true if the meta key is depressed
-   */
-  public final boolean getMetaKey() {
-    return nativeEvent.getMetaKey();
-  }
-
-  /**
-   * @return true if the alt key is depressed
-   */
-  public final boolean getAltKey() {
-    // TODO(danilatos): Handle Alt vs Option on OSX?
-    return nativeEvent.getAltKey();
-  }
-
-  /**
-   * @return true if the shift key is depressed
-   */
-  public final boolean getShiftKey() {
-    return nativeEvent.getShiftKey();
-  }
-
-  /**
-   * @return The underlying event view of this event
-   */
-  public final Event asEvent() {
-    return (Event) nativeEvent;
-  }
-
-  /**
-   * Only valid for key events.
-   * Currently only implemented for deleting, not actual navigating.
-   * @return The move unit of this event
-   */
-  public final MoveUnit getMoveUnit() {
-    if (getKeySignalType() == KeySignalType.DELETE) {
-      if (UserAgent.isMac()) {
-        if (getAltKey()) {
-          // Note: in practice, some combinations of bkspc/delete + modifier 
key
-          // have no effect. This is inconsistent across browsers. It's 
probably
-          // ok to normalise it here, as we will be manually implementing 
everything
-          // except character-sized deletes on collapsed selections, and so 
users
-          // would get a more consistent (and logical and symmetrical) 
experience.
-          return MoveUnit.WORD;
-        } else if (getCommandKey()) {
-          return MoveUnit.LINE;
-        } else {
-          return MoveUnit.CHARACTER;
-        }
-      } else {
-        if (getCommandKey()) {
-          return MoveUnit.WORD;
-        } else {
-          return MoveUnit.CHARACTER;
-        }
-      }
-    } else {
-      // TODO(danilatos): Also implement for mere navigation events?
-      // Currently just for deleting... so we'll at least for now just pretend
-      // everything else is of character magnitude. This is because we
-      // probably won't be using the information anyway, instead letting
-      // the browser just do its default navigation behaviour.
-
-      return MoveUnit.CHARACTER;
-    }
-  }
-
-  @Override
-  public final boolean isUndoCombo() {
-    return isCombo('Z', KeyModifier.COMMAND);
-  }
-
-  @Override
-  public final boolean isRedoCombo() {
-    if ((UserAgent.isMac() || UserAgent.isLinux()) &&
-        isCombo('Z', KeyModifier.COMMAND_SHIFT)) {
-      // Mac and Linux accept command-shift-z for undo
-      return true;
-    }
-    // NOTE(user): COMMAND + Y for redo, except for Mac OS X (for chrome,
-    // default behaviour is browser history)
-    return !UserAgent.isMac() && isCombo('Y', KeyModifier.COMMAND);
-  }
-
-  /**
-   * Because we must use keypress events for FF, in order to get repeats,
-   * but prefer keydowns for combo type events for the other browsers,
-   * we need to convert the case here.
-   *
-   * @param letter
-   */
-  private final int comboInputKeyCode(char letter) {
-    // TODO(danilatos): Check the compiled javascript to make sure it does 
simple
-    // numerical operations and not string manipulations and conversions... 
char is
-    // used all over this file
-    return UserAgent.isFirefox()
-      ? letter + 'a' - 'A'
-      : letter;
-  }
-
-  /**
-   * @param letter Treated case-insensitive, including things like '1' vs '!'
-   *    User may provide either, but upper case for letters and unshifted for
-   *    other keys is recommended
-   * @param modifier
-   * @return True if the given letter is pressed, and only the given modifiers.
-   */
-  public final boolean isCombo(int letter, KeyModifier modifier) {
-    assert letter > 0 && letter < shiftMappings.length;
-    int keyCode = getKeyCode();
-    if (keyCode >= shiftMappings.length) {
-      return false;
-    }
-
-    return (letter == keyCode || letter == shiftMappings[keyCode]) && 
modifier.check(this);
-  }
-
-  /**
-   * @param letter
-   * @return true, if the given letter was pressed without modifiers. Takes 
into
-   *         account the caps lock key being pressed (it will be as if it
-   *         weren't pressed)
-   */
-  public final boolean isOnly(int letter) {
-    return isCombo(letter, KeyModifier.NONE);
-  }
-
-  @Override
-  public final int getMouseButton() {
-    return nativeEvent.getButton();
-  }
-
-  /**
-   * @return The key signal type of this even, or null if it is not a key event
-   * @see SignalEvent.KeySignalType
-   */
-  public KeySignalType getKeySignalType() {
-    return this.keySignalType;
-  }
-
-  /**
-   * @return The gwtKeyCode of this event, with some minor compatibility
-   *         adjustments
-   */
-  public int getKeyCode() {
-    return this.cachedKeyCode;
-  }
-
-  /**
-   * Returns true if the event has effectively had its propagation stopped, 
since
-   * we couldn't physically stop it due to browser quirkiness.  See {@link 
#stopPropagation()}.
-   */
-  private boolean hasBeenConsumed() {
-    return hasBeenConsumed;
-  }
-
-  private void markAsConsumed() {
-    hasBeenConsumed = true;
-  }
-
-  protected void cacheKeyCode(int keyCode) {
-    this.cachedKeyCode = keyCode;
-  }
-
-  private boolean stopPropagationPreventsDefault() {
-    if 
(QuirksConstants.CANCEL_BUBBLING_CANCELS_IME_COMPOSITION_AND_CONTEXTMENU) {
-      return CANCEL_BUBBLE_QUIRKS.contains(getType());
-    } else {
-      return false;
-    }
-  }
-
-  private boolean isPreventDefaultEffective() {
-    if (QuirksConstants.PREVENT_DEFAULT_STOPS_CONTEXTMENT) {
-      return true;
-    } else {
-      String type = nativeEvent.getType();
-      return !type.equals("contextmenu");
-    }
-  }
-
-  @Override
-  public final void stopPropagation() {
-    if (stopPropagationPreventsDefault()) {
-      markAsConsumed();
-    } else {
-      nativeEvent.stopPropagation();
-    }
-  }
-
-  protected final void setup(KeySignalType signalType) {
-    this.keySignalType = signalType;
-  }
-
-  @Override
-  public final void preventDefault() {
-    nativeEvent.preventDefault();
-    if (!isPreventDefaultEffective()) {
-      // HACK(user): Really we would like the event to continue to propagate
-      //   and stop it immediately before reaching the top, rather than at this
-      //   point.
-      nativeEvent.stopPropagation();
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/wave/client/common/util/SignalKeyLogic.java
----------------------------------------------------------------------
diff --git 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/SignalKeyLogic.java
 
b/wave/src/main/java/org/waveprotocol/wave/client/common/util/SignalKeyLogic.java
deleted file mode 100644
index 5da169a..0000000
--- 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/SignalKeyLogic.java
+++ /dev/null
@@ -1,394 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.waveprotocol.wave.client.common.util;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.user.client.Event;
-
-import org.waveprotocol.wave.client.common.util.SignalEvent.KeySignalType;
-import org.waveprotocol.wave.model.util.CollectionUtils;
-import org.waveprotocol.wave.model.util.ReadableStringMap.ProcV;
-import org.waveprotocol.wave.model.util.StringMap;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Instances of this class encapsulate the event to signal mapping logic for a
- * specific environment (os/browser).
- *
- * Contains as much of the signal event logic as possible in a POJO testable
- * manner.
- *
- * @author danila...@google.com (Daniel Danilatos)
- */
-public final class SignalKeyLogic {
-
-  /**
-   * For webkit + IE
-   * I think also all browsers on windows?
-   */
-  public static final int IME_CODE = 229;
-
-  private static final String DELETE_KEY_IDENTIFIER = "U+007F";
-
-  //TODO(danilatos): Use int map
-  private static final Set<Integer> NAVIGATION_KEYS = new HashSet<Integer>();
-  private static final StringMap<Integer> NAVIGATION_KEY_IDENTIFIERS =
-      CollectionUtils.createStringMap();
-  static {
-
-    NAVIGATION_KEY_IDENTIFIERS.put("Left", KeyCodes.KEY_LEFT);
-    NAVIGATION_KEY_IDENTIFIERS.put("Right", KeyCodes.KEY_RIGHT);
-    NAVIGATION_KEY_IDENTIFIERS.put("Up", KeyCodes.KEY_UP);
-    NAVIGATION_KEY_IDENTIFIERS.put("Down", KeyCodes.KEY_DOWN);
-    NAVIGATION_KEY_IDENTIFIERS.put("PageUp", KeyCodes.KEY_PAGEUP);
-    NAVIGATION_KEY_IDENTIFIERS.put("PageDown", KeyCodes.KEY_PAGEDOWN);
-    NAVIGATION_KEY_IDENTIFIERS.put("Home", KeyCodes.KEY_HOME);
-    NAVIGATION_KEY_IDENTIFIERS.put("End", KeyCodes.KEY_END);
-
-    NAVIGATION_KEY_IDENTIFIERS.each(new ProcV<Integer>() {
-      public void apply(String key, Integer keyCode) {
-        NAVIGATION_KEYS.add(keyCode);
-      }
-    });
-  }
-
-  public enum UserAgentType {
-    WEBKIT,
-    GECKO,
-    IE
-  }
-
-  public enum OperatingSystem {
-    WINDOWS,
-    MAC,
-    LINUX
-  }
-
-  @VisibleForTesting
-  public static class Result {
-    @VisibleForTesting
-    public int keyCode;
-    // Sentinal by default for testing purposes
-    @VisibleForTesting
-    public KeySignalType type = KeySignalType.SENTINAL;
-  }
-
-  private final UserAgentType userAgent;
-  private final boolean commandIsCtrl;
-
-
-  // Hack, get rid of this
-  final boolean commandComboDoesntGiveKeypress;
-
-  /**
-   * @param userAgent
-   * @param os Operating system
-   */
-  public SignalKeyLogic(UserAgentType userAgent, OperatingSystem os,
-      boolean commandComboDoesntGiveKeypress) {
-    this.userAgent = userAgent;
-    this.commandComboDoesntGiveKeypress = commandComboDoesntGiveKeypress;
-    commandIsCtrl = os != OperatingSystem.MAC;
-  }
-
-  public boolean commandIsCtrl() {
-    return commandIsCtrl;
-  }
-
-  public void computeKeySignalType(
-      Result result,
-      String typeName,
-      int keyCode, int which, String keyIdentifier,
-      boolean metaKey, boolean ctrlKey, boolean altKey, boolean shiftKey) {
-
-    boolean ret = true;
-
-    int typeInt;
-    if ("keydown".equals(typeName)) {
-      typeInt = Event.ONKEYDOWN;
-    } else if ("keypress".equals(typeName)) {
-      typeInt = Event.ONKEYPRESS;
-    } else if ("keyup".equals(typeName)) {
-      result.type = null;
-      return;
-    } else {
-      throw new AssertionError("Non-key-event passed to computeKeySignalType");
-    }
-
-    KeySignalType type;
-
-    int computedKeyCode = which != 0 ? which : keyCode;
-
-    if (computedKeyCode == 10) {
-      computedKeyCode = KeyCodes.KEY_ENTER;
-    }
-
-    // For non-firefox browsers, we only get keydown events for IME, no 
keypress
-    boolean isIME = computedKeyCode == IME_CODE;
-
-    boolean commandKey = commandIsCtrl ? ctrlKey : metaKey;
-
-    switch (userAgent) {
-      case WEBKIT:
-        // This is a bit tricky because there are significant differences
-        // between safari 3.0 and safari 3.1...
-
-        // We could probably actually almost use the same code that we use for 
IE
-        // for safari 3.1, because with 3.1 the webkit folks made a big shift 
to
-        // get the events to be in line with IE for compatibility. 3.0 events
-        // are a lot more similar to FF, but different enough to need special
-        // handling. However, it seems that using more advanced features like
-        // keyIdentifier for safaris is probably better and more future-proof,
-        // as well as being compatible between the two, so for now we're not
-        // using IE logic for safari 3.1
-
-        // Weird special large keycode numbers for safari 3.0, where it gives
-        // us keypress events (though they happen after the dom is changed,
-        // for some things like delete. So not too useful). The number
-        // 63200 is known as the cutoff mark.
-        if (typeInt == Event.ONKEYDOWN && computedKeyCode > 63200) {
-          result.type = null;
-          return;
-        } else if (typeInt == Event.ONKEYPRESS) {
-          // Skip keypress for tab and escape, because they are the only 
non-input keys
-          // that don't have keycodes above 63200. This is to prevent them 
from being treated
-          // as INPUT in the || = keypress below. See (X) below
-          if (computedKeyCode == KeyCodes.KEY_ESCAPE
-              || computedKeyCode == KeyCodes.KEY_TAB) {
-            result.type = null;
-            return;
-          }
-        }
-
-        // boolean isPossiblyCtrlInput = typeInt == Event.ONKEYDOWN && 
ret.getCtrlKey();
-        boolean isActuallyCtrlInput = false;
-
-        boolean startsWithUPlus = keyIdentifier != null && 
keyIdentifier.startsWith("U+");
-
-        // Need to use identifier for the delete key because the keycode 
conflicts
-        // with the keycode for the full stop.
-        if (isIME) {
-          // If is IME, override the logic below - we get keyIdentifiers for 
IME events,
-          // but those are basically useless as the event is basically still 
an IME input
-          // event (e.g. keyIdentifier might say "Up", but it's certainly not 
navigation,
-          // it's just the user selecting from the IME dialog).
-          type = KeySignalType.INPUT;
-        } else if (DELETE_KEY_IDENTIFIER.equals(keyIdentifier) ||
-            computedKeyCode == KeyCodes.KEY_BACKSPACE) {
-
-          type = KeySignalType.DELETE;
-        } else if (NAVIGATION_KEY_IDENTIFIERS.containsKey(keyIdentifier)) {
-          type = KeySignalType.NAVIGATION;
-        // Escape, backspace and context-menu-key (U+0010) are, to my 
knowledge,
-        // the only non-navigation keys that
-        // have a "U+..." keyIdentifier, so we handle them explicitly.
-        // (Backspace was handled earlier).
-        } else if (computedKeyCode == KeyCodes.KEY_ESCAPE || 
"U+0010".equals(keyIdentifier)) {
-          type = KeySignalType.NOEFFECT;
-        } else if (
-            computedKeyCode < 63200 && // if it's not a safari 3.0 non-input 
key (See (X) above)
-            (typeInt == Event.ONKEYPRESS ||  // if it's a regular keypress
-                  startsWithUPlus || computedKeyCode == KeyCodes.KEY_ENTER)) {
-          type = KeySignalType.INPUT;
-          isActuallyCtrlInput = ctrlKey
-              || (commandComboDoesntGiveKeypress && commandKey);
-        } else {
-          type = KeySignalType.NOEFFECT;
-        }
-
-        // Maybe nullify it with the same logic as IE, EXCEPT for the special
-        // Ctrl Input webkit behaviour, and IME for windows
-        if (isActuallyCtrlInput) {
-          if (computedKeyCode == KeyCodes.KEY_ENTER) {
-            ret = typeInt == Event.ONKEYDOWN;
-          }
-          // HACK(danilatos): Don't actually nullify isActuallyCtrlInput for 
key press.
-          // We get that for AltGr combos on non-mac computers.
-        } else if (isIME || keyCode == KeyCodes.KEY_TAB) {
-          ret = typeInt == Event.ONKEYDOWN;
-        } else {
-          ret = maybeNullWebkitIE(ret, typeInt, type);
-        }
-        if (!ret) {
-          result.type = null;
-          return;
-        }
-        break;
-      case GECKO:
-        boolean hasKeyCodeButNotWhich = keyCode != 0 && which == 0;
-
-        // Firefox is easy for deciding signal events, because it issues a 
keypress for
-        // whenever we would want a signal. So we can basically ignore all 
keydown events.
-        // It also, on all OSes, does any default action AFTER the keypress 
(even for
-        // things like Ctrl/Meta+C, etc). So keypress is perfect for us.
-        // Ctrl+Space is an exception, where we don't get a keypress
-        // Firefox also gives us keypress events even for Windows IME input
-        if (ctrlKey && !altKey && !shiftKey && computedKeyCode == ' ') {
-          if (typeInt != Event.ONKEYDOWN) {
-            result.type = null;
-            return;
-          }
-        } else if (typeInt == Event.ONKEYDOWN) {
-          result.type = null;
-          return;
-        }
-
-        // Backspace fails the !hasKeyCodeButNotWhich test, so check it 
explicitly first
-        if (computedKeyCode == KeyCodes.KEY_BACKSPACE) {
-          type = KeySignalType.DELETE;
-        // This 'keyCode' but not 'which' works very nicely for catching 
normal typing input keys,
-        // the only 'exceptions' I've seen so far are bksp & enter which have 
both
-        } else if (!hasKeyCodeButNotWhich || computedKeyCode == 
KeyCodes.KEY_ENTER
-            || computedKeyCode == KeyCodes.KEY_TAB) {
-          type = KeySignalType.INPUT;
-        } else if (computedKeyCode == KeyCodes.KEY_DELETE) {
-          type = KeySignalType.DELETE;
-        } else if (NAVIGATION_KEYS.contains(computedKeyCode)) {
-          type = KeySignalType.NAVIGATION;
-        } else {
-          type = KeySignalType.NOEFFECT;
-        }
-
-        break;
-      case IE:
-
-        // Unfortunately IE gives us the least information, so there are no 
nifty tricks.
-        // So we pretty much need to use some educated guessing based on key 
codes.
-        // Experimentation page to the rescue.
-
-        boolean isKeydownForInputKey = isInputKeyCodeIE(computedKeyCode);
-
-        // IE has some strange behaviour with modifiers and whether or not 
there will
-        // be a keypress. Ctrl kills the keypress, unless shift is also held.
-        // Meta doesn't kill it. Alt always kills the keypress, overriding 
other rules.
-        boolean hasModifiersThatResultInNoKeyPress =
-          altKey || (ctrlKey && !shiftKey);
-
-        if (typeInt == Event.ONKEYDOWN) {
-          if (isKeydownForInputKey) {
-            type = KeySignalType.INPUT;
-          } else if (computedKeyCode == KeyCodes.KEY_BACKSPACE ||
-              computedKeyCode == KeyCodes.KEY_DELETE) {
-            type = KeySignalType.DELETE;
-          } else if (NAVIGATION_KEYS.contains(computedKeyCode)) {
-            type = KeySignalType.NAVIGATION;
-          } else {
-            type = KeySignalType.NOEFFECT;
-          }
-        } else {
-          // Escape is the only non-input thing that has a keypress event
-          if (computedKeyCode == KeyCodes.KEY_ESCAPE) {
-            result.type = null;
-            return;
-          }
-          assert typeInt == Event.ONKEYPRESS;
-          // I think the guessCommandFromModifiers() check here isn't needed,
-          // but i feel safer putting it in.
-          type = KeySignalType.INPUT;
-        }
-
-        if (hasModifiersThatResultInNoKeyPress || isIME || computedKeyCode == 
KeyCodes.KEY_TAB) {
-          ret = typeInt == Event.ONKEYDOWN ? ret : false;
-        } else {
-          ret = maybeNullWebkitIE(ret, typeInt, type);
-        }
-        if (!ret) {
-          result.type = null;
-          return;
-        }
-        break;
-      default:
-        throw new UnsupportedOperationException("Unhandled user agent");
-    }
-
-    if (ret) {
-      result.type = type;
-      result.keyCode = computedKeyCode;
-    } else {
-      result.type = null;
-      return;
-    }
-  }
-
-  private static final boolean isInputKeyCodeIE(int keyCode) {
-    /*
-    DATA
-    ----
-    For KEYDOWN:
-
-    "Input"
-    48-57 (numbers)
-    65-90 (a-z)
-    96-111 (Numpad digits & other keys, with numlock off. with numlock on, they
-      behave like their corresponding keys on the rest of the keyboard)
-    186-192 219-222 (random non-alphanumeric next to letters on RHS + backtick)
-    229 Code that the input has passed to an IME
-
-    Non-"input"
-    < 48 ('0')
-    91-93 (Left & Right Win keys, ContextMenu key)
-    112-123 (F1-F12)
-    144-5 (NUMLOCK,SCROLL LOCK)
-
-    For KEYPRESS: only "input" things get this event! yay! not even backspace!
-    Well, one exception: ESCAPE
-    */
-    // boundaries in keycode ranges where the keycode for a keydown is for an 
input
-    // key. at "ON" it is, starting from the number going up, and the opposite 
for "OFF".
-    final int A_ON = 48;
-    final int B_OFF = 91;
-    final int C_ON = 96;
-    final int D_OFF = 112;
-    final int E_ON = 186;
-
-    return
-      (keyCode == 9 || keyCode == 32 || keyCode == 13) || // And tab, enter & 
spacebar, of course!
-      (keyCode >= A_ON && keyCode < B_OFF) ||
-      (keyCode >= C_ON && keyCode < D_OFF) ||
-      (keyCode >= E_ON);
-  }
-
-  /**
-   * Common logic between Webkit and IE for deciding whether we want the 
keydown
-   * or the keypress
-   */
-  private static boolean maybeNullWebkitIE(boolean ret, int typeInt,
-      KeySignalType type) {
-    // Use keydown as the signal for everything except input.
-    // This is because the mutation always happens after the keypress for
-    // input (this is especially important for chrome,
-    // which interleaves deferred commands between keydown and keypress).
-    //
-    // For everything else, keypress is redundant with keydown, and also, the 
resulting default
-    // dom mutation (if any) often happens after the keydown but before the 
keypress in webkit.
-    // Also, if the 'Command' key is held for chrome/safari etc, we want to 
get the keydown
-    // event, NOT the keypress event, for everything because of things like 
ctrl+c etc.
-    // where sometimes it'll happen just after the keydown, or sometimes we 
just won't
-    // get a keypress at all
-    if (typeInt == (type == KeySignalType.INPUT ? Event.ONKEYDOWN : 
Event.ONKEYPRESS)) {
-      return false;
-    }
-
-    return ret;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/wave/client/common/util/SimpleDoubleToIntMap.java
----------------------------------------------------------------------
diff --git 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/SimpleDoubleToIntMap.java
 
b/wave/src/main/java/org/waveprotocol/wave/client/common/util/SimpleDoubleToIntMap.java
deleted file mode 100644
index 0566bfc..0000000
--- 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/SimpleDoubleToIntMap.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.waveprotocol.wave.client.common.util;
-
-
-/**
- * Cut down map where the keys are unboxed doubles and the values are unboxed 
ints
- *
- * @author danila...@google.com (Daniel Danilatos)
- */
-public final class SimpleDoubleToIntMap extends JsoMapBase {
-
-  protected SimpleDoubleToIntMap() {}
-
-  /** Construct an empty SimpleDoubleMap */
-  public static native SimpleDoubleToIntMap create() /*-{
-     return {};
-   }-*/;
-
-  /**
-   * @param key
-   * @return true if a value indexed by the given key is in the map
-   */
-  public native boolean has(double key) /*-{
-     return this[key] !== undefined;
-   }-*/;
-
-  /**
-   * @param key
-   * @return The value with the given key, or null if not present
-   */
-  public native int get(double key) /*-{
-     return this[key];
-   }-*/;
-
-  /**
-   * Put the value in the map at the given key. Note: Does not return the old
-   * value.
-   *
-   * @param key
-   * @param value
-   */
-  public native void put(double key, int value) /*-{
-     this[key] = value;
-   }-*/;
-
-  /**
-   * Remove the value with the given key from the map. Note: does not return 
the
-   * old value.
-   *
-   * @param key
-   */
-  public native void remove(double key) /*-{
-     delete this[key];
-   }-*/;
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/wave/client/common/util/StringCodec.java
----------------------------------------------------------------------
diff --git 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/StringCodec.java 
b/wave/src/main/java/org/waveprotocol/wave/client/common/util/StringCodec.java
deleted file mode 100644
index aa6e7a0..0000000
--- 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/StringCodec.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.waveprotocol.wave.client.common.util;
-
-import com.google.gwt.core.client.GWT;
-
-
-/**
- * Provides cross-platform encoding and decoding of arbitrary strings.
- *
- */
-public interface StringCodec {
-  /**
-   * A basic codec that moves the string to an alphabet that does not include
-   * commas. Decoding restores the original string. This allows commas to be
-   * used to mark structure (like Godel numbering).
-   */
-  public StringCodec INSTANCE = GWT.isScript() ? new JsCodec() : new 
JavaCodec();
-
-  /**
-   * Encodes a string. This method provides the contract that, for any input
-   * string:
-   * <ul>
-   * <li>decode(encode(s)) == s; and</li>
-   * <li>encode(s) contains no characters from the set free()</li>
-   * </ul>
-   *
-   * @param s string to encode
-   * @return encoding of {@code s}
-   */
-  String encode(String s);
-
-  /**
-   * Decodes a string encoded by {@link #encode(String)}.
-   *
-   * @param s string to decode
-   * @return decoding of {@code s}
-   */
-  String decode(String s);
-
-  /** The characters that are removed from the alphabet encoded strings. */
-  String free();
-
-  //
-  // Default implementations below.
-  //
-  // Simple quotation logic:
-  // 1. & --> && (promotes & as the quote char)
-  // 2. , --> &c (removes commas from alphabet)
-  //
-  // Unquotation is the inverse:
-  // 1. &c --> , (reinserts commas into alphabet)
-  // 2. && --> & (demotes & from being the quote char)
-  //
-  //
-
-  final class JsCodec implements StringCodec {
-    @Override
-    public String free() {
-      return ",";
-    }
-
-    @Override
-    public native String encode(String s) /*-{
-      return s.replace(/&/g, "&&").replace(/,/g, "&c");
-    }-*/;
-
-    @Override
-    public native String decode(String s) /*-{
-      return s.replace(/&c/g, ",").replace(/&&/g, "&");
-    }-*/;
-  }
-
-  final class JavaCodec implements StringCodec {
-    @Override
-    public String free() {
-      return ",";
-    }
-
-    @Override
-    public String encode(String s) {
-      return s.replace("&", "&&").replace(",", "&c");
-    }
-
-    @Override
-    public String decode(String s) {
-      return s.replace("&c", ",").replace("&&", "&");
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/wave/client/common/util/StringSequence.java
----------------------------------------------------------------------
diff --git 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/StringSequence.java
 
b/wave/src/main/java/org/waveprotocol/wave/client/common/util/StringSequence.java
deleted file mode 100644
index 03785c2..0000000
--- 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/StringSequence.java
+++ /dev/null
@@ -1,330 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.waveprotocol.wave.client.common.util;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-
-import java.util.Collection;
-
-/**
- * Encodes a string sequence as a single string. As per the {@link Sequence}
- * interface, repeated strings are not supported.
- * <p>
- * The single string that holds the sequences is a comma-delimited list. There
- * are no restrictions on the strings that can be placed in this sequence -
- * strings are encoded and decoded appropriately. For example,
- *
- * <pre>
- * [&quot;foo&quot;, &quot;bar&quot;] --&gt; &quot;,foo,bar,&quot;
- * [&quot;foo,bar&quot;, &quot;foo&amp;baz&quot;] --&gt; 
&quot;,foo&amp;,bar,foo&amp;&amp;baz,&quot;
- * </pre>
- *
- * All random-access methods in this implementation are linear time, so a 
linear
- * number of accesses is quadratic in the worst case. This class expects a
- * sequential access pattern, and is implemented so that <em>m</em> sequential
- * queries on an <em>n</em>-sized sequence is only <em>O(n + m)</em>. This is
- * not true for mutations, however: a series of <em>m</em> mutations, 
sequential
- * or not, will be <em>O(nm)</em>. For a sequence implementation that provides
- * expected constant time complexity for all methods, see {@link 
LinkedSequence}.
- *
- */
-//
-// Unescaped version of the example above:
-// ["foo", "bar"] --> ",foo,bar,"
-// ["foo,bar", "baz&quux"] --> ",foo&cbar,baz&&quux,"
-//
-public final class StringSequence implements Sequence<String> {
-  /** Codec to use for encoding / decoding values in the list. */
-  private static final StringCodec CODEC = StringCodec.INSTANCE;
-
-  /** String to demarcate items in the list. */
-  private static final String DELIMITER = CODEC.free().substring(0, 1);
-
-  /**
-   * Embedded list. Never null, and is always is of the form: DELIMITER
-   * (NONDELIMITER+ DELIMITER)*.
-   */
-  // Note: composite linear complexity for sequential writes (i.e., m 
sequential
-  // writes is only O(n + m)) could be achieved by alternating between a
-  // serialized string and a stringbuffer of pending sequential mutations. This
-  // is not implemented in order to keep this implementation very lightweight.
-  private String data;
-
-  /**
-   * Last index used in a reference search. This is used to optimize for
-   * sequential access, so that m queries cost (n + m) rather than O(nm).
-   */
-  private int recentIndex;
-
-  @VisibleForTesting
-  StringSequence(String data) {
-    this.data = data;
-  }
-
-  /** Creates an empty string sequence. */
-  public static StringSequence create() {
-    return new StringSequence(DELIMITER);
-  }
-
-  /** Creates a string sequence on a string from another {@code 
StringSequence}. */
-  public static StringSequence create(String serializedSequence) {
-    Preconditions.checkArgument(serializedSequence.startsWith(DELIMITER)
-        && serializedSequence.endsWith(DELIMITER));
-    return new StringSequence(serializedSequence);
-  }
-
-  /** Creates a string sequence with an initial state. */
-  public static StringSequence of(Collection<String> xs) {
-    StringBuilder data = new StringBuilder();
-    data.append(DELIMITER);
-    for (String x : xs) {
-      data.append(CODEC.encode(x));
-      data.append(DELIMITER);
-    }
-    return new StringSequence(data.toString());
-  }
-
-  // JS does not do automatic builderization of composite concatentaions.
-  /** Concatenates strings. */
-  private static String concat(String s1, String s2, String s3) {
-    StringBuilder s = new StringBuilder();
-    s.append(s1);
-    s.append(s2);
-    s.append(s3);
-    return s.toString();
-  }
-
-  /** Concatenates strings. */
-  private static String concat(String s1, String s2, String s3, String s4) {
-    StringBuilder s = new StringBuilder();
-    s.append(s1);
-    s.append(s2);
-    s.append(s3);
-    s.append(s4);
-    return s.toString();
-  }
-
-  @Override
-  public boolean contains(String x) {
-    return data.contains(concat(DELIMITER, CODEC.encode(x), DELIMITER));
-  }
-
-  /**
-   * Finds a term in the data string. The search is initiated from the location
-   * of the most recent hit.
-   *
-   * @param term (coded) term to search for
-   * @param forwardFirst if true, the search is performed with a forward search
-   *        then a backward search; if false, the search is performed with a
-   *        backward search then a forward search;
-   * @return the index after {@code term} for a forward search; the index of
-   *         {@code} term for a backward search.
-   * @throws IllegalArgumentException if {@code term} is not found.
-   */
-  private int find(String term, boolean forwardFirst) {
-    int index;
-
-    if (forwardFirst) {
-      // Search forward, leaving cursor after the find.
-      index = data.indexOf(term, recentIndex);
-      if (index >= 0) {
-        return recentIndex = index + term.length();
-      }
-
-      // Search backward, leaving cursor after the find.
-      index = data.lastIndexOf(term, recentIndex);
-      if (index >= 0) {
-        return recentIndex = index + term.length();
-      }
-    } else {
-      // Search backward, leaving cursor before the find.
-      index = data.lastIndexOf(term, recentIndex);
-      if (index >= 0) {
-        return recentIndex = index;
-      }
-
-      // Search forward, leaving cursor before the find.
-      index = data.indexOf(term, recentIndex);
-      if (index >= 0) {
-        return recentIndex = index;
-      }
-    }
-
-    // Miss.
-    throw new IllegalArgumentException("Item not found: "
-        + CODEC.decode(term.substring(DELIMITER.length(), term.length() - 
DELIMITER.length())));
-  }
-
-  private int findForward(String term) {
-    return find(term, true);
-  }
-
-  private int findBackward(String term) {
-    return find(term, false);
-  }
-
-  @Override
-  public String getFirst() {
-    //
-    // , f o o , ... , b a r ,
-    // . ^ first
-    //
-    recentIndex = DELIMITER.length();
-    return recentIndex == data.length() ? null // \u2620
-        : CODEC.decode(data.substring(recentIndex, data.indexOf(DELIMITER, 
recentIndex)));
-  }
-
-  @Override
-  public String getLast() {
-    //
-    // , f o o , ... , b a r ,
-    // 0 1 . . . ... . . . . ^ last
-    //
-    recentIndex = data.length() - DELIMITER.length();
-    return recentIndex == 0 ? null // \u2620
-        : CODEC.decode(data.substring(data.lastIndexOf(DELIMITER, recentIndex 
- 1)
-            + DELIMITER.length(), recentIndex));
-  }
-
-  @Override
-  public String getNext(String x) {
-    if (x == null) {
-      return getFirst();
-    }
-    //
-    // if x = "foobar", then
-    // , ... , f o o b a r , b a z q u u x , ... ,
-    // . . . ^ index . . . . ^ nextStart . ^ nextEnd
-    //
-    String coded = concat(DELIMITER, CODEC.encode(x), DELIMITER);
-    int nextStart = findForward(coded);
-    if (nextStart == data.length()) {
-      return null;
-    } else {
-      int nextEnd = data.indexOf(DELIMITER, nextStart);
-      return CODEC.decode(data.substring(nextStart, nextEnd));
-    }
-  }
-
-  @Override
-  public String getPrevious(String x) {
-    if (x == null) {
-      return getLast();
-    }
-    //
-    // if x = "foobar", then
-    // , ... , b a z q u u x , f o o b a r , ... ,
-    // . . . . ^ prevStart . ^ index / prevEnd
-    //
-    String coded = concat(DELIMITER, CODEC.encode(x), DELIMITER);
-    int prevEnd = findBackward(coded);
-    if (prevEnd == 0) {
-      return null;
-    } else {
-      int prevStart = data.lastIndexOf(DELIMITER, prevEnd - 1) + 
DELIMITER.length();
-      return CODEC.decode(data.substring(prevStart, prevEnd));
-    }
-  }
-
-  @Override
-  public boolean isEmpty() {
-    // Being shorter than DELIMITER is impossible, due to data's invariant.
-    return data.length() == DELIMITER.length();
-  }
-
-  /**
-   * Inserts a value before a reference item.
-   *
-   * @param ref reference value (or {@code null} for append)
-   * @param x value to insert
-   * @throws IllegalArgumentException if {@code x} is null, or {@code ref} is
-   *         non-null and not in this sequence.
-   */
-  public void insertBefore(String ref, String x) {
-    Preconditions.checkArgument(x != null, "null item");
-    if (ref == null) {
-      data += CODEC.encode(x) + DELIMITER;
-    } else {
-      // if ref = "foobar", then
-      // , ... , b a z q u u x , f o o b a r , ... ,
-      // . . . . . . . . . . . ^ refIndex
-      String codedRef = concat(DELIMITER, CODEC.encode(ref), DELIMITER);
-      int refIndex = findBackward(codedRef);
-      data =
-          concat(data.substring(0, refIndex), DELIMITER, CODEC.encode(x), 
data.substring(refIndex));
-    }
-  }
-
-  /**
-   * Inserts a value after a reference item.
-   *
-   * @param ref reference value (or {@code null} for prepend)
-   * @param x value to insert
-   * @throws IllegalArgumentException if {@code x} is null, or {@code ref} is
-   *         non-null and not in this sequence.
-   */
-  public void insertAfter(String ref, String x) {
-    Preconditions.checkArgument(x != null, "null item");
-    if (ref == null) {
-      data = DELIMITER + CODEC.encode(x) + data;
-    } else {
-      // if ref = "foobar", then
-      // , ... , f o o b a r , b a z q u u x , ... ,
-      // . . . ^refIndex . . . ^refIndex'
-      String codedRef = concat(DELIMITER, CODEC.encode(ref), DELIMITER);
-      int refIndex = findForward(codedRef);
-      data =
-          concat(data.substring(0, refIndex), CODEC.encode(x), DELIMITER, 
data.substring(refIndex));
-    }
-  }
-
-  /**
-   * Removes a value from this sequence.
-   *
-   * @param x
-   * @throws IllegalArgumentException if {@code x} is null or not in this
-   *         sequence.
-   */
-  public void remove(String x) {
-    // if ref = "foobar", then
-    // , ... , b a r , f o o , b a z , ... ,
-    // . . . . . . . ^refIndex
-    Preconditions.checkArgument(x != null, "null item");
-    String coded = concat(DELIMITER, CODEC.encode(x), DELIMITER);
-    int index = findBackward(coded);
-    data = data.substring(0, index) + data.substring(index + coded.length() - 
DELIMITER.length());
-    // Reminder that the trailing delimiter is there.
-    assert data.startsWith(DELIMITER, index);
-  }
-
-  /**
-   * Clears all entries from this sequence.
-   */
-  public void clear() {
-    data = DELIMITER;
-    recentIndex = 0;
-  }
-
-  /** @return the underyling data in which strings are embedded. */
-  public String getRaw() {
-    return data;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/wave/client/common/util/StringUtil.java
----------------------------------------------------------------------
diff --git 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/StringUtil.java 
b/wave/src/main/java/org/waveprotocol/wave/client/common/util/StringUtil.java
deleted file mode 100644
index 933d88a..0000000
--- 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/StringUtil.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.waveprotocol.wave.client.common.util;
-
-/**
- * String functions.
- *
- */
-public class StringUtil {
-
-  /**
-   * @param xml
-   * @return XML-escaped string
-   */
-  public static String xmlEscape(String xml) {
-    return xml
-        .replaceAll("&", "&amp;")
-        .replaceAll("<", "&lt;")
-        .replaceAll(">", "&gt;");
-  }
-
-  /**
-   * Notice that this function only escape entity reference and not character 
reference.
-   * @param xml
-   * @return the unescaped xml string.
-   */
-  public static String xmlUnescape(String xml) {
-    return  xml
-        .replaceAll("&lt;", "<")
-        .replaceAll("&gt;", ">")
-        .replaceAll("&quot;", "\"")
-        .replaceAll("&apos;", "'")
-        .replaceAll("&amp;", "&");
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/wave/client/common/util/UserAgent.java
----------------------------------------------------------------------
diff --git 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/UserAgent.java 
b/wave/src/main/java/org/waveprotocol/wave/client/common/util/UserAgent.java
deleted file mode 100644
index 90e469c..0000000
--- a/wave/src/main/java/org/waveprotocol/wave/client/common/util/UserAgent.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.waveprotocol.wave.client.common.util;
-
-
-/**
- * Information about the current user agent. Some of the information is
- * dynamically determined at runtime, other information is determined at 
compile
- * time as it is baked into the particular permutation with the deferred 
binding
- * mechanism.
- *
- * Methods that are statically evaluable allow conditional compilation for
- * different user agents.
- *
- * e.g. currently, the following code:
- *
- *   if (UserAgent.isIE()) {
- *     // do IE-specific implementation
- *   } else {
- *     // do non-IE implementation
- *   }
- *
- * should for "user.agent" set to "ie6" compile down to just the IE-specific
- * implementation.
- *
- * It is not exposed as part of this API which methods are statically 
determined
- * and which are not, as this may be subject to change. In general it should 
not
- * matter as the cost of a runtime check is very cheap. If it does matter, it 
is
- * up to the caller to know and keep track of the current state of affairs.
- *
- */
-public abstract class UserAgent {
-
-  /**
-   * @return true iff the user agent uses webkit
-   */
-  public static boolean isWebkit() {
-    return UserAgentStaticProperties.get().isWebkit();
-  }
-
-  /**
-   * @return true iff the user agent uses mobile webkit
-   */
-  public static boolean isMobileWebkit() {
-    return UserAgentStaticProperties.get().isMobileWebkit();
-  }
-
-  /**
-   * @return true iff the user.agent GWT property is "safari"
-   */
-  public static boolean isSafari() {
-    return UserAgentStaticProperties.get().isSafari();
-  }
-
-  /**
-   * @return true iff the user.agent GWT property is "gecko" or "gecko1_8"
-   */
-  public static boolean isFirefox() {
-    return UserAgentStaticProperties.get().isFirefox();
-  }
-
-  /**
-   * @return true iff the user.agent GWT property is "ie6"
-   */
-  public static boolean isIE() {
-    return UserAgentStaticProperties.get().isIE();
-  }
-
-  /**
-   * @return true iff the user.agent GWT property is "android"
-   */
-  public static boolean isAndroid() {
-    return UserAgentStaticProperties.get().isAndroid();
-  }
-
-  /**
-   * @return true iff the user.agent GWT property is "iphone"
-   */
-  public static boolean isIPhone() {
-    return UserAgentStaticProperties.get().isIPhone();
-  }
-
-  /**
-   * @return true if this is the chrome browser
-   */
-  public static boolean isChrome() {
-    return UserAgentRuntimeProperties.get().isChrome();
-  }
-
-  public static boolean isIE7() {
-    return UserAgentRuntimeProperties.get().isIe7();
-  }
-
-  public static boolean isIE8() {
-    return UserAgentRuntimeProperties.get().isIe8();
-  }
-
-  /**
-   * @return true if we are on OSX
-   */
-  public static boolean isMac() {
-    return UserAgentRuntimeProperties.get().isMac();
-  }
-
-  /**
-   * @return true if we are on Windows
-   */
-  public static boolean isWin() {
-    return UserAgentRuntimeProperties.get().isWin();
-  }
-
-  /**
-   * @return true if we are on Linux
-   */
-  public static boolean isLinux() {
-    return UserAgentRuntimeProperties.get().isLinux();
-  }
-
-  /**
-   * Debug method that returns the user-agent string.
-   *
-   * NOTE(user): FOR DEBUGGING PURPOSES ONLY. DO NOT USE FOR PROGRAM LOGIC.
-   */
-  public static String debugUserAgentString() {
-    return UserAgentRuntimeProperties.get().getUserAgent();
-  }
-
-  /**
-   * @return whether the current user agent version is at least the one given 
by
-   *         the method parameters.
-   */
-  public static boolean isAtLeastVersion(int major, int minor) {
-    return UserAgentRuntimeProperties.get().isAtLeastVersion(major, minor);
-  }
-
-  /**
-   * Do not use this for program logic - for debugging only. For program logic,
-   * instead use {@link #isAtLeastVersion(int, int)}
-   */
-  public static int debugGetMajorVer() {
-    return UserAgentRuntimeProperties.get().getMajorVer();
-  }
-
-  /**
-   * Do not use this for program logic - for debugging only. For program logic,
-   * instead use {@link #isAtLeastVersion(int, int)}
-   */
-  public static int debugGetMinorVer() {
-    return UserAgentRuntimeProperties.get().getMinorVer();
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/051db092/wave/src/main/java/org/waveprotocol/wave/client/common/util/UserAgentRuntimeProperties.java
----------------------------------------------------------------------
diff --git 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/UserAgentRuntimeProperties.java
 
b/wave/src/main/java/org/waveprotocol/wave/client/common/util/UserAgentRuntimeProperties.java
deleted file mode 100644
index 2cab1b5..0000000
--- 
a/wave/src/main/java/org/waveprotocol/wave/client/common/util/UserAgentRuntimeProperties.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.waveprotocol.wave.client.common.util;
-
-import com.google.gwt.core.client.GWT;
-
-import org.waveprotocol.wave.model.util.Box;
-import com.google.common.annotations.VisibleForTesting;
-
-/**
- * Class to contain run-time checks of a user-agent's capabilities.
- *
- *
- */
-@VisibleForTesting
-public class UserAgentRuntimeProperties {
-  private static final UserAgentRuntimeProperties INSTANCE = createInstance();
-
-  private static UserAgentRuntimeProperties createInstance() {
-    return GWT.isClient() ? new 
UserAgentRuntimeProperties(getNativeUserAgent())
-                          : new UserAgentRuntimeProperties("");
-  }
-
-  @VisibleForTesting
-  public static UserAgentRuntimeProperties get() {
-    return INSTANCE;
-  }
-
-  private final String userAgent;
-  private final int version;
-  private final boolean isMac;
-  private final boolean isWin;
-  private final boolean isLinux;
-  private final boolean isIe7;
-  private final boolean isIe8;
-  private final boolean isChrome;
-
-  @VisibleForTesting
-  public UserAgentRuntimeProperties(String userAgent) {
-    this.userAgent = userAgent;
-    this.version = calculateVersion(userAgent);
-    this.isMac = calculateIsMac(userAgent);
-    this.isWin = calculateIsWin(userAgent);
-    this.isLinux = calculateIsLinux(userAgent);
-    this.isIe7 = calculateIe7(userAgent);
-    this.isIe8 = calculateIe8(userAgent);
-    this.isChrome = calculateIsChrome(userAgent);
-  }
-
-  @VisibleForTesting
-  public String getUserAgent() {
-    return userAgent;
-  }
-
-  @VisibleForTesting
-  public boolean isMac() {
-    return isMac;
-  }
-
-  @VisibleForTesting
-  public boolean isWin() {
-    return isWin;
-  }
-
-  @VisibleForTesting
-  public boolean isLinux() {
-    return isLinux;
-  }
-
-  @VisibleForTesting
-  public boolean isIe7() {
-    return isIe7;
-  }
-
-  @VisibleForTesting
-  public boolean isIe8(){
-    return isIe8;
-  }
-
-  @VisibleForTesting
-  public boolean isChrome() {
-    return isChrome;
-  }
-
-  /**
-   * @return whether the current user agent version is at least the one given 
by
-   *         the method parameters.
-   */
-  @VisibleForTesting
-  public boolean isAtLeastVersion(int major, int minor) {
-    return version >= (major * 1000 + minor);
-  }
-
-  /**
-   * Do not use this for program logic - for debugging only. For program logic,
-   * instead use {@link #isAtLeastVersion(int, int)}
-   */
-  @VisibleForTesting
-  public int getMajorVer() {
-    return version / 1000;
-  }
-
-  /**
-   * Do not use this for program logic - for debugging only. For program logic,
-   * instead use {@link #isAtLeastVersion(int, int)}
-   */
-  @VisibleForTesting
-  public int getMinorVer() {
-    return version % 1000;
-  }
-
-  private static native String getNativeUserAgent() /*-{
-    return navigator.userAgent;
-  }-*/;
-
-  private static boolean calculateIe7(String userAgent) {
-    return userAgent.indexOf(" MSIE 7.") != -1;
-  }
-
-  private static boolean calculateIe8(String userAgent) {
-    return userAgent.indexOf(" MSIE 8.") != -1;
-  }
-
-  private static boolean calculateIsMac(String userAgent) {
-    return userAgent.indexOf("Mac") != -1;
-  }
-
-  private static boolean calculateIsWin(String userAgent) {
-    return userAgent.indexOf("Windows") != -1;
-  }
-
-  private static boolean calculateIsLinux(String userAgent) {
-    return userAgent.indexOf("Linux") != -1;
-  }
-
-  private static boolean calculateIsChrome(String userAgent) {
-    return userAgent.indexOf("Chrome") != -1;
-  }
-
-  private static int calculateVersion(String userAgent) {
-    if (userAgent == null || userAgent.isEmpty()) {
-      return -1;
-    }
-
-//  TODO(user): Make this work after regex deps are fixed and don't break 
static rendering
-//
-//    String regexps[] = {"firefox.([0-9]+).([0-9]+)",
-//                        "webkit.([0-9]+).([0-9]+)",
-//                        "msie.([0-9]+).([0-9]+)",
-//                        "minefield.([0-9]+).([0-9]+)"};
-
-
-//  TODO(user): Don't use "firefox" and "minefield", check Gecko rv.
-    String names[] = {"firefox", "webkit", "msie", "minefield"};
-
-    for (String name : names) {
-      int v = calculateVersion(name, userAgent);
-      if (v >= 0) {
-        return v;
-      }
-    }
-    return -1;
-  }
-
-//  /**
-//   * Matches a browser-specific regular expression against the user agent to
-//   * obtain a version number.
-//   *
-//   * @param regexp The browser-specific regular expression to use
-//   * @param userAgent The user agent string to check
-//   * @return A version number or -1 if unknown
-//   */
-  /**
-   * Matches a browser-specific name against the user agent to obtain a version
-   * number.
-   *
-   * @param name The browser-specific name to use
-   * @param userAgent The user agent string to check
-   * @return A version number or -1 if unknown
-   */
-  private static int calculateVersion(String name, String userAgent) {
-    int index = userAgent.toLowerCase().indexOf(name);
-    if (index == -1) {
-      return -1;
-    }
-
-    Box<Integer> output = Box.create();
-
-    index += name.length() + 1;
-
-    if ((index = consumeDigit(index, userAgent, output)) == -1) {
-      return -1;
-    }
-    int major = output.boxed;
-
-    index++;
-
-    if ((index = consumeDigit(index, userAgent, output)) == -1) {
-      return -1;
-    }
-    int minor = output.boxed;
-
-    return major * 1000 + minor;
-
-//  TODO(user): Make this work after regex deps are fixed and don't break 
static rendering
-//
-//    RegExp pattern = RegExp.compile(regexp);
-//    MatchResult result = pattern.exec(userAgent.toLowerCase());
-//    if (result != null && result.getGroupCount() == 3) {
-//      int major = Integer.parseInt(result.getGroup(1));
-//      int minor = Integer.parseInt(result.getGroup(2));
-//      return major * 1000 + minor;
-//    }
-//    return -1;
-  }
-
-  private static int consumeDigit(int index, String str, Box<Integer> output) {
-    StringBuilder nb = new StringBuilder();
-
-    char c;
-    while (index < str.length() && Character.isDigit( (c = str.charAt(index)) 
)) {
-      nb.append(c);
-      index++;
-    }
-
-    if (nb.length() == 0) {
-      return -1;
-    }
-
-    try {
-      output.boxed = Integer.parseInt(nb.toString());
-      return index;
-    } catch (NumberFormatException e) {
-      return -1;
-    }
-  }
-
-}

Reply via email to