public void upgrade(T snap) {
    Transaction me  = Thread.getTransaction();
    Locator oldLocator = this.start.get();
    T version = (T) oldLocator.fastPath(me);
    if (version != null) {
      if (version != snap) {
        throw new SnapshotException();
      } else {
        return;
      }
    }
    ContentionManager manager = Thread.getContentionManager();
    Locator newLocator = new Locator(me, (Copyable)factory.create());
    while (true) {
      oldLocator.writePath(me, manager, newLocator);
      if (!me.isActive()) {
        throw new AbortedException();
      }
      if (snap != newLocator.oldVersion) {
        throw new SnapshotException();
      }
      if (this.start.compareAndSet(oldLocator, newLocator)) {
        return;
      }
      oldLocator = this.start.get();
    }
  }