/*
 * 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.editor.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.editor.client.adapters.EditorSource;
import com.google.gwt.editor.client.adapters.ListEditor;
import com.google.gwt.editor.client.adapters.OptionalFieldEditor;
import com.google.gwt.editor.client.adapters.SimpleEditor;
import com.google.gwt.junit.client.GWTTestCase;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * Uses the SimpleBeanEditorTest to test core Editor behaviors as generated by
 * AbstractEditorDriverGenerator.
 */
public class SimpleBeanEditorTest extends GWTTestCase {
  class AddressCoEditorView extends LeafAddressEditor implements IsEditor<LeafAddressEditor> {
    private LeafAddressEditor addressEditor = new LeafAddressEditor();

    public LeafAddressEditor asEditor() {
      return addressEditor;
    }
  }

  class AddressEditorPartOne implements Editor<Address> {
    SimpleEditor<String> city = SimpleEditor.of(UNINITIALIZED);
  }

  class AddressEditorPartTwo implements Editor<Address> {
    SimpleEditor<String> street = SimpleEditor.of(UNINITIALIZED);
  }

  class AddressEditorView implements IsEditor<LeafAddressEditor> {
    LeafAddressEditor addressEditor = new LeafAddressEditor();

    public LeafAddressEditor asEditor() {
      return addressEditor;
    }
  }

  class LeafAddressEditor extends AddressEditor implements LeafValueEditor<Address> {
    /*
     * These two fields are used to ensure that getValue() and setValue() aren't
     * called excessively.
     */
    int getValueCalled;
    int setValueCalled;
    Address value;

    public Address getValue() {
      getValueCalled++;
      return value;
    }

    public void setValue(Address value) {
      setValueCalled++;
      value = new Address();
    }
  }

  interface ListEditorDriver extends
      SimpleBeanEditorDriver<List<String>, ListEditor<String, SimpleEditor<String>>> {
  }

  class PersonEditorWithAddressEditorView implements Editor<Person> {
    AddressEditorView addressEditor = new AddressEditorView();
    SimpleEditor<String> name = SimpleEditor.of(UNINITIALIZED);
  }

  interface PersonEditorWithAddressEditorViewDriver extends
      SimpleBeanEditorDriver<Person, PersonEditorWithAddressEditorView> {
  }

  /**
   * A test for assigning the object associated with an editor to an immediate
   * child editors.
   */
  class PersonEditorWithAliasedSubEditors implements Editor<Person> {
    @Path("")
    PersonEditor e1 = new PersonEditor();

    @Path("")
    PersonEditor e2 = new PersonEditor();
  }

  interface PersonEditorWithAliasedSubEditorsDriver extends
      SimpleBeanEditorDriver<Person, PersonEditorWithAliasedSubEditors> {
  }

  class PersonEditorWithCoAddressEditorView implements Editor<Person> {
    AddressCoEditorView addressEditor = new AddressCoEditorView();
    SimpleEditor<String> name = SimpleEditor.of(UNINITIALIZED);
  }

  interface PersonEditorWithCoAddressEditorViewDriver extends
      SimpleBeanEditorDriver<Person, PersonEditorWithCoAddressEditorView> {
  }

  static class PersonEditorWithDelegate extends PersonEditor implements HasEditorDelegate<Person> {
    EditorDelegate<Person> delegate;

    public void setDelegate(EditorDelegate<Person> delegate) {
      this.delegate = delegate;
    }
  }

  interface PersonEditorWithDelegateDriver extends
      SimpleBeanEditorDriver<Person, PersonEditorWithDelegate> {
  }

  class PersonEditorWithLeafAddressEditor implements Editor<Person> {
    LeafAddressEditor addressEditor = new LeafAddressEditor();
    SimpleEditor<String> name = SimpleEditor.of(UNINITIALIZED);
    @Path("manager.name")
    SimpleEditor<String> managerName = SimpleEditor.of(UNINITIALIZED);
  }

  interface PersonEditorWithLeafAddressEditorDriver extends
      SimpleBeanEditorDriver<Person, PersonEditorWithLeafAddressEditor> {
  }

