private Object getValue(Object classObject, String fieldName, Object... arguments) {
    if (classObject == null) {
      return null;
    }

    List<Object> value = this.argumentRetriever.getValue(fieldName, classObject, arguments);
    if (!value.isEmpty()) {
      return value.get(0);
    }

    List<MethodDescriptor> methodDescriptors = fieldDescriptorsMap.get(fieldName);

    if (methodDescriptors == null) {
      // TODO: Logger Logger
      this.argumentRetriever.setValue(fieldName, true, null, classObject, arguments);
      return null;
    }

    try {
      // FIXME
      for (MethodDescriptor methodDescriptor : methodDescriptors) {
        Object obtainedValue = methodDescriptor.invoke(classObject, this.fRegistry, arguments);
        if (obtainedValue == null) {
          continue;
        }
        this.argumentRetriever.setValue(fieldName, true, obtainedValue, classObject, arguments);

        return obtainedValue;
      }
    } catch (Exception e) {
      // No need to get an exception value over and over, so cache it regardless
      this.argumentRetriever.setValue(fieldName, true, null, classObject, arguments);

      // TODO: Logger Logger
      return null;
    }

    // TODO: Logger Logger
    this.argumentRetriever.setValue(fieldName, true, null, classObject, arguments);
    return null;
  }