public <V> Adapter.Setter<V> makeSetter(String methodName, Class<V> _class)  {
    try {
      final Method method = version.getClass().getMethod(methodName, _class);
      return new Adapter.Setter<V>() {
        public void call(V value) {
          try{
            lock.lock();
            if (firstTime) {
              ((Recoverable)version).backup();
              firstTime = false;
            }
    Thread.onCommitOnce( new Runnable() {
      public void run() {
        lock.unlock();
      }
    });
    Thread.onAbortOnce( new Runnable() {
      public void run() {
        lock.unlock();
        ((Recoverable)version).recover();
      }
    });
            method.invoke(version, value);
          } catch (IllegalArgumentException ex) {
            throw new PanicException(ex);
          } catch (IllegalAccessException ex) {
            throw new PanicException(ex);
          } catch (InvocationTargetException ex) {
            throw new PanicException(ex);
          }
        }};
    } catch (NoSuchMethodException e) {
      throw new PanicException(e);
    }
  }