  class PersonEditorWithManagerNameWithDelegate implements Editor<Person> {
    @Path("manager.name")
    SimpleEditorWithDelegate<String> managerName = new SimpleEditorWithDelegate<String>(
        UNINITIALIZED);
  }

  interface PersonEditorWithManagerNameWithDelegateDriver extends
      SimpleBeanEditorDriver<Person, PersonEditorWithManagerNameWithDelegate> {
  }

  class PersonEditorWithMultipleBindings implements Editor<Person> {
    @Editor.Path("address")
    AddressEditorPartOne one = new AddressEditorPartOne();

    @Editor.Path("address")
    AddressEditorPartTwo two = new AddressEditorPartTwo();
  }

  interface PersonEditorWithMultipleBindingsDriver extends
      SimpleBeanEditorDriver<Person, PersonEditorWithMultipleBindings> {
  }

  interface PersonEditorWithOptionalAddressDriver extends
      SimpleBeanEditorDriver<Person, PersonEditorWithOptionalAddressEditor> {
  }

  static class PersonEditorWithOptionalAddressEditor implements Editor<Person> {
    OptionalFieldEditor<Address, AddressEditor> address;
    SimpleEditor<String> name = SimpleEditor.of(UNINITIALIZED);

    public PersonEditorWithOptionalAddressEditor(AddressEditor delegate) {
      address = OptionalFieldEditor.of(delegate);
    }
  }

  class PersonEditorWithValueAwareAddressEditor implements Editor<Person> {
    ValueAwareAddressEditor addressEditor = new ValueAwareAddressEditor();
    SimpleEditor<String> name = SimpleEditor.of(UNINITIALIZED);
    @Path("manager.name")
    SimpleEditor<String> managerName = SimpleEditor.of(UNINITIALIZED);
  }

  interface PersonEditorWithValueAwareAddressEditorDriver extends
      SimpleBeanEditorDriver<Person, PersonEditorWithValueAwareAddressEditor> {
  }

  class PersonEditorWithValueAwareLeafAddressEditor implements Editor<Person> {
    ValueAwareLeafAddressEditor addressEditor = new ValueAwareLeafAddressEditor();
    SimpleEditor<String> name = SimpleEditor.of(UNINITIALIZED);
    @Path("manager.name")
    SimpleEditor<String> managerName = SimpleEditor.of(UNINITIALIZED);
  }

  interface PersonEditorWithValueAwareLeafAddressEditorDriver extends
      SimpleBeanEditorDriver<Person, PersonEditorWithValueAwareLeafAddressEditor> {
  }

  class PersonWithList {
    String name = "PersonWithList";
    List<Address> addresses = new ArrayList<Address>();

    public List<Address> getAddresses() {
      return addresses;
    }

    public String getName() {
      return name;
    }
  }

  class PersonWithListEditor implements Editor<PersonWithList> {
    SimpleEditor<String> nameEditor = SimpleEditor.of(UNINITIALIZED);
    ListEditor<Address, AddressEditor> addressesEditor = ListEditor
        .of(new EditorSource<AddressEditor>() {
          @Override
          public AddressEditor create(int index) {
            return new AddressEditor();
          }
        });
  }

  interface PersonWithListEditorDriver extends
      SimpleBeanEditorDriver<PersonWithList, PersonWithListEditor> {
  }

  class SimpleEditorWithDelegate<T> extends SimpleEditor<T> implements HasEditorDelegate<T> {
    EditorDelegate<T> delegate;

    public SimpleEditorWithDelegate(T value) {
      super(value);
    }

    public void setDelegate(EditorDelegate<T> delegate) {
      this.delegate = delegate;
    }
  }

  class ValueAwareAddressEditor extends AddressEditor implements ValueAwareEditor<Address> {
    int flushCalled;
    int setDelegateCalled;
    int setValueCalled;
    Address value;

    public void flush() {
      flushCalled++;
    }

    public void onPropertyChange(String... paths) {
    }

    public void setDelegate(EditorDelegate<Address> delegate) {
      setDelegateCalled++;
    }

    public void setValue(Address value) {
      setValueCalled++;
      this.value = value;
    }
  }

  /**
   * All the mix-ins. Not that this seems like a good idea...
   */
  class ValueAwareLeafAddressEditor extends LeafAddressEditor implements ValueAwareEditor<Address> {
    int flushCalled;
    int setDelegateCalled;

