[jboss-svn-commits] JBL Code SVN: r21110 - in labs/jbosstm/workspace/adinn: orchestration and 17 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Jul 18 09:23:49 EDT 2008


Author: adinn
Date: 2008-07-18 09:23:49 -0400 (Fri, 18 Jul 2008)
New Revision: 21110

Added:
   labs/jbosstm/workspace/adinn/orchestration/
   labs/jbosstm/workspace/adinn/orchestration/build.xml
   labs/jbosstm/workspace/adinn/orchestration/dd/
   labs/jbosstm/workspace/adinn/orchestration/dd/META-INF/
   labs/jbosstm/workspace/adinn/orchestration/dd/META-INF/MANIFEST.MF
   labs/jbosstm/workspace/adinn/orchestration/dd/grammar/
   labs/jbosstm/workspace/adinn/orchestration/dd/grammar/ECAGrammar.g
   labs/jbosstm/workspace/adinn/orchestration/dd/grammar/ECAToken.g
   labs/jbosstm/workspace/adinn/orchestration/ext/
   labs/jbosstm/workspace/adinn/orchestration/ext/antlr-2.7.7.jar
   labs/jbosstm/workspace/adinn/orchestration/ext/antlr-3.0.1.jar
   labs/jbosstm/workspace/adinn/orchestration/ext/antlr-runtime-3.0.1.jar
   labs/jbosstm/workspace/adinn/orchestration/ext/asm-all-3.0.jar
   labs/jbosstm/workspace/adinn/orchestration/ext/junit.jar
   labs/jbosstm/workspace/adinn/orchestration/ext/stringtemplate-3.1b1.jar
   labs/jbosstm/workspace/adinn/orchestration/src/
   labs/jbosstm/workspace/adinn/orchestration/src/TestParse.java
   labs/jbosstm/workspace/adinn/orchestration/src/TestRule.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/agent/
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/agent/Main.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/agent/Transformer.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/annotation/
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/annotation/EventHandler.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/annotation/EventHandlerClass.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/Action.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/Condition.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/Event.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/binding/
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/binding/Binding.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/binding/Bindings.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ArithmeticExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ArrayExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/BinaryOperExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/BitExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/BooleanExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ComparisonExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ConditionalEvalExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/DollarExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/Expression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ExpressionHelper.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/FieldExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/LogicalExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/MethodExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/NotExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/NumericLiteral.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/OperExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/PlusExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/StaticExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/StringLiteral.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/StringPlusExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/TernaryOperExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/TwiddleExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/UnaryOperExpression.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/Variable.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/grammar/
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/grammar/ECAGrammarParser.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/grammar/ECATokenLexer.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/type/
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/type/Type.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/type/TypeGroup.java
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/test/
   labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/test/HandlerClass.java
Log:
partial build of test orchestration tool -- still missing rule type checker and code generator

Added: labs/jbosstm/workspace/adinn/orchestration/build.xml
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/build.xml	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/build.xml	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,161 @@
+<!--
+  JBoss, Home of Professional Open Source
+  Copyright 2007, Red Hat Middleware LLC, and individual contributors
+  as indicated by the @author tags.
+  See the copyright.txt in the distribution for a full listing
+  of individual contributors.
+  This copyrighted material is made available to anyone wishing to use,
+  modify, copy, or redistribute it subject to the terms and conditions
+  of the GNU General Public License, v. 2.0.
+  This program is distributed in the hope that it will be useful, but WITHOUT A
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+  PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+  You should have received a copy of the GNU General Public License,
+  v. 2.0 along with this distribution; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+  MA  02110-1301, USA.
+
+  (C) 2007,
+  @author JBoss Inc.
+-->
+
+<project name="orchestration" default="jar" basedir=".">
+
+    <!-- the directory in which your installed app server resides -->
+    <property environment="env"/>
+
+    <!-- pick up the asm.org code transform library -->
+    <property name="asm.home" value="${env.HOME}/Download/asm/asm-3.0/output/dist/lib/all"/>
+    <property name="asm.jar" value="asm-all-3.0.jar"/>
+
+    <condition property="jboss.home" value="${env.JBOSS_HOME}">
+      <isset property="env.JBOSS_HOME"/>
+    </condition>
+
+    <fail unless="jboss.home">
+The JBoss installation directory must be specified with the JBOSS_HOME environment variable or the jboss.home property.
+    </fail>
+
+    <property name="src.dir"           value="src"/>
+    <property name="dd.dir"            value="dd"/>
+    <property name="dd.grammar.dir"    value="${dd.dir}/grammar"/>
+    <property name="ext.lib.dir" value="ext"/>
+    <property name="build.dir"         value="build"/>
+    <property name="build.classes.dir" value="${build.dir}/classes"/>
+    <property name="build.lib.dir"     value="${build.dir}/lib"/>
+
+    <property name="ext.antlr.jars" value="antlr-3.0.1.jar antlr-2.7.7.jar antlr-runtime-3.0.1.jar stringtemplate-3.1b1.jar"/>
+
+    <!-- enable debugging of XTS service code -->
+
+    <property name="javac.debug" value="on"/>
+
+    <target name="init">
+        <delete dir="${build.dir}"/>
+        <mkdir dir="${build.dir}"/>
+        <mkdir dir="${build.classes.dir}"/>
+        <mkdir dir="${build.lib.dir}"/>
+        <mkdir dir="${build.classes.dir}/META-INF"/>
+    </target>
+
+    <!-- ??? parser is not automatically remade ??? -->
+    <target name="parser" depends="init">
+        <java classname="org.antlr.Tool">
+            <classpath>
+                <fileset dir="${ext.lib.dir}" includes="${ext.antlr.jars}"/>
+            </classpath>
+            <arg value="${dd.grammar.dir}/ECAToken.g"/>
+        </java>
+        
+        <java classname="org.antlr.Tool">
+            <classpath>
+                <fileset dir="${ext.lib.dir}" includes="${ext.antlr.jars}"/>
+            </classpath>
+            <arg value="-lib" />
+            <arg value="${dd.grammar.dir}"/>
+            <arg value="${dd.grammar.dir}/ECAGrammar.g"/>
+        </java>
+        <copy file="${dd.grammar.dir}/ECATokenLexer.java"
+            tofile="${src.dir}/org/jboss/jbossts/orchestration/rule/grammar/ECATokenLexer.java"/>
+        <copy file="${dd.grammar.dir}/ECAGrammarParser.java"
+            tofile="${src.dir}/org/jboss/jbossts/orchestration/rule/grammar/ECAGrammarParser.java"/>
+    </target>
+    <!-- ?? we should maybe always remake the parser and not include the generate code in SVN ??? -->
+    <target name="compile" depends="init">
+        <javac srcdir="${src.dir}" destdir="${build.classes.dir}" debug="${javac.debug}">
+            <classpath>
+                <pathelement location="${asm.home}/${asm.jar}"/>
+                <fileset dir="${ext.lib.dir}" includes="${ext.antlr.jars}"/>
+            </classpath>
+        </javac>
+    </target>
+
+     <target name="jar" depends="compile">
+         <!-- until we know better include all the antlr runtime in our deployed jar -->
+         <unjar src="${ext.lib.dir}/antlr-3.0.1.jar" dest="${build.classes.dir}"/>
+         <unjar src="${ext.lib.dir}/antlr-runtime-3.0.1.jar" dest="${build.classes.dir}"/>
+         <unjar src="${ext.lib.dir}/antlr-2.7.7.jar" dest="${build.classes.dir}"/>
+         <unjar src="${ext.lib.dir}/stringtemplate-3.1b1.jar" dest="${build.classes.dir}"/>
+         <unjar src="${ext.lib.dir}/junit.jar" dest="${build.classes.dir}"/>
+         <unjar src="${ext.lib.dir}/asm-all-3.0.jar" dest="${build.classes.dir}"/>
+         <jar jarfile="${build.lib.dir}/orchestration.jar" manifest="${dd.dir}/META-INF/MANIFEST.MF">
+             <fileset dir="${build.classes.dir}" includes="**/*"/>
+         </jar>
+    </target>
+
+   <target name="clean">
+       <delete dir="${build.dir}"/>
+       <delete dir="${dd.grammar.dir}" includes="*.java *.tokens"/>
+    </target>
+
+    <target name="TestParse.compile" depends="jar">
+        <!-- build the TestParse class and then run it to check parsing of rule elements -->
+        <javac srcdir="${src.dir}" destdir="${build.classes.dir}" debug="${javac.debug}" source="TestParse.java">
+            <classpath>
+                <pathelement location="${asm.home}/${asm.jar}"/>
+                <fileset dir="${ext.lib.dir}" includes="${ext.antlr.jars}"/>
+            </classpath>
+        </javac>
+    </target>
+
+    <target name="TestParse" depends="TestParse.compile">
+        <java classname="TestParse">
+            <classpath>
+                <fileset dir="${build.lib.dir}" includes="orchestration.jar"/>
+                <pathelement location="${asm.home}/${asm.jar}"/>
+                <fileset dir="${ext.lib.dir}" includes="${ext.antlr.jars}"/>
+            </classpath>
+            <arg value='WHEN coordinator:Coordinator = $1, recovered : boolean = coordinator.recovered, identifier : String = coordinator.getInstanceIdentifier()'/>
+            <arg value='IF recovered AND getCounter(identifier)'/>
+            <arg value='DO debug("killing prepare"),  killThread()'/>
+        </java>
+    </target>
+
+    <target name="TestRule.compile" depends="jar">
+        <!-- build the TestRule class and then run it to check parsing of rule elements -->
+        <javac srcdir="${src.dir}" destdir="${build.classes.dir}" debug="${javac.debug}" source="TestRule.java">
+            <classpath>
+                <pathelement location="${asm.home}/${asm.jar}"/>
+                <fileset dir="${ext.lib.dir}" includes="${ext.antlr.jars}"/>
+            </classpath>
+        </javac>
+    </target>
+
+    <target name="TestRule" depends="TestRule.compile">
+        <java classname="TestRule" fork="true">
+            <classpath>
+                <fileset dir="${build.lib.dir}" includes="orchestration.jar"/>
+                <pathelement location="${asm.home}/${asm.jar}"/>
+                <fileset dir="${ext.lib.dir}" includes="${ext.antlr.jars}"/>
+            </classpath>
+            <jvmarg value="-Xdebug"/>
+            <jvmarg value="-Xrunjdwp:transport=dt_socket,server=n,address=5005,suspend=y"/>
+            <arg value='-event'/>
+            <arg value='coordinator:Coordinator = $1, recovered : boolean = coordinator.recovered, identifier : String = coordinator.getInstanceIdentifier()'/>
+            <arg value='-condition'/>
+            <arg value='recovered AND getCounter(identifier)'/>
+            <arg value='-action'/>
+            <arg value='debug("killing prepare"),  killThread()'/>
+        </java>
+    </target>
+</project>

Added: labs/jbosstm/workspace/adinn/orchestration/dd/META-INF/MANIFEST.MF
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/dd/META-INF/MANIFEST.MF	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/dd/META-INF/MANIFEST.MF	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,3 @@
+Premain-Class: org.jboss.jbossts.orchestration.agent.Main
+Can-Redefine-Classes: true
+Can-Retransform-Classes: true

Added: labs/jbosstm/workspace/adinn/orchestration/dd/grammar/ECAGrammar.g
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/dd/grammar/ECAGrammar.g	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/dd/grammar/ECAGrammar.g	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,139 @@
+parser grammar ECAGrammar;
+options {
+ // use AST output
+ output = AST;
+ // We're going to use the tokens defined in our ECALexer grammar.
+ tokenVocab = ECAToken;
+ // enable backtracking
+ backtrack = true;
+}
+
+// we need some synthetic tokens for the AST
+tokens {
+	UNOP;
+	BINOP;
+	TERNOP;
+	METH;
+	ARRAY;
+	NUM_LIT;
+	STRING_LIT;
+}
+
+ at header {
+package org.jboss.jbossts.orchestration.rule.grammar;
+}
+
+eca_rule	:	eca EOF ;
+
+eca	:	WHEN event	-> ^(WHEN event)
+	|	IF condition 	-> ^(IF condition)
+	|	DO action	-> ^(DO action)
+	;
+
+// event specifications -- for now events are just a list of bindings
+
+event	:	bindings
+	;
+
+// zero event bindings is specified by an empty event string so we always expect at least one binding
+
+bindings	:	binding SEPR bindings	-> ^(SEPR binding bindings)
+	|	binding
+	;
+
+binding	:	bind_sym ASSIGN expr	-> ^(ASSIGN bind_sym expr)
+	;
+
+// a bound symbol can be specified to be of a particular type
+bind_sym	:	v=SYMBOL COLON t=SYMBOL	-> ^(COLON $v $t) 
+	|	SYMBOL
+	;
+
+// a condition is simply an expression. it not type-constrained by the grammar -- it's easier to do
+// the type checking after parsing  n.b. we always have at least one condition as an empty (i.e.
+// vacuously true) condition is defined by an empty input string.
+
+condition	:	expr
+	;
+
+// actions area defined as a sequence of expressions.it not type-constrained by the grammar -- it's
+// easier to do the type checking after parsing  n.b. we always have at least one action as
+// an  empty (i.e. do nothing) action is defined by an empty action string
+
+action	:	action_expr_list
+	;
+
+action_expr_list
+	:	action_expr SEPR action_expr_list	-> ^(SEPR action_expr action_expr_list)
+	|	action_expr
+	;
+
+action_expr	:	expr
+	;
+
+expr	:	simple_expr infix_oper expr		-> ^(BINOP infix_oper simple_expr expr)
+	|	simple_expr
+	|	unary_oper expr 		-> ^(UNOP unary_oper expr)
+	|	cond=simple_expr TERN_IF iftrue=expr COLON iffalse=expr -> ^(TERNOP $cond $iftrue $iffalse)
+	;
+
+simple_expr	:	v=DOLLARSYM
+	|	v=SYMBOL idx=array_idx			-> ^(ARRAY $v $idx)
+	|	v=SYMBOL LPAREN RPAREN			-> ^(METH $v)
+	|	v=SYMBOL
+	|	v=SYMBOL LPAREN args=expr_list RPAREN		-> ^(METH $v $args) 
+	|	NUMBER
+	|	STRING
+	|	LPAREN expr RPAREN			-> ^(expr)
+	;
+
+expr_list
+	:	expr SEPR expr_list			-> ^(SEPR expr expr_list)
+	|	expr
+	;
+
+array_idx_list
+	:	array_idx array_idx_list			-> ^(SEPR array_idx array_idx_list)
+	|	array_idx
+	;
+
+array_idx
+	:	LSQUARE expr RSQUARE			-> ^(expr)
+	;
+
+infix_oper	:	infix_bit_oper
+	|	infix_arith_oper
+	|	infix_bool_oper
+	|	infix_cmp_oper
+	;
+
+infix_bit_oper
+	:	BAND
+	|	BOR
+	|	BXOR
+	;
+	
+infix_arith_oper
+	:	MUL
+	|	DIV
+	|	PLUS
+	|	MINUS
+	;
+
+infix_bool_oper
+	:	AND
+	|	OR
+	;
+
+infix_cmp_oper
+	:	EQ
+	|	NEQ
+	|	GT
+	|	LT
+	|	GEQ
+	|	LEQ
+	;
+
+unary_oper	:	NOT
+	|	TWIDDLE
+	;

Added: labs/jbosstm/workspace/adinn/orchestration/dd/grammar/ECAToken.g
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/dd/grammar/ECAToken.g	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/dd/grammar/ECAToken.g	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,253 @@
+lexer grammar ECAToken;
+
+ at header {
+package org.jboss.jbossts.orchestration.rule.grammar;
+}
+
+// integers or floats
+	
+fragment
+DIGIT	:	'0'..'9'
+	;
+
+fragment
+POSDIGIT	:	'1'..'9'
+	;
+
+fragment
+SIGN	:	'+'|'-'
+	;
+
+fragment
+BAREINT	:	'0' | (POSDIGIT (DIGIT)*)
+	;
+
+fragment
+INTEGER	:	SIGN? BAREINT
+	;
+
+fragment	
+POINT	:	'.'
+	;
+
+fragment	
+EXPPART	:	 ('e'|'E') INTEGER
+	;
+
+
+fragment
+FLOAT	:	INTEGER POINT BAREINT? EXPPART?
+	;
+
+NUMBER	:	INTEGER | FLOAT
+	;
+
+// builtin symbols -- need to add these before addign the rules for adding any old symbol
+
+WHEN	:	'WHEN'
+	;
+
+IF	:	'IF'
+	;
+
+DO	:	'DO'
+	;
+
+// various bracket pairs
+
+LPAREN	:	'('
+	;
+
+RPAREN	:	')'
+	;
+
+LSQUARE	:	'\['
+	;
+
+RSQUARE	:	'\]'
+	;
+
+LBRACE	:	'{'
+	;
+
+RBRACE	:	'}'
+	;
+
+// statement or expression separator -- we don't care
+
+SEPR	:	';'
+	|	','
+	;
+
+// symbol punctuator
+
+DOT	:	'.'
+	;
+
+// binding for events and assignment for exprs
+
+ASSIGN	:	'='
+	|	'<--'
+	;
+
+// logical operators
+	
+OR	:	'||'
+	|	'OR'
+	|	'or'
+	;
+
+AND	:	'&&'
+	|	'AND'
+	|	'and'
+	;
+
+NOT	:	'!'
+	|	'NOT'
+	|	'not'
+	;
+
+// comparison operators
+
+EQ	:	'=='
+	|	'EQ'
+	|	'eq'
+	;
+
+NEQ	:	'!='
+	|	'NEQ'
+	|	'neq'
+	;
+
+GT	:	'>'
+	|	'GT'
+	|	'gt'
+	;
+
+LT	:	'<'
+	|	'LT'
+	|	'lt'
+	;
+
+GEQ	:	'>='
+	|	'GEQ'
+	|	'geq'
+	;
+
+LEQ	:	'<='
+	|	'LEQ'
+	|	'leq'
+	;
+
+// bitwise operators
+
+BOR	:	'|'
+	;
+
+BAND	:	'&'
+	;
+
+BXOR	:	'^'
+	;
+
+TWIDDLE	:	'~'
+	;
+
+// arithmetic operators
+
+MUL	:	'*'
+	|	'TIMES'
+	|	'times'
+	;
+
+DIV	:	'/'
+	|	'DIVIDE'
+	|	'divide'
+	;
+
+PLUS	:	'+'
+	|	'PLUS'
+	|	'plus'
+	;
+
+MINUS	:	'-'
+	|	'MINUS'
+	|	'minus'
+	;
+
+MOD	:	'%'
+	|	'MOD'
+	|	'mod'
+	;
+
+// ternary condition operator
+
+TERN_IF	:	'?'
+	;
+
+COLON	:	':'
+	;
+
+// "strings" and symbols, the latter possibly with leading or embedded '_' and possibly 'quoted_inlcuding_punctuation_@#$_!!!' 
+
+fragment
+LETTER	:	'a'..'z' | 'A'..'Z'
+	;
+
+fragment
+UNDERSCORE	:	'_'
+	;
+	
+QUOTE	:	'\''
+	;
+
+DQUOTE	:	'"'
+	;
+
+fragment
+SPACE	:	' '|'\t'|'\r'
+	;
+
+fragment
+NEWLINE	:	'\n'
+	;
+
+fragment
+PUNCT	:	'!'|'$'|'%'|'^'|'&'|'*'|'('|')'|'-'|'+'|'='|'{'|'}'|'['|']'|':'|';'|'@'|'~'|'#'|'|'|'\\'|'`'|','|'<'|'.'|'>'|'/'|'?'
+	;
+
+STRING	:	DQUOTE (SPACE | PUNCT | LETTER | UNDERSCORE | DIGIT | QUOTE )* DQUOTE
+	;
+
+fragment
+BARESYM	:	(LETTER | UNDERSCORE) (LETTER | DIGIT | UNDERSCORE)*
+	;
+fragment
+QUOTSYM	:	QUOTE (PUNCT |LETTER | UNDERSCORE | DIGIT | DQUOTE )* QUOTE
+	;
+
+// n.b. dot separated symbol can contain zero or more dot separators
+fragment
+DOTSYM	:	BARESYM DOT DOTSYM
+	|	BARESYM
+	;
+
+SYMBOL	:	DOTSYM
+	|	QUOTSYM
+	;
+
+// dollar is not allowed except in fromt of number or id or in quotes
+fragment
+DOLLAR	:	'$'
+	;
+
+// dollar symbols have dollar followed by a trailing non-signed integer or unquoted string
+
+DOLLARSYM	:	DOLLAR (BAREINT | BARESYM)
+	;
+
+// ignore any other white space
+
+// WS	:	(' ' | '\t' | '\n' | '\r') { setType(Token.SKIP); }
+WS	:	(SPACE | NEWLINE) { skip(); }
+	;

Added: labs/jbosstm/workspace/adinn/orchestration/ext/antlr-2.7.7.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosstm/workspace/adinn/orchestration/ext/antlr-2.7.7.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosstm/workspace/adinn/orchestration/ext/antlr-3.0.1.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosstm/workspace/adinn/orchestration/ext/antlr-3.0.1.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosstm/workspace/adinn/orchestration/ext/antlr-runtime-3.0.1.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosstm/workspace/adinn/orchestration/ext/antlr-runtime-3.0.1.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosstm/workspace/adinn/orchestration/ext/asm-all-3.0.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosstm/workspace/adinn/orchestration/ext/asm-all-3.0.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosstm/workspace/adinn/orchestration/ext/junit.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosstm/workspace/adinn/orchestration/ext/junit.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosstm/workspace/adinn/orchestration/ext/stringtemplate-3.1b1.jar
===================================================================
(Binary files differ)


