Remove ListModel and add ListView/ListView.Delegate; clean up javadoc

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


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7904 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/bikeshed/src/com/google/gwt/bikeshed/cells/client/ActionCell.java b/bikeshed/src/com/google/gwt/bikeshed/cells/client/ActionCell.java
index 823eaaf..8e40523 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/cells/client/ActionCell.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/cells/client/ActionCell.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -21,12 +21,12 @@
 /**
  * A cell that renders a button and takes a delegate to perform actions on
  * mouseUp.
- * 
+ *
  * @param <C> the type that this Cell represents
  */
 public class ActionCell<C> extends Cell<C, Void> {
   /**
-   * @param <C> the type that this delegate acts on
+   * @param <T> the type that this delegate acts on
    */
   public interface Delegate<T> {
     void execute(T object);
diff --git a/bikeshed/src/com/google/gwt/bikeshed/cells/client/EditTextCell.java b/bikeshed/src/com/google/gwt/bikeshed/cells/client/EditTextCell.java
index d19822a..91dc6cc 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/cells/client/EditTextCell.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/cells/client/EditTextCell.java
@@ -31,7 +31,7 @@
     if (viewData != null) {
       return editEvent(parent, value, viewData, event, valueUpdater);
     }
-    return nonEditEvent(parent, value, viewData, event, valueUpdater);
+    return nonEditEvent(parent, value, event);
   }
 
   @Override
@@ -78,11 +78,10 @@
     return viewData;
   }
 
-  private String nonEditEvent(Element parent, String value, String viewData,
-      NativeEvent event, ValueUpdater<String, String> valueUpdater) {
+  private String nonEditEvent(Element parent, String value, NativeEvent event) {
     if ("click".equals(event.getType())) {
       return edit(parent, value);
     }
-    return viewData;
+    return null;
   }
 }
diff --git a/bikeshed/src/com/google/gwt/bikeshed/cells/client/ValueUpdater.java b/bikeshed/src/com/google/gwt/bikeshed/cells/client/ValueUpdater.java
index 3fead87..3a630c6 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/cells/client/ValueUpdater.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/cells/client/ValueUpdater.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -17,16 +17,16 @@
 
 /**
  * A {@link ValueUpdater} may be added to a Cell to provide updated data.
- * 
+ *
  * @param <C> the data type of the cell
  * @param <V> the data type of view data associated with the cell
  */
 public interface ValueUpdater<C, V> {
-  
+
   /**
    * Announces a new value.
-   * 
-   * @param value the updated value.
+   *
+   * @param value the updated value
    */
   void update(C value, V viewData);
 }
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/client/ListView.java b/bikeshed/src/com/google/gwt/bikeshed/list/client/ListView.java
new file mode 100644
index 0000000..b23145e
--- /dev/null
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/client/ListView.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.bikeshed.list.client;
+
+import com.google.gwt.bikeshed.list.shared.ListEvent;
+import com.google.gwt.bikeshed.list.shared.Range;
+import com.google.gwt.bikeshed.list.shared.SizeChangeEvent;
+
+/**
+ * A list view.
+ *
+ * @param <T> the data type of each row
+ */
+public interface ListView<T> {
+
+  /**
+   * A list view delegate, implemented by classes that supply data to a view.
+   *
+   * @param <T> the data type of each row
+   */
+  public interface Delegate<T> {
+    void onRangeChanged(ListView<T> listView);
+  }
+
+  void setDelegate(Delegate<T> delegate);
+
+  Range getRange();
+
+  // TODO - rename to setData, don't use event?
+  void onDataChanged(ListEvent<T> event);
+
+  // TODO - rename to setDataSize, don't use event?
+  void onSizeChanged(SizeChangeEvent event);
+}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/client/PagingTableListView.java b/bikeshed/src/com/google/gwt/bikeshed/list/client/PagingTableListView.java
index d24666b..d883ac9 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/client/PagingTableListView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/client/PagingTableListView.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -16,11 +16,11 @@
 package com.google.gwt.bikeshed.list.client;
 
 import com.google.gwt.bikeshed.list.shared.ListEvent;
-import com.google.gwt.bikeshed.list.shared.ListHandler;
-import com.google.gwt.bikeshed.list.shared.ListModel;
-import com.google.gwt.bikeshed.list.shared.ListRegistration;
+import com.google.gwt.bikeshed.list.shared.ProvidesKey;
+import com.google.gwt.bikeshed.list.shared.Range;
 import com.google.gwt.bikeshed.list.shared.SelectionModel;
 import com.google.gwt.bikeshed.list.shared.SizeChangeEvent;
+import com.google.gwt.bikeshed.list.shared.AbstractListViewAdapter.DefaultRange;
 import com.google.gwt.bikeshed.list.shared.SelectionModel.SelectionChangeEvent;
 import com.google.gwt.bikeshed.list.shared.SelectionModel.SelectionChangeHandler;
 import com.google.gwt.dom.client.Document;
@@ -43,10 +43,10 @@
 
 /**
  * A list view that supports paging and columns.
- * 
- * @param <T> the data type of each row.
+ *
+ * @param <T> the data type of each row
  */
