class EvalHelper {

    public static String normalizeVariableName(String name) {
        // private static final Pattern SPACES_PATTERN = Pattern.compile( "[\\s\u00A0]+" );
        // return SPACES_PATTERN.matcher( name.trim() ).replaceAll( " " );

        // The above code was refactored for performance reasons
        // Check org.drools.benchmarks.dmn.runtime.DMNEvaluateDecisionNameLengthBenchmark
        // This method tries to return the original String whenever possible to avoid allocation of char[]

        if (name == null || name.isEmpty()) {
            return name;
        }

        // Find the first valid char, used to skip leading spaces
        int firstValid = 0, size = name.length();

        for (; firstValid < size; firstValid++) {
            if (isValidChar(name.charAt(firstValid))) {
                break;
            }
        }
        if (firstValid == size) {
            return "";
        }

        // Finds the last valid char, either before a non-regular space, the first of multiple spaces or the last char
        int lastValid = 0, trailing = 0;
        boolean inWhitespace = false;

        for (int i = firstValid; i < size; i++) {
            if (isValidChar(name.charAt(i))) {
                lastValid = i + 1;
                inWhitespace = false;
            } else {
                if (inWhitespace) {
                    break;
                }
                inWhitespace = true;
                if (name.charAt(i) != ' ') {
                    break;
                }
            }
        }

        // Counts the number of spaces after 'lastValid' (to remove possible trailing spaces)
        for (int i = lastValid; i < size && !isValidChar(name.charAt(i)); i++) {
            trailing++;
        }
        if (lastValid + trailing == size) {
            return firstValid != 0 || trailing != 0 ? name.substring(firstValid, lastValid) : name;
        }

        // There are valid chars after 'lastValid' and substring won't do (full normalization is required)
        int pos = 0;
        char[] target = new char[size-firstValid];

        // Copy the chars know to be valid to the new array
        for (int i = firstValid; i < lastValid; i++) {
            target[pos++] = name.charAt(i);
        }

        // Copy valid chars after 'lastValid' to new array
        // Many whitespaces are collapsed into one and trailing spaces are ignored
        for (int i = lastValid + 1; i < size; i++) {
            char c = name.charAt(i);
            if (isValidChar(c)) {
                if (inWhitespace) {
                    target[pos++] = ' ';
                }
                target[pos++] = c;
                inWhitespace = false;
            } else {
                inWhitespace = true;
            }
        }
        return new String(target, 0, pos);
    }

}