@Override
  public synchronized R put(Integer key, R r) {
    String id = getIdOf(r);
    int n = getNumberOf(r);

    Index copy = copy();
    BuildReference<R> ref = createReference(r);
    BuildReference<R> old = copy.byId.put(id, ref);
    copy.byNumber.put(n, ref);
    index = copy;

    /*
       search relies on the fact that every object added via
       put() method be available in the xyzOnDisk index, so I'm adding them here
       however, this is awfully inefficient. I wonder if there's any better way to do this?
    */
    if (!idOnDisk.contains(id)) {
      ArrayList<String> a = new ArrayList<String>(idOnDisk);
      a.add(id);
      Collections.sort(a);
      idOnDisk = new SortedList<String>(a);
    }

    if (!numberOnDisk.contains(n)) {
      SortedIntList a = new SortedIntList(numberOnDisk);
      a.add(n);
      a.sort();
      numberOnDisk = a;
    }

    return unwrap(old);
  }