    public void flush() {
      flushCalled++;
    }

    public void onPropertyChange(String... paths) {
    }

    public void setDelegate(EditorDelegate<Address> delegate) {
      setDelegateCalled++;
    }
  }

  Person person;
  Address personAddress;
  Person manager;
  long now;

  static final String UNINITIALIZED = "uninitialized";

  @Override
  public String getModuleName() {
    return "com.google.gwt.editor.Editor";
  }

  public void test() {
    PersonEditorDriver driver = GWT.create(PersonEditorDriver.class);
    PersonEditor editor = new PersonEditor();
    driver.initialize(editor);
    driver.edit(person);
    assertEquals(now, editor.localTime.getValue().longValue());
    assertEquals("Alice", editor.name.getValue());
    assertEquals("City", editor.addressEditor.city.getValue());
    assertEquals("Street", editor.addressEditor.street.getValue());
    assertEquals("Bill", editor.managerName.getValue());

    editor.localTime.setValue(now + 1);
    editor.name.setValue("Charles");
    editor.addressEditor.city.setValue("Wootville");
    editor.addressEditor.street.setValue("12345");
    editor.managerName.setValue("David");

    driver.flush();
    assertEquals(now + 1, person.localTime);
    assertEquals("Charles", person.name);
    assertEquals("Wootville", person.address.city);
    assertEquals("12345", person.address.street);
    assertEquals("David", person.manager.name);
  }

  public void testAliasedEditors() {
    PersonEditorWithAliasedSubEditors editor = new PersonEditorWithAliasedSubEditors();
    PersonEditorWithAliasedSubEditorsDriver driver =
        GWT.create(PersonEditorWithAliasedSubEditorsDriver.class);
    driver.initialize(editor);
    driver.edit(person);

    assertEquals("Alice", editor.e1.name.getValue());
    assertEquals("Alice", editor.e2.name.getValue());

    /*
     * Expecting that aliased editors will be editing disjoint sets of
     * properties, but we want to at least have a predictable behavior if two
     * editors are assigned to the same property.
     */
    editor.e1.name.setValue("Should not see this");
    driver.flush();
    assertEquals("Alice", person.getName());

    editor.e2.name.setValue("Should see this");
    driver.flush();
    assertEquals("Should see this", person.getName());
  }

  public void testDelegatePath() {
    PersonEditorWithManagerNameWithDelegate editor = new PersonEditorWithManagerNameWithDelegate();
    PersonEditorWithManagerNameWithDelegateDriver driver =
        GWT.create(PersonEditorWithManagerNameWithDelegateDriver.class);
    driver.initialize(editor);
    driver.edit(person);

    assertEquals("manager.name", editor.managerName.delegate.getPath());
  }

  public void testEditorWithNullSubEditor() {
    PersonEditor editor = new PersonEditor();
    editor.addressEditor = null;
    PersonEditorDriver driver = GWT.create(PersonEditorDriver.class);
    driver.initialize(editor);
    driver.edit(person);

    assertEquals("Alice", editor.name.getValue());
    editor.name.setValue("New name");
    driver.flush();
    assertEquals("New name", person.getName());

    /*
     * Verify that changing the editor structure without re-initializing is a
     * no-op.
     */
    editor.name.setValue("Should see this");
    editor.addressEditor = new AddressEditor();
    editor.addressEditor.city.setValue("Should not see this");
    driver.flush();
    assertEquals("Should see this", person.getName());
    assertEquals("City", person.getAddress().getCity());

    // Re-initialize and check that flushing works again
    driver.initialize(editor);
    driver.edit(person);
    editor.addressEditor.city.setValue("Should see this");
    driver.flush();
    assertEquals("Should see this", person.getAddress().getCity());
  }

  /**
   * Test the use of the IsEditor interface that allows a view object to
   * encapsulate its Editor.
   */
  public void testIsEditorView() {
    PersonEditorWithAddressEditorView personEditor = new PersonEditorWithAddressEditorView();
    PersonEditorWithAddressEditorViewDriver driver =
        GWT.create(PersonEditorWithAddressEditorViewDriver.class);
    testLeafAddressEditor(driver, personEditor, personEditor.addressEditor.asEditor(), true);
  }

