@TestTargets({
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        method = "deactivate",
        args = {}),
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        method = "setWindow",
        args = {android.database.CursorWindow.class}),
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        method = "registerDataSetObserver",
        args = {android.database.DataSetObserver.class})
  })
  public void testRegisterDataSetObserver() {
    SQLiteCursor cursor = getCursor();
    MockCursorWindow cursorWindow = new MockCursorWindow(false);

    MockObserver observer = new MockObserver();

    cursor.setWindow(cursorWindow);
    // Before registering, observer can't be notified.
    assertFalse(observer.hasInvalidated());
    cursor.moveToLast();
    assertFalse(cursorWindow.isClosed());
    cursor.deactivate();
    assertFalse(observer.hasInvalidated());
    // deactivate() will close the CursorWindow
    assertTrue(cursorWindow.isClosed());

    // test registering DataSetObserver
    assertTrue(cursor.requery());
    cursor.registerDataSetObserver(observer);
    assertFalse(observer.hasInvalidated());
    cursor.moveToLast();
    assertEquals(TEST_COUNT, cursor.getInt(1));
    cursor.deactivate();
    // deactivate method can invoke invalidate() method, can be observed by DataSetObserver.
    assertTrue(observer.hasInvalidated());

    try {
      cursor.getInt(1);
      fail("After deactivating, cursor cannot execute getting value operations.");
    } catch (StaleDataException e) {
    }

    assertTrue(cursor.requery());
    cursor.moveToLast();
    assertEquals(TEST_COUNT, cursor.getInt(1));

    // can't register a same observer twice.
    try {
      cursor.registerDataSetObserver(observer);
      fail("didn't throw IllegalStateException when register existed observer");
    } catch (IllegalStateException e) {
    }

    // after unregistering, observer can't be notified.
    cursor.unregisterDataSetObserver(observer);
    observer.resetStatus();
    assertFalse(observer.hasInvalidated());
    cursor.deactivate();
    assertFalse(observer.hasInvalidated());
  }