@Override
  public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable {
    if (StableElement.class.equals(method.getDeclaringClass())) {
      try {
        return method.invoke(this, args);
      }
      catch (InvocationTargetException e) {
        throw e.getCause();
      }
    }

    if (AdvancedProxy.FINALIZE_METHOD.equals(method)) return null;

    if (isNotValid(cachedValue)) {
      if (cachedValue != null) {
        oldValue = cachedValue;
      }
      cachedValue = provider.get();
      if (isNotValid(cachedValue)) {
        if (AdvancedProxy.EQUALS_METHOD.equals(method)) {

          final Object arg = args[0];
          if (!(arg instanceof StableElement)) return false;

          final StableInvocationHandler<?> handler = DomManagerImpl.getStableInvocationHandler(arg);
          if (handler == null || handler.getWrappedElement() != null) return false;

          return Comparing.equal(oldValue, handler.oldValue);
        }

        if (oldValue != null && Object.class.equals(method.getDeclaringClass())) {
          return method.invoke(oldValue, args);
        }

        if ("isValid".equals(method.getName())) {
          return Boolean.FALSE;
        }
        throw new AssertionError("Calling methods on invalid value");
      }
    }

    if (AdvancedProxy.EQUALS_METHOD.equals(method)) {
      final Object arg = args[0];
      if (arg instanceof StableElement) {
        return cachedValue.equals(((StableElement<?>)arg).getWrappedElement());
      }
      return cachedValue.equals(arg);

    }
    if (AdvancedProxy.HASHCODE_METHOD.equals(method)) {
      return cachedValue.hashCode();
    }

    try {
      return method.invoke(cachedValue, args);
    }
    catch (InvocationTargetException e) {
      throw e.getCause();
    }
  }
@Override
  public Object invoke(Object proxy, final Method method, final Object[] args)