You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by cc...@apache.org on 2017/12/14 21:56:57 UTC

[32/57] [abbrv] [partial] groovy git commit: Move Java source set into `src/main/java`

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/VariableExpression.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/VariableExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/VariableExpression.java
new file mode 100644
index 0000000..4ddf07b
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/VariableExpression.java
@@ -0,0 +1,199 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.expr;
+
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.Variable;
+
+/**
+ * Represents a local variable name, the simplest form of expression. e.g. "foo".
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class VariableExpression extends Expression implements Variable {
+    // The following fields are only used internally; every occurrence of a user-defined expression of the same kind
+    // has its own instance so as to preserve line information. Consequently, to test for such an expression, don't
+    // compare against the field but call isXXXExpression() instead.
+    public static final VariableExpression THIS_EXPRESSION = new VariableExpression("this", ClassHelper.DYNAMIC_TYPE);
+    public static final VariableExpression SUPER_EXPRESSION = new VariableExpression("super", ClassHelper.DYNAMIC_TYPE);
+
+    private final String variable;
+    private int modifiers;
+    private boolean inStaticContext;
+    private boolean isDynamicTyped=false;
+    private Variable accessedVariable;
+    boolean closureShare=false;
+    boolean useRef=false;
+    private final ClassNode originType;
+
+    public Variable getAccessedVariable() {
+        return accessedVariable;
+    }
+
+    public void setAccessedVariable(Variable origin) {
+        this.accessedVariable = origin;
+    }
+
+    public VariableExpression(String variable, ClassNode type) {
+        this.variable = variable;
+        originType = type;
+        setType(ClassHelper.getWrapper(type));
+    }
+    
+    public VariableExpression(String variable) {
+        this(variable, ClassHelper.DYNAMIC_TYPE);
+    }
+    
+    public VariableExpression(Variable variable) {
+        this(variable.getName(), variable.getOriginType());
+        setAccessedVariable(variable);
+        setModifiers(variable.getModifiers());
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitVariableExpression(this);
+    }
+
+    public Expression transformExpression(ExpressionTransformer transformer) {
+        return this;
+    }
+
+    public String getText() {
+        return variable;
+    }
+    
+    public String getName() {
+        return variable;
+    }
+
+    public String toString() {
+        return super.toString() + "[variable: " + variable + (this.isDynamicTyped() ? "" : " type: " + getType()) + "]";
+    }
+
+    public Expression getInitialExpression() {
+        return null;
+    }
+
+    public boolean hasInitialExpression() {
+        return false;
+    }
+    
+    public boolean isInStaticContext() {
+        if (accessedVariable!=null && accessedVariable!=this) return accessedVariable.isInStaticContext();
+        return inStaticContext;
+    }
+    
+    public void setInStaticContext(boolean inStaticContext) {
+        this.inStaticContext = inStaticContext;
+    }
+
+    /**
+     * Set the type of this variable. If you call this method from an AST transformation and that
+     * the {@link #getAccessedVariable() accessed variable} is ({@link #isClosureSharedVariable() shared},
+     * this operation is unsafe and may lead to a verify error at compile time. Instead, set the type of
+     * the {@link #getAccessedVariable() accessed variable}
+     * @param cn the type to be set on this variable
+     */
+    public void setType(ClassNode cn){
+        super.setType(cn);
+        isDynamicTyped |= ClassHelper.DYNAMIC_TYPE==cn;
+    }
+    
+    public boolean isDynamicTyped() {
+        if (accessedVariable!=null && accessedVariable!=this) return accessedVariable.isDynamicTyped();
+        return isDynamicTyped;
+    }
+
+    /**
+     * Tells if this variable or the accessed variable is used in a closure context, like in the following
+     * example :
+     * <pre>def str = 'Hello'
+     * def cl = { println str }
+     * </pre>
+     * The "str" variable is closure shared.
+     * @return true if this variable is used in a closure
+     */
+    public boolean isClosureSharedVariable() {
+        if (accessedVariable!=null && accessedVariable!=this) return accessedVariable.isClosureSharedVariable();
+        return closureShare;
+    }
+
+    /**
+     * Use this method to tell if a variable is used in a closure, like in the following example:
+     * <pre>def str = 'Hello'
+     * def cl = { println str }
+     * </pre>
+     * The "str" variable is closure shared. The variable expression inside the closure references an
+     * accessed variable "str" which must have the closure shared flag set.
+     * @param inClosure tells if this variable is later referenced in a closure
+     */
+    public void setClosureSharedVariable(boolean inClosure) {
+        closureShare = inClosure;        
+    }
+
+    public int getModifiers() {
+        return modifiers;
+    }
+
+    /**
+     * For internal use only. This flag is used by compiler internals and should probably
+     * be converted to a node metadata in future.
+     * @param useRef
+     */
+    public void setUseReferenceDirectly(boolean useRef) {
+        this.useRef = useRef;        
+    }
+    
+    /**
+     * For internal use only. This flag is used by compiler internals and should probably
+     * be converted to a node metadata in future.
+     */
+    public boolean isUseReferenceDirectly() {
+        return useRef;
+    }
+    
+    public ClassNode getType() {
+        if (accessedVariable!=null && accessedVariable!=this) return accessedVariable.getType();
+        return super.getType();
+    }
+
+    /**
+     * Returns the type which was used when this variable expression was created. For example,
+     * {@link #getType()} may return a boxed type while this method would return the primitive type.
+     * @return the type which was used to define this variable expression
+     */
+    public ClassNode getOriginType() {
+        if (accessedVariable!=null && accessedVariable!=this) return accessedVariable.getOriginType();
+        return originType;
+    }
+
+    public boolean isThisExpression() {
+        return "this".equals(variable);
+    }
+
+    public boolean isSuperExpression() {
+        return "super".equals(variable);
+    }
+
+    public void setModifiers(int modifiers) {
+        this.modifiers = modifiers;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/expr/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/package.html b/src/main/java/org/codehaus/groovy/ast/expr/package.html
new file mode 100644
index 0000000..806854e
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/expr/package.html
@@ -0,0 +1,28 @@
+<!--
+
+     Licensed to the Apache Software Foundation (ASF) under one
+     or more contributor license agreements.  See the NOTICE file
+     distributed with this work for additional information
+     regarding copyright ownership.  The ASF licenses this file
+     to you under the Apache License, Version 2.0 (the
+     "License"); you may not use this file except in compliance
+     with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing,
+     software distributed under the License is distributed on an
+     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+     KIND, either express or implied.  See the License for the
+     specific language governing permissions and limitations
+     under the License.
+
+-->
+<html>
+  <head>
+    <title>package org.codehaus.groovy.ast.expr.*</title>
+  </head>
+  <body>
+    <p>AST nodes for Groovy expressions</p>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/package.html b/src/main/java/org/codehaus/groovy/ast/package.html
new file mode 100644
index 0000000..f8f132a
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/package.html
@@ -0,0 +1,28 @@
+<!--
+
+     Licensed to the Apache Software Foundation (ASF) under one
+     or more contributor license agreements.  See the NOTICE file
+     distributed with this work for additional information
+     regarding copyright ownership.  The ASF licenses this file
+     to you under the Apache License, Version 2.0 (the
+     "License"); you may not use this file except in compliance
+     with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing,
+     software distributed under the License is distributed on an
+     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+     KIND, either express or implied.  See the License for the
+     specific language governing permissions and limitations
+     under the License.
+
+-->
+<html>
+  <head>
+    <title>package org.codehaus.groovy.ast.*</title>
+  </head>
+  <body>
+    <p>Groovy AST nodes for the syntax of the language</p>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/AssertStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/AssertStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/AssertStatement.java
new file mode 100644
index 0000000..3f1fb33
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/AssertStatement.java
@@ -0,0 +1,66 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.expr.BooleanExpression;
+import org.codehaus.groovy.ast.expr.ConstantExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+
+/**
+ * Represents an assert statement.
+ * E.g.:
+ * <code>
+ * assert i != 0 : "should never be zero";
+ * </code>
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class AssertStatement extends Statement {
+
+    private BooleanExpression booleanExpression;
+    private Expression messageExpression;
+    
+    public AssertStatement(BooleanExpression booleanExpression) {
+        this(booleanExpression, ConstantExpression.NULL);
+    }
+    
+    public AssertStatement(BooleanExpression booleanExpression, Expression messageExpression) {
+        this.booleanExpression = booleanExpression;
+        this.messageExpression = messageExpression;
+    }
+    
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitAssertStatement(this);
+    }
+
+    public Expression getMessageExpression() {
+        return messageExpression;
+    }
+
+    public BooleanExpression getBooleanExpression() {
+        return booleanExpression;
+    }
+    public void setBooleanExpression(BooleanExpression booleanExpression) {
+        this.booleanExpression = booleanExpression;
+    }
+    public void setMessageExpression(Expression messageExpression) {
+        this.messageExpression = messageExpression;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/BlockStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/BlockStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/BlockStatement.java
new file mode 100644
index 0000000..5013726
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/BlockStatement.java
@@ -0,0 +1,117 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.VariableScope;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A list of statements and a scope. 
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class BlockStatement extends Statement {
+
+    private List<Statement> statements = new ArrayList<Statement>();
+    private VariableScope scope;
+    
+    public BlockStatement() {
+        this(new ArrayList<Statement>(), new VariableScope());
+    }
+
+    /**
+     * Creates a BlockStatement with a scope and children statements.
+     * @param statements
+     *      the statements. Do not pass null. If you do, no exception will occur,
+     *      but a NullPointerException will eventually occur later. Also, a reference
+     *      to the list is kept, so modifying the List later does effect this class.
+     * @param scope
+     *      the scope
+     */
+    public BlockStatement(List<Statement> statements, VariableScope scope) {
+        this.statements = statements;
+        this.scope = scope;
+    }
+    
+    /**
+     * Creates a BlockStatement with a scope and children statements.
+     * @param statements
+     *      the statements, which cannot be null or an exception occurs. No reference
+     *      to the array is held, so modifying the array later has no effect on this
+     *      class.
+     * @param scope
+     *      the scope
+     */
+    public BlockStatement(Statement[] statements, VariableScope scope) {
+        this.statements.addAll(Arrays.asList(statements));
+        this.scope = scope;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitBlockStatement(this);
+    }
+
+    public List<Statement> getStatements() {
+        return statements;
+    }
+
+    public void addStatement(Statement statement) {
+        statements.add(statement);
+    }
+
+    public void addStatements(List<Statement> listOfStatements) {
+        statements.addAll(listOfStatements);
+    }
+
+    public String toString() {
+        return super.toString() + statements;
+    }
+
+    public String getText() {
+        StringBuilder buffer = new StringBuilder("{ ");
+        boolean first = true;
+        for (Statement statement : statements) {
+            if (first) {
+                first = false;
+            }
+            else {
+                buffer.append("; ");
+            }
+            buffer.append(statement.getText());
+        }
+        buffer.append(" }");
+        return buffer.toString();
+    }
+
+    public boolean isEmpty() {
+        return statements.isEmpty();
+    }
+
+    public void setVariableScope(VariableScope scope) {
+        this.scope = scope;
+    }
+    
+    public VariableScope getVariableScope() {
+        return scope;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/BreakStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/BreakStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/BreakStatement.java
new file mode 100644
index 0000000..5257991
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/BreakStatement.java
@@ -0,0 +1,48 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+
+
+/**
+ * Represents a break statement in a switch or loop statement
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class BreakStatement extends Statement {
+
+    private String label;
+    
+    public BreakStatement() {
+        this(null);
+    }
+    
+    public BreakStatement(String label) {
+        this.label = label;
+    }
+    
+    public String getLabel() {
+        return label;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitBreakStatement(this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/CaseStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/CaseStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/CaseStatement.java
new file mode 100644
index 0000000..7c06e69
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/CaseStatement.java
@@ -0,0 +1,63 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.expr.Expression;
+
+
+/**
+ * Represents a case statement in a switch statement
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class CaseStatement extends Statement {
+
+    private Statement code;
+    private Expression expression;
+    
+    public CaseStatement(Expression expression, Statement code) {
+        this.expression = expression;
+        this.code = code;
+    }
+    
+    public Statement getCode() {
+        return code;
+    }
+
+    public void setCode(Statement code) {
+        this.code = code;
+    }
+
+    public Expression getExpression() {
+        return expression;
+    }
+    
+    public void setExpression(Expression e) {
+        expression=e;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitCaseStatement(this);
+    }
+    
+    public String toString() {
+        return super.toString() + "[expression: " + expression + "; code: " + code + "]";
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/CatchStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/CatchStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/CatchStatement.java
new file mode 100644
index 0000000..3f40957
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/CatchStatement.java
@@ -0,0 +1,61 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.Parameter;
+
+
+/**
+ * Represents a catch (Exception var) { } statement
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class CatchStatement extends Statement {
+
+    private Parameter variable;
+
+    private Statement code;
+    
+    public CatchStatement(Parameter variable, Statement code) {
+        this.variable = variable;
+        this.code = code;
+    }
+    
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitCatchStatement(this);
+    }
+    
+    public Statement getCode() {
+        return code;
+    }
+
+    public ClassNode getExceptionType() {
+        return variable.getType();
+    }
+
+    public Parameter getVariable() {
+        return variable;
+    }
+
+    public void setCode(Statement code) {
+        this.code = code;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/ContinueStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/ContinueStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/ContinueStatement.java
new file mode 100644
index 0000000..034dcf2
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/ContinueStatement.java
@@ -0,0 +1,48 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+
+
+/**
+ * Represents a continue statement in a loop statement
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class ContinueStatement extends Statement {
+
+    private String label;
+    
+    public ContinueStatement() {
+        this(null);
+    }
+    
+    public ContinueStatement(String label) {
+        this.label = label;
+    }
+    
+    public String getLabel() {
+        return label;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitContinueStatement(this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/DoWhileStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/DoWhileStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/DoWhileStatement.java
new file mode 100644
index 0000000..a7b518b
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/DoWhileStatement.java
@@ -0,0 +1,58 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.expr.BooleanExpression;
+
+/**
+ * Represents a do { ... } while (condition) loop in Groovy
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class DoWhileStatement extends Statement implements LoopingStatement {
+
+    private BooleanExpression booleanExpression;
+    private Statement loopBlock;
+    
+
+    public DoWhileStatement(BooleanExpression booleanExpression, Statement loopBlock) {
+        this.booleanExpression = booleanExpression;
+        this.loopBlock = loopBlock;
+    }
+    
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitDoWhileLoop(this);
+    }
+    
+    public BooleanExpression getBooleanExpression() {
+        return booleanExpression;
+    }
+
+    public Statement getLoopBlock() {
+        return loopBlock;
+    }
+    public void setBooleanExpression(BooleanExpression booleanExpression) {
+        this.booleanExpression = booleanExpression;
+    }
+
+    public void setLoopBlock(Statement loopBlock) {
+        this.loopBlock = loopBlock;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/EmptyStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/EmptyStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/EmptyStatement.java
new file mode 100644
index 0000000..2ef78af
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/EmptyStatement.java
@@ -0,0 +1,115 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+import org.codehaus.groovy.ast.ASTNode;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.NodeMetaDataHandler;
+
+import java.util.Map;
+
+/**
+ * Represents an empty statement
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+
+public class EmptyStatement extends Statement {
+    public static final EmptyStatement INSTANCE = new EmptyStatement();
+
+    /**
+     * use EmptyStatement.INSTANCE instead
+     */
+//    @Deprecated
+    private EmptyStatement() {
+        // org.spockframework.compiler.ConditionRewriter will create EmptyStatement via calling the constructor
+        // so we keep the constructor for the time being, but it will be removed finally.
+    }
+    
+    public void visit(GroovyCodeVisitor visitor) {
+    }
+
+    public boolean isEmpty() {
+        return true;
+    }
+
+    @Override
+    public void setStatementLabel(String label) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void addStatementLabel(String label) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void setLineNumber(int lineNumber) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void setColumnNumber(int columnNumber) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void setLastLineNumber(int lastLineNumber) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void setLastColumnNumber(int lastColumnNumber) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void setSourcePosition(ASTNode node) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void copyNodeMetaData(NodeMetaDataHandler other) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void setNodeMetaData(Object key, Object value) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public Object putNodeMetaData(Object key, Object value) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void removeNodeMetaData(Object key) {
+        throw createUnsupportedOperationException();
+    }
+
+    @Override
+    public void setMetaDataMap(Map<?, ?> metaDataMap) {
+        throw createUnsupportedOperationException();
+    }
+
+    private UnsupportedOperationException createUnsupportedOperationException() {
+        return new UnsupportedOperationException("EmptyStatement.INSTANCE is immutable");
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/ExpressionStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/ExpressionStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/ExpressionStatement.java
new file mode 100644
index 0000000..c6376b2
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/ExpressionStatement.java
@@ -0,0 +1,61 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.expr.Expression;
+
+
+/**
+ * A simple statement such as a method call where the return value is ignored
+ *
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class ExpressionStatement extends Statement {
+
+    private Expression expression;
+
+    public ExpressionStatement(Expression expression) {
+        if (expression == null) {
+            throw new IllegalArgumentException("expression cannot be null");
+        }
+        this.expression = expression;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitExpressionStatement(this);
+    }
+
+    public Expression getExpression() {
+        return expression;
+    }
+
+    public void setExpression(Expression expression) {
+        this.expression = expression;
+    }
+
+    public String getText() {
+        return expression.getText();
+    }
+
+    public String toString() {
+        return super.toString() + "[expression:" + expression + "]";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/ForStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/ForStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/ForStatement.java
new file mode 100644
index 0000000..072ee6e
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/ForStatement.java
@@ -0,0 +1,83 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.Parameter;
+import org.codehaus.groovy.ast.VariableScope;
+import org.codehaus.groovy.ast.expr.Expression;
+
+/**
+ * Represents a standard for loop in Groovy
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class ForStatement extends Statement implements LoopingStatement {
+    public static final Parameter FOR_LOOP_DUMMY = new Parameter(ClassHelper.OBJECT_TYPE,"forLoopDummyParameter");
+
+    private Parameter variable;
+    private Expression collectionExpression;
+    private Statement loopBlock;
+    private VariableScope scope;
+    
+
+    public ForStatement(Parameter variable, Expression collectionExpression, Statement loopBlock) {
+        this.variable = variable; 
+        this.collectionExpression = collectionExpression;
+        this.loopBlock = loopBlock;
+    }
+    
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitForLoop(this);
+    }
+    
+    public Expression getCollectionExpression() {
+        return collectionExpression;
+    }
+
+    public Statement getLoopBlock() {
+        return loopBlock;
+    }
+
+    public Parameter getVariable() {
+        return variable;
+    }
+    
+    public ClassNode getVariableType() {
+        return variable.getType();
+    }
+    
+    public void setCollectionExpression(Expression collectionExpression) {
+        this.collectionExpression = collectionExpression;
+    }
+
+    public void setVariableScope(VariableScope variableScope) {
+       scope = variableScope;        
+    }
+
+    public VariableScope getVariableScope() {
+        return scope;
+    }
+
+    public void setLoopBlock(Statement loopBlock) {
+        this.loopBlock = loopBlock;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/IfStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/IfStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/IfStatement.java
new file mode 100644
index 0000000..3f614cc
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/IfStatement.java
@@ -0,0 +1,69 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.expr.BooleanExpression;
+
+/**
+ * Represents an if (condition) { ... } else { ... } statement in Groovy
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class IfStatement extends Statement {
+
+    private BooleanExpression booleanExpression;
+    private Statement ifBlock;
+    private Statement elseBlock;
+    
+
+    public IfStatement(BooleanExpression booleanExpression, Statement ifBlock, Statement elseBlock) {
+        this.booleanExpression = booleanExpression;
+        this.ifBlock = ifBlock;
+        this.elseBlock = elseBlock;
+    }
+    
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitIfElse(this);
+    }
+    
+    public BooleanExpression getBooleanExpression() {
+        return booleanExpression;
+    }
+    
+    public Statement getIfBlock() {
+        return ifBlock;
+    }
+
+    public Statement getElseBlock() {
+        return elseBlock;
+    }
+
+    public void setBooleanExpression(BooleanExpression booleanExpression) {
+        this.booleanExpression = booleanExpression;
+    }
+
+    public void setIfBlock(Statement statement) {
+        ifBlock = statement;
+    }
+
+    public void setElseBlock(Statement statement) {
+        elseBlock = statement;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/LoopingStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/LoopingStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/LoopingStatement.java
new file mode 100644
index 0000000..4568103
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/LoopingStatement.java
@@ -0,0 +1,38 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+/**
+* This is an AST Node that provides some sort of looping mechanism. Typically
+* in the form of a block that will be executed repeatedly. 
+* DoWhileStatements, WhileStatements, and ForStatements are all examples of LoopingStatements. 
+*
+* @author Hamlet D'Arcy
+*/ 
+public interface LoopingStatement {
+
+     /**
+     * Gets the loop block. 
+     */
+     Statement getLoopBlock();
+     /**
+     * Sets the loop block. 
+     */
+     void setLoopBlock(Statement loopBlock);
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/ReturnStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/ReturnStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/ReturnStatement.java
new file mode 100644
index 0000000..9e08ebd
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/ReturnStatement.java
@@ -0,0 +1,72 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.expr.ConstantExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+
+/**
+ * A return statement
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class ReturnStatement extends Statement {
+    /**
+     * Only used for synthetic return statements emitted by the compiler.
+     * For comparisons use isReturningNullOrVoid() instead.
+     */
+    public static final ReturnStatement RETURN_NULL_OR_VOID = new ReturnStatement(ConstantExpression.NULL);
+
+    private Expression expression;
+    
+    public ReturnStatement(ExpressionStatement statement) {
+        this(statement.getExpression());
+        setStatementLabel(statement.getStatementLabel());
+    }
+    
+    public ReturnStatement(Expression expression) {
+        this.expression = expression;
+    }
+    
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitReturnStatement(this);
+    }
+
+    public Expression getExpression() {
+        return expression;
+    }
+
+    public String getText() {
+        return "return " + expression.getText();
+    }
+
+    public void setExpression(Expression expression) {
+        this.expression = expression;
+    }
+
+    public boolean isReturningNullOrVoid() {
+        return expression instanceof ConstantExpression
+            && ((ConstantExpression)expression).isNullExpression();
+    }
+
+    public String toString() {
+        return super.toString() + "[expression:" + expression + "]";
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/Statement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/Statement.java b/src/main/java/org/codehaus/groovy/ast/stmt/Statement.java
new file mode 100644
index 0000000..80dbc4d
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/Statement.java
@@ -0,0 +1,64 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+import org.codehaus.groovy.ast.ASTNode;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Base class for any statement
+ *
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class Statement extends ASTNode {
+
+    private List<String> statementLabels;
+
+    public Statement() {
+        statementLabels = null;
+    }
+
+    public List<String> getStatementLabels() {
+        return statementLabels;
+    }
+
+    // TODO @Deprecated
+    public String getStatementLabel() {
+        // last label by default which is added first by APP
+        return statementLabels == null ? null : statementLabels.get(0);
+    }
+
+    // TODO @Deprecated
+    public void setStatementLabel(String label) {
+        if (statementLabels == null) statementLabels = new LinkedList<String>();
+        statementLabels.add(label);
+    }
+
+    public void addStatementLabel(String label) {
+        if (statementLabels == null) statementLabels = new LinkedList<String>();
+        statementLabels.add(label);
+    }
+
+    public boolean isEmpty() {
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/SwitchStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/SwitchStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/SwitchStatement.java
new file mode 100644
index 0000000..bad0194
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/SwitchStatement.java
@@ -0,0 +1,91 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.expr.Expression;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a switch (object) { case value: ... case [1, 2, 3]: ...  default: ... } statement in Groovy.
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class SwitchStatement extends Statement {
+
+    private Expression expression;
+    private List<CaseStatement> caseStatements = new ArrayList<CaseStatement>();
+    private Statement defaultStatement;
+    
+
+    public SwitchStatement(Expression expression) {
+        this(expression, EmptyStatement.INSTANCE);
+    }
+
+    public SwitchStatement(Expression expression, Statement defaultStatement) {
+        this.expression = expression;
+        this.defaultStatement = defaultStatement;
+    }
+
+    public SwitchStatement(Expression expression, List<CaseStatement> caseStatements, Statement defaultStatement) {
+        this.expression = expression;
+        this.caseStatements = caseStatements;
+        this.defaultStatement = defaultStatement;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitSwitch(this);
+    }
+    
+    public List<CaseStatement> getCaseStatements() {
+        return caseStatements;
+    }
+
+    public Expression getExpression() {
+        return expression;
+    }
+
+    public void setExpression(Expression e) {
+        expression=e;
+    }
+    
+    public Statement getDefaultStatement() {
+        return defaultStatement;
+    }
+
+    public void setDefaultStatement(Statement defaultStatement) {
+        this.defaultStatement = defaultStatement;
+    }
+
+    public void addCase(CaseStatement caseStatement) {
+        caseStatements.add(caseStatement);
+    }
+
+    /**
+     * @return the case statement of the given index or null
+     */
+    public CaseStatement getCaseStatement(int idx) {
+        if (idx >= 0 && idx < caseStatements.size()) {
+            return caseStatements.get(idx);
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/SynchronizedStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/SynchronizedStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/SynchronizedStatement.java
new file mode 100644
index 0000000..1fd3e5c
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/SynchronizedStatement.java
@@ -0,0 +1,58 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.expr.Expression;
+
+
+/**
+ * Represents a synchronized statement
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class SynchronizedStatement extends Statement {
+
+    private Statement code;
+    private Expression expression;
+    
+    public SynchronizedStatement(Expression expression, Statement code) {
+        this.expression = expression;
+        this.code = code;
+    }
+    
+    public Statement getCode() {
+        return code;
+    }
+    
+    public void setCode(Statement statement) {
+        code = statement;
+    }
+
+    public Expression getExpression() {
+        return expression;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitSynchronizedStatement(this);
+    }
+    public void setExpression(Expression expression) {
+        this.expression = expression;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/ThrowStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/ThrowStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/ThrowStatement.java
new file mode 100644
index 0000000..a217840
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/ThrowStatement.java
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.expr.Expression;
+
+
+/**
+ * Represents a throw statement
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class ThrowStatement extends Statement {
+
+    private Expression expression;
+    
+    public ThrowStatement(Expression expression) {
+        this.expression = expression;
+    }
+    
+    public Expression getExpression() {
+        return expression;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitThrowStatement(this);
+    }
+    public void setExpression(Expression expression) {
+        this.expression = expression;
+    }
+
+    @Override
+    public String getText() {
+        return "throw " + expression.getText();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/TryCatchStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/TryCatchStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/TryCatchStatement.java
new file mode 100644
index 0000000..f05460f
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/TryCatchStatement.java
@@ -0,0 +1,108 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.expr.DeclarationExpression;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a try { ... } catch () finally {} statement in Groovy
+ * 
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class TryCatchStatement extends Statement {
+
+    private Statement tryStatement;
+    private List<ExpressionStatement> resourceStatements = new ArrayList<ExpressionStatement>();
+    private List<CatchStatement> catchStatements = new ArrayList<CatchStatement>();
+    private Statement finallyStatement;
+    
+
+    public TryCatchStatement(Statement tryStatement, Statement finallyStatement) {
+        this.tryStatement = tryStatement;
+        this.finallyStatement = finallyStatement;
+    }
+    
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitTryCatchFinally(this);
+    }
+
+    public List<ExpressionStatement> getResourceStatements() {
+        return resourceStatements;
+    }
+
+    public List<CatchStatement> getCatchStatements() {
+        return catchStatements;
+    }
+
+    public Statement getFinallyStatement() {
+        return finallyStatement;
+    }
+
+    public Statement getTryStatement() {
+        return tryStatement;
+    }
+
+    public void addResource(ExpressionStatement resourceStatement) {
+        if (!(resourceStatement.getExpression() instanceof DeclarationExpression)) {
+            throw new IllegalArgumentException("resourceStatement should be a variable declaration statement");
+        }
+
+        resourceStatements.add(resourceStatement);
+    }
+
+    public void addCatch(CatchStatement catchStatement) {
+        catchStatements.add(catchStatement);
+    }
+
+    /**
+     * @return the catch statement of the given index or null
+     */
+    public CatchStatement getCatchStatement(int idx) {
+        if (idx >= 0 && idx < catchStatements.size()) {
+            return catchStatements.get(idx);
+        }
+        return null;
+    }
+
+    /**
+     * @return the resource statement of the given index or null
+     */
+    public ExpressionStatement getResourceStatement(int idx) {
+        if (idx >= 0 && idx < resourceStatements.size()) {
+            return resourceStatements.get(idx);
+        }
+        return null;
+    }
+
+    public void setTryStatement(Statement tryStatement) {
+        this.tryStatement = tryStatement;
+    }
+
+    public void setCatchStatement(int idx, CatchStatement catchStatement) {
+        catchStatements.set(idx, catchStatement);
+    }
+
+    public void setFinallyStatement(Statement finallyStatement) {
+        this.finallyStatement = finallyStatement;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/WhileStatement.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/WhileStatement.java b/src/main/java/org/codehaus/groovy/ast/stmt/WhileStatement.java
new file mode 100644
index 0000000..e325481
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/WhileStatement.java
@@ -0,0 +1,59 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.stmt;
+
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.expr.BooleanExpression;
+
+/**
+ * Represents a while (condition) { ... } loop in Groovy
+ *
+ * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
+ */
+public class WhileStatement extends Statement implements LoopingStatement {
+
+    private BooleanExpression booleanExpression;
+    private Statement loopBlock;
+
+
+    public WhileStatement(BooleanExpression booleanExpression, Statement loopBlock) {
+        this.booleanExpression = booleanExpression;
+        this.loopBlock = loopBlock;
+    }
+
+    public void visit(GroovyCodeVisitor visitor) {
+        visitor.visitWhileLoop(this);
+    }
+
+    public BooleanExpression getBooleanExpression() {
+        return booleanExpression;
+    }
+
+    public Statement getLoopBlock() {
+        return loopBlock;
+    }
+
+    public void setBooleanExpression(BooleanExpression booleanExpression) {
+        this.booleanExpression = booleanExpression;
+    }
+
+    public void setLoopBlock(Statement loopBlock) {
+        this.loopBlock = loopBlock;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/stmt/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/stmt/package.html b/src/main/java/org/codehaus/groovy/ast/stmt/package.html
new file mode 100644
index 0000000..8226776
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/stmt/package.html
@@ -0,0 +1,28 @@
+<!--
+
+     Licensed to the Apache Software Foundation (ASF) under one
+     or more contributor license agreements.  See the NOTICE file
+     distributed with this work for additional information
+     regarding copyright ownership.  The ASF licenses this file
+     to you under the Apache License, Version 2.0 (the
+     "License"); you may not use this file except in compliance
+     with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing,
+     software distributed under the License is distributed on an
+     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+     KIND, either express or implied.  See the License for the
+     specific language governing permissions and limitations
+     under the License.
+
+-->
+<html>
+  <head>
+    <title>package org.codehaus.groovy.ast.stmt.*</title>
+  </head>
+  <body>
+    <p>AST nodes for Groovy statements</p>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/tools/BeanUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/BeanUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/BeanUtils.java
new file mode 100644
index 0000000..32d4a81
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/tools/BeanUtils.java
@@ -0,0 +1,120 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.tools;
+
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.MethodNode;
+import org.codehaus.groovy.ast.PropertyNode;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static java.beans.Introspector.decapitalize;
+
+public class BeanUtils {
+    static final String GET_PREFIX = "get";
+    static final String IS_PREFIX = "is";
+
+    /**
+     * Get all properties including JavaBean pseudo properties matching getter conventions.
+     *
+     * @param type the ClassNode
+     * @param includeSuperProperties whether to include super properties
+     * @param includeStatic whether to include static properties
+     * @param includePseudoGetters whether to include JavaBean pseudo (getXXX/isYYY) properties with no corresponding field
+     * @return the list of found property nodes
+     */
+    public static List<PropertyNode> getAllProperties(ClassNode type, boolean includeSuperProperties, boolean includeStatic, boolean includePseudoGetters) {
+        // TODO add generics support so this can be used for @EAHC
+        // TODO add an includePseudoSetters so this can be used for @TupleConstructor
+        ClassNode node = type;
+        List<PropertyNode> result = new ArrayList<PropertyNode>();
+        Set<String> names = new HashSet<String>();
+        while (node != null) {
+            addExplicitProperties(node, result, names, includeStatic);
+            if (!includeSuperProperties) break;
+            node = node.getSuperClass();
+        }
+        addPseudoProperties(type, result, names, includeStatic, includePseudoGetters, includeSuperProperties);
+        return result;
+    }
+
+    private static void addExplicitProperties(ClassNode cNode, List<PropertyNode> result, Set<String> names, boolean includeStatic) {
+        for (PropertyNode pNode : cNode.getProperties()) {
+            if (includeStatic || !pNode.isStatic()) {
+                if (!names.contains(pNode.getName())) {
+                    result.add(pNode);
+                    names.add(pNode.getName());
+                }
+            }
+        }
+    }
+
+    private static void addPseudoProperties(ClassNode cNode, List<PropertyNode> result, Set<String> names, boolean includeStatic, boolean includePseudoGetters, boolean includeSuperProperties) {
+        if (!includePseudoGetters) return;
+        List<MethodNode> methods = cNode.getAllDeclaredMethods();
+        ClassNode node = cNode.getSuperClass();
+        if (includeSuperProperties) {
+            while (node != null) {
+                for (MethodNode next : node.getAllDeclaredMethods()) {
+                    if (!next.isPrivate()) {
+                        methods.add(next);
+                    }
+                }
+                node = node.getSuperClass();
+            }
+        }
+        for (MethodNode mNode : methods) {
+            if (!includeStatic && mNode.isStatic()) continue;
+            String name = mNode.getName();
+            if ((name.length() <= 3 && !name.startsWith(IS_PREFIX)) || name.equals("getClass") || name.equals("getMetaClass") || name.equals("getDeclaringClass")) {
+                // Optimization: skip invalid propertyNames
+                continue;
+            }
+            if (mNode.getDeclaringClass() != cNode && mNode.isPrivate()) {
+                // skip private super methods
+                continue;
+            }
+            int paramCount = mNode.getParameters().length;
+            ClassNode returnType = mNode.getReturnType();
+            if (paramCount == 0) {
+                if (name.startsWith(GET_PREFIX)) {
+                    // Simple getter
+                    String propName = decapitalize(name.substring(3));
+                    if (!names.contains(propName)) {
+                        result.add(new PropertyNode(propName, mNode.getModifiers(), returnType, cNode, null, mNode.getCode(), null));
+                        names.add(propName);
+                    }
+                } else {
+                    if (name.startsWith(IS_PREFIX) && returnType.equals(ClassHelper.boolean_TYPE)) {
+                        // boolean getter
+                        String propName = decapitalize(name.substring(2));
+                        if (!names.contains(propName)) {
+                            names.add(propName);
+                            result.add(new PropertyNode(propName, mNode.getModifiers(), returnType, cNode, null, mNode.getCode(), null));
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/tools/ClassNodeUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/ClassNodeUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/ClassNodeUtils.java
new file mode 100644
index 0000000..5c43586
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/tools/ClassNodeUtils.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.codehaus.groovy.ast.tools;
+
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.MethodNode;
+import org.codehaus.groovy.ast.PropertyNode;
+import org.codehaus.groovy.ast.expr.Expression;
+
+import java.util.Map;
+
+@Deprecated
+public class ClassNodeUtils {
+    @Deprecated
+    public static void addInterfaceMethods(ClassNode cNode, Map<String, MethodNode> methodsMap) {
+        org.apache.groovy.ast.tools.ClassNodeUtils.addDeclaredMethodsFromInterfaces(cNode, methodsMap);
+    }
+
+    @Deprecated
+    public static Map<String, MethodNode> getDeclaredMethodMapsFromInterfaces(ClassNode cNode) {
+        return org.apache.groovy.ast.tools.ClassNodeUtils.getDeclaredMethodsFromInterfaces(cNode);
+    }
+
+    @Deprecated
+    public static void addDeclaredMethodMapsFromSuperInterfaces(ClassNode cNode, Map<String, MethodNode> methodsMap) {
+        org.apache.groovy.ast.tools.ClassNodeUtils.addDeclaredMethodsFromAllInterfaces(cNode, methodsMap);
+    }
+
+    @Deprecated
+    public static boolean hasPossibleStaticMethod(ClassNode cNode, String name, Expression arguments, boolean trySpread) {
+        return org.apache.groovy.ast.tools.ClassNodeUtils.hasPossibleStaticMethod(cNode, name, arguments, trySpread);
+    }
+
+    @Deprecated
+    public static boolean hasPossibleStaticProperty(ClassNode cNode, String methodName) {
+        return org.apache.groovy.ast.tools.ClassNodeUtils.hasPossibleStaticProperty(cNode, methodName);
+    }
+
+    @Deprecated
+    public static String getPropNameForAccessor(String accessorName) {
+        return org.apache.groovy.ast.tools.ClassNodeUtils.getPropNameForAccessor(accessorName);
+    }
+
+    @Deprecated
+    public static boolean isValidAccessorName(String accessorName) {
+        return org.apache.groovy.ast.tools.ClassNodeUtils.isValidAccessorName(accessorName);
+    }
+
+    @Deprecated
+    public static boolean hasStaticProperty(ClassNode cNode, String propName) {
+        return org.apache.groovy.ast.tools.ClassNodeUtils.hasStaticProperty(cNode, propName);
+    }
+
+    @Deprecated
+    public static PropertyNode getStaticProperty(ClassNode cNode, String propName) {
+        return org.apache.groovy.ast.tools.ClassNodeUtils.getStaticProperty(cNode, propName);
+    }
+
+    @Deprecated
+    public static boolean isInnerClass(ClassNode cNode) {
+        return org.apache.groovy.ast.tools.ClassNodeUtils.isInnerClass(cNode);
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/b25d0e55/src/main/java/org/codehaus/groovy/ast/tools/ClosureUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/ClosureUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/ClosureUtils.java
new file mode 100644
index 0000000..06d4995
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/ast/tools/ClosureUtils.java
@@ -0,0 +1,69 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.ast.tools;
+
+import groovy.lang.Closure;
+import org.codehaus.groovy.ast.expr.ClosureExpression;
+import org.codehaus.groovy.control.io.ReaderSource;
+/**
+ * Handy methods when working with Closure AST data structures.
+ */
+
+public class ClosureUtils {
+
+    /**
+     * Converts a ClosureExpression into the String source.
+     *
+     * @param readerSource a source
+     * @param expression a closure. Can't be null
+     * @return the source the closure was created from
+     * @throws java.lang.IllegalArgumentException when expression is null
+     * @throws java.lang.Exception when closure can't be read from source
+     */
+    public static String convertClosureToSource(ReaderSource readerSource, ClosureExpression expression) throws Exception {
+        String source = GeneralUtils.convertASTToSource(readerSource, expression);
+        if (!source.startsWith("{")) {
+            throw new Exception("Error converting ClosureExpression into source code. Closures must start with {. Found: " + source);
+        }
+        return source;
+    }
+
+    /**
+     * Does the Closure have a single char-like (char or Character) argument.
+     * @param c a Closure
+     * @return true if it has exactly one argument and the type is char or Character
+     */
+    public static boolean hasSingleCharacterArg(Closure c) {
+        if (c.getMaximumNumberOfParameters() != 1) return false;
+        String typeName = c.getParameterTypes()[0].getName();
+        return typeName.equals("char") || typeName.equals("java.lang.Character");
+    }
+
+    /**
+     * Does the Closure have a single String argument.
+     * @param c a Closure
+     * @return true if it has exactly one argument and the type is String
+     */
+    public static boolean hasSingleStringArg(Closure c) {
+        if (c.getMaximumNumberOfParameters() != 1) return false;
+        String typeName = c.getParameterTypes()[0].getName();
+        return typeName.equals("java.lang.String");
+    }
+
+}