  /**
   * Test the use of the IsEditor interface that allows a view object to
   * encapsulate its Editor as well as be an editor itself.
   */
  public void testIsEditorViewWithCoEditorA() {
    PersonEditorWithCoAddressEditorView personEditor = new PersonEditorWithCoAddressEditorView();
    PersonEditorWithCoAddressEditorViewDriver driver =
        GWT.create(PersonEditorWithCoAddressEditorViewDriver.class);
    testLeafAddressEditor(driver, personEditor, personEditor.addressEditor, true);
  }

  /**
   * Test the use of the IsEditor interface that allows a view object to
   * encapsulate its Editor as well as be an editor itself.
   */
  public void testIsEditorViewWithCoEditorB() {
    PersonEditorWithCoAddressEditorView personEditor = new PersonEditorWithCoAddressEditorView();
    PersonEditorWithCoAddressEditorViewDriver driver =
        GWT.create(PersonEditorWithCoAddressEditorViewDriver.class);
    testLeafAddressEditor(driver, personEditor, personEditor.addressEditor.asEditor(), true);
  }

  /**
   * We want to verify that the sub-editors of a LeafValueEditor are not
   * initialized. Additonally, we want to ensure that the instance returned from
   * the LVE is assigned into the owner type.
   */
  public void testLeafValueEditorDeclaredInSlot() {
    PersonEditorWithLeafAddressEditor personEditor = new PersonEditorWithLeafAddressEditor();
    PersonEditorWithLeafAddressEditorDriver driver =
        GWT.create(PersonEditorWithLeafAddressEditorDriver.class);
    LeafAddressEditor addressEditor = personEditor.addressEditor;

    testLeafAddressEditor(driver, personEditor, addressEditor, true);
  }

  /**
   * This tests a weird case where the user has put a LeafValueEditor into a
   * plain Editor field. Because the Editor system relies heavily on static type
   * information at compile time, this is not a supported configuration.
   */
  public void testLeafValueEditorInPlainEditorSlot() {
    PersonEditorDriver driver = GWT.create(PersonEditorDriver.class);

    PersonEditor personEditor = new PersonEditor();
    LeafAddressEditor addressEditor = new LeafAddressEditor();

    // Runtime assignment of unexpected LeafValueEditor
    personEditor.addressEditor = addressEditor;

    testLeafAddressEditor(driver, personEditor, addressEditor, true);
  }

  public void testLifecycle() {
    PersonEditorDriver driver = GWT.create(PersonEditorDriver.class);
    try {
      driver.edit(person);
      fail("Should have thrown execption");
    } catch (IllegalStateException expected) {
    }
    driver.initialize(new PersonEditor());
    try {
      driver.flush();
      fail("Should have thrown exception");
    } catch (IllegalStateException expected) {
    }
    driver.edit(person);
    driver.flush();
  }

  /**
   * Test a top-level ListEditor.
   */
  public void testListEditor() {
    final SortedMap<Integer, SimpleEditor<String>> positionMap =
        new TreeMap<Integer, SimpleEditor<String>>();
    @SuppressWarnings("unchecked")
    final SimpleEditor<String>[] disposed = new SimpleEditor[1];
    class StringSource extends EditorSource<SimpleEditor<String>> {
      public SimpleEditor<String> create(int index) {
        SimpleEditor<String> editor = SimpleEditor.of();
        positionMap.put(index, editor);
        return editor;
      }

      public void dispose(SimpleEditor<String> editor) {
        disposed[0] = editor;
        positionMap.values().remove(editor);
      }

      public void setIndex(SimpleEditor<String> editor, int index) {
        positionMap.values().remove(editor);
        positionMap.put(index, editor);
      }
    };

    ListEditorDriver driver = GWT.create(ListEditorDriver.class);
    ListEditor<String, SimpleEditor<String>> editor = ListEditor.of(new StringSource());

    driver.initialize(editor);

    List<String> rawData = new ArrayList<String>(Arrays.asList("foo", "bar", "baz"));
    driver.edit(rawData);

    List<SimpleEditor<String>> editors = editor.getEditors();
    assertEquals(rawData.size(), editors.size());
    assertEquals(rawData, Arrays.asList(editors.get(0).getValue(), editors.get(1).getValue(),
        editors.get(2).getValue()));
    assertEquals(editors, new ArrayList<SimpleEditor<String>>(positionMap.values()));

    List<String> mutableList = editor.getList();
    assertEquals(rawData, mutableList);

    // Test through wrapped list
    mutableList.set(1, "Hello");
    assertEquals("Hello", editors.get(1).getValue());

    // Test using editor
    editors.get(2).setValue("World");
    assertEquals("baz", rawData.get(2));
    driver.flush();
    assertEquals("World", rawData.get(2));

    // Change list size
    mutableList.add("quux");
    assertEquals(4, editors.size());
    assertEquals("quux", editors.get(3).getValue());
    assertEquals(editors, new ArrayList<SimpleEditor<String>>(positionMap.values()));

    // Delete an element
    SimpleEditor<String> expectedDisposed = editors.get(0);
    mutableList.remove(0);
    assertSame(expectedDisposed, disposed[0]);
    assertEquals(3, editors.size());
    assertEquals("quux", editors.get(2).getValue());
    assertEquals(editors, new ArrayList<SimpleEditor<String>>(positionMap.values()));
  }

