private ObjectUsage createUsage(String typeName, String methodName) {

    DefinitionSite def = DefinitionSites.createDefinitionByConstant();
    def.setType(VmTypeName.get(typeName));

    EnclosingMethodContext ctx = new EnclosingMethodContext();
    ctx.setSuperclass(VmTypeName.get("LSuperType"));
    ctx.setName(VmMethodName.get(methodName));
    ctx.setIntroducedBy(VmTypeName.get("LSuperType"));

    CallSite call = new CallSite();
    call.setKind(CallSiteKind.RECEIVER_CALL_SITE);
    call.setCall(VmMethodName.get(methodName));

    List<CallSite> path = Lists.newLinkedList();
    path.add(call);

    Set<List<CallSite>> paths = newHashSet();
    paths.add(path);

    ObjectUsage usage = new ObjectUsage();
    usage.setUuid(UUID.randomUUID());
    usage.setDef(def);
    usage.setContext(ctx);
    usage.setPaths(paths);
    return usage;
  }
  @Test
  public void allTypesAreRememberedAsKeys() {
    ObjectUsage usage1 = createUsage(TYPE1, "LContext.m1()V");
    ObjectUsage usage2 = createUsage(TYPE2, "LContext.m2()V");

    sut.store(newArrayList(usage1));
    sut.store(newArrayList(usage2));
    sut.close();

    sut = createSUT(directory);
    Set<ITypeName> actual = sut.getKeys();
    Set<ITypeName> expected = newHashSet();
    expected.add(VmTypeName.get(TYPE1));
    expected.add(VmTypeName.get(TYPE2));
    assertEquals(expected, actual);
  }
  @Test(expected = IllegalStateException.class)
  public void ioExceptionsCauseAnotherKindOfException() throws IOException {
    ObjectUsage usage1 = createUsage(TYPE1, "LContext.m1()V");
    Directory dir = mock(Directory.class);
    doThrow(new ZipException()).when(dir).getReadingArchive(anyString());
    WritingArchive archive = mock(WritingArchive.class);
    when(dir.getWritingArchive(anyString())).thenReturn(archive);
    when(dir.reopenWritingArchive(anyString(), any(Type.class))).thenReturn(archive);
    when(dir.read(any(String.class), any(Type.class)))
        .thenReturn(newHashSet(VmTypeName.get(TYPE1)));

    sut = createSUT(dir);
    sut.store(newArrayList(usage1));
    sut.close();

    sut.read(VmTypeName.get(TYPE1));
  }
  @Test
  public void allUsagesAreStoredForAKey() {
    ObjectUsage usage1 = createUsage(TYPE1, "LContext.m1()V");
    ObjectUsage usage2 = createUsage(TYPE1, "LContext.m3()V");

    sut.store(newArrayList(usage1, usage2));
    sut.close();

    sut = createSUT(directory);
    List<ObjectUsage> actual = sut.read(VmTypeName.get(TYPE1));
    List<ObjectUsage> expected = newArrayList(usage1, usage2);
    // input is shuffled
    assertFalse(actual.equals(expected));
    // but everything is remembered
    assertEqualEntries(expected, actual);
  }
 @Test(expected = IllegalArgumentException.class)
 public void exceptionIsThrownIfTypeIsNotKnown() {
   ObjectUsage usage1 = createUsage(TYPE1, "LContext.m1()V");
   sut.store(newArrayList(usage1));
   sut.read(VmTypeName.get(TYPE2));
 }