docs: public <T> T convert(final Object source, final Class<T> targetclass) {
          if (source == null) {
              return null;
          }
  
          final Class<?> sourceclass = source.getClass();
          if (targetclass.isPrimitive() && String.class.isAssignableFrom(sourceclass)) {
              return (T) parsePrimitive(source.toString(), targetclass);
          }
  
          final int sourceId = ids.getId(sourceclass);
          final int targetId = ids.getId(targetclass);
          final SourceTargetPairKey key = new SourceTargetPairKey(sourceId, targetId);
          Converter converter = cache.get(key);
  
          if (converter != null) {
              return (T) converter.convert(source, targetclass);
          }
          final LinkedList<SourceTargetPairMatch> matches = new LinkedList<>();
          for (SourceTargetPair pair : converters.values()) {
              SourceTargetPairMatch match = pair.match(sourceclass, targetclass);
              if (match.matchesSource() && match.matchesTarget()) {
                  matches.add(match);
              }
          }
          if (matches.size() == 0) {
              throw new ConversionException("No suitable converter found for target class ["
                      + targetclass.getName() + "] and source value [" + sourceclass.getName()
                      + "]. The following converters are available [" + converters.keySet() + "]");
          }
  
          Collections.sort(matches, SourceTargetPairMatch.bestTargetMatch());
          converter = matches.get(0).pair.converter;
          cache.put(key, converter);
          return (T) converter.convert(source, targetclass);
  
      }