  /**
   * Ensure that a ListEditor deeper in the chain is properly flushed.
   */
  public void testListEditorChainFlush() {
    PersonWithListEditorDriver driver = GWT.create(PersonWithListEditorDriver.class);
    PersonWithList person = new PersonWithList();
    Address a1 = new Address();
    a1.city = "a1City";
    a1.street = "a1Street";
    Address a2 = new Address();
    a2.city = "a2City";
    a2.street = "a2Street";

    person.addresses.add(a1);
    person.addresses.add(a2);

    PersonWithListEditor personEditor = new PersonWithListEditor();
    // Initialize
    driver.initialize(personEditor);
    try {
      personEditor.addressesEditor.getEditors();
      // Address editors aren't created until edit() is called
      fail();
    } catch (IllegalStateException expected) {
    }

    // Edit
    driver.edit(person);
    AddressEditor addressEditor = personEditor.addressesEditor.getEditors().get(1);
    assertEquals("a2City", addressEditor.city.getValue());
    addressEditor.city.setValue("edited");

    // Flush
    driver.flush();
    assertEquals("edited", person.addresses.get(1).getCity());
  }

  public void testMultipleBinding() {
    PersonEditorWithMultipleBindingsDriver driver =
        GWT.create(PersonEditorWithMultipleBindingsDriver.class);
    PersonEditorWithMultipleBindings editor = new PersonEditorWithMultipleBindings();

    driver.initialize(editor);
    driver.edit(person);
    assertEquals("City", editor.one.city.getValue());
    assertEquals("Street", editor.two.street.getValue());

    editor.one.city.setValue("Foo");
    editor.two.street.setValue("Bar");
    driver.flush();

    assertEquals("Foo", person.getAddress().getCity());
    assertEquals("Bar", person.getAddress().getStreet());
  }

  public void testOptionalField() {
    PersonEditorWithOptionalAddressDriver driver =
        GWT.create(PersonEditorWithOptionalAddressDriver.class);
    person.address = null;

    AddressEditor delegate = new AddressEditor();
    PersonEditorWithOptionalAddressEditor editor =
        new PersonEditorWithOptionalAddressEditor(delegate);
    driver.initialize(editor);

    // Make sure we don't blow up with the null field
    driver.edit(person);
    editor.address.setValue(personAddress);
    assertEquals("City", delegate.city.getValue());
    delegate.city.setValue("Hello");
    driver.flush();
    assertNotNull(person.address);
    assertSame(personAddress, person.address);
    assertEquals("Hello", personAddress.city);

    editor.address.setValue(null);
    driver.flush();
    assertNull(person.address);
  }

  public void testValueAwareEditorInDeclaredSlot() {
    PersonEditorWithValueAwareAddressEditorDriver driver =
        GWT.create(PersonEditorWithValueAwareAddressEditorDriver.class);
    PersonEditorWithValueAwareAddressEditor personEditor =
        new PersonEditorWithValueAwareAddressEditor();
    ValueAwareAddressEditor addressEditor = personEditor.addressEditor;

    testValueAwareAddressEditor(driver, personEditor, addressEditor);
  }

