### Question:
Query { public static List<ResultType> extractResultTypes(final String value) throws AttributeExpressionLanguageParsingException { final List<ResultType> types = new ArrayList<>(); for (final Range range : extractExpressionRanges(value)) { final String text = value.substring(range.getStart(), range.getEnd() + 1); types.add(getResultType(text)); } return types; } private  Query(final String query, final Tree tree, final Evaluator<?> evaluator); static boolean isValidExpression(final String value); static ResultType getResultType(final String value); static List<ResultType> extractResultTypes(final String value); static List<String> extractExpressions(final String value); static List<Range> extractExpressionRanges(final String value); static void validateExpression(final String value, final boolean allowSurroundingCharacters); static String unescape(final String value); static Query fromTree(final Tree tree, final String text); static PreparedQuery prepare(final String query); static Query compile(final String query); ResultType getResultType(); @Override String toString();  }### Answer:
@Test public void testExtractExpressionTypes() { final List<ResultType> types = Query.extractResultTypes("${hello:equals( ${goodbye} )} or just hi, ${bob}, are you ${bob.age:toNumber()} yet? $$$${bob}"); assertEquals(3, types.size()); assertEquals(ResultType.BOOLEAN, types.get(0)); assertEquals(ResultType.STRING, types.get(1)); assertEquals(ResultType.WHOLE_NUMBER, types.get(2)); }