Make ListEditorWrapper update its backing on flush().
Fixes Issue 5500.

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


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9305 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/editor/client/adapters/ListEditorWrapper.java b/user/src/com/google/gwt/editor/client/adapters/ListEditorWrapper.java
index 18820db..b028a79 100644
--- a/user/src/com/google/gwt/editor/client/adapters/ListEditorWrapper.java
+++ b/user/src/com/google/gwt/editor/client/adapters/ListEditorWrapper.java
@@ -33,6 +33,7 @@
   private final CompositeEditor.EditorChain<T, E> chain;
   private final List<E> editors;
   private final EditorSource<E> editorSource;
+  private final List<T> workingCopy;
 
   public ListEditorWrapper(List<T> backing,
       CompositeEditor.EditorChain<T, E> chain, EditorSource<E> editorSource) {
@@ -40,11 +41,12 @@
     this.chain = chain;
     this.editorSource = editorSource;
     editors = new ArrayList<E>(backing.size());
+    workingCopy = new ArrayList<T>(backing);
   }
 
   @Override
   public void add(int index, T element) {
-    backing.add(index, element);
+    workingCopy.add(index, element);
     E subEditor = editorSource.create(index);
     editors.add(index, subEditor);
     for (int i = index + 1, j = editors.size(); i < j; i++) {
@@ -55,13 +57,12 @@
 
   @Override
   public T get(int index) {
-    return backing.get(index);
+    return workingCopy.get(index);
   }
 
   @Override
   public T remove(int index) {
-    // Try to mutate the list first, in case it is immutable
-    T toReturn = backing.remove(index);
+    T toReturn = workingCopy.remove(index);
     E subEditor = editors.remove(index);
     editorSource.dispose(subEditor);
     for (int i = index, j = editors.size(); i < j; i++) {
@@ -73,15 +74,14 @@
 
   @Override
   public T set(int index, T element) {
-    // Try to mutate the list first, in case it is immutable
-    T toReturn = backing.set(index, element);
+    T toReturn = workingCopy.set(index, element);
     chain.attach(element, editors.get(index));
     return toReturn;
   }
 
   @Override
   public int size() {
-    return backing.size();
+    return workingCopy.size();
   }
 
   /**
@@ -90,9 +90,9 @@
    * {@link ListEditor#getList()}
    */
   void attach() {
-    editors.addAll(editorSource.create(backing.size(), 0));
-    for (int i = 0, j = backing.size(); i < j; i++) {
-      chain.attach(backing.get(i), editors.get(i));
+    editors.addAll(editorSource.create(workingCopy.size(), 0));
+    for (int i = 0, j = workingCopy.size(); i < j; i++) {
+      chain.attach(workingCopy.get(i), editors.get(i));
     }
   }
 
@@ -104,14 +104,16 @@
   }
 
   void flush() {
-    for (int i = 0, j = backing.size(); i < j; i++) {
+    for (int i = 0, j = workingCopy.size(); i < j; i++) {
       E subEditor = editors.get(i);
       T value = chain.getValue(subEditor);
       // Use of object-identity intentional
-      if (backing.get(i) != value) {
-        backing.set(i, value);
+      if (workingCopy.get(i) != value) {
+        workingCopy.set(i, value);
       }
     }
+    backing.clear();
+    backing.addAll(workingCopy);
   }
 
   /**
diff --git a/user/test/com/google/gwt/editor/client/adapters/ListEditorWrapperTest.java b/user/test/com/google/gwt/editor/client/adapters/ListEditorWrapperTest.java
index b787449..8c8c2a1 100644
--- a/user/test/com/google/gwt/editor/client/adapters/ListEditorWrapperTest.java
+++ b/user/test/com/google/gwt/editor/client/adapters/ListEditorWrapperTest.java
@@ -44,6 +44,9 @@
 
     Object o1 = new Object();
     wrapper.add(o1);
+    assertEquals(0, backing.size());
+    wrapper.flush();
+    assertEquals(1, backing.size());
     assertSame(o1, backing.get(0));
     FakeLeafValueEditor<Object> editor1 = wrapper.getEditors().get(0);
     assertSame(o1, editor1.getValue());
@@ -52,6 +55,9 @@
 
     Object o0 = new Object();
     wrapper.add(0, o0);
+    assertEquals(1, backing.size());
+    wrapper.flush();
+    assertEquals(2, backing.size());
     assertSame(o0, backing.get(0));
     assertSame(o1, backing.get(1));
     FakeLeafValueEditor<Object> editor0 = wrapper.getEditors().get(0);
@@ -112,6 +118,9 @@
     assertSame(o2, e2.getValue());
 
     wrapper.remove(1);
+    assertEquals(Arrays.asList(o0, o1, o2), backing);
+    assertEquals(Arrays.asList(e0, e2), wrapper.getEditors());
+    wrapper.flush();
     assertEquals(Arrays.asList(o0, o2), backing);
     assertEquals(Arrays.asList(e0, e2), wrapper.getEditors());
     assertFalse(chain.isAttached(e1));
@@ -119,6 +128,8 @@
     assertEquals(1, source.getLastKnownPosition(e2));
 
     wrapper.set(1, o1);
+    assertEquals(Arrays.asList(o0, o2), backing);
+    wrapper.flush();
     assertEquals(Arrays.asList(o0, o1), backing);
     // Re-use existing editor
     assertEquals(Arrays.asList(e0, e2), wrapper.getEditors());