  /**
   * This is another instance of a LeafValueEditor found in a plain slot.
   */
  public void testValueAwareEditorInPlainSlot() {
    PersonEditorDriver driver = GWT.create(PersonEditorDriver.class);

    PersonEditor personEditor = new PersonEditor();
    ValueAwareAddressEditor addressEditor = new ValueAwareAddressEditor();

    // Runtime assignment of unexpected LeafValueEditor
    personEditor.addressEditor = addressEditor;

    testValueAwareAddressEditor(driver, personEditor, addressEditor);
  }

  public void testValueAwareLeafValueEditorInDeclaredSlot() {
    PersonEditorWithValueAwareLeafAddressEditor personEditor =
        new PersonEditorWithValueAwareLeafAddressEditor();
    PersonEditorWithValueAwareLeafAddressEditorDriver driver =
        GWT.create(PersonEditorWithValueAwareLeafAddressEditorDriver.class);
    ValueAwareLeafAddressEditor addressEditor = personEditor.addressEditor;

    testLeafAddressEditor(driver, personEditor, addressEditor, true);
    assertEquals(1, addressEditor.flushCalled);
    assertEquals(1, addressEditor.setDelegateCalled);
  }

  public void testValueAwareLeafValueEditorInPlainEditorSlot() {
    PersonEditorDriver driver = GWT.create(PersonEditorDriver.class);

    PersonEditor personEditor = new PersonEditor();
    ValueAwareLeafAddressEditor addressEditor = new ValueAwareLeafAddressEditor();

    // Runtime assignment of unexpected LeafValueEditor
    personEditor.addressEditor = addressEditor;

    testLeafAddressEditor(driver, personEditor, addressEditor, true);
    assertEquals(1, addressEditor.flushCalled);
    assertEquals(1, addressEditor.setDelegateCalled);
  }

  @Override
  protected void gwtSetUp() throws Exception {
    personAddress = new Address();
    personAddress.city = "City";
    personAddress.street = "Street";

    manager = new Person();
    manager.name = "Bill";

    person = new Person();
    person.address = personAddress;
    person.name = "Alice";
    person.manager = manager;
    person.localTime = now = System.currentTimeMillis();
  }

  private <T extends Editor<Person>> void testLeafAddressEditor(
      SimpleBeanEditorDriver<Person, T> driver, T personEditor, LeafAddressEditor addressEditor,
      boolean declaredAsLeaf) {
    Address oldAddress = person.address;
    // Initialize
    driver.initialize(personEditor);
    assertEquals(0, addressEditor.setValueCalled);
    assertEquals(0, addressEditor.getValueCalled);

    // Edit
    driver.edit(person);
    assertEquals(1, addressEditor.setValueCalled);
    // The DirtCollector will interrogate the leaf editors
    assertEquals(1, addressEditor.getValueCalled);

    // Flush
    driver.flush();
    assertEquals(1, addressEditor.setValueCalled);
    assertEquals(2, addressEditor.getValueCalled);
    assertNotSame(oldAddress, person.address);
    assertSame(person.address, addressEditor.value);
  }

  private <T extends Editor<Person>> void testValueAwareAddressEditor(
      SimpleBeanEditorDriver<Person, T> driver, T personEditor,
      ValueAwareAddressEditor addressEditor) {
    Address oldAddress = person.address;
    // Initialize
    driver.initialize(personEditor);
    assertEquals(0, addressEditor.setValueCalled);
    assertEquals(0, addressEditor.setDelegateCalled);
    assertEquals(0, addressEditor.flushCalled);

    // Edit
    driver.edit(person);
    assertEquals(1, addressEditor.setValueCalled);
    assertEquals(1, addressEditor.setDelegateCalled);
    assertEquals(0, addressEditor.flushCalled);
    assertEquals("City", addressEditor.city.getValue());

    // Flush
    driver.flush();
    assertEquals(1, addressEditor.setValueCalled);
    assertEquals(1, addressEditor.setDelegateCalled);
    assertEquals(1, addressEditor.flushCalled);
    assertSame(oldAddress, person.address);
    assertSame(person.address, addressEditor.value);
  }
}
