src/main/software/amazon/event/ruler/JsonRuleCompiler.java [469:597]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                tooManyElements(parser);
            }

            return anythingBut;
        } else if (Constants.EXISTS_MATCH.equals(matchTypeName)) {
            return processExistsExpression(parser);
        } else if (Constants.CIDR.equals(matchTypeName)) {
            final JsonToken cidrToken = parser.nextToken();
            if (cidrToken != JsonToken.VALUE_STRING) {
                barf(parser, "prefix match pattern must be a string");
            }
            final Range cidr = CIDR.cidr(parser.getText());
            if (parser.nextToken() != JsonToken.END_OBJECT) {
                barf(parser, "Only one key allowed in match expression");
            }
            return cidr;
        } else if (Constants.EQUALS_IGNORE_CASE.equals(matchTypeName)) {
            final JsonToken equalsIgnoreCaseToken = parser.nextToken();
            if (equalsIgnoreCaseToken != JsonToken.VALUE_STRING) {
                barf(parser, "equals-ignore-case match pattern must be a string");
            }
            final Patterns pattern = Patterns.equalsIgnoreCaseMatch('"' + parser.getText() + '"');
            if (parser.nextToken() != JsonToken.END_OBJECT) {
                barf(parser, "Only one key allowed in match expression");
            }
            return pattern;
        } else if (Constants.WILDCARD.equals(matchTypeName)) {
            final JsonToken wildcardToken = parser.nextToken();
            if (wildcardToken != JsonToken.VALUE_STRING) {
                barf(parser, "wildcard match pattern must be a string");
            }
            final String parserText = parser.getText();
            String value = '"' + parserText + '"';
            try {
                getParser().parse(MatchType.WILDCARD, value);
            } catch (ParseException e) {
                barf(parser, e.getLocalizedMessage());
            }
            final Patterns pattern = Patterns.wildcardMatch(value);
            if (parser.nextToken() != JsonToken.END_OBJECT) {
                barf(parser, "Only one key allowed in match expression");
            }
            return pattern;
        } else {
            barf(parser, "Unrecognized match type " + matchTypeName);
            return null; // unreachable statement, but java can't see that?
        }
    }

    private static Patterns processPrefixEqualsIgnoreCaseExpression(final JsonParser parser) throws IOException {
        final JsonToken prefixObject = parser.nextToken();
        if (prefixObject != JsonToken.FIELD_NAME) {
            barf(parser, "Prefix expression name not found");
        }

        final String prefixObjectOp = parser.getCurrentName();
        if (!Constants.EQUALS_IGNORE_CASE.equals(prefixObjectOp)) {
            barf(parser, "Unsupported prefix pattern: " + prefixObjectOp);
        }

        final JsonToken prefixEqualsIgnoreCase = parser.nextToken();
        if (prefixEqualsIgnoreCase != JsonToken.VALUE_STRING) {
            barf(parser, "equals-ignore-case match pattern must be a string");
        }
        final Patterns pattern = Patterns.prefixEqualsIgnoreCaseMatch('"' + parser.getText());
        if (parser.nextToken() != JsonToken.END_OBJECT) {
            barf(parser, "Only one key allowed in match expression");
        }
        if (parser.nextToken() != JsonToken.END_OBJECT) {
            barf(parser, "Only one key allowed in match expression");
        }
        return pattern;
    }

    private static Patterns processSuffixEqualsIgnoreCaseExpression(final JsonParser parser) throws IOException {
        final JsonToken suffixObject = parser.nextToken();
        if (suffixObject != JsonToken.FIELD_NAME) {
            barf(parser, "Suffix expression name not found");
        }

        final String suffixObjectOp = parser.getCurrentName();
        if (!Constants.EQUALS_IGNORE_CASE.equals(suffixObjectOp)) {
            barf(parser, "Unsupported suffix pattern: " + suffixObjectOp);
        }

        final JsonToken suffixEqualsIgnoreCase = parser.nextToken();
        if (suffixEqualsIgnoreCase != JsonToken.VALUE_STRING) {
            barf(parser, "equals-ignore-case match pattern must be a string");
        }
        final Patterns pattern = Patterns.suffixEqualsIgnoreCaseMatch(parser.getText() + '"');
        if (parser.nextToken() != JsonToken.END_OBJECT) {
            barf(parser, "Only one key allowed in match expression");
        }
        if (parser.nextToken() != JsonToken.END_OBJECT) {
            barf(parser, "Only one key allowed in match expression");
        }
        return pattern;
    }

    private static Patterns processAnythingButListMatchExpression(JsonParser parser) throws JsonParseException {
        JsonToken token;
        Set<String> values = new HashSet<>();
        boolean hasNumber = false;
        boolean hasString = false;
        try {
            while ((token = parser.nextToken()) != JsonToken.END_ARRAY) {
                switch (token) {
                    case VALUE_STRING:
                        values.add('"' + parser.getText() + '"');
                        hasString = true;
                        break;
                    case VALUE_NUMBER_FLOAT:
                    case VALUE_NUMBER_INT:
                        values.add(ComparableNumber.generate(parser.getText()));
                        hasNumber = true;
                        break;
                    default:
                        barf(parser, "Inside anything but list, start|null|boolean is not supported.");
                }
            }
        } catch (IllegalArgumentException | IOException e) {
            barf(parser, e.getMessage());
        }

        if ((hasNumber && hasString) || (!hasNumber && !hasString)) {
            barf(parser, "Inside anything but list, either all values are number or string, " +
                    "mixed type is not supported");
        }
        return AnythingBut.anythingButMatch(values, hasNumber);
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



src/main/software/amazon/event/ruler/RuleCompiler.java [379:506]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                tooManyElements(parser);
            }
            return anythingBut;
        } else if (Constants.EXISTS_MATCH.equals(matchTypeName)) {
            return processExistsExpression(parser);
        } else if (Constants.CIDR.equals(matchTypeName)) {
            final JsonToken cidrToken = parser.nextToken();
            if (cidrToken != JsonToken.VALUE_STRING) {
                barf(parser, "prefix match pattern must be a string");
            }
            final Range cidr = CIDR.cidr(parser.getText());
            if (parser.nextToken() != JsonToken.END_OBJECT) {
                barf(parser, "Only one key allowed in match expression");
            }
            return cidr;
        } else if (Constants.EQUALS_IGNORE_CASE.equals(matchTypeName)) {
            final JsonToken equalsIgnoreCaseToken = parser.nextToken();
            if (equalsIgnoreCaseToken != JsonToken.VALUE_STRING) {
                barf(parser, "equals-ignore-case match pattern must be a string");
            }
            final Patterns pattern = Patterns.equalsIgnoreCaseMatch('"' + parser.getText() + '"');
            if (parser.nextToken() != JsonToken.END_OBJECT) {
                barf(parser, "Only one key allowed in match expression");
            }
            return pattern;
        } else if (Constants.WILDCARD.equals(matchTypeName)) {
            final JsonToken wildcardToken = parser.nextToken();
            if (wildcardToken != JsonToken.VALUE_STRING) {
                barf(parser, "wildcard match pattern must be a string");
            }
            final String parserText = parser.getText();
            String value = '"' + parserText + '"';
            try {
                getParser().parse(MatchType.WILDCARD, value);
            } catch (ParseException e) {
                barf(parser, e.getLocalizedMessage());
            }
            final Patterns pattern = Patterns.wildcardMatch(value);
            if (parser.nextToken() != JsonToken.END_OBJECT) {
                barf(parser, "Only one key allowed in match expression");
            }
            return pattern;
        } else {
            barf(parser, "Unrecognized match type " + matchTypeName);
            return null; // unreachable statement, but java can't see that?
        }
    }

    private static Patterns processPrefixEqualsIgnoreCaseExpression(final JsonParser parser) throws IOException {
        final JsonToken prefixObject = parser.nextToken();
        if (prefixObject != JsonToken.FIELD_NAME) {
            barf(parser, "Prefix expression name not found");
        }

        final String prefixObjectOp = parser.getCurrentName();
        if (!Constants.EQUALS_IGNORE_CASE.equals(prefixObjectOp)) {
            barf(parser, "Unsupported prefix pattern: " + prefixObjectOp);
        }

        final JsonToken prefixEqualsIgnoreCase = parser.nextToken();
        if (prefixEqualsIgnoreCase != JsonToken.VALUE_STRING) {
            barf(parser, "equals-ignore-case match pattern must be a string");
        }
        final Patterns pattern = Patterns.prefixEqualsIgnoreCaseMatch('"' + parser.getText());
        if (parser.nextToken() != JsonToken.END_OBJECT) {
            barf(parser, "Only one key allowed in match expression");
        }
        if (parser.nextToken() != JsonToken.END_OBJECT) {
            barf(parser, "Only one key allowed in match expression");
        }
        return pattern;
    }

    private static Patterns processSuffixEqualsIgnoreCaseExpression(final JsonParser parser) throws IOException {
        final JsonToken suffixObject = parser.nextToken();
        if (suffixObject != JsonToken.FIELD_NAME) {
            barf(parser, "Suffix expression name not found");
        }

        final String suffixObjectOp = parser.getCurrentName();
        if (!Constants.EQUALS_IGNORE_CASE.equals(suffixObjectOp)) {
            barf(parser, "Unsupported suffix pattern: " + suffixObjectOp);
        }

        final JsonToken suffixEqualsIgnoreCase = parser.nextToken();
        if (suffixEqualsIgnoreCase != JsonToken.VALUE_STRING) {
            barf(parser, "equals-ignore-case match pattern must be a string");
        }
        final Patterns pattern = Patterns.suffixEqualsIgnoreCaseMatch(parser.getText() + '"');
        if (parser.nextToken() != JsonToken.END_OBJECT) {
            barf(parser, "Only one key allowed in match expression");
        }
        if (parser.nextToken() != JsonToken.END_OBJECT) {
            barf(parser, "Only one key allowed in match expression");
        }
        return pattern;
    }

    private static Patterns processAnythingButListMatchExpression(JsonParser parser) throws JsonParseException {
        JsonToken token;
        Set<String> values = new HashSet<>();
        boolean hasNumber = false;
        boolean hasString = false;
        try {
            while ((token = parser.nextToken()) != JsonToken.END_ARRAY) {
                switch (token) {
                    case VALUE_STRING:
                        values.add('"' + parser.getText() + '"');
                        hasString = true;
                        break;
                    case VALUE_NUMBER_FLOAT:
                    case VALUE_NUMBER_INT:
                        values.add(ComparableNumber.generate(parser.getText()));
                        hasNumber = true;
                        break;
                    default:
                        barf(parser, "Inside anything but list, start|null|boolean is not supported.");
                }
            }
        } catch (IllegalArgumentException | IOException e) {
            barf(parser, e.getMessage());
        }

        if ((hasNumber && hasString) || (!hasNumber && !hasString)) {
            barf(parser, "Inside anything but list, either all values are number or string, " +
                    "mixed type is not supported");
        }
        return AnythingBut.anythingButMatch(values, hasNumber);
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



