docs: private void matchSource(TypeInfo<?> sourceTypeInfo, Mutator destinationMutator, boolean hitSameSourceType) {
      sourceTypes.add(sourceTypeInfo.getType());
  
      for (Map.Entry<String, Accessor> entry : sourceTypeInfo.getAccessors().entrySet()) {
        Accessor accessor = entry.getValue();
        propertyNameInfo.pushSource(entry.getKey(), entry.getValue());
        boolean doneMatching = false;
  
        if (matchingStrategy.matches(propertyNameInfo)) {
          if (destinationTypes.contains(destinationMutator.getType())) {
            mappings.add(new PropertyMappingImpl(propertyNameInfo.getSourceProperties(),
                propertyNameInfo.getDestinationProperties(), true));
          } else {
            TypeMap<?, ?> propertyTypeMap = typeMapStore.get(accessor.getType(),
                destinationMutator.getType(), null);
            PropertyMappingImpl mapping = null;
  
            // Check to create mapping(s) from existing TypeMap
            if (propertyTypeMap != null) {
              Converter<?, ?> propertyConverter = propertyTypeMap.getConverter();
              if (propertyConverter == null)
                mergeMappings(propertyTypeMap);
              else
                mappings.add(new PropertyMappingImpl(propertyNameInfo.getSourceProperties(),
                    propertyNameInfo.getDestinationProperties(), propertyTypeMap.getProvider(),
                    propertyConverter));
              doneMatching = matchingStrategy.isExact();
            } else {
              for (ConditionalConverter<?, ?> converter : converterStore.getConverters()) {
                MatchResult matchResult = converter.match(accessor.getType(),
                    destinationMutator.getType());
  
                if (!MatchResult.NONE.equals(matchResult)) {
                  mapping = new PropertyMappingImpl(propertyNameInfo.getSourceProperties(),
                      propertyNameInfo.getDestinationProperties(), false);
  
                  if (MatchResult.FULL.equals(matchResult)) {
                    mappings.add(mapping);
                    doneMatching = matchingStrategy.isExact();
                    break;
                  } else if (!configuration.isFullTypeMatchingRequired()) {
                    partiallyMatchedMappings.add(mapping);
                    break;
                  }
                }
              }
            }
  
            if (mapping == null)
              intermediateMappings.put(
                  accessor,
                  new PropertyMappingImpl(propertyNameInfo.getSourceProperties(),
                      propertyNameInfo.getDestinationProperties(), false));
          }
        }
  
        if (!doneMatching
            && !hitSameSourceType
            && Types.mightContainsProperties(accessor.getType())) {
          if (accessor instanceof ValueReaderPropertyInfo)
            matchSource(accessor.getTypeInfo(configuration), destinationMutator, false);
          else if (!sourceTypes.contains(accessor.getType()))
            matchSource(accessor.getTypeInfo(configuration), destinationMutator, false);
          else
            matchSource(accessor.getTypeInfo(configuration), destinationMutator, true);
        }
  
        propertyNameInfo.popSource();
  
        if (doneMatching)
          break;
      }
  
      if (!hitSameSourceType)
        sourceTypes.remove(sourceTypeInfo.getType());
    }