-public class PagingTableListView<T> extends Widget {
+public class PagingTableListView<T> extends Widget implements ListView<T> {
 
   private class TableSelectionHandler implements SelectionChangeHandler {
     public void onSelectionChange(SelectionChangeEvent event) {
@@ -57,13 +57,12 @@
   protected int curPage;
   private List<Column<T, ?, ?>> columns = new ArrayList<Column<T, ?, ?>>();
   private ArrayList<T> data = new ArrayList<T>();
+  private Delegate<T> delegate;
   private List<Header<?>> footers = new ArrayList<Header<?>>();
   private List<Header<?>> headers = new ArrayList<Header<?>>();
-  private ListRegistration<T> listReg;
-  private ListModel<T> listModel;
   private int numPages;
-
   private int pageSize;
+  private ProvidesKey<T> providesKey;
   private HandlerRegistration selectionHandler;
   private SelectionModel<T> selectionModel;
 
@@ -74,8 +73,8 @@
   private TableSectionElement thead;
   private int totalSize;
 
-  public PagingTableListView(ListModel<T> listModel, final int pageSize) {
-    this.listModel = listModel;
+  public PagingTableListView(ProvidesKey<T> providesKey, final int pageSize) {
+    this.providesKey = providesKey;
     this.pageSize = pageSize;
     setElement(table = Document.get().createTableElement());
     thead = table.createTHead();
@@ -97,10 +96,6 @@
     addColumn(col, header, null);
   }
 
-  public void addColumn(Column<T, ?, ?> col, String headerString) {
-    addColumn(col, new TextHeader(headerString), null);
-  }
-
   // TODO: remove(Column)
   public void addColumn(Column<T, ?, ?> col, Header<?> header, Header<?> footer) {
     headers.add(header);
@@ -111,6 +106,10 @@
     setPage(curPage); // TODO: better way to refresh?
   }
 
+  public void addColumn(Column<T, ?, ?> col, String headerString) {
+    addColumn(col, new TextHeader(headerString), null);
+  }
+
   // TODO - bounds check
   public T getDisplayedItem(int indexOnPage) {
     if (indexOnPage < 0 || indexOnPage >= getNumDisplayedItems()) {
@@ -129,7 +128,7 @@
 
   /**
    * Get the current page.
-   * 
+   *
    * @return the current page
    */
   public int getPage() {
@@ -140,6 +139,10 @@
     return pageSize;
   }
 
+  public Range getRange() {
+    return new DefaultRange(curPage * pageSize, pageSize);
+  }
+
   public void nextPage() {
     setPage(curPage + 1);
   }
@@ -172,16 +175,32 @@
       Column<T, ?, ?> column = columns.get(col);
 
       column.onBrowserEvent(cell, curPage * pageSize + row, value, event,
-          listModel);
+          providesKey);
     }
   }
 
+  public void onDataChanged(ListEvent<T> event) {
+    render(event.getStart(), event.getLength(), event.getValues());
+  }
+
+  public void onSizeChanged(SizeChangeEvent event) {
+    totalSize = event.getSize();
+    if (totalSize <= 0) {
+      numPages = 0;
+    } else {
+      numPages = 1 + (totalSize - 1) / pageSize;
+    }
+    setPage(curPage);
+  }
+
   public void previousPage() {
     setPage(curPage - 1);
   }
 
   public void refresh() {
-    listReg.setRangeOfInterest(curPage * pageSize, pageSize);
+    if (delegate != null) {
+      delegate.onRangeChanged(this);
+    }
     updateRowVisibility();
   }
 
@@ -210,9 +229,16 @@
     }
   }
 
+  public void setDelegate(Delegate<T> delegate) {
+    this.delegate = delegate;
+    if (delegate != null) {
+      delegate.onRangeChanged(this);
+    }
+  }
+
   /**
    * Set the current visible page.
-   * 
+   *
    * @param page the page index
    */
   public void setPage(int page) {
@@ -225,7 +251,9 @@
     // Early exit if we are already on the right page.
     if (curPage != newPage) {
       curPage = newPage;
-      listReg.setRangeOfInterest(curPage * pageSize, pageSize);
+      if (delegate != null) {
+        delegate.onRangeChanged(this);
+      }
     }
 
     updateRowVisibility();
@@ -233,7 +261,7 @@
 
   /**
    * Set the number of rows per page.
-   * 
+   *
    * @param pageSize the page size
    */
   public void setPageSize(int pageSize) {
@@ -262,24 +290,6 @@
     if (selectionModel != null) {
       selectionHandler = selectionModel.addSelectionChangeHandler(new TableSelectionHandler());
     }
-
-    // Attach to the list model.
-    listReg = listModel.addListHandler(new ListHandler<T>() {
-      public void onDataChanged(ListEvent<T> event) {
-        render(event.getStart(), event.getLength(), event.getValues());
-      }
-
-      public void onSizeChanged(SizeChangeEvent event) {
-        totalSize = event.getSize();
-        if (totalSize <= 0) {
-          numPages = 0;
-        } else {
-          numPages = 1 + (totalSize - 1) / pageSize;
-        }
-        setPage(curPage);
-      }
-    });
-    listReg.setRangeOfInterest(curPage * pageSize, pageSize);
   }
 
   @Override
@@ -289,12 +299,6 @@
       selectionHandler.removeHandler();
       selectionHandler = null;
     }
-
-    // Detach from the list model.
-    if (listReg != null) {
-      listReg.removeHandler();
-      listReg = null;
-    }
   }
 
   protected void render(int start, int length, List<T> values) {
@@ -396,7 +400,7 @@
 
   /**
    * Update the text that shows the current page.
-   * 
+   *
    * @param page the current page
    */
   private void updatePageText(int page) {
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/client/SimpleCellList.java b/bikeshed/src/com/google/gwt/bikeshed/list/client/SimpleCellList.java
index 3f700b7..7738c44 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/client/SimpleCellList.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/client/SimpleCellList.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -18,10 +18,9 @@
 import com.google.gwt.bikeshed.cells.client.Cell;
 import com.google.gwt.bikeshed.cells.client.ValueUpdater;
 import com.google.gwt.bikeshed.list.shared.ListEvent;
-import com.google.gwt.bikeshed.list.shared.ListHandler;
-import com.google.gwt.bikeshed.list.shared.ListModel;
-import com.google.gwt.bikeshed.list.shared.ListRegistration;
+import com.google.gwt.bikeshed.list.shared.Range;
 import com.google.gwt.bikeshed.list.shared.SizeChangeEvent;
+import com.google.gwt.bikeshed.list.shared.AbstractListViewAdapter.DefaultRange;
 import com.google.gwt.dom.client.DivElement;
 import com.google.gwt.dom.client.Document;
 import com.google.gwt.dom.client.Element;
@@ -34,34 +33,32 @@
 
 /**
  * A single column list of cells.
- * 
+ *
  * @param <T> the data type of list items
  */
-public class SimpleCellList<T> extends Widget {
+public class SimpleCellList<T> extends Widget implements ListView<T> {
 
   private final Cell<T, Void> cell;
   private final ArrayList<T> data = new ArrayList<T>();
+  private Delegate<T> delegate;
   private int increment;
   private int initialMaxSize;
   private int maxSize;
-  private ListModel<T> model;
-  private ListRegistration<T> reg;
   private int seq; // for debugging - TODO: remove
   private final Element showFewerElem;
   private final Element showMoreElem;
   private int size;
   private final Element tmpElem;
   private ValueUpdater<T, Void> valueUpdater;
-  public SimpleCellList(ListModel<T> model, Cell<T, Void> cell, int maxSize,
-      int increment) {
+
+  public SimpleCellList(Cell<T, Void> cell, int maxSize, int increment) {
     this.initialMaxSize = this.maxSize = maxSize;
     this.increment = increment;
-    this.model = model;
     this.cell = cell;
     this.seq = 0;
-    
+
     tmpElem = Document.get().createDivElement();
-    
+
     showMoreElem = Document.get().createDivElement();
     showMoreElem.setInnerHTML("<button>Show more</button>");
 
@@ -82,15 +79,25 @@
     sinkEvents(Event.ONCHANGE);
   }
 
+  public Range getRange() {
+    return new DefaultRange(0, maxSize);
+  }
+
   @Override
   public void onBrowserEvent(Event event) {
     Element target = event.getEventTarget().cast();
     if (target.getParentElement() == showMoreElem) {
       this.maxSize += increment;
-      reg.setRangeOfInterest(0, maxSize);
+      sizeChanged();
+      if (delegate != null) {
+        delegate.onRangeChanged(this);
+      }
     } else if (target.getParentElement() == showFewerElem) {
       this.maxSize = Math.max(initialMaxSize, maxSize - increment);
-      reg.setRangeOfInterest(0, maxSize);
+      sizeChanged();
+      if (delegate != null) {
+        delegate.onRangeChanged(this);
+      }
     } else {
       String idxString = "";
       while ((target != null)
@@ -103,87 +110,76 @@
       }
     }
   }
-  
+
+  public void onDataChanged(ListEvent<T> event) {
+    int start = event.getStart();
+    int len = event.getLength();
+    List<T> values = event.getValues();
+
+    // Construct a run of element from start (inclusive) to start + len (exclusive)
+    StringBuilder sb = new StringBuilder();
+    for (int i = 0; i < len; i++) {
+      sb.append("<div __idx='" + (start + i) + "' __seq='" + seq++ + "'>");
+      cell.render(values.get(i), null, sb);
+      sb.append("</div>");
+    }
+
+    Element parent = getElement().getFirstChildElement();
+    if (start == 0 && len == maxSize) {
+      parent.setInnerHTML(sb.toString());
+    } else {
+      makeElements();
+      tmpElem.setInnerHTML(sb.toString());
+      for (int i = 0; i < len; i++) {
+        Element child = parent.getChild(start + i).cast();
+        parent.replaceChild(tmpElem.getChild(0), child);
+      }
+    }
+  }
+
+  public void onSizeChanged(SizeChangeEvent event) {
+    size = event.getSize();
+    sizeChanged();
+  }
+
+  public void setDelegate(Delegate<T> delegate) {
+    this.delegate = delegate;
+    if (delegate != null) {
+      delegate.onRangeChanged(this);
+    }
+  }
+
   public void setValueUpdater(ValueUpdater<T, Void> valueUpdater) {
     this.valueUpdater = valueUpdater;
   }
 
-  @Override
-  protected void onLoad() {
-    super.onLoad();
-    
-    // Register for model events.
-    this.reg = model.addListHandler(new ListHandler<T>() {
-      public void onDataChanged(ListEvent<T> event) {
-        int start = event.getStart();
-        int len = event.getLength();
-        List<T> values = event.getValues();
+  private void makeElements() {
+    Element parent = getElement().getFirstChildElement();
+    int childCount = parent.getChildCount();
 
-        // Construct a run of element from start (inclusive) to start + len (exclusive)
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < len; i++) {
-          sb.append("<div __idx='" + (start + i) + "' __seq='" + seq++ + "'>");
-          cell.render(values.get(i), null, sb);
-          sb.append("</div>");
-        }
-
-        Element parent = getElement().getFirstChildElement();
-        if (start == 0 && len == maxSize) {
-          parent.setInnerHTML(sb.toString());
-        } else {
-          makeElements();
-          tmpElem.setInnerHTML(sb.toString());
-          for (int i = 0; i < len; i++) {
-            Element child = parent.getChild(start + i).cast();
-            parent.replaceChild(tmpElem.getChild(0), child);
-          }
-        }
+    int actualSize = Math.min(size, maxSize);
+    if (actualSize > childCount) {
+      // Create new elements with a "loading..." message
+      StringBuilder sb = new StringBuilder();
+      int newElements = actualSize - childCount;
+      for (int i = 0; i < newElements; i++) {
+        sb.append("<div __idx='" + (childCount + i) + "'><i>loading...</i></div>");
       }
 
-      public void onSizeChanged(SizeChangeEvent event) {
-        size = event.getSize();
-        showOrHide(showMoreElem, size > maxSize);
-        showOrHide(showFewerElem, maxSize > initialMaxSize);
-      }
-
-      private void makeElements() {
-        Element parent = getElement().getFirstChildElement();
-        int childCount = parent.getChildCount();
-        
-        int actualSize = Math.min(size, maxSize);
-        if (actualSize > childCount) {
-          // Create new elements with a "loading..." message
-          StringBuilder sb = new StringBuilder();
-          int newElements = actualSize - childCount;
-          for (int i = 0; i < newElements; i++) {
-            sb.append("<div __idx='" + (childCount + i) + "'><i>loading...</i></div>");
-          }
-
-          if (childCount == 0) {
-            parent.setInnerHTML(sb.toString());
-          } else {
-            tmpElem.setInnerHTML(sb.toString());
-            for (int i = 0; i < newElements; i++) {
-              parent.appendChild(tmpElem.getChild(0));
-            }
-          }
-        } else if (actualSize < childCount) {
-          // Remove excess elements
-          while (actualSize < childCount) {
-            parent.getChild(--childCount).removeFromParent();
-          }
+      if (childCount == 0) {
+        parent.setInnerHTML(sb.toString());
+      } else {
+        tmpElem.setInnerHTML(sb.toString());
+        for (int i = 0; i < newElements; i++) {
+          parent.appendChild(tmpElem.getChild(0));
         }
       }
-    });
-
-    // Request up to maxSize elements
-    reg.setRangeOfInterest(0, maxSize);
-  }
-  
-  @Override
-  protected void onUnload() {
-    this.reg.removeHandler();
-    this.reg = null;
+    } else if (actualSize < childCount) {
+      // Remove excess elements
+      while (actualSize < childCount) {
+        parent.getChild(--childCount).removeFromParent();
+      }
+    }
   }
 
   private void showOrHide(Element element, boolean show) {
@@ -193,4 +189,9 @@
       element.getStyle().setDisplay(Display.NONE);
     }
   }
+
+  private void sizeChanged() {
+    showOrHide(showMoreElem, size > maxSize);
+    showOrHide(showFewerElem, maxSize > initialMaxSize);
+  }
 }
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListModel.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListModel.java
deleted file mode 100644
index b20fbee..0000000
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListModel.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.bikeshed.list.shared;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * An implementation of {@link ListModel}.
- * 
- * @param <T> the data type of records in the list
- */
-public abstract class AbstractListModel<T> implements ListModel<T> {
-
-  /**
-   * The range of interest for a single handler.
-   */
-  public static class DefaultRange implements Range, Serializable {
-    private int start;
-    private int length;
-
-    public DefaultRange(int start, int length) {
-      this.start = start;
-      this.length = length;
-    }
-
-    /**
-     * Used by RPC.
-     */
-    DefaultRange() {
-    }
-
-    public int getLength() {
-      return length;
-    }
-
-    public int getStart() {
-      return start;
-    }
-  }
-
-  /**
-   * An implementation of {@link ListRegistration} that remembers its own range
-   * of interest.
-   */
-  private class DefaultListRegistration implements ListRegistration<T> {
-
-    private final ListHandler<T> handler;
-    private int start;
-    private int length = -1;
-
-    /**
-     * Construct a new {@link DefaultListRegistration}.
-     * 
-     * @param handler the handler being registered
-     */
-    public DefaultListRegistration(ListHandler<T> handler) {
-      this.handler = handler;
-    }
-
-    public ListHandler<T> getHandler() {
-      return handler;
-    }
-
-    public int getLength() {
-      return length;
-    }
-
-    public int getStart() {
-      return start;
-    }
-
-    public void removeHandler() {
-      if (!registrations.contains(this)) {
-        throw new IllegalStateException("ListHandler has already been removed.");
-      }
-      registrations.remove(this);
-    }
-
-    public void setRangeOfInterest(int start, int length) {
-      this.start = start;
-      this.length = length;
-      onRangeChanged(this, start, length);
-    }
-  }
-
-  /**
-   * The provider of keys for list items.
-   */
-  private ProvidesKey<T> keyProvider;
-
-  /**
-   * The handlers that are listening to this model.
-   */
-  private List<DefaultListRegistration> registrations = new ArrayList<DefaultListRegistration>();
-
-  public ListRegistration<T> addListHandler(ListHandler<T> handler) {
-    DefaultListRegistration reg = new DefaultListRegistration(handler);
-    registrations.add(reg);
-    return reg;
-  }
-
-  /**
-   * Get the key for a list item. The default implementation returns the item
-   * itself.
-   * 
-   * @param item the list item
-   * @return the key that represents the item
-   */
-  public Object getKey(T item) {
-    return keyProvider == null ? item : keyProvider.getKey(item);
-  }
-
-  /**
-   * Get the {@link ProvidesKey} that provides keys for list items.
-   * 
-   * @return the {@link ProvidesKey}
-   */
-  public ProvidesKey<T> getKeyProvider() {
-    return keyProvider;
-  }
-
-  /**
-   * Get the current ranges of all views.
-   * 
-   * @return the ranges
-   */
-  public Range[] getRanges() {
-    Range[] ranges = new Range[registrations.size()];
-    for (int i = 0; i < registrations.size(); i++) {
-      DefaultListRegistration reg = registrations.get(i);
-      ranges[i] = new DefaultRange(reg.getStart(), reg.getLength());
-    }
-    return ranges;
-  }
-
-  /**
-   * Set the {@link ProvidesKey} that provides keys for list items.
-   * 
-   * @param keyProvider the {@link ProvidesKey}
-   */
-  public void setKeyProvider(ProvidesKey<T> keyProvider) {
-    this.keyProvider = keyProvider;
-  }
-
-  /**
-   * Called when a view changes its range of interest.
-   * 
-   * @param reg the list whose range has changed
-   * @param start the start of the list's new range
-   * @param length the length of the list's new range
-   */
-  protected abstract void onRangeChanged(ListRegistration<T> reg, int start,
-      int length);
-
-  /**
-   * Inform the views of the total number of items that are available.
-   * 
-   * @param size the new size
-   * @param exact true if the size is exact, false if it is a guess
-   */
-  protected void updateDataSize(int size, boolean exact) {
-    SizeChangeEvent event = new SizeChangeEvent(size, exact);
-    for (DefaultListRegistration reg : registrations) {
-      reg.getHandler().onSizeChanged(event);
-    }
-  }
-
-  /**
-   * Inform the views of the new data.
-   * 
-   * @param start the start index
-   * @param length the length of the data
-   * @param values the data values
-   */
-  protected void updateViewData(int start, int length, List<T> values) {
-    for (ListRegistration<T> reg : registrations) {
-      updateViewData(reg, start, length, values);
-    }
-  }
-
-  /**
-   * Informs a single view (via its {@link ListRegistration}) of new data.
-   * 
-   * @param reg the list registration of the view to be updated
-   * @param start the start index
-   * @param length the length of the data
-   * @param values the data values
-   */
-  protected void updateViewData(ListRegistration<T> reg, int start, int length, List<T> values) {
-    int end = start + length;
-    int curStart = reg.getStart();
-    int curLength = reg.getLength();
-    int curEnd = curStart + curLength;
-    if (curStart < end && curEnd > start) {
-      // Fire the handler with the data that is in the range.
-      int realStart = curStart < start ? start : curStart;
-      int realEnd = curEnd > end ? end : curEnd;
-      int realLength = realEnd - realStart;
-      List<T> realValues = values.subList(realStart - start, realStart
-          - start + realLength);
-      ListEvent<T> event = new ListEvent<T>(realStart, realLength, realValues);
-      reg.getHandler().onDataChanged(event);
-    }
-  }
-}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListViewAdapter.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListViewAdapter.java
new file mode 100644
index 0000000..d1e5cf6
--- /dev/null
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/shared/AbstractListViewAdapter.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.bikeshed.list.shared;
+
+import com.google.gwt.bikeshed.list.client.ListView;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A base implementation of a data source for list views.
+ *
+ * @param <T> the data type of records in the list
+ */
+public abstract class AbstractListViewAdapter<T> implements ProvidesKey<T> {
+
+  /**
+   * The range of interest for a single handler.
+   */
+  public static class DefaultRange implements Range, Serializable {
+    private int length;
+    private int start;
+
+    public DefaultRange(int start, int length) {
+      this.start = start;
+      this.length = length;
+    }
+
+    /**
+     * Used by RPC.
+     */
+    DefaultRange() {
+    }
+
+    public int getLength() {
+      return length;
+    }
+
+    public int getStart() {
+      return start;
+    }
+  }
+
+  private class Delegate implements ListView.Delegate<T> {
+    public void onRangeChanged(ListView<T> view) {
+      AbstractListViewAdapter.this.onRangeChanged(view);
+    }
+  }
+
+  private final Delegate delegate = new Delegate();
+
+  private Set<ListView<T>> views = new HashSet<ListView<T>>();
+
+  /**
+   * The provider of keys for list items.
+   */
+  private ProvidesKey<T> keyProvider;
+
+  public void addView(ListView<T> view) {
+    if (views.contains(view)) {
+      throw new IllegalStateException("ListView already added");
+    }
+    views.add(view);
+    view.setDelegate(delegate);
+  }
+
+  /**
+   * Get the key for a list item. The default implementation returns the item
+   * itself.
+   *
+   * @param item the list item
+   * @return the key that represents the item
+   */
+  public Object getKey(T item) {
+    return keyProvider == null ? item : keyProvider.getKey(item);
+  }
+
+  /**
+   * Get the {@link ProvidesKey} that provides keys for list items.
+   *
+   * @return the {@link ProvidesKey}
+   */
+  public ProvidesKey<T> getKeyProvider() {
+    return keyProvider;
+  }
+
+  /**
+   * Get the current ranges of all views.
+   *
+   * @return the ranges
+   */
+  public Range[] getRanges() {
+    Range[] ranges = new Range[views.size()];
+    int i = 0;
+    for (ListView<T> view : views) {
+      ranges[i++] = view.getRange();
+    }
+    return ranges;
+  }
+
+  public void removeView(ListView<T> view) {
+    if (!views.contains(view)) {
+      throw new IllegalStateException("ListView not present");
+    }
+    views.remove(view);
+    view.setDelegate(null);
+  }
+
+  /**
+   * Set the {@link ProvidesKey} that provides keys for list items.
+   *
+   * @param keyProvider the {@link ProvidesKey}
+   */
+  public void setKeyProvider(ProvidesKey<T> keyProvider) {
+    this.keyProvider = keyProvider;
+  }
+
+  /**
+   * Called when a view changes its range of interest.
+   *
+   * @param view the view whose range has changed
+   */
+  protected abstract void onRangeChanged(ListView<T> view);
+
+  /**
+   * Inform the views of the total number of items that are available.
+   *
+   * @param size the new size
+   * @param exact true if the size is exact, false if it is a guess
+   */
+  protected void updateDataSize(int size, boolean exact) {
+    SizeChangeEvent event = new SizeChangeEvent(size, exact);
+    for (ListView<T> view : views) {
+      view.onSizeChanged(event);
+    }
+  }
+
+  /**
+   * Inform the views of the new data.
+   *
+   * @param start the start index
+   * @param length the length of the data
+   * @param values the data values
+   */
+  protected void updateViewData(int start, int length, List<T> values) {
+    for (ListView<T> view : views) {
+      updateViewData(view, start, length, values);
+    }
+  }
+
+  /**
+   * Informs a single view of new data.
+   *
+   * @param view the view to be updated
+   * @param start the start index
+   * @param length the length of the data
+   * @param values the data values
+   */
+  protected void updateViewData(ListView<T> view, int start, int length, List<T> values) {
+    int end = start + length;
+    Range range = view.getRange();
+    int curStart = range.getStart();
+    int curLength = range.getLength();
+    int curEnd = curStart + curLength;
+    if (curStart < end && curEnd > start) {
+      // Fire the handler with the data that is in the range.
+      int realStart = curStart < start ? start : curStart;
+      int realEnd = curEnd > end ? end : curEnd;
+      int realLength = realEnd - realStart;
+      List<T> realValues = values.subList(realStart - start, realStart
+          - start + realLength);
+      ListEvent<T> event = new ListEvent<T>(realStart, realLength, realValues);
+      view.onDataChanged(event);
+    }
+  }
+}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/AsyncListModel.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/AsyncListViewAdapter.java
similarity index 87%
rename from bikeshed/src/com/google/gwt/bikeshed/list/shared/AsyncListModel.java
rename to bikeshed/src/com/google/gwt/bikeshed/list/shared/AsyncListViewAdapter.java
index 42c2212..06fd164 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/AsyncListModel.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/shared/AsyncListViewAdapter.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -18,16 +18,16 @@
 import java.util.List;
 
 /**
- * An implementation of {@link AbstractListModel} that allows the data to be
+ * An implementation of {@link AbstractListViewAdapter} that allows the data to be
  * modified.
- * 
+ *
  * @param <T> the data type of records in the list
  */
-public abstract class AsyncListModel<T> extends AbstractListModel<T> {
-  
+public abstract class AsyncListViewAdapter<T> extends AbstractListViewAdapter<T> {
+
   /**
    * Inform the views of the total number of items that are available.
-   * 
+   *
    * @param size the new size
    * @param exact true if the size is exact, false if it is a guess
    */
@@ -38,7 +38,7 @@
 
   /**
    * Inform the views of the new data.
-   * 
+   *
    * @param start the start index
    * @param length the length of the data
    * @param values the data values
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListEvent.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListEvent.java
index 82ceec6..1c78314 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListEvent.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListEvent.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -15,33 +15,14 @@
  */
 package com.google.gwt.bikeshed.list.shared;
 
-import com.google.gwt.event.shared.GwtEvent;
-
 import java.util.List;
 
 /**
  * Represents a list event.
- * 
+ *
  * @param <T> the type of data in the list
  */
-public class ListEvent<T> extends GwtEvent<ListHandler<T>> {
-
-  /**
-   * Handler type.
-   */
-  private static Type<ListHandler<?>> TYPE;
-
-  /**
-   * Gets the type associated with this event.
-   * 
-   * @return returns the handler type
-   */
-  public static Type<ListHandler<?>> getType() {
-    if (TYPE == null) {
-      TYPE = new Type<ListHandler<?>>();
-    }
-    return TYPE;
-  }
+public class ListEvent<T> {
 
   private final int length;
   private final int start;
@@ -49,7 +30,7 @@
 
   /**
    * Creates a {@link ListEvent}.
-   * 
+   *
    * @param start the start index of the data
    * @param length the length of the data
    * @param values the new values
@@ -60,15 +41,9 @@
     this.values = values;
   }
 
-  @SuppressWarnings("unchecked")
-  @Override
-  public final Type<ListHandler<T>> getAssociatedType() {
-    return (Type) TYPE;
-  }
-
   /**
    * Get the length of the changed data set.
-   * 
+   *
    * @return the length of the data set
    */
   public int getLength() {
@@ -77,7 +52,7 @@
 
   /**
    * Get the start index of the changed data.
-   * 
+   *
    * @return the start index
    */
   public int getStart() {
@@ -86,15 +61,10 @@
 
   /**
    * Gets the value.
-   * 
+   *
    * @return the value
    */
   public List<T> getValues() {
     return values;
   }
-
-  @Override
-  protected void dispatch(ListHandler<T> handler) {
-    handler.onDataChanged(this);
-  }
 }
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListHandler.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListHandler.java
deleted file mode 100644
index fd41884..0000000
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListHandler.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.bikeshed.list.shared;
-
-import com.google.gwt.event.shared.EventHandler;
-
-/**
- * Handler interface for {@link ListEvent} events.
- * 
- * @param <T> the value about to be changed
- */
-public interface ListHandler<T> extends EventHandler {
-
-  /**
-   * Called when {@link ListEvent} is fired.
-   * 
-   * @param event the {@link ListEvent} that was fired
-   */
-  void onDataChanged(ListEvent<T> event);
-
-  /**
-   * Called when a {@link SizeChangeEvent} is fired.
-   * 
-   * @param event the {@link SizeChangeEvent} that was fired
-   */
-  void onSizeChanged(SizeChangeEvent event);
-}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListModel.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListModel.java
deleted file mode 100644
index 04bb121..0000000
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListModel.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.bikeshed.list.shared;
-
-/**
- * A model for a list.
- * 
- * @param <T> the data type of records in the list
- */
-public interface ListModel<T> extends ProvidesKey<T> {
-
-  /**
-   * Add a {@link ListHandler} to the model.
-   * 
-   * @param handler the {@link ListHandler}
-   */
-  ListRegistration<T> addListHandler(ListHandler<T> handler);
-}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListRegistration.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListRegistration.java
deleted file mode 100644
index a097446..0000000
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListRegistration.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.bikeshed.list.shared;
-
-import com.google.gwt.event.shared.HandlerRegistration;
-
-/**
- * Registration returned from a call to ListModel#addListHandler.
- * 
- * @param <T> the data type displayed by the list
- */
-public interface ListRegistration<T> extends HandlerRegistration {
-
-  /**
-   * Set the range of data that is interesting to the {@link ListHandler}.
-   * 
-   * @param start the start index
-   * @param length the length
-   */
-  void setRangeOfInterest(int start, int length);
-
-  /**
-   * Gets the {@link ListHandler} associated with this registration.
-   */
-  ListHandler<T> getHandler();
-
-  /**
-   * Gets the length of this registration's range of interest.
-   */
-  int getLength();
-
-  /**
-   * Gets the start of this registration's range of interest.
-   */
-  int getStart();
-}
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListListModel.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListViewAdapter.java
similarity index 93%
rename from bikeshed/src/com/google/gwt/bikeshed/list/shared/ListListModel.java
rename to bikeshed/src/com/google/gwt/bikeshed/list/shared/ListViewAdapter.java
index b23fbdc..4124ab0 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListListModel.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/shared/ListViewAdapter.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.bikeshed.list.shared;
 
+import com.google.gwt.bikeshed.list.client.ListView;
 import com.google.gwt.user.client.Command;
 import com.google.gwt.user.client.DeferredCommand;
 
@@ -25,11 +26,12 @@
 import java.util.ListIterator;
 
 /**
- * A {@link ListModel} that is backed by a list.
- * 
+ * A concrete subclass of {@link AbstractListViewAdapter} that is backed by an
+ * in-memory list.
+ *
  * @param <T> the data type of the list
  */
-public class ListListModel<T> extends AbstractListModel<T> {
+public class ListViewAdapter<T> extends AbstractListViewAdapter<T> {
 
   /**
    * A wrapper around a list that updates the model on any change.
@@ -55,10 +57,11 @@
           curSize = newSize;
           updateDataSize(curSize, true);
         }
-        
+
         if (modified) {
           int length = maxModified - minModified;
-          updateViewData(minModified, length, list.subList(minModified, maxModified));
+          updateViewData(minModified, length, list.subList(minModified,
+              maxModified));
           modified = false;
         }
         minModified = Integer.MAX_VALUE;
@@ -259,16 +262,6 @@
     }
 
     /**
-     * Flush the data to the model and return the boolean.
-     * 
-     * @param toRet the boolean to return
-     */
-    private boolean flush(boolean toRet) {
-      flush();
-      return toRet;
-    }
-
-    /**
      * Flush the data to the model.
      */
     private void flush() {
@@ -277,6 +270,16 @@
         DeferredCommand.addCommand(flushCommand);
       }
     }
+
+    /**
+     * Flush the data to the model and return the boolean.
+     *
+     * @param toRet the boolean to return
+     */
+    private boolean flush(boolean toRet) {
+      flush();
+      return toRet;
+    }
   }
 
   /**
@@ -287,7 +290,7 @@
   /**
    * Creates an empty model.
    */
-  public ListListModel() {
+  public ListViewAdapter() {
     this(new ArrayList<T>());
   }
 
@@ -296,14 +299,14 @@
    * wrapped list must be made via this model in order to be correctly applied
    * to views.
    */
-  public ListListModel(List<T> wrappee) {
+  public ListViewAdapter(List<T> wrappee) {
     listWrapper = new ListWrapper(wrappee);
   }
 
   /**
    * Get the list that backs this model. Changes to the list will be reflected
    * in the model.
-   * 
+   *
    * @return the list
    */
   public List<T> getList() {
@@ -312,7 +315,7 @@
 
   /**
    * Replaces this model's list.
-   * 
+   *
    * @param wrappee the model's new list
    */
   public void setList(List<T> wrappee) {
@@ -322,8 +325,7 @@
   }
 
   @Override
-  protected void onRangeChanged(ListRegistration<T> reg, int start, int length) {
-    // TODO - update only relevant range of data
-    updateViewData(reg, 0, listWrapper.size(), listWrapper);
+  protected void onRangeChanged(ListView<T> view) {
+    updateViewData(view, 0, listWrapper.size(), listWrapper);
   }
 }
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ProvidesKey.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/ProvidesKey.java
index f1ff4ff..7b31f32 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/ProvidesKey.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/shared/ProvidesKey.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -20,18 +20,19 @@
  * Implementors of {@link ProvidesKey} provide a key for list items.
  * </p>
  * <p>
- * The key must implement a coherent set of {@link #equals(Object)} and
- * {@link #hashCode()} methods. If the item type is a not uniquely identifiable,
- * such as a list of {@link String}, the index can be used as the key.
+ * The key must implement a coherent set of {@link Object#equals(Object)} and
+ * {@link Object#hashCode()} methods. If the item type is a not uniquely
+ * identifiable, such as a list of {@link String}, the index can be used as the
+ * key.
  * </p>
- * 
+ *
  * @param <T> the data type of records in the list
  */
 public interface ProvidesKey<T> {
 
   /**
    * Get the key for a list item.
-   * 
+   *
    * @param item the list item
    * @return the key that represents the item
    */
diff --git a/bikeshed/src/com/google/gwt/bikeshed/list/shared/SizeChangeEvent.java b/bikeshed/src/com/google/gwt/bikeshed/list/shared/SizeChangeEvent.java
index bc82706..81dd219 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/list/shared/SizeChangeEvent.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/list/shared/SizeChangeEvent.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -15,36 +15,17 @@
  */
 package com.google.gwt.bikeshed.list.shared;
 
-import com.google.gwt.event.shared.GwtEvent;
-
 /**
  * Fired when the size of a list is known or changed.
  */
-public class SizeChangeEvent extends GwtEvent<ListHandler<?>> {
-
-  /**
-   * Handler type.
-   */
-  private static Type<ListHandler<?>> TYPE;
-
-  /**
-   * Gets the type associated with this event.
-   * 
-   * @return returns the handler type
-   */
-  public static Type<ListHandler<?>> getType() {
-    if (TYPE == null) {
-      TYPE = new Type<ListHandler<?>>();
-    }
-    return TYPE;
-  }
+public class SizeChangeEvent {
 
   private final boolean exact;
   private final int size;
 
   /**
    * Creates a {@link SizeChangeEvent}.
-   * 
+   *
    * @param size the total size of the list
    * @param exact true if this is an exact size
    */
@@ -53,14 +34,9 @@
     this.exact = exact;
   }
 
-  @Override
-  public final Type<ListHandler<?>> getAssociatedType() {
-    return TYPE;
-  }
-
   /**
    * Get the length of the changed data set.
-   * 
+   *
    * @return the length of the data set
    */
   public int getSize() {
@@ -69,15 +45,10 @@
 
   /**
    * Check if the size is an exact size or an approximation.
-   * 
+   *
    * @return true if exact, false if approximation
    */
   public boolean isExact() {
     return exact;
   }
-
-  @Override
-  protected void dispatch(ListHandler<?> handler) {
-    handler.onSizeChanged(this);
-  }
 }
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeView.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeView.java
index 62c33bf..0e0cdfa 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/SideBySideTreeView.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -56,7 +56,7 @@
    * @param viewModel the {@link TreeViewModel} that backs the tree
    * @param rootValue the hidden root value of the tree
    * @param columnWidth the width of each column
-   * @param maxColumns the maximum number of columns to display horizontally.
+   * @param maxColumns the maximum number of columns to display horizontally
    */
   public <T> SideBySideTreeView(TreeViewModel viewModel, T rootValue,
       int columnWidth, int maxColumns) {
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeNodeView.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeNodeView.java
index 7d7a47d..483ca34 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeNodeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeNodeView.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -38,7 +38,7 @@
    * @param tree the parent {@link TreeView}
    * @param parent the parent {@link TreeNodeView}
    * @param parentNodeInfo the {@link NodeInfo} of the parent
-   * @param elem the outer element of this {@link TreeNodeView}.
+   * @param elem the outer element of this {@link TreeNodeView}
    * @param value the value of this node
    */
   StandardTreeNodeView(final TreeView tree,
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeView.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeView.java
index 6552e68..a2a78ff 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/StandardTreeView.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -31,7 +31,8 @@
 public class StandardTreeView extends TreeView implements HasAnimation {
 
   /**
-   * A {@link TreeNodeAnimation} that reveals the contents of child nodes.
+   * A {@link TreeView.TreeNodeViewAnimation} that reveals the contents of child
+   * nodes.
    */
   public static class RevealAnimation extends TreeNodeViewAnimation {
 
@@ -144,7 +145,7 @@
   }
 
   /**
-   * A {@link TreeNodeAnimation} that slides children into view.
+   * A {@link TreeView.TreeNodeViewAnimation} that slides children into view.
    */
   public static class SlideAnimation extends RevealAnimation {
     /**
@@ -210,10 +211,12 @@
     setAnimation(SlideAnimation.create());
 
     // Add event handlers.
-    sinkEvents(Event.ONCLICK | Event.ONMOUSEDOWN | Event.ONMOUSEUP | Event.ONCHANGE);
+    sinkEvents(Event.ONCLICK | Event.ONMOUSEDOWN | Event.ONMOUSEUP
+        | Event.ONCHANGE);
 
     // Associate a view with the item.
-    TreeNodeView<T> root = new StandardTreeNodeView<T>(this, null, null, getElement(), rootValue);
+    TreeNodeView<T> root = new StandardTreeNodeView<T>(this, null, null,
+        getElement(), rootValue);
     setRootNode(root);
     root.setState(true);
   }
@@ -252,8 +255,8 @@
   /**
    * Collects parents going up the element tree, terminated at the tree root.
    */
-  private void collectElementChain(ArrayList<Element> chain, ArrayList<String> ids, Element hRoot,
-      Element hElem) {
+  private void collectElementChain(ArrayList<Element> chain,
+      ArrayList<String> ids, Element hRoot, Element hElem) {
     if ((hElem == null) || (hElem == hRoot)) {
       return;
     }
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNode.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNode.java
index 88f6492..690b556 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNode.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNode.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -17,18 +17,18 @@
 
 /**
  * A interface allowing navigation within a tree view.
- * 
- * @param <T> the type of data stored at this node.
+ *
+ * @param <T> the type of data stored at this node
  */
 public interface TreeNode<T> {
-  
+
   TreeNode<?> getChildNode(int childIndex);
-  
+
   int getChildCount();
-  
+
   TreeNode<?> getParentNode();
-  
+
   T getValue();
-  
+
   boolean isOpen();
 }
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java
index 0e177e3..90d302e 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeNodeView.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -16,11 +16,12 @@
 package com.google.gwt.bikeshed.tree.client;
 
 import com.google.gwt.bikeshed.list.client.HasCell;
+import com.google.gwt.bikeshed.list.client.ListView;
 import com.google.gwt.bikeshed.list.shared.ListEvent;
-import com.google.gwt.bikeshed.list.shared.ListHandler;
-import com.google.gwt.bikeshed.list.shared.ListModel;
-import com.google.gwt.bikeshed.list.shared.ListRegistration;
+import com.google.gwt.bikeshed.list.shared.ProvidesKey;
+import com.google.gwt.bikeshed.list.shared.Range;
 import com.google.gwt.bikeshed.list.shared.SizeChangeEvent;
+import com.google.gwt.bikeshed.list.shared.AbstractListViewAdapter.DefaultRange;
 import com.google.gwt.bikeshed.tree.client.TreeViewModel.NodeInfo;
 import com.google.gwt.dom.client.Document;
 import com.google.gwt.dom.client.Element;
@@ -47,11 +48,6 @@
   public static final String LEAF_IMAGE = "<div style='position:absolute;display:none;'></div>";
 
   /**
-   * A reference to the element that contains the children.
-   */
-  private Element childContainer;
-
-  /**
    * True during the time a node should be animated.
    */
   private boolean animate;
@@ -59,12 +55,17 @@
   /**
    * A reference to the element that contains the children.
    */
+  private Element childContainer;
+
+  /**
+   * A reference to the element that contains the children.
+   */
   private List<TreeNodeView<?>> children;
 
   /**
    * The list registration for the list of children.
    */
-  private ListRegistration<?> listReg;
+  private ListView<?> listView;
 
   /**
    * The info about children of this node.
@@ -152,7 +153,7 @@
   public boolean isOpen() {
     return open;
   }
-  
+
   /**
    * Check if this is a root node at the top of the tree.
    *
@@ -212,9 +213,9 @@
    */
   protected void cleanup() {
     // Unregister the list handler.
-    if (listReg != null) {
-      listReg.removeHandler();
-      listReg = null;
+    if (listView != null) {
+      nodeInfo.unsetView();
+      listView = null;
     }
 
     // Recursively kill children.
@@ -336,7 +337,7 @@
    * implementation of NodeInfo.getKey().
    */
   protected Object getValueKey() {
-    return getParentNodeInfo().getListModel().getKey(getValue());
+    return getParentNodeInfo().getProvidesKey().getKey(getValue());
   }
 
   /**
@@ -353,8 +354,12 @@
     ensureAnimationFrame().getStyle().setProperty("display", "");
 
     // Get the node info.
-    final ListModel<C> listModel = nodeInfo.getListModel();
-    listReg = listModel.addListHandler(new ListHandler<C>() {
+    final ProvidesKey<C> providesKey = nodeInfo.getProvidesKey();
+    ListView<C> view = new ListView<C>() {
+      public Range getRange() {
+        return new DefaultRange(0, 100);
+      }
+
       public void onDataChanged(ListEvent<C> event) {
         // TODO - handle event start and length
 
@@ -378,7 +383,7 @@
         for (C childValue : event.getValues()) {
           // Remove any child elements that correspond to prior children
           // so the call to setInnerHtml will not destroy them
-          TreeNodeView<?> savedView = map.get(listModel.getKey(childValue));
+          TreeNodeView<?> savedView = map.get(providesKey.getKey(childValue));
           if (savedView != null) {
             savedView.getContainer().getFirstChild().removeFromParent();
           }
@@ -397,12 +402,11 @@
         for (C childValue : event.getValues()) {
           TreeNodeView<C> child = createTreeNodeView(nodeInfo, childElem,
               childValue, null, idx);
-          TreeNodeView<?> savedChild = map.get(listModel.getKey(childValue));
+          TreeNodeView<?> savedChild = map.get(providesKey.getKey(childValue));
           // Copy the saved child's state into the new child
           if (savedChild != null) {
             child.children = savedChild.children;
             child.childContainer = savedChild.childContainer;
-            child.listReg = savedChild.listReg;
             child.nodeInfo = savedChild.nodeInfo;
             child.nodeInfoLoaded = savedChild.nodeInfoLoaded;
             child.open = savedChild.getState();
@@ -435,8 +439,16 @@
           }
         }
       }
-    });
-    listReg.setRangeOfInterest(0, 100);
+
+      public void setDelegate(ListView.Delegate<C> delegate) {
+        // Range never actually changes so no need to store the delegate
+        if (delegate != null) {
+          delegate.onRangeChanged(this);
+        }
+      }
+    };
+    nodeInfo.setView(view);
+    this.listView = view;
   }
 
   /**
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeView.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeView.java
index 4b0e63e..563b4e0 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeView.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeView.java
@@ -101,11 +101,6 @@
   private String loadingHtml = "Loading...";
 
   /**
-   * The {@link TreeViewModel} that backs the tree.
-   */
-  private TreeViewModel model;
-
-  /**
    * The HTML used to generate the open image.
    */
   private String openImageHtml;
@@ -115,15 +110,23 @@
    */
   private TreeNodeView<?> rootNode;
 
+  /**
+   * The {@link SelectionModel} for the tree.
+   */
   private SelectionModel<Object> selectionModel;
 
   /**
+   * The {@link TreeViewModel} that backs the tree.
+   */
+  private TreeViewModel viewModel;
+
+  /**
    * Construct a new {@link TreeView}.
    *
    * @param viewModel the {@link TreeViewModel} that backs the tree
    */
   public TreeView(TreeViewModel viewModel) {
-    this.model = viewModel;
+    this.viewModel = viewModel;
   }
 
   /**
@@ -146,7 +149,7 @@
   }
 
   public TreeViewModel getTreeViewModel() {
-    return model;
+    return viewModel;
   }
 
   public boolean isAnimationEnabled() {
@@ -157,7 +160,7 @@
    * Set the animation used to open and close nodes in this tree. You must call
    * {@link #setAnimationEnabled(boolean)} to enable or disable animation.
    *
-   * @param animation a {@link TreeNodeViewAnimation}.
+   * @param animation a {@link TreeNodeViewAnimation}
    * @see #setAnimationEnabled(boolean)
    */
   public void setAnimation(TreeNodeViewAnimation animation) {
diff --git a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java
index 5433ff1..b619971 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/tree/client/TreeViewModel.java
@@ -19,7 +19,9 @@
 import com.google.gwt.bikeshed.cells.client.FieldUpdater;
 import com.google.gwt.bikeshed.cells.client.ValueUpdater;
 import com.google.gwt.bikeshed.list.client.HasCell;
-import com.google.gwt.bikeshed.list.shared.ListModel;
+import com.google.gwt.bikeshed.list.client.ListView;
+import com.google.gwt.bikeshed.list.shared.AbstractListViewAdapter;
+import com.google.gwt.bikeshed.list.shared.ProvidesKey;
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.dom.client.NativeEvent;
 
@@ -32,46 +34,36 @@
 public interface TreeViewModel {
 
   /**
-   * The info needed to create a {@link TreeNodeView}.
-   */
-  interface NodeInfo<T> {
-
-    List<HasCell<T, ?, Void>> getHasCells();
-
-    /**
-     * Get the {@link ListModel} used to retrieve child node values.
-     *
-     * @return the list model
-     */
-    ListModel<T> getListModel();
-
-    /**
-     * Handle an event that is fired on one of the children of this item.
-     *
-     * @param elem the parent element of the item
-     * @param object the data value of the item
-     * @param event the event that was fired
-     */
-    void onBrowserEvent(Element elem, final T object, NativeEvent event);
-  }
-
-  /**
    * Default implementation of {@link NodeInfo}.
    */
   class DefaultNodeInfo<T> implements NodeInfo<T> {
     private List<HasCell<T, ?, Void>> hasCells = new ArrayList<HasCell<T, ?, Void>>();
-    private ListModel<T> listModel;
+    private AbstractListViewAdapter<T> listViewAdapter;
+    private ListView<T> view;
+
+    /**
+     * Construct a new {@link DefaultNodeInfo}.
+     *
+     * @param adapter the {@link AbstractListViewAdapter} that provides the
+     *          child values
+     * @param cell the {@link Cell} used to render the child values
+     */
+    public DefaultNodeInfo(AbstractListViewAdapter<T> adapter,
+        Cell<T, Void> cell) {
+      this(adapter, cell, null);
+    }
 
     /**
      * Construct a new {@link DefaultNodeInfo} with a single cell and a
      * {@link ValueUpdater}.
      *
-     * @param listModel the {@link ListModel} that provides the child values
+     * @param adapter the {@link AbstractListViewAdapter} that provides the
+     *          child values
      * @param cell the {@link Cell} used to render the child values
      * @param valueUpdater the {@link ValueUpdater}
      */
-    public DefaultNodeInfo(ListModel<T> listModel, final Cell<T, Void> cell,
-        final ValueUpdater<T, Void> valueUpdater) {
+    public DefaultNodeInfo(AbstractListViewAdapter<T> adapter,
+        final Cell<T, Void> cell, final ValueUpdater<T, Void> valueUpdater) {
       hasCells.add(new HasCell<T, T, Void>() {
         public Cell<T, Void> getCell() {
           return cell;
@@ -89,31 +81,21 @@
           return object;
         }
       });
-      this.listModel = listModel;
+      this.listViewAdapter = adapter;
     }
 
-    /**
-     * Construct a new {@link DefaultNodeInfo}.
-     *
-     * @param listModel the {@link ListModel} that provides the child values
-     * @param cell the {@link Cell} used to render the child values
-     */
-    public DefaultNodeInfo(ListModel<T> listModel, Cell<T, Void> cell) {
-      this(listModel, cell, null);
-    }
-
-    public DefaultNodeInfo(ListModel<T> listModel,
+    public DefaultNodeInfo(AbstractListViewAdapter<T> adapter,
         List<HasCell<T, ?, Void>> hasCells) {
       this.hasCells.addAll(hasCells);
-      this.listModel = listModel;
+      this.listViewAdapter = adapter;
     }
 
     public List<HasCell<T, ?, Void>> getHasCells() {
       return hasCells;
     }
 
-    public ListModel<T> getListModel() {
-      return listModel;
+    public ProvidesKey<T> getProvidesKey() {
+      return listViewAdapter;
     }
 
     // TODO - dispatch into cells
@@ -130,6 +112,15 @@
       }
     }
 
+    public void setView(ListView<T> view) {
+      this.view = view;
+      listViewAdapter.addView(view);
+    }
+
+    public void unsetView() {
+      listViewAdapter.removeView(view);
+    }
+
     private <X> void dispatch(Element target, final T object,
         NativeEvent event, HasCell<T, X, Void> hc) {
       final FieldUpdater<T, X, Void> fieldUpdater = hc.getFieldUpdater();
@@ -143,8 +134,32 @@
   }
 
   /**
-   * Get the {@link NodeInfo} that will provide the {@link ListModel} and
-   * {@link Cell} to retrieve the children of the specified value.
+   * The info needed to create a {@link TreeNodeView}.
+   */
+  interface NodeInfo<T> {
+
+    List<HasCell<T, ?, Void>> getHasCells();
+
+    ProvidesKey<T> getProvidesKey();
+
+    /**
+     * Handle an event that is fired on one of the children of this item.
+     *
+     * @param elem the parent element of the item
+     * @param object the data value of the item
+     * @param event the event that was fired
+     */
+    void onBrowserEvent(Element elem, final T object, NativeEvent event);
+
+    void setView(ListView<T> view);
+
+    void unsetView();
+  }
+
+  /**
+   * Get the {@link NodeInfo} that will provide the {@link ProvidesKey},
+   * {@link Cell}, and {@link ListView}s to retrieve and display the children of
+   * the specified value.
    *
    * @param value the value in the parent node
    * @param treeNode the {@link TreeNode} that contains the value
diff --git a/bikeshed/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java b/bikeshed/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java
index b013efd..f22ac86 100644
--- a/bikeshed/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java
+++ b/bikeshed/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -37,7 +37,7 @@
   private ValueStoreJsonImpl valueStore;
 
   /**
-   * @param valueStore
+   * @param handlerManager
    */
   public void init(HandlerManager handlerManager) {
     this.valueStore = new ValueStoreJsonImpl(handlerManager);
diff --git a/bikeshed/src/com/google/gwt/requestfactory/shared/LongString.java b/bikeshed/src/com/google/gwt/requestfactory/shared/LongString.java
index ad427a8..b236ad0 100644
--- a/bikeshed/src/com/google/gwt/requestfactory/shared/LongString.java
+++ b/bikeshed/src/com/google/gwt/requestfactory/shared/LongString.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -16,7 +16,8 @@
 package com.google.gwt.requestfactory.shared;
 
 /**
- * Marks a String {@link Property} that represents a long server side.
+ * Marks a String {@link com.google.gwt.valuestore.shared.Property Property}
+ * that represents a long server side.
  */
 public @interface LongString {
 
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/BasicTreeRecipe.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/BasicTreeRecipe.java
index d718c70..1fd42e9 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/BasicTreeRecipe.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/BasicTreeRecipe.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -39,7 +39,6 @@
     final Label label = new Label();
     final MultiSelectionModel<Object> selectionModel = new MultiSelectionModel<Object>();
     selectionModel.addSelectionChangeHandler(new SelectionModel.SelectionChangeHandler() {
-      @Override
       public void onSelectionChange(SelectionChangeEvent event) {
         label.setText("Selected "
             + selectionModel.getSelectedSet().toString());
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Cookbook.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Cookbook.java
index 73abf66..6ae4be6 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Cookbook.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Cookbook.java
@@ -16,7 +16,7 @@
 package com.google.gwt.sample.bikeshed.cookbook.client;
 
 import com.google.gwt.bikeshed.cells.client.Cell;
-import com.google.gwt.bikeshed.list.shared.ListListModel;
+import com.google.gwt.bikeshed.list.shared.ListViewAdapter;
 import com.google.gwt.bikeshed.list.shared.SelectionModel;
 import com.google.gwt.bikeshed.list.shared.SelectionModel.SelectionChangeEvent;
 import com.google.gwt.bikeshed.tree.client.StandardTreeView;
@@ -38,7 +38,8 @@
  */
 public class Cookbook implements EntryPoint {
 
-  interface Binder extends UiBinder<Widget, Cookbook> {}
+  interface Binder extends UiBinder<Widget, Cookbook> {
+  }
 
   static class CategoryCell extends Cell<Category, Void> {
     @Override
@@ -54,24 +55,22 @@
     }
   }
 
-  private final class RecipeTreeModel implements TreeViewModel {
-    private ListListModel<Category> catModel = new ListListModel<Category>();
+  private static final class RecipeTreeModel implements TreeViewModel {
+    private ListViewAdapter<Category> adapter = new ListViewAdapter<Category>();
 
-    @Override
     public <T> NodeInfo<?> getNodeInfo(T value, TreeNode<T> treeNode) {
       if (value == null) {
         // Categories at the root.
-        return new DefaultNodeInfo<Category>(catModel, new CategoryCell());
+        return new DefaultNodeInfo<Category>(adapter, new CategoryCell());
       } else if (value instanceof Category) {
         // Demos for each category.
         Category category = (Category) value;
-        return new DefaultNodeInfo<Recipe>(new ListListModel<Recipe>(
+        return new DefaultNodeInfo<Recipe>(new ListViewAdapter<Recipe>(
             category.getRecipes()), new RecipeCell());
       }
       return null;
     }
 
-    @Override
     public boolean isLeaf(Object value, TreeNode<?> treeNode) {
       // The root and categories have children.
       if (value == null || value instanceof Category) {
@@ -93,15 +92,13 @@
   private SimpleCellListRecipe defaultRecipe;
   private Recipe curRecipe;
 
-  @Override
   public void onModuleLoad() {
     RootLayoutPanel.get().add(binder.createAndBindUi(this));
-    createRecipes(recipeTreeModel.catModel.getList());
+    createRecipes(recipeTreeModel.adapter.getList());
 
     treeSelection = new SingleSelectionModel<Object>();
     recipeTree.setSelectionModel(treeSelection);
     treeSelection.addSelectionChangeHandler(new SelectionModel.SelectionChangeHandler() {
-      @Override
       public void onSelectionChange(SelectionChangeEvent event) {
         Object o = treeSelection.getSelectedObject();
         if (o instanceof Recipe) {
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/EditableTableRecipe.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/EditableTableRecipe.java
index 1307d2a..11b5e49 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/EditableTableRecipe.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/EditableTableRecipe.java
@@ -21,7 +21,7 @@
 import com.google.gwt.bikeshed.list.client.Column;
 import com.google.gwt.bikeshed.list.client.Header;
 import com.google.gwt.bikeshed.list.client.PagingTableListView;
-import com.google.gwt.bikeshed.list.shared.ListListModel;
+import com.google.gwt.bikeshed.list.shared.ListViewAdapter;
 import com.google.gwt.event.dom.client.ClickEvent;
 import com.google.gwt.event.dom.client.ClickHandler;
 import com.google.gwt.user.client.ui.Button;
@@ -52,11 +52,12 @@
 
   @Override
   protected Widget createWidget() {
-    final ListListModel<String> model = new ListListModel<String>();
-    final PagingTableListView<String> table = new PagingTableListView<String>(model, 10);
+    final ListViewAdapter<String> adapter = new ListViewAdapter<String>();
+    final PagingTableListView<String> table = new PagingTableListView<String>(adapter, 10);
+    adapter.addView(table);
 
     for (int i = 0; i < 25; ++i) {
-      model.getList().add("" + i);
+      adapter.getList().add("" + i);
     }
 
     EditTextColumn column = new EditTextColumn();
@@ -65,26 +66,23 @@
     table.addColumn(column, header);
 
     column.setFieldUpdater(new FieldUpdater<String, String, String>() {
-      @Override
       public void update(int index, String object, String value, String viewData) {
-        model.getList().set(index, value);
+        adapter.getList().set(index, value);
       }
     });
 
     FlowPanel plusMinusPanel = new FlowPanel();
     Button addBtn = new Button("+", new ClickHandler() {
-      @Override
       public void onClick(ClickEvent event) {
-        List<String> list = model.getList();
+        List<String> list = adapter.getList();
         list.add("" + list.size());
       }
     });
     Button removeBtn = new Button("-", new ClickHandler() {
-      @Override
       public void onClick(ClickEvent event) {
-        int size = model.getList().size();
+        int size = adapter.getList().size();
         if (size > 0) {
-          model.getList().remove(size - 1);
+          adapter.getList().remove(size - 1);
         }
       }
     });
@@ -93,13 +91,11 @@
 
     FlowPanel nextPrevPanel = new FlowPanel();
     Button prevBtn = new Button("<", new ClickHandler() {
-      @Override
       public void onClick(ClickEvent event) {
         table.previousPage();
       }
     });
     Button nextBtn = new Button(">", new ClickHandler() {
-      @Override
       public void onClick(ClickEvent event) {
         table.nextPage();
       }
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MailRecipe.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MailRecipe.java
index 02aa427..4456372 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MailRecipe.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MailRecipe.java
@@ -22,7 +22,8 @@
 import com.google.gwt.bikeshed.list.client.SimpleColumn;
 import com.google.gwt.bikeshed.list.client.TextColumn;
 import com.google.gwt.bikeshed.list.shared.DefaultSelectionModel;
-import com.google.gwt.bikeshed.list.shared.ListListModel;
+import com.google.gwt.bikeshed.list.shared.ListViewAdapter;
+import com.google.gwt.bikeshed.list.shared.ProvidesKey;
 import com.google.gwt.event.dom.client.ClickEvent;
 import com.google.gwt.event.dom.client.ClickHandler;
 import com.google.gwt.event.dom.client.KeyUpEvent;
@@ -55,6 +56,12 @@
       }
     }
 
+    private static ProvidesKey<Message> keyProvider = new ProvidesKey<Message>() {
+      public Object getKey(Message item) {
+        return Integer.valueOf(item.id);
+      }
+    };
+
     // A map from enum names to their values
     private static Map<String, Type> typeMap = new HashMap<String, Type>();
 
@@ -62,6 +69,11 @@
     private Type type = Type.NONE;
 
     @Override
+    public ProvidesKey<Message> getKeyProvider() {
+      return keyProvider;
+    }
+
+    @Override
     public boolean isDefaultSelected(Message object) {
       switch (type) {
         case NONE:
@@ -127,8 +139,8 @@
     private void appendExceptions(StringBuilder sb,
         Map<Object, Boolean> exceptions, boolean selected) {
       boolean first = true;
-      for (Object messageId : exceptions.keySet()) {
-        if (exceptions.get(messageId) != selected) {
+      for (Map.Entry<Object, Boolean> entry : exceptions.entrySet()) {
+        if (entry.getValue() != selected) {
           continue;
         }
 
@@ -137,7 +149,7 @@
           sb.append(selected ? '+' : '-');
           sb.append("msg(s) ");
         }
-        sb.append(messageId);
+        sb.append(entry.getKey());
         sb.append(' ');
       }
     }
@@ -148,7 +160,7 @@
   }
 
   // Hashing, comparison, and equality are based on the message id
-  class Message implements Comparable<Message> {
+  static class Message {
     int id;
     boolean isRead;
     String sender;
@@ -161,10 +173,6 @@
       this.subject = subject;
     }
 
-    public int compareTo(Message o) {
-      return id - o.id;
-    }
-
     @Override
     public boolean equals(Object obj) {
       if (!(obj instanceof Message)) {
@@ -245,8 +253,8 @@
 
   @Override
   protected Widget createWidget() {
-    ListListModel<Message> listModel = new ListListModel<Message>();
-    List<Message> messages = listModel.getList();
+    ListViewAdapter<Message> adapter = new ListViewAdapter<Message>();
+    List<Message> messages = adapter.getList();
     Random rand = new Random();
     for (int i = 0; i < 1000; i++) {
       Message message = new Message(10000 + i,
@@ -256,8 +264,9 @@
       messages.add(message);
     }
 
-    table = new PagingTableListView<Message>(listModel, 10);
+    table = new PagingTableListView<Message>(adapter, 10);
     table.setSelectionModel(selectionModel);
+    adapter.addView(table);
 
     // The state of the checkbox is taken from the selection model
     SimpleColumn<Message, Boolean> selectedColumn = new SimpleColumn<Message, Boolean>(
@@ -287,7 +296,7 @@
       }
     };
     table.addColumn(idColumn, "ID");
-  
+
     TextColumn<Message> isReadColumn = new TextColumn<Message>() {
       @Override
       public String getValue(Message object) {
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MultiSelectionModel.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MultiSelectionModel.java
index 7b63ecd..c5c8be2 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MultiSelectionModel.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MultiSelectionModel.java
@@ -22,16 +22,21 @@
 
 /**
  * A simple selection model that allows only multiple objects to be selected.
+ *
+ * @param <T> the record data type
  */
 public class MultiSelectionModel<T> extends AbstractSelectionModel<T> {
 
   private Set<T> selectedSet = new TreeSet<T>();
 
+  public Set<T> getSelectedSet() {
+    return selectedSet;
+  }
+
   public boolean isSelected(T object) {
     return selectedSet.contains(object);
   }
 
-  @Override
   public void setSelected(T object, boolean selected) {
     if (selected) {
       selectedSet.add(object);
@@ -40,8 +45,4 @@
     }
     scheduleSelectionChangeEvent();
   }
-
-  public Set<T> getSelectedSet() {
-    return selectedSet;
-  }
 }
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MyTreeViewModel.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MyTreeViewModel.java
index 127e446..bdc6b7b 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MyTreeViewModel.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/MyTreeViewModel.java
@@ -21,10 +21,9 @@
 import com.google.gwt.bikeshed.cells.client.FieldUpdater;
 import com.google.gwt.bikeshed.cells.client.ValueUpdater;
 import com.google.gwt.bikeshed.list.client.HasCell;
-import com.google.gwt.bikeshed.list.shared.AbstractListModel;
-import com.google.gwt.bikeshed.list.shared.ListModel;
+import com.google.gwt.bikeshed.list.client.ListView;
+import com.google.gwt.bikeshed.list.shared.AbstractListViewAdapter;
 import com.google.gwt.bikeshed.list.shared.SelectionModel;
-import com.google.gwt.bikeshed.list.shared.ListRegistration;
 import com.google.gwt.bikeshed.tree.client.TreeNode;
 import com.google.gwt.bikeshed.tree.client.TreeViewModel;
 import com.google.gwt.core.client.GWT;
@@ -40,15 +39,15 @@
  */
 public class MyTreeViewModel implements TreeViewModel {
 
-  private static class IntegerListModel extends AbstractListModel<Integer> {
+  private static class IntegerListViewAdapter extends AbstractListViewAdapter<Integer> {
     int wordLength;
 
-    public IntegerListModel(int wordLength) {
+    public IntegerListViewAdapter(int wordLength) {
       this.wordLength = wordLength;
     }
 
     @Override
-    protected void onRangeChanged(ListRegistration<Integer> reg, int start, int length) {
+    protected void onRangeChanged(ListView<Integer> view) {
       List<Integer> values = new ArrayList<Integer>(1);
       values.add(wordLength);
       updateDataSize(1, true);
@@ -56,15 +55,15 @@
     }
   }
 
-  private static class StringListModel extends AbstractListModel<String> {
+  private static class StringListViewAdapter extends AbstractListViewAdapter<String> {
     String value;
 
-    public StringListModel(final String value) {
+    public StringListViewAdapter(final String value) {
       this.value = value;
     }
 
     @Override
-    protected void onRangeChanged(ListRegistration<String> reg, int start, int length) {
+    protected void onRangeChanged(ListView<String> view) {
       String prefix = value.endsWith("...") ? value.substring(0,
           value.length() - 3) : value;
       dataService.getNext(prefix, new AsyncCallback<List<String>>() {
@@ -162,11 +161,11 @@
 
   private NodeInfo<?> getNodeInfoHelper(final String value) {
     if (value.endsWith("...")) {
-      ListModel<String> listModel = new StringListModel(value.toString());
-      return new DefaultNodeInfo<String>(listModel, hasCells);
+      AbstractListViewAdapter<String> adapter = new StringListViewAdapter(value.toString());
+      return new DefaultNodeInfo<String>(adapter, hasCells);
     } else {
-      ListModel<Integer> listModel = new IntegerListModel(value.length());
-      return new DefaultNodeInfo<Integer>(listModel, INTEGER_CELL,
+      AbstractListViewAdapter<Integer> adapter = new IntegerListViewAdapter(value.length());
+      return new DefaultNodeInfo<Integer>(adapter, INTEGER_CELL,
           new ValueUpdater<Integer, Void>() {
             public void update(Integer value, Void viewData) {
               Window.alert("Integer = " + value);
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Recipe.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Recipe.java
index cf66a1b..4f450da 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Recipe.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/Recipe.java
@@ -28,6 +28,10 @@
     this.title = title;
   }
 
+  public String getTitle() {
+    return title;
+  }
+
   public final Widget getWidget() {
     if (widget == null) {
       widget = createWidget();
@@ -35,9 +39,5 @@
     return widget;
   }
 
-  public String getTitle() {
-    return title;
-  }
-
   protected abstract Widget createWidget();
 }
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/SideBySideTreeRecipe.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/SideBySideTreeRecipe.java
index 497d503..8e7e234 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/SideBySideTreeRecipe.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/SideBySideTreeRecipe.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -39,7 +39,6 @@
     final Label label = new Label();
     final MultiSelectionModel<Object> selectionModel = new MultiSelectionModel<Object>();
     selectionModel.addSelectionChangeHandler(new SelectionModel.SelectionChangeHandler() {
-      @Override
       public void onSelectionChange(SelectionChangeEvent event) {
         label.setText("Selected " + selectionModel.getSelectedSet().toString());
       }
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/SimpleCellListRecipe.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/SimpleCellListRecipe.java
index 4184971..b30250d 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/SimpleCellListRecipe.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/SimpleCellListRecipe.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -17,7 +17,7 @@
 
 import com.google.gwt.bikeshed.cells.client.TextCell;
 import com.google.gwt.bikeshed.list.client.SimpleCellList;
-import com.google.gwt.bikeshed.list.shared.ListListModel;
+import com.google.gwt.bikeshed.list.shared.ListViewAdapter;
 import com.google.gwt.user.client.Timer;
 import com.google.gwt.user.client.ui.Widget;
 
@@ -34,14 +34,15 @@
 
   @Override
   protected Widget createWidget() {
-    ListListModel<String> listModel = new ListListModel<String>();
-    final List<String> list = listModel.getList();
-    for (int i = 0; i < 50; i++) {
-      list.add("" + (i * 1000));
+    ListViewAdapter<String> adapter = new ListViewAdapter<String>();
+    final List<String> list = adapter.getList();
+    for (int i = 0; i < 40; i++) {
+      list.add("" + ((i + 10) * 1000));
     }
 
     SimpleCellList<String> simpleCellList =
-      new SimpleCellList<String>(listModel, TextCell.getInstance(), 10, 5);
+      new SimpleCellList<String>(TextCell.getInstance(), 10, 5);
+    adapter.addView(simpleCellList);
 
     new Timer() {
       int index = 0;
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/SingleSelectionModel.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/SingleSelectionModel.java
index 1d15171..7fae547 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/SingleSelectionModel.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/SingleSelectionModel.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -19,17 +19,24 @@
 
 /**
  * A simple selection model that allows only one object to be selected a a time.
+ *
+ * @param <T> the record data type
  */
 public final class SingleSelectionModel<T> extends AbstractSelectionModel<T> {
 
   private T curSelection;
 
-  @Override
+  /**
+   * Gets the currently-selected object.
+   */
+  public T getSelectedObject() {
+    return curSelection;
+  }
+
   public boolean isSelected(T object) {
     return object.equals(curSelection);
   }
 
-  @Override
   public void setSelected(T object, boolean selected) {
     if (selected) {
       curSelection = object;
@@ -38,11 +45,4 @@
     }
     scheduleSelectionChangeEvent();
   }
-
-  /**
-   * Gets the currently-selected object.
-   */
-  public T getSelectedObject() {
-    return curSelection;
-  }
 }
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/ValidationRecipe.java b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/ValidationRecipe.java
index cf0d4eb..0c10eba 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/ValidationRecipe.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/cookbook/client/ValidationRecipe.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -19,7 +19,7 @@
 import com.google.gwt.bikeshed.list.client.Column;
 import com.google.gwt.bikeshed.list.client.PagingTableListView;
 import com.google.gwt.bikeshed.list.client.TextColumn;
-import com.google.gwt.bikeshed.list.shared.ListListModel;
+import com.google.gwt.bikeshed.list.shared.ListViewAdapter;
 import com.google.gwt.bikeshed.list.shared.ProvidesKey;
 import com.google.gwt.user.client.Timer;
 import com.google.gwt.user.client.ui.Widget;
@@ -74,8 +74,8 @@
 
   @Override
   protected Widget createWidget() {
-    ListListModel<Address> listModel = new ListListModel<Address>();
-    final List<Address> list = listModel.getList();
+    ListViewAdapter<Address> adapter = new ListViewAdapter<Address>();
+    final List<Address> list = adapter.getList();
     for (int i = 10; i < 50; i++) {
       if (zipInvalid(30000 + i)) {
         continue;
@@ -84,14 +84,15 @@
       String zip = "300" + i;
       list.add(new Address("GA", zip));
     }
-    listModel.setKeyProvider(new ProvidesKey<Address>() {
+    adapter.setKeyProvider(new ProvidesKey<Address>() {
       public Object getKey(Address object) {
         return object.key;
       }
     });
 
     PagingTableListView<Address> table = new PagingTableListView<Address>(
-        listModel, 10);
+        adapter, 10);
+    adapter.addView(table);
     TextColumn<Address> stateColumn = new TextColumn<Address>() {
       @Override
       public String getValue(Address object) {
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/ChangeCell.java b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/ChangeCell.java
index 61efe6f..0969bcb 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/ChangeCell.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/ChangeCell.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -18,7 +18,8 @@
 import com.google.gwt.bikeshed.cells.client.Cell;
 
 /**
- * A cell that represents a {@link StockQuote}.
+ * A cell that represents a
+ * {@link com.google.gwt.sample.bikeshed.stocks.shared.StockQuote StockQuote}.
  */
 public class ChangeCell extends Cell<String, Void> {
 
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/FavoritesWidget.java b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/FavoritesWidget.java
index 7ef9774..137c750 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/FavoritesWidget.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/FavoritesWidget.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -16,7 +16,7 @@
 package com.google.gwt.sample.bikeshed.stocks.client;
 
 import com.google.gwt.bikeshed.list.client.PagingTableListView;
-import com.google.gwt.bikeshed.list.shared.ListModel;
+import com.google.gwt.bikeshed.list.shared.AbstractListViewAdapter;
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.sample.bikeshed.stocks.shared.StockQuote;
 import com.google.gwt.uibinder.client.UiBinder;
@@ -35,10 +35,10 @@
 
   @UiField PagingTableListView<StockQuote> listView;
 
-  private final ListModel<StockQuote> model;
+  private final AbstractListViewAdapter<StockQuote> adapter;
 
-  public FavoritesWidget(ListModel<StockQuote> model) {
-    this.model = model;
+  public FavoritesWidget(AbstractListViewAdapter<StockQuote> adapter) {
+    this.adapter = adapter;
     initWidget(binder.createAndBindUi(this));
 
     listView.addColumn(Columns.tickerColumn, "ticker");
@@ -53,6 +53,8 @@
 
   @UiFactory
   PagingTableListView<StockQuote> createListView() {
-    return new PagingTableListView<StockQuote>(model, 10);
+    PagingTableListView<StockQuote> view = new PagingTableListView<StockQuote>(adapter, 10);
+    adapter.addView(view);
+    return view;
   }
 }
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/PlayerScoresWidget.java b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/PlayerScoresWidget.java
index ac55f44..30d9c17 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/PlayerScoresWidget.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/PlayerScoresWidget.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -17,7 +17,7 @@
 
 import com.google.gwt.bikeshed.cells.client.Cell;
 import com.google.gwt.bikeshed.list.client.SimpleCellList;
-import com.google.gwt.bikeshed.list.shared.ListModel;
+import com.google.gwt.bikeshed.list.shared.AbstractListViewAdapter;
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.sample.bikeshed.stocks.shared.PlayerInfo;
 import com.google.gwt.uibinder.client.UiBinder;
@@ -51,7 +51,7 @@
       sb.append(StocksDesktop.getFormattedPrice(value.getNetWorth()));
       sb.append("<br><b>Cash: </b>");
       sb.append(StocksDesktop.getFormattedPrice(value.getCash()));
-      
+
       List<String> status = value.getStatus();
       if (status != null) {
         for (String s : status) {
@@ -66,15 +66,17 @@
   @UiField
   SimpleCellList<PlayerInfo> listView;
 
-  private final ListModel<PlayerInfo> model;
+  private final AbstractListViewAdapter<PlayerInfo> adapter;
 
-  public PlayerScoresWidget(ListModel<PlayerInfo> model) {
-    this.model = model;
+  public PlayerScoresWidget(AbstractListViewAdapter<PlayerInfo> adapter) {
+    this.adapter = adapter;
     initWidget(binder.createAndBindUi(this));
   }
 
   @UiFactory
   SimpleCellList<PlayerInfo> createListView() {
-    return new SimpleCellList<PlayerInfo>(model, new PlayerInfoCell(), 1, 1);
+    SimpleCellList<PlayerInfo> view = new SimpleCellList<PlayerInfo>(new PlayerInfoCell(), 1, 1);
+    adapter.addView(view);
+    return view;
   }
 }
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StockQueryWidget.java b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StockQueryWidget.java
index c404c8c..f7a36cb 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StockQueryWidget.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StockQueryWidget.java
@@ -16,7 +16,7 @@
 package com.google.gwt.sample.bikeshed.stocks.client;
 
 import com.google.gwt.bikeshed.list.client.PagingTableListView;
-import com.google.gwt.bikeshed.list.shared.ListModel;
+import com.google.gwt.bikeshed.list.shared.AbstractListViewAdapter;
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.event.dom.client.KeyUpEvent;
 import com.google.gwt.event.dom.client.KeyUpHandler;
@@ -40,10 +40,10 @@
   @UiField PagingTableListView<StockQuote> listView;
   @UiField TextBox queryField = new TextBox();
 
-  private final ListModel<StockQuote> model;
+  private final AbstractListViewAdapter<StockQuote> adapter;
 
-  public StockQueryWidget(ListModel<StockQuote> model, final Updater updater) {
-    this.model = model;
+  public StockQueryWidget(AbstractListViewAdapter<StockQuote> adapter, final Updater updater) {
+    this.adapter = adapter;
     initWidget(binder.createAndBindUi(this));
 
     listView.addColumn(Columns.favoriteColumn);
@@ -77,10 +77,12 @@
   public String getSearchQuery() {
     return normalize(queryField.getText());
   }
-  
+
   @UiFactory
   PagingTableListView<StockQuote> createListView() {
-    return new PagingTableListView<StockQuote>(model, 10);
+    PagingTableListView<StockQuote> view = new PagingTableListView<StockQuote>(adapter, 10);
+    adapter.addView(view);
+    return view;
   }
 
   private String normalize(String input) {
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksDesktop.java b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksDesktop.java
index 9dc451f..cbc7b94 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksDesktop.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksDesktop.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -16,9 +16,9 @@
 package com.google.gwt.sample.bikeshed.stocks.client;
 
 import com.google.gwt.bikeshed.cells.client.FieldUpdater;
-import com.google.gwt.bikeshed.list.shared.AsyncListModel;
-import com.google.gwt.bikeshed.list.shared.ListListModel;
-import com.google.gwt.bikeshed.list.shared.ListRegistration;
+import com.google.gwt.bikeshed.list.client.ListView;
+import com.google.gwt.bikeshed.list.shared.AsyncListViewAdapter;
+import com.google.gwt.bikeshed.list.shared.ListViewAdapter;
 import com.google.gwt.bikeshed.list.shared.Range;
 import com.google.gwt.bikeshed.tree.client.SideBySideTreeView;
 import com.google.gwt.bikeshed.tree.client.TreeNode;
@@ -27,7 +27,7 @@
 import com.google.gwt.event.logical.shared.CloseEvent;
 import com.google.gwt.event.logical.shared.CloseHandler;
 import com.google.gwt.i18n.client.NumberFormat;
-import com.google.gwt.sample.bikeshed.stocks.client.TransactionTreeViewModel.SectorListModel;
+import com.google.gwt.sample.bikeshed.stocks.client.TransactionTreeViewModel.SectorListViewAdapter;
 import com.google.gwt.sample.bikeshed.stocks.shared.PlayerInfo;
 import com.google.gwt.sample.bikeshed.stocks.shared.StockQuote;
 import com.google.gwt.sample.bikeshed.stocks.shared.StockQuoteList;
@@ -81,12 +81,12 @@
   private BuySellPopup buySellPopup = new BuySellPopup();
   private final StockServiceAsync dataService = GWT.create(StockService.class);
 
-  private AsyncListModel<StockQuote> favoritesListModel;
-  private AsyncListModel<PlayerInfo> playerScoresListModel;
-  private AsyncListModel<StockQuote> searchListModel;
-  private Map<String, ListListModel<Transaction>> transactionListListModelsByTicker =
-    new HashMap<String, ListListModel<Transaction>>();
-  private ListListModel<Transaction> transactionListModel;
+  private AsyncListViewAdapter<StockQuote> favoritesListViewAdapter;
+  private AsyncListViewAdapter<PlayerInfo> playerScoresListViewAdapter;
+  private AsyncListViewAdapter<StockQuote> searchListViewAdapter;
+  private Map<String, ListViewAdapter<Transaction>> transactionListViewAdaptersByTicker =
+    new HashMap<String, ListViewAdapter<Transaction>>();
+  private ListViewAdapter<Transaction> transactionListViewAdapter;
   private List<Transaction> transactions;
 
   private TransactionTreeViewModel treeModel;
@@ -112,33 +112,33 @@
   public void onModuleLoad() {
     // Create the various models. Do this before binding the UI, because some
     // of the UiFactories need the models to instantiate their widgets.
-    searchListModel = new AsyncListModel<StockQuote>() {
+    searchListViewAdapter = new AsyncListViewAdapter<StockQuote>() {
       @Override
-      protected void onRangeChanged(ListRegistration<StockQuote> reg, int start, int length) {
+      protected void onRangeChanged(ListView<StockQuote> view) {
         update();
       }
     };
-    searchListModel.setKeyProvider(StockQuote.KEY_PROVIDER);
+    searchListViewAdapter.setKeyProvider(StockQuote.KEY_PROVIDER);
 
-    favoritesListModel = new AsyncListModel<StockQuote>() {
+    favoritesListViewAdapter = new AsyncListViewAdapter<StockQuote>() {
       @Override
-      protected void onRangeChanged(ListRegistration<StockQuote> reg, int start, int length) {
+      protected void onRangeChanged(ListView<StockQuote> view) {
         update();
       }
     };
-    favoritesListModel.setKeyProvider(StockQuote.KEY_PROVIDER);
+    favoritesListViewAdapter.setKeyProvider(StockQuote.KEY_PROVIDER);
 
-    playerScoresListModel = new AsyncListModel<PlayerInfo>() {
+    playerScoresListViewAdapter = new AsyncListViewAdapter<PlayerInfo>() {
       @Override
-      protected void onRangeChanged(ListRegistration<PlayerInfo> reg, int start, int length) {
+      protected void onRangeChanged(ListView<PlayerInfo> view) {
       }
     };
 
-    treeModel = new TransactionTreeViewModel(this, favoritesListModel,
-        transactionListListModelsByTicker);
+    treeModel = new TransactionTreeViewModel(this, favoritesListViewAdapter,
+        transactionListViewAdaptersByTicker);
 
-    transactionListModel = new ListListModel<Transaction>();
-    transactions = transactionListModel.getList();
+    transactionListViewAdapter = new ListViewAdapter<Transaction>();
+    transactions = transactionListViewAdapter.getList();
 
     // Now create the UI.
     RootLayoutPanel.get().add(binder.createAndBindUi(this));
@@ -176,7 +176,7 @@
 
   /**
    * Process the {@link StockResponse} from the server.
-   * 
+   *
    * @param response the stock response
    */
   public void processStockResponse(StockResponse response) {
@@ -184,8 +184,8 @@
     StockQuoteList searchResults = response.getSearchResults();
     String searchQuery = queryWidget.getSearchQuery();
     if (searchQuery != null && searchQuery.equals(response.getSearchQuery())) {
-      searchListModel.updateDataSize(response.getNumSearchResults(), true);
-      searchListModel.updateViewData(searchResults.getStartIndex(),
+      searchListViewAdapter.updateDataSize(response.getNumSearchResults(), true);
+      searchListViewAdapter.updateViewData(searchResults.getStartIndex(),
           searchResults.size(), searchResults);
     }
 
@@ -212,13 +212,13 @@
 
   /**
    * Set or unset a ticker symbol as a 'favorite'.
-   * 
+   *
    * @param ticker the ticker symbol
    * @param favorite if true, make the stock a favorite
    */
   public void setFavorite(String ticker, boolean favorite) {
     if (favorite) {
-      dataService.addFavorite(ticker, favoritesListModel.getRanges()[0],
+      dataService.addFavorite(ticker, favoritesListViewAdapter.getRanges()[0],
           new AsyncCallback<StockResponse>() {
             public void onFailure(Throwable caught) {
               handleRpcError(caught, "Error adding favorite");
@@ -230,7 +230,7 @@
             }
           });
     } else {
-      dataService.removeFavorite(ticker, favoritesListModel.getRanges()[0],
+      dataService.removeFavorite(ticker, favoritesListViewAdapter.getRanges()[0],
           new AsyncCallback<StockResponse>() {
             public void onFailure(Throwable caught) {
               handleRpcError(caught, "Error removing favorite");
@@ -266,10 +266,10 @@
 
         // Update the next level of the transaction tree
         // for the given ticker
-        ListListModel<Transaction> t = transactionListListModelsByTicker.get(ticker);
+        ListViewAdapter<Transaction> t = transactionListViewAdaptersByTicker.get(ticker);
         if (t == null) {
-          t = new ListListModel<Transaction>();
-          transactionListListModelsByTicker.put(ticker, t);
+          t = new ListViewAdapter<Transaction>();
+          transactionListViewAdaptersByTicker.put(ticker, t);
         }
         t.getList().add(result);
       }
@@ -286,14 +286,14 @@
 
     updateTimer.cancel();
 
-    Range[] searchRanges = searchListModel.getRanges();
-    Range[] favoritesRanges = favoritesListModel.getRanges();
+    Range[] searchRanges = searchListViewAdapter.getRanges();
+    Range[] favoritesRanges = favoritesListViewAdapter.getRanges();
 
     String sectorName = getSectorName();
-    SectorListModel sectorListModel = sectorName != null
-        ? treeModel.getSectorListModel(sectorName) : null;
-    Range[] sectorRanges = sectorListModel == null ? null
-        : sectorListModel.getRanges();
+    SectorListViewAdapter sectorListViewAdapter = sectorName != null
+        ? treeModel.getSectorListViewAdapter(sectorName) : null;
+    Range[] sectorRanges = sectorListViewAdapter == null ? null
+        : sectorListViewAdapter.getRanges();
 
     if (searchRanges == null || searchRanges.length == 0
         || favoritesRanges == null || favoritesRanges.length == 0) {
@@ -303,7 +303,7 @@
     String searchQuery = queryWidget.getSearchQuery();
 
     StockRequest request = new StockRequest(searchQuery,
-        sectorListModel != null ? sectorListModel.getSector() : null,
+        sectorListViewAdapter != null ? sectorListViewAdapter.getSector() : null,
         searchRanges[0], favoritesRanges[0], sectorRanges != null
             && sectorRanges.length > 0 ? sectorRanges[0] : null);
     dataService.getStockQuotes(request, new AsyncCallback<StockResponse>() {
@@ -321,17 +321,17 @@
 
   @UiFactory
   FavoritesWidget createFavoritesWidget() {
-    return new FavoritesWidget(favoritesListModel);
+    return new FavoritesWidget(favoritesListViewAdapter);
   }
 
   @UiFactory
   PlayerScoresWidget createPlayerScoresWidget() {
-    return new PlayerScoresWidget(playerScoresListModel);
+    return new PlayerScoresWidget(playerScoresListViewAdapter);
   }
 
   @UiFactory
   StockQueryWidget createQueryWidget() {
-    return new StockQueryWidget(searchListModel, this);
+    return new StockQueryWidget(searchListViewAdapter, this);
   }
 
   @UiFactory
@@ -354,8 +354,8 @@
 
   /**
    * Display a message to the user when an RPC call fails.
-   * 
-   * @param caught the exception
+   *
+   * @param caughtbad the exception
    * @param displayMessage the message to display to the user, or null to
    *          display a default message
    * @return true if recoverable, false if not
@@ -378,8 +378,8 @@
   private void updateFavorites(StockResponse response) {
     // Update the favorites list.
     StockQuoteList favorites = response.getFavorites();
-    favoritesListModel.updateDataSize(response.getNumFavorites(), true);
-    favoritesListModel.updateViewData(favorites.getStartIndex(),
+    favoritesListViewAdapter.updateDataSize(response.getNumFavorites(), true);
+    favoritesListViewAdapter.updateViewData(favorites.getStartIndex(),
         favorites.size(), favorites);
   }
 
@@ -387,18 +387,18 @@
     // Update the player scores.
     List<PlayerInfo> playerScores = response.getPlayers();
     int numPlayers = playerScores.size();
-    playerScoresListModel.updateDataSize(numPlayers, true);
-    playerScoresListModel.updateViewData(0, numPlayers, playerScores);
+    playerScoresListViewAdapter.updateDataSize(numPlayers, true);
+    playerScoresListViewAdapter.updateViewData(0, numPlayers, playerScores);
   }
 
   private void updateSector(StockResponse response) {
     // Update the sector list.
     StockQuoteList sectorList = response.getSector();
     if (sectorList != null) {
-      SectorListModel sectorListModel = treeModel.getSectorListModel(getSectorName());
-      if (sectorListModel != null) {
-        sectorListModel.updateDataSize(response.getNumSector(), true);
-        sectorListModel.updateViewData(sectorList.getStartIndex(),
+      SectorListViewAdapter sectorListViewAdapter = treeModel.getSectorListViewAdapter(getSectorName());
+      if (sectorListViewAdapter != null) {
+        sectorListViewAdapter.updateDataSize(response.getNumSector(), true);
+        sectorListViewAdapter.updateViewData(sectorList.getStartIndex(),
             sectorList.size(), sectorList);
       }
     }
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksMobile.java b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksMobile.java
index b401424..9c3c8f5 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksMobile.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/StocksMobile.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -15,9 +15,9 @@
  */
 package com.google.gwt.sample.bikeshed.stocks.client;
 
+import com.google.gwt.bikeshed.list.client.ListView;
 import com.google.gwt.bikeshed.list.client.PagingTableListView;
-import com.google.gwt.bikeshed.list.shared.AsyncListModel;
-import com.google.gwt.bikeshed.list.shared.ListRegistration;
+import com.google.gwt.bikeshed.list.shared.AsyncListViewAdapter;
 import com.google.gwt.bikeshed.list.shared.Range;
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.i18n.client.NumberFormat;
@@ -39,9 +39,9 @@
  */
 public class StocksMobile {
 
-  interface Binder extends UiBinder<Widget, StocksMobile> {  
+  interface Binder extends UiBinder<Widget, StocksMobile> {
   }
-  
+
   private static final Binder binder = GWT.create(Binder.class);
 
   /**
@@ -55,7 +55,7 @@
 
   @UiField PagingTableListView<StockQuote> listView;
   private final StockServiceAsync dataService = GWT.create(StockService.class);
-  private AsyncListModel<StockQuote> favoritesListModel;
+  private AsyncListViewAdapter<StockQuote> favoritesListViewAdapter;
 
   /**
    * The timer used to update the stock quotes.
@@ -73,13 +73,13 @@
   public void onModuleLoad() {
     // Create the various models. Do this before binding the UI, because some
     // of the UiFactories need the models to instantiate their widgets.
-    favoritesListModel = new AsyncListModel<StockQuote>() {
+    favoritesListViewAdapter = new AsyncListViewAdapter<StockQuote>() {
       @Override
-      protected void onRangeChanged(ListRegistration<StockQuote> reg, int start, int length) {
+      protected void onRangeChanged(ListView<StockQuote> view) {
         update();
       }
     };
-    favoritesListModel.setKeyProvider(StockQuote.KEY_PROVIDER);
+    favoritesListViewAdapter.setKeyProvider(StockQuote.KEY_PROVIDER);
 
     // Now create the UI.
     RootPanel.get().add(binder.createAndBindUi(this));
@@ -88,7 +88,7 @@
 
   /**
    * Process the {@link StockResponse} from the server.
-   * 
+   *
    * @param response the stock response
    */
   public void processStockResponse(StockResponse response) {
@@ -100,7 +100,7 @@
   }
 
   public void update() {
-    Range[] favoritesRanges = favoritesListModel.getRanges();
+    Range[] favoritesRanges = favoritesListViewAdapter.getRanges();
 
     StockRequest request = new StockRequest("TODO", null, null,
         favoritesRanges[0], null);
@@ -121,7 +121,8 @@
   @UiFactory
   PagingTableListView<StockQuote> createFavoritesWidget() {
     PagingTableListView<StockQuote> favorite = new PagingTableListView<StockQuote>(
-        favoritesListModel, 10);
+        favoritesListViewAdapter, 10);
+    favoritesListViewAdapter.addView(favorite);
 
     favorite.addColumn(Columns.tickerColumn, "ticker");
     favorite.addColumn(Columns.priceColumn, "price");
@@ -135,7 +136,7 @@
 
   /**
    * Display a message to the user when an RPC call fails.
-   * 
+   *
    * @param caught the exception
    * @param displayMessage the message to display to the user, or null to
    *          display a default message
@@ -159,8 +160,8 @@
   private void updateFavorites(StockResponse response) {
     // Update the favorites list.
     StockQuoteList favorites = response.getFavorites();
-    favoritesListModel.updateDataSize(response.getNumFavorites(), true);
-    favoritesListModel.updateViewData(favorites.getStartIndex(),
+    favoritesListViewAdapter.updateDataSize(response.getNumFavorites(), true);
+    favoritesListViewAdapter.updateViewData(favorites.getStartIndex(),
         favorites.size(), favorites);
   }
 }
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/TransactionTreeViewModel.java b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/TransactionTreeViewModel.java
index 4065273..790800d 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/TransactionTreeViewModel.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/TransactionTreeViewModel.java
@@ -19,10 +19,10 @@
 import com.google.gwt.bikeshed.cells.client.Cell;
 import com.google.gwt.bikeshed.cells.client.TextCell;
 import com.google.gwt.bikeshed.cells.client.ValueUpdater;
-import com.google.gwt.bikeshed.list.shared.AsyncListModel;
-import com.google.gwt.bikeshed.list.shared.ListListModel;
-import com.google.gwt.bikeshed.list.shared.ListModel;
-import com.google.gwt.bikeshed.list.shared.ListRegistration;
+import com.google.gwt.bikeshed.list.client.ListView;
+import com.google.gwt.bikeshed.list.shared.AbstractListViewAdapter;
+import com.google.gwt.bikeshed.list.shared.AsyncListViewAdapter;
+import com.google.gwt.bikeshed.list.shared.ListViewAdapter;
 import com.google.gwt.bikeshed.tree.client.TreeNode;
 import com.google.gwt.bikeshed.tree.client.TreeViewModel;
 import com.google.gwt.sample.bikeshed.stocks.shared.StockQuote;
@@ -38,11 +38,11 @@
  */
 class TransactionTreeViewModel implements TreeViewModel {
 
-  class SectorListModel extends AsyncListModel<StockQuote> {
+  class SectorListViewAdapter extends AsyncListViewAdapter<StockQuote> {
 
     String sector;
 
-    public SectorListModel(String sector) {
+    public SectorListViewAdapter(String sector) {
       this.sector = sector;
       setKeyProvider(StockQuote.KEY_PROVIDER);
     }
@@ -52,7 +52,7 @@
     }
 
     @Override
-    protected void onRangeChanged(ListRegistration<StockQuote> reg, int start, int length) {
+    protected void onRangeChanged(ListView<StockQuote> view) {
       updater.update();
     }
   }
@@ -73,48 +73,48 @@
 
   private static final Cell<Transaction, Void> TRANSACTION_CELL = new TransactionCell();
 
-  private Map<String, SectorListModel> sectorListModels = new HashMap<String, SectorListModel>();
-  private ListModel<StockQuote> stockQuoteListModel;
-  private ListListModel<String> topLevelListListModel = new ListListModel<String>();
+  private Map<String, SectorListViewAdapter> sectorListViewAdapters = new HashMap<String, SectorListViewAdapter>();
+  private AbstractListViewAdapter<StockQuote> stockQuoteListViewAdapter;
+  private ListViewAdapter<String> topLevelListViewAdapter = new ListViewAdapter<String>();
 
-  private Map<String, ListListModel<Transaction>> transactionListListModelsByTicker;
+  private Map<String, ListViewAdapter<Transaction>> transactionListViewAdaptersByTicker;
 
   private Updater updater;
 
   public TransactionTreeViewModel(Updater updater,
-      ListModel<StockQuote> stockQuoteListModel,
-      Map<String, ListListModel<Transaction>> transactionListListModelsByTicker) {
+      AbstractListViewAdapter<StockQuote> stockQuoteListViewAdapter,
+      Map<String, ListViewAdapter<Transaction>> transactionListViewAdaptersByTicker) {
     this.updater = updater;
-    this.stockQuoteListModel = stockQuoteListModel;
-    List<String> topLevelList = topLevelListListModel.getList();
+    this.stockQuoteListViewAdapter = stockQuoteListViewAdapter;
+    List<String> topLevelList = topLevelListViewAdapter.getList();
     topLevelList.add("Favorites");
     topLevelList.add("Dow Jones Industrials");
     topLevelList.add("S&P 500");
-    this.transactionListListModelsByTicker = transactionListListModelsByTicker;
+    this.transactionListViewAdaptersByTicker = transactionListViewAdaptersByTicker;
   }
 
   public <T> NodeInfo<?> getNodeInfo(T value, final TreeNode<T> treeNode) {
     if (value == null) {
-      return new TreeViewModel.DefaultNodeInfo<String>(topLevelListListModel,
+      return new TreeViewModel.DefaultNodeInfo<String>(topLevelListViewAdapter,
           TextCell.getInstance());
     } else if ("Favorites".equals(value)) {
-      return new TreeViewModel.DefaultNodeInfo<StockQuote>(stockQuoteListModel,
+      return new TreeViewModel.DefaultNodeInfo<StockQuote>(stockQuoteListViewAdapter,
           STOCK_QUOTE_CELL);
     } else if ("History".equals(value)) {
       String ticker = ((StockQuote) treeNode.getParentNode().getValue()).getTicker();
-      ListListModel<Transaction> listModel = transactionListListModelsByTicker.get(ticker);
-      if (listModel == null) {
-        listModel = new ListListModel<Transaction>();
-        transactionListListModelsByTicker.put(ticker, listModel);
+      ListViewAdapter<Transaction> adapter = transactionListViewAdaptersByTicker.get(ticker);
+      if (adapter == null) {
+        adapter = new ListViewAdapter<Transaction>();
+        transactionListViewAdaptersByTicker.put(ticker, adapter);
       }
-      return new TreeViewModel.DefaultNodeInfo<Transaction>(listModel,
+      return new TreeViewModel.DefaultNodeInfo<Transaction>(adapter,
           TRANSACTION_CELL);
     } else if ("Actions".equals(value)) {
-      ListListModel<String> listModel = new ListListModel<String>();
-      List<String> list = listModel.getList();
+      ListViewAdapter<String> adapter = new ListViewAdapter<String>();
+      List<String> list = adapter.getList();
       list.add("Buy");
       list.add("Sell");
-      return new TreeViewModel.DefaultNodeInfo<String>(listModel,
+      return new TreeViewModel.DefaultNodeInfo<String>(adapter,
           ButtonCell.getInstance(), new ValueUpdater<String, Void>() {
             public void update(String value, Void viewData) {
               StockQuote stockQuote = (StockQuote) treeNode.getParentNode().getValue();
@@ -126,24 +126,24 @@
             }
           });
     } else if (value instanceof String) {
-      SectorListModel listModel = new SectorListModel((String) value);
-      sectorListModels.put((String) value, listModel);
-      return new TreeViewModel.DefaultNodeInfo<StockQuote>(listModel,
+      SectorListViewAdapter adapter = new SectorListViewAdapter((String) value);
+      sectorListViewAdapters.put((String) value, adapter);
+      return new TreeViewModel.DefaultNodeInfo<StockQuote>(adapter,
           STOCK_QUOTE_CELL);
     } else if (value instanceof StockQuote) {
-      ListListModel<String> listModel = new ListListModel<String>();
-      List<String> list = listModel.getList();
+      ListViewAdapter<String> adapter = new ListViewAdapter<String>();
+      List<String> list = adapter.getList();
       list.add("Actions");
       list.add("History");
-      return new TreeViewModel.DefaultNodeInfo<String>(listModel,
+      return new TreeViewModel.DefaultNodeInfo<String>(adapter,
           TextCell.getInstance());
     }
 
     throw new IllegalArgumentException(value.toString());
   }
 
-  public SectorListModel getSectorListModel(String value) {
-    return sectorListModels.get(value);
+  public SectorListViewAdapter getSectorListViewAdapter(String value) {
+    return sectorListViewAdapters.get(value);
   }
 
   public boolean isLeaf(Object value, final TreeNode<?> parentNode) {
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/Updater.java b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/Updater.java
index de58000..56d7fb6 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/Updater.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/client/Updater.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -18,7 +18,7 @@
 import com.google.gwt.sample.bikeshed.stocks.shared.StockQuote;
 
 /**
- * Bridge between StockSample and StockQueryWidget.
+ * Bridge between StocksDesktop and StockQueryWidget.
  */
 public interface Updater {
 
@@ -28,7 +28,7 @@
 
   /**
    * Update the widget.
-   * 
+   *
    * TODO - refactor this
    */
   void update();
diff --git a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/server/StockServiceImpl.java b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/server/StockServiceImpl.java
index 74560cb..a9a6bb1 100644
--- a/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/server/StockServiceImpl.java
+++ b/bikeshed/src/com/google/gwt/sample/bikeshed/stocks/server/StockServiceImpl.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -19,7 +19,7 @@
 import com.google.appengine.api.users.UserService;
 import com.google.appengine.api.users.UserServiceFactory;
 import com.google.gwt.bikeshed.list.shared.Range;
-import com.google.gwt.bikeshed.list.shared.AbstractListModel.DefaultRange;
+import com.google.gwt.bikeshed.list.shared.AbstractListViewAdapter.DefaultRange;
 import com.google.gwt.sample.bikeshed.stocks.client.StockService;
 import com.google.gwt.sample.bikeshed.stocks.shared.PlayerInfo;
 import com.google.gwt.sample.bikeshed.stocks.shared.StockQuote;
@@ -147,7 +147,7 @@
       return null;
     }
   }
-  
+
   /**
    * A mapping of usernames to {@link PlayerStatus}.
    */
@@ -222,7 +222,7 @@
     // Perform the transaction with the user.
     int quantity = transaction.getQuantity();
     int price = quote.getPrice();
-    
+
     PlayerStatus player = ensurePlayer();
     if (transaction.isBuy()) {
       player.buy(ticker, quantity, price);
@@ -239,7 +239,7 @@
 
   /**
    * Create a stock response, updating the current user's net worth.
-   * 
+   *
    * @param player the player info
    * @param searchQuery the original search query
    * @param searchResults the search results
@@ -286,7 +286,7 @@
   /**
    * Ensure that a {@link PlayerStatus} for the current player exists and return
    * it.
-   * 
+   *
    * @return the {@link PlayerStatus} for the current player
    */
   private PlayerStatus ensurePlayer() {
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/gwt/customized/CustomizedShell.java b/bikeshed/src/com/google/gwt/sample/expenses/gwt/customized/CustomizedShell.java
index 50026c1..0098a44 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/gwt/customized/CustomizedShell.java
+++ b/bikeshed/src/com/google/gwt/sample/expenses/gwt/customized/CustomizedShell.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -21,7 +21,7 @@
 import com.google.gwt.bikeshed.cells.client.TextCell;
 import com.google.gwt.bikeshed.list.client.Column;
 import com.google.gwt.bikeshed.list.client.PagingTableListView;
-import com.google.gwt.bikeshed.list.shared.ListListModel;
+import com.google.gwt.bikeshed.list.shared.ListViewAdapter;
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.sample.expenses.gwt.request.ReportChanged;
@@ -48,17 +48,13 @@
   }
 
   interface ShellUiBinder extends UiBinder<Widget, CustomizedShell> {
-  } 
+  }
 
   private static ShellUiBinder uiBinder = GWT.create(ShellUiBinder.class);
 
-  private Listener listener;
-  private List<Values<ReportKey>> values;
-  private final ListListModel<Values<ReportKey>> model;
-
   @UiField Element error;
-  @UiField ListBox users;
   @UiField PagingTableListView<Values<ReportKey>> listView;
+  @UiField ListBox users;
 
   private Column<Values<ReportKey>, Date, Void> createdCol = new Column<Values<ReportKey>, Date, Void>(
       new DateCell()) {
@@ -67,6 +63,16 @@
       return object.get(ReportKey.get().getCreated());
     }
   };
+  private Listener listener;
+  private final ListViewAdapter<Values<ReportKey>> adapter;
+
+  private Column<Values<ReportKey>, String, String> purposeCol = new Column<Values<ReportKey>, String, String>(
+      new EditTextCell()) {
+    @Override
+    public String getValue(Values<ReportKey> object) {
+      return object.get(ReportKey.get().getPurpose());
+    }
+  };
 
   private Column<Values<ReportKey>, String, Void> statusCol = new Column<Values<ReportKey>, String, Void>(
       TextCell.getInstance()) {
@@ -76,16 +82,10 @@
     }
   };
 
-  private Column<Values<ReportKey>, String, String> purposeCol = new Column<Values<ReportKey>, String, String>(
-      new EditTextCell()) {
-    @Override
-    public String getValue(Values<ReportKey> object) {
-      return object.get(ReportKey.get().getPurpose());
-    }
-  };
+  private List<Values<ReportKey>> values;
 
   public CustomizedShell() {
-    model = new ListListModel<Values<ReportKey>>();
+    adapter = new ListViewAdapter<Values<ReportKey>>();
     initWidget(uiBinder.createAndBindUi(this));
 
     listView.addColumn(createdCol, "Created");
@@ -93,10 +93,9 @@
     listView.addColumn(purposeCol, "Purpose");
 
     purposeCol.setFieldUpdater(new FieldUpdater<Values<ReportKey>, String, String>() {
-      @Override
       public void update(int index, Values<ReportKey> object, String value,
           String viewData) {
-        model.getList().set(index, object);
+        adapter.getList().set(index, object);
         listener.setPurpose(object, value);
       }
     });
@@ -119,12 +118,12 @@
     refresh();
   }
 
-  private void refresh() {
-    model.setList(values);
-  }
-
   @UiFactory
   PagingTableListView<Values<ReportKey>> createListView() {
-    return new PagingTableListView<Values<ReportKey>>(model, 10);
+    return new PagingTableListView<Values<ReportKey>>(adapter, 10);
+  }
+
+  private void refresh() {
+    adapter.setList(values);
   }
 }
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/gwt/customized/EmployeeList.java b/bikeshed/src/com/google/gwt/sample/expenses/gwt/customized/EmployeeList.java
index 1634658..97adc19 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/gwt/customized/EmployeeList.java
+++ b/bikeshed/src/com/google/gwt/sample/expenses/gwt/customized/EmployeeList.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -46,8 +46,7 @@
   private Listener listener;
 
   /**
-   * @param shell
-   * @param requestFactory
+   * @param listBox
    */
   public EmployeeList(ListBox listBox) {
     this.listBox = listBox;
@@ -66,4 +65,4 @@
       listBox.addItem(values.get(EmployeeKey.get().getDisplayName()));
     }
   }
-}
\ No newline at end of file
+}
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/gwt/ui/employee/EmployeeListView.java b/bikeshed/src/com/google/gwt/sample/expenses/gwt/ui/employee/EmployeeListView.java
index cdefa6e..0f60c7a 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/gwt/ui/employee/EmployeeListView.java
+++ b/bikeshed/src/com/google/gwt/sample/expenses/gwt/ui/employee/EmployeeListView.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -32,7 +32,7 @@
 import java.util.List;
 
 /**
- * {@ValuesListViewTable} specialized to {@link EmployeeKey} values.
+ * {@link ValuesListViewTable} specialized to {@link EmployeeKey} values.
  * <p>
  * TODO The bulk of this should be in a <g:table> in a ui.xml file
  */
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/gwt/ui/report/ReportListView.java b/bikeshed/src/com/google/gwt/sample/expenses/gwt/ui/report/ReportListView.java
index 7dfe967..b1f8d6c 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/gwt/ui/report/ReportListView.java
+++ b/bikeshed/src/com/google/gwt/sample/expenses/gwt/ui/report/ReportListView.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -36,7 +36,7 @@
 import java.util.List;
 
 /**
- * {@ValuesListViewTable} specialized to {@link ReportKey} values.
+ * {@link ValuesListViewTable} specialized to {@link ReportKey} values.
  * <p>
  * TODO The bulk of this should be in a <g:table> in a ui.xml file
  */
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/server/domain/CreationVisitor.java b/bikeshed/src/com/google/gwt/sample/expenses/server/domain/CreationVisitor.java
index 0682211..9f15d15 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/server/domain/CreationVisitor.java
+++ b/bikeshed/src/com/google/gwt/sample/expenses/server/domain/CreationVisitor.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -18,7 +18,7 @@
 /**
  * Creates a new entity of the type of the receiver.
  *
- * @param <E> The type of entity to create.
+ * @param <E> The type of entity to create\
  */
 class CreationVisitor<E extends Entity> implements EntityVisitor<E> {
   private final long id;
diff --git a/bikeshed/src/com/google/gwt/sample/expenses/server/domain/Report.java b/bikeshed/src/com/google/gwt/sample/expenses/server/domain/Report.java
index 1a3dbf1..c7ceedc 100644
--- a/bikeshed/src/com/google/gwt/sample/expenses/server/domain/Report.java
+++ b/bikeshed/src/com/google/gwt/sample/expenses/server/domain/Report.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -24,9 +24,6 @@
 // @javax.persistence.Entity
 public class Report implements Entity {
 
-  /**
-   * @return
-   */
   public static List<Report> findAllReports() {
     return Storage.INSTANCE.findAllReports();
   }
@@ -131,7 +128,7 @@
   public Integer getVersion() {
     return version;
   }
-  
+
   /**
    * @param approvedSupervisor the approved_supervisor to set
    */
@@ -149,7 +146,7 @@
   public void setPurpose(String purpose) {
     this.purpose = purpose;
   }
-  
+
   /**
    * @param reporter the reporter to set
    */
diff --git a/bikeshed/src/com/google/gwt/user/client/ui/HasValue.java b/bikeshed/src/com/google/gwt/user/client/ui/HasValue.java
index e6131de..46eed6c 100644
--- a/bikeshed/src/com/google/gwt/user/client/ui/HasValue.java
+++ b/bikeshed/src/com/google/gwt/user/client/ui/HasValue.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2008 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -19,20 +19,21 @@
 
 /**
  * Extends {@link TakesValue} to allow the value to be pulled back out, and to
- * throw {@ValueChanged} events.
+ * throw {@link com.google.gwt.event.logical.shared.ValueChangeEvent
+ * ValueChangeEvent} events.
  * <p>
  * An object that implements this interface should be a user input widget, where
  * the user and programmer can both set and get the object's value. It is
  * intended to provide a unified interface to widgets with "atomic" values, like
  * Strings and Dates.
- * 
- * @param <T> the type of value.
+ *
+ * @param <T> the type of value
  */
 public interface HasValue<T> extends TakesValue<T>, HasValueChangeHandlers<T> {
 
   /**
    * Gets this object's value.
-   * 
+   *
    * @return the object's value
    */
   T getValue();
@@ -47,7 +48,7 @@
    * By convention, GWT widgets that can be cleared accept null for
    * <code>value</code>, but it is acceptable for widgets that cannot be cleared
    * to throw an exception for null values.
-   * 
+   *
    * @param value the object's new value
    */
   void setValue(T value);
@@ -59,7 +60,7 @@
    * <p>
    * It is acceptable to fail assertions or throw (documented) unchecked
    * exceptions in response to bad values.
-   * 
+   *
    * @param value the object's new value
    * @param fireEvents fire events if true and value is new
    */
diff --git a/bikeshed/src/com/google/gwt/user/client/ui/ValueListBox.java b/bikeshed/src/com/google/gwt/user/client/ui/ValueListBox.java
index ddb0ebf..50a93cf 100644
--- a/bikeshed/src/com/google/gwt/user/client/ui/ValueListBox.java
+++ b/bikeshed/src/com/google/gwt/user/client/ui/ValueListBox.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -27,7 +27,7 @@
 
 /**
  * A {@link HasValue} variation on {@link ListBox}.
- * 
+ *
  * @param <T> the value type
  */
 public class ValueListBox<T> extends Composite implements HasValue<T>,
@@ -55,7 +55,7 @@
 
     return null;
   }
-  
+
   public void setValue(T value) {
     setValue(value, false);
   }
@@ -69,8 +69,9 @@
     Integer index = valueToIndex.get(value);
     if (index == null) {
       listBox.setSelectedIndex(-1);
+    } else {
+      listBox.setSelectedIndex(index);
     }
-    listBox.setSelectedIndex(index);
     if (fireEvents) {
       ValueChangeEvent.fireIfNotEqual(this, oldValue, value);
     }
diff --git a/bikeshed/src/com/google/gwt/valuestore/client/DeltaValueStoreJsonImpl.java b/bikeshed/src/com/google/gwt/valuestore/client/DeltaValueStoreJsonImpl.java
index e4da58b..7764bb8 100644
--- a/bikeshed/src/com/google/gwt/valuestore/client/DeltaValueStoreJsonImpl.java
+++ b/bikeshed/src/com/google/gwt/valuestore/client/DeltaValueStoreJsonImpl.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -40,8 +40,8 @@
   }
 
   public void commit() {
-    // TODO This will drop new verison numbers (and whatever else) returned 
-    // by the server. 
+    // TODO This will drop new verison numbers (and whatever else) returned
+    // by the server.
     for (Map.Entry<RecordKey, ValuesImpl<?>> entry : changes.entrySet()) {
       final RecordKey key = entry.getKey();
       ValuesImpl<?> masterRecord = master.records.get(key);
@@ -102,9 +102,6 @@
     throw new UnsupportedOperationException("Auto-generated method stub");
   }
 
-  /**
-   * @return
-   */
   public String toJson() {
     StringBuffer requestData = new StringBuffer("[");
     boolean first = true;
diff --git a/bikeshed/src/com/google/gwt/valuestore/client/ListModelAdapter.java b/bikeshed/src/com/google/gwt/valuestore/client/ValueStoreListViewAdapter.java
similarity index 79%
rename from bikeshed/src/com/google/gwt/valuestore/client/ListModelAdapter.java
rename to bikeshed/src/com/google/gwt/valuestore/client/ValueStoreListViewAdapter.java
index d52b9a8..a80f90f 100644
--- a/bikeshed/src/com/google/gwt/valuestore/client/ListModelAdapter.java
+++ b/bikeshed/src/com/google/gwt/valuestore/client/ValueStoreListViewAdapter.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -15,7 +15,7 @@
  */
 package com.google.gwt.valuestore.client;
 
-import com.google.gwt.bikeshed.list.shared.AsyncListModel;
+import com.google.gwt.bikeshed.list.shared.AsyncListViewAdapter;
 import com.google.gwt.user.client.ui.TakesValueList;
 import com.google.gwt.valuestore.shared.Values;
 import com.google.gwt.valuestore.shared.ValuesKey;
@@ -24,19 +24,18 @@
 
 /**
  * Simple adapter from a {@link com.google.gwt.valuestore.shared.ValueStore
- * ValueStore} to a {@link com.google.gwt.bikeshed.list.shared.ListModel
- * ListModel}.
+ * ValueStore} to an {@link AsyncListViewAdapter}.
  * <p>
  * TODO: pay attention to the visible range info that subclasses receive via
  * {@link #onRangeChanged}
- * 
+ *
  * @param <K> the ValuesKey of the records to display
  */
-public abstract class ListModelAdapter<K extends ValuesKey<K>> extends
-    AsyncListModel<Values<K>> implements TakesValueList<Values<K>> {
+public abstract class ValueStoreListViewAdapter<K extends ValuesKey<K>> extends
+    AsyncListViewAdapter<Values<K>> implements TakesValueList<Values<K>> {
 
   public void setValueList(List<Values<K>> newValues) {
     updateDataSize(newValues.size(), true);
     updateViewData(0, newValues.size(), newValues);
   }
-}
\ No newline at end of file
+}
diff --git a/bikeshed/src/com/google/gwt/valuestore/client/ValuesImpl.java b/bikeshed/src/com/google/gwt/valuestore/client/ValuesImpl.java
index 12b90c8..09dc6ac 100644
--- a/bikeshed/src/com/google/gwt/valuestore/client/ValuesImpl.java
+++ b/bikeshed/src/com/google/gwt/valuestore/client/ValuesImpl.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -29,7 +29,7 @@
 
 /**
  * JSO implementation of {@link Values}.
- * 
+ *
  * @param <K> value type
  */
 public final class ValuesImpl<K extends ValuesKey<K>> extends JavaScriptObject
@@ -105,8 +105,7 @@
   }
 
   /**
-   * @param property
-   * @return
+   * @param name
    */
   public native boolean isDefined(String name)/*-{
     return this[name] !== undefined;
@@ -145,11 +144,11 @@
     if (value instanceof String) {
       setString(property.getName(), (String) value);
       return;
-    } 
+    }
     if (value instanceof Integer) {
       setInt(property.getName(), (Integer) value);
       return;
-    } 
+    }
     throw new UnsupportedOperationException("Can't yet set properties of type " + value.getClass().getName());
   }
 
@@ -159,7 +158,7 @@
 
   /**
    * Return JSON representation using org.json library.
-   * 
+   *
    * @return returned string.
    */
   public native String toJson() /*-{
diff --git a/bikeshed/src/com/google/gwt/valuestore/client/ValuesListViewTable.java b/bikeshed/src/com/google/gwt/valuestore/client/ValuesListViewTable.java
index 7255d0f..ccda042 100644
--- a/bikeshed/src/com/google/gwt/valuestore/client/ValuesListViewTable.java
+++ b/bikeshed/src/com/google/gwt/valuestore/client/ValuesListViewTable.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -17,8 +17,9 @@
 
 import com.google.gwt.bikeshed.list.client.Column;
 import com.google.gwt.bikeshed.list.client.Header;
+import com.google.gwt.bikeshed.list.client.ListView;
 import com.google.gwt.bikeshed.list.client.PagingTableListView;
-import com.google.gwt.bikeshed.list.shared.ListRegistration;
+import com.google.gwt.bikeshed.list.shared.Range;
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.dom.client.HeadingElement;
 import com.google.gwt.uibinder.client.UiBinder;
@@ -35,8 +36,8 @@
 import java.util.List;
 
 /**
- * A widget that displays lists of {@link com.google.gwt.valuestore.ValueStore
- * ValueStore} records in a {@link PagingTableListView}
+ * A widget that displays lists of {@link com.google.gwt.valuestore.shared.ValueStore
+ * ValueStore} records in a {@link PagingTableListView}.
  *
  * @param <K> the type of the ValuesKey shared by these records
  */
@@ -48,7 +49,7 @@
   private static final Binder BINDER = GWT.create(Binder.class);
 
   public ValuesListView.Delegate delegate;
-  public ListModelAdapter<K> listModel;
+  public ValueStoreListViewAdapter<K> adapter;
 
   @UiField(provided = true)
   PagingTableListView<Values<K>> table;
@@ -57,8 +58,9 @@
 
   public ValuesListViewTable(String headingMessage,
       List<Column<Values<K>, ?, ?>> columns, List<Header<?>> headers) {
-    listModel = createModel();
-    table = new PagingTableListView<Values<K>>(listModel, 100);
+    adapter = createAdapter();
+    table = new PagingTableListView<Values<K>>(adapter, 100);
+    adapter.addView(table);
     final Iterator<Header<?>> nextHeader = headers.iterator();
     for (Column<Values<K>, ?, ?> column : columns) {
       if (nextHeader.hasNext()) {
@@ -86,21 +88,22 @@
   public abstract Collection<Property<K, ?>> getProperties();
 
   /**
-   * @param delegate the new delegate for this view. May be null
+   * @param delegate the new delegate for this view, may be null
    */
   public void setDelegate(ValuesListView.Delegate delegate) {
     this.delegate = delegate;
   }
-  
+
   public void setValueList(List<Values<K>> newValues) {
-    listModel.setValueList(newValues);
+    adapter.setValueList(newValues);
   }
 
-  private ListModelAdapter<K> createModel() {
-    return new ListModelAdapter<K>() {
+  private ValueStoreListViewAdapter<K> createAdapter() {
+    return new ValueStoreListViewAdapter<K>() {
       @Override
-      protected void onRangeChanged(ListRegistration<Values<K>> reg, int start, int length) {
-        getDelegate().onRangeChanged(start, length);
+      protected void onRangeChanged(ListView<Values<K>> view) {
+        Range range = view.getRange();
+        getDelegate().onRangeChanged(range.getStart(), range.getLength());
       }
     };
   }
diff --git a/bikeshed/src/com/google/gwt/valuestore/shared/DeltaValueStore.java b/bikeshed/src/com/google/gwt/valuestore/shared/DeltaValueStore.java
index e8570f2..2022651 100644
--- a/bikeshed/src/com/google/gwt/valuestore/shared/DeltaValueStore.java
+++ b/bikeshed/src/com/google/gwt/valuestore/shared/DeltaValueStore.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -26,8 +26,8 @@
 
   /**
    * Returns true if all validations have passed. May notify subscribers that
-   * implement {@com.google.gwt.user.client.ui.HasErrors} of new validation
-   * errors.
+   * implement {@link com.google.gwt.user.client.ui.HasErrors HasErrors} of new
+   * validation errors.
    */
   boolean validate();
 }
diff --git a/bikeshed/src/com/google/gwt/valuestore/shared/PrimitiveProperty.java b/bikeshed/src/com/google/gwt/valuestore/shared/PrimitiveProperty.java
index e2d7a37..43bd160 100644
--- a/bikeshed/src/com/google/gwt/valuestore/shared/PrimitiveProperty.java
+++ b/bikeshed/src/com/google/gwt/valuestore/shared/PrimitiveProperty.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -18,8 +18,8 @@
 /**
  * Represents a "primitive" property of a record managed by {@link ValueStore}.
  * Primitives include {@link java.lang.Number} and its subclasses,
- * {@link java.lang.String}, {@link java.lang.Date} and enums (tbd).
- * 
+ * {@link java.lang.String}, {@link java.util.Date} and enums (tbd).
+ *
  * @param <K> type of the property holder
  * @param <V> type of the property
  */
diff --git a/bikeshed/src/com/google/gwt/valuestore/shared/Values.java b/bikeshed/src/com/google/gwt/valuestore/shared/Values.java
index 30d2a92..74c0092 100644
--- a/bikeshed/src/com/google/gwt/valuestore/shared/Values.java
+++ b/bikeshed/src/com/google/gwt/valuestore/shared/Values.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -17,8 +17,8 @@
 
 /**
  * Provides access to the property values of a record in a {@link ValueStore}.
- * 
- * @param <K> value type.
+ *
+ * @param <K> value type
  */
 public interface Values<K extends ValuesKey<K>> {
   <V, P extends Property<K, V>> V get(P property);
@@ -27,8 +27,8 @@
 
   K getKey();
 
-  /** 
-   * TODO: Starting to wonder again if this is useful. 
+  /**
+   * TODO: Starting to wonder again if this is useful.
    */
   <V> ValueRef<K, V> getRef(Property<K, V> property);
 }
diff --git a/bikeshed/src/com/google/gwt/valuestore/shared/ValuesKey.java b/bikeshed/src/com/google/gwt/valuestore/shared/ValuesKey.java
index 920442c..1781525 100644
--- a/bikeshed/src/com/google/gwt/valuestore/shared/ValuesKey.java
+++ b/bikeshed/src/com/google/gwt/valuestore/shared/ValuesKey.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -18,9 +18,9 @@
 import java.util.Set;
 
 /**
- * The set of {@link Property properties} for {@ValueStore} records
+ * The set of {@link Property properties} for {@link ValueStore} records
  * of a particular type.
- * 
+ *
  * @param <K> type of this key
  */
 public interface ValuesKey<K extends ValuesKey<K>> {
@@ -35,12 +35,12 @@
    * @return an event to announce changes to the given record
    */
   ValuesChangedEvent<K, ?> createChangeEvent(Values<K> values);
-  
+
   /**
    * @return the id property for records of this type
    */
   Property<K, String> getId();
-  
+
   /**
    * @return the id property for records of this type
    */
diff --git a/bikeshed/src/com/google/gwt/valuestore/shared/ValuesListView.java b/bikeshed/src/com/google/gwt/valuestore/shared/ValuesListView.java
index 8ec5189..2839a6a 100644
--- a/bikeshed/src/com/google/gwt/valuestore/shared/ValuesListView.java
+++ b/bikeshed/src/com/google/gwt/valuestore/shared/ValuesListView.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -23,7 +23,7 @@
 
 /**
  * Implemented by widgets that display lists of records.
- * 
+ *
  * @param <K> the type of the key of the records
  */
 public interface ValuesListView<K extends ValuesKey<K>> extends
@@ -42,7 +42,7 @@
   Collection<Property<K, ?>> getProperties();
 
   /**
-   * @param delegate the new delegate for this view. May be null
+   * @param delegate the new delegate for this view, may be null
    */
   void setDelegate(ValuesListView.Delegate delegate);
 
diff --git a/bikeshed/src/com/google/gwt/valuestore/shared/impl/PrimitivePropertyImpl.java b/bikeshed/src/com/google/gwt/valuestore/shared/impl/PrimitivePropertyImpl.java
index 5567417..5e0579c 100644
--- a/bikeshed/src/com/google/gwt/valuestore/shared/impl/PrimitivePropertyImpl.java
+++ b/bikeshed/src/com/google/gwt/valuestore/shared/impl/PrimitivePropertyImpl.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -19,10 +19,11 @@
 import com.google.gwt.valuestore.shared.ValuesKey;
 
 /**
- * Represents a "primitive" property of a record managed by {@link ValueStore}.
- * Primitives include {@link java.lang.Number} and its subclasses,
- * {@link java.lang.String}, {@link java.lang.Date} and enums (tbd).
- * 
+ * Represents a "primitive" property of a record managed by
+ * {@link com.google.gwt.valuestore.shared.ValueStore}. Primitives include
+ * {@link java.lang.Number} and its subclasses, {@link java.lang.String},
+ * {@link java.util.Date} and enums (tbd).
+ *
  * @param <K> type of the property holder
  * @param <V> type of the property
  */
diff --git a/bikeshed/src/com/google/gwt/valuestore/shared/impl/PropertyImpl.java b/bikeshed/src/com/google/gwt/valuestore/shared/impl/PropertyImpl.java
index 786903c..cdfdcae 100644
--- a/bikeshed/src/com/google/gwt/valuestore/shared/impl/PropertyImpl.java
+++ b/bikeshed/src/com/google/gwt/valuestore/shared/impl/PropertyImpl.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -19,15 +19,15 @@
 import com.google.gwt.valuestore.shared.ValuesKey;
 
 /**
- * Represents a property of a record managed by {@link ValueStore}.
- * 
+ * Represents a property of a record managed by {@link com.google.gwt.valuestore.shared.ValueStore}.
+ *
  * @param <K> type of the property holder
  * @param <V> type of the property
  */
 public class PropertyImpl<K extends ValuesKey<K>, V> implements Property<K, V> {
   private final String name;
 
-  private K key; // Cannot be final due to circular realtionship with ValuesKey 
+  private K key; // Cannot be final due to circular realtionship with ValuesKey
 
   public PropertyImpl(String name) {
     this.name = name;
@@ -43,7 +43,7 @@
   public String getName() {
     return name;
   }
-  
+
   public void setKey(K key) {
     this.key = key;
   }