@@ -1318,14 +1339,15 @@
         {
             if (Boolean.TRUE.equals(returnValue))
             {
-                return node.jjtGetChild(1).jjtAccept(this, data);                
-            } else 
+                return node.jjtGetChild(1).jjtAccept(this, data);
+            } else
             {
                 return node.jjtGetChild(2).jjtAccept(this, data);
             }
-        } else 
+        } else
         {
-            throw generateProcessingException(new IllegalArgumentException("condition of hook expression is not a boolean expression"), node);
+            throw generateProcessingException(new IllegalArgumentException(
+                    "condition of hook expression is not a boolean expression"), node);
         }
     }
 
@@ -1541,8 +1563,8 @@
                 block = (SimpleNode) node.jjtGetChild(i++);
             } while (!(block instanceof AstBlock) && i < n);
         }
-        return getCurrentContext().getFunctions().put((String) declarator.getData(),
-                new JxpUserDefinedFunction((AstFormalParameters) declarator.jjtGetChild(0), (AstBlock) block));
+        return getCurrentContext().getUserDefinedFunctions().put((String) declarator.getData(),
+                new JxpUserDefinedFunction((SimpleNode) declarator.jjtGetChild(0), (AstBlock) block));
     }
 
     /**
@@ -1870,49 +1892,48 @@
     public Object visit(AstSwitchStatement node, Object data) throws Exception
     {
         Object switchValue = node.jjtGetChild(0).jjtAccept(this, data); //resolve the value first
-        if (switchValue==null)
+        if (switchValue == null)
         {
             throw generateProcessingException(new IllegalArgumentException("Switch value cannot be null"), node);
         }
         int n = node.jjtGetNumChildren();
         boolean matchCase = false;
-        for (int i=1; i<n; i++)
-        {            
-            AstCase case_ = (AstCase)node.jjtGetChild(i);
+        for (int i = 1; i < n; i++)
+        {
+            AstCase case_ = (AstCase) node.jjtGetChild(i);
             int caseChildren = case_.jjtGetNumChildren();
             if (!matchCase) //haven't match before
             {//try to match the case
-                if (caseChildren==1)
+                if (caseChildren == 1)
                 {//must be the default: calse
                     matchCase = true;
-                } else 
+                } else
                 {
-	                Object caseValue = case_.jjtGetChild(0).jjtAccept(this, null);
-	                if (caseValue==null)
-	                {
-	                    throw generateProcessingException(new IllegalArgumentException("Switch case value cannot be null"), case_);
-	                }
-	                if (switchValue.equals(caseValue))
-	                {
-	                    matchCase = true;
-	                }
+                    Object caseValue = case_.jjtGetChild(0).jjtAccept(this, null);
+                    if (caseValue == null)
+                    {
+                        throw generateProcessingException(new IllegalArgumentException("Switch case value cannot be null"), case_);
+                    }
+                    if (switchValue.equals(caseValue))
+                    {
+                        matchCase = true;
+                    }
                 }
             }
-             
             if (matchCase)
-            {                
-                Object obj = case_.jjtGetChild(caseChildren-1).jjtAccept(this, null);
-	            if (obj==Control.BREAK)
-	            {
-	                return null;
-	            } else if (obj instanceof Control)
-	            {//either return or exit
-	                return obj;
-	            } //else just continue to fall through	            
+            {
+                Object obj = case_.jjtGetChild(caseChildren - 1).jjtAccept(this, null);
+                if (obj == Control.BREAK)
+                {
+                    return null;
+                } else if (obj instanceof Control)
+                {//either return or exit
+                    return obj;
+                } //else just continue to fall through	            
             }
         }
         return null;
-    }        
+    }
 
     /**
      * @see jxp.parser.JxpParserVisitor#visit(jxp.parser.AstSynchronizedStatement, java.lang.Object)
@@ -2213,7 +2234,76 @@
      * {@inheritDoc}
      */
     public Object visit(AstExitStatement node, Object data) throws Exception
-    {        
+    {
         return Control.EXIT;
     }
+
+    /** 
+     * {@inheritDoc}
+     */
+    public Object visit(AstStaticImportDeclaration node, Object data) throws Exception
+    {
+        AstName name = (AstName) node.jjtGetChild(0);
+        String className = toDottedName(name);
+        Class c = getCurrentContext().resolveClass(className);
+        if (c == null)
+        {
+            throw generateProcessingException(new IllegalArgumentException("Cannot resolve class " + className), node);
+        }
+        getCurrentContext().addStaticImport(StaticImportUtils.getStaticImport(c));
+        return null;
+    }
+
+    /** 
+     * {@inheritDoc}
+     */
+    public Object visit(AstVariableParameters node, Object data) throws Exception
+    {
+        throw generateProcessingException(new UnsupportedOperationException("variable parameters is not yet supported"), node);
+    }
+
+    /** 
+     * {@inheritDoc}
+     */
+    public Object visit(AstEnhancedForStatement node, Object data) throws Exception
+    {
+        JxpProcessingContext context = getCurrentContext();
+        String variable = (String)node.getData();
+        Node statements = node.jjtGetChild(2);
+        Object colObj = node.jjtGetChild(1).jjtAccept(this, data);
+        
+        if (colObj instanceof Collection)
+        {//must be
+            Object returnValue = null;
+            Iterator it = ((Collection)colObj).iterator();
+            int newscope = context.getNametableStack().newScope();            
+            try {
+                declareVariable(variable, null);
+	            while (it.hasNext())
+	            {
+	                assignVariable(variable, it.next());
+	                returnValue = statements.jjtAccept(this, data);
+	                if (returnValue == Control.CONTINUE)
+	                {
+	                    returnValue = null;
+	                    //let it pass
+	                } else if (returnValue == Control.BREAK)
+	                {
+	                    returnValue = null;
+	                    break;
+	                } else if (returnValue instanceof Control)
+	                { //must be return w/wo object
+	                    break;
+	                }
+	            }
+	            return returnValue;
+            } finally 
+            {
+                context.getNametableStack().closeScope(newscope);
+            }
+        } else {
+            throw generateProcessingException(new IllegalArgumentException(
+                    "Expression for enhanced for loop must be collection, get " + colObj + " instead"), node);
+        }        
+    }
 }
