class MediaTypeComparator implements Comparator<MediaType> {

    @Override
    public int compare(MediaType mediaTypeOne, MediaType mediaTypeTwo) {

        if (mediaTypeOne.isWildcardType() && !mediaTypeTwo.isWildcardType()) {
            return 1;
        }
        if (mediaTypeOne.isWildcardSubtype() && !mediaTypeTwo.isWildcardSubtype()) {
            return 1;
        }
        if (!mediaTypeOne.isWildcardType() && mediaTypeTwo.isWildcardType()) {
            return -1;
        }
        if (!mediaTypeOne.isWildcardSubtype() && mediaTypeTwo.isWildcardSubtype()) {
            return -1;
        }

        Matcher extSubtypeMatcherOne = MediaTypeHelper.EXT_SUBTYPE_PATTERN.matcher(mediaTypeOne.getSubtype());
        Matcher extSubtypeMatcherTwo = MediaTypeHelper.EXT_SUBTYPE_PATTERN.matcher(mediaTypeTwo.getSubtype());
        boolean extSubtypeMatcherOneMatches = extSubtypeMatcherOne.matches();
        boolean extSubtypeMatcherTwoMatches = extSubtypeMatcherTwo.matches();

        if (extSubtypeMatcherOneMatches && !extSubtypeMatcherTwoMatches) {
            return 1;
        }
        if (!extSubtypeMatcherOneMatches && extSubtypeMatcherTwoMatches) {
            return -1;
        }

        extSubtypeMatcherOne = MediaTypeHelper.EXT_PREFIX_SUBTYPE_PATTERN.matcher(mediaTypeOne.getSubtype());
        extSubtypeMatcherTwo = MediaTypeHelper.EXT_PREFIX_SUBTYPE_PATTERN.matcher(mediaTypeTwo.getSubtype());
        extSubtypeMatcherOneMatches = extSubtypeMatcherOne.matches();
        extSubtypeMatcherTwoMatches = extSubtypeMatcherTwo.matches();

        if (extSubtypeMatcherOneMatches && !extSubtypeMatcherTwoMatches) {
            return 1;
        }
        if (!extSubtypeMatcherOneMatches && extSubtypeMatcherTwoMatches) {
            return -1;
        }

        extSubtypeMatcherOne = MediaTypeHelper.EXT_SUFFIX_SUBTYPE_PATTERN.matcher(mediaTypeOne.getSubtype());
        extSubtypeMatcherTwo = MediaTypeHelper.EXT_SUFFIX_SUBTYPE_PATTERN.matcher(mediaTypeTwo.getSubtype());
        extSubtypeMatcherOneMatches = extSubtypeMatcherOne.matches();
        extSubtypeMatcherTwoMatches = extSubtypeMatcherTwo.matches();

        if (extSubtypeMatcherOneMatches && !extSubtypeMatcherTwoMatches) {
            return 1;
        }
        if (!extSubtypeMatcherOneMatches && extSubtypeMatcherTwoMatches) {
            return -1;
        }

        return toString(mediaTypeOne).compareToIgnoreCase(toString(mediaTypeTwo));
    }

}