@Test
 public void testAddItemAfterPerformance() {
   Object initialId = "Item0";
   Collection<Long> times = new ArrayList<Long>();
   for (int j = 0; j < REPEATS; ++j) {
     IndexedContainer c = new IndexedContainer();
     c.addItem(initialId);
     long start = System.currentTimeMillis();
     for (int i = 0; i < ITEMS; i++) {
       c.addItemAfter(initialId);
     }
     times.add(System.currentTimeMillis() - start);
   }
   checkMedian(ITEMS, times, "IndexedContainer.addItemAfter()", ADD_ITEM_AFTER_FAIL_THRESHOLD);
 }
  @Test
  public void testItemAdd_idSequence() {
    IndexedContainer container = new IndexedContainer();
    Object itemId;

    itemId = container.addItem();
    assertEquals(Integer.valueOf(1), itemId);

    itemId = container.addItem();
    assertEquals(Integer.valueOf(2), itemId);

    itemId = container.addItemAfter(null);
    assertEquals(Integer.valueOf(3), itemId);

    itemId = container.addItemAt(2);
    assertEquals(Integer.valueOf(4), itemId);
  }
 @Test
 public void testAddItemAfterLastPerformance() {
   // TODO running with less items because slow otherwise
   Collection<Long> times = new ArrayList<Long>();
   for (int j = 0; j < REPEATS; ++j) {
     IndexedContainer c = new IndexedContainer();
     c.addItem();
     long start = System.currentTimeMillis();
     for (int i = 0; i < ITEMS / 3; i++) {
       c.addItemAfter(c.lastItemId());
     }
     times.add(System.currentTimeMillis() - start);
   }
   checkMedian(
       ITEMS / 3,
       times,
       "IndexedContainer.addItemAfter(lastId)",
       ADD_ITEM_AFTER_LAST_FAIL_THRESHOLD);
 }
  @Test
  public void testItemSetChangeListeners() {
    IndexedContainer container = new IndexedContainer();
    ItemSetChangeCounter counter = new ItemSetChangeCounter();
    container.addListener(counter);

    String id1 = "id1";
    String id2 = "id2";
    String id3 = "id3";

    initializeContainer(container);
    counter.reset();
    container.addItem();
    counter.assertOnce();
    container.addItem(id1);
    counter.assertOnce();

    initializeContainer(container);
    counter.reset();
    container.addItemAt(0);
    counter.assertOnce();
    container.addItemAt(0, id1);
    counter.assertOnce();
    container.addItemAt(0, id2);
    counter.assertOnce();
    container.addItemAt(container.size(), id3);
    counter.assertOnce();
    // no notification if already in container
    container.addItemAt(0, id1);
    counter.assertNone();

    initializeContainer(container);
    counter.reset();
    container.addItemAfter(null);
    counter.assertOnce();
    container.addItemAfter(null, id1);
    counter.assertOnce();
    container.addItemAfter(id1);
    counter.assertOnce();
    container.addItemAfter(id1, id2);
    counter.assertOnce();
    container.addItemAfter(container.firstItemId());
    counter.assertOnce();
    container.addItemAfter(container.lastItemId());
    counter.assertOnce();
    container.addItemAfter(container.lastItemId(), id3);
    counter.assertOnce();
    // no notification if already in container
    container.addItemAfter(0, id1);
    counter.assertNone();

    initializeContainer(container);
    counter.reset();
    container.removeItem(sampleData[0]);
    counter.assertOnce();

    initializeContainer(container);
    counter.reset();
    // no notification for removing a non-existing item
    container.removeItem(id1);
    counter.assertNone();

    initializeContainer(container);
    counter.reset();
    container.removeAllItems();
    counter.assertOnce();
    // already empty
    container.removeAllItems();
    counter.assertNone();
  }
  // TODO other tests should check positions after removing filter etc,
  // here concentrating on listeners
  @Test
  public void testItemSetChangeListenersFiltering() {
    IndexedContainer container = new IndexedContainer();
    ItemSetChangeCounter counter = new ItemSetChangeCounter();
    container.addListener(counter);

    counter.reset();
    container.addContainerFilter(FULLY_QUALIFIED_NAME, "Test", true, false);
    // no real change, so no notification required
    counter.assertNone();

    String id1 = "com.example.Test1";
    String id2 = "com.example.Test2";
    String id3 = "com.example.Other";

    // perform operations while filtering container

    Item item;

    initializeContainer(container);
    counter.reset();
    // passes filter
    item = container.addItem(id1);
    // no event if filtered out
    counter.assertNone();
    item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id1);
    counter.assertOnce();
    // passes filter but already in the container
    item = container.addItem(id1);
    counter.assertNone();

    initializeContainer(container);
    counter.reset();
    // passes filter after change
    item = container.addItemAt(0, id1);
    counter.assertNone();
    item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id1);
    counter.assertOnce();
    item = container.addItemAt(container.size(), id2);
    counter.assertNone();
    item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id2);
    counter.assertOnce();
    // passes filter but already in the container
    item = container.addItemAt(0, id1);
    counter.assertNone();
    item = container.addItemAt(container.size(), id2);
    counter.assertNone();

    initializeContainer(container);
    counter.reset();
    // passes filter
    item = container.addItemAfter(null, id1);
    counter.assertNone();
    item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id1);
    counter.assertOnce();
    item = container.addItemAfter(container.lastItemId(), id2);
    counter.assertNone();
    item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id2);
    counter.assertOnce();
    // passes filter but already in the container
    item = container.addItemAfter(null, id1);
    counter.assertNone();
    item = container.addItemAfter(container.lastItemId(), id2);
    counter.assertNone();

    // does not pass filter

    // TODO implement rest

    initializeContainer(container);
    counter.reset();
    item = container.addItemAfter(null, id3);
    counter.assertNone();
    item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id3);
    counter.assertNone();

    initializeContainer(container);
    counter.reset();
    item = container.addItemAfter(container.firstItemId(), id3);
    counter.assertNone();
    item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id3);
    counter.assertNone();

    initializeContainer(container);
    counter.reset();
    item = container.addItemAfter(container.lastItemId(), id3);
    counter.assertNone();
    item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id3);
    counter.assertNone();

    initializeContainer(container);
    counter.reset();
    item = container.addItemAt(0, id3);
    counter.assertNone();
    item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id3);
    counter.assertNone();

    initializeContainer(container);
    counter.reset();
    item = container.addItemAt(1, id3);
    counter.assertNone();
    item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id3);
    counter.assertNone();

    initializeContainer(container);
    counter.reset();
    item = container.addItemAt(container.size(), id3);
    counter.assertNone();
    item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id3);
    counter.assertNone();

    // passes filter

    initializeContainer(container);
    counter.reset();
    item = container.addItem(id1);
    counter.assertNone();
    item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id1);
    counter.assertOnce();
    container.removeItem(id1);
    counter.assertOnce();
    // already removed
    container.removeItem(id1);
    counter.assertNone();

    item = container.addItem(id3);
    counter.assertNone();
    item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id3);
    counter.assertNone();
    // not visible
    container.removeItem(id3);
    counter.assertNone();

    // remove all

    initializeContainer(container);
    item = container.addItem(id1);
    item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(id1);
    counter.reset();
    container.removeAllItems();
    counter.assertOnce();
    // no visible items
    container.removeAllItems();
    counter.assertNone();
  }