private void checkForCorrectAnnotations(Object object) throws UnsupportedOperationException {
   Map<Annotation, Object> annotationValueMapping = new HashMap<>();
   for (Field field : object.getClass().getDeclaredFields()) {
     ProvidesState providesStateAnnotation = field.getAnnotation(ProvidesState.class);
     if (providesStateAnnotation != null) {
       if (annotationValueMapping.put(providesStateAnnotation, providesStateAnnotation.value())
           != null) {
         throw new UnsupportedOperationException(
             "More than one @"
                 + ProvidesState.class.getSimpleName()
                 + " for "
                 + providesStateAnnotation.value().getName()
                 + " used in "
                 + object.getClass().getName());
       }
     }
     HandlesAction handlesActionAnnotation = field.getAnnotation(HandlesAction.class);
     if (handlesActionAnnotation != null) {
       if (annotationValueMapping.put(handlesActionAnnotation, handlesActionAnnotation.value())
           != null) {
         throw new UnsupportedOperationException(
             "More than one @"
                 + HandlesAction.class.getSimpleName()
                 + " for "
                 + handlesActionAnnotation.value().getName()
                 + " used in "
                 + object.getClass().getName());
       }
     }
   }
 }
  private Method findActionHandlerInstance(
      Object viewModel, Class<? extends ActionHandler> actionHandlerType)
      throws IllegalAccessException, UnsupportedOperationException {
    checkForCorrectAnnotations(viewModel);
    for (Method method : viewModel.getClass().getDeclaredMethods()) {
      HandlesAction handlesActionAnnotation = method.getAnnotation(HandlesAction.class);
      if (handlesActionAnnotation == null || handlesActionAnnotation.value() != actionHandlerType) {
        continue;
      }

      if (!Modifier.isPublic(method.getModifiers())) {
        method.setAccessible(true);
      }

      return method;
    }
    return null;
  }