src/main/java/org/deephacks/tools4j/cli/Conversion.java
public <T> T convert(final Object source, final Class<T> targetclass) {
        if (source == null) {
            return null;
        }

        final Class<?> sourceclass = source.getClass();
        final SourceTargetPairKey key = new SourceTargetPairKey(sourceclass, targetclass);
        Converter converter = cache.get(key);

        if (converter != null) {
            return (T) converter.convert(source, targetclass);
        }
        final LinkedList<SourceTargetPairMatch> matches = new LinkedList<SourceTargetPairMatch>();
        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);

    }
public <T> T convert(final Object source, final Class<T> targetclass) {
        if (source == null) {
            return null;
        }

        final Class<?> sourceclass = source.getClass();
        final SourceTargetPairKey key = new SourceTargetPairKey(sourceclass, targetclass);
        Converter converter = cache.get(key);

        if (converter != null) {
            return (T) converter.convert(source, targetclass);
        }
        final LinkedList<SourceTargetPairMatch> matches = new LinkedList<SourceTargetPairMatch>();
        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);

    }
Convert a value to a specific class.

The algorithm for finding a suitable converter is as follows:

Find converters that is able to convert both source and target; a exact or
superclass match. Pick the converter that have the best target match, if both
are equal, pick the one with best source match.

That is, the converter that is most specialized in converting a value to
a specific target class will be prioritized, as long as it recognizes the source
value.

@param source value to convert.
@param targetclass class to convert to.
@return converted value