public void testSingleGetOperationCloning() {
    GetOperation.Callback callback =
        (GetOperation.Callback) mock(GetOperation.Callback.class).proxy();
    GetOperation op = ofact.get(TEST_KEY, callback);

    GetOperation op2 = cloneOne(GetOperation.class, op);
    assertKey(op2);
    assertSame(callback, op.getCallback());
  }
  // These are harder cases as they fan out.
  public void testMultipleGetOperationCloning() {
    Collection<String> keys = Arrays.asList("k1", "k2", "k3");
    GetOperation.Callback callback =
        (GetOperation.Callback) mock(GetOperation.Callback.class).proxy();
    GetOperation op = ofact.get(keys, callback);

    Collection<Operation> ops = ofact.clone(op);
    assertEquals(3, ops.size());

    Collection<String> mutableKeys = new ArrayList<String>(keys);
    int i = 3;
    for (Operation o : ops) {
      assertEquals(i, mutableKeys.size()); // Starting size
      GetOperation go = (GetOperation) o;
      mutableKeys.removeAll(go.getKeys());
      // Verify we matched and removed 1
      assertEquals(--i, mutableKeys.size());
    }
  }
  public void testMultipleGetOperationFanout() {
    Collection<String> keys = Arrays.asList("k1", "k2", "k3");
    Mock m = mock(GetOperation.Callback.class);
    OperationStatus st = new OperationStatus(true, "blah");
    m.expects(once()).method("complete");
    m.expects(once()).method("receivedStatus").with(same(st));
    m.expects(once()).method("gotData").with(eq("k1"), eq(1), isA(byte[].class));
    m.expects(once()).method("gotData").with(eq("k2"), eq(2), isA(byte[].class));
    m.expects(once()).method("gotData").with(eq("k3"), eq(3), isA(byte[].class));

    GetOperation.Callback callback = (GetOperation.Callback) m.proxy();
    GetOperation op = ofact.get(keys, callback);

    // Transition each operation callback into the complete state.
    Iterator<String> ki = keys.iterator();
    int i = 0;
    for (Operation o : ofact.clone(op)) {
      GetOperation.Callback cb = (GetOperation.Callback) o.getCallback();
      cb.gotData(ki.next(), ++i, new byte[3]);
      cb.receivedStatus(st);
      cb.complete();
    }
  }