public static Map<String, Map<String, Expression>> getConstraintMetadata(final ClosureExpression closureExpression) {

        final List<MethodCallExpression> methodExpressions = new ArrayList<MethodCallExpression>();

        final Map<String, Map<String, Expression>> results = new LinkedHashMap<String, Map<String, Expression>>();
        final Statement closureCode = closureExpression.getCode();
        if (closureCode instanceof BlockStatement) {
            final List<Statement> closureStatements = ((BlockStatement) closureCode).getStatements();
            for (final Statement closureStatement : closureStatements) {
                if (closureStatement instanceof ExpressionStatement) {
                    final Expression expression = ((ExpressionStatement) closureStatement).getExpression();
                    if (expression instanceof MethodCallExpression) {
                        methodExpressions.add((MethodCallExpression) expression);
                    }
                } else if (closureStatement instanceof ReturnStatement) {
                    final ReturnStatement returnStatement = (ReturnStatement) closureStatement;
                    Expression expression = returnStatement.getExpression();
                    if (expression instanceof MethodCallExpression) {
                        methodExpressions.add((MethodCallExpression) expression);
                    }
                }

                for (final MethodCallExpression methodCallExpression : methodExpressions) {
                    final Expression objectExpression = methodCallExpression.getObjectExpression();
                    if (objectExpression instanceof VariableExpression && "this".equals(((VariableExpression)objectExpression).getName())) {
                        final Expression methodCallArguments = methodCallExpression.getArguments();
                        if (methodCallArguments instanceof TupleExpression) {
                            final List<Expression> methodCallArgumentExpressions = ((TupleExpression) methodCallArguments).getExpressions();
                            if (methodCallArgumentExpressions != null && methodCallArgumentExpressions.size() == 1 && methodCallArgumentExpressions.get(0) instanceof NamedArgumentListExpression) {
                                final Map<String, Expression> constraintNameToExpression = new LinkedHashMap<String, Expression>();
                                final List<MapEntryExpression> mapEntryExpressions = ((NamedArgumentListExpression) methodCallArgumentExpressions.get(0)).getMapEntryExpressions();
                                for (final MapEntryExpression mapEntryExpression : mapEntryExpressions) {
                                    final Expression keyExpression = mapEntryExpression.getKeyExpression();
                                    if (keyExpression instanceof ConstantExpression) {
                                        final Object value = ((ConstantExpression) keyExpression).getValue();
                                        if (value instanceof String) {
                                            constraintNameToExpression.put((String)value, mapEntryExpression.getValueExpression());
                                        }
                                    }
                                }
                                results.put(methodCallExpression.getMethodAsString(), constraintNameToExpression);
                            }
                        }
                    }
                }
            }
        }
        return results;
    }
public static Map < String , Map < String , Expression > > getConstraintMetadata ( final ClosureExpression closureExpression ) { final List < MethodCallExpression > methodExpressions = new ArrayList < MethodCallExpression > ( ) ; final Map < String , Map < String , Expression > > results = new LinkedHashMap < String , Map < String , Expression > > ( ) ; final Statement closureCode = closureExpression . getCode ( ) ; if ( closureCode instanceof BlockStatement ) { final List < Statement > closureStatements = ( ( BlockStatement ) closureCode ) . getStatements ( ) ; for ( final Statement closureStatement : closureStatements ) { if ( closureStatement instanceof ExpressionStatement ) { final Expression expression = ( ( ExpressionStatement ) closureStatement ) . getExpression ( ) ; if ( expression instanceof MethodCallExpression ) { methodExpressions . add ( ( MethodCallExpression ) expression ) ; } } else if ( closureStatement instanceof ReturnStatement ) { final ReturnStatement returnStatement = ( ReturnStatement ) closureStatement ; Expression expression = returnStatement . getExpression ( ) ; if ( expression instanceof MethodCallExpression ) { methodExpressions . add ( ( MethodCallExpression ) expression ) ; } } for ( final MethodCallExpression methodCallExpression : methodExpressions ) { final Expression objectExpression = methodCallExpression . getObjectExpression ( ) ; if ( objectExpression instanceof VariableExpression && "this" . equals ( ( ( VariableExpression ) objectExpression ) . getName ( ) ) ) { final Expression methodCallArguments = methodCallExpression . getArguments ( ) ; if ( methodCallArguments instanceof TupleExpression ) { final List < Expression > methodCallArgumentExpressions = ( ( TupleExpression ) methodCallArguments ) . getExpressions ( ) ; if ( methodCallArgumentExpressions != null && methodCallArgumentExpressions . size ( ) == 1 && methodCallArgumentExpressions . get ( 0 ) instanceof NamedArgumentListExpression ) { final Map < String , Expression > constraintNameToExpression = new LinkedHashMap < String , Expression > ( ) ; final List < MapEntryExpression > mapEntryExpressions = ( ( NamedArgumentListExpression ) methodCallArgumentExpressions . get ( 0 ) ) . getMapEntryExpressions ( ) ; for ( final MapEntryExpression mapEntryExpression : mapEntryExpressions ) { final Expression keyExpression = mapEntryExpression . getKeyExpression ( ) ; if ( keyExpression instanceof ConstantExpression ) { final Object value = ( ( ConstantExpression ) keyExpression ) . getValue ( ) ; if ( value instanceof String ) { constraintNameToExpression . put ( ( String ) value , mapEntryExpression . getValueExpression ( ) ) ; } } } results . put ( methodCallExpression . getMethodAsString ( ) , constraintNameToExpression ) ; } } } } } } return results ; }
Evaluates a constraints closure and returns metadata about the constraints configured in the closure.  The
Map returned has property names as keys and the value associated with each of those property names is
a Map<String, Expression> which has constraint names as keys and the Expression associated with that constraint
as values.

@param closureExpression the closure expression to evaluate
@return the Map as described above