/**
   * Returns the configuring forward method's options in case the given method is annotated with
   * {@code @InheritConfiguration} and exactly one such configuring method can unambiguously be
   * selected (as per the source/target type and optionally the name given via
   * {@code @InheritConfiguration}). The method cannot be marked forward mapping itself (hence
   * 'ohter'). And neither can it contain an {@code @InheritReverseConfiguration}
   */
  private MappingOptions getTemplateMappingOptions(
      List<SourceMethod> rawMethods,
      SourceMethod method,
      List<SourceMethod> initializingMethods,
      MapperConfiguration mapperConfig) {
    SourceMethod resultMethod = null;
    InheritConfigurationPrism forwardPrism =
        InheritConfigurationPrism.getInstanceOn(method.getExecutable());

    if (forwardPrism != null) {
      reportErrorWhenInheritForwardAlsoHasInheritReverseMapping(method);

      List<SourceMethod> candidates = new ArrayList<SourceMethod>();
      for (SourceMethod oneMethod : rawMethods) {
        // method must be similar but not equal
        if (method.canInheritFrom(oneMethod) && !(oneMethod.equals(method))) {
          candidates.add(oneMethod);
        }
      }

      String name = forwardPrism.name();
      if (candidates.size() == 1) {
        // no ambiguity: if no configuredBy is specified, or configuredBy specified and match
        SourceMethod sourceMethod = first(candidates);
        if (name.isEmpty()) {
          resultMethod = sourceMethod;
        } else if (sourceMethod.getName().equals(name)) {
          resultMethod = sourceMethod;
        } else {
          reportErrorWhenNonMatchingName(sourceMethod, method, forwardPrism);
        }
      } else if (candidates.size() > 1) {
        // ambiguity: find a matching method that matches configuredBy

        List<SourceMethod> nameFilteredcandidates = new ArrayList<SourceMethod>();
        for (SourceMethod candidate : candidates) {
          if (candidate.getName().equals(name)) {
            nameFilteredcandidates.add(candidate);
          }
        }

        if (nameFilteredcandidates.size() == 1) {
          resultMethod = first(nameFilteredcandidates);
        } else if (nameFilteredcandidates.size() > 1) {
          reportErrorWhenSeveralNamesMatch(nameFilteredcandidates, method, forwardPrism);
        } else {
          reportErrorWhenAmbigousMapping(candidates, method, forwardPrism);
        }
      }
    }

    return extractInitializedOptions(resultMethod, rawMethods, mapperConfig, initializingMethods);
  }