public static int from(String roman) throws ParseException {
        if (!RomanNumeral.properlyFormatted(roman))
            throw new ParseException(
                    new Diagnosis().append("diagnosis.roman-numeral-from-invalid-value", roman),
                    ParseException.ParseType.GENERIC
            );

        roman = roman.toUpperCase();
        int result = 0, index = 0;

        loop: for (RomanNumeral unit : RomanNumeral.reverseOrder()) {

            if (index == roman.length())
                break;

            while (index < roman.length()) {
                if (   unit.hasSubtractiveUnit()
                         && roman.charAt(index) == unit.subtractiveUnit().getChar()
                         && roman.length() - index > 1
                         && roman.charAt(index + 1) == unit.getChar()) {
                    result += unit.subtractiveUnitValue();
                    index += 2;
                }

                else if (roman.charAt(index) == unit.getChar()) {
                    result += unit.value();
                    ++index;
                }

                else continue loop;
            }
        }

        return result;
    }