public <V> Adapter.Setter<V> makeSetter(String methodName, Class<V> _class) {
    try {
      T version = (T) start.get().newVersion;
      final Method method = version.getClass().getMethod(methodName, _class);
      return new Adapter.Setter<V>() {
        public void call(V value) {
          try {
            Transaction me  = Thread.getTransaction();
            Locator oldLocator = start.get();
            T version = (T) oldLocator.fastPath(me);
            if (version != null) {
              method.invoke(version, value);
              return;
            }
            ContentionManager manager = Thread.getContentionManager();
            Locator newLocator = new Locator(me, (Copyable)factory.create());
            version = (T) newLocator.newVersion;
            LocalReadSet readSet = LocalReadSet.getLocal();
            readSet.release(Adapter.this);  // don't conflict with self
            while (true) {
              oldLocator.writePath(me, manager, newLocator);
              if (!me.isActive()) {
                throw new AbortedException();
              }
              method.invoke(version, value);
              if (Adapter.this.start.compareAndSet(oldLocator, newLocator)) {
                return;
              }
              oldLocator = Adapter.this.start.get();
            }
          } catch (IllegalAccessException e) {
            throw new PanicException(e);
          } catch (InvocationTargetException e) {
            throw new PanicException(e);
          }
        }};
    } catch (NoSuchMethodException e) {
      throw new PanicException(e);
    }
  }