Property changes on: labs/jbosstm/workspace/adinn/orchestration/ext/stringtemplate-3.1b1.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: labs/jbosstm/workspace/adinn/orchestration/src/TestParse.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/TestParse.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/TestParse.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,27 @@
+import org.antlr.runtime.tree.CommonTree;
+import org.antlr.runtime.ANTLRStringStream;
+import org.antlr.runtime.CommonTokenStream;
+import org.antlr.runtime.RecognitionException;
+import org.jboss.jbossts.orchestration.rule.grammar.ECATokenLexer;
+import org.jboss.jbossts.orchestration.rule.grammar.ECAGrammarParser;
+
+public class TestParse
+{
+    public static void main(String[] args)
+    {
+        CommonTree result = null;
+        for (String arg : args) {
+            System.out.println("Parsing : " + arg);
+            try {
+                ECATokenLexer lexer = new ECATokenLexer(new ANTLRStringStream(arg));
+                CommonTokenStream tokenStream = new CommonTokenStream(lexer);
+                ECAGrammarParser parser = new ECAGrammarParser(tokenStream);
+                ECAGrammarParser.eca_rule_return eca_rule = parser.eca_rule();
+                result = (CommonTree) eca_rule.getTree();
+            } catch (RecognitionException e) {
+                // bad rule event
+                System.err.println(": error parsing arg");
+            }
+        }
+    }
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/TestRule.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/TestRule.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/TestRule.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,54 @@
+import org.antlr.runtime.tree.CommonTree;
+import org.antlr.runtime.ANTLRStringStream;
+import org.antlr.runtime.CommonTokenStream;
+import org.antlr.runtime.RecognitionException;
+import org.jboss.jbossts.orchestration.rule.grammar.ECATokenLexer;
+import org.jboss.jbossts.orchestration.rule.grammar.ECAGrammarParser;
+import org.jboss.jbossts.orchestration.rule.Condition;
+import org.jboss.jbossts.orchestration.rule.Event;
+import org.jboss.jbossts.orchestration.rule.Action;
+
+public class TestRule
+{
+    public static void main(String[] args)
+    {
+        Event event = null;
+        Condition condition = null;
+        Action action = null;
+        for (int i = 0; i < args.length ; i++) {
+            if ("-event".equals(args[i])) {
+                System.out.println("Creating event from " + args[++i]);
+                try {
+                    event = Event.create(args[i]);
+                } catch (Throwable th) {
+                    // bad rule event
+                    System.err.println(": error " + th);
+                }
+            } else if ("-condition".equals(args[i])) {
+                if (event != null) {
+                    System.out.println("Creating condition from " + args[++i]);
+                    try {
+                        condition = Condition.create(event.getTypeGroup(), event.getBindings(), args[i]);
+                    } catch (Throwable th) {
+                        // bad rule event
+                        System.err.println(": error " + th);
+                    }
+                } else {
+                     System.out.println("No event to create condition from " + args[++i]);
+                }
+            } else if ("-action".equals(args[i])) {
+                if (event != null) {
+                    System.out.println("Creating action from " + args[++i]);
+                    try {
+                        action = Action.create(event.getTypeGroup(), event.getBindings(), args[i]);
+                    } catch (Throwable th) {
+                        // bad rule event
+                        System.err.println(": error " + th);
+                    }
+                } else {
+                     System.out.println("No event to create action from " + args[++i]);
+                }
+            }
+        }
+    }
+}
\ No newline at end of file

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/agent/Main.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/agent/Main.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/agent/Main.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,129 @@
+package org.jboss.jbossts.orchestration.agent;
+
+import org.jboss.jbossts.orchestration.annotation.EventHandlerClass;
+
+import java.lang.instrument.Instrumentation;
+import java.lang.annotation.Annotation;
+import java.util.jar.JarFile;
+import java.util.jar.JarEntry;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Enumeration;
+import java.io.File;
+import java.io.IOException;
+import java.net.URLClassLoader;
+import java.net.URL;
+import java.net.MalformedURLException;
+
+/**
+ * agent class supplied at JVM startup to install orchestration package bytecode transformer
+ */
+public class Main {
+    public static void premain(String args, Instrumentation inst) {
+        if (args != null) {
+            // args are supplied eparated by ',' characters
+            String[] argsArray = args.split(",");
+            // the only args we accept are extra jar files to be added to the boot path or scanned for rules
+            for (String arg : argsArray) {
+                if (arg.startsWith(BOOT_PREFIX)) {
+                    bootJarPaths.add(arg.substring(BOOT_PREFIX.length(), arg.length()));
+                } else if (arg.startsWith(RULE_PREFIX)) {
+                    ruleJarPaths.add(arg.substring(RULE_PREFIX.length(), arg.length()));
+                } else {
+                    System.err.println("org.jboss.jbossts.orchestration.agent.Main:\n" +
+                            "  illegal agent argument : " + arg + "\n" +
+                            "  valid arguments are boot:<path-to-jar> or rule:<path-to-jar>");
+                }
+            }
+        }
+
+        // add any boot jars to the boot class path
+        // TODO can only do this when we get to 1.6
+
+        for (String bootJarPath : bootJarPaths) {
+            try {
+                JarFile jarfile = new JarFile(new File(bootJarPath));
+                // inst.appendToBootstrapClassLoaderSearch(jarfile);
+            } catch (IOException ioe) {
+                System.err.println("org.jboss.jbossts.orchestration.agent.Main: unable to open boot jar file : " + bootJarPath);
+            }
+        }
+
+        // look up rules in any rule jars
+
+        for (String ruleJarPath : ruleJarPaths) {
+            try {
+                JarFile jarFile = new JarFile(new File(ruleJarPath));
+                processRules(jarFile);
+            } catch (IOException ioe) {
+                System.err.println("org.jboss.jbossts.orchestration.agent.Main: unable to open rule jar file : " + ruleJarPath);
+            }
+        }
+
+        // install an instance of Transformer to instrument the bytecode
+
+        inst.addTransformer(new Transformer(inst, ruleClasses));
+    }
+
+    private static void processRules(JarFile jarFile)
+    {
+        try {
+            URLClassLoader classLoader = new URLClassLoader(new URL[] { new URL("file:" + jarFile.getName()) });
+            Enumeration<JarEntry> jarEntries = jarFile.entries();
+
+            while (jarEntries.hasMoreElements()) {
+                JarEntry jarEntry = jarEntries.nextElement();
+                String entryName = jarEntry.getName();
+
+                if (entryName.endsWith(CLASS_FILE_SUFFIX)) {
+                    // try to load the rule class
+                    int classNameLength = entryName.length() - CLASS_FILE_SUFFIX.length();
+                    String className = entryName.substring(0, classNameLength).replaceAll("/", ".");
+                    try {
+                        Class clazz = classLoader.loadClass(className);
+                        Annotation a = clazz.getAnnotation(EventHandlerClass.class);
+                        if (a != null) {
+                            ruleClasses.add(clazz);
+                        }
+                    } catch (ClassNotFoundException e) {
+                        System.err.println("org.jboss.jbossts.orchestration.agent.Main: unable to load class " + className + " from : " + jarFile.getName());
+                    }
+                }
+            }
+        } catch (MalformedURLException mue) {
+            System.err.println("org.jboss.jbossts.orchestration.agent.Main: unable to load classes from : " + jarFile.getName());
+        }
+    }
+
+    /**
+     * prefix used to specify boot jar argument for agent
+     */
+    private static final String BOOT_PREFIX = "boot:";
+
+    /**
+     * prefix used to specify rulejar argument for agent
+     */
+
+    private static final String RULE_PREFIX = "rule:";
+
+    /**
+     * suffix found on end of .class files (doh :-)
+     */
+
+    private static final String CLASS_FILE_SUFFIX = ".class";
+
+    /**
+     * list of paths to extra bootstrap jars supplied on command line
+     */
+    private static List<String> bootJarPaths = new ArrayList<String>();
+
+    /**
+     * list of paths to rule jars supplied on command line
+     */
+    private static List<String> ruleJarPaths = new ArrayList<String>();
+
+    /**
+     * list of classes annotated with methods annotated with event handler annotations
+     */
+    private static List<Class> ruleClasses = new ArrayList<Class>();
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/agent/Transformer.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/agent/Transformer.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/agent/Transformer.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,402 @@
+package org.jboss.jbossts.orchestration.agent;
+
+import org.jboss.jbossts.orchestration.annotation.EventHandler;
+import org.jboss.jbossts.orchestration.annotation.EventHandlerClass;
+import org.jboss.jbossts.orchestration.rule.grammar.ECATokenLexer;
+import org.jboss.jbossts.orchestration.rule.grammar.ECAGrammarParser;
+import org.jboss.jbossts.orchestration.rule.Event;
+import org.jboss.jbossts.orchestration.rule.Condition;
+import org.jboss.jbossts.orchestration.rule.Action;
+import org.jboss.jbossts.orchestration.rule.type.TypeGroup;
+import org.jboss.jbossts.orchestration.rule.binding.Bindings;
+import org.objectweb.asm.*;
+import org.antlr.runtime.tree.CommonTree;
+import org.antlr.runtime.ANTLRStringStream;
+import org.antlr.runtime.CommonTokenStream;
+import org.antlr.runtime.RecognitionException;
+
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.IllegalClassFormatException;
+import java.lang.instrument.Instrumentation;
+import java.lang.reflect.Method;
+import java.lang.annotation.Annotation;
+import java.security.ProtectionDomain;
+import java.util.List;
+import java.util.HashMap;
+import java.util.ArrayList;
+
+/**
+ * byte code transformer used to introduce orchestration events into JBoss code
+ */
+public class Transformer implements ClassFileTransformer {
+    /**
+     * constructor allowing this transformer to be provided with access to the JVM's instrumentation
+     * implementation
+     *
+     * @param inst the instrumentation object used to interface to the JVM
+     */
+    public Transformer(Instrumentation inst, List<Class> ruleClasses)
+    {
+        this.inst = inst;
+        this.ruleClasses = ruleClasses;
+        targetToHandlerClassMap = new HashMap<String, List<Annotation>>();
+        targetToHandlerMethodMap = new HashMap<String, List<Method>>();
+
+        // insert all event handling methods into the map indexed by the associated target class
+
+        for (Class ruleClass : ruleClasses) {
+            Annotation classAnnotation = ruleClass.getAnnotation(EventHandlerClass.class);
+            for (Method method : ruleClass.getDeclaredMethods()) {
+                EventHandler eventHandler = method.getAnnotation(EventHandler.class);
+                if (eventHandler != null) {
+                    String target = externalize(eventHandler.targetClass());
+                    if (isTransformable(target)) {
+                        List<Annotation> clazzes = targetToHandlerClassMap.get(target);
+                        if (clazzes == null) {
+                            clazzes = new ArrayList<Annotation>();
+                        }
+                        if (!clazzes.contains(classAnnotation)) {
+                            clazzes.add(classAnnotation);
+                        }
+                        List<Method> methods = targetToHandlerMethodMap.get(target);
+                        if (methods == null) {
+                            methods = new ArrayList<Method>();
+                            targetToHandlerMethodMap.put(target, methods);
+                        }
+                        methods.add(method);
+                    } else {
+                        System.err.println("org.jboss.jbossts.orchestration.agent.Transformer: requested to transform invalid class " + target);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * The implementation of this method may transform the supplied class file and
+     * return a new replacement class file.
+     * <p/>
+     * <p/>
+     * Once a transformer has been registered with
+     * {@link java.lang.instrument.Instrumentation#addTransformer Instrumentation.addTransformer},
+     * the transformer will be called for every new class definition and every class redefinition.
+     * The request for a new class definition is made with
+     * {@link ClassLoader#defineClass ClassLoader.defineClass}.
+     * The request for a class redefinition is made with
+     * {@link java.lang.instrument.Instrumentation#redefineClasses Instrumentation.redefineClasses}
+     * or its native equivalents.
+     * The transformer is called during the processing of the request, before the class file bytes
+     * have been verified or applied.
+     * <p/>
+     * <p/>
+     * If the implementing method determines that no transformations are needed,
+     * it should return <code>null</code>.
+     * Otherwise, it should create a new <code>byte[]</code> array,
+     * copy the input <code>classfileBuffer</code> into it,
+     * along with all desired transformations, and return the new array.
+     * The input <code>classfileBuffer</code> must not be modified.
+     * <p/>
+     * <p/>
+     * In the redefine case, the transformer must support the redefinition semantics.
+     * If a class that the transformer changed during initial definition is later redefined, the
+     * transformer must insure that the second class output class file is a legal
+     * redefinition of the first output class file.
+     * <p/>
+     * <p/>
+     * If the transformer believes the <code>classFileBuffer</code> does not
+     * represent a validly formatted class file, it should throw
+     * an <code>IllegalClassFormatException</code>.  Subsequent transformers
+     * will still be called and the load or redefine will still
+     * be attempted.  Throwing an <code>IllegalClassFormatException</code> thus
+     * has the same effect as returning null but facilitates the
+     * logging or debugging of format corruptions.
+     *
+     * @param loader              the defining loader of the class to be transformed,
+     *                            may be <code>null</code> if the bootstrap loader
+     * @param className           the name of the class in the internal form of fully
+     *                            qualified class and interface names as defined in
+     *                            <i>The Java Virtual Machine Specification</i>.
+     *                            For example, <code>"java/util/List"</code>.
+     * @param classBeingRedefined if this is a redefine, the class being redefined,
+     *                            otherwise <code>null</code>
+     * @param protectionDomain    the protection domain of the class being defined or redefined
+     * @param classfileBuffer     the input byte buffer in class file format - must not be modified
+     * @return a well-formed class file buffer (the result of the transform),
+     *         or <code>null</code> if no transform is performed.
+     * @throws java.lang.instrument.IllegalClassFormatException
+     *          if the input does not represent a well-formed class file
+     * @see java.lang.instrument.Instrumentation#redefineClasses
+     */
+
+    public byte[] transform(ClassLoader loader,
+                            String className,
+                            Class<?> classBeingRedefined,
+                            ProtectionDomain protectionDomain,
+                            byte[] classfileBuffer)
+            throws IllegalClassFormatException
+    {
+        // we only transform certain classes -- in  particular, we exclude bootstrap classes whose loader is null
+        // and we exclude orchestration classes
+        if (loader == null || className.startsWith("org/jboss/jbossts/orchestration/") || !isTransformable(className)) {
+            return classfileBuffer;
+        }
+
+        // ok, we need to check whether there are any event handlers associated with this class and if so
+        // we will consider transforming the byte code
+
+        List<Method> handlerMethods = targetToHandlerMethodMap.get(className);
+
+        if (handlerMethods != null) {
+            for (Method handlerMethod : handlerMethods) {
+                try {
+                    transform(handlerMethod.getAnnotation(EventHandler.class), loader, className,  classBeingRedefined, classfileBuffer);
+                } catch (Throwable th) {
+                    System.err.println("transform  : caught throwable " + th);
+                }
+            }
+        }
+
+        return classfileBuffer;
+    }
+
+    private byte[] transform(EventHandler handler, ClassLoader loader, String className, Class targetClass, byte[] targetClassBytes)
+    {
+        // set up trees for parse;
+        CommonTree eventTree = null;
+        CommonTree conditionTree = null;
+        CommonTree actionTree = null;
+
+        System.out.println("org.jboss.jbossts.orchestration.agent.Transformer: Inserting trigger event");
+        System.out.println("                                                 : class " + className);
+        System.out.println("                                                 : method " + handler.targetMethod());
+        System.out.println("                                                 : line " + handler.targetLine());
+        Event event;
+        TypeGroup typeGroup;
+        Bindings bindings;
+        Condition condition;
+        Action action;
+        if ("".equals(handler.event())) {
+            System.out.println("                                                 : WHEN []");
+        } else {
+            System.out.println("                                                : " + handler.event());
+        }
+        event = Event.create(handler.event());
+        typeGroup = event.getTypeGroup();
+        bindings = event.getBindings();
+        if ("".equals(handler.condition())) {
+            System.out.println("                                                 : IF true");
+        } else {
+            System.out.println("                                                : " + handler.condition());
+        }
+        condition = Condition.create(typeGroup, bindings, handler.condition());
+        if ("".equals(handler.action())) {
+            System.out.println("                                                 : DO nothing");
+        } else {
+            System.out.println("                                                 : " + handler.action());
+        }
+        action = Action.create(typeGroup, bindings, handler.action());
+        final String finalClassName = className;
+        final EventHandler finalHandler = handler;
+        final ClassLoader finalLoader = loader;
+        final Class finalClass = targetClass;
+        final String targetMethod = handler.targetMethod();
+        final int targetLine = handler.targetLine();
+        final String targetName = parseMethodName(targetMethod);
+        final String targetSignature = parseMethodSignature(targetMethod);
+        final String ecaRuleFieldName = generateFieldName(targetName, targetSignature);
+
+        final ClassReader cr = new ClassReader(targetClassBytes);
+        ClassWriter cw = new ClassWriter(0);
+        ClassAdapter adapter = new ClassAdapter(cw) {
+            public void visit(final int version,
+                    final int access,
+                    final String name,
+                    final String signature,
+                    final String superName,
+                    final String[] interfaces)
+            {
+                // create a class derived from ECARule to implement the event handler and
+                // instantiate it with a singleton instance
+                //
+                // n.b. we have to wait until here to do this because we need to resolve type names
+                // in the rule dynamically aginst types which are only available via the target class
+                // and its class loader.
+                //
+                // TODO see if we need to throw up if we try to resolve types which are not yet loaded
+
+                Class handlerClazz = generateHandlerClass(finalHandler, finalLoader, finalClassName, finalClass);
+                Object handlerSingleton = null;
+                try {
+                    // TODO do we want to give the handler class some arguments?
+                    handlerSingleton = handlerClazz.newInstance();
+                } catch (InstantiationException e) {
+                    // should not happen!!!
+                } catch (IllegalAccessException e) {
+                    // should not happen!!!
+                }
+
+                // add a static field to the class to hold the singleton
+/*                FieldVisitor visitor = visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL,
+                        ecaRuleFieldName,
+                        handlerClazz.getName(),
+                        null,
+                        handlerSingleton);
+*/
+            }
+
+            public MethodVisitor visitMethod(final int access,
+                                             final String name,
+                                             final String desc,
+                                             final String signature,
+                                             final String[] exceptions) {
+                MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
+                if (name.equals(targetName) &&
+                        (targetSignature.length() == 0 || signature.equals(targetSignature))) {
+                    return new MethodAdapter(mv) {
+                        public void visitCode()
+                        {
+                            // generate try catch block for kill thread/JVM
+                            System.out.println("                                                 : // generate wrapper");
+                            System.out.println("                                                 : try { ");
+                            super.visitCode();
+                            System.out.println("                                                 : } catch (KillThreadException kte) { ");
+                            System.out.println("                                                 :   killThread();");
+                            System.out.println("                                                 : } catch (KillJVMException kje) { ");
+                            System.out.println("                                                 :   killJVM();");
+                            System.out.println("                                                 : }");
+                            // and the rest
+                        }
+                        public void visitLineNumber(final int line, final Label start)
+                        {
+                            if (line == targetLine) {
+                                // insert call to relevant event handler instance
+                                System.out.println("                                                 : // generate event notification");
+                                System.out.println("                                                 :    " + finalClassName + "." + ecaRuleFieldName + ".event(this, . . .);");
+                                System.out.println("                                                 : }");
+                            }
+                            super.visitLineNumber(line, start);
+                        }
+                    };
+                }
+                return mv;
+            }
+        };
+
+        cr.accept(adapter, 0);
+        return targetClassBytes;
+    }
+
+    /**
+     * convert a classname from canonical form to the form used to represent it externally i.e. replace
+     * all dots with slashes
+     *
+     * @param className
+     * @return
+     */
+    private String externalize(String className)
+    {
+        return className.replaceAll("\\.", "/");
+    }
+
+    /**
+     * test whether a class witha given name is a potential candidate for insertion of event notifications
+     * @param className
+     * @return true if a class is a potential candidate for insertion of event notifications otherwise return false
+     */
+    private boolean isTransformable(String className)
+    {
+        return (className.startsWith("com/arjuna/"));
+    }
+
+    /**
+     * split off the method name preceding the signature and return it
+     * @param targetMethod - the unqualified method name, possibly including signature
+     * @return
+     */
+    private String parseMethodName(String targetMethod) {
+        int sigIdx = targetMethod.indexOf("(");
+        if (sigIdx > 0) {
+            return targetMethod.substring(0, sigIdx).trim();
+        } else {
+            return targetMethod;
+        }
+    }
+
+    /**
+     * split off the signature following the method name and return it
+     * @param targetMethod - the unqualified method name, possibly including signature
+     * @return
+     */
+    private String parseMethodSignature(String targetMethod) {
+        int sigIdx = targetMethod.indexOf("(");
+        if (sigIdx >= 0) {
+            return targetMethod.substring(sigIdx, targetMethod.length()).trim();
+        } else {
+            return "";
+        }
+    }
+
+    /**
+     * split off the signature following the method name and return it
+     * @param targetName the unqualified method name, not including signature
+     * @param targetSignature the method signature including brackets types and return type
+     * @return
+     */
+    private String generateFieldName(String targetName, String targetSignature) {
+        String result = targetName;
+        int startIdx = targetSignature.indexOf("(");
+        int endIdx = targetSignature.indexOf(")");
+        if (startIdx < 0) {
+            startIdx = 0;
+        }
+        if (endIdx < 0) {
+            endIdx = targetSignature.length() - 1;
+        }
+
+        String args = targetSignature.substring(startIdx, endIdx + 1);
+
+        // remove any brackets, commas, spaces, semi-colons, slashes and '[' characters
+        args = args.replaceAll("\\(", "\\$_\\$");
+        args = args.replaceAll("\\)", "\\$_\\$");
+        args = args.replaceAll(",", "\\$1\\$");
+        args = args.replaceAll(" ", "\\$2\\$");
+        args = args.replaceAll(";", "\\$3\\$");
+        args = args.replaceAll("\\/", "\\$4\\$");
+        args = args.replaceAll("\\[", "\\$5\\$");
+
+        return result + args;
+    }
+
+    private Class generateHandlerClass(EventHandler handler, ClassLoader loader, String targetClassName, Class targetClass)
+    {
+        // TODO -- write this but use Object for now
+        return Object.class;
+    }
+
+    /**
+     * the instrumentation interface to the JVM
+     */
+    private final Instrumentation inst;
+
+    /**
+     * the set of rule classes supplied to the agent program
+     */
+    private final List<Class> ruleClasses;
+
+    /**
+     * a mapping from class names which appear in rule targets to the associated event handling methods
+     */
+
+    private final HashMap<String, List<Method>> targetToHandlerMethodMap;
+
+    /**
+     * a mapping from class names which appear in rule targets to the associated event handling classes
+     */
+
+    private final HashMap<String, List<Annotation>> targetToHandlerClassMap;
+    
+    /**
+     * external form of ECA rule class from which synthesised ECA handler classes are derived
+     */
+    private static final String ECA_RULE_CLASS_NAME = "org/jboss/jbossts/orchestration/rule/ECARule";
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/annotation/EventHandler.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/annotation/EventHandler.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/annotation/EventHandler.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,21 @@
+package org.jboss.jbossts.orchestration.annotation;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Annotation used to tag classes which implement event handler code
+ */
+
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target(ElementType.METHOD)
+public @interface EventHandler {
+    String targetClass();
+    String targetMethod() default "";
+    int targetLine() default -1;
+    String event() default "";
+    String condition() default "";
+    String action() default "";
+}
\ No newline at end of file

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/annotation/EventHandlerClass.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/annotation/EventHandlerClass.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/annotation/EventHandlerClass.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,15 @@
+package org.jboss.jbossts.orchestration.annotation;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Annotation used to tag classes which implement event handler code
+ */
+
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target(ElementType.TYPE)
+public @interface EventHandlerClass {
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/Action.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/Action.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/Action.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,60 @@
+package org.jboss.jbossts.orchestration.rule;
+
+import org.antlr.runtime.tree.CommonTree;
+import org.antlr.runtime.ANTLRStringStream;
+import org.antlr.runtime.CommonTokenStream;
+import org.antlr.runtime.RecognitionException;
+import org.jboss.jbossts.orchestration.rule.type.TypeGroup;
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.jboss.jbossts.orchestration.rule.binding.Bindings;
+import org.jboss.jbossts.orchestration.rule.expression.ExpressionHelper;
+import org.jboss.jbossts.orchestration.rule.expression.Expression;
+import org.jboss.jbossts.orchestration.rule.grammar.ECATokenLexer;
+import org.jboss.jbossts.orchestration.rule.grammar.ECAGrammarParser;
+
+import java.util.List;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: adinn
+ * Date: 17-Jul-2008
+ * Time: 15:20:18
+ * To change this template use File | Settings | File Templates.
+ */
+public class Action
+{
+    public static Action create(TypeGroup typeGroup, Bindings bindings, String text)
+    {
+        if ("".equals(text)) {
+            return new Action(typeGroup, bindings);
+        }
+        try {
+            ECATokenLexer lexer = new ECATokenLexer(new ANTLRStringStream(text));
+            CommonTokenStream tokenStream = new CommonTokenStream(lexer);
+            ECAGrammarParser parser = new ECAGrammarParser(tokenStream);
+            ECAGrammarParser.action_return parse = parser.action();
+            CommonTree actionTree = (CommonTree) parse.getTree();
+            Action action = new Action(typeGroup, bindings, actionTree);
+            return action;
+        } catch (RecognitionException e) {
+            System.err.println("org.jboss.jbossts.orchestration.rule.event : error parsing action " + text);
+            return new Action(typeGroup, bindings);
+        }
+    }
+    protected Action(TypeGroup typeGroup, Bindings bindings, CommonTree actionTree)
+    {
+        this.typeGroup = typeGroup;
+        this.bindings = bindings;
+        this.action = ExpressionHelper.createExpressionList(this.bindings, actionTree, Type.VOID);
+    }
+
+    protected Action(TypeGroup typeGroup, Bindings bindings)
+    {
+        this.typeGroup = typeGroup;
+        this.bindings = bindings;
+    }
+
+    private List<Expression> action;
+    private TypeGroup typeGroup;
+    private Bindings bindings;
+}
\ No newline at end of file

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/Condition.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/Condition.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/Condition.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,60 @@
+package org.jboss.jbossts.orchestration.rule;
+
+import org.antlr.runtime.tree.CommonTree;
+import org.antlr.runtime.ANTLRStringStream;
+import org.antlr.runtime.CommonTokenStream;
+import org.antlr.runtime.RecognitionException;
+import org.jboss.jbossts.orchestration.rule.type.TypeGroup;
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.jboss.jbossts.orchestration.rule.binding.Bindings;
+import org.jboss.jbossts.orchestration.rule.expression.ExpressionHelper;
+import org.jboss.jbossts.orchestration.rule.expression.Expression;
+import org.jboss.jbossts.orchestration.rule.grammar.ECATokenLexer;
+import org.jboss.jbossts.orchestration.rule.grammar.ECAGrammarParser;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: adinn
+ * Date: 17-Jul-2008
+ * Time: 15:20:18
+ * To change this template use File | Settings | File Templates.
+ */
+public class Condition
+{
+    public static Condition create(TypeGroup typeGroup, Bindings bindings, String text)
+    {
+        if ("".equals(text)) {
+            return new Condition(typeGroup, bindings);
+        }
+        try {
+            ECATokenLexer lexer = new ECATokenLexer(new ANTLRStringStream(text));
+            CommonTokenStream tokenStream = new CommonTokenStream(lexer);
+            ECAGrammarParser parser = new ECAGrammarParser(tokenStream);
+            ECAGrammarParser.condition_return parse = parser.condition();
+            CommonTree conditionTree = (CommonTree) parse.getTree();
+            Condition condition = new Condition(typeGroup,  bindings, conditionTree);
+            return condition;
+        } catch (RecognitionException e) {
+            System.err.println("org.jboss.jbossts.orchestration.rule.event : error parsing condition " + text);
+            return new Condition(typeGroup, bindings);
+        }
+    }
+
+    protected Condition(TypeGroup typeGroup, Bindings bindings, CommonTree conditionTree)
+    {
+        this.typeGroup = typeGroup;
+        this.bindings = bindings;
+        this.condition = ExpressionHelper.createExpression(this.bindings, conditionTree, Type.BOOLEAN);
+    }
+
+    protected Condition(TypeGroup typeGroup, Bindings bindings)
+    {
+        this.typeGroup = typeGroup;
+        this.bindings = bindings;
+        this.condition = null;
+    }
+
+    private Expression condition;
+    private TypeGroup typeGroup;
+    private Bindings bindings;
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/Event.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/Event.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/Event.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,197 @@
+package org.jboss.jbossts.orchestration.rule;
+
+import org.antlr.runtime.tree.CommonTree;
+import org.antlr.runtime.tree.Tree;
+import org.antlr.runtime.Token;
+import org.antlr.runtime.ANTLRStringStream;
+import org.antlr.runtime.CommonTokenStream;
+import org.antlr.runtime.RecognitionException;
+import org.jboss.jbossts.orchestration.rule.binding.Bindings;
+import org.jboss.jbossts.orchestration.rule.binding.Binding;
+import static org.jboss.jbossts.orchestration.rule.grammar.ECAGrammarParser.*;
+import org.jboss.jbossts.orchestration.rule.grammar.ECATokenLexer;
+import org.jboss.jbossts.orchestration.rule.grammar.ECAGrammarParser;
+import org.jboss.jbossts.orchestration.rule.expression.Expression;
+import org.jboss.jbossts.orchestration.rule.expression.ExpressionHelper;
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.jboss.jbossts.orchestration.rule.type.TypeGroup;
+
+/**
+ * class which represents a rule event comprising of a set of abstract bindings of event variables to
+ * evaluable expressions.
+ */
+public class Event {
+
+    public static Event create(String text)
+    {
+        if ("".equals(text)) {
+            return new Event();
+        }
+
+        try {
+            ECATokenLexer lexer = new ECATokenLexer(new ANTLRStringStream(text));
+            CommonTokenStream tokenStream = new CommonTokenStream(lexer);
+            ECAGrammarParser parser = new ECAGrammarParser(tokenStream);
+            ECAGrammarParser.event_return event_parse = parser.event();
+            CommonTree eventTree = (CommonTree) event_parse.getTree();
+            Event event = new Event(eventTree);
+            return event;
+        } catch (RecognitionException e) {
+            System.err.println("org.jboss.jbossts.orchestration.rule.event : error parsing event " + text);
+            return new Event();
+        }
+    }
+
+    protected Event(CommonTree eventTree)
+    {
+        this.typeGroup = new TypeGroup();
+        createBindings(eventTree);
+    }
+
+    protected Event()
+    {
+        this.typeGroup = new TypeGroup();
+        this.bindings = new Bindings();
+    }
+
+    public boolean compile()
+    {
+        return true;
+    }
+
+    public Bindings getBindings()
+    {
+        return bindings;
+    }
+
+    private void createBindings(CommonTree eventTree)
+    {
+        Bindings bindings = new Bindings();
+        boolean success = true;
+
+        // we expect BINDINGS = (SEPR BINDING BINDINGS) | BINDING
+        // where BINDING = (BIND BINDSYM EXPR)
+
+        while (eventTree != null) {
+            Token token = eventTree.getToken();
+            int tokenType = token.getType();
+            switch (tokenType) {
+                case SEPR:
+                {
+                    success |= addBinding(bindings, (CommonTree)eventTree.getChild(0));
+                    eventTree = (CommonTree)eventTree.getChild(1);
+                }
+                break;
+                case ASSIGN:
+                {
+                    success |= addBinding(bindings, eventTree);
+                    eventTree = null;
+                }
+                break;
+                default:
+                    System.err.println("Event.createBindings : unexpected token Type in binding list " + tokenType + " for token " + token.getText() + " @ " + token.getLine() + "." + token.getCharPositionInLine());
+                    break;
+            }
+        }
+
+        // if we had any errors we leave bindings null to ensure that we don't try to
+        // compile this rule any further
+
+        if (success) {
+            this.bindings = bindings;
+        }
+    }
+
+    private boolean addBinding(Bindings bindings, CommonTree bindingTree)
+    {
+        Token token = bindingTree.getToken();
+        int tokenType = token.getType();
+
+        if (tokenType != ASSIGN) {
+            System.err.println("Event.createBindings : unexpected token Type in binding " + tokenType + " for token " + token.getText() + " @ " + token.getLine() + "." + token.getCharPositionInLine());
+            return false;
+        }
+
+        CommonTree varTree = (CommonTree)bindingTree.getChild(0);
+        CommonTree exprTree = (CommonTree)bindingTree.getChild(1);
+
+        Binding binding = createBinding(varTree);
+
+        // don't allow current binding to be used when parsing the expression
+        // but do use any type supplied for the binding
+
+        Expression expr;
+
+        if (binding == null) {
+            // try expression anyway so we get as manyh errors as possible
+            expr = ExpressionHelper.createExpression(bindings, exprTree);
+        } else {
+            expr = ExpressionHelper.createExpression(bindings, exprTree, binding.getType());
+        }
+
+        if (binding == null || expr == null) {
+            // errors wil have been notified already
+            return false;
+        }
+
+        if (bindings.lookup(binding.getName()) != null) {
+            // oops rebinding not allowed
+            System.err.println("Event.createBindings : rebinding disallowed for variable " + token.getText() + " @ " + token.getLine() + "." + token.getCharPositionInLine());
+            return false;
+        }
+
+        binding.setValue(expr);
+        bindings.append(binding);
+
+        return true;
+    }
+
+    public Binding createBinding(CommonTree varTree)
+    {
+        Token token = varTree.getToken();
+        int tokenType = token.getType();
+
+        // we expect either (COLON SYMBOL SYMBOL) or SYMBOL
+        switch (tokenType) {
+            case SYMBOL:
+            {
+                return new Binding(token.getText());
+            }
+            case COLON:
+            {
+                CommonTree child0 = (CommonTree)varTree.getChild(0);
+                CommonTree child1 = (CommonTree)varTree.getChild(1);
+                if (child0.getToken().getType() != SYMBOL) {
+                    System.err.println("Event.createBindings : unexpected token Type in variable declaration" + child0.getToken().getType() + " for token " + child0.getToken().getText() + " @ " + token.getLine() + "." + token.getCharPositionInLine());
+                    return null;
+                } else if (child1.getToken().getType() != SYMBOL) {
+                    System.err.println("Event.createBindings : unexpected token Type in variable type declaration" + child1.getToken().getType()  + " for token " + child1.getToken().getText() + " @ " + token.getLine() + "." + token.getCharPositionInLine());
+                    return null;
+                }
+                String typeName = child1.getText();
+                Type type = typeGroup.lookup(typeName);
+                if (type == null) {
+                    type = typeGroup.create(typeName);
+                    if (type == null) {
+                        System.err.println("Event.createBindings : incompatible type in declaration of variable " + child1.getToken().getText() + " @ " + token.getLine() + "." + token.getCharPositionInLine());
+                        return null;
+                    }
+                }
+                return new Binding(child0.getText(), type);
+            }
+            default:
+            {
+                System.err.println("Event.createBindings : unexpected token Type in binding variable declaration" + tokenType + " for token " + token.getText() + " @ " + token.getLine() + "." + token.getCharPositionInLine());
+                return null;
+            }
+        }
+    }
+
+    public TypeGroup getTypeGroup()
+    {
+        return typeGroup;
+    }
+
+    private TypeGroup typeGroup;
+    private Bindings bindings;
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/binding/Binding.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/binding/Binding.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/binding/Binding.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,78 @@
+package org.jboss.jbossts.orchestration.rule.binding;
+
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.jboss.jbossts.orchestration.rule.expression.Expression;
+
+/**
+ * Class used to store a binding of a named variable to a value of some given type
+ */
+
+public class Binding {
+
+    public Binding(String name)
+    {
+        this(name, null, null);
+    }
+
+    public Binding(String name, Type type)
+    {
+        this(name, type, null);
+    }
+
+    public Binding(String name, Type type, Expression value)
+    {
+        this.name = name;
+        this.type = type;
+        this.value = value;
+    }
+
+    public boolean typeCheck(ClassLoader loader, Type type)
+    {
+        if (this.type.isUndefined()) {
+            // accept the candidate type
+            if (type.isUndefined()) {
+                // !!should never happen
+                System.err.println("Binding.typecheck : shouldn't happen! variable " + getName() + " has undefined tyep and undefined derived type " + type.getName());
+                return false;
+            } else {
+                this.type = type;
+                return true;
+            }
+        } else {
+            // TODO check is this the right way round???
+            if (type.isAssignableFrom(this.type)) {
+                return true;
+            } else {
+                System.err.println("Binding.typecheck : current type " + this.type.getName() + " for variable " + getName() + " is incompatible with derived type " + type.getName());
+                return false;
+            }
+        }
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public Object getValue()
+    {
+        return value;
+    }
+
+    public Expression setValue(Expression value)
+    {
+        Expression oldValue = this.value;
+        this.value = value;
+
+        return oldValue;
+    }
+
+    public Type getType()
+    {
+        return type;
+    }
+
+    private String name;
+    private Type type;
+    private Expression value;
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/binding/Bindings.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/binding/Bindings.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/binding/Bindings.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,56 @@
+package org.jboss.jbossts.orchestration.rule.binding;
+
+import java.util.Iterator;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * * an ordered list of ECA rule event bindings as they occur in the event specification
+ */
+public class Bindings {
+    /**
+     * lookup a binding in the list by name
+     *
+     * @param name
+     * @return the binding or null if no bidngin exists with the supplied name
+     */
+    public Binding lookup(String name)
+    {
+        ListIterator<Binding> iterator = bindings.listIterator();
+
+        while (iterator.hasNext()) {
+            Binding binding = iterator.next();
+            if (binding.getName().equals(name)) {
+                return binding;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * add a binding to the end of the list
+     *
+     * n.b. the caller msut ensure that no binding with the same name is already present in
+     * the list
+     * @param binding
+     * @return
+     */
+    public Binding append(Binding binding)
+    {
+        Binding oldBinding = lookup(binding.getName());
+        if (oldBinding!= null) {
+            bindings.remove(binding);
+        }
+
+        bindings.add(binding);
+
+        return oldBinding;
+    }
+
+    /**
+     * the list of current bindings
+     */
+    private List<Binding> bindings = new ArrayList<Binding>();
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ArithmeticExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ArithmeticExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ArithmeticExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,15 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.antlr.runtime.Token;
+
+/**
+ * A binary arithmetic operator expression
+ */
+public class ArithmeticExpression extends BinaryOperExpression
+{
+    public ArithmeticExpression(int oper, Token token, Expression left, Expression right)
+    {
+        super(oper, Type.promote(left.getType(), right.getType()), token, left, right);
+    }
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ArrayExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ArrayExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ArrayExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,55 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.jboss.jbossts.orchestration.rule.binding.Bindings;
+import org.antlr.runtime.Token;
+import org.antlr.runtime.tree.CommonTree;
+
+import java.util.List;
+import java.util.Iterator;
+
+/**
+ * an expression which identifies an array reference.
+ */
+
+public class ArrayExpression extends Expression
+{
+
+    public ArrayExpression(Type type, Token token, List<Expression> idxList)
+    {
+        super(type, token);
+        this.name = token.getText();
+        this.idxList = idxList;
+    }
+
+    /**
+     * verify that variables mentioned in this expression are actually available in the supplied
+     * bindings list and infer/validate the type of this expression or its subexpressions
+     * where possible
+     *
+     * @param bindings the set of bindings in place at the point of evaluation of this expression
+     * @return true if all variables in this expression are bound and no type mismatches have
+     *         been detected during inference/validation.
+     */
+    public boolean bind(Bindings bindings) {
+        // we  have to make sure that the array name is bound and taht the index expressions
+        // contain valid bindings
+        boolean valid = true;
+
+        if (bindings.lookup(name) == null) {
+            System.err.println("ArrayExpression.bind : unbound symbol " + name + getPos());
+            valid = false;
+        }
+
+        Iterator<Expression> iterator = idxList.iterator();
+
+        while (iterator.hasNext()) {
+            valid &= iterator.next().bind(bindings);
+        }
+
+        return valid;
+    }
+
+    String name;
+    List<Expression> idxList;
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/BinaryOperExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/BinaryOperExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/BinaryOperExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,55 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.jboss.jbossts.orchestration.rule.binding.Bindings;
+import org.antlr.runtime.Token;
+
+/**
+ * binary operators includes arithmetic and comparison operators
+ */
+public class BinaryOperExpression extends OperExpression
+{
+    public BinaryOperExpression(int oper, Type type, Token token, Expression operand1, Expression operand2)
+    {
+        super(oper, type, token);
+        this.operand1 = operand1;
+        this.operand2 = operand2;
+    }
+
+    /**
+     * verify that variables mentioned in this expression are actually available in the supplied
+     * bindings list and infer/validate the type of this expression or its subexpressions
+     * where possible
+     *
+     * @param bindings the set of bindings in place at the point of evaluation of this expression
+     * @return true if all variables in this expression are bound and no type mismatches have
+     *         been detected during inference/validation.
+     */
+    public boolean bind(Bindings bindings) {
+        // we just need to ensure that the operands can find their bindings
+        // run both so we get as many errors as possible
+
+        boolean success = operand1.bind(bindings);
+        success  &= operand2.bind(bindings);
+        return success;
+    }
+
+    /**
+     * return the operand with the given index or null if the index is out of range
+     * @param index
+     * @return the operand with the given index
+     */
+    public Expression getOperand(int index)
+    {
+        if (index == 0) {
+            return operand1;
+        } else if (index == 1) {
+            return operand2;
+        }
+
+        return null;
+    }
+
+    private Expression operand1;
+    private Expression operand2;
+}
\ No newline at end of file

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/BitExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/BitExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/BitExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,17 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.antlr.runtime.Token;
+
+/**
+ * A binary arithmetic operator expression
+ */
+public class BitExpression extends BinaryOperExpression
+{
+    public BitExpression(int oper, Token token, Expression left, Expression right)
+    {
+        // n.b. left and right must be of integral type
+
+        super(oper, Type.promote(left.getType(), right.getType()), token, left, right);
+    }
+}
\ No newline at end of file

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/BooleanExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/BooleanExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/BooleanExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,15 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.antlr.runtime.Token;
+
+/**
+ * A binary arithmetic operator expression
+ */
+public class BooleanExpression extends BinaryOperExpression
+{
+    public BooleanExpression(int oper, Token token, Expression left, Expression right)
+    {
+        super(oper, Type.BOOLEAN, token, left, right);
+    }
+}
\ No newline at end of file

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ComparisonExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ComparisonExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ComparisonExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,15 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.antlr.runtime.Token;
+
+/**
+ * A binary comparison operator expression
+ */
+public class ComparisonExpression extends BooleanExpression
+{
+    public ComparisonExpression(int oper, Token token, Expression left, Expression right)
+    {
+        super(oper, token, left, right);
+    }
+}
\ No newline at end of file

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ConditionalEvalExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ConditionalEvalExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ConditionalEvalExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,15 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.antlr.runtime.Token;
+
+/**
+ * expression representing a ternary conditional evaluation (cond ? if_expr : else_expr)
+ */
+public class ConditionalEvalExpression extends TernaryOperExpression
+{
+    public ConditionalEvalExpression(Type type, Token token, Expression cond, Expression if_expr, Expression else_expr)
+    {
+        super(TERNARY, type, token, cond, if_expr, else_expr);
+    }
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/DollarExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/DollarExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/DollarExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,72 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.binding.Bindings;
+import org.jboss.jbossts.orchestration.rule.binding.Binding;
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.antlr.runtime.Token;
+
+/**
+ * an expression which refers either to a builtin variable or to a bound parameter of the
+ * triggering method for an ECA rule. builtin variables are written as a dollar sign followed
+ * by a leading alpha-underscore, trailing alpha-numeric-underscore string. bound parameters are
+ * written as a dollar sign followed by a non-negativeinteger parameter index
+ *
+ * e.g. if the rule applies to method foo.bar(int baz, Mumble mumble) then an occurrence of $2
+ * appearing as an expression in a rule would have type Mumble and evaluate to the value of mumble
+ * at the point when the rule was triggered.
+ *
+ * At present there are no special variables but we may need to add some later
+ */
+public class DollarExpression extends Expression
+{
+    public DollarExpression(Type type, Token token)
+    {
+        super(type, token);
+        String text = token.getText();
+        this.name = text.substring(1, text.length());
+        char first = name.charAt(0);
+        if ('0' <= first && first <= '9') {
+            try {
+                index = Integer.decode(name);
+            } catch (NumberFormatException nfe) {
+                // oops should not be possible according to tokenizer rules
+                index = -1;
+            }
+        }
+    }
+
+    /**
+     * verify that variables mentioned in this expression are actually available in the supplied
+     * bindings list and infer/validate the type of this expression or its subexpressions
+     * where possible
+
+     * @param bindings the set of bindings in place at the point of evaluation of this expression
+     * @return true if all variables in this expression are bound and no type mismatches have
+     * been detected during inference/validation.
+     */
+
+    public boolean bind(Bindings bindings) {
+        if (index < 0) {
+            // reference to special symbol
+            int l = dollarSymbols.length;
+            int i;
+            for (i = 0; i < l; i++) {
+                if (dollarSymbols[i].equals(name)) {
+                    return true;
+                }
+            }
+            System.err.println("DollarExpression.bind : invalid builtin symbol " + name + getPos());
+            return false;
+        } else {
+            // reference to positional parameter -- name must be a non-signed integer
+            // we will do type checking later
+            return true;
+        }
+    }
+
+    private String name;
+    private int index;
+
+    private static String[] dollarSymbols = {
+    };
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/Expression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/Expression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/Expression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,56 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.antlr.runtime.tree.CommonTree;
+import org.antlr.runtime.Token;
+import static org.jboss.jbossts.orchestration.rule.grammar.ECAGrammarParser.*;
+import org.jboss.jbossts.orchestration.rule.binding.Bindings;
+import org.jboss.jbossts.orchestration.rule.expression.*;
+import org.jboss.jbossts.orchestration.rule.type.Type;
+
+/**
+ * abstract class representing an evaluable expression. this is used in all 3 elements of ECA rules:
+ * as the value part of each of the event bindings in the binding list comprising an ECA rule event;
+ * as the condition expression of an ECA rule condition;and as an element of the actions list in an
+ * ECA rule action.
+ */
+public abstract class Expression
+{
+    /**
+     * Create a new expression.
+     * @param type the current type for this expression.
+     */
+    protected Expression(Type type, Token token)
+    {
+        this.type = type;
+        this.charPos = token.getCharPositionInLine();
+        this.line = token.getLine();
+    }
+
+    /**
+     * verify that variables mentioned in this expression are actually available in the supplied
+     * bindings list and infer/validate the type of this expression or its subexpressions
+     * where possible
+     *
+     * @param bindings the set of bindings in place at the point of evaluation of this expression
+     * @return true if all variables in this expression are bound and no type mismatches have
+     * been detected during inference/validation.
+     */
+    public abstract boolean bind(Bindings bindings);
+
+    public String getPos()
+    {
+        return " @ " + line + "." + charPos;
+    }
+
+    public Type getType()
+    {
+        return type;
+    }
+
+    /**
+     * the name of the
+     */
+    protected Type type;
+    protected int charPos;
+    protected int line;
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ExpressionHelper.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ExpressionHelper.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/ExpressionHelper.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,470 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.binding.Bindings;
+import static org.jboss.jbossts.orchestration.rule.grammar.ECAGrammarParser.*;
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.antlr.runtime.tree.CommonTree;
+import org.antlr.runtime.Token;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * helper class to transform parsed expression AST into an actual Expression instance
+ */
+public class ExpressionHelper
+{
+    public static Expression createExpression(Bindings bindings, CommonTree exprTree)
+    {
+        return createExpression(bindings, exprTree, Type.UNDEFINED);
+    }
+
+    public static Expression createExpression(Bindings bindings, CommonTree exprTree, Type type)
+    {
+        // we expect expr = simple_expr |
+        //                  (UNARYOP unary_oper expr) |
+        //                  (BINOP infix_oper simple_expr exp) |
+        //                  (TERNOP simple_expr expr expr)
+        //
+        // where simple_expr = (DOLLARSYM) |
+        //                     (SYMBOL)
+        //                     (ARRAY SYMBOL idx_list)
+        //                     (METH SYMBOL)
+        //                     (METH SYMBOL expr_list)
+        //                     (NUMBER)
+        //                     (STRING)
+        //                     expr
+
+        Token token = exprTree.getToken();
+        int tokenType = token.getType();
+        Expression expr = null;
+        switch (tokenType) {
+            case DOLLARSYM:
+            {
+                expr = new DollarExpression(type, token);
+            }
+            break;
+            case SYMBOL:
+            {
+                // check for embedded dots
+
+                String text = token.getText();
+                int dotIdx = text.lastIndexOf('.');
+                if (dotIdx < 0) {
+                    // direct variable reference
+                    expr = new Variable(type, token);
+                } else {
+                    // field reference either to an instance named by a field or or a static
+
+                    String[] parts = text.split("\\.");
+                    if (parts.length < 2) {
+                        // oops malformed symbol either "." ro "foo." or ".foo"
+                        // shoudl nto happen but ...
+                        System.err.println("ExpressionHelper.createExpression : unexpected symbol "  + token.getText() + " @ " + token.getLine() + "." + token.getCharPositionInLine());
+                    } else {
+                        String prefix = parts[0];
+
+                        if (bindings.lookup(prefix) != null) {
+                            // intitial segment of text identifies a bound variable so treat as
+                            // instance field access
+                            int l = parts.length - 1;
+                            String[] fields = new String[l];
+                            for (int i = 0; i < l; i++) {
+                                fields[i] = parts[i + 1];
+                            }
+                            expr = new FieldExpression(type, token, prefix, fields);
+                        } else {
+                            String clazzName = text.substring(0, dotIdx);
+                            String fieldName = text.substring(dotIdx);
+                            expr = new StaticExpression(type, token, clazzName, fieldName);
+                        }
+                    }
+                }
+            }
+            break;
+            case ARRAY:
+            {
+                CommonTree child0 = (CommonTree) exprTree.getChild(0);
+                CommonTree child1 = (CommonTree) exprTree.getChild(1);
+                token = child0.getToken();
+                if (token.getType() != SYMBOL) {
+                    System.err.println("ExpressionHelper.createExpression : unexpected token Type in array expression tree " + tokenType + " for token " + token.getText() + " @ " + token.getLine() + "." + token.getCharPositionInLine());
+                } else {
+                    List<Expression> indices = createExpressionList(bindings, child1, Type.INTEGER);
+                    if (indices != null) {
+                        expr = new ArrayExpression(type, token, indices);
+                    } else {
+                        System.err.println("ExpressionHelper.createExpression : invalid array index expression @ " + token.getLine() + "." + token.getCharPositionInLine());
+                    }
+                }
+            }
+            break;
+            case METH:
+            {
+                CommonTree child0 = (CommonTree) exprTree.getChild(0);
+                CommonTree child1;
+                if (exprTree.getChildCount() > 1) {
+                    child1 = (CommonTree) exprTree.getChild(1);
+                } else {
+                    child1 = null;
+                }
+                token = child0.getToken();
+                if (token.getType() != SYMBOL) {
+                    System.err.println("ExpressionHelper.createExpression : unexpected token Type in method expression tree " + tokenType + " for token " + token.getText() + " @ " + token.getLine() + "." + token.getCharPositionInLine());
+                } else if (child1 == null) {
+                    expr = new MethodExpression(type, token, new ArrayList<Expression>());
+                } else {
+                    List<Expression> args = createExpressionList(bindings, child1);
+                    if (args != null) {
+                        // need to separate out builtins, instance methdo calls and
+                        // static method calls
+                        expr = new MethodExpression(type, token, args);
+                    } else {
+                        System.err.println("ExpressionHelper.createExpression : method argument @ " + token.getLine() + "." + token.getCharPositionInLine());
+                    }
+                }
+            }
+            break;
+            case NUMBER:
+            {
+                expr = new NumericLiteral(token);
+            }
+            break;
+            case STRING:
+            {
+                expr = new StringLiteral(token);
+            }
+            break;
+            case UNOP:
+            {
+                expr = createUnaryExpression(bindings, exprTree, type);
+            }
+            break;
+            case BINOP:
+            {
+                expr = createBinaryExpression(bindings, exprTree, type);
+            }
+            break;
+            case TERNOP:
+            {
+                expr = createTernaryExpression(bindings, exprTree, type);
+            }
+            break;
+            default:
+            {
+                System.err.println("ExpressionHelper.createExpression : unexpected token Type in expression tree " + tokenType + " for token " + token.getText() + " @ " + token.getLine() + "." + token.getCharPositionInLine());
+            }
+            break;
+        }
+
+        if (expr != null) {
+            Type exprType = Type.dereference(expr.getType());
+            Type targetType = Type.dereference(type);
+            if (exprType.isDefined() && targetType.isDefined() && !targetType.isAssignableFrom(exprType)) {
+                // we already know this is an invalid type so notify an error and return null
+                System.err.println("ExpressionHelper.createExpression : invalid expression type " + exprType.getName() + " expecting " + targetType.getName() + " @ " + token.getLine() + "." + token.getCharPositionInLine());
+                return null;
+            } else if (targetType == Type.NUMBER && !exprType.isNumeric()) {
+                // we already know this is an invalid type so notify ane rror and return null
+                System.err.println("ExpressionHelper.createExpression : invalid expression type " + exprType.getName() + " expecting " + targetType.getName() + " @ " + token.getLine() + "." + token.getCharPositionInLine());
+                return null;
+            }
+            if (expr.bind(bindings)) {
+                return expr;
+            } else {
+                System.err.println("ExpressionHelper.createExpression : unknown reference in expression @ " + token.getLine() + "." + token.getCharPositionInLine());
+                return null;
+            }
+        } else {
+            return null;
+        }
+    }
+
+    public static Expression createUnaryExpression(Bindings bindings, CommonTree exprTree, Type type)
+    {
+        // we expect ^(UNOP unary_oper expr)
+
+        CommonTree child0 = (CommonTree) exprTree.getChild(0);
+        CommonTree child1 = (CommonTree) exprTree.getChild(1);
+        Expression expr;
+        Token token = child0.getToken();
+
+        switch (token.getType())
+        {
+            case TWIDDLE:
+            {
+                // the argument must be a numeric expression
+                Expression operand = createExpression(bindings, child1, Type.NUMBER);
+                if (operand != null) {
+                    expr = new TwiddleExpression(token, operand);
+                } else {
+                    expr = null;
+                }
+            }
+            break;
+            case NOT:
+            {
+                // the argument must be a boolean expression
+                Expression operand = createExpression(bindings, child1, Type.BOOLEAN);
+                if (operand != null) {
+                    expr = new NotExpression(token, operand);
+                } else {
+                    expr = null;
+                }
+            }
+            break;
+            default:
+            {
+                System.err.println("ExpressionHelper.createUnaryExpression : unexpected token Type in expression tree " + token.getType() + " for token " + token.getText() + " @ " + token.getLine() + "." + token.getCharPositionInLine());
+                expr = null;
+            }
+            break;
+        }
+
+        return expr;
+    }
+
+    public static Expression createBinaryExpression(Bindings bindings, CommonTree exprTree, Type type)
+    {
+        // we expect ^(BINOP infix_oper simple_expr expr)
+
+        CommonTree child0 = (CommonTree) exprTree.getChild(0);
+        CommonTree child1 = (CommonTree) exprTree.getChild(1);
+        CommonTree child2 = (CommonTree) exprTree.getChild(2);
+        Expression expr;
+        Token token = child0.getToken();
+
+        switch (token.getType())
+        {
+            case PLUS:
+            {
+                // this is a special case since we may be doing String concatenation
+                Expression operand1;
+                Expression operand2;
+                if (type == Type.STRING) {
+                    // must be doing String concatenation
+                    operand1 = createExpression(bindings, child1, Type.STRING);
+                    operand2 = createExpression(bindings, child1, Type.STRING);
+                    if (operand1 != null && operand2 != null) {
+                        expr = new StringPlusExpression(token, operand1,  operand2);
+                    } else {
+                        expr = null;
+                    }
+                } else if (type.isNumeric()) {
+                    // must be doing arithmetic
+                    operand1 = createExpression(bindings, child1, Type.NUMBER);
+                    operand2 = createExpression(bindings, child1, Type.NUMBER);
+                    if (operand1 != null && operand2 != null) {
+                        expr = new ArithmeticExpression(PLUS, token, operand1,  operand2);
+                    } else {
+                        expr = null;
+                    }
+                } else {
+                    // see if the operand gives us any type info
+                    operand1 = createExpression(bindings, child1, Type.UNDEFINED);
+                    if (operand1 != null) {
+                        if (operand1.getType().isNumeric()) {
+                            operand2 = createExpression(bindings, child1, Type.NUMBER);
+                            if (operand2 != null) {
+                                expr = new ArithmeticExpression(PLUS, token, operand1, operand2);
+                            } else {
+                                expr = null;
+                            }
+                        } else if (operand1.getType() == Type.STRING) {
+                            operand2 = createExpression(bindings, child1, Type.STRING);
+                            if (operand2 != null) {
+                                expr = new StringPlusExpression(token, operand1,  operand2);
+                            } else {
+                                expr = null;
+                            }
+                        } else {
+                            operand2 = createExpression(bindings, child1, Type.UNDEFINED);
+                            if (operand2 != null) {
+                                // create as generic plus expression which we will replace later during type
+                                // checking
+                                expr = new PlusExpression(token, operand1,  operand2);
+                            } else {
+                                expr = null;
+                            }
+                        }
+                    } else {
+                        // generate more errors if we can even though we are giving up
+                        operand2 = createExpression(bindings, child1, Type.UNDEFINED);
+                        expr = null;
+                    }
+                }
+            }
+            break;
+            case MINUS:
+            case MUL:
+            case DIV:
+            case MOD:
+            {
+                Expression operand1 = createExpression(bindings, child1, Type.NUMBER);
+                Expression operand2 = createExpression(bindings, child2, Type.NUMBER);
+
+                if (operand1 != null & operand2 != null) {
+                    return new ArithmeticExpression(token.getType(), token, operand1, operand2);
+                } else {
+                    expr = null;
+                }
+            }
+            break;
+            case BAND:
+            case BOR:
+            case BXOR:
+            {
+                Expression operand1 = createExpression(bindings, child1, Type.NUMBER);
+                Expression operand2 = createExpression(bindings, child2, Type.NUMBER);
+
+                if (operand1 != null & operand2 != null) {
+                    return new BitExpression(token.getType(), token, operand1, operand2);
+                } else {
+                    expr = null;
+                }
+            }
+            break;
+            case AND:
+            case OR:
+            {
+                Expression operand1 = createExpression(bindings, child1, Type.BOOLEAN);
+                Expression operand2 = createExpression(bindings, child2, Type.BOOLEAN);
+
+                if (operand1 != null & operand2 != null) {
+                    expr = new LogicalExpression(token.getType(), token, operand1, operand2);
+                } else {
+                    expr = null;
+                }
+            }
+            break;
+            case EQ:
+            case NEQ:
+            case GT:
+            case LT:
+            case GEQ:
+            case LEQ:
+            {
+                Expression operand1 = createExpression(bindings, child1, Type.NUMBER);
+                Expression operand2 = createExpression(bindings, child2, Type.NUMBER);
+
+                if (operand1 != null & operand2 != null) {
+                    expr = new ComparisonExpression(token.getType(), token, operand1, operand2);
+                } else {
+                    expr = null;
+                }
+            }
+            default:
+            {
+                System.err.println("ExpressionHelper.createBinaryExpression : unexpected token Type in expression tree " + token.getType() + " for token " + token.getText() + " @ " + token.getLine() + "." + token.getCharPositionInLine());
+                expr = null;
+            }
+            break;
+        }
+
+        return expr;
+    }
+
+    public static Expression createTernaryExpression(Bindings bindings, CommonTree exprTree, Type type)
+    {
+        // we expect ^(TERNOP ternary_oper simple_expr expr expr)
+
+        CommonTree child0 = (CommonTree) exprTree.getChild(0);
+        CommonTree child1 = (CommonTree) exprTree.getChild(1);
+        CommonTree child2 = (CommonTree) exprTree.getChild(2);
+        CommonTree child3 = (CommonTree) exprTree.getChild(3);
+        Expression expr;
+        Token token = child0.getToken();
+
+        switch (token.getType())
+        {
+            case TERN_IF:
+            {
+                // the argument must be a numeric expression
+                Expression operand1 = createExpression(bindings, child1, Type.BOOLEAN);
+                Expression operand2 = createExpression(bindings, child1, Type.UNDEFINED);
+                Expression operand3 = createExpression(bindings, child1, Type.UNDEFINED);
+                if (operand1 != null && operand2 != null && operand3 != null) {
+                    Type type2 = Type.dereference(operand2.getType());
+                    Type type3 = Type.dereference(operand3.getType());
+                    if (type2.isNumeric() || type3.isNumeric()) {
+                        expr = new TernaryOperExpression(TERN_IF, Type.promote(type2, type3),  token, operand1,  operand2, operand3);
+                    } else if (type2.isDefined() && type3.isDefined()) {
+                        // since they are not numeric we have to have the same type
+                        if (type2 == type3) {
+                            // use this type
+                            expr = new TernaryOperExpression(TERN_IF, type2,  token, operand1,  operand2, operand3);
+                        } else {
+                            // mismatched types so don't generate a result
+                            System.err.println("ExpressionHelper.createTernaryExpression : mismatched types " + type2.getName() + " and " + type3.getName()  + " in conditional expression " + token.getType() + " for token " + token.getText() + " @ " + token.getLine() + "." + token.getCharPositionInLine());
+                            expr = null;
+                        }
+                    } else {
+                        // have to wait for type check to resolve types
+                        expr = new TernaryOperExpression(TERN_IF, Type.UNDEFINED,  token, operand1,  operand2, operand3);
+                    }
+                } else {
+                    expr = null;
+                }
+            }
+            break;
+            default:
+            {
+                System.err.println("ExpressionHelper.createTernaryExpression : unexpected token Type in expression tree " + token.getType() + " for token " + token.getText() + " @ " + token.getLine() + "." + token.getCharPositionInLine());
+                expr = null;
+            }
+            break;
+        }
+
+        return expr;
+    }
+
+    public static List<Expression> createExpressionList(Bindings bindings, CommonTree exprTree)
+    {
+        return createExpressionList(bindings, exprTree, Type.UNDEFINED);
+
+    }
+    public static List<Expression> createExpressionList(Bindings bindings, CommonTree exprTree, Type type)
+    {
+        // we expect expr_list = ^(EXPR) |
+        //                       ^(SEPR expr expr_list)
+
+        List<Expression> exprList = new ArrayList<Expression>();
+        boolean success = true;
+
+        while (exprTree != null)
+        {
+            switch (exprTree.getToken().getType())
+            {
+                case SEPR:
+                {
+                    CommonTree child0 = (CommonTree) exprTree.getChild(0);
+                    CommonTree child1 = (CommonTree) exprTree.getChild(1);
+                    Expression expr = createExpression(bindings, child0, type);
+                    if (expr != null) {
+                        exprList.add(expr);
+                    } else {
+                        success &= false;
+                    }
+                    exprTree = child1;
+                }
+                break;
+                default:
+                {
+                    Expression expr = createExpression(bindings, exprTree, type);
+                    if (expr != null) {
+                        exprList.add(expr);
+                    } else {
+                        success &= false;
+                    }
+                    exprTree = null;
+                }
+                break;
+            }
+        }
+        if (success) {
+            return exprList;
+        } else {
+            return null;
+        }
+    }
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/FieldExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/FieldExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/FieldExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,59 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.binding.Bindings;
+import org.jboss.jbossts.orchestration.rule.binding.Binding;
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.antlr.runtime.Token;
+
+/**
+ * an expression which identifies an instance field reference
+ */
+public class FieldExpression extends Expression
+{
+    public FieldExpression(Type type, Token token, String ref, String[] fields) {
+        // type is the type of last field
+        // ownerType[i] is the type of the owner of field[i]
+        // so ownerType[0] is the type of ref;
+        super(type, token);
+        this.ref = ref;
+        this.fields = fields;
+        int len = fields.length;
+        this.ownerType = new Type[len];
+        for (int i = 0; i < len; i++) {
+            ownerType[i] = Type.UNDEFINED;
+        }
+    }
+
+    /**
+     * verify that variables mentioned in this expression are actually available in the supplied
+     * bindings list and infer/validate the type of this expression or its subexpressions
+     * where possible
+     *
+     * @param bindings the set of bindings in place at the point of evaluation of this expression
+     * @return true if all variables in this expression are bound and no type mismatches have
+     *         been detected during inference/validation.
+     */
+    public boolean bind(Bindings bindings) {
+        // ensure that there is a binding with this name
+
+        Binding binding = bindings.lookup(ref);
+
+        if (binding == null) {
+            System.err.println("FieldExpresssion.bind : unbound instance " + ref + getPos());
+            return false;
+        }
+
+        // use the binding type to type ref
+
+        if (ownerType[0].isUndefined()) {
+            Type bindingType = binding.getType();
+            ownerType[0] = bindingType;
+        }
+
+        return true;
+    }
+
+    private String ref;
+    private String[] fields;
+    private Type[] ownerType;
+}
\ No newline at end of file

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/LogicalExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/LogicalExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/LogicalExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,15 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.antlr.runtime.Token;
+
+/**
+ * A binary logical operator expression
+ */
+public class LogicalExpression extends BooleanExpression
+{
+    public LogicalExpression(int oper, Token token, Expression left, Expression right)
+    {
+        super(oper, token, left, right);
+    }
+}
\ No newline at end of file

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/MethodExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/MethodExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/MethodExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,45 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.jboss.jbossts.orchestration.rule.binding.Bindings;
+import org.antlr.runtime.Token;
+import java.util.List;
+import java.util.Iterator;
+
+/**
+ * an expression which identifies a method invocation
+ */
+public class MethodExpression extends Expression
+{
+    public MethodExpression(Type type, Token token, List<Expression> arguments) {
+        super(type, token);
+        this.name = token.getText();
+        this.arguments = arguments;
+    }
+
+    /**
+     * verify that variables mentioned in this expression are actually available in the supplied
+     * bindings list and infer/validate the type of this expression or its subexpressions
+     * where possible
+     *
+     * @param bindings the set of bindings in place at the point of evaluation of this expression
+     * @return true if all variables in this expression are bound and no type mismatches have
+     *         been detected during inference/validation.
+     */
+    public boolean bind(Bindings bindings) {
+        // we just have to check that the arguemnt expressions ahve valid bindings
+
+        boolean valid = true;
+
+        Iterator<Expression> iterator = arguments.iterator();
+
+        while (iterator.hasNext()) {
+            valid &= iterator.next().bind(bindings);
+        }
+
+        return valid;
+    }
+
+    private String name;
+    private List<Expression> arguments;
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/NotExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/NotExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/NotExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,14 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.antlr.runtime.Token;
+
+/**
+ */
+public class NotExpression extends UnaryOperExpression
+{
+    public NotExpression(Token token, Expression operand)
+    {
+        super(NOT, Type.BOOLEAN, token, operand);
+    }
+}
\ No newline at end of file

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/NumericLiteral.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/NumericLiteral.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/NumericLiteral.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,93 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.jboss.jbossts.orchestration.rule.binding.Bindings;
+import org.antlr.runtime.Token;
+
+/**
+ */
+public class NumericLiteral extends Expression
+{
+
+    public NumericLiteral(Token token) {
+        super(checkType(token.getText()), token);
+
+        this.text = token.getText();
+    }
+
+    /**
+     * verify that variables mentioned in this expression are actually available in the supplied
+     * bindings list and infer/validate the type of this expression or its subexpressions
+     * where possible
+     *
+     * @param bindings the set of bindings in place at the point of evaluation of this expression
+     * @return true if all variables in this expression are bound and no type mismatches have
+     *         been detected during inference/validation.
+     */
+    public boolean bind(Bindings bindings) {
+        // no bindings to check but stash a valid value to help with type checking
+        if (type == Type.FLOAT) {
+            value = Float.valueOf(text);
+        } else if (type == Type.DOUBLE) {
+            value = Float.valueOf(text);
+        } else if (type == Type.INTEGER) {
+            value = Integer.valueOf(text);
+        } else if (type == Type.LONG) {
+            value = Long.valueOf(text);            
+        } else {
+            // should not happen!
+            value = Integer.valueOf("0");
+            System.err.println("NumericLiteral.bind : invalid number format " + text + getPos());
+            return false;
+        }
+        return true;
+    }
+
+    private static Type checkType(String text)
+    {
+        if (text.contains("e") | text.contains("E") | text.contains(".")) {
+            return checkFloat(text);
+        } else {
+            return checkInt(text);
+        }
+    }
+
+    private static Type checkFloat(String text)
+    {
+        try {
+            Float.valueOf(text);
+            return Type.FLOAT;
+        } catch (NumberFormatException e) {
+            // ok retry as Double
+            try {
+                Double.valueOf(text);
+                return Type.DOUBLE;
+            } catch (NumberFormatException e1) {
+                // should not happen!
+                System.err.println("NumericLiteral.checkFloat : invalid float format " + text);
+                return Type.NUMBER;
+            }
+        }
+    }
+
+    private static Type checkInt(String text)
+    {
+        try {
+            Integer.decode(text);
+            return Type.INTEGER;
+        } catch (NumberFormatException e) {
+            // ok retry as Double
+            try {
+                Long.decode(text);
+                return Type.LONG;
+            } catch (NumberFormatException e1) {
+                // should not happen!
+                System.err.println("NumericLiteral.checkInt : invalid integer format " + text);
+                return Type.NUMBER;
+            }
+        }
+    }
+
+    private String text;
+    private Object value;
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/OperExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/OperExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/OperExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,58 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.antlr.runtime.Token;
+import org.jboss.jbossts.orchestration.rule.type.Type;
+
+import java.util.Iterator;
+
+/**
+ * generic operator expression subsumes unary, binary and ternary operators
+ */
+public abstract class OperExpression extends Expression
+{
+    OperExpression(int oper, Type type, Token token)
+    {
+        super(type, token);
+
+        this.oper = oper;
+    }
+
+    protected int oper;
+
+    /**
+     * return the operand with the given index or null if the index is out of range
+     * @param index
+     * @return the operand with the given index
+     */
+    public abstract Expression getOperand(int index);
+
+    final public static int UNARY       = 0x1000;
+    final public static int BINARY      = 0x2000;
+    final public static int TERNARY     = 0x4000;
+
+    final public static int NOT         = 0x0010 | UNARY;
+
+    final public static int TWIDDLE     = 0x0020 | UNARY;
+
+    final public static int OR          = 0x0040 | BINARY;
+    final public static int AND         = 0x0041 | BINARY;
+
+    final public static int EQ          = 0x0080 | BINARY;
+    final public static int NEQ         = 0x0081 | BINARY;
+    final public static int GT          = 0x0082 | BINARY;
+    final public static int LT          = 0x0083 | BINARY;
+    final public static int GEQ         = 0x0084 | BINARY;
+    final public static int LEQ         = 0x0085 | BINARY;
+
+    final public static int BOR         = 0x0100 | BINARY;
+    final public static int BAND        = 0x0101 | BINARY;
+    final public static int BXOR        = 0x0102 | BINARY;
+
+    final public static int MUL         = 0x0201 | BINARY;
+    final public static int DIV         = 0x0202 | BINARY;
+    final public static int PLUS        = 0x0203| BINARY;
+    final public static int MINUS       = 0x0204 | BINARY;
+    final public static int MOD         = 0x0205 | BINARY;
+
+    final public static int IF          = 0x0400 | TERNARY;
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/PlusExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/PlusExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/PlusExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,17 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.antlr.runtime.Token;
+
+/**
+ * A plus operator expression which handles the case where we do not know the type of the first
+ * operand. this expression must be replaced by an expression with a known type during type
+ * checking
+ */
+public class PlusExpression extends BinaryOperExpression
+{
+    public PlusExpression(Token token, Expression left, Expression right)
+    {
+        super(PLUS, Type.UNDEFINED, token, left, right);
+    }
+}
\ No newline at end of file

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/StaticExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/StaticExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/StaticExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,37 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.binding.Bindings;
+import org.jboss.jbossts.orchestration.rule.binding.Binding;
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.antlr.runtime.Token;
+
+/**
+ * an expression which identifies aa static field reference
+ */
+public class StaticExpression extends Expression
+{
+    public StaticExpression(Type type, Token token, String clazzName, String fieldName) {
+        // type is the type of static field
+        super(type, token);
+        this.clazzName = clazzName;
+        this.fieldName = fieldName;
+    }
+
+    /**
+     * verify that variables mentioned in this expression are actually available in the supplied
+     * bindings list and infer/validate the type of this expression or its subexpressions
+     * where possible
+     *
+     * @param bindings the set of bindings in place at the point of evaluation of this expression
+     * @return true if all variables in this expression are bound and no type mismatches have
+     *         been detected during inference/validation.
+     */
+    public boolean bind(Bindings bindings) {
+        // nothing to verify
+
+        return true;
+    }
+
+    private String fieldName;
+    private String clazzName;
+}
\ No newline at end of file

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/StringLiteral.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/StringLiteral.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/StringLiteral.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,33 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.jboss.jbossts.orchestration.rule.binding.Bindings;
+import org.antlr.runtime.Token;
+
+/**
+ * an expression which identifies a character string.
+ */
+public class StringLiteral extends Expression
+{
+    public StringLiteral(Token token)
+    {
+        super(Type.STRING, token);
+
+        this.text = token.getText();
+    }
+
+    /**
+     * verify that variables mentioned in this expression are actually available in the supplied
+     * bindings list and infer/validate the type of this expression or its subexpressions
+     * where possible
+     *
+     * @param bindings the set of bindings in place at the point of evaluation of this expression
+     * @return true if all variables in this expression are bound and no type mismatches have
+     *         been detected during inference/validation.
+     */
+    public boolean bind(Bindings bindings) {
+        return true;
+    }
+
+    private String text;
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/StringPlusExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/StringPlusExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/StringPlusExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,15 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.antlr.runtime.Token;
+
+/**
+ * A binary string concatenation operator expression
+ */
+public class StringPlusExpression extends BinaryOperExpression
+{
+    public StringPlusExpression(Token token, Expression left, Expression right)
+    {
+        super(PLUS, Type.STRING, token, left, right);
+    }
+}
\ No newline at end of file

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/TernaryOperExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/TernaryOperExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/TernaryOperExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,61 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.jboss.jbossts.orchestration.rule.binding.Bindings;
+import org.antlr.runtime.Token;
+
+/**
+ * ternary operators includes conditional evaluation operator 'cond ? if_expr : else_expr'
+ */
+public class TernaryOperExpression extends OperExpression
+{
+    public TernaryOperExpression(int oper, Type type, Token token, Expression operand1,
+                                 Expression operand2, Expression operand3)
+    {
+        super(oper, type, token);
+        this.operand1 = operand1;
+        this.operand2 = operand2;
+        this.operand3 = operand3;
+    }
+
+    /**
+     * verify that variables mentioned in this expression are actually available in the supplied
+     * bindings list and infer/validate the type of this expression or its subexpressions
+     * where possible
+     *
+     * @param bindings the set of bindings in place at the point of evaluation of this expression
+     * @return true if all variables in this expression are bound and no type mismatches have
+     *         been detected during inference/validation.
+     */
+    public boolean bind(Bindings bindings) {
+        // we just need to ensure that the operands can find their bindings
+        // run both so we get as many errors as possible
+
+        boolean success = operand1.bind(bindings);
+        success &= operand2.bind(bindings);
+        success &= operand3.bind(bindings);
+        return success;
+    }
+
+    /**
+     * return the operand with the given index or null if the index is out of range
+     * @param index
+     * @return the operand with the given index
+     */
+    public Expression getOperand(int index)
+    {
+        if (index == 0) {
+            return operand1;
+        } else if (index == 1) {
+            return operand2;
+        } else if (index == 2) {
+            return operand3;
+        }
+
+        return null;
+    }
+
+    private Expression operand1;
+    private Expression operand2;
+    private Expression operand3;
+}
\ No newline at end of file

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/TwiddleExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/TwiddleExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/TwiddleExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,14 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.antlr.runtime.Token;
+
+/**
+ */
+public class TwiddleExpression extends UnaryOperExpression
+{
+    public TwiddleExpression(Token token, Expression operand)
+    {
+        super(TWIDDLE, operand.getType(), token, operand);
+    }
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/UnaryOperExpression.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/UnaryOperExpression.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/UnaryOperExpression.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,49 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.jboss.jbossts.orchestration.rule.binding.Bindings;
+import org.antlr.runtime.Token;
+
+/**
+ * unary operators includes boolean NOT and arithmetic TWIDDLE
+ * n.b. unary MINUS is not currently supported except as part of number
+ * parsing
+ */
+public class UnaryOperExpression extends OperExpression
+{
+    public UnaryOperExpression(int oper, Type type, Token token, Expression operand)
+    {
+        super(oper, type, token);
+        this.operand = operand;
+    }
+
+    /**
+     * verify that variables mentioned in this expression are actually available in the supplied
+     * bindings list and infer/validate the type of this expression or its subexpressions
+     * where possible
+     *
+     * @param bindings the set of bindings in place at the point of evaluation of this expression
+     * @return true if all variables in this expression are bound and no type mismatches have
+     *         been detected during inference/validation.
+     */
+    public boolean bind(Bindings bindings) {
+        // we just need to ensure that the operand can find its bindings
+        return operand.bind(bindings);
+    }
+
+    /**
+     * return the operand with the given index or null if the index is out of range
+     * @param index
+     * @return the operand with the given index
+     */
+    public Expression getOperand(int index)
+    {
+        if (index != 0) {
+            return null;
+        }
+
+        return operand;
+    }
+
+    private Expression operand;
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/Variable.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/Variable.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/expression/Variable.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,51 @@
+package org.jboss.jbossts.orchestration.rule.expression;
+
+import org.jboss.jbossts.orchestration.rule.binding.Bindings;
+import org.jboss.jbossts.orchestration.rule.binding.Binding;
+import org.jboss.jbossts.orchestration.rule.type.Type;
+import org.antlr.runtime.Token;
+
+/**
+ * an expression which identifies a variable occurring either as an LVALUE on the LHS of an event
+ * binding in the rule's event or as an RVALUE mentioned in the RHS of an event binding or in thre
+ * rule's conditon or action.
+ */
+public class Variable extends Expression
+{
+    public Variable(Type type, Token token) {
+        super(type, token);
+        this.name = token.getText();
+    }
+
+    /**
+     * verify that variables mentioned in this expression are actually available in the supplied
+     * bindings list and infer/validate the type of this expression or its subexpressions
+     * where possible
+     *
+     * @param bindings the set of bindings in place at the point of evaluation of this expression
+     * @return true if all variables in this expression are bound and no type mismatches have
+     *         been detected during inference/validation.
+     */
+    public boolean bind(Bindings bindings) {
+        // ensure that there is a binding with this name
+
+        Binding binding = bindings.lookup(name);
+
+        if (binding == null) {
+            System.err.println("VarExpresssion.bind : unbound variable " + name + getPos());                
+            return false;
+        }
+        // if the binding has a defined type and this has an undefined one then adopt it
+
+        if (type.isUndefined()) {
+            Type bindingType = binding.getType();
+            if (!bindingType.isUndefined()) {
+                this.type = bindingType;
+            }
+        }
+
+        return true;
+    }
+
+    private String name;
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/grammar/ECAGrammarParser.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/grammar/ECAGrammarParser.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/grammar/ECAGrammarParser.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,3201 @@
+// $ANTLR 3.0.1 dd/grammar/ECAGrammar.g 2008-07-18 14:16:03
+
+package org.jboss.jbossts.orchestration.rule.grammar;
+
+
+import org.antlr.runtime.*;
+import java.util.Stack;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+
+import org.antlr.runtime.tree.*;
+
+public class ECAGrammarParser extends Parser {
+    public static final String[] tokenNames = new String[] {
+        "<invalid>", "<EOR>", "<DOWN>", "<UP>", "DIGIT", "POSDIGIT", "SIGN", "BAREINT", "INTEGER", "POINT", "EXPPART", "FLOAT", "NUMBER", "WHEN", "IF", "DO", "LPAREN", "RPAREN", "LSQUARE", "RSQUARE", "LBRACE", "RBRACE", "SEPR", "DOT", "ASSIGN", "OR", "AND", "NOT", "EQ", "NEQ", "GT", "LT", "GEQ", "LEQ", "BOR", "BAND", "BXOR", "TWIDDLE", "MUL", "DIV", "PLUS", "MINUS", "MOD", "TERN_IF", "COLON", "LETTER", "UNDERSCORE", "QUOTE", "DQUOTE", "SPACE", "NEWLINE", "PUNCT", "STRING", "BARESYM", "QUOTSYM", "DOTSYM", "SYMBOL", "DOLLAR", "DOLLARSYM", "WS", "Tokens", "UNOP", "BINOP", "TERNOP", "METH", "ARRAY", "NUM_LIT", "STRING_LIT"
+    };
+    public static final int MINUS=41;
+    public static final int ARRAY=65;
+    public static final int NUMBER=12;
+    public static final int FLOAT=11;
+    public static final int POSDIGIT=5;
+    public static final int TWIDDLE=37;
+    public static final int LEQ=33;
+    public static final int MOD=42;
+    public static final int GEQ=32;
+    public static final int DQUOTE=48;
+    public static final int BOR=34;
+    public static final int OR=25;
+    public static final int STRING_LIT=67;
+    public static final int BAREINT=7;
+    public static final int LBRACE=20;
+    public static final int DOT=23;
+    public static final int NEWLINE=50;
+    public static final int RBRACE=21;
+    public static final int INTEGER=8;
+    public static final int AND=26;
+    public static final int NUM_LIT=66;
+    public static final int ASSIGN=24;
+    public static final int SYMBOL=56;
+    public static final int RPAREN=17;
+    public static final int LPAREN=16;
+    public static final int SIGN=6;
+    public static final int METH=64;
+    public static final int DIGIT=4;
+    public static final int PLUS=40;
+    public static final int BINOP=62;
+    public static final int BAND=35;
+    public static final int NEQ=29;
+    public static final int TERNOP=63;
+    public static final int SPACE=49;
+    public static final int LETTER=45;
+    public static final int LSQUARE=18;
+    public static final int DO=15;
+    public static final int POINT=9;
+    public static final int WHEN=13;
+    public static final int BARESYM=53;
+    public static final int SEPR=22;
+    public static final int WS=59;
+    public static final int STRING=52;
+    public static final int EQ=28;
+    public static final int QUOTSYM=54;
+    public static final int LT=31;
+    public static final int GT=30;
+    public static final int DOLLAR=57;
+    public static final int RSQUARE=19;
+    public static final int TERN_IF=43;
+    public static final int QUOTE=47;
+    public static final int UNOP=61;
+    public static final int MUL=38;
+    public static final int EXPPART=10;
+    public static final int PUNCT=51;
+    public static final int IF=14;
+    public static final int EOF=-1;
+    public static final int Tokens=60;
+    public static final int COLON=44;
+    public static final int DIV=39;
+    public static final int DOTSYM=55;
+    public static final int BXOR=36;
+    public static final int NOT=27;
+    public static final int UNDERSCORE=46;
+    public static final int DOLLARSYM=58;
+
+        public ECAGrammarParser(TokenStream input) {
+            super(input);
+            ruleMemo = new HashMap[53+1];
+         }
+        
+    protected TreeAdaptor adaptor = new CommonTreeAdaptor();
+
+    public void setTreeAdaptor(TreeAdaptor adaptor) {
+        this.adaptor = adaptor;
+    }
+    public TreeAdaptor getTreeAdaptor() {
+        return adaptor;
+    }
+
+    public String[] getTokenNames() { return tokenNames; }
+    public String getGrammarFileName() { return "dd/grammar/ECAGrammar.g"; }
+
+
+    public static class eca_rule_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start eca_rule
+    // dd/grammar/ECAGrammar.g:26:1: eca_rule : eca EOF ;
+    public final eca_rule_return eca_rule() throws RecognitionException {
+        eca_rule_return retval = new eca_rule_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        Token EOF2=null;
+        eca_return eca1 = null;
+
+
+        Object EOF2_tree=null;
+
+        try {
+            // dd/grammar/ECAGrammar.g:26:10: ( eca EOF )
+            // dd/grammar/ECAGrammar.g:26:12: eca EOF
+            {
+            root_0 = (Object)adaptor.nil();
+
+            pushFollow(FOLLOW_eca_in_eca_rule86);
+            eca1=eca();
+            _fsp--;
+            if (failed) return retval;
+            if ( backtracking==0 ) adaptor.addChild(root_0, eca1.getTree());
+            EOF2=(Token)input.LT(1);
+            match(input,EOF,FOLLOW_EOF_in_eca_rule88); if (failed) return retval;
+            if ( backtracking==0 ) {
+            EOF2_tree = (Object)adaptor.create(EOF2);
+            adaptor.addChild(root_0, EOF2_tree);
+            }
+
+            }
+
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end eca_rule
+
+    public static class eca_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start eca
+    // dd/grammar/ECAGrammar.g:28:1: eca : ( WHEN event -> ^( WHEN event ) | IF condition -> ^( IF condition ) | DO action -> ^( DO action ) );
+    public final eca_return eca() throws RecognitionException {
+        eca_return retval = new eca_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        Token WHEN3=null;
+        Token IF5=null;
+        Token DO7=null;
+        event_return event4 = null;
+
+        condition_return condition6 = null;
+
+        action_return action8 = null;
+
+
+        Object WHEN3_tree=null;
+        Object IF5_tree=null;
+        Object DO7_tree=null;
+        RewriteRuleTokenStream stream_DO=new RewriteRuleTokenStream(adaptor,"token DO");
+        RewriteRuleTokenStream stream_WHEN=new RewriteRuleTokenStream(adaptor,"token WHEN");
+        RewriteRuleTokenStream stream_IF=new RewriteRuleTokenStream(adaptor,"token IF");
+        RewriteRuleSubtreeStream stream_action=new RewriteRuleSubtreeStream(adaptor,"rule action");
+        RewriteRuleSubtreeStream stream_event=new RewriteRuleSubtreeStream(adaptor,"rule event");
+        RewriteRuleSubtreeStream stream_condition=new RewriteRuleSubtreeStream(adaptor,"rule condition");
+        try {
+            // dd/grammar/ECAGrammar.g:28:5: ( WHEN event -> ^( WHEN event ) | IF condition -> ^( IF condition ) | DO action -> ^( DO action ) )
+            int alt1=3;
+            switch ( input.LA(1) ) {
+            case WHEN:
+                {
+                alt1=1;
+                }
+                break;
+            case IF:
+                {
+                alt1=2;
+                }
+                break;
+            case DO:
+                {
+                alt1=3;
+                }
+                break;
+            default:
+                if (backtracking>0) {failed=true; return retval;}
+                NoViableAltException nvae =
+                    new NoViableAltException("28:1: eca : ( WHEN event -> ^( WHEN event ) | IF condition -> ^( IF condition ) | DO action -> ^( DO action ) );", 1, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt1) {
+                case 1 :
+                    // dd/grammar/ECAGrammar.g:28:7: WHEN event
+                    {
+                    WHEN3=(Token)input.LT(1);
+                    match(input,WHEN,FOLLOW_WHEN_in_eca97); if (failed) return retval;
+                    if ( backtracking==0 ) stream_WHEN.add(WHEN3);
+
+                    pushFollow(FOLLOW_event_in_eca99);
+                    event4=event();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_event.add(event4.getTree());
+
+                    // AST REWRITE
+                    // elements: event, WHEN
+                    // token labels: 
+                    // rule labels: retval
+                    // token list labels: 
+                    // rule list labels: 
+                    if ( backtracking==0 ) {
+                    retval.tree = root_0;
+                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);
+
+                    root_0 = (Object)adaptor.nil();
+                    // 28:18: -> ^( WHEN event )
+                    {
+                        // dd/grammar/ECAGrammar.g:28:21: ^( WHEN event )
+                        {
+                        Object root_1 = (Object)adaptor.nil();
+                        root_1 = (Object)adaptor.becomeRoot(stream_WHEN.next(), root_1);
+
+                        adaptor.addChild(root_1, stream_event.next());
+
+                        adaptor.addChild(root_0, root_1);
+                        }
+
+                    }
+
+                    }
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAGrammar.g:29:4: IF condition
+                    {
+                    IF5=(Token)input.LT(1);
+                    match(input,IF,FOLLOW_IF_in_eca112); if (failed) return retval;
+                    if ( backtracking==0 ) stream_IF.add(IF5);
+
+                    pushFollow(FOLLOW_condition_in_eca114);
+                    condition6=condition();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_condition.add(condition6.getTree());
+
+                    // AST REWRITE
+                    // elements: IF, condition
+                    // token labels: 
+                    // rule labels: retval
+                    // token list labels: 
+                    // rule list labels: 
+                    if ( backtracking==0 ) {
+                    retval.tree = root_0;
+                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);
+
+                    root_0 = (Object)adaptor.nil();
+                    // 29:18: -> ^( IF condition )
+                    {
+                        // dd/grammar/ECAGrammar.g:29:21: ^( IF condition )
+                        {
+                        Object root_1 = (Object)adaptor.nil();
+                        root_1 = (Object)adaptor.becomeRoot(stream_IF.next(), root_1);
+
+                        adaptor.addChild(root_1, stream_condition.next());
+
+                        adaptor.addChild(root_0, root_1);
+                        }
+
+                    }
+
+                    }
+
+                    }
+                    break;
+                case 3 :
+                    // dd/grammar/ECAGrammar.g:30:4: DO action
+                    {
+                    DO7=(Token)input.LT(1);
+                    match(input,DO,FOLLOW_DO_in_eca128); if (failed) return retval;
+                    if ( backtracking==0 ) stream_DO.add(DO7);
+
+                    pushFollow(FOLLOW_action_in_eca130);
+                    action8=action();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_action.add(action8.getTree());
+
+                    // AST REWRITE
+                    // elements: DO, action
+                    // token labels: 
+                    // rule labels: retval
+                    // token list labels: 
+                    // rule list labels: 
+                    if ( backtracking==0 ) {
+                    retval.tree = root_0;
+                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);
+
+                    root_0 = (Object)adaptor.nil();
+                    // 30:14: -> ^( DO action )
+                    {
+                        // dd/grammar/ECAGrammar.g:30:17: ^( DO action )
+                        {
+                        Object root_1 = (Object)adaptor.nil();
+                        root_1 = (Object)adaptor.becomeRoot(stream_DO.next(), root_1);
+
+                        adaptor.addChild(root_1, stream_action.next());
+
+                        adaptor.addChild(root_0, root_1);
+                        }
+
+                    }
+
+                    }
+
+                    }
+                    break;
+
+            }
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end eca
+
+    public static class event_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start event
+    // dd/grammar/ECAGrammar.g:35:1: event : bindings ;
+    public final event_return event() throws RecognitionException {
+        event_return retval = new event_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        bindings_return bindings9 = null;
+
+
+
+        try {
+            // dd/grammar/ECAGrammar.g:35:7: ( bindings )
+            // dd/grammar/ECAGrammar.g:35:9: bindings
+            {
+            root_0 = (Object)adaptor.nil();
+
+            pushFollow(FOLLOW_bindings_in_event150);
+            bindings9=bindings();
+            _fsp--;
+            if (failed) return retval;
+            if ( backtracking==0 ) adaptor.addChild(root_0, bindings9.getTree());
+
+            }
+
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end event
+
+    public static class bindings_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start bindings
+    // dd/grammar/ECAGrammar.g:40:1: bindings : ( binding SEPR bindings -> ^( SEPR binding bindings ) | binding );
+    public final bindings_return bindings() throws RecognitionException {
+        bindings_return retval = new bindings_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        Token SEPR11=null;
+        binding_return binding10 = null;
+
+        bindings_return bindings12 = null;
+
+        binding_return binding13 = null;
+
+
+        Object SEPR11_tree=null;
+        RewriteRuleTokenStream stream_SEPR=new RewriteRuleTokenStream(adaptor,"token SEPR");
+        RewriteRuleSubtreeStream stream_bindings=new RewriteRuleSubtreeStream(adaptor,"rule bindings");
+        RewriteRuleSubtreeStream stream_binding=new RewriteRuleSubtreeStream(adaptor,"rule binding");
+        try {
+            // dd/grammar/ECAGrammar.g:40:10: ( binding SEPR bindings -> ^( SEPR binding bindings ) | binding )
+            int alt2=2;
+            int LA2_0 = input.LA(1);
+
+            if ( (LA2_0==SYMBOL) ) {
+                int LA2_1 = input.LA(2);
+
+                if ( (synpred3()) ) {
+                    alt2=1;
+                }
+                else if ( (true) ) {
+                    alt2=2;
+                }
+                else {
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("40:1: bindings : ( binding SEPR bindings -> ^( SEPR binding bindings ) | binding );", 2, 1, input);
+
+                    throw nvae;
+                }
+            }
+            else {
+                if (backtracking>0) {failed=true; return retval;}
+                NoViableAltException nvae =
+                    new NoViableAltException("40:1: bindings : ( binding SEPR bindings -> ^( SEPR binding bindings ) | binding );", 2, 0, input);
+
+                throw nvae;
+            }
+            switch (alt2) {
+                case 1 :
+                    // dd/grammar/ECAGrammar.g:40:12: binding SEPR bindings
+                    {
+                    pushFollow(FOLLOW_binding_in_bindings162);
+                    binding10=binding();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_binding.add(binding10.getTree());
+                    SEPR11=(Token)input.LT(1);
+                    match(input,SEPR,FOLLOW_SEPR_in_bindings164); if (failed) return retval;
+                    if ( backtracking==0 ) stream_SEPR.add(SEPR11);
+
+                    pushFollow(FOLLOW_bindings_in_bindings166);
+                    bindings12=bindings();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_bindings.add(bindings12.getTree());
+
+                    // AST REWRITE
+                    // elements: SEPR, binding, bindings
+                    // token labels: 
+                    // rule labels: retval
+                    // token list labels: 
+                    // rule list labels: 
+                    if ( backtracking==0 ) {
+                    retval.tree = root_0;
+                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);
+
+                    root_0 = (Object)adaptor.nil();
+                    // 40:34: -> ^( SEPR binding bindings )
+                    {
+                        // dd/grammar/ECAGrammar.g:40:37: ^( SEPR binding bindings )
+                        {
+                        Object root_1 = (Object)adaptor.nil();
+                        root_1 = (Object)adaptor.becomeRoot(stream_SEPR.next(), root_1);
+
+                        adaptor.addChild(root_1, stream_binding.next());
+                        adaptor.addChild(root_1, stream_bindings.next());
+
+                        adaptor.addChild(root_0, root_1);
+                        }
+
+                    }
+
+                    }
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAGrammar.g:41:4: binding
+                    {
+                    root_0 = (Object)adaptor.nil();
+
+                    pushFollow(FOLLOW_binding_in_bindings181);
+                    binding13=binding();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) adaptor.addChild(root_0, binding13.getTree());
+
+                    }
+                    break;
+
+            }
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end bindings
+
+    public static class binding_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start binding
+    // dd/grammar/ECAGrammar.g:44:1: binding : bind_sym ASSIGN expr -> ^( ASSIGN bind_sym expr ) ;
+    public final binding_return binding() throws RecognitionException {
+        binding_return retval = new binding_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        Token ASSIGN15=null;
+        bind_sym_return bind_sym14 = null;
+
+        expr_return expr16 = null;
+
+
+        Object ASSIGN15_tree=null;
+        RewriteRuleTokenStream stream_ASSIGN=new RewriteRuleTokenStream(adaptor,"token ASSIGN");
+        RewriteRuleSubtreeStream stream_expr=new RewriteRuleSubtreeStream(adaptor,"rule expr");
+        RewriteRuleSubtreeStream stream_bind_sym=new RewriteRuleSubtreeStream(adaptor,"rule bind_sym");
+        try {
+            // dd/grammar/ECAGrammar.g:44:9: ( bind_sym ASSIGN expr -> ^( ASSIGN bind_sym expr ) )
+            // dd/grammar/ECAGrammar.g:44:11: bind_sym ASSIGN expr
+            {
+            pushFollow(FOLLOW_bind_sym_in_binding191);
+            bind_sym14=bind_sym();
+            _fsp--;
+            if (failed) return retval;
+            if ( backtracking==0 ) stream_bind_sym.add(bind_sym14.getTree());
+            ASSIGN15=(Token)input.LT(1);
+            match(input,ASSIGN,FOLLOW_ASSIGN_in_binding193); if (failed) return retval;
+            if ( backtracking==0 ) stream_ASSIGN.add(ASSIGN15);
+
+            pushFollow(FOLLOW_expr_in_binding195);
+            expr16=expr();
+            _fsp--;
+            if (failed) return retval;
+            if ( backtracking==0 ) stream_expr.add(expr16.getTree());
+
+            // AST REWRITE
+            // elements: bind_sym, ASSIGN, expr
+            // token labels: 
+            // rule labels: retval
+            // token list labels: 
+            // rule list labels: 
+            if ( backtracking==0 ) {
+            retval.tree = root_0;
+            RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);
+
+            root_0 = (Object)adaptor.nil();
+            // 44:32: -> ^( ASSIGN bind_sym expr )
+            {
+                // dd/grammar/ECAGrammar.g:44:35: ^( ASSIGN bind_sym expr )
+                {
+                Object root_1 = (Object)adaptor.nil();
+                root_1 = (Object)adaptor.becomeRoot(stream_ASSIGN.next(), root_1);
+
+                adaptor.addChild(root_1, stream_bind_sym.next());
+                adaptor.addChild(root_1, stream_expr.next());
+
+                adaptor.addChild(root_0, root_1);
+                }
+
+            }
+
+            }
+
+            }
+
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end binding
+
+    public static class bind_sym_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start bind_sym
+    // dd/grammar/ECAGrammar.g:48:1: bind_sym : (v= SYMBOL COLON t= SYMBOL -> ^( COLON $v $t) | SYMBOL );
+    public final bind_sym_return bind_sym() throws RecognitionException {
+        bind_sym_return retval = new bind_sym_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        Token v=null;
+        Token t=null;
+        Token COLON17=null;
+        Token SYMBOL18=null;
+
+        Object v_tree=null;
+        Object t_tree=null;
+        Object COLON17_tree=null;
+        Object SYMBOL18_tree=null;
+        RewriteRuleTokenStream stream_COLON=new RewriteRuleTokenStream(adaptor,"token COLON");
+        RewriteRuleTokenStream stream_SYMBOL=new RewriteRuleTokenStream(adaptor,"token SYMBOL");
+
+        try {
+            // dd/grammar/ECAGrammar.g:48:10: (v= SYMBOL COLON t= SYMBOL -> ^( COLON $v $t) | SYMBOL )
+            int alt3=2;
+            int LA3_0 = input.LA(1);
+
+            if ( (LA3_0==SYMBOL) ) {
+                int LA3_1 = input.LA(2);
+
+                if ( (LA3_1==COLON) ) {
+                    alt3=1;
+                }
+                else if ( (LA3_1==ASSIGN) ) {
+                    alt3=2;
+                }
+                else {
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("48:1: bind_sym : (v= SYMBOL COLON t= SYMBOL -> ^( COLON $v $t) | SYMBOL );", 3, 1, input);
+
+                    throw nvae;
+                }
+            }
+            else {
+                if (backtracking>0) {failed=true; return retval;}
+                NoViableAltException nvae =
+                    new NoViableAltException("48:1: bind_sym : (v= SYMBOL COLON t= SYMBOL -> ^( COLON $v $t) | SYMBOL );", 3, 0, input);
+
+                throw nvae;
+            }
+            switch (alt3) {
+                case 1 :
+                    // dd/grammar/ECAGrammar.g:48:12: v= SYMBOL COLON t= SYMBOL
+                    {
+                    v=(Token)input.LT(1);
+                    match(input,SYMBOL,FOLLOW_SYMBOL_in_bind_sym218); if (failed) return retval;
+                    if ( backtracking==0 ) stream_SYMBOL.add(v);
+
+                    COLON17=(Token)input.LT(1);
+                    match(input,COLON,FOLLOW_COLON_in_bind_sym220); if (failed) return retval;
+                    if ( backtracking==0 ) stream_COLON.add(COLON17);
+
+                    t=(Token)input.LT(1);
+                    match(input,SYMBOL,FOLLOW_SYMBOL_in_bind_sym224); if (failed) return retval;
+                    if ( backtracking==0 ) stream_SYMBOL.add(t);
+
+
+                    // AST REWRITE
+                    // elements: t, v, COLON
+                    // token labels: t, v
+                    // rule labels: retval
+                    // token list labels: 
+                    // rule list labels: 
+                    if ( backtracking==0 ) {
+                    retval.tree = root_0;
+                    RewriteRuleTokenStream stream_t=new RewriteRuleTokenStream(adaptor,"token t",t);
+                    RewriteRuleTokenStream stream_v=new RewriteRuleTokenStream(adaptor,"token v",v);
+                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);
+
+                    root_0 = (Object)adaptor.nil();
+                    // 48:36: -> ^( COLON $v $t)
+                    {
+                        // dd/grammar/ECAGrammar.g:48:39: ^( COLON $v $t)
+                        {
+                        Object root_1 = (Object)adaptor.nil();
+                        root_1 = (Object)adaptor.becomeRoot(stream_COLON.next(), root_1);
+
+                        adaptor.addChild(root_1, stream_v.next());
+                        adaptor.addChild(root_1, stream_t.next());
+
+                        adaptor.addChild(root_0, root_1);
+                        }
+
+                    }
+
+                    }
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAGrammar.g:49:4: SYMBOL
+                    {
+                    root_0 = (Object)adaptor.nil();
+
+                    SYMBOL18=(Token)input.LT(1);
+                    match(input,SYMBOL,FOLLOW_SYMBOL_in_bind_sym242); if (failed) return retval;
+                    if ( backtracking==0 ) {
+                    SYMBOL18_tree = (Object)adaptor.create(SYMBOL18);
+                    adaptor.addChild(root_0, SYMBOL18_tree);
+                    }
+
+                    }
+                    break;
+
+            }
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end bind_sym
+
+    public static class condition_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start condition
+    // dd/grammar/ECAGrammar.g:56:1: condition : expr ;
+    public final condition_return condition() throws RecognitionException {
+        condition_return retval = new condition_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        expr_return expr19 = null;
+
+
+
+        try {
+            // dd/grammar/ECAGrammar.g:56:11: ( expr )
+            // dd/grammar/ECAGrammar.g:56:13: expr
+            {
+            root_0 = (Object)adaptor.nil();
+
+            pushFollow(FOLLOW_expr_in_condition256);
+            expr19=expr();
+            _fsp--;
+            if (failed) return retval;
+            if ( backtracking==0 ) adaptor.addChild(root_0, expr19.getTree());
+
+            }
+
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end condition
+
+    public static class action_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start action
+    // dd/grammar/ECAGrammar.g:63:1: action : action_expr_list ;
+    public final action_return action() throws RecognitionException {
+        action_return retval = new action_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        action_expr_list_return action_expr_list20 = null;
+
+
+
+        try {
+            // dd/grammar/ECAGrammar.g:63:8: ( action_expr_list )
+            // dd/grammar/ECAGrammar.g:63:10: action_expr_list
+            {
+            root_0 = (Object)adaptor.nil();
+
+            pushFollow(FOLLOW_action_expr_list_in_action270);
+            action_expr_list20=action_expr_list();
+            _fsp--;
+            if (failed) return retval;
+            if ( backtracking==0 ) adaptor.addChild(root_0, action_expr_list20.getTree());
+
+            }
+
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end action
+
+    public static class action_expr_list_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start action_expr_list
+    // dd/grammar/ECAGrammar.g:66:1: action_expr_list : ( action_expr SEPR action_expr_list -> ^( SEPR action_expr action_expr_list ) | action_expr );
+    public final action_expr_list_return action_expr_list() throws RecognitionException {
+        action_expr_list_return retval = new action_expr_list_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        Token SEPR22=null;
+        action_expr_return action_expr21 = null;
+
+        action_expr_list_return action_expr_list23 = null;
+
+        action_expr_return action_expr24 = null;
+
+
+        Object SEPR22_tree=null;
+        RewriteRuleTokenStream stream_SEPR=new RewriteRuleTokenStream(adaptor,"token SEPR");
+        RewriteRuleSubtreeStream stream_action_expr_list=new RewriteRuleSubtreeStream(adaptor,"rule action_expr_list");
+        RewriteRuleSubtreeStream stream_action_expr=new RewriteRuleSubtreeStream(adaptor,"rule action_expr");
+        try {
+            // dd/grammar/ECAGrammar.g:67:2: ( action_expr SEPR action_expr_list -> ^( SEPR action_expr action_expr_list ) | action_expr )
+            int alt4=2;
+            switch ( input.LA(1) ) {
+            case DOLLARSYM:
+                {
+                int LA4_1 = input.LA(2);
+
+                if ( (synpred5()) ) {
+                    alt4=1;
+                }
+                else if ( (true) ) {
+                    alt4=2;
+                }
+                else {
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("66:1: action_expr_list : ( action_expr SEPR action_expr_list -> ^( SEPR action_expr action_expr_list ) | action_expr );", 4, 1, input);
+
+                    throw nvae;
+                }
+                }
+                break;
+            case SYMBOL:
+                {
+                int LA4_2 = input.LA(2);
+
+                if ( (synpred5()) ) {
+                    alt4=1;
+                }
+                else if ( (true) ) {
+                    alt4=2;
+                }
+                else {
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("66:1: action_expr_list : ( action_expr SEPR action_expr_list -> ^( SEPR action_expr action_expr_list ) | action_expr );", 4, 2, input);
+
+                    throw nvae;
+                }
+                }
+                break;
+            case NUMBER:
+                {
+                int LA4_3 = input.LA(2);
+
+                if ( (synpred5()) ) {
+                    alt4=1;
+                }
+                else if ( (true) ) {
+                    alt4=2;
+                }
+                else {
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("66:1: action_expr_list : ( action_expr SEPR action_expr_list -> ^( SEPR action_expr action_expr_list ) | action_expr );", 4, 3, input);
+
+                    throw nvae;
+                }
+                }
+                break;
+            case STRING:
+                {
+                int LA4_4 = input.LA(2);
+
+                if ( (synpred5()) ) {
+                    alt4=1;
+                }
+                else if ( (true) ) {
+                    alt4=2;
+                }
+                else {
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("66:1: action_expr_list : ( action_expr SEPR action_expr_list -> ^( SEPR action_expr action_expr_list ) | action_expr );", 4, 4, input);
+
+                    throw nvae;
+                }
+                }
+                break;
+            case LPAREN:
+                {
+                int LA4_5 = input.LA(2);
+
+                if ( (synpred5()) ) {
+                    alt4=1;
+                }
+                else if ( (true) ) {
+                    alt4=2;
+                }
+                else {
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("66:1: action_expr_list : ( action_expr SEPR action_expr_list -> ^( SEPR action_expr action_expr_list ) | action_expr );", 4, 5, input);
+
+                    throw nvae;
+                }
+                }
+                break;
+            case NOT:
+            case TWIDDLE:
+                {
+                int LA4_6 = input.LA(2);
+
+                if ( (synpred5()) ) {
+                    alt4=1;
+                }
+                else if ( (true) ) {
+                    alt4=2;
+                }
+                else {
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("66:1: action_expr_list : ( action_expr SEPR action_expr_list -> ^( SEPR action_expr action_expr_list ) | action_expr );", 4, 6, input);
+
+                    throw nvae;
+                }
+                }
+                break;
+            default:
+                if (backtracking>0) {failed=true; return retval;}
+                NoViableAltException nvae =
+                    new NoViableAltException("66:1: action_expr_list : ( action_expr SEPR action_expr_list -> ^( SEPR action_expr action_expr_list ) | action_expr );", 4, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt4) {
+                case 1 :
+                    // dd/grammar/ECAGrammar.g:67:4: action_expr SEPR action_expr_list
+                    {
+                    pushFollow(FOLLOW_action_expr_in_action_expr_list281);
+                    action_expr21=action_expr();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_action_expr.add(action_expr21.getTree());
+                    SEPR22=(Token)input.LT(1);
+                    match(input,SEPR,FOLLOW_SEPR_in_action_expr_list283); if (failed) return retval;
+                    if ( backtracking==0 ) stream_SEPR.add(SEPR22);
+
+                    pushFollow(FOLLOW_action_expr_list_in_action_expr_list285);
+                    action_expr_list23=action_expr_list();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_action_expr_list.add(action_expr_list23.getTree());
+
+                    // AST REWRITE
+                    // elements: action_expr_list, SEPR, action_expr
+                    // token labels: 
+                    // rule labels: retval
+                    // token list labels: 
+                    // rule list labels: 
+                    if ( backtracking==0 ) {
+                    retval.tree = root_0;
+                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);
+
+                    root_0 = (Object)adaptor.nil();
+                    // 67:38: -> ^( SEPR action_expr action_expr_list )
+                    {
+                        // dd/grammar/ECAGrammar.g:67:41: ^( SEPR action_expr action_expr_list )
+                        {
+                        Object root_1 = (Object)adaptor.nil();
+                        root_1 = (Object)adaptor.becomeRoot(stream_SEPR.next(), root_1);
+
+                        adaptor.addChild(root_1, stream_action_expr.next());
+                        adaptor.addChild(root_1, stream_action_expr_list.next());
+
+                        adaptor.addChild(root_0, root_1);
+                        }
+
+                    }
+
+                    }
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAGrammar.g:68:4: action_expr
+                    {
+                    root_0 = (Object)adaptor.nil();
+
+                    pushFollow(FOLLOW_action_expr_in_action_expr_list300);
+                    action_expr24=action_expr();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) adaptor.addChild(root_0, action_expr24.getTree());
+
+                    }
+                    break;
+
+            }
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end action_expr_list
+
+    public static class action_expr_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start action_expr
+    // dd/grammar/ECAGrammar.g:71:1: action_expr : expr ;
+    public final action_expr_return action_expr() throws RecognitionException {
+        action_expr_return retval = new action_expr_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        expr_return expr25 = null;
+
+
+
+        try {
+            // dd/grammar/ECAGrammar.g:71:13: ( expr )
+            // dd/grammar/ECAGrammar.g:71:15: expr
+            {
+            root_0 = (Object)adaptor.nil();
+
+            pushFollow(FOLLOW_expr_in_action_expr310);
+            expr25=expr();
+            _fsp--;
+            if (failed) return retval;
+            if ( backtracking==0 ) adaptor.addChild(root_0, expr25.getTree());
+
+            }
+
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end action_expr
+
+    public static class expr_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start expr
+    // dd/grammar/ECAGrammar.g:74:1: expr : ( simple_expr infix_oper expr -> ^( BINOP infix_oper simple_expr expr ) | simple_expr | unary_oper expr -> ^( UNOP unary_oper expr ) | cond= simple_expr TERN_IF iftrue= expr COLON iffalse= expr -> ^( TERNOP $cond $iftrue $iffalse) );
+    public final expr_return expr() throws RecognitionException {
+        expr_return retval = new expr_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        Token TERN_IF32=null;
+        Token COLON33=null;
+        simple_expr_return cond = null;
+
+        expr_return iftrue = null;
+
+        expr_return iffalse = null;
+
+        simple_expr_return simple_expr26 = null;
+
+        infix_oper_return infix_oper27 = null;
+
+        expr_return expr28 = null;
+
+        simple_expr_return simple_expr29 = null;
+
+        unary_oper_return unary_oper30 = null;
+
+        expr_return expr31 = null;
+
+
+        Object TERN_IF32_tree=null;
+        Object COLON33_tree=null;
+        RewriteRuleTokenStream stream_COLON=new RewriteRuleTokenStream(adaptor,"token COLON");
+        RewriteRuleTokenStream stream_TERN_IF=new RewriteRuleTokenStream(adaptor,"token TERN_IF");
+        RewriteRuleSubtreeStream stream_unary_oper=new RewriteRuleSubtreeStream(adaptor,"rule unary_oper");
+        RewriteRuleSubtreeStream stream_infix_oper=new RewriteRuleSubtreeStream(adaptor,"rule infix_oper");
+        RewriteRuleSubtreeStream stream_expr=new RewriteRuleSubtreeStream(adaptor,"rule expr");
+        RewriteRuleSubtreeStream stream_simple_expr=new RewriteRuleSubtreeStream(adaptor,"rule simple_expr");
+        try {
+            // dd/grammar/ECAGrammar.g:74:6: ( simple_expr infix_oper expr -> ^( BINOP infix_oper simple_expr expr ) | simple_expr | unary_oper expr -> ^( UNOP unary_oper expr ) | cond= simple_expr TERN_IF iftrue= expr COLON iffalse= expr -> ^( TERNOP $cond $iftrue $iffalse) )
+            int alt5=4;
+            switch ( input.LA(1) ) {
+            case DOLLARSYM:
+                {
+                switch ( input.LA(2) ) {
+                case EOF:
+                case RPAREN:
+                case RSQUARE:
+                case SEPR:
+                case COLON:
+                    {
+                    alt5=2;
+                    }
+                    break;
+                case TERN_IF:
+                    {
+                    alt5=4;
+                    }
+                    break;
+                case OR:
+                case AND:
+                case EQ:
+                case NEQ:
+                case GT:
+                case LT:
+                case GEQ:
+                case LEQ:
+                case BOR:
+                case BAND:
+                case BXOR:
+                case MUL:
+                case DIV:
+                case PLUS:
+                case MINUS:
+                    {
+                    alt5=1;
+                    }
+                    break;
+                default:
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("74:1: expr : ( simple_expr infix_oper expr -> ^( BINOP infix_oper simple_expr expr ) | simple_expr | unary_oper expr -> ^( UNOP unary_oper expr ) | cond= simple_expr TERN_IF iftrue= expr COLON iffalse= expr -> ^( TERNOP $cond $iftrue $iffalse) );", 5, 1, input);
+
+                    throw nvae;
+                }
+
+                }
+                break;
+            case SYMBOL:
+                {
+                switch ( input.LA(2) ) {
+                case LPAREN:
+                    {
+                    int LA5_10 = input.LA(3);
+
+                    if ( (synpred6()) ) {
+                        alt5=1;
+                    }
+                    else if ( (synpred7()) ) {
+                        alt5=2;
+                    }
+                    else if ( (true) ) {
+                        alt5=4;
+                    }
+                    else {
+                        if (backtracking>0) {failed=true; return retval;}
+                        NoViableAltException nvae =
+                            new NoViableAltException("74:1: expr : ( simple_expr infix_oper expr -> ^( BINOP infix_oper simple_expr expr ) | simple_expr | unary_oper expr -> ^( UNOP unary_oper expr ) | cond= simple_expr TERN_IF iftrue= expr COLON iffalse= expr -> ^( TERNOP $cond $iftrue $iffalse) );", 5, 10, input);
+
+                        throw nvae;
+                    }
+                    }
+                    break;
+                case LSQUARE:
+                    {
+                    int LA5_11 = input.LA(3);
+
+                    if ( (synpred6()) ) {
+                        alt5=1;
+                    }
+                    else if ( (synpred7()) ) {
+                        alt5=2;
+                    }
+                    else if ( (true) ) {
+                        alt5=4;
+                    }
+                    else {
+                        if (backtracking>0) {failed=true; return retval;}
+                        NoViableAltException nvae =
+                            new NoViableAltException("74:1: expr : ( simple_expr infix_oper expr -> ^( BINOP infix_oper simple_expr expr ) | simple_expr | unary_oper expr -> ^( UNOP unary_oper expr ) | cond= simple_expr TERN_IF iftrue= expr COLON iffalse= expr -> ^( TERNOP $cond $iftrue $iffalse) );", 5, 11, input);
+
+                        throw nvae;
+                    }
+                    }
+                    break;
+                case OR:
+                case AND:
+                case EQ:
+                case NEQ:
+                case GT:
+                case LT:
+                case GEQ:
+                case LEQ:
+                case BOR:
+                case BAND:
+                case BXOR:
+                case MUL:
+                case DIV:
+                case PLUS:
+                case MINUS:
+                    {
+                    alt5=1;
+                    }
+                    break;
+                case TERN_IF:
+                    {
+                    alt5=4;
+                    }
+                    break;
+                case EOF:
+                case RPAREN:
+                case RSQUARE:
+                case SEPR:
+                case COLON:
+                    {
+                    alt5=2;
+                    }
+                    break;
+                default:
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("74:1: expr : ( simple_expr infix_oper expr -> ^( BINOP infix_oper simple_expr expr ) | simple_expr | unary_oper expr -> ^( UNOP unary_oper expr ) | cond= simple_expr TERN_IF iftrue= expr COLON iffalse= expr -> ^( TERNOP $cond $iftrue $iffalse) );", 5, 2, input);
+
+                    throw nvae;
+                }
+
+                }
+                break;
+            case NUMBER:
+                {
+                switch ( input.LA(2) ) {
+                case TERN_IF:
+                    {
+                    alt5=4;
+                    }
+                    break;
+                case EOF:
+                case RPAREN:
+                case RSQUARE:
+                case SEPR:
+                case COLON:
+                    {
+                    alt5=2;
+                    }
+                    break;
+                case OR:
+                case AND:
+                case EQ:
+                case NEQ:
+                case GT:
+                case LT:
+                case GEQ:
+                case LEQ:
+                case BOR:
+                case BAND:
+                case BXOR:
+                case MUL:
+                case DIV:
+                case PLUS:
+                case MINUS:
+                    {
+                    alt5=1;
+                    }
+                    break;
+                default:
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("74:1: expr : ( simple_expr infix_oper expr -> ^( BINOP infix_oper simple_expr expr ) | simple_expr | unary_oper expr -> ^( UNOP unary_oper expr ) | cond= simple_expr TERN_IF iftrue= expr COLON iffalse= expr -> ^( TERNOP $cond $iftrue $iffalse) );", 5, 3, input);
+
+                    throw nvae;
+                }
+
+                }
+                break;
+            case STRING:
+                {
+                switch ( input.LA(2) ) {
+                case TERN_IF:
+                    {
+                    alt5=4;
+                    }
+                    break;
+                case OR:
+                case AND:
+                case EQ:
+                case NEQ:
+                case GT:
+                case LT:
+                case GEQ:
+                case LEQ:
+                case BOR:
+                case BAND:
+                case BXOR:
+                case MUL:
+                case DIV:
+                case PLUS:
+                case MINUS:
+                    {
+                    alt5=1;
+                    }
+                    break;
+                case EOF:
+                case RPAREN:
+                case RSQUARE:
+                case SEPR:
+                case COLON:
+                    {
+                    alt5=2;
+                    }
+                    break;
+                default:
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("74:1: expr : ( simple_expr infix_oper expr -> ^( BINOP infix_oper simple_expr expr ) | simple_expr | unary_oper expr -> ^( UNOP unary_oper expr ) | cond= simple_expr TERN_IF iftrue= expr COLON iffalse= expr -> ^( TERNOP $cond $iftrue $iffalse) );", 5, 4, input);
+
+                    throw nvae;
+                }
+
+                }
+                break;
+            case LPAREN:
+                {
+                int LA5_5 = input.LA(2);
+
+                if ( (synpred6()) ) {
+                    alt5=1;
+                }
+                else if ( (synpred7()) ) {
+                    alt5=2;
+                }
+                else if ( (true) ) {
+                    alt5=4;
+                }
+                else {
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("74:1: expr : ( simple_expr infix_oper expr -> ^( BINOP infix_oper simple_expr expr ) | simple_expr | unary_oper expr -> ^( UNOP unary_oper expr ) | cond= simple_expr TERN_IF iftrue= expr COLON iffalse= expr -> ^( TERNOP $cond $iftrue $iffalse) );", 5, 5, input);
+
+                    throw nvae;
+                }
+                }
+                break;
+            case NOT:
+            case TWIDDLE:
+                {
+                alt5=3;
+                }
+                break;
+            default:
+                if (backtracking>0) {failed=true; return retval;}
+                NoViableAltException nvae =
+                    new NoViableAltException("74:1: expr : ( simple_expr infix_oper expr -> ^( BINOP infix_oper simple_expr expr ) | simple_expr | unary_oper expr -> ^( UNOP unary_oper expr ) | cond= simple_expr TERN_IF iftrue= expr COLON iffalse= expr -> ^( TERNOP $cond $iftrue $iffalse) );", 5, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt5) {
+                case 1 :
+                    // dd/grammar/ECAGrammar.g:74:8: simple_expr infix_oper expr
+                    {
+                    pushFollow(FOLLOW_simple_expr_in_expr320);
+                    simple_expr26=simple_expr();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_simple_expr.add(simple_expr26.getTree());
+                    pushFollow(FOLLOW_infix_oper_in_expr322);
+                    infix_oper27=infix_oper();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_infix_oper.add(infix_oper27.getTree());
+                    pushFollow(FOLLOW_expr_in_expr324);
+                    expr28=expr();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_expr.add(expr28.getTree());
+
+                    // AST REWRITE
+                    // elements: expr, infix_oper, simple_expr
+                    // token labels: 
+                    // rule labels: retval
+                    // token list labels: 
+                    // rule list labels: 
+                    if ( backtracking==0 ) {
+                    retval.tree = root_0;
+                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);
+
+                    root_0 = (Object)adaptor.nil();
+                    // 74:37: -> ^( BINOP infix_oper simple_expr expr )
+                    {
+                        // dd/grammar/ECAGrammar.g:74:40: ^( BINOP infix_oper simple_expr expr )
+                        {
+                        Object root_1 = (Object)adaptor.nil();
+                        root_1 = (Object)adaptor.becomeRoot(adaptor.create(BINOP, "BINOP"), root_1);
+
+                        adaptor.addChild(root_1, stream_infix_oper.next());
+                        adaptor.addChild(root_1, stream_simple_expr.next());
+                        adaptor.addChild(root_1, stream_expr.next());
+
+                        adaptor.addChild(root_0, root_1);
+                        }
+
+                    }
+
+                    }
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAGrammar.g:75:4: simple_expr
+                    {
+                    root_0 = (Object)adaptor.nil();
+
+                    pushFollow(FOLLOW_simple_expr_in_expr342);
+                    simple_expr29=simple_expr();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) adaptor.addChild(root_0, simple_expr29.getTree());
+
+                    }
+                    break;
+                case 3 :
+                    // dd/grammar/ECAGrammar.g:76:4: unary_oper expr
+                    {
+                    pushFollow(FOLLOW_unary_oper_in_expr347);
+                    unary_oper30=unary_oper();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_unary_oper.add(unary_oper30.getTree());
+                    pushFollow(FOLLOW_expr_in_expr349);
+                    expr31=expr();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_expr.add(expr31.getTree());
+
+                    // AST REWRITE
+                    // elements: expr, unary_oper
+                    // token labels: 
+                    // rule labels: retval
+                    // token list labels: 
+                    // rule list labels: 
+                    if ( backtracking==0 ) {
+                    retval.tree = root_0;
+                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);
+
+                    root_0 = (Object)adaptor.nil();
+                    // 76:22: -> ^( UNOP unary_oper expr )
+                    {
+                        // dd/grammar/ECAGrammar.g:76:25: ^( UNOP unary_oper expr )
+                        {
+                        Object root_1 = (Object)adaptor.nil();
+                        root_1 = (Object)adaptor.becomeRoot(adaptor.create(UNOP, "UNOP"), root_1);
+
+                        adaptor.addChild(root_1, stream_unary_oper.next());
+                        adaptor.addChild(root_1, stream_expr.next());
+
+                        adaptor.addChild(root_0, root_1);
+                        }
+
+                    }
+
+                    }
+
+                    }
+                    break;
+                case 4 :
+                    // dd/grammar/ECAGrammar.g:77:4: cond= simple_expr TERN_IF iftrue= expr COLON iffalse= expr
+                    {
+                    pushFollow(FOLLOW_simple_expr_in_expr368);
+                    cond=simple_expr();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_simple_expr.add(cond.getTree());
+                    TERN_IF32=(Token)input.LT(1);
+                    match(input,TERN_IF,FOLLOW_TERN_IF_in_expr370); if (failed) return retval;
+                    if ( backtracking==0 ) stream_TERN_IF.add(TERN_IF32);
+
+                    pushFollow(FOLLOW_expr_in_expr374);
+                    iftrue=expr();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_expr.add(iftrue.getTree());
+                    COLON33=(Token)input.LT(1);
+                    match(input,COLON,FOLLOW_COLON_in_expr376); if (failed) return retval;
+                    if ( backtracking==0 ) stream_COLON.add(COLON33);
+
+                    pushFollow(FOLLOW_expr_in_expr380);
+                    iffalse=expr();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_expr.add(iffalse.getTree());
+
+                    // AST REWRITE
+                    // elements: iffalse, cond, iftrue
+                    // token labels: 
+                    // rule labels: iftrue, cond, iffalse, retval
+                    // token list labels: 
+                    // rule list labels: 
+                    if ( backtracking==0 ) {
+                    retval.tree = root_0;
+                    RewriteRuleSubtreeStream stream_iftrue=new RewriteRuleSubtreeStream(adaptor,"token iftrue",iftrue!=null?iftrue.tree:null);
+                    RewriteRuleSubtreeStream stream_cond=new RewriteRuleSubtreeStream(adaptor,"token cond",cond!=null?cond.tree:null);
+                    RewriteRuleSubtreeStream stream_iffalse=new RewriteRuleSubtreeStream(adaptor,"token iffalse",iffalse!=null?iffalse.tree:null);
+                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);
+
+                    root_0 = (Object)adaptor.nil();
+                    // 77:60: -> ^( TERNOP $cond $iftrue $iffalse)
+                    {
+                        // dd/grammar/ECAGrammar.g:77:63: ^( TERNOP $cond $iftrue $iffalse)
+                        {
+                        Object root_1 = (Object)adaptor.nil();
+                        root_1 = (Object)adaptor.becomeRoot(adaptor.create(TERNOP, "TERNOP"), root_1);
+
+                        adaptor.addChild(root_1, stream_cond.next());
+                        adaptor.addChild(root_1, stream_iftrue.next());
+                        adaptor.addChild(root_1, stream_iffalse.next());
+
+                        adaptor.addChild(root_0, root_1);
+                        }
+
+                    }
+
+                    }
+
+                    }
+                    break;
+
+            }
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end expr
+
+    public static class simple_expr_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start simple_expr
+    // dd/grammar/ECAGrammar.g:80:1: simple_expr : (v= DOLLARSYM | v= SYMBOL idx= array_idx -> ^( ARRAY $v $idx) | v= SYMBOL LPAREN RPAREN -> ^( METH $v) | v= SYMBOL | v= SYMBOL LPAREN args= expr_list RPAREN -> ^( METH $v $args) | NUMBER | STRING | LPAREN expr RPAREN -> ^( expr ) );
+    public final simple_expr_return simple_expr() throws RecognitionException {
+        simple_expr_return retval = new simple_expr_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        Token v=null;
+        Token LPAREN34=null;
+        Token RPAREN35=null;
+        Token LPAREN36=null;
+        Token RPAREN37=null;
+        Token NUMBER38=null;
+        Token STRING39=null;
+        Token LPAREN40=null;
+        Token RPAREN42=null;
+        array_idx_return idx = null;
+
+        expr_list_return args = null;
+
+        expr_return expr41 = null;
+
+
+        Object v_tree=null;
+        Object LPAREN34_tree=null;
+        Object RPAREN35_tree=null;
+        Object LPAREN36_tree=null;
+        Object RPAREN37_tree=null;
+        Object NUMBER38_tree=null;
+        Object STRING39_tree=null;
+        Object LPAREN40_tree=null;
+        Object RPAREN42_tree=null;
+        RewriteRuleTokenStream stream_RPAREN=new RewriteRuleTokenStream(adaptor,"token RPAREN");
+        RewriteRuleTokenStream stream_LPAREN=new RewriteRuleTokenStream(adaptor,"token LPAREN");
+        RewriteRuleTokenStream stream_SYMBOL=new RewriteRuleTokenStream(adaptor,"token SYMBOL");
+        RewriteRuleSubtreeStream stream_expr_list=new RewriteRuleSubtreeStream(adaptor,"rule expr_list");
+        RewriteRuleSubtreeStream stream_expr=new RewriteRuleSubtreeStream(adaptor,"rule expr");
+        RewriteRuleSubtreeStream stream_array_idx=new RewriteRuleSubtreeStream(adaptor,"rule array_idx");
+        try {
+            // dd/grammar/ECAGrammar.g:80:13: (v= DOLLARSYM | v= SYMBOL idx= array_idx -> ^( ARRAY $v $idx) | v= SYMBOL LPAREN RPAREN -> ^( METH $v) | v= SYMBOL | v= SYMBOL LPAREN args= expr_list RPAREN -> ^( METH $v $args) | NUMBER | STRING | LPAREN expr RPAREN -> ^( expr ) )
+            int alt6=8;
+            switch ( input.LA(1) ) {
+            case DOLLARSYM:
+                {
+                alt6=1;
+                }
+                break;
+            case SYMBOL:
+                {
+                switch ( input.LA(2) ) {
+                case LPAREN:
+                    {
+                    int LA6_6 = input.LA(3);
+
+                    if ( (LA6_6==RPAREN) ) {
+                        alt6=3;
+                    }
+                    else if ( (LA6_6==NUMBER||LA6_6==LPAREN||LA6_6==NOT||LA6_6==TWIDDLE||LA6_6==STRING||LA6_6==SYMBOL||LA6_6==DOLLARSYM) ) {
+                        alt6=5;
+                    }
+                    else {
+                        if (backtracking>0) {failed=true; return retval;}
+                        NoViableAltException nvae =
+                            new NoViableAltException("80:1: simple_expr : (v= DOLLARSYM | v= SYMBOL idx= array_idx -> ^( ARRAY $v $idx) | v= SYMBOL LPAREN RPAREN -> ^( METH $v) | v= SYMBOL | v= SYMBOL LPAREN args= expr_list RPAREN -> ^( METH $v $args) | NUMBER | STRING | LPAREN expr RPAREN -> ^( expr ) );", 6, 6, input);
+
+                        throw nvae;
+                    }
+                    }
+                    break;
+                case LSQUARE:
+                    {
+                    alt6=2;
+                    }
+                    break;
+                case EOF:
+                case RPAREN:
+                case RSQUARE:
+                case SEPR:
+                case OR:
+                case AND:
+                case EQ:
+                case NEQ:
+                case GT:
+                case LT:
+                case GEQ:
+                case LEQ:
+                case BOR:
+                case BAND:
+                case BXOR:
+                case MUL:
+                case DIV:
+                case PLUS:
+                case MINUS:
+                case TERN_IF:
+                case COLON:
+                    {
+                    alt6=4;
+                    }
+                    break;
+                default:
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("80:1: simple_expr : (v= DOLLARSYM | v= SYMBOL idx= array_idx -> ^( ARRAY $v $idx) | v= SYMBOL LPAREN RPAREN -> ^( METH $v) | v= SYMBOL | v= SYMBOL LPAREN args= expr_list RPAREN -> ^( METH $v $args) | NUMBER | STRING | LPAREN expr RPAREN -> ^( expr ) );", 6, 2, input);
+
+                    throw nvae;
+                }
+
+                }
+                break;
+            case NUMBER:
+                {
+                alt6=6;
+                }
+                break;
+            case STRING:
+                {
+                alt6=7;
+                }
+                break;
+            case LPAREN:
+                {
+                alt6=8;
+                }
+                break;
+            default:
+                if (backtracking>0) {failed=true; return retval;}
+                NoViableAltException nvae =
+                    new NoViableAltException("80:1: simple_expr : (v= DOLLARSYM | v= SYMBOL idx= array_idx -> ^( ARRAY $v $idx) | v= SYMBOL LPAREN RPAREN -> ^( METH $v) | v= SYMBOL | v= SYMBOL LPAREN args= expr_list RPAREN -> ^( METH $v $args) | NUMBER | STRING | LPAREN expr RPAREN -> ^( expr ) );", 6, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt6) {
+                case 1 :
+                    // dd/grammar/ECAGrammar.g:80:15: v= DOLLARSYM
+                    {
+                    root_0 = (Object)adaptor.nil();
+
+                    v=(Token)input.LT(1);
+                    match(input,DOLLARSYM,FOLLOW_DOLLARSYM_in_simple_expr407); if (failed) return retval;
+                    if ( backtracking==0 ) {
+                    v_tree = (Object)adaptor.create(v);
+                    adaptor.addChild(root_0, v_tree);
+                    }
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAGrammar.g:81:4: v= SYMBOL idx= array_idx
+                    {
+                    v=(Token)input.LT(1);
+                    match(input,SYMBOL,FOLLOW_SYMBOL_in_simple_expr414); if (failed) return retval;
+                    if ( backtracking==0 ) stream_SYMBOL.add(v);
+
+                    pushFollow(FOLLOW_array_idx_in_simple_expr418);
+                    idx=array_idx();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_array_idx.add(idx.getTree());
+
+                    // AST REWRITE
+                    // elements: v, idx
+                    // token labels: v
+                    // rule labels: idx, retval
+                    // token list labels: 
+                    // rule list labels: 
+                    if ( backtracking==0 ) {
+                    retval.tree = root_0;
+                    RewriteRuleTokenStream stream_v=new RewriteRuleTokenStream(adaptor,"token v",v);
+                    RewriteRuleSubtreeStream stream_idx=new RewriteRuleSubtreeStream(adaptor,"token idx",idx!=null?idx.tree:null);
+                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);
+
+                    root_0 = (Object)adaptor.nil();
+                    // 81:29: -> ^( ARRAY $v $idx)
+                    {
+                        // dd/grammar/ECAGrammar.g:81:32: ^( ARRAY $v $idx)
+                        {
+                        Object root_1 = (Object)adaptor.nil();
+                        root_1 = (Object)adaptor.becomeRoot(adaptor.create(ARRAY, "ARRAY"), root_1);
+
+                        adaptor.addChild(root_1, stream_v.next());
+                        adaptor.addChild(root_1, stream_idx.next());
+
+                        adaptor.addChild(root_0, root_1);
+                        }
+
+                    }
+
+                    }
+
+                    }
+                    break;
+                case 3 :
+                    // dd/grammar/ECAGrammar.g:82:4: v= SYMBOL LPAREN RPAREN
+                    {
+                    v=(Token)input.LT(1);
+                    match(input,SYMBOL,FOLLOW_SYMBOL_in_simple_expr439); if (failed) return retval;
+                    if ( backtracking==0 ) stream_SYMBOL.add(v);
+
+                    LPAREN34=(Token)input.LT(1);
+                    match(input,LPAREN,FOLLOW_LPAREN_in_simple_expr441); if (failed) return retval;
+                    if ( backtracking==0 ) stream_LPAREN.add(LPAREN34);
+
+                    RPAREN35=(Token)input.LT(1);
+                    match(input,RPAREN,FOLLOW_RPAREN_in_simple_expr443); if (failed) return retval;
+                    if ( backtracking==0 ) stream_RPAREN.add(RPAREN35);
+
+
+                    // AST REWRITE
+                    // elements: v
+                    // token labels: v
+                    // rule labels: retval
+                    // token list labels: 
+                    // rule list labels: 
+                    if ( backtracking==0 ) {
+                    retval.tree = root_0;
+                    RewriteRuleTokenStream stream_v=new RewriteRuleTokenStream(adaptor,"token v",v);
+                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);
+
+                    root_0 = (Object)adaptor.nil();
+                    // 82:29: -> ^( METH $v)
+                    {
+                        // dd/grammar/ECAGrammar.g:82:32: ^( METH $v)
+                        {
+                        Object root_1 = (Object)adaptor.nil();
+                        root_1 = (Object)adaptor.becomeRoot(adaptor.create(METH, "METH"), root_1);
+
+                        adaptor.addChild(root_1, stream_v.next());
+
+                        adaptor.addChild(root_0, root_1);
+                        }
+
+                    }
+
+                    }
+
+                    }
+                    break;
+                case 4 :
+                    // dd/grammar/ECAGrammar.g:83:4: v= SYMBOL
+                    {
+                    root_0 = (Object)adaptor.nil();
+
+                    v=(Token)input.LT(1);
+                    match(input,SYMBOL,FOLLOW_SYMBOL_in_simple_expr461); if (failed) return retval;
+                    if ( backtracking==0 ) {
+                    v_tree = (Object)adaptor.create(v);
+                    adaptor.addChild(root_0, v_tree);
+                    }
+
+                    }
+                    break;
+                case 5 :
+                    // dd/grammar/ECAGrammar.g:84:4: v= SYMBOL LPAREN args= expr_list RPAREN
+                    {
+                    v=(Token)input.LT(1);
+                    match(input,SYMBOL,FOLLOW_SYMBOL_in_simple_expr468); if (failed) return retval;
+                    if ( backtracking==0 ) stream_SYMBOL.add(v);
+
+                    LPAREN36=(Token)input.LT(1);
+                    match(input,LPAREN,FOLLOW_LPAREN_in_simple_expr470); if (failed) return retval;
+                    if ( backtracking==0 ) stream_LPAREN.add(LPAREN36);
+
+                    pushFollow(FOLLOW_expr_list_in_simple_expr474);
+                    args=expr_list();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_expr_list.add(args.getTree());
+                    RPAREN37=(Token)input.LT(1);
+                    match(input,RPAREN,FOLLOW_RPAREN_in_simple_expr476); if (failed) return retval;
+                    if ( backtracking==0 ) stream_RPAREN.add(RPAREN37);
+
+
+                    // AST REWRITE
+                    // elements: v, args
+                    // token labels: v
+                    // rule labels: args, retval
+                    // token list labels: 
+                    // rule list labels: 
+                    if ( backtracking==0 ) {
+                    retval.tree = root_0;
+                    RewriteRuleTokenStream stream_v=new RewriteRuleTokenStream(adaptor,"token v",v);
+                    RewriteRuleSubtreeStream stream_args=new RewriteRuleSubtreeStream(adaptor,"token args",args!=null?args.tree:null);
+                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);
+
+                    root_0 = (Object)adaptor.nil();
+                    // 84:43: -> ^( METH $v $args)
+                    {
+                        // dd/grammar/ECAGrammar.g:84:46: ^( METH $v $args)
+                        {
+                        Object root_1 = (Object)adaptor.nil();
+                        root_1 = (Object)adaptor.becomeRoot(adaptor.create(METH, "METH"), root_1);
+
+                        adaptor.addChild(root_1, stream_v.next());
+                        adaptor.addChild(root_1, stream_args.next());
+
+                        adaptor.addChild(root_0, root_1);
+                        }
+
+                    }
+
+                    }
+
+                    }
+                    break;
+                case 6 :
+                    // dd/grammar/ECAGrammar.g:85:4: NUMBER
+                    {
+                    root_0 = (Object)adaptor.nil();
+
+                    NUMBER38=(Token)input.LT(1);
+                    match(input,NUMBER,FOLLOW_NUMBER_in_simple_expr495); if (failed) return retval;
+                    if ( backtracking==0 ) {
+                    NUMBER38_tree = (Object)adaptor.create(NUMBER38);
+                    adaptor.addChild(root_0, NUMBER38_tree);
+                    }
+
+                    }
+                    break;
+                case 7 :
+                    // dd/grammar/ECAGrammar.g:86:4: STRING
+                    {
+                    root_0 = (Object)adaptor.nil();
+
+                    STRING39=(Token)input.LT(1);
+                    match(input,STRING,FOLLOW_STRING_in_simple_expr500); if (failed) return retval;
+                    if ( backtracking==0 ) {
+                    STRING39_tree = (Object)adaptor.create(STRING39);
+                    adaptor.addChild(root_0, STRING39_tree);
+                    }
+
+                    }
+                    break;
+                case 8 :
+                    // dd/grammar/ECAGrammar.g:87:4: LPAREN expr RPAREN
+                    {
+                    LPAREN40=(Token)input.LT(1);
+                    match(input,LPAREN,FOLLOW_LPAREN_in_simple_expr505); if (failed) return retval;
+                    if ( backtracking==0 ) stream_LPAREN.add(LPAREN40);
+
+                    pushFollow(FOLLOW_expr_in_simple_expr507);
+                    expr41=expr();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_expr.add(expr41.getTree());
+                    RPAREN42=(Token)input.LT(1);
+                    match(input,RPAREN,FOLLOW_RPAREN_in_simple_expr509); if (failed) return retval;
+                    if ( backtracking==0 ) stream_RPAREN.add(RPAREN42);
+
+
+                    // AST REWRITE
+                    // elements: expr
+                    // token labels: 
+                    // rule labels: retval
+                    // token list labels: 
+                    // rule list labels: 
+                    if ( backtracking==0 ) {
+                    retval.tree = root_0;
+                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);
+
+                    root_0 = (Object)adaptor.nil();
+                    // 87:25: -> ^( expr )
+                    {
+                        // dd/grammar/ECAGrammar.g:87:28: ^( expr )
+                        {
+                        Object root_1 = (Object)adaptor.nil();
+                        root_1 = (Object)adaptor.becomeRoot(stream_expr.nextNode(), root_1);
+
+                        adaptor.addChild(root_0, root_1);
+                        }
+
+                    }
+
+                    }
+
+                    }
+                    break;
+
+            }
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end simple_expr
+
+    public static class expr_list_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start expr_list
+    // dd/grammar/ECAGrammar.g:90:1: expr_list : ( expr SEPR expr_list -> ^( SEPR expr expr_list ) | expr );
+    public final expr_list_return expr_list() throws RecognitionException {
+        expr_list_return retval = new expr_list_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        Token SEPR44=null;
+        expr_return expr43 = null;
+
+        expr_list_return expr_list45 = null;
+
+        expr_return expr46 = null;
+
+
+        Object SEPR44_tree=null;
+        RewriteRuleTokenStream stream_SEPR=new RewriteRuleTokenStream(adaptor,"token SEPR");
+        RewriteRuleSubtreeStream stream_expr_list=new RewriteRuleSubtreeStream(adaptor,"rule expr_list");
+        RewriteRuleSubtreeStream stream_expr=new RewriteRuleSubtreeStream(adaptor,"rule expr");
+        try {
+            // dd/grammar/ECAGrammar.g:91:2: ( expr SEPR expr_list -> ^( SEPR expr expr_list ) | expr )
+            int alt7=2;
+            switch ( input.LA(1) ) {
+            case DOLLARSYM:
+                {
+                int LA7_1 = input.LA(2);
+
+                if ( (synpred16()) ) {
+                    alt7=1;
+                }
+                else if ( (true) ) {
+                    alt7=2;
+                }
+                else {
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("90:1: expr_list : ( expr SEPR expr_list -> ^( SEPR expr expr_list ) | expr );", 7, 1, input);
+
+                    throw nvae;
+                }
+                }
+                break;
+            case SYMBOL:
+                {
+                int LA7_2 = input.LA(2);
+
+                if ( (synpred16()) ) {
+                    alt7=1;
+                }
+                else if ( (true) ) {
+                    alt7=2;
+                }
+                else {
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("90:1: expr_list : ( expr SEPR expr_list -> ^( SEPR expr expr_list ) | expr );", 7, 2, input);
+
+                    throw nvae;
+                }
+                }
+                break;
+            case NUMBER:
+                {
+                int LA7_3 = input.LA(2);
+
+                if ( (synpred16()) ) {
+                    alt7=1;
+                }
+                else if ( (true) ) {
+                    alt7=2;
+                }
+                else {
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("90:1: expr_list : ( expr SEPR expr_list -> ^( SEPR expr expr_list ) | expr );", 7, 3, input);
+
+                    throw nvae;
+                }
+                }
+                break;
+            case STRING:
+                {
+                int LA7_4 = input.LA(2);
+
+                if ( (synpred16()) ) {
+                    alt7=1;
+                }
+                else if ( (true) ) {
+                    alt7=2;
+                }
+                else {
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("90:1: expr_list : ( expr SEPR expr_list -> ^( SEPR expr expr_list ) | expr );", 7, 4, input);
+
+                    throw nvae;
+                }
+                }
+                break;
+            case LPAREN:
+                {
+                int LA7_5 = input.LA(2);
+
+                if ( (synpred16()) ) {
+                    alt7=1;
+                }
+                else if ( (true) ) {
+                    alt7=2;
+                }
+                else {
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("90:1: expr_list : ( expr SEPR expr_list -> ^( SEPR expr expr_list ) | expr );", 7, 5, input);
+
+                    throw nvae;
+                }
+                }
+                break;
+            case NOT:
+            case TWIDDLE:
+                {
+                int LA7_6 = input.LA(2);
+
+                if ( (synpred16()) ) {
+                    alt7=1;
+                }
+                else if ( (true) ) {
+                    alt7=2;
+                }
+                else {
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("90:1: expr_list : ( expr SEPR expr_list -> ^( SEPR expr expr_list ) | expr );", 7, 6, input);
+
+                    throw nvae;
+                }
+                }
+                break;
+            default:
+                if (backtracking>0) {failed=true; return retval;}
+                NoViableAltException nvae =
+                    new NoViableAltException("90:1: expr_list : ( expr SEPR expr_list -> ^( SEPR expr expr_list ) | expr );", 7, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt7) {
+                case 1 :
+                    // dd/grammar/ECAGrammar.g:91:4: expr SEPR expr_list
+                    {
+                    pushFollow(FOLLOW_expr_in_expr_list528);
+                    expr43=expr();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_expr.add(expr43.getTree());
+                    SEPR44=(Token)input.LT(1);
+                    match(input,SEPR,FOLLOW_SEPR_in_expr_list530); if (failed) return retval;
+                    if ( backtracking==0 ) stream_SEPR.add(SEPR44);
+
+                    pushFollow(FOLLOW_expr_list_in_expr_list532);
+                    expr_list45=expr_list();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_expr_list.add(expr_list45.getTree());
+
+                    // AST REWRITE
+                    // elements: expr, expr_list, SEPR
+                    // token labels: 
+                    // rule labels: retval
+                    // token list labels: 
+                    // rule list labels: 
+                    if ( backtracking==0 ) {
+                    retval.tree = root_0;
+                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);
+
+                    root_0 = (Object)adaptor.nil();
+                    // 91:26: -> ^( SEPR expr expr_list )
+                    {
+                        // dd/grammar/ECAGrammar.g:91:29: ^( SEPR expr expr_list )
+                        {
+                        Object root_1 = (Object)adaptor.nil();
+                        root_1 = (Object)adaptor.becomeRoot(stream_SEPR.next(), root_1);
+
+                        adaptor.addChild(root_1, stream_expr.next());
+                        adaptor.addChild(root_1, stream_expr_list.next());
+
+                        adaptor.addChild(root_0, root_1);
+                        }
+
+                    }
+
+                    }
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAGrammar.g:92:4: expr
+                    {
+                    root_0 = (Object)adaptor.nil();
+
+                    pushFollow(FOLLOW_expr_in_expr_list549);
+                    expr46=expr();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) adaptor.addChild(root_0, expr46.getTree());
+
+                    }
+                    break;
+
+            }
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end expr_list
+
+    public static class array_idx_list_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start array_idx_list
+    // dd/grammar/ECAGrammar.g:95:1: array_idx_list : ( array_idx array_idx_list -> ^( SEPR array_idx array_idx_list ) | array_idx );
+    public final array_idx_list_return array_idx_list() throws RecognitionException {
+        array_idx_list_return retval = new array_idx_list_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        array_idx_return array_idx47 = null;
+
+        array_idx_list_return array_idx_list48 = null;
+
+        array_idx_return array_idx49 = null;
+
+
+        RewriteRuleSubtreeStream stream_array_idx=new RewriteRuleSubtreeStream(adaptor,"rule array_idx");
+        RewriteRuleSubtreeStream stream_array_idx_list=new RewriteRuleSubtreeStream(adaptor,"rule array_idx_list");
+        try {
+            // dd/grammar/ECAGrammar.g:96:2: ( array_idx array_idx_list -> ^( SEPR array_idx array_idx_list ) | array_idx )
+            int alt8=2;
+            int LA8_0 = input.LA(1);
+
+            if ( (LA8_0==LSQUARE) ) {
+                int LA8_1 = input.LA(2);
+
+                if ( (synpred17()) ) {
+                    alt8=1;
+                }
+                else if ( (true) ) {
+                    alt8=2;
+                }
+                else {
+                    if (backtracking>0) {failed=true; return retval;}
+                    NoViableAltException nvae =
+                        new NoViableAltException("95:1: array_idx_list : ( array_idx array_idx_list -> ^( SEPR array_idx array_idx_list ) | array_idx );", 8, 1, input);
+
+                    throw nvae;
+                }
+            }
+            else {
+                if (backtracking>0) {failed=true; return retval;}
+                NoViableAltException nvae =
+                    new NoViableAltException("95:1: array_idx_list : ( array_idx array_idx_list -> ^( SEPR array_idx array_idx_list ) | array_idx );", 8, 0, input);
+
+                throw nvae;
+            }
+            switch (alt8) {
+                case 1 :
+                    // dd/grammar/ECAGrammar.g:96:4: array_idx array_idx_list
+                    {
+                    pushFollow(FOLLOW_array_idx_in_array_idx_list560);
+                    array_idx47=array_idx();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_array_idx.add(array_idx47.getTree());
+                    pushFollow(FOLLOW_array_idx_list_in_array_idx_list562);
+                    array_idx_list48=array_idx_list();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) stream_array_idx_list.add(array_idx_list48.getTree());
+
+                    // AST REWRITE
+                    // elements: array_idx, array_idx_list
+                    // token labels: 
+                    // rule labels: retval
+                    // token list labels: 
+                    // rule list labels: 
+                    if ( backtracking==0 ) {
+                    retval.tree = root_0;
+                    RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);
+
+                    root_0 = (Object)adaptor.nil();
+                    // 96:31: -> ^( SEPR array_idx array_idx_list )
+                    {
+                        // dd/grammar/ECAGrammar.g:96:34: ^( SEPR array_idx array_idx_list )
+                        {
+                        Object root_1 = (Object)adaptor.nil();
+                        root_1 = (Object)adaptor.becomeRoot(adaptor.create(SEPR, "SEPR"), root_1);
+
+                        adaptor.addChild(root_1, stream_array_idx.next());
+                        adaptor.addChild(root_1, stream_array_idx_list.next());
+
+                        adaptor.addChild(root_0, root_1);
+                        }
+
+                    }
+
+                    }
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAGrammar.g:97:4: array_idx
+                    {
+                    root_0 = (Object)adaptor.nil();
+
+                    pushFollow(FOLLOW_array_idx_in_array_idx_list579);
+                    array_idx49=array_idx();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) adaptor.addChild(root_0, array_idx49.getTree());
+
+                    }
+                    break;
+
+            }
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end array_idx_list
+
+    public static class array_idx_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start array_idx
+    // dd/grammar/ECAGrammar.g:100:1: array_idx : LSQUARE expr RSQUARE -> ^( expr ) ;
+    public final array_idx_return array_idx() throws RecognitionException {
+        array_idx_return retval = new array_idx_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        Token LSQUARE50=null;
+        Token RSQUARE52=null;
+        expr_return expr51 = null;
+
+
+        Object LSQUARE50_tree=null;
+        Object RSQUARE52_tree=null;
+        RewriteRuleTokenStream stream_LSQUARE=new RewriteRuleTokenStream(adaptor,"token LSQUARE");
+        RewriteRuleTokenStream stream_RSQUARE=new RewriteRuleTokenStream(adaptor,"token RSQUARE");
+        RewriteRuleSubtreeStream stream_expr=new RewriteRuleSubtreeStream(adaptor,"rule expr");
+        try {
+            // dd/grammar/ECAGrammar.g:101:2: ( LSQUARE expr RSQUARE -> ^( expr ) )
+            // dd/grammar/ECAGrammar.g:101:4: LSQUARE expr RSQUARE
+            {
+            LSQUARE50=(Token)input.LT(1);
+            match(input,LSQUARE,FOLLOW_LSQUARE_in_array_idx590); if (failed) return retval;
+            if ( backtracking==0 ) stream_LSQUARE.add(LSQUARE50);
+
+            pushFollow(FOLLOW_expr_in_array_idx592);
+            expr51=expr();
+            _fsp--;
+            if (failed) return retval;
+            if ( backtracking==0 ) stream_expr.add(expr51.getTree());
+            RSQUARE52=(Token)input.LT(1);
+            match(input,RSQUARE,FOLLOW_RSQUARE_in_array_idx594); if (failed) return retval;
+            if ( backtracking==0 ) stream_RSQUARE.add(RSQUARE52);
+
+
+            // AST REWRITE
+            // elements: expr
+            // token labels: 
+            // rule labels: retval
+            // token list labels: 
+            // rule list labels: 
+            if ( backtracking==0 ) {
+            retval.tree = root_0;
+            RewriteRuleSubtreeStream stream_retval=new RewriteRuleSubtreeStream(adaptor,"token retval",retval!=null?retval.tree:null);
+
+            root_0 = (Object)adaptor.nil();
+            // 101:27: -> ^( expr )
+            {
+                // dd/grammar/ECAGrammar.g:101:30: ^( expr )
+                {
+                Object root_1 = (Object)adaptor.nil();
+                root_1 = (Object)adaptor.becomeRoot(stream_expr.nextNode(), root_1);
+
+                adaptor.addChild(root_0, root_1);
+                }
+
+            }
+
+            }
+
+            }
+
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end array_idx
+
+    public static class infix_oper_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start infix_oper
+    // dd/grammar/ECAGrammar.g:104:1: infix_oper : ( infix_bit_oper | infix_arith_oper | infix_bool_oper | infix_cmp_oper );
+    public final infix_oper_return infix_oper() throws RecognitionException {
+        infix_oper_return retval = new infix_oper_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        infix_bit_oper_return infix_bit_oper53 = null;
+
+        infix_arith_oper_return infix_arith_oper54 = null;
+
+        infix_bool_oper_return infix_bool_oper55 = null;
+
+        infix_cmp_oper_return infix_cmp_oper56 = null;
+
+
+
+        try {
+            // dd/grammar/ECAGrammar.g:104:12: ( infix_bit_oper | infix_arith_oper | infix_bool_oper | infix_cmp_oper )
+            int alt9=4;
+            switch ( input.LA(1) ) {
+            case BOR:
+            case BAND:
+            case BXOR:
+                {
+                alt9=1;
+                }
+                break;
+            case MUL:
+            case DIV:
+            case PLUS:
+            case MINUS:
+                {
+                alt9=2;
+                }
+                break;
+            case OR:
+            case AND:
+                {
+                alt9=3;
+                }
+                break;
+            case EQ:
+            case NEQ:
+            case GT:
+            case LT:
+            case GEQ:
+            case LEQ:
+                {
+                alt9=4;
+                }
+                break;
+            default:
+                if (backtracking>0) {failed=true; return retval;}
+                NoViableAltException nvae =
+                    new NoViableAltException("104:1: infix_oper : ( infix_bit_oper | infix_arith_oper | infix_bool_oper | infix_cmp_oper );", 9, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt9) {
+                case 1 :
+                    // dd/grammar/ECAGrammar.g:104:14: infix_bit_oper
+                    {
+                    root_0 = (Object)adaptor.nil();
+
+                    pushFollow(FOLLOW_infix_bit_oper_in_infix_oper612);
+                    infix_bit_oper53=infix_bit_oper();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) adaptor.addChild(root_0, infix_bit_oper53.getTree());
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAGrammar.g:105:4: infix_arith_oper
+                    {
+                    root_0 = (Object)adaptor.nil();
+
+                    pushFollow(FOLLOW_infix_arith_oper_in_infix_oper617);
+                    infix_arith_oper54=infix_arith_oper();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) adaptor.addChild(root_0, infix_arith_oper54.getTree());
+
+                    }
+                    break;
+                case 3 :
+                    // dd/grammar/ECAGrammar.g:106:4: infix_bool_oper
+                    {
+                    root_0 = (Object)adaptor.nil();
+
+                    pushFollow(FOLLOW_infix_bool_oper_in_infix_oper622);
+                    infix_bool_oper55=infix_bool_oper();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) adaptor.addChild(root_0, infix_bool_oper55.getTree());
+
+                    }
+                    break;
+                case 4 :
+                    // dd/grammar/ECAGrammar.g:107:4: infix_cmp_oper
+                    {
+                    root_0 = (Object)adaptor.nil();
+
+                    pushFollow(FOLLOW_infix_cmp_oper_in_infix_oper627);
+                    infix_cmp_oper56=infix_cmp_oper();
+                    _fsp--;
+                    if (failed) return retval;
+                    if ( backtracking==0 ) adaptor.addChild(root_0, infix_cmp_oper56.getTree());
+
+                    }
+                    break;
+
+            }
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end infix_oper
+
+    public static class infix_bit_oper_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start infix_bit_oper
+    // dd/grammar/ECAGrammar.g:110:1: infix_bit_oper : ( BAND | BOR | BXOR );
+    public final infix_bit_oper_return infix_bit_oper() throws RecognitionException {
+        infix_bit_oper_return retval = new infix_bit_oper_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        Token set57=null;
+
+        Object set57_tree=null;
+
+        try {
+            // dd/grammar/ECAGrammar.g:111:2: ( BAND | BOR | BXOR )
+            // dd/grammar/ECAGrammar.g:
+            {
+            root_0 = (Object)adaptor.nil();
+
+            set57=(Token)input.LT(1);
+            if ( (input.LA(1)>=BOR && input.LA(1)<=BXOR) ) {
+                input.consume();
+                if ( backtracking==0 ) adaptor.addChild(root_0, adaptor.create(set57));
+                errorRecovery=false;failed=false;
+            }
+            else {
+                if (backtracking>0) {failed=true; return retval;}
+                MismatchedSetException mse =
+                    new MismatchedSetException(null,input);
+                recoverFromMismatchedSet(input,mse,FOLLOW_set_in_infix_bit_oper0);    throw mse;
+            }
+
+
+            }
+
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end infix_bit_oper
+
+    public static class infix_arith_oper_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start infix_arith_oper
+    // dd/grammar/ECAGrammar.g:116:1: infix_arith_oper : ( MUL | DIV | PLUS | MINUS );
+    public final infix_arith_oper_return infix_arith_oper() throws RecognitionException {
+        infix_arith_oper_return retval = new infix_arith_oper_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        Token set58=null;
+
+        Object set58_tree=null;
+
+        try {
+            // dd/grammar/ECAGrammar.g:117:2: ( MUL | DIV | PLUS | MINUS )
+            // dd/grammar/ECAGrammar.g:
+            {
+            root_0 = (Object)adaptor.nil();
+
+            set58=(Token)input.LT(1);
+            if ( (input.LA(1)>=MUL && input.LA(1)<=MINUS) ) {
+                input.consume();
+                if ( backtracking==0 ) adaptor.addChild(root_0, adaptor.create(set58));
+                errorRecovery=false;failed=false;
+            }
+            else {
+                if (backtracking>0) {failed=true; return retval;}
+                MismatchedSetException mse =
+                    new MismatchedSetException(null,input);
+                recoverFromMismatchedSet(input,mse,FOLLOW_set_in_infix_arith_oper0);    throw mse;
+            }
+
+
+            }
+
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end infix_arith_oper
+
+    public static class infix_bool_oper_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start infix_bool_oper
+    // dd/grammar/ECAGrammar.g:123:1: infix_bool_oper : ( AND | OR );
+    public final infix_bool_oper_return infix_bool_oper() throws RecognitionException {
+        infix_bool_oper_return retval = new infix_bool_oper_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        Token set59=null;
+
+        Object set59_tree=null;
+
+        try {
+            // dd/grammar/ECAGrammar.g:124:2: ( AND | OR )
+            // dd/grammar/ECAGrammar.g:
+            {
+            root_0 = (Object)adaptor.nil();
+
+            set59=(Token)input.LT(1);
+            if ( (input.LA(1)>=OR && input.LA(1)<=AND) ) {
+                input.consume();
+                if ( backtracking==0 ) adaptor.addChild(root_0, adaptor.create(set59));
+                errorRecovery=false;failed=false;
+            }
+            else {
+                if (backtracking>0) {failed=true; return retval;}
+                MismatchedSetException mse =
+                    new MismatchedSetException(null,input);
+                recoverFromMismatchedSet(input,mse,FOLLOW_set_in_infix_bool_oper0);    throw mse;
+            }
+
+
+            }
+
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end infix_bool_oper
+
+    public static class infix_cmp_oper_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start infix_cmp_oper
+    // dd/grammar/ECAGrammar.g:128:1: infix_cmp_oper : ( EQ | NEQ | GT | LT | GEQ | LEQ );
+    public final infix_cmp_oper_return infix_cmp_oper() throws RecognitionException {
+        infix_cmp_oper_return retval = new infix_cmp_oper_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        Token set60=null;
+
+        Object set60_tree=null;
+
+        try {
+            // dd/grammar/ECAGrammar.g:129:2: ( EQ | NEQ | GT | LT | GEQ | LEQ )
+            // dd/grammar/ECAGrammar.g:
+            {
+            root_0 = (Object)adaptor.nil();
+
+            set60=(Token)input.LT(1);
+            if ( (input.LA(1)>=EQ && input.LA(1)<=LEQ) ) {
+                input.consume();
+                if ( backtracking==0 ) adaptor.addChild(root_0, adaptor.create(set60));
+                errorRecovery=false;failed=false;
+            }
+            else {
+                if (backtracking>0) {failed=true; return retval;}
+                MismatchedSetException mse =
+                    new MismatchedSetException(null,input);
+                recoverFromMismatchedSet(input,mse,FOLLOW_set_in_infix_cmp_oper0);    throw mse;
+            }
+
+
+            }
+
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end infix_cmp_oper
+
+    public static class unary_oper_return extends ParserRuleReturnScope {
+        Object tree;
+        public Object getTree() { return tree; }
+    };
+
+    // $ANTLR start unary_oper
+    // dd/grammar/ECAGrammar.g:137:1: unary_oper : ( NOT | TWIDDLE );
+    public final unary_oper_return unary_oper() throws RecognitionException {
+        unary_oper_return retval = new unary_oper_return();
+        retval.start = input.LT(1);
+
+        Object root_0 = null;
+
+        Token set61=null;
+
+        Object set61_tree=null;
+
+        try {
+            // dd/grammar/ECAGrammar.g:137:12: ( NOT | TWIDDLE )
+            // dd/grammar/ECAGrammar.g:
+            {
+            root_0 = (Object)adaptor.nil();
+
+            set61=(Token)input.LT(1);
+            if ( input.LA(1)==NOT||input.LA(1)==TWIDDLE ) {
+                input.consume();
+                if ( backtracking==0 ) adaptor.addChild(root_0, adaptor.create(set61));
+                errorRecovery=false;failed=false;
+            }
+            else {
+                if (backtracking>0) {failed=true; return retval;}
+                MismatchedSetException mse =
+                    new MismatchedSetException(null,input);
+                recoverFromMismatchedSet(input,mse,FOLLOW_set_in_unary_oper0);    throw mse;
+            }
+
+
+            }
+
+            retval.stop = input.LT(-1);
+
+            if ( backtracking==0 ) {
+                retval.tree = (Object)adaptor.rulePostProcessing(root_0);
+                adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
+            }
+        }
+        catch (RecognitionException re) {
+            reportError(re);
+            recover(input,re);
+        }
+        finally {
+        }
+        return retval;
+    }
+    // $ANTLR end unary_oper
+
+    // $ANTLR start synpred3
+    public final void synpred3_fragment() throws RecognitionException {   
+        // dd/grammar/ECAGrammar.g:40:12: ( binding SEPR bindings )
+        // dd/grammar/ECAGrammar.g:40:12: binding SEPR bindings
+        {
+        pushFollow(FOLLOW_binding_in_synpred3162);
+        binding();
+        _fsp--;
+        if (failed) return ;
+        match(input,SEPR,FOLLOW_SEPR_in_synpred3164); if (failed) return ;
+        pushFollow(FOLLOW_bindings_in_synpred3166);
+        bindings();
+        _fsp--;
+        if (failed) return ;
+
+        }
+    }
+    // $ANTLR end synpred3
+
+    // $ANTLR start synpred5
+    public final void synpred5_fragment() throws RecognitionException {   
+        // dd/grammar/ECAGrammar.g:67:4: ( action_expr SEPR action_expr_list )
+        // dd/grammar/ECAGrammar.g:67:4: action_expr SEPR action_expr_list
+        {
+        pushFollow(FOLLOW_action_expr_in_synpred5281);
+        action_expr();
+        _fsp--;
+        if (failed) return ;
+        match(input,SEPR,FOLLOW_SEPR_in_synpred5283); if (failed) return ;
+        pushFollow(FOLLOW_action_expr_list_in_synpred5285);
+        action_expr_list();
+        _fsp--;
+        if (failed) return ;
+
+        }
+    }
+    // $ANTLR end synpred5
+
+    // $ANTLR start synpred6
+    public final void synpred6_fragment() throws RecognitionException {   
+        // dd/grammar/ECAGrammar.g:74:8: ( simple_expr infix_oper expr )
+        // dd/grammar/ECAGrammar.g:74:8: simple_expr infix_oper expr
+        {
+        pushFollow(FOLLOW_simple_expr_in_synpred6320);
+        simple_expr();
+        _fsp--;
+        if (failed) return ;
+        pushFollow(FOLLOW_infix_oper_in_synpred6322);
+        infix_oper();
+        _fsp--;
+        if (failed) return ;
+        pushFollow(FOLLOW_expr_in_synpred6324);
+        expr();
+        _fsp--;
+        if (failed) return ;
+
+        }
+    }
+    // $ANTLR end synpred6
+
+    // $ANTLR start synpred7
+    public final void synpred7_fragment() throws RecognitionException {   
+        // dd/grammar/ECAGrammar.g:75:4: ( simple_expr )
+        // dd/grammar/ECAGrammar.g:75:4: simple_expr
+        {
+        pushFollow(FOLLOW_simple_expr_in_synpred7342);
+        simple_expr();
+        _fsp--;
+        if (failed) return ;
+
+        }
+    }
+    // $ANTLR end synpred7
+
+    // $ANTLR start synpred16
+    public final void synpred16_fragment() throws RecognitionException {   
+        // dd/grammar/ECAGrammar.g:91:4: ( expr SEPR expr_list )
+        // dd/grammar/ECAGrammar.g:91:4: expr SEPR expr_list
+        {
+        pushFollow(FOLLOW_expr_in_synpred16528);
+        expr();
+        _fsp--;
+        if (failed) return ;
+        match(input,SEPR,FOLLOW_SEPR_in_synpred16530); if (failed) return ;
+        pushFollow(FOLLOW_expr_list_in_synpred16532);
+        expr_list();
+        _fsp--;
+        if (failed) return ;
+
+        }
+    }
+    // $ANTLR end synpred16
+
+    // $ANTLR start synpred17
+    public final void synpred17_fragment() throws RecognitionException {   
+        // dd/grammar/ECAGrammar.g:96:4: ( array_idx array_idx_list )
+        // dd/grammar/ECAGrammar.g:96:4: array_idx array_idx_list
+        {
+        pushFollow(FOLLOW_array_idx_in_synpred17560);
+        array_idx();
+        _fsp--;
+        if (failed) return ;
+        pushFollow(FOLLOW_array_idx_list_in_synpred17562);
+        array_idx_list();
+        _fsp--;
+        if (failed) return ;
+
+        }
+    }
+    // $ANTLR end synpred17
+
+    public final boolean synpred16() {
+        backtracking++;
+        int start = input.mark();
+        try {
+            synpred16_fragment(); // can never throw exception
+        } catch (RecognitionException re) {
+            System.err.println("impossible: "+re);
+        }
+        boolean success = !failed;
+        input.rewind(start);
+        backtracking--;
+        failed=false;
+        return success;
+    }
+    public final boolean synpred7() {
+        backtracking++;
+        int start = input.mark();
+        try {
+            synpred7_fragment(); // can never throw exception
+        } catch (RecognitionException re) {
+            System.err.println("impossible: "+re);
+        }
+        boolean success = !failed;
+        input.rewind(start);
+        backtracking--;
+        failed=false;
+        return success;
+    }
+    public final boolean synpred3() {
+        backtracking++;
+        int start = input.mark();
+        try {
+            synpred3_fragment(); // can never throw exception
+        } catch (RecognitionException re) {
+            System.err.println("impossible: "+re);
+        }
+        boolean success = !failed;
+        input.rewind(start);
+        backtracking--;
+        failed=false;
+        return success;
+    }
+    public final boolean synpred5() {
+        backtracking++;
+        int start = input.mark();
+        try {
+            synpred5_fragment(); // can never throw exception
+        } catch (RecognitionException re) {
+            System.err.println("impossible: "+re);
+        }
+        boolean success = !failed;
+        input.rewind(start);
+        backtracking--;
+        failed=false;
+        return success;
+    }
+    public final boolean synpred17() {
+        backtracking++;
+        int start = input.mark();
+        try {
+            synpred17_fragment(); // can never throw exception
+        } catch (RecognitionException re) {
+            System.err.println("impossible: "+re);
+        }
+        boolean success = !failed;
+        input.rewind(start);
+        backtracking--;
+        failed=false;
+        return success;
+    }
+    public final boolean synpred6() {
+        backtracking++;
+        int start = input.mark();
+        try {
+            synpred6_fragment(); // can never throw exception
+        } catch (RecognitionException re) {
+            System.err.println("impossible: "+re);
+        }
+        boolean success = !failed;
+        input.rewind(start);
+        backtracking--;
+        failed=false;
+        return success;
+    }
+
+
+ 
+
+    public static final BitSet FOLLOW_eca_in_eca_rule86 = new BitSet(new long[]{0x0000000000000000L});
+    public static final BitSet FOLLOW_EOF_in_eca_rule88 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_WHEN_in_eca97 = new BitSet(new long[]{0x0100000000000000L});
+    public static final BitSet FOLLOW_event_in_eca99 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_IF_in_eca112 = new BitSet(new long[]{0x0510002008011000L});
+    public static final BitSet FOLLOW_condition_in_eca114 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_DO_in_eca128 = new BitSet(new long[]{0x0510002008011000L});
+    public static final BitSet FOLLOW_action_in_eca130 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_bindings_in_event150 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_binding_in_bindings162 = new BitSet(new long[]{0x0000000000400000L});
+    public static final BitSet FOLLOW_SEPR_in_bindings164 = new BitSet(new long[]{0x0100000000000000L});
+    public static final BitSet FOLLOW_bindings_in_bindings166 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_binding_in_bindings181 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_bind_sym_in_binding191 = new BitSet(new long[]{0x0000000001000000L});
+    public static final BitSet FOLLOW_ASSIGN_in_binding193 = new BitSet(new long[]{0x0510002008011000L});
+    public static final BitSet FOLLOW_expr_in_binding195 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_SYMBOL_in_bind_sym218 = new BitSet(new long[]{0x0000100000000000L});
+    public static final BitSet FOLLOW_COLON_in_bind_sym220 = new BitSet(new long[]{0x0100000000000000L});
+    public static final BitSet FOLLOW_SYMBOL_in_bind_sym224 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_SYMBOL_in_bind_sym242 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_expr_in_condition256 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_action_expr_list_in_action270 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_action_expr_in_action_expr_list281 = new BitSet(new long[]{0x0000000000400000L});
+    public static final BitSet FOLLOW_SEPR_in_action_expr_list283 = new BitSet(new long[]{0x0510002008011000L});
+    public static final BitSet FOLLOW_action_expr_list_in_action_expr_list285 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_action_expr_in_action_expr_list300 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_expr_in_action_expr310 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_simple_expr_in_expr320 = new BitSet(new long[]{0x000003DFF6000000L});
+    public static final BitSet FOLLOW_infix_oper_in_expr322 = new BitSet(new long[]{0x0510002008011000L});
+    public static final BitSet FOLLOW_expr_in_expr324 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_simple_expr_in_expr342 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_unary_oper_in_expr347 = new BitSet(new long[]{0x0510002008011000L});
+    public static final BitSet FOLLOW_expr_in_expr349 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_simple_expr_in_expr368 = new BitSet(new long[]{0x0000080000000000L});
+    public static final BitSet FOLLOW_TERN_IF_in_expr370 = new BitSet(new long[]{0x0510002008011000L});
+    public static final BitSet FOLLOW_expr_in_expr374 = new BitSet(new long[]{0x0000100000000000L});
+    public static final BitSet FOLLOW_COLON_in_expr376 = new BitSet(new long[]{0x0510002008011000L});
+    public static final BitSet FOLLOW_expr_in_expr380 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_DOLLARSYM_in_simple_expr407 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_SYMBOL_in_simple_expr414 = new BitSet(new long[]{0x0000000000040000L});
+    public static final BitSet FOLLOW_array_idx_in_simple_expr418 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_SYMBOL_in_simple_expr439 = new BitSet(new long[]{0x0000000000010000L});
+    public static final BitSet FOLLOW_LPAREN_in_simple_expr441 = new BitSet(new long[]{0x0000000000020000L});
+    public static final BitSet FOLLOW_RPAREN_in_simple_expr443 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_SYMBOL_in_simple_expr461 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_SYMBOL_in_simple_expr468 = new BitSet(new long[]{0x0000000000010000L});
+    public static final BitSet FOLLOW_LPAREN_in_simple_expr470 = new BitSet(new long[]{0x0510002008011000L});
+    public static final BitSet FOLLOW_expr_list_in_simple_expr474 = new BitSet(new long[]{0x0000000000020000L});
+    public static final BitSet FOLLOW_RPAREN_in_simple_expr476 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_NUMBER_in_simple_expr495 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_STRING_in_simple_expr500 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_LPAREN_in_simple_expr505 = new BitSet(new long[]{0x0510002008011000L});
+    public static final BitSet FOLLOW_expr_in_simple_expr507 = new BitSet(new long[]{0x0000000000020000L});
+    public static final BitSet FOLLOW_RPAREN_in_simple_expr509 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_expr_in_expr_list528 = new BitSet(new long[]{0x0000000000400000L});
+    public static final BitSet FOLLOW_SEPR_in_expr_list530 = new BitSet(new long[]{0x0510002008011000L});
+    public static final BitSet FOLLOW_expr_list_in_expr_list532 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_expr_in_expr_list549 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_array_idx_in_array_idx_list560 = new BitSet(new long[]{0x0000000000040000L});
+    public static final BitSet FOLLOW_array_idx_list_in_array_idx_list562 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_array_idx_in_array_idx_list579 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_LSQUARE_in_array_idx590 = new BitSet(new long[]{0x0510002008011000L});
+    public static final BitSet FOLLOW_expr_in_array_idx592 = new BitSet(new long[]{0x0000000000080000L});
+    public static final BitSet FOLLOW_RSQUARE_in_array_idx594 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_infix_bit_oper_in_infix_oper612 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_infix_arith_oper_in_infix_oper617 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_infix_bool_oper_in_infix_oper622 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_infix_cmp_oper_in_infix_oper627 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_set_in_infix_bit_oper0 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_set_in_infix_arith_oper0 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_set_in_infix_bool_oper0 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_set_in_infix_cmp_oper0 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_set_in_unary_oper0 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_binding_in_synpred3162 = new BitSet(new long[]{0x0000000000400000L});
+    public static final BitSet FOLLOW_SEPR_in_synpred3164 = new BitSet(new long[]{0x0100000000000000L});
+    public static final BitSet FOLLOW_bindings_in_synpred3166 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_action_expr_in_synpred5281 = new BitSet(new long[]{0x0000000000400000L});
+    public static final BitSet FOLLOW_SEPR_in_synpred5283 = new BitSet(new long[]{0x0510002008011000L});
+    public static final BitSet FOLLOW_action_expr_list_in_synpred5285 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_simple_expr_in_synpred6320 = new BitSet(new long[]{0x000003DFF6000000L});
+    public static final BitSet FOLLOW_infix_oper_in_synpred6322 = new BitSet(new long[]{0x0510002008011000L});
+    public static final BitSet FOLLOW_expr_in_synpred6324 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_simple_expr_in_synpred7342 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_expr_in_synpred16528 = new BitSet(new long[]{0x0000000000400000L});
+    public static final BitSet FOLLOW_SEPR_in_synpred16530 = new BitSet(new long[]{0x0510002008011000L});
+    public static final BitSet FOLLOW_expr_list_in_synpred16532 = new BitSet(new long[]{0x0000000000000002L});
+    public static final BitSet FOLLOW_array_idx_in_synpred17560 = new BitSet(new long[]{0x0000000000040000L});
+    public static final BitSet FOLLOW_array_idx_list_in_synpred17562 = new BitSet(new long[]{0x0000000000000002L});
+
+}
\ No newline at end of file

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/grammar/ECATokenLexer.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/grammar/ECATokenLexer.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/grammar/ECATokenLexer.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,3457 @@
+// $ANTLR 3.0.1 dd/grammar/ECAToken.g 2008-07-18 14:15:59
+
+package org.jboss.jbossts.orchestration.rule.grammar;
+
+
+import org.antlr.runtime.*;
+import java.util.Stack;
+import java.util.List;
+import java.util.ArrayList;
+
+public class ECATokenLexer extends Lexer {
+    public static final int MINUS=41;
+    public static final int NUMBER=12;
+    public static final int FLOAT=11;
+    public static final int POSDIGIT=5;
+    public static final int LEQ=33;
+    public static final int TWIDDLE=37;
+    public static final int MOD=42;
+    public static final int GEQ=32;
+    public static final int DQUOTE=48;
+    public static final int OR=25;
+    public static final int BOR=34;
+    public static final int BAREINT=7;
+    public static final int LBRACE=20;
+    public static final int NEWLINE=50;
+    public static final int DOT=23;
+    public static final int RBRACE=21;
+    public static final int INTEGER=8;
+    public static final int AND=26;
+    public static final int ASSIGN=24;
+    public static final int SYMBOL=56;
+    public static final int RPAREN=17;
+    public static final int LPAREN=16;
+    public static final int SIGN=6;
+    public static final int DIGIT=4;
+    public static final int PLUS=40;
+    public static final int BAND=35;
+    public static final int NEQ=29;
+    public static final int SPACE=49;
+    public static final int LETTER=45;
+    public static final int LSQUARE=18;
+    public static final int DO=15;
+    public static final int POINT=9;
+    public static final int WHEN=13;
+    public static final int BARESYM=53;
+    public static final int SEPR=22;
+    public static final int WS=59;
+    public static final int STRING=52;
+    public static final int EQ=28;
+    public static final int QUOTSYM=54;
+    public static final int LT=31;
+    public static final int GT=30;
+    public static final int DOLLAR=57;
+    public static final int RSQUARE=19;
+    public static final int QUOTE=47;
+    public static final int TERN_IF=43;
+    public static final int MUL=38;
+    public static final int EXPPART=10;
+    public static final int PUNCT=51;
+    public static final int IF=14;
+    public static final int EOF=-1;
+    public static final int Tokens=60;
+    public static final int COLON=44;
+    public static final int DIV=39;
+    public static final int DOTSYM=55;
+    public static final int BXOR=36;
+    public static final int NOT=27;
+    public static final int UNDERSCORE=46;
+    public static final int DOLLARSYM=58;
+    public ECATokenLexer() {;} 
+    public ECATokenLexer(CharStream input) {
+        super(input);
+    }
+    public String getGrammarFileName() { return "dd/grammar/ECAToken.g"; }
+
+    // $ANTLR start DIGIT
+    public final void mDIGIT() throws RecognitionException {
+        try {
+            // dd/grammar/ECAToken.g:10:7: ( '0' .. '9' )
+            // dd/grammar/ECAToken.g:10:9: '0' .. '9'
+            {
+            matchRange('0','9'); 
+
+            }
+
+        }
+        finally {
+        }
+    }
+    // $ANTLR end DIGIT
+
+    // $ANTLR start POSDIGIT
+    public final void mPOSDIGIT() throws RecognitionException {
+        try {
+            // dd/grammar/ECAToken.g:14:10: ( '1' .. '9' )
+            // dd/grammar/ECAToken.g:14:12: '1' .. '9'
+            {
+            matchRange('1','9'); 
+
+            }
+
+        }
+        finally {
+        }
+    }
+    // $ANTLR end POSDIGIT
+
+    // $ANTLR start SIGN
+    public final void mSIGN() throws RecognitionException {
+        try {
+            // dd/grammar/ECAToken.g:18:6: ( '+' | '-' )
+            // dd/grammar/ECAToken.g:
+            {
+            if ( input.LA(1)=='+'||input.LA(1)=='-' ) {
+                input.consume();
+
+            }
+            else {
+                MismatchedSetException mse =
+                    new MismatchedSetException(null,input);
+                recover(mse);    throw mse;
+            }
+
+
+            }
+
+        }
+        finally {
+        }
+    }
+    // $ANTLR end SIGN
+
+    // $ANTLR start BAREINT
+    public final void mBAREINT() throws RecognitionException {
+        try {
+            // dd/grammar/ECAToken.g:22:9: ( '0' | ( POSDIGIT ( DIGIT )* ) )
+            int alt2=2;
+            int LA2_0 = input.LA(1);
+
+            if ( (LA2_0=='0') ) {
+                alt2=1;
+            }
+            else if ( ((LA2_0>='1' && LA2_0<='9')) ) {
+                alt2=2;
+            }
+            else {
+                NoViableAltException nvae =
+                    new NoViableAltException("21:1: fragment BAREINT : ( '0' | ( POSDIGIT ( DIGIT )* ) );", 2, 0, input);
+
+                throw nvae;
+            }
+            switch (alt2) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:22:11: '0'
+                    {
+                    match('0'); 
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:22:17: ( POSDIGIT ( DIGIT )* )
+                    {
+                    // dd/grammar/ECAToken.g:22:17: ( POSDIGIT ( DIGIT )* )
+                    // dd/grammar/ECAToken.g:22:18: POSDIGIT ( DIGIT )*
+                    {
+                    mPOSDIGIT(); 
+                    // dd/grammar/ECAToken.g:22:27: ( DIGIT )*
+                    loop1:
+                    do {
+                        int alt1=2;
+                        int LA1_0 = input.LA(1);
+
+                        if ( ((LA1_0>='0' && LA1_0<='9')) ) {
+                            alt1=1;
+                        }
+
+
+                        switch (alt1) {
+                    	case 1 :
+                    	    // dd/grammar/ECAToken.g:22:28: DIGIT
+                    	    {
+                    	    mDIGIT(); 
+
+                    	    }
+                    	    break;
+
+                    	default :
+                    	    break loop1;
+                        }
+                    } while (true);
+
+
+                    }
+
+
+                    }
+                    break;
+
+            }
+        }
+        finally {
+        }
+    }
+    // $ANTLR end BAREINT
+
+    // $ANTLR start INTEGER
+    public final void mINTEGER() throws RecognitionException {
+        try {
+            // dd/grammar/ECAToken.g:26:9: ( ( SIGN )? BAREINT )
+            // dd/grammar/ECAToken.g:26:11: ( SIGN )? BAREINT
+            {
+            // dd/grammar/ECAToken.g:26:11: ( SIGN )?
+            int alt3=2;
+            int LA3_0 = input.LA(1);
+
+            if ( (LA3_0=='+'||LA3_0=='-') ) {
+                alt3=1;
+            }
+            switch (alt3) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:26:11: SIGN
+                    {
+                    mSIGN(); 
+
+                    }
+                    break;
+
+            }
+
+            mBAREINT(); 
+
+            }
+
+        }
+        finally {
+        }
+    }
+    // $ANTLR end INTEGER
+
+    // $ANTLR start POINT
+    public final void mPOINT() throws RecognitionException {
+        try {
+            // dd/grammar/ECAToken.g:30:7: ( '.' )
+            // dd/grammar/ECAToken.g:30:9: '.'
+            {
+            match('.'); 
+
+            }
+
+        }
+        finally {
+        }
+    }
+    // $ANTLR end POINT
+
+    // $ANTLR start EXPPART
+    public final void mEXPPART() throws RecognitionException {
+        try {
+            // dd/grammar/ECAToken.g:34:9: ( ( 'e' | 'E' ) INTEGER )
+            // dd/grammar/ECAToken.g:34:12: ( 'e' | 'E' ) INTEGER
+            {
+            if ( input.LA(1)=='E'||input.LA(1)=='e' ) {
+                input.consume();
+
+            }
+            else {
+                MismatchedSetException mse =
+                    new MismatchedSetException(null,input);
+                recover(mse);    throw mse;
+            }
+
+            mINTEGER(); 
+
+            }
+
+        }
+        finally {
+        }
+    }
+    // $ANTLR end EXPPART
+
+    // $ANTLR start FLOAT
+    public final void mFLOAT() throws RecognitionException {
+        try {
+            // dd/grammar/ECAToken.g:39:7: ( INTEGER POINT ( BAREINT )? ( EXPPART )? )
+            // dd/grammar/ECAToken.g:39:9: INTEGER POINT ( BAREINT )? ( EXPPART )?
+            {
+            mINTEGER(); 
+            mPOINT(); 
+            // dd/grammar/ECAToken.g:39:23: ( BAREINT )?
+            int alt4=2;
+            int LA4_0 = input.LA(1);
+
+            if ( ((LA4_0>='0' && LA4_0<='9')) ) {
+                alt4=1;
+            }
+            switch (alt4) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:39:23: BAREINT
+                    {
+                    mBAREINT(); 
+
+                    }
+                    break;
+
+            }
+
+            // dd/grammar/ECAToken.g:39:32: ( EXPPART )?
+            int alt5=2;
+            int LA5_0 = input.LA(1);
+
+            if ( (LA5_0=='E'||LA5_0=='e') ) {
+                alt5=1;
+            }
+            switch (alt5) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:39:32: EXPPART
+                    {
+                    mEXPPART(); 
+
+                    }
+                    break;
+
+            }
+
+
+            }
+
+        }
+        finally {
+        }
+    }
+    // $ANTLR end FLOAT
+
+    // $ANTLR start NUMBER
+    public final void mNUMBER() throws RecognitionException {
+        try {
+            int _type = NUMBER;
+            // dd/grammar/ECAToken.g:42:8: ( INTEGER | FLOAT )
+            int alt6=2;
+            alt6 = dfa6.predict(input);
+            switch (alt6) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:42:10: INTEGER
+                    {
+                    mINTEGER(); 
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:42:20: FLOAT
+                    {
+                    mFLOAT(); 
+
+                    }
+                    break;
+
+            }
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end NUMBER
+
+    // $ANTLR start WHEN
+    public final void mWHEN() throws RecognitionException {
+        try {
+            int _type = WHEN;
+            // dd/grammar/ECAToken.g:47:6: ( 'WHEN' )
+            // dd/grammar/ECAToken.g:47:8: 'WHEN'
+            {
+            match("WHEN"); 
+
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end WHEN
+
+    // $ANTLR start IF
+    public final void mIF() throws RecognitionException {
+        try {
+            int _type = IF;
+            // dd/grammar/ECAToken.g:50:4: ( 'IF' )
+            // dd/grammar/ECAToken.g:50:6: 'IF'
+            {
+            match("IF"); 
+
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end IF
+
+    // $ANTLR start DO
+    public final void mDO() throws RecognitionException {
+        try {
+            int _type = DO;
+            // dd/grammar/ECAToken.g:53:4: ( 'DO' )
+            // dd/grammar/ECAToken.g:53:6: 'DO'
+            {
+            match("DO"); 
+
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end DO
+
+    // $ANTLR start LPAREN
+    public final void mLPAREN() throws RecognitionException {
+        try {
+            int _type = LPAREN;
+            // dd/grammar/ECAToken.g:58:8: ( '(' )
+            // dd/grammar/ECAToken.g:58:10: '('
+            {
+            match('('); 
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end LPAREN
+
+    // $ANTLR start RPAREN
+    public final void mRPAREN() throws RecognitionException {
+        try {
+            int _type = RPAREN;
+            // dd/grammar/ECAToken.g:61:8: ( ')' )
+            // dd/grammar/ECAToken.g:61:10: ')'
+            {
+            match(')'); 
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end RPAREN
+
+    // $ANTLR start LSQUARE
+    public final void mLSQUARE() throws RecognitionException {
+        try {
+            int _type = LSQUARE;
+            // dd/grammar/ECAToken.g:64:9: ( '\\[' )
+            // dd/grammar/ECAToken.g:64:11: '\\['
+            {
+            match('['); 
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end LSQUARE
+
+    // $ANTLR start RSQUARE
+    public final void mRSQUARE() throws RecognitionException {
+        try {
+            int _type = RSQUARE;
+            // dd/grammar/ECAToken.g:67:9: ( '\\]' )
+            // dd/grammar/ECAToken.g:67:11: '\\]'
+            {
+            match(']'); 
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end RSQUARE
+
+    // $ANTLR start LBRACE
+    public final void mLBRACE() throws RecognitionException {
+        try {
+            int _type = LBRACE;
+            // dd/grammar/ECAToken.g:70:8: ( '{' )
+            // dd/grammar/ECAToken.g:70:10: '{'
+            {
+            match('{'); 
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end LBRACE
+
+    // $ANTLR start RBRACE
+    public final void mRBRACE() throws RecognitionException {
+        try {
+            int _type = RBRACE;
+            // dd/grammar/ECAToken.g:73:8: ( '}' )
+            // dd/grammar/ECAToken.g:73:10: '}'
+            {
+            match('}'); 
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end RBRACE
+
+    // $ANTLR start SEPR
+    public final void mSEPR() throws RecognitionException {
+        try {
+            int _type = SEPR;
+            // dd/grammar/ECAToken.g:78:6: ( ';' | ',' )
+            // dd/grammar/ECAToken.g:
+            {
+            if ( input.LA(1)==','||input.LA(1)==';' ) {
+                input.consume();
+
+            }
+            else {
+                MismatchedSetException mse =
+                    new MismatchedSetException(null,input);
+                recover(mse);    throw mse;
+            }
+
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end SEPR
+
+    // $ANTLR start DOT
+    public final void mDOT() throws RecognitionException {
+        try {
+            int _type = DOT;
+            // dd/grammar/ECAToken.g:84:5: ( '.' )
+            // dd/grammar/ECAToken.g:84:7: '.'
+            {
+            match('.'); 
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end DOT
+
+    // $ANTLR start ASSIGN
+    public final void mASSIGN() throws RecognitionException {
+        try {
+            int _type = ASSIGN;
+            // dd/grammar/ECAToken.g:89:8: ( '=' | '<--' )
+            int alt7=2;
+            int LA7_0 = input.LA(1);
+
+            if ( (LA7_0=='=') ) {
+                alt7=1;
+            }
+            else if ( (LA7_0=='<') ) {
+                alt7=2;
+            }
+            else {
+                NoViableAltException nvae =
+                    new NoViableAltException("89:1: ASSIGN : ( '=' | '<--' );", 7, 0, input);
+
+                throw nvae;
+            }
+            switch (alt7) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:89:10: '='
+                    {
+                    match('='); 
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:90:4: '<--'
+                    {
+                    match("<--"); 
+
+
+                    }
+                    break;
+
+            }
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end ASSIGN
+
+    // $ANTLR start OR
+    public final void mOR() throws RecognitionException {
+        try {
+            int _type = OR;
+            // dd/grammar/ECAToken.g:95:4: ( '||' | 'OR' | 'or' )
+            int alt8=3;
+            switch ( input.LA(1) ) {
+            case '|':
+                {
+                alt8=1;
+                }
+                break;
+            case 'O':
+                {
+                alt8=2;
+                }
+                break;
+            case 'o':
+                {
+                alt8=3;
+                }
+                break;
+            default:
+                NoViableAltException nvae =
+                    new NoViableAltException("95:1: OR : ( '||' | 'OR' | 'or' );", 8, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt8) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:95:6: '||'
+                    {
+                    match("||"); 
+
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:96:4: 'OR'
+                    {
+                    match("OR"); 
+
+
+                    }
+                    break;
+                case 3 :
+                    // dd/grammar/ECAToken.g:97:4: 'or'
+                    {
+                    match("or"); 
+
+
+                    }
+                    break;
+
+            }
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end OR
+
+    // $ANTLR start AND
+    public final void mAND() throws RecognitionException {
+        try {
+            int _type = AND;
+            // dd/grammar/ECAToken.g:100:5: ( '&&' | 'AND' | 'and' )
+            int alt9=3;
+            switch ( input.LA(1) ) {
+            case '&':
+                {
+                alt9=1;
+                }
+                break;
+            case 'A':
+                {
+                alt9=2;
+                }
+                break;
+            case 'a':
+                {
+                alt9=3;
+                }
+                break;
+            default:
+                NoViableAltException nvae =
+                    new NoViableAltException("100:1: AND : ( '&&' | 'AND' | 'and' );", 9, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt9) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:100:7: '&&'
+                    {
+                    match("&&"); 
+
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:101:4: 'AND'
+                    {
+                    match("AND"); 
+
+
+                    }
+                    break;
+                case 3 :
+                    // dd/grammar/ECAToken.g:102:4: 'and'
+                    {
+                    match("and"); 
+
+
+                    }
+                    break;
+
+            }
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end AND
+
+    // $ANTLR start NOT
+    public final void mNOT() throws RecognitionException {
+        try {
+            int _type = NOT;
+            // dd/grammar/ECAToken.g:105:5: ( '!' | 'NOT' | 'not' )
+            int alt10=3;
+            switch ( input.LA(1) ) {
+            case '!':
+                {
+                alt10=1;
+                }
+                break;
+            case 'N':
+                {
+                alt10=2;
+                }
+                break;
+            case 'n':
+                {
+                alt10=3;
+                }
+                break;
+            default:
+                NoViableAltException nvae =
+                    new NoViableAltException("105:1: NOT : ( '!' | 'NOT' | 'not' );", 10, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt10) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:105:7: '!'
+                    {
+                    match('!'); 
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:106:4: 'NOT'
+                    {
+                    match("NOT"); 
+
+
+                    }
+                    break;
+                case 3 :
+                    // dd/grammar/ECAToken.g:107:4: 'not'
+                    {
+                    match("not"); 
+
+
+                    }
+                    break;
+
+            }
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end NOT
+
+    // $ANTLR start EQ
+    public final void mEQ() throws RecognitionException {
+        try {
+            int _type = EQ;
+            // dd/grammar/ECAToken.g:112:4: ( '==' | 'EQ' | 'eq' )
+            int alt11=3;
+            switch ( input.LA(1) ) {
+            case '=':
+                {
+                alt11=1;
+                }
+                break;
+            case 'E':
+                {
+                alt11=2;
+                }
+                break;
+            case 'e':
+                {
+                alt11=3;
+                }
+                break;
+            default:
+                NoViableAltException nvae =
+                    new NoViableAltException("112:1: EQ : ( '==' | 'EQ' | 'eq' );", 11, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt11) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:112:6: '=='
+                    {
+                    match("=="); 
+
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:113:4: 'EQ'
+                    {
+                    match("EQ"); 
+
+
+                    }
+                    break;
+                case 3 :
+                    // dd/grammar/ECAToken.g:114:4: 'eq'
+                    {
+                    match("eq"); 
+
+
+                    }
+                    break;
+
+            }
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end EQ
+
+    // $ANTLR start NEQ
+    public final void mNEQ() throws RecognitionException {
+        try {
+            int _type = NEQ;
+            // dd/grammar/ECAToken.g:117:5: ( '!=' | 'NEQ' | 'neq' )
+            int alt12=3;
+            switch ( input.LA(1) ) {
+            case '!':
+                {
+                alt12=1;
+                }
+                break;
+            case 'N':
+                {
+                alt12=2;
+                }
+                break;
+            case 'n':
+                {
+                alt12=3;
+                }
+                break;
+            default:
+                NoViableAltException nvae =
+                    new NoViableAltException("117:1: NEQ : ( '!=' | 'NEQ' | 'neq' );", 12, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt12) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:117:7: '!='
+                    {
+                    match("!="); 
+
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:118:4: 'NEQ'
+                    {
+                    match("NEQ"); 
+
+
+                    }
+                    break;
+                case 3 :
+                    // dd/grammar/ECAToken.g:119:4: 'neq'
+                    {
+                    match("neq"); 
+
+
+                    }
+                    break;
+
+            }
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end NEQ
+
+    // $ANTLR start GT
+    public final void mGT() throws RecognitionException {
+        try {
+            int _type = GT;
+            // dd/grammar/ECAToken.g:122:4: ( '>' | 'GT' | 'gt' )
+            int alt13=3;
+            switch ( input.LA(1) ) {
+            case '>':
+                {
+                alt13=1;
+                }
+                break;
+            case 'G':
+                {
+                alt13=2;
+                }
+                break;
+            case 'g':
+                {
+                alt13=3;
+                }
+                break;
+            default:
+                NoViableAltException nvae =
+                    new NoViableAltException("122:1: GT : ( '>' | 'GT' | 'gt' );", 13, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt13) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:122:6: '>'
+                    {
+                    match('>'); 
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:123:4: 'GT'
+                    {
+                    match("GT"); 
+
+
+                    }
+                    break;
+                case 3 :
+                    // dd/grammar/ECAToken.g:124:4: 'gt'
+                    {
+                    match("gt"); 
+
+
+                    }
+                    break;
+
+            }
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end GT
+
+    // $ANTLR start LT
+    public final void mLT() throws RecognitionException {
+        try {
+            int _type = LT;
+            // dd/grammar/ECAToken.g:127:4: ( '<' | 'LT' | 'lt' )
+            int alt14=3;
+            switch ( input.LA(1) ) {
+            case '<':
+                {
+                alt14=1;
+                }
+                break;
+            case 'L':
+                {
+                alt14=2;
+                }
+                break;
+            case 'l':
+                {
+                alt14=3;
+                }
+                break;
+            default:
+                NoViableAltException nvae =
+                    new NoViableAltException("127:1: LT : ( '<' | 'LT' | 'lt' );", 14, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt14) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:127:6: '<'
+                    {
+                    match('<'); 
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:128:4: 'LT'
+                    {
+                    match("LT"); 
+
+
+                    }
+                    break;
+                case 3 :
+                    // dd/grammar/ECAToken.g:129:4: 'lt'
+                    {
+                    match("lt"); 
+
+
+                    }
+                    break;
+
+            }
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end LT
+
+    // $ANTLR start GEQ
+    public final void mGEQ() throws RecognitionException {
+        try {
+            int _type = GEQ;
+            // dd/grammar/ECAToken.g:132:5: ( '>=' | 'GEQ' | 'geq' )
+            int alt15=3;
+            switch ( input.LA(1) ) {
+            case '>':
+                {
+                alt15=1;
+                }
+                break;
+            case 'G':
+                {
+                alt15=2;
+                }
+                break;
+            case 'g':
+                {
+                alt15=3;
+                }
+                break;
+            default:
+                NoViableAltException nvae =
+                    new NoViableAltException("132:1: GEQ : ( '>=' | 'GEQ' | 'geq' );", 15, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt15) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:132:7: '>='
+                    {
+                    match(">="); 
+
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:133:4: 'GEQ'
+                    {
+                    match("GEQ"); 
+
+
+                    }
+                    break;
+                case 3 :
+                    // dd/grammar/ECAToken.g:134:4: 'geq'
+                    {
+                    match("geq"); 
+
+
+                    }
+                    break;
+
+            }
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end GEQ
+
+    // $ANTLR start LEQ
+    public final void mLEQ() throws RecognitionException {
+        try {
+            int _type = LEQ;
+            // dd/grammar/ECAToken.g:137:5: ( '<=' | 'LEQ' | 'leq' )
+            int alt16=3;
+            switch ( input.LA(1) ) {
+            case '<':
+                {
+                alt16=1;
+                }
+                break;
+            case 'L':
+                {
+                alt16=2;
+                }
+                break;
+            case 'l':
+                {
+                alt16=3;
+                }
+                break;
+            default:
+                NoViableAltException nvae =
+                    new NoViableAltException("137:1: LEQ : ( '<=' | 'LEQ' | 'leq' );", 16, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt16) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:137:7: '<='
+                    {
+                    match("<="); 
+
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:138:4: 'LEQ'
+                    {
+                    match("LEQ"); 
+
+
+                    }
+                    break;
+                case 3 :
+                    // dd/grammar/ECAToken.g:139:4: 'leq'
+                    {
+                    match("leq"); 
+
+
+                    }
+                    break;
+
+            }
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end LEQ
+
+    // $ANTLR start BOR
+    public final void mBOR() throws RecognitionException {
+        try {
+            int _type = BOR;
+            // dd/grammar/ECAToken.g:144:5: ( '|' )
+            // dd/grammar/ECAToken.g:144:7: '|'
+            {
+            match('|'); 
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end BOR
+
+    // $ANTLR start BAND
+    public final void mBAND() throws RecognitionException {
+        try {
+            int _type = BAND;
+            // dd/grammar/ECAToken.g:147:6: ( '&' )
+            // dd/grammar/ECAToken.g:147:8: '&'
+            {
+            match('&'); 
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end BAND
+
+    // $ANTLR start BXOR
+    public final void mBXOR() throws RecognitionException {
+        try {
+            int _type = BXOR;
+            // dd/grammar/ECAToken.g:150:6: ( '^' )
+            // dd/grammar/ECAToken.g:150:8: '^'
+            {
+            match('^'); 
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end BXOR
+
+    // $ANTLR start TWIDDLE
+    public final void mTWIDDLE() throws RecognitionException {
+        try {
+            int _type = TWIDDLE;
+            // dd/grammar/ECAToken.g:153:9: ( '~' )
+            // dd/grammar/ECAToken.g:153:11: '~'
+            {
+            match('~'); 
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end TWIDDLE
+
+    // $ANTLR start MUL
+    public final void mMUL() throws RecognitionException {
+        try {
+            int _type = MUL;
+            // dd/grammar/ECAToken.g:158:5: ( '*' | 'TIMES' | 'times' )
+            int alt17=3;
+            switch ( input.LA(1) ) {
+            case '*':
+                {
+                alt17=1;
+                }
+                break;
+            case 'T':
+                {
+                alt17=2;
+                }
+                break;
+            case 't':
+                {
+                alt17=3;
+                }
+                break;
+            default:
+                NoViableAltException nvae =
+                    new NoViableAltException("158:1: MUL : ( '*' | 'TIMES' | 'times' );", 17, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt17) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:158:7: '*'
+                    {
+                    match('*'); 
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:159:4: 'TIMES'
+                    {
+                    match("TIMES"); 
+
+
+                    }
+                    break;
+                case 3 :
+                    // dd/grammar/ECAToken.g:160:4: 'times'
+                    {
+                    match("times"); 
+
+
+                    }
+                    break;
+
+            }
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end MUL
+
+    // $ANTLR start DIV
+    public final void mDIV() throws RecognitionException {
+        try {
+            int _type = DIV;
+            // dd/grammar/ECAToken.g:163:5: ( '/' | 'DIVIDE' | 'divide' )
+            int alt18=3;
+            switch ( input.LA(1) ) {
+            case '/':
+                {
+                alt18=1;
+                }
+                break;
+            case 'D':
+                {
+                alt18=2;
+                }
+                break;
+            case 'd':
+                {
+                alt18=3;
+                }
+                break;
+            default:
+                NoViableAltException nvae =
+                    new NoViableAltException("163:1: DIV : ( '/' | 'DIVIDE' | 'divide' );", 18, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt18) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:163:7: '/'
+                    {
+                    match('/'); 
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:164:4: 'DIVIDE'
+                    {
+                    match("DIVIDE"); 
+
+
+                    }
+                    break;
+                case 3 :
+                    // dd/grammar/ECAToken.g:165:4: 'divide'
+                    {
+                    match("divide"); 
+
+
+                    }
+                    break;
+
+            }
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end DIV
+
+    // $ANTLR start PLUS
+    public final void mPLUS() throws RecognitionException {
+        try {
+            int _type = PLUS;
+            // dd/grammar/ECAToken.g:168:6: ( '+' | 'PLUS' | 'plus' )
+            int alt19=3;
+            switch ( input.LA(1) ) {
+            case '+':
+                {
+                alt19=1;
+                }
+                break;
+            case 'P':
+                {
+                alt19=2;
+                }
+                break;
+            case 'p':
+                {
+                alt19=3;
+                }
+                break;
+            default:
+                NoViableAltException nvae =
+                    new NoViableAltException("168:1: PLUS : ( '+' | 'PLUS' | 'plus' );", 19, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt19) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:168:8: '+'
+                    {
+                    match('+'); 
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:169:4: 'PLUS'
+                    {
+                    match("PLUS"); 
+
+
+                    }
+                    break;
+                case 3 :
+                    // dd/grammar/ECAToken.g:170:4: 'plus'
+                    {
+                    match("plus"); 
+
+
+                    }
+                    break;
+
+            }
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end PLUS
+
+    // $ANTLR start MINUS
+    public final void mMINUS() throws RecognitionException {
+        try {
+            int _type = MINUS;
+            // dd/grammar/ECAToken.g:173:7: ( '-' | 'MINUS' | 'minus' )
+            int alt20=3;
+            switch ( input.LA(1) ) {
+            case '-':
+                {
+                alt20=1;
+                }
+                break;
+            case 'M':
+                {
+                alt20=2;
+                }
+                break;
+            case 'm':
+                {
+                alt20=3;
+                }
+                break;
+            default:
+                NoViableAltException nvae =
+                    new NoViableAltException("173:1: MINUS : ( '-' | 'MINUS' | 'minus' );", 20, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt20) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:173:9: '-'
+                    {
+                    match('-'); 
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:174:4: 'MINUS'
+                    {
+                    match("MINUS"); 
+
+
+                    }
+                    break;
+                case 3 :
+                    // dd/grammar/ECAToken.g:175:4: 'minus'
+                    {
+                    match("minus"); 
+
+
+                    }
+                    break;
+
+            }
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end MINUS
+
+    // $ANTLR start MOD
+    public final void mMOD() throws RecognitionException {
+        try {
+            int _type = MOD;
+            // dd/grammar/ECAToken.g:178:5: ( '%' | 'MOD' | 'mod' )
+            int alt21=3;
+            switch ( input.LA(1) ) {
+            case '%':
+                {
+                alt21=1;
+                }
+                break;
+            case 'M':
+                {
+                alt21=2;
+                }
+                break;
+            case 'm':
+                {
+                alt21=3;
+                }
+                break;
+            default:
+                NoViableAltException nvae =
+                    new NoViableAltException("178:1: MOD : ( '%' | 'MOD' | 'mod' );", 21, 0, input);
+
+                throw nvae;
+            }
+
+            switch (alt21) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:178:7: '%'
+                    {
+                    match('%'); 
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:179:4: 'MOD'
+                    {
+                    match("MOD"); 
+
+
+                    }
+                    break;
+                case 3 :
+                    // dd/grammar/ECAToken.g:180:4: 'mod'
+                    {
+                    match("mod"); 
+
+
+                    }
+                    break;
+
+            }
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end MOD
+
+    // $ANTLR start TERN_IF
+    public final void mTERN_IF() throws RecognitionException {
+        try {
+            int _type = TERN_IF;
+            // dd/grammar/ECAToken.g:185:9: ( '?' )
+            // dd/grammar/ECAToken.g:185:11: '?'
+            {
+            match('?'); 
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end TERN_IF
+
+    // $ANTLR start COLON
+    public final void mCOLON() throws RecognitionException {
+        try {
+            int _type = COLON;
+            // dd/grammar/ECAToken.g:188:7: ( ':' )
+            // dd/grammar/ECAToken.g:188:9: ':'
+            {
+            match(':'); 
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end COLON
+
+    // $ANTLR start LETTER
+    public final void mLETTER() throws RecognitionException {
+        try {
+            // dd/grammar/ECAToken.g:194:8: ( 'a' .. 'z' | 'A' .. 'Z' )
+            // dd/grammar/ECAToken.g:
+            {
+            if ( (input.LA(1)>='A' && input.LA(1)<='Z')||(input.LA(1)>='a' && input.LA(1)<='z') ) {
+                input.consume();
+
+            }
+            else {
+                MismatchedSetException mse =
+                    new MismatchedSetException(null,input);
+                recover(mse);    throw mse;
+            }
+
+
+            }
+
+        }
+        finally {
+        }
+    }
+    // $ANTLR end LETTER
+
+    // $ANTLR start UNDERSCORE
+    public final void mUNDERSCORE() throws RecognitionException {
+        try {
+            // dd/grammar/ECAToken.g:198:12: ( '_' )
+            // dd/grammar/ECAToken.g:198:14: '_'
+            {
+            match('_'); 
+
+            }
+
+        }
+        finally {
+        }
+    }
+    // $ANTLR end UNDERSCORE
+
+    // $ANTLR start QUOTE
+    public final void mQUOTE() throws RecognitionException {
+        try {
+            int _type = QUOTE;
+            // dd/grammar/ECAToken.g:201:7: ( '\\'' )
+            // dd/grammar/ECAToken.g:201:9: '\\''
+            {
+            match('\''); 
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end QUOTE
+
+    // $ANTLR start DQUOTE
+    public final void mDQUOTE() throws RecognitionException {
+        try {
+            int _type = DQUOTE;
+            // dd/grammar/ECAToken.g:204:8: ( '\"' )
+            // dd/grammar/ECAToken.g:204:10: '\"'
+            {
+            match('\"'); 
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end DQUOTE
+
+    // $ANTLR start SPACE
+    public final void mSPACE() throws RecognitionException {
+        try {
+            // dd/grammar/ECAToken.g:208:7: ( ' ' | '\\t' | '\\r' )
+            // dd/grammar/ECAToken.g:
+            {
+            if ( input.LA(1)=='\t'||input.LA(1)=='\r'||input.LA(1)==' ' ) {
+                input.consume();
+
+            }
+            else {
+                MismatchedSetException mse =
+                    new MismatchedSetException(null,input);
+                recover(mse);    throw mse;
+            }
+
+
+            }
+
+        }
+        finally {
+        }
+    }
+    // $ANTLR end SPACE
+
+    // $ANTLR start NEWLINE
+    public final void mNEWLINE() throws RecognitionException {
+        try {
+            // dd/grammar/ECAToken.g:212:9: ( '\\n' )
+            // dd/grammar/ECAToken.g:212:11: '\\n'
+            {
+            match('\n'); 
+
+            }
+
+        }
+        finally {
+        }
+    }
+    // $ANTLR end NEWLINE
+
+    // $ANTLR start PUNCT
+    public final void mPUNCT() throws RecognitionException {
+        try {
+            // dd/grammar/ECAToken.g:216:7: ( '!' | '$' | '%' | '^' | '&' | '*' | '(' | ')' | '-' | '+' | '=' | '{' | '}' | '[' | ']' | ':' | ';' | '@' | '~' | '#' | '|' | '\\\\' | '`' | ',' | '<' | '.' | '>' | '/' | '?' )
+            // dd/grammar/ECAToken.g:
+            {
+            if ( input.LA(1)=='!'||(input.LA(1)>='#' && input.LA(1)<='&')||(input.LA(1)>='(' && input.LA(1)<='/')||(input.LA(1)>=':' && input.LA(1)<='@')||(input.LA(1)>='[' && input.LA(1)<='^')||input.LA(1)=='`'||(input.LA(1)>='{' && input.LA(1)<='~') ) {
+                input.consume();
+
+            }
+            else {
+                MismatchedSetException mse =
+                    new MismatchedSetException(null,input);
+                recover(mse);    throw mse;
+            }
+
+
+            }
+
+        }
+        finally {
+        }
+    }
+    // $ANTLR end PUNCT
+
+    // $ANTLR start STRING
+    public final void mSTRING() throws RecognitionException {
+        try {
+            int _type = STRING;
+            // dd/grammar/ECAToken.g:219:8: ( DQUOTE ( SPACE | PUNCT | LETTER | UNDERSCORE | DIGIT | QUOTE )* DQUOTE )
+            // dd/grammar/ECAToken.g:219:10: DQUOTE ( SPACE | PUNCT | LETTER | UNDERSCORE | DIGIT | QUOTE )* DQUOTE
+            {
+            mDQUOTE(); 
+            // dd/grammar/ECAToken.g:219:17: ( SPACE | PUNCT | LETTER | UNDERSCORE | DIGIT | QUOTE )*
+            loop22:
+            do {
+                int alt22=2;
+                int LA22_0 = input.LA(1);
+
+                if ( (LA22_0=='\t'||LA22_0=='\r'||(LA22_0>=' ' && LA22_0<='!')||(LA22_0>='#' && LA22_0<='~')) ) {
+                    alt22=1;
+                }
+
+
+                switch (alt22) {
+            	case 1 :
+            	    // dd/grammar/ECAToken.g:
+            	    {
+            	    if ( input.LA(1)=='\t'||input.LA(1)=='\r'||(input.LA(1)>=' ' && input.LA(1)<='!')||(input.LA(1)>='#' && input.LA(1)<='~') ) {
+            	        input.consume();
+
+            	    }
+            	    else {
+            	        MismatchedSetException mse =
+            	            new MismatchedSetException(null,input);
+            	        recover(mse);    throw mse;
+            	    }
+
+
+            	    }
+            	    break;
+
+            	default :
+            	    break loop22;
+                }
+            } while (true);
+
+            mDQUOTE(); 
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end STRING
+
+    // $ANTLR start BARESYM
+    public final void mBARESYM() throws RecognitionException {
+        try {
+            // dd/grammar/ECAToken.g:223:9: ( ( LETTER | UNDERSCORE ) ( LETTER | DIGIT | UNDERSCORE )* )
+            // dd/grammar/ECAToken.g:223:11: ( LETTER | UNDERSCORE ) ( LETTER | DIGIT | UNDERSCORE )*
+            {
+            if ( (input.LA(1)>='A' && input.LA(1)<='Z')||input.LA(1)=='_'||(input.LA(1)>='a' && input.LA(1)<='z') ) {
+                input.consume();
+
+            }
+            else {
+                MismatchedSetException mse =
+                    new MismatchedSetException(null,input);
+                recover(mse);    throw mse;
+            }
+
+            // dd/grammar/ECAToken.g:223:33: ( LETTER | DIGIT | UNDERSCORE )*
+            loop23:
+            do {
+                int alt23=2;
+                int LA23_0 = input.LA(1);
+
+                if ( ((LA23_0>='0' && LA23_0<='9')||(LA23_0>='A' && LA23_0<='Z')||LA23_0=='_'||(LA23_0>='a' && LA23_0<='z')) ) {
+                    alt23=1;
+                }
+
+
+                switch (alt23) {
+            	case 1 :
+            	    // dd/grammar/ECAToken.g:
+            	    {
+            	    if ( (input.LA(1)>='0' && input.LA(1)<='9')||(input.LA(1)>='A' && input.LA(1)<='Z')||input.LA(1)=='_'||(input.LA(1)>='a' && input.LA(1)<='z') ) {
+            	        input.consume();
+
+            	    }
+            	    else {
+            	        MismatchedSetException mse =
+            	            new MismatchedSetException(null,input);
+            	        recover(mse);    throw mse;
+            	    }
+
+
+            	    }
+            	    break;
+
+            	default :
+            	    break loop23;
+                }
+            } while (true);
+
+
+            }
+
+        }
+        finally {
+        }
+    }
+    // $ANTLR end BARESYM
+
+    // $ANTLR start QUOTSYM
+    public final void mQUOTSYM() throws RecognitionException {
+        try {
+            // dd/grammar/ECAToken.g:226:9: ( QUOTE ( PUNCT | LETTER | UNDERSCORE | DIGIT | DQUOTE )* QUOTE )
+            // dd/grammar/ECAToken.g:226:11: QUOTE ( PUNCT | LETTER | UNDERSCORE | DIGIT | DQUOTE )* QUOTE
+            {
+            mQUOTE(); 
+            // dd/grammar/ECAToken.g:226:17: ( PUNCT | LETTER | UNDERSCORE | DIGIT | DQUOTE )*
+            loop24:
+            do {
+                int alt24=2;
+                int LA24_0 = input.LA(1);
+
+                if ( ((LA24_0>='!' && LA24_0<='&')||(LA24_0>='(' && LA24_0<='~')) ) {
+                    alt24=1;
+                }
+
+
+                switch (alt24) {
+            	case 1 :
+            	    // dd/grammar/ECAToken.g:
+            	    {
+            	    if ( (input.LA(1)>='!' && input.LA(1)<='&')||(input.LA(1)>='(' && input.LA(1)<='~') ) {
+            	        input.consume();
+
+            	    }
+            	    else {
+            	        MismatchedSetException mse =
+            	            new MismatchedSetException(null,input);
+            	        recover(mse);    throw mse;
+            	    }
+
+
+            	    }
+            	    break;
+
+            	default :
+            	    break loop24;
+                }
+            } while (true);
+
+            mQUOTE(); 
+
+            }
+
+        }
+        finally {
+        }
+    }
+    // $ANTLR end QUOTSYM
+
+    // $ANTLR start DOTSYM
+    public final void mDOTSYM() throws RecognitionException {
+        try {
+            // dd/grammar/ECAToken.g:231:8: ( BARESYM DOT DOTSYM | BARESYM )
+            int alt25=2;
+            alt25 = dfa25.predict(input);
+            switch (alt25) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:231:10: BARESYM DOT DOTSYM
+                    {
+                    mBARESYM(); 
+                    mDOT(); 
+                    mDOTSYM(); 
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:232:4: BARESYM
+                    {
+                    mBARESYM(); 
+
+                    }
+                    break;
+
+            }
+        }
+        finally {
+        }
+    }
+    // $ANTLR end DOTSYM
+
+    // $ANTLR start SYMBOL
+    public final void mSYMBOL() throws RecognitionException {
+        try {
+            int _type = SYMBOL;
+            // dd/grammar/ECAToken.g:235:8: ( DOTSYM | QUOTSYM )
+            int alt26=2;
+            int LA26_0 = input.LA(1);
+
+            if ( ((LA26_0>='A' && LA26_0<='Z')||LA26_0=='_'||(LA26_0>='a' && LA26_0<='z')) ) {
+                alt26=1;
+            }
+            else if ( (LA26_0=='\'') ) {
+                alt26=2;
+            }
+            else {
+                NoViableAltException nvae =
+                    new NoViableAltException("235:1: SYMBOL : ( DOTSYM | QUOTSYM );", 26, 0, input);
+
+                throw nvae;
+            }
+            switch (alt26) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:235:10: DOTSYM
+                    {
+                    mDOTSYM(); 
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:236:4: QUOTSYM
+                    {
+                    mQUOTSYM(); 
+
+                    }
+                    break;
+
+            }
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end SYMBOL
+
+    // $ANTLR start DOLLAR
+    public final void mDOLLAR() throws RecognitionException {
+        try {
+            // dd/grammar/ECAToken.g:241:8: ( '$' )
+            // dd/grammar/ECAToken.g:241:10: '$'
+            {
+            match('$'); 
+
+            }
+
+        }
+        finally {
+        }
+    }
+    // $ANTLR end DOLLAR
+
+    // $ANTLR start DOLLARSYM
+    public final void mDOLLARSYM() throws RecognitionException {
+        try {
+            int _type = DOLLARSYM;
+            // dd/grammar/ECAToken.g:246:11: ( DOLLAR ( BAREINT | BARESYM ) )
+            // dd/grammar/ECAToken.g:246:13: DOLLAR ( BAREINT | BARESYM )
+            {
+            mDOLLAR(); 
+            // dd/grammar/ECAToken.g:246:20: ( BAREINT | BARESYM )
+            int alt27=2;
+            int LA27_0 = input.LA(1);
+
+            if ( ((LA27_0>='0' && LA27_0<='9')) ) {
+                alt27=1;
+            }
+            else if ( ((LA27_0>='A' && LA27_0<='Z')||LA27_0=='_'||(LA27_0>='a' && LA27_0<='z')) ) {
+                alt27=2;
+            }
+            else {
+                NoViableAltException nvae =
+                    new NoViableAltException("246:20: ( BAREINT | BARESYM )", 27, 0, input);
+
+                throw nvae;
+            }
+            switch (alt27) {
+                case 1 :
+                    // dd/grammar/ECAToken.g:246:21: BAREINT
+                    {
+                    mBAREINT(); 
+
+                    }
+                    break;
+                case 2 :
+                    // dd/grammar/ECAToken.g:246:31: BARESYM
+                    {
+                    mBARESYM(); 
+
+                    }
+                    break;
+
+            }
+
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end DOLLARSYM
+
+    // $ANTLR start WS
+    public final void mWS() throws RecognitionException {
+        try {
+            int _type = WS;
+            // dd/grammar/ECAToken.g:252:4: ( ( SPACE | NEWLINE ) )
+            // dd/grammar/ECAToken.g:252:6: ( SPACE | NEWLINE )
+            {
+            if ( (input.LA(1)>='\t' && input.LA(1)<='\n')||input.LA(1)=='\r'||input.LA(1)==' ' ) {
+                input.consume();
+
+            }
+            else {
+                MismatchedSetException mse =
+                    new MismatchedSetException(null,input);
+                recover(mse);    throw mse;
+            }
+
+             skip(); 
+
+            }
+
+            this.type = _type;
+        }
+        finally {
+        }
+    }
+    // $ANTLR end WS
+
+    public void mTokens() throws RecognitionException {
+        // dd/grammar/ECAToken.g:1:8: ( NUMBER | WHEN | IF | DO | LPAREN | RPAREN | LSQUARE | RSQUARE | LBRACE | RBRACE | SEPR | DOT | ASSIGN | OR | AND | NOT | EQ | NEQ | GT | LT | GEQ | LEQ | BOR | BAND | BXOR | TWIDDLE | MUL | DIV | PLUS | MINUS | MOD | TERN_IF | COLON | QUOTE | DQUOTE | STRING | SYMBOL | DOLLARSYM | WS )
+        int alt28=39;
+        switch ( input.LA(1) ) {
+        case '+':
+            {
+            int LA28_1 = input.LA(2);
+
+            if ( ((LA28_1>='0' && LA28_1<='9')) ) {
+                alt28=1;
+            }
+            else {
+                alt28=29;}
+            }
+            break;
+        case '0':
+        case '1':
+        case '2':
+        case '3':
+        case '4':
+        case '5':
+        case '6':
+        case '7':
+        case '8':
+        case '9':
+            {
+            alt28=1;
+            }
+            break;
+        case 'W':
+            {
+            int LA28_3 = input.LA(2);
+
+            if ( (LA28_3=='H') ) {
+                int LA28_53 = input.LA(3);
+
+                if ( (LA28_53=='E') ) {
+                    int LA28_100 = input.LA(4);
+
+                    if ( (LA28_100=='N') ) {
+                        int LA28_123 = input.LA(5);
+
+                        if ( (LA28_123=='.'||(LA28_123>='0' && LA28_123<='9')||(LA28_123>='A' && LA28_123<='Z')||LA28_123=='_'||(LA28_123>='a' && LA28_123<='z')) ) {
+                            alt28=37;
+                        }
+                        else {
+                            alt28=2;}
+                    }
+                    else {
+                        alt28=37;}
+                }
+                else {
+                    alt28=37;}
+            }
+            else {
+                alt28=37;}
+            }
+            break;
+        case 'I':
+            {
+            int LA28_4 = input.LA(2);
+
+            if ( (LA28_4=='F') ) {
+                int LA28_54 = input.LA(3);
+
+                if ( (LA28_54=='.'||(LA28_54>='0' && LA28_54<='9')||(LA28_54>='A' && LA28_54<='Z')||LA28_54=='_'||(LA28_54>='a' && LA28_54<='z')) ) {
+                    alt28=37;
+                }
+                else {
+                    alt28=3;}
+            }
+            else {
+                alt28=37;}
+            }
+            break;
+        case 'D':
+            {
+            switch ( input.LA(2) ) {
+            case 'O':
+                {
+                int LA28_55 = input.LA(3);
+
+                if ( (LA28_55=='.'||(LA28_55>='0' && LA28_55<='9')||(LA28_55>='A' && LA28_55<='Z')||LA28_55=='_'||(LA28_55>='a' && LA28_55<='z')) ) {
+                    alt28=37;
+                }
+                else {
+                    alt28=4;}
+                }
+                break;
+            case 'I':
+                {
+                int LA28_56 = input.LA(3);
+
+                if ( (LA28_56=='V') ) {
+                    int LA28_103 = input.LA(4);
+
+                    if ( (LA28_103=='I') ) {
+                        int LA28_124 = input.LA(5);
+
+                        if ( (LA28_124=='D') ) {
+                            int LA28_133 = input.LA(6);
+
+                            if ( (LA28_133=='E') ) {
+                                int LA28_139 = input.LA(7);
+
+                                if ( (LA28_139=='.'||(LA28_139>='0' && LA28_139<='9')||(LA28_139>='A' && LA28_139<='Z')||LA28_139=='_'||(LA28_139>='a' && LA28_139<='z')) ) {
+                                    alt28=37;
+                                }
+                                else {
+                                    alt28=28;}
+                            }
+                            else {
+                                alt28=37;}
+                        }
+                        else {
+                            alt28=37;}
+                    }
+                    else {
+                        alt28=37;}
+                }
+                else {
+                    alt28=37;}
+                }
+                break;
+            default:
+                alt28=37;}
+
+            }
+            break;
+        case '(':
+            {
+            alt28=5;
+            }
+            break;
+        case ')':
+            {
+            alt28=6;
+            }
+            break;
+        case '[':
+            {
+            alt28=7;
+            }
+            break;
+        case ']':
+            {
+            alt28=8;
+            }
+            break;
+        case '{':
+            {
+            alt28=9;
+            }
+            break;
+        case '}':
+            {
+            alt28=10;
+            }
+            break;
+        case ',':
+        case ';':
+            {
+            alt28=11;
+            }
+            break;
+        case '.':
+            {
+            alt28=12;
+            }
+            break;
+        case '=':
+            {
+            int LA28_14 = input.LA(2);
+
+            if ( (LA28_14=='=') ) {
+                alt28=17;
+            }
+            else {
+                alt28=13;}
+            }
+            break;
+        case '<':
+            {
+            switch ( input.LA(2) ) {
+            case '=':
+                {
+                alt28=22;
+                }
+                break;
+            case '-':
+                {
+                alt28=13;
+                }
+                break;
+            default:
+                alt28=20;}
+
+            }
+            break;
+        case '|':
+            {
+            int LA28_16 = input.LA(2);
+
+            if ( (LA28_16=='|') ) {
+                alt28=14;
+            }
+            else {
+                alt28=23;}
+            }
+            break;
+        case 'O':
+            {
+            int LA28_17 = input.LA(2);
+
+            if ( (LA28_17=='R') ) {
+                int LA28_63 = input.LA(3);
+
+                if ( (LA28_63=='.'||(LA28_63>='0' && LA28_63<='9')||(LA28_63>='A' && LA28_63<='Z')||LA28_63=='_'||(LA28_63>='a' && LA28_63<='z')) ) {
+                    alt28=37;
+                }
+                else {
+                    alt28=14;}
+            }
+            else {
+                alt28=37;}
+            }
+            break;
+        case 'o':
+            {
+            int LA28_18 = input.LA(2);
+
+            if ( (LA28_18=='r') ) {
+                int LA28_64 = input.LA(3);
+
+                if ( (LA28_64=='.'||(LA28_64>='0' && LA28_64<='9')||(LA28_64>='A' && LA28_64<='Z')||LA28_64=='_'||(LA28_64>='a' && LA28_64<='z')) ) {
+                    alt28=37;
+                }
+                else {
+                    alt28=14;}
+            }
+            else {
+                alt28=37;}
+            }
+            break;
+        case '&':
+            {
+            int LA28_19 = input.LA(2);
+
+            if ( (LA28_19=='&') ) {
+                alt28=15;
+            }
+            else {
+                alt28=24;}
+            }
+            break;
+        case 'A':
+            {
+            int LA28_20 = input.LA(2);
+
+            if ( (LA28_20=='N') ) {
+                int LA28_67 = input.LA(3);
+
+                if ( (LA28_67=='D') ) {
+                    int LA28_104 = input.LA(4);
+
+                    if ( (LA28_104=='.'||(LA28_104>='0' && LA28_104<='9')||(LA28_104>='A' && LA28_104<='Z')||LA28_104=='_'||(LA28_104>='a' && LA28_104<='z')) ) {
+                        alt28=37;
+                    }
+                    else {
+                        alt28=15;}
+                }
+                else {
+                    alt28=37;}
+            }
+            else {
+                alt28=37;}
+            }
+            break;
+        case 'a':
+            {
+            int LA28_21 = input.LA(2);
+
+            if ( (LA28_21=='n') ) {
+                int LA28_68 = input.LA(3);
+
+                if ( (LA28_68=='d') ) {
+                    int LA28_105 = input.LA(4);
+
+                    if ( (LA28_105=='.'||(LA28_105>='0' && LA28_105<='9')||(LA28_105>='A' && LA28_105<='Z')||LA28_105=='_'||(LA28_105>='a' && LA28_105<='z')) ) {
+                        alt28=37;
+                    }
+                    else {
+                        alt28=15;}
+                }
+                else {
+                    alt28=37;}
+            }
+            else {
+                alt28=37;}
+            }
+            break;
+        case '!':
+            {
+            int LA28_22 = input.LA(2);
+
+            if ( (LA28_22=='=') ) {
+                alt28=18;
+            }
+            else {
+                alt28=16;}
+            }
+            break;
+        case 'N':
+            {
+            switch ( input.LA(2) ) {
+            case 'E':
+                {
+                int LA28_71 = input.LA(3);
+
+                if ( (LA28_71=='Q') ) {
+                    int LA28_106 = input.LA(4);
+
+                    if ( (LA28_106=='.'||(LA28_106>='0' && LA28_106<='9')||(LA28_106>='A' && LA28_106<='Z')||LA28_106=='_'||(LA28_106>='a' && LA28_106<='z')) ) {
+                        alt28=37;
+                    }
+                    else {
+                        alt28=18;}
+                }
+                else {
+                    alt28=37;}
+                }
+                break;
+            case 'O':
+                {
+                int LA28_72 = input.LA(3);
+
+                if ( (LA28_72=='T') ) {
+                    int LA28_107 = input.LA(4);
+
+                    if ( (LA28_107=='.'||(LA28_107>='0' && LA28_107<='9')||(LA28_107>='A' && LA28_107<='Z')||LA28_107=='_'||(LA28_107>='a' && LA28_107<='z')) ) {
+                        alt28=37;
+                    }
+                    else {
+                        alt28=16;}
+                }
+                else {
+                    alt28=37;}
+                }
+                break;
+            default:
+                alt28=37;}
+
+            }
+            break;
+        case 'n':
+            {
+            switch ( input.LA(2) ) {
+            case 'e':
+                {
+                int LA28_73 = input.LA(3);
+
+                if ( (LA28_73=='q') ) {
+                    int LA28_108 = input.LA(4);
+
+                    if ( (LA28_108=='.'||(LA28_108>='0' && LA28_108<='9')||(LA28_108>='A' && LA28_108<='Z')||LA28_108=='_'||(LA28_108>='a' && LA28_108<='z')) ) {
+                        alt28=37;
+                    }
+                    else {
+                        alt28=18;}
+                }
+                else {
+                    alt28=37;}
+                }
+                break;
+            case 'o':
+                {
+                int LA28_74 = input.LA(3);
+
+                if ( (LA28_74=='t') ) {
+                    int LA28_109 = input.LA(4);
+
+                    if ( (LA28_109=='.'||(LA28_109>='0' && LA28_109<='9')||(LA28_109>='A' && LA28_109<='Z')||LA28_109=='_'||(LA28_109>='a' && LA28_109<='z')) ) {
+                        alt28=37;
+                    }
+                    else {
+                        alt28=16;}
+                }
+                else {
+                    alt28=37;}
+                }
+                break;
+            default:
+                alt28=37;}
+
+            }
+            break;
+        case 'E':
+            {
+            int LA28_25 = input.LA(2);
+
+            if ( (LA28_25=='Q') ) {
+                int LA28_75 = input.LA(3);
+
+                if ( (LA28_75=='.'||(LA28_75>='0' && LA28_75<='9')||(LA28_75>='A' && LA28_75<='Z')||LA28_75=='_'||(LA28_75>='a' && LA28_75<='z')) ) {
+                    alt28=37;
+                }
+                else {
+                    alt28=17;}
+            }
+            else {
+                alt28=37;}
+            }
+            break;
+        case 'e':
+            {
+            int LA28_26 = input.LA(2);
+
+            if ( (LA28_26=='q') ) {
+                int LA28_76 = input.LA(3);
+
+                if ( (LA28_76=='.'||(LA28_76>='0' && LA28_76<='9')||(LA28_76>='A' && LA28_76<='Z')||LA28_76=='_'||(LA28_76>='a' && LA28_76<='z')) ) {
+                    alt28=37;
+                }
+                else {
+                    alt28=17;}
+            }
+            else {
+                alt28=37;}
+            }
+            break;
+        case '>':
+            {
+            int LA28_27 = input.LA(2);
+
+            if ( (LA28_27=='=') ) {
+                alt28=21;
+            }
+            else {
+                alt28=19;}
+            }
+            break;
+        case 'G':
+            {
+            switch ( input.LA(2) ) {
+            case 'T':
+                {
+                int LA28_79 = input.LA(3);
+
+                if ( (LA28_79=='.'||(LA28_79>='0' && LA28_79<='9')||(LA28_79>='A' && LA28_79<='Z')||LA28_79=='_'||(LA28_79>='a' && LA28_79<='z')) ) {
+                    alt28=37;
+                }
+                else {
+                    alt28=19;}
+                }
+                break;
+            case 'E':
+                {
+                int LA28_80 = input.LA(3);
+
+                if ( (LA28_80=='Q') ) {
+                    int LA28_110 = input.LA(4);
+
+                    if ( (LA28_110=='.'||(LA28_110>='0' && LA28_110<='9')||(LA28_110>='A' && LA28_110<='Z')||LA28_110=='_'||(LA28_110>='a' && LA28_110<='z')) ) {
+                        alt28=37;
+                    }
+                    else {
+                        alt28=21;}
+                }
+                else {
+                    alt28=37;}
+                }
+                break;
+            default:
+                alt28=37;}
+
+            }
+            break;
+        case 'g':
+            {
+            switch ( input.LA(2) ) {
+            case 't':
+                {
+                int LA28_81 = input.LA(3);
+
+                if ( (LA28_81=='.'||(LA28_81>='0' && LA28_81<='9')||(LA28_81>='A' && LA28_81<='Z')||LA28_81=='_'||(LA28_81>='a' && LA28_81<='z')) ) {
+                    alt28=37;
+                }
+                else {
+                    alt28=19;}
+                }
+                break;
+            case 'e':
+                {
+                int LA28_82 = input.LA(3);
+
+                if ( (LA28_82=='q') ) {
+                    int LA28_111 = input.LA(4);
+
+                    if ( (LA28_111=='.'||(LA28_111>='0' && LA28_111<='9')||(LA28_111>='A' && LA28_111<='Z')||LA28_111=='_'||(LA28_111>='a' && LA28_111<='z')) ) {
+                        alt28=37;
+                    }
+                    else {
+                        alt28=21;}
+                }
+                else {
+                    alt28=37;}
+                }
+                break;
+            default:
+                alt28=37;}
+
+            }
+            break;
+        case 'L':
+            {
+            switch ( input.LA(2) ) {
+            case 'E':
+                {
+                int LA28_83 = input.LA(3);
+
+                if ( (LA28_83=='Q') ) {
+                    int LA28_112 = input.LA(4);
+
+                    if ( (LA28_112=='.'||(LA28_112>='0' && LA28_112<='9')||(LA28_112>='A' && LA28_112<='Z')||LA28_112=='_'||(LA28_112>='a' && LA28_112<='z')) ) {
+                        alt28=37;
+                    }
+                    else {
+                        alt28=22;}
+                }
+                else {
+                    alt28=37;}
+                }
+                break;
+            case 'T':
+                {
+                int LA28_84 = input.LA(3);
+
+                if ( (LA28_84=='.'||(LA28_84>='0' && LA28_84<='9')||(LA28_84>='A' && LA28_84<='Z')||LA28_84=='_'||(LA28_84>='a' && LA28_84<='z')) ) {
+                    alt28=37;
+                }
+                else {
+                    alt28=20;}
+                }
+                break;
+            default:
+                alt28=37;}
+
+            }
+            break;
+        case 'l':
+            {
+            switch ( input.LA(2) ) {
+            case 'e':
+                {
+                int LA28_85 = input.LA(3);
+
+                if ( (LA28_85=='q') ) {
+                    int LA28_113 = input.LA(4);
+
+                    if ( (LA28_113=='.'||(LA28_113>='0' && LA28_113<='9')||(LA28_113>='A' && LA28_113<='Z')||LA28_113=='_'||(LA28_113>='a' && LA28_113<='z')) ) {
+                        alt28=37;
+                    }
+                    else {
+                        alt28=22;}
+                }
+                else {
+                    alt28=37;}
+                }
+                break;
+            case 't':
+                {
+                int LA28_86 = input.LA(3);
+
+                if ( (LA28_86=='.'||(LA28_86>='0' && LA28_86<='9')||(LA28_86>='A' && LA28_86<='Z')||LA28_86=='_'||(LA28_86>='a' && LA28_86<='z')) ) {
+                    alt28=37;
+                }
+                else {
+                    alt28=20;}
+                }
+                break;
+            default:
+                alt28=37;}
+
+            }
+            break;
+        case '^':
+            {
+            alt28=25;
+            }
+            break;
+        case '~':
+            {
+            alt28=26;
+            }
+            break;
+        case '*':
+            {
+            alt28=27;
+            }
+            break;
+        case 'T':
+            {
+            int LA28_35 = input.LA(2);
+
+            if ( (LA28_35=='I') ) {
+                int LA28_87 = input.LA(3);
+
+                if ( (LA28_87=='M') ) {
+                    int LA28_114 = input.LA(4);
+
+                    if ( (LA28_114=='E') ) {
+                        int LA28_125 = input.LA(5);
+
+                        if ( (LA28_125=='S') ) {
+                            int LA28_134 = input.LA(6);
+
+                            if ( (LA28_134=='.'||(LA28_134>='0' && LA28_134<='9')||(LA28_134>='A' && LA28_134<='Z')||LA28_134=='_'||(LA28_134>='a' && LA28_134<='z')) ) {
+                                alt28=37;
+                            }
+                            else {
+                                alt28=27;}
+                        }
+                        else {
+                            alt28=37;}
+                    }
+                    else {
+                        alt28=37;}
+                }
+                else {
+                    alt28=37;}
+            }
+            else {
+                alt28=37;}
+            }
+            break;
+        case 't':
+            {
+            int LA28_36 = input.LA(2);
+
+            if ( (LA28_36=='i') ) {
+                int LA28_88 = input.LA(3);
+
+                if ( (LA28_88=='m') ) {
+                    int LA28_115 = input.LA(4);
+
+                    if ( (LA28_115=='e') ) {
+                        int LA28_126 = input.LA(5);
+
+                        if ( (LA28_126=='s') ) {
+                            int LA28_135 = input.LA(6);
+
+                            if ( (LA28_135=='.'||(LA28_135>='0' && LA28_135<='9')||(LA28_135>='A' && LA28_135<='Z')||LA28_135=='_'||(LA28_135>='a' && LA28_135<='z')) ) {
+                                alt28=37;
+                            }
+                            else {
+                                alt28=27;}
+                        }
+                        else {
+                            alt28=37;}
+                    }
+                    else {
+                        alt28=37;}
+                }
+                else {
+                    alt28=37;}
+            }
+            else {
+                alt28=37;}
+            }
+            break;
+        case '/':
+            {
+            alt28=28;
+            }
+            break;
+        case 'd':
+            {
+            int LA28_38 = input.LA(2);
+
+            if ( (LA28_38=='i') ) {
+                int LA28_89 = input.LA(3);
+
+                if ( (LA28_89=='v') ) {
+                    int LA28_116 = input.LA(4);
+
+                    if ( (LA28_116=='i') ) {
+                        int LA28_127 = input.LA(5);
+
+                        if ( (LA28_127=='d') ) {
+                            int LA28_136 = input.LA(6);
+
+                            if ( (LA28_136=='e') ) {
+                                int LA28_140 = input.LA(7);
+
+                                if ( (LA28_140=='.'||(LA28_140>='0' && LA28_140<='9')||(LA28_140>='A' && LA28_140<='Z')||LA28_140=='_'||(LA28_140>='a' && LA28_140<='z')) ) {
+                                    alt28=37;
+                                }
+                                else {
+                                    alt28=28;}
+                            }
+                            else {
+                                alt28=37;}
+                        }
+                        else {
+                            alt28=37;}
+                    }
+                    else {
+                        alt28=37;}
+                }
+                else {
+                    alt28=37;}
+            }
+            else {
+                alt28=37;}
+            }
+            break;
+        case '-':
+            {
+            int LA28_39 = input.LA(2);
+
+            if ( ((LA28_39>='0' && LA28_39<='9')) ) {
+                alt28=1;
+            }
+            else {
+                alt28=30;}
+            }
+            break;
+        case 'P':
+            {
+            int LA28_40 = input.LA(2);
+
+            if ( (LA28_40=='L') ) {
+                int LA28_91 = input.LA(3);
+
+                if ( (LA28_91=='U') ) {
+                    int LA28_117 = input.LA(4);
+
+                    if ( (LA28_117=='S') ) {
+                        int LA28_128 = input.LA(5);
+
+                        if ( (LA28_128=='.'||(LA28_128>='0' && LA28_128<='9')||(LA28_128>='A' && LA28_128<='Z')||LA28_128=='_'||(LA28_128>='a' && LA28_128<='z')) ) {
+                            alt28=37;
+                        }
+                        else {
+                            alt28=29;}
+                    }
+                    else {
+                        alt28=37;}
+                }
+                else {
+                    alt28=37;}
+            }
+            else {
+                alt28=37;}
+            }
+            break;
+        case 'p':
+            {
+            int LA28_41 = input.LA(2);
+
+            if ( (LA28_41=='l') ) {
+                int LA28_92 = input.LA(3);
+
+                if ( (LA28_92=='u') ) {
+                    int LA28_118 = input.LA(4);
+
+                    if ( (LA28_118=='s') ) {
+                        int LA28_129 = input.LA(5);
+
+                        if ( (LA28_129=='.'||(LA28_129>='0' && LA28_129<='9')||(LA28_129>='A' && LA28_129<='Z')||LA28_129=='_'||(LA28_129>='a' && LA28_129<='z')) ) {
+                            alt28=37;
+                        }
+                        else {
+                            alt28=29;}
+                    }
+                    else {
+                        alt28=37;}
+                }
+                else {
+                    alt28=37;}
+            }
+            else {
+                alt28=37;}
+            }
+            break;
+        case 'M':
+            {
+            switch ( input.LA(2) ) {
+            case 'O':
+                {
+                int LA28_93 = input.LA(3);
+
+                if ( (LA28_93=='D') ) {
+                    int LA28_119 = input.LA(4);
+
+                    if ( (LA28_119=='.'||(LA28_119>='0' && LA28_119<='9')||(LA28_119>='A' && LA28_119<='Z')||LA28_119=='_'||(LA28_119>='a' && LA28_119<='z')) ) {
+                        alt28=37;
+                    }
+                    else {
+                        alt28=31;}
+                }
+                else {
+                    alt28=37;}
+                }
+                break;
+            case 'I':
+                {
+                int LA28_94 = input.LA(3);
+
+                if ( (LA28_94=='N') ) {
+                    int LA28_120 = input.LA(4);
+
+                    if ( (LA28_120=='U') ) {
+                        int LA28_130 = input.LA(5);
+
+                        if ( (LA28_130=='S') ) {
+                            int LA28_137 = input.LA(6);
+
+                            if ( (LA28_137=='.'||(LA28_137>='0' && LA28_137<='9')||(LA28_137>='A' && LA28_137<='Z')||LA28_137=='_'||(LA28_137>='a' && LA28_137<='z')) ) {
+                                alt28=37;
+                            }
+                            else {
+                                alt28=30;}
+                        }
+                        else {
+                            alt28=37;}
+                    }
+                    else {
+                        alt28=37;}
+                }
+                else {
+                    alt28=37;}
+                }
+                break;
+            default:
+                alt28=37;}
+
+            }
+            break;
+        case 'm':
+            {
+            switch ( input.LA(2) ) {
+            case 'o':
+                {
+                int LA28_95 = input.LA(3);
+
+                if ( (LA28_95=='d') ) {
+                    int LA28_121 = input.LA(4);
+
+                    if ( (LA28_121=='.'||(LA28_121>='0' && LA28_121<='9')||(LA28_121>='A' && LA28_121<='Z')||LA28_121=='_'||(LA28_121>='a' && LA28_121<='z')) ) {
+                        alt28=37;
+                    }
+                    else {
+                        alt28=31;}
+                }
+                else {
+                    alt28=37;}
+                }
+                break;
+            case 'i':
+                {
+                int LA28_96 = input.LA(3);
+
+                if ( (LA28_96=='n') ) {
+                    int LA28_122 = input.LA(4);
+
+                    if ( (LA28_122=='u') ) {
+                        int LA28_131 = input.LA(5);
+
+                        if ( (LA28_131=='s') ) {
+                            int LA28_138 = input.LA(6);
+
+                            if ( (LA28_138=='.'||(LA28_138>='0' && LA28_138<='9')||(LA28_138>='A' && LA28_138<='Z')||LA28_138=='_'||(LA28_138>='a' && LA28_138<='z')) ) {
+                                alt28=37;
+                            }
+                            else {
+                                alt28=30;}
+                        }
+                        else {
+                            alt28=37;}
+                    }
+                    else {
+                        alt28=37;}
+                }
+                else {
+                    alt28=37;}
+                }
+                break;
+            default:
+                alt28=37;}
+
+            }
+            break;
+        case '%':
+            {
+            alt28=31;
+            }
+            break;
+        case '?':
+            {
+            alt28=32;
+            }
+            break;
+        case ':':
+            {
+            alt28=33;
+            }
+            break;
+        case '\'':
+            {
+            int LA28_47 = input.LA(2);
+
+            if ( ((LA28_47>='!' && LA28_47<='~')) ) {
+                alt28=37;
+            }
+            else {
+                alt28=34;}
+            }
+            break;
+        case '\"':
+            {
+            int LA28_48 = input.LA(2);
+
+            if ( (LA28_48=='\t'||LA28_48=='\r'||(LA28_48>=' ' && LA28_48<='~')) ) {
+                alt28=36;
+            }
+            else {
+                alt28=35;}
+            }
+            break;
+        case 'B':
+        case 'C':
+        case 'F':
+        case 'H':
+        case 'J':
+        case 'K':
+        case 'Q':
+        case 'R':
+        case 'S':
+        case 'U':
+        case 'V':
+        case 'X':
+        case 'Y':
+        case 'Z':
+        case '_':
+        case 'b':
+        case 'c':
+        case 'f':
+        case 'h':
+        case 'i':
+        case 'j':
+        case 'k':
+        case 'q':
+        case 'r':
+        case 's':
+        case 'u':
+        case 'v':
+        case 'w':
+        case 'x':
+        case 'y':
+        case 'z':
+            {
+            alt28=37;
+            }
+            break;
+        case '$':
+            {
+            alt28=38;
+            }
+            break;
+        case '\t':
+        case '\n':
+        case '\r':
+        case ' ':
+            {
+            alt28=39;
+            }
+            break;
+        default:
+            NoViableAltException nvae =
+                new NoViableAltException("1:1: Tokens : ( NUMBER | WHEN | IF | DO | LPAREN | RPAREN | LSQUARE | RSQUARE | LBRACE | RBRACE | SEPR | DOT | ASSIGN | OR | AND | NOT | EQ | NEQ | GT | LT | GEQ | LEQ | BOR | BAND | BXOR | TWIDDLE | MUL | DIV | PLUS | MINUS | MOD | TERN_IF | COLON | QUOTE | DQUOTE | STRING | SYMBOL | DOLLARSYM | WS );", 28, 0, input);
+
+            throw nvae;
+        }
+
+        switch (alt28) {
+            case 1 :
+                // dd/grammar/ECAToken.g:1:10: NUMBER
+                {
+                mNUMBER(); 
+
+                }
+                break;
+            case 2 :
+                // dd/grammar/ECAToken.g:1:17: WHEN
+                {
+                mWHEN(); 
+
+                }
+                break;
+            case 3 :
+                // dd/grammar/ECAToken.g:1:22: IF
+                {
+                mIF(); 
+
+                }
+                break;
+            case 4 :
+                // dd/grammar/ECAToken.g:1:25: DO
+                {
+                mDO(); 
+
+                }
+                break;
+            case 5 :
+                // dd/grammar/ECAToken.g:1:28: LPAREN
+                {
+                mLPAREN(); 
+
+                }
+                break;
+            case 6 :
+                // dd/grammar/ECAToken.g:1:35: RPAREN
+                {
+                mRPAREN(); 
+
+                }
+                break;
+            case 7 :
+                // dd/grammar/ECAToken.g:1:42: LSQUARE
+                {
+                mLSQUARE(); 
+
+                }
+                break;
+            case 8 :
+                // dd/grammar/ECAToken.g:1:50: RSQUARE
+                {
+                mRSQUARE(); 
+
+                }
+                break;
+            case 9 :
+                // dd/grammar/ECAToken.g:1:58: LBRACE
+                {
+                mLBRACE(); 
+
+                }
+                break;
+            case 10 :
+                // dd/grammar/ECAToken.g:1:65: RBRACE
+                {
+                mRBRACE(); 
+
+                }
+                break;
+            case 11 :
+                // dd/grammar/ECAToken.g:1:72: SEPR
+                {
+                mSEPR(); 
+
+                }
+                break;
+            case 12 :
+                // dd/grammar/ECAToken.g:1:77: DOT
+                {
+                mDOT(); 
+
+                }
+                break;
+            case 13 :
+                // dd/grammar/ECAToken.g:1:81: ASSIGN
+                {
+                mASSIGN(); 
+
+                }
+                break;
+            case 14 :
+                // dd/grammar/ECAToken.g:1:88: OR
+                {
+                mOR(); 
+
+                }
+                break;
+            case 15 :
+                // dd/grammar/ECAToken.g:1:91: AND
+                {
+                mAND(); 
+
+                }
+                break;
+            case 16 :
+                // dd/grammar/ECAToken.g:1:95: NOT
+                {
+                mNOT(); 
+
+                }
+                break;
+            case 17 :
+                // dd/grammar/ECAToken.g:1:99: EQ
+                {
+                mEQ(); 
+
+                }
+                break;
+            case 18 :
+                // dd/grammar/ECAToken.g:1:102: NEQ
+                {
+                mNEQ(); 
+
+                }
+                break;
+            case 19 :
+                // dd/grammar/ECAToken.g:1:106: GT
+                {
+                mGT(); 
+
+                }
+                break;
+            case 20 :
+                // dd/grammar/ECAToken.g:1:109: LT
+                {
+                mLT(); 
+
+                }
+                break;
+            case 21 :
+                // dd/grammar/ECAToken.g:1:112: GEQ
+                {
+                mGEQ(); 
+
+                }
+                break;
+            case 22 :
+                // dd/grammar/ECAToken.g:1:116: LEQ
+                {
+                mLEQ(); 
+
+                }
+                break;
+            case 23 :
+                // dd/grammar/ECAToken.g:1:120: BOR
+                {
+                mBOR(); 
+
+                }
+                break;
+            case 24 :
+                // dd/grammar/ECAToken.g:1:124: BAND
+                {
+                mBAND(); 
+
+                }
+                break;
+            case 25 :
+                // dd/grammar/ECAToken.g:1:129: BXOR
+                {
+                mBXOR(); 
+
+                }
+                break;
+            case 26 :
+                // dd/grammar/ECAToken.g:1:134: TWIDDLE
+                {
+                mTWIDDLE(); 
+
+                }
+                break;
+            case 27 :
+                // dd/grammar/ECAToken.g:1:142: MUL
+                {
+                mMUL(); 
+
+                }
+                break;
+            case 28 :
+                // dd/grammar/ECAToken.g:1:146: DIV
+                {
+                mDIV(); 
+
+                }
+                break;
+            case 29 :
+                // dd/grammar/ECAToken.g:1:150: PLUS
+                {
+                mPLUS(); 
+
+                }
+                break;
+            case 30 :
+                // dd/grammar/ECAToken.g:1:155: MINUS
+                {
+                mMINUS(); 
+
+                }
+                break;
+            case 31 :
+                // dd/grammar/ECAToken.g:1:161: MOD
+                {
+                mMOD(); 
+
+                }
+                break;
+            case 32 :
+                // dd/grammar/ECAToken.g:1:165: TERN_IF
+                {
+                mTERN_IF(); 
+
+                }
+                break;
+            case 33 :
+                // dd/grammar/ECAToken.g:1:173: COLON
+                {
+                mCOLON(); 
+
+                }
+                break;
+            case 34 :
+                // dd/grammar/ECAToken.g:1:179: QUOTE
+                {
+                mQUOTE(); 
+
+                }
+                break;
+            case 35 :
+                // dd/grammar/ECAToken.g:1:185: DQUOTE
+                {
+                mDQUOTE(); 
+
+                }
+                break;
+            case 36 :
+                // dd/grammar/ECAToken.g:1:192: STRING
+                {
+                mSTRING(); 
+
+                }
+                break;
+            case 37 :
+                // dd/grammar/ECAToken.g:1:199: SYMBOL
+                {
+                mSYMBOL(); 
+
+                }
+                break;
+            case 38 :
+                // dd/grammar/ECAToken.g:1:206: DOLLARSYM
+                {
+                mDOLLARSYM(); 
+
+                }
+                break;
+            case 39 :
+                // dd/grammar/ECAToken.g:1:216: WS
+                {
+                mWS(); 
+
+                }
+                break;
+
+        }
+
+    }
+
+
+    protected DFA6 dfa6 = new DFA6(this);
+    protected DFA25 dfa25 = new DFA25(this);
+    static final String DFA6_eotS =
+        "\2\uffff\2\4\2\uffff\1\4";
+    static final String DFA6_eofS =
+        "\7\uffff";
+    static final String DFA6_minS =
+        "\1\53\1\60\2\56\2\uffff\1\56";
+    static final String DFA6_maxS =
+        "\2\71\1\56\1\71\2\uffff\1\71";
+    static final String DFA6_acceptS =
+        "\4\uffff\1\1\1\2\1\uffff";
+    static final String DFA6_specialS =
+        "\7\uffff}>";
+    static final String[] DFA6_transitionS = {
+            "\1\1\1\uffff\1\1\2\uffff\1\2\11\3",
+            "\1\2\11\3",
+            "\1\5",
+            "\1\5\1\uffff\12\6",
+            "",
+            "",
+            "\1\5\1\uffff\12\6"
+    };
+
+    static final short[] DFA6_eot = DFA.unpackEncodedString(DFA6_eotS);
+    static final short[] DFA6_eof = DFA.unpackEncodedString(DFA6_eofS);
+    static final char[] DFA6_min = DFA.unpackEncodedStringToUnsignedChars(DFA6_minS);
+    static final char[] DFA6_max = DFA.unpackEncodedStringToUnsignedChars(DFA6_maxS);
+    static final short[] DFA6_accept = DFA.unpackEncodedString(DFA6_acceptS);
+    static final short[] DFA6_special = DFA.unpackEncodedString(DFA6_specialS);
+    static final short[][] DFA6_transition;
+
+    static {
+        int numStates = DFA6_transitionS.length;
+        DFA6_transition = new short[numStates][];
+        for (int i=0; i<numStates; i++) {
+            DFA6_transition[i] = DFA.unpackEncodedString(DFA6_transitionS[i]);
+        }
+    }
+
+    class DFA6 extends DFA {
+
+        public DFA6(BaseRecognizer recognizer) {
+            this.recognizer = recognizer;
+            this.decisionNumber = 6;
+            this.eot = DFA6_eot;
+            this.eof = DFA6_eof;
+            this.min = DFA6_min;
+            this.max = DFA6_max;
+            this.accept = DFA6_accept;
+            this.special = DFA6_special;
+            this.transition = DFA6_transition;
+        }
+        public String getDescription() {
+            return "42:1: NUMBER : ( INTEGER | FLOAT );";
+        }
+    }
+    static final String DFA25_eotS =
+        "\1\uffff\2\3\2\uffff";
+    static final String DFA25_eofS =
+        "\5\uffff";
+    static final String DFA25_minS =
+        "\1\101\2\56\2\uffff";
+    static final String DFA25_maxS =
+        "\3\172\2\uffff";
+    static final String DFA25_acceptS =
+        "\3\uffff\1\2\1\1";
+    static final String DFA25_specialS =
+        "\5\uffff}>";
+    static final String[] DFA25_transitionS = {
+            "\32\1\4\uffff\1\1\1\uffff\32\1",
+            "\1\4\1\uffff\12\2\7\uffff\32\2\4\uffff\1\2\1\uffff\32\2",
+            "\1\4\1\uffff\12\2\7\uffff\32\2\4\uffff\1\2\1\uffff\32\2",
+            "",
+            ""
+    };
+
+    static final short[] DFA25_eot = DFA.unpackEncodedString(DFA25_eotS);
+    static final short[] DFA25_eof = DFA.unpackEncodedString(DFA25_eofS);
+    static final char[] DFA25_min = DFA.unpackEncodedStringToUnsignedChars(DFA25_minS);
+    static final char[] DFA25_max = DFA.unpackEncodedStringToUnsignedChars(DFA25_maxS);
+    static final short[] DFA25_accept = DFA.unpackEncodedString(DFA25_acceptS);
+    static final short[] DFA25_special = DFA.unpackEncodedString(DFA25_specialS);
+    static final short[][] DFA25_transition;
+
+    static {
+        int numStates = DFA25_transitionS.length;
+        DFA25_transition = new short[numStates][];
+        for (int i=0; i<numStates; i++) {
+            DFA25_transition[i] = DFA.unpackEncodedString(DFA25_transitionS[i]);
+        }
+    }
+
+    class DFA25 extends DFA {
+
+        public DFA25(BaseRecognizer recognizer) {
+            this.recognizer = recognizer;
+            this.decisionNumber = 25;
+            this.eot = DFA25_eot;
+            this.eof = DFA25_eof;
+            this.min = DFA25_min;
+            this.max = DFA25_max;
+            this.accept = DFA25_accept;
+            this.special = DFA25_special;
+            this.transition = DFA25_transition;
+        }
+        public String getDescription() {
+            return "230:1: fragment DOTSYM : ( BARESYM DOT DOTSYM | BARESYM );";
+        }
+    }
+ 
+
+}
\ No newline at end of file

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/type/Type.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/type/Type.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/type/Type.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,402 @@
+package org.jboss.jbossts.orchestration.rule.type;
+
+import java.util.HashMap;
+
+/**
+ * models the type of a rule binding or expression
+ */
+public class Type {
+    // TODO we need eventually to be able to create array types
+    /**
+     * create a type with a given name and optionally an associated class
+     *
+     * @param clazzName the name of the type which may or may not be fully qualified
+     * @param clazz the class associated with this name if it is know otherwise null
+     */
+    public Type(String clazzName, Class clazz)
+    {
+        this(clazzName, clazz, F_OBJECT);
+    }
+
+    /**
+     * create a type with a given name and no associated class
+     *
+     * @param clazzName the name of the type which may or may not be fully qualified
+     */
+    public Type(String clazzName)
+    {
+        this(clazzName, null);
+    }
+
+    /**
+     * get the possibly unqualified name with which this type was created
+     * @return
+     */
+    public String getName()
+    {
+        return clazzName;
+    }
+
+    /**
+     * get the class associated with this type or a special undefined class if the type is not defined
+     * @return
+     */
+    public Class getTargetClass()
+    {
+        return clazz;
+    }
+
+    /**
+     * get the package component of the name associated with this type or the empty String
+     * if it has no package or is was defiend with an unqualified name or is a builtin type
+     * @return
+     */
+
+    public String getPackageName()
+    {
+            return packageName;
+    }
+
+    /**
+     * dereference an object type to the fully qualified named type to which it is aliased where
+     * such an alias has been found to exist or return the supplied type if no alias exists or the
+     * type is a non-objecttype or was originally specified using a fully qualified type name.
+     *
+     * @param target the type to be dereferenced
+     * @return the alias where it exists or the supplied type where there is no alias or null
+     * if a null value is supplied
+     */
+    public static Type dereference(Type target)
+    {
+        if (target == null) {
+            return null;
+        }
+
+        while (target.aliasFor != target) {
+            target = target.aliasFor;
+        }
+
+        return target;
+    }
+
+    /**
+     * attempt to establish an alias from an package unqualified named object type to a package
+     * qualified named object type whose unqualified name equals this type's name
+     * @param target the package qualified named type for which this type should become an alias
+     * @return true if the alias link can be established or already exsits or false if an alias
+     * to a different target already exists or this type or the target are not object types
+     */
+    public boolean aliasTo(Type target)
+    {
+        // we can only legitimately alias an object type without a package to a type with a package
+        // ???caller should already have checked this???
+        if (!isObject() || !target.isObject()) {
+            return false;
+        }
+        // ???caller should already have checked this???
+        if (packageName.length() != 0 || target.packageName.length() == 0) {
+            return false;
+        }
+        // if there is already an alias for this type then it has to be the same as the supplied type
+
+        if (aliasFor != this) {
+            return (aliasFor == target);
+        } else {
+            // we assume the caller has already checked that the names match so . . .
+            // update the alias
+            aliasFor = target;
+            return true;
+        }
+    }
+
+    /**
+     * check whether this type can be assigned with values of the supplied type including
+     * the case where numeric conversion from known or unknown numeric types but excluding any other
+     * cases where this type is undefined
+     * @param type the type poviding RHS values
+     * @return true if it is known that the assignment is valid, false if it is not known to be valid or
+     * is known not to be valid
+     */
+
+    public boolean isAssignableFrom(Type type)
+    {
+        return isAssignableFrom(type.clazz);
+    }
+
+    /**
+     * check whether this type can be assigned with values of the supplied class including
+     * the case where numeric conversion from known or unknown numeric types but excluding any other
+     * cases where this type is undefined
+     * @param clazz the class poviding RHS values
+     * @return true if it is known that the assignment is valid, false if it is not known to be valid or
+     * is known not to be valid
+     */
+    public boolean isAssignableFrom(Class clazz)
+    {
+        if (isUndefined()) {
+            // we can only say yes if this is void or if it is an undefined numeric type
+            if (isVoid()) {
+                return true;
+            } else if (isNumeric()) {
+                // we can coerce any numeric type to another numeric type
+                Type type = primitiveType(clazz);
+                if (type != null && type.isNumeric()) {
+                    return true;
+                }
+            }
+            // we don't know if we can coerce here so return false to play safe
+            return false;
+        } else if (isObject()) {
+            // we can always convert something to a string unless it is void
+            if (this == STRING) {
+                return (clazz != void.class);
+            }
+            // see if the supplied type is assignable from this type's class
+            if (this.clazz.isAssignableFrom(clazz)) {
+                return true;
+            }
+            return false;
+        } else {
+
+            // ok this is a defined primitive type check that clazz is primitive
+
+            Type type = primitiveType(clazz);
+
+            if (type == null) {
+                return false;
+            }
+            // ok we can proceed if the two types have overlapping flags
+            return ((this.flags & type.flags) != 0);
+        }
+    }
+
+    public boolean isUndefined()
+    {
+        return ((flags & F_UNKNOWN) != 0);
+    }
+
+    public boolean isDefined()
+    {
+        return !isUndefined();
+    }
+
+    public boolean isPrimitive()
+    {
+        return ((flags & F_PRIMITIVE) != 0);
+    }
+
+    public boolean isVoid()
+    {
+        return this == VOID;
+    }
+
+    public boolean isNumeric()
+    {
+        return (flags & F_NUMERIC) != 0;
+    }
+
+    public boolean isIntegral()
+    {
+        return (flags & F_INTEGRAL) == F_INTEGRAL;
+    }
+
+    public boolean isFloating()
+    {
+        return (flags & F_FLOATING) == F_FLOATING;
+    }
+
+    public boolean isBoolean()
+    {
+        return (flags & F_BOOLEAN) != 0;
+    }
+
+    public boolean isObject()
+    {
+        return (flags & F_OBJECT) != 0;
+    }
+
+    public boolean isArray()
+    {
+        return (flags & F_ARRAY) != 0;
+    }
+
+    public Type builtinType(Class clazz)
+    {
+        return builtinTypes.get(clazz.getName());
+    }
+
+    public Type primitiveType(Class clazz)
+    {
+        Type type = builtinType(clazz);
+
+        if (type != null && type.isDefined() && type.isPrimitive())
+        {
+            return type;
+        }
+
+        return null;
+    }
+
+    public Type numericType(Class clazz) {
+        Type type = builtinType(clazz);
+
+        if (type != null && type.isNumeric())
+        {
+            return type;
+        }
+
+        return null;
+    }
+
+    private String clazzName;
+    private Class clazz;
+    private String packageName;
+    private int flags;
+    private Type aliasFor;
+
+    private Type(String clazzName, Class clazz, int flags)
+    {
+        this.clazzName = clazzName;
+
+        if (clazz != null) {
+            this.clazz = clazz;
+        } else {
+            this.clazz = Undefined.class;
+            flags |= F_UNKNOWN; 
+        }
+
+        this.flags = flags;
+
+        // types dereference to themselves until they are aliased
+
+        aliasFor = this;
+
+        packageName = packagePart(clazzName);
+    }
+
+    /**
+     * compute the type to which a binary arithmetic operator should promote its operands
+     * before combination based on the two operand types which is also the type to be
+     * used for the result of the operation
+     * @param type1 the type of the left operand  which must be numeric but may be undefined
+     * @param type2 the type of the right operand which must be numeric but may be undefined
+     * @return the corresponding promotion/result type which may be undefined numeric
+     */
+    public static Type promote(Type type1, Type type2) {
+        if (!type1.isNumeric() || !type2.isNumeric()) {
+            // should not happen!
+            System.err.println("Type.promote : unexpected non-numeric type argument");
+            return Type.NUMBER;
+        } else if (type1.isUndefined() || type2.isUndefined()) {
+                // don't know for sure which is which so return undefined numeric
+                return Type.NUMBER;
+        } else if (type1.isFloating() || type2.isFloating()) {
+            if (type1 == DOUBLE || type2 == DOUBLE) {
+                return DOUBLE;
+            } else {
+                return FLOAT;
+            }
+        } else {
+            // integral types -- ok lets invent^H^H^H declare some rules here :-)
+            // either arg long forces a long result
+            // either arg integer forces an integer result
+            // a matched pair of short, char or byte arguments retains the same type in the result
+            // otherwise the result is an integer and args wil be coerced to integer
+            if (type1 == LONG || type2 == LONG) {
+                return LONG;
+            } else if (type1 == INTEGER || type2 == INTEGER) {
+                return INTEGER;
+            } else if (type1 == SHORT && type2 == SHORT) {
+                return SHORT;
+            } else if (type1 == CHARACTER && type2 == CHARACTER) {
+                return CHARACTER;
+            } else if (type1 == BYTE && type2 == BYTE) {
+                return BYTE;
+            } else {
+                return INTEGER;
+            }
+        }
+    }
+
+    private static String classPart(String className)
+    {
+        int dotIdx = className.lastIndexOf('.');
+
+        if (dotIdx < 0) {
+            return className;
+        } else {
+            return className.substring(dotIdx);
+        }
+    }
+
+    private static String packagePart(String className)
+    {
+        int dotIdx = className.lastIndexOf('.');
+
+        if (dotIdx < 0) {
+            return "";
+        } else {
+            return className.substring(0, dotIdx);
+        }
+    }
+
+    // private class used to type unknown types
+    private static class Undefined {
+    };
+
+    final public static int F_UNKNOWN       = 0x1000;
+    final public static int F_BOOLEAN       = 0x0001;
+    final public static int F_INTEGRAL      = 0x0002;
+    final public static int F_FLOATING      = 0x0004;
+    final public static int F_NUMERIC       = F_UNKNOWN | F_INTEGRAL | F_FLOATING;
+    final public static int F_PRIMITIVE     = F_UNKNOWN | F_BOOLEAN | F_NUMERIC;
+    final public static int F_OBJECT        = 0x0008;
+    final public static int F_ARRAY         = 0x0010;
+    final public static int F_ANY           = F_UNKNOWN | F_PRIMITIVE | F_OBJECT | F_ARRAY;
+
+    // we need to cope with array types
+    final public static Type BOOLEAN = new Type("Boolean", Boolean.class, F_BOOLEAN);
+    final public static Type BYTE = new Type("Byte", Byte.class, F_INTEGRAL);
+    final public static Type SHORT = new Type("Short", Short.class, F_INTEGRAL);
+    final public static Type CHARACTER = new Type("Character", Character.class, F_INTEGRAL);
+    final public static Type INTEGER = new Type("Integer", Integer.class, F_INTEGRAL);
+    final public static Type LONG = new Type("Long", Long.class, F_INTEGRAL);
+    final public static Type FLOAT = new Type("Float", Float.class, F_FLOATING);
+    final public static Type DOUBLE = new Type("Double", Double.class, F_FLOATING);
+    final public static Type STRING = new Type("String", String.class, F_OBJECT);
+    final public static Type VOID = new Type("void", void.class, F_ANY);
+    final public static Type NUMBER = new Type("Number", Number.class, F_NUMERIC);
+    final public static Type UNDEFINED = new Type("", Undefined.class, F_ANY);
+
+    final private static HashMap<String, Type> builtinTypes;
+
+    static {
+        builtinTypes = new HashMap<String, Type>();
+        // canonical names
+        builtinTypes.put(BOOLEAN.getTargetClass().getName(), BOOLEAN);
+        builtinTypes.put(BYTE.getTargetClass().getName(), BYTE);
+        builtinTypes.put(SHORT.getTargetClass().getName(), SHORT);
+        builtinTypes.put(CHARACTER.getTargetClass().getName(), CHARACTER);
+        builtinTypes.put(INTEGER.getTargetClass().getName(), INTEGER);
+        builtinTypes.put(LONG.getTargetClass().getName(), LONG);
+        builtinTypes.put(FLOAT.getTargetClass().getName(), FLOAT);
+        builtinTypes.put(STRING.getTargetClass().getName(), STRING);
+        builtinTypes.put(VOID.getTargetClass().getName(), VOID);
+        builtinTypes.put(NUMBER.getTargetClass().getName(), NUMBER);
+        builtinTypes.put(UNDEFINED.getTargetClass().getName(), UNDEFINED);
+        // nicknames
+        builtinTypes.put(BOOLEAN.getName(), BOOLEAN);
+        builtinTypes.put(BYTE.getName(), BYTE);
+        builtinTypes.put(SHORT.getName(), SHORT);
+        builtinTypes.put(CHARACTER.getName(), CHARACTER);
+        builtinTypes.put(INTEGER.getName(), INTEGER);
+        builtinTypes.put(LONG.getName(), LONG);
+        builtinTypes.put(FLOAT.getName(), FLOAT);
+        builtinTypes.put(STRING.getName(), STRING);
+        builtinTypes.put(VOID.getName(), VOID);
+        builtinTypes.put(NUMBER.getName(), NUMBER);
+        builtinTypes.put(UNDEFINED.getName(), UNDEFINED);
+        // allow undefined to be spelled out
+        builtinTypes.put("Undefined", UNDEFINED);
+    }
+}

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/type/TypeGroup.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/type/TypeGroup.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/orchestration/rule/type/TypeGroup.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,116 @@
+package org.jboss.jbossts.orchestration.rule.type;
+
+import java.util.HashMap;
+
+/**
+ * the collection of types associated with an ECA rule
+ */
+public class TypeGroup {
+    protected HashMap<String, Type> typeTable;
+
+    /**
+     * create a type group for a rule containing all the basic types
+     */
+
+    public TypeGroup()
+    {
+        // ensure default types are all in table
+
+        typeTable = new HashMap<String, Type>();
+
+        typeTable.put("boolean", Type.BOOLEAN);
+        typeTable.put("Boolean", Type.BOOLEAN);
+
+        typeTable.put("byte", Type.BYTE);
+        typeTable.put("Byte", Type.BYTE);
+        typeTable.put("short", Type.SHORT);
+        typeTable.put("Short", Type.SHORT);
+        typeTable.put("char", Type.CHARACTER);
+        typeTable.put("Char", Type.CHARACTER);
+        typeTable.put("int", Type.INTEGER);
+        typeTable.put("Integer", Type.INTEGER);
+        typeTable.put("long", Type.LONG);
+        typeTable.put("Long", Type.LONG);
+
+        typeTable.put("float", Type.FLOAT);
+        typeTable.put("Float", Type.FLOAT);
+        typeTable.put("double", Type.DOUBLE);
+        typeTable.put("DOUBLE", Type.DOUBLE);
+
+        typeTable.put("String", Type.STRING);
+        typeTable.put("void", Type.VOID);
+    }
+
+    /**
+     * lookup a type by name dereferencing it to its fully qualified type if that exists
+     * @param name
+     * @return
+     */
+    public Type lookup(String name)
+    {
+        return Type.dereference(typeTable.get(name));
+    }
+
+    /**
+     * create a type with a given name or return an existing type if the supplied
+     * name can be matched. if the type name is qualified ensure that any existing
+     * type with an unqualified name matching this entry is not already aliased to
+     * another type.
+     * @param name
+     * @return the type if created or matched or null if there is an alias mismatch
+     */
+    public Type create(String name)
+    {
+        return create(name, null);
+    }
+
+    /**
+     * create a type with a given name and class or return an existing type if the supplied
+     * name and  class can be matched. if the type name is qualified ensure that any existing
+     * type with an unqualified name matching this entry is not already aliased to another
+     * type.
+     * @param name
+     * @param clazz
+     * @return the type if created or matched or null if there is a class or alias mismatch
+     */
+    public Type create(String name, Class clazz)
+    {
+        Type existing = typeTable.get(name);
+        if (existing == null) {
+            Type newType = new Type(name, clazz);
+            if (checkAlias(newType)) {
+                return Type.dereference(newType);
+            } else {
+                return null;
+            }
+        } else {
+            if (existing.isAssignableFrom(clazz)) {
+                return Type.dereference(existing);
+            } else {
+                return null;
+            }
+        }
+    }
+
+    private boolean checkAlias(Type type)
+    {
+        String name = type.getName();
+        int dotIdx = name.lastIndexOf('.');
+
+        if (dotIdx >= 0) {
+            // we are inserrting a qualified type -- ensure it does not clash with any
+            // unqualified name
+
+            name = name.substring(dotIdx);
+
+            Type alias = typeTable.get(name);
+
+            if (alias != null && !alias.aliasTo(type)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+}
+

Added: labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/test/HandlerClass.java
===================================================================
--- labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/test/HandlerClass.java	                        (rev 0)
+++ labs/jbosstm/workspace/adinn/orchestration/src/org/jboss/jbossts/test/HandlerClass.java	2008-07-18 13:23:49 UTC (rev 21110)
@@ -0,0 +1,61 @@
+package org.jboss.jbossts.test;
+
+import org.jboss.jbossts.orchestration.annotation.EventHandler;
+import org.jboss.jbossts.orchestration.annotation.EventHandlerClass;
+
+/**
+ * sample class to test event handling
+ */
+ at EventHandlerClass
+public class HandlerClass {
+    @EventHandler(
+            targetClass="com.arjuna.wst11.messaging.engines.CoordinatorEngine",
+            targetMethod="commit",
+            targetLine = 77,
+            event = "engine:CoordinatorEngine = $1, recovered:boolean = engine.isRecovered(), identifier:String = engine.getInstanceidentifier()",
+            condition = "recovered AND decrementCounter(identifier)"//,
+            //action = ""
+    ) public static void handleCommit1()
+    {
+        // decrements the counter identified by a recovered engine's identifier each time recovery is attempted
+        // for that engine -- if the counter decrements to zero it will be deactivated
+    }
+
+    @EventHandler(
+            targetClass="com.arjuna.wst11.messaging.engines.CoordinatorEngine",
+            targetMethod="commit",
+            targetLine = 77,
+            event = "engine:CoordinatorEngine = $1, recovered:boolean = engine.isRecovered()",
+            condition = "NOT recovered",
+            action = "killJVM()"
+    ) public static void handleCommit2()
+    {
+        // kills the JVM when a commit is attempted on a non-recovered engine
+    }
+
+    @EventHandler(
+            targetClass="com.arjuna.wst11.messaging.engines.CoordinatorEngine",
+            targetMethod="<init>(String, boolean, W3CEndpointReference)",
+            targetLine = -1,
+            event = "engine:CoordinatorEngine = $1, recovered:boolean = engine.isRecovered(), identifier:String = engine.getInstanceIdentifier()",
+            condition = "recovered",
+            action = "addCounter(identifier, 2)"
+    ) public static void handleNewEngine()
+    {
+        // activates a counter identified by a recovered engine's identifier when the engine is recreated
+        // from the logged data
+    }
+
+    @EventHandler(
+            targetClass="com.arjuna.wst11.messaging.engines.CoordinatorProcessorImpl",
+            targetMethod="committed(Notification, AddressingProperties, ArjunaContext)",
+            targetLine = -1,
+            event = "processor:CoordinatorProcessorImpl = $1, identifier:String = $3.getInstanceIdentifier(), engine:CoordinatorEngine = processor.getCoordinator(identifier), recovered:boolean = engine.isRecovered()",
+            condition = "recovered AND getCounter(identifier)",
+            action = "killThread()"
+    ) public static void handleCommitted()
+    {
+        // kills the current thread when a committed message is received for an engine whose identifier identifies
+        // an active counter
+    }
+}




More information about the jboss-svn-commits mailing list