System.err.println("These conflict: " + o1 + " and " + o2);
   public static void rebuildFileInPlace(File file, List deltas)   throws IOException   {      final boolean copyOnly = !file.exists();      RandomAccessFile f = new RandomAccessFile(file, "rw");      List offsets = new LinkedList();      List dataBlocks = new LinkedList();      TreeMap digraph = new TreeMap(new OffsetComparator());      long newFileLength = 0;      for (Iterator i = deltas.iterator(); i.hasNext(); ) {         Object o = i.next();         if (o instanceof Offsets) {            if (copyOnly)               throw new IOException("original file does not exist.");            offsets.add(o);            digraph.put(o, new HashSet());            newFileLength = Math.max(newFileLength,               ((Offsets) o).getNewOffset()+((Offsets) o).getBlockLength());         } else if (o instanceof DataBlock) {            dataBlocks.add(o);            newFileLength = Math.max(newFileLength,               ((DataBlock) o).getOffset()+((DataBlock) o).getBlockLength());         }      }      if (copyOnly) {         for (Iterator i = dataBlocks.iterator(); i.hasNext(); ) {            DataBlock d = (DataBlock) i.next();            f.seek(d.getWriteOffset());            f.write(d.getData());         }         if (f.length() < newFileLength) {            f.setLength(newFileLength);         }         f.close();         return;      }      // build the digraph      for (Iterator i = offsets.iterator(); i.hasNext(); ) {         Offsets o1 = (Offsets) i.next();         Set adj = (Set) digraph.get(o1);         for (Iterator j = offsets.iterator(); j.hasNext(); ) {            Offsets o2 = (Offsets) j.next();            if (o1 == o2) continue;            if (conflict(o1, o2)) {               System.err.println("These conflict: " + o1 + " and " + o2);               adj.add(o2);            }         }      }      // Sort the digraph topologically, removing nodes that cause cycles.      TopologicalSorter ts = new TopologicalSorter(digraph);      ts.sort();      for (Iterator i = ts.getCycleNodes().iterator(); i.hasNext(); ) {         Offsets o = (Offsets) i.next();         System.err.println(">RFIP: conflicting offsets: " + o);         byte[] buf = new byte[o.getBlockLength()];         f.seek(o.getOldOffset());         f.read(buf);         dataBlocks.add(new DataBlock(o.getNewOffset(), buf));      }      for (Iterator i = ts.getFinished().iterator(); i.hasNext(); ) {         Offsets o = (Offsets) i.next();         System.err.println(">RFIP: offsets: " + o);         byte[] buf = new byte[o.getBlockLength()];         f.seek(o.getOldOffset());         f.read(buf);         f.seek(o.getNewOffset());         f.write(buf);      }      for (Iterator i = dataBlocks.iterator(); i.hasNext(); ) {         DataBlock db = (DataBlock) i.next();         System.err.println(">RFIP: data block: " + db);         f.seek(db.getOffset());         f.write(db.getData());      }      if (f.length() > newFileLength) {         f.setLength(newFileLength);      }      f.close();   }