@Override
  public <A extends Action<R>, R extends Result> DispatchRequest execute(
      A action, AsyncCallback<R> callback) {

    ActionHandler<A, R> handler = registry.resolve(action);

    if (null == handler)
      callback.onFailure(new IllegalStateException("No handler for type " + action.getType()));

    return handler.execute(action, callback, Collections.unmodifiableMap(properties));
  }
  @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
  @Override
  @SuppressWarnings("unchecked")
  public <S extends Schema> AllowedSchemas<S> findAllowedSchemas(
      final A any, final Class<S> reference) {
    AllowedSchemas<S> result = new AllowedSchemas<>();

    // schemas given by type and aux classes
    Set<AnyTypeClass> typeOwnClasses = new HashSet<>();
    typeOwnClasses.addAll(any.getType().getClasses());
    typeOwnClasses.addAll(any.getAuxClasses());

    for (AnyTypeClass typeClass : typeOwnClasses) {
      if (reference.equals(PlainSchema.class)) {
        result.getForSelf().addAll((Collection<? extends S>) typeClass.getPlainSchemas());
      } else if (reference.equals(DerSchema.class)) {
        result.getForSelf().addAll((Collection<? extends S>) typeClass.getDerSchemas());
      } else if (reference.equals(VirSchema.class)) {
        result.getForSelf().addAll((Collection<? extends S>) typeClass.getVirSchemas());
      }
    }

    // schemas given by type extensions
    Map<Group, List<? extends AnyTypeClass>> typeExtensionClasses = new HashMap<>();
    if (any instanceof User) {
      for (UMembership memb : ((User) any).getMemberships()) {
        for (TypeExtension typeExtension : memb.getRightEnd().getTypeExtensions()) {
          typeExtensionClasses.put(memb.getRightEnd(), typeExtension.getAuxClasses());
        }
      }
    } else if (any instanceof AnyObject) {
      for (AMembership memb : ((AnyObject) any).getMemberships()) {
        for (TypeExtension typeExtension : memb.getRightEnd().getTypeExtensions()) {
          if (any.getType().equals(typeExtension.getAnyType())) {
            typeExtensionClasses.put(memb.getRightEnd(), typeExtension.getAuxClasses());
          }
        }
      }
    }

    for (Map.Entry<Group, List<? extends AnyTypeClass>> entry : typeExtensionClasses.entrySet()) {
      result.getForMemberships().put(entry.getKey(), new HashSet<S>());
      for (AnyTypeClass typeClass : entry.getValue()) {
        if (reference.equals(PlainSchema.class)) {
          result
              .getForMemberships()
              .get(entry.getKey())
              .addAll((Collection<? extends S>) typeClass.getPlainSchemas());
        } else if (reference.equals(DerSchema.class)) {
          result
              .getForMemberships()
              .get(entry.getKey())
              .addAll((Collection<? extends S>) typeClass.getDerSchemas());
        } else if (reference.equals(VirSchema.class)) {
          result
              .getForMemberships()
              .get(entry.getKey())
              .addAll((Collection<? extends S>) typeClass.getVirSchemas());
        }
      }
    }

    return result;
  }