class SpringSelectedValueComparator {


    /*
     * NOTE This code is based on org.springframework.web.servlet.tags.form.SelectedValueComparator as of Spring 5.0.0
     *      Original license is Apache License 2.0, which is the same as the license for this file.
     *      Original copyright notice is "Copyright 2002-2016 the original author or authors".
     *      Original authors are Rob Harrop and Juergen Hoeller.
     *
     * NOTE The code in this class has been adapted to use Thymeleaf's own BindStatus interfaces.
     */


    public static boolean isSelected(final IThymeleafBindStatus bindStatus, final Object candidateValue) {

        if (bindStatus == null) {
            return (candidateValue == null);
        }

        // Check obvious equality matches with the candidate first,
        // both with the rendered value and with the original value.
        Object boundValue = bindStatus.getValue();
        if (ObjectUtils.nullSafeEquals(boundValue, candidateValue)) {
            return true;
        }
        Object actualValue = bindStatus.getActualValue();
        if (actualValue != null && actualValue != boundValue &&
                ObjectUtils.nullSafeEquals(actualValue, candidateValue)) {
            return true;
        }
        if (actualValue != null) {
            boundValue = actualValue;
        } else if (boundValue == null) {
            return false;
        }

        // Non-null value but no obvious equality with the candidate value:
        // go into more exhaustive comparisons.
        boolean selected = false;
        if (boundValue.getClass().isArray()) {
            selected = collectionCompare(CollectionUtils.arrayToList(boundValue), candidateValue, bindStatus);
        } else if (boundValue instanceof Collection) {
            selected = collectionCompare((Collection<?>) boundValue, candidateValue, bindStatus);
        } else if (boundValue instanceof Map) {
            selected = mapCompare((Map<?, ?>) boundValue, candidateValue, bindStatus);
        }
        if (!selected) {
            selected = exhaustiveCompare(boundValue, candidateValue, bindStatus.getEditor(), null);
        }
        return selected;

    }


    private static boolean collectionCompare(
            final Collection<?> boundCollection, final Object candidateValue, final IThymeleafBindStatus bindStatus) {

        try {
            if (boundCollection.contains(candidateValue)) {
                return true;
            }
        } catch (ClassCastException ex) {
            // Probably from a TreeSet - ignore.
        }
        return exhaustiveCollectionCompare(boundCollection, candidateValue, bindStatus);

    }


    private static boolean mapCompare(
            final Map<?, ?> boundMap, final Object candidateValue, final IThymeleafBindStatus bindStatus) {

        try {
            if (boundMap.containsKey(candidateValue)) {
                return true;
            }
        } catch (ClassCastException ex) {
            // Probably from a TreeMap - ignore.
        }
        return exhaustiveCollectionCompare(boundMap.keySet(), candidateValue, bindStatus);

    }


    private static boolean exhaustiveCollectionCompare(
            final Collection<?> collection, final Object candidateValue, final IThymeleafBindStatus bindStatus) {

        final Map<PropertyEditor, Object> convertedValueCache = new HashMap<>(1);
        PropertyEditor editor = null;
        boolean candidateIsString = (candidateValue instanceof String);
        if (!candidateIsString) {
            editor = bindStatus.findEditor(candidateValue.getClass());
        }
        for (Object element : collection) {
            if (editor == null && element != null && candidateIsString) {
                editor = bindStatus.findEditor(element.getClass());
            }
            if (exhaustiveCompare(element, candidateValue, editor, convertedValueCache)) {
                return true;
            }
        }
        return false;

    }


    private static boolean exhaustiveCompare(
            final Object boundValue, final Object candidate,
            final PropertyEditor editor, final Map<PropertyEditor, Object> convertedValueCache) {<FILL_FUNCTION_BODY>}


    private SpringSelectedValueComparator() {
        super();
    }


}


        final String candidateDisplayString = SpringValueFormatter.getDisplayString(candidate, editor, false);
        if (boundValue != null && boundValue.getClass().isEnum()) {
            final Enum<?> boundEnum = (Enum<?>) boundValue;
            final String enumCodeAsString = ObjectUtils.getDisplayString(boundEnum.name());
            if (enumCodeAsString.equals(candidateDisplayString)) {
                return true;
            }
            final String enumLabelAsString = ObjectUtils.getDisplayString(boundEnum.toString());
            if (enumLabelAsString.equals(candidateDisplayString)) {
                return true;
            }
        } else if (ObjectUtils.getDisplayString(boundValue).equals(candidateDisplayString)) {
            return true;
        } else if (editor != null && candidate instanceof String) {
            // Try PE-based comparison (PE should *not* be allowed to escape creating thread)
            final String candidateAsString = (String) candidate;
            final Object candidateAsValue;
            if (convertedValueCache != null && convertedValueCache.containsKey(editor)) {
                candidateAsValue = convertedValueCache.get(editor);
            } else {
                editor.setAsText(candidateAsString);
                candidateAsValue = editor.getValue();
                if (convertedValueCache != null) {
                    convertedValueCache.put(editor, candidateAsValue);
                }
            }
            if (ObjectUtils.nullSafeEquals(boundValue, candidateAsValue)) {
                return true;
            }
        }
        return false;

    
<no_super_class>