http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/expression/ASTBuilder.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/expression/ASTBuilder.java 
b/debugger/src/main/java/flash/tools/debugger/expression/ASTBuilder.java
new file mode 100644
index 0000000..a3950a1
--- /dev/null
+++ b/debugger/src/main/java/flash/tools/debugger/expression/ASTBuilder.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.expression;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.tree.as.IASNode;
+
+import flash.localization.LocalizationManager;
+import flash.tools.debugger.DebuggerLocalizer;
+
+/**
+ * ASTBuilder.java
+ * 
+ *    This class creates an abstract syntax tree representation
+ *    of an expression given a sequence of tokens.
+ * 
+ *    The tree is built by calling the ActionScript compiler and
+ *    having it parse the expression, then converting the result
+ *    to a form we prefer.
+ *
+ *    No compression is performed on the tree, thus expressions
+ *    such as (3*4) will result in 3 nodes.
+ * 
+ */
+public class ASTBuilder implements IASTBuilder
+{
+       private static LocalizationManager s_localizationManager;
+
+       /**
+        * whether the fdb indirection operators are allowed, e.g. asterisk 
(*x) or
+        * trailing dot (x.)
+        */
+       private boolean m_isIndirectionOperatorAllowed = true;
+
+       static
+       {
+        // set up for localizing messages
+        s_localizationManager = new LocalizationManager();
+        s_localizationManager.addLocalizer( new 
DebuggerLocalizer("flash.tools.debugger.expression.expression.") ); 
//$NON-NLS-1$
+       }
+
+       /**
+        * @param isIndirectionOperatorAllowed
+        *            whether the fdb indirection operators are allowed, e.g.
+        *            asterisk (*x) or trailing dot (x.)
+        */
+       public ASTBuilder(boolean isIndirectionOperatorAllowed)
+       {
+               m_isIndirectionOperatorAllowed = isIndirectionOperatorAllowed;
+       }
+
+       /**
+        * @return whether the fdb indirection operators are allowed, e.g. 
asterisk
+        *         (*x) or trailing dot (x.)
+        */
+       public boolean isIndirectionOperatorAllowed()
+       {
+               return m_isIndirectionOperatorAllowed;
+       }
+
+
+       /*
+        * @see 
flash.tools.debugger.expression.IASTBuilder#parse(java.io.Reader)
+        */
+       public ValueExp parse(Reader in) throws IOException, ParseException
+       {
+               DebuggerExpression retval = new DebuggerExpression();
+
+               StringBuilder sb = new StringBuilder();
+               int ch;
+               while ( (ch=in.read()) != -1 )
+                       sb.append((char)ch);
+
+               String s = sb.toString();
+
+               // FB-16879: If expression begins with "#N" where N is a number,
+               // replace that with "$obj(N)".  For example, "#3" would become
+               // "$obj(3)".  Later, in PlayerSession.callFunction(), we will
+               // detect the $obj() function and handle it.
+               s = s.replaceFirst("^#([0-9]+)", "\\$obj($1)"); //$NON-NLS-1$ 
//$NON-NLS-2$
+
+               if (isIndirectionOperatorAllowed()) {
+                       if (s.endsWith(".")) { //$NON-NLS-1$
+                               retval.setLookupMembers(true);
+                               s = s.substring(0, s.length() - 1);
+                       } else if (s.startsWith("*")) { //$NON-NLS-1$
+                               retval.setLookupMembers(true);
+                               s = s.substring(1);
+                       }
+               }
+
+               // Enclose the expression in parentheses, in order to ensure 
that the
+               // parser considers it to be an expression.  For example, 
"{x:3}" would
+               // be considered to be a block with label "x" and value "3", 
but,
+               // "({x:3})" is considered to be an inline object with field 
"x" that
+               // has value 3.
+               s = "(" + s + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+
+               final List<ICompilerProblem> errors = new 
ArrayList<ICompilerProblem>();
+//             CompilerHandler newHandler = new CompilerHandler() {
+//                     @Override
+//                     public void error(final String filename, int ln, int 
col, String msg, String source) {
+//                             ErrorInfo ei = new ErrorInfo();
+//                             ei.filename = filename;
+//                             ei.ln = ln;
+//                             ei.col = col;
+//                             ei.msg = msg;
+//                             ei.source = source;
+//                             errors.add(ei);
+//                     }
+//             };
+//             cx.setHandler(newHandler);
+//             cx.scriptAssistParsing = true;
+       //      Parser parser = new Parser(cx, s, "Expression"); //$NON-NLS-1$
+               IASNode programNode = DebuggerUtil.parseExpression(s, errors);
+               //ProgramNode programNode = parser.parseProgram();
+
+               if (errors.size() > 0) {
+                        ICompilerProblem firstError = errors.get(0);
+                       throw new ParseException(firstError.toString(), 
firstError.getColumn());
+               }
+
+               retval.setProgramNode(programNode);
+               return retval;
+       }
+
+        
+       static LocalizationManager getLocalizationManager()
+       {
+               return s_localizationManager;
+       }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/expression/Context.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/expression/Context.java 
b/debugger/src/main/java/flash/tools/debugger/expression/Context.java
new file mode 100644
index 0000000..0088ac3
--- /dev/null
+++ b/debugger/src/main/java/flash/tools/debugger/expression/Context.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.expression;
+
+import flash.tools.debugger.Session;
+import flash.tools.debugger.Value;
+
+/**
+ * An object which returns a value given a name and
+ * appropriate context information.
+ */
+public interface Context
+{
+       /**
+        * Looks for an object of the given name in this context -- for 
example, a member variable.
+        *
+        * The returned Object can be of any type at all.  For example, it 
could be:
+        *
+        * <ul>
+        * <li> a <code>flash.tools.debugger.Variable</code> </li>
+        * <li> your own wrapper around <code>Variable</code> </li>
+        * <li> a <code>flash.tools.debugger.Value</code> </li>
+        * <li> any built-in Java primitive such as <code>Long</code>, 
<code>Integer</code>,
+        *      <code>Double</code>, <code>Boolean</code>, or 
<code>String</code> </li>
+        * <li> any other type you want which has a good 
<code>toString()</code>; see below </li>
+        * </ul>
+        *
+        * Since the return type is just Object, the returned value is only 
meaningful when
+        * passed to other functions this interface.  For example, the returned 
Object can be
+        * passed to createContext(), assign(), or toValue().
+        * 
+        * @param o the object to look up; most commonly a string representing 
the name of
+        * a member variable.
+        */
+       public Object lookup(Object o) throws NoSuchVariableException, 
PlayerFaultException;
+
+       /**
+        * Looks for the members of an object.
+        * 
+        * @param o
+        *            A variable whose members we want to look up
+        * @return Some object which represents the members; could even be just 
a
+        *         string. See lookup() for more information about the returned
+        *         type.
+        * @see #lookup(Object)
+        */
+       public Object lookupMembers(Object o) throws NoSuchVariableException;
+
+       /**
+        * Creates a new context object by combining the current one and o.
+        * For example, if the user typed "myVariable.myMember", then this 
function
+        * will get called with o equal to the object which represents 
"myVariable".
+        * This function should return a new context which, when called with
+        * lookup("myMember"), will return an object for that member.
+        *
+        * @param o any object which may have been returned by this class's 
lookup() function
+        */
+       public Context createContext(Object o);
+
+       /**
+        * Assign the object o, the value v.
+        * 
+        * @param o
+        *            a variable to assign to -- this should be some value 
returned
+        *            by an earlier call to lookup().
+        * @param v
+        *            a value, such as a Boolean, Long, String, etc.
+        */
+       public void assign(Object o, Value v) throws NoSuchVariableException, 
PlayerFaultException;
+
+       /**
+        * Enables/disables the creation of variables during lookup calls.
+        * This is ONLY used by AssignmentExp for creating a assigning a value 
+        * to a property which currently does not exist.
+        */
+       public void createPseudoVariables(boolean oui);
+
+       /**
+        * Converts the object to a Value.
+        * 
+        * @param o
+        *            Either object that was returned by an earlier call to
+        *            <code>lookup()</code>, or one of the raw types that can be
+        *            returned by <code>Value.getValueAsObject()</code>.
+        * @return the corresponding Value, or <code>null</code>.
+        * @see Value#getValueAsObject()
+        */
+       public Value toValue(Object o);
+
+       /**
+        * Converts the context to a Value. Very similar to
+        * <code>toValue(Object o)</code>, except that the object being 
converted
+        * is the object that was used to initialize this context.
+        * 
+        * @return the corresponding Value, or <code>null</code>.
+        */
+       public Value toValue();
+
+       /**
+        * Returns the session associated with this context, or null.
+        * This can legitimately be null; for example, in fdb, you are
+        * allowed to do things like "set $columnwidth = 120" before
+        * beginning a debugging session.
+        */
+       public Session getSession();
+       
+       /**
+        * The worker id to which this context object belongs. 
+        */
+       public int getIsolateId();
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/expression/DebuggerExpression.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/expression/DebuggerExpression.java
 
b/debugger/src/main/java/flash/tools/debugger/expression/DebuggerExpression.java
new file mode 100644
index 0000000..14eab90
--- /dev/null
+++ 
b/debugger/src/main/java/flash/tools/debugger/expression/DebuggerExpression.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flash.tools.debugger.expression;
+
+import java.util.HashSet;
+
+import org.apache.flex.compiler.internal.projects.ASCProject;
+import org.apache.flex.compiler.internal.tree.as.BinaryOperatorLogicalAndNode;
+import org.apache.flex.compiler.internal.tree.as.ExpressionNodeBase;
+import org.apache.flex.compiler.internal.workspaces.Workspace;
+import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.tree.ASTNodeID;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IExpressionNode;
+import org.apache.flex.compiler.workspaces.IWorkspace;
+
+import flash.tools.debugger.PlayerDebugException;
+
+/**
+ * A wrapper around an abstract syntax tree (AST) that was provided by the
+ * ActionScript Compiler (ASC), suitable for use by the debugger.
+ * 
+ * When {@link #evaluate(Context)} is called, this will walk the AST and return
+ * a value. But please note that this class's implementation of expression
+ * evaluation should not be taken as a model of 100% perfect ActionScript
+ * evaluation. While this implementation handles all the cases the debugger is
+ * likely to run into, there are many edge cases that this class can't handle.
+ * For most cases where you need an on-the-fly expression evaluator, you would
+ * be better off using the code from the "esc" project.
+ * 
+ * @author Mike Morearty
+ */
+class DebuggerExpression implements ValueExp {
+
+       private final static HashSet<ASTNodeID> ASSIGN_OPRATORS = new 
HashSet<ASTNodeID>();
+       static {
+               ASSIGN_OPRATORS.add(ASTNodeID.Op_AssignId);
+               ASSIGN_OPRATORS.add(ASTNodeID.Op_LeftShiftAssignID);
+               ASSIGN_OPRATORS.add(ASTNodeID.Op_RightShiftAssignID);
+               ASSIGN_OPRATORS.add(ASTNodeID.Op_UnsignedRightShiftAssignID);
+               ASSIGN_OPRATORS.add(ASTNodeID.Op_MultiplyAssignID);
+               ASSIGN_OPRATORS.add(ASTNodeID.Op_DivideAssignID);
+               ASSIGN_OPRATORS.add(ASTNodeID.Op_ModuloAssignID);
+               ASSIGN_OPRATORS.add(ASTNodeID.Op_BitwiseAndAssignID);
+               ASSIGN_OPRATORS.add(ASTNodeID.Op_BitwiseXorAssignID);
+               ASSIGN_OPRATORS.add(ASTNodeID.Op_BitwiseOrAssignID);
+               ASSIGN_OPRATORS.add(ASTNodeID.Op_AddAssignID);
+               ASSIGN_OPRATORS.add(ASTNodeID.Op_SubtractAssignID);
+               ASSIGN_OPRATORS.add(ASTNodeID.Op_LogicalAndAssignID);
+               ASSIGN_OPRATORS.add(ASTNodeID.Op_LogicalOrAssignID);
+       }
+       /**
+        * The AST representing the expression.
+        */
+       private IASNode m_programNode;
+
+       /**
+        * @see #isLookupMembers()
+        */
+       private boolean m_lookupMembers = false;
+
+       /**
+        * @return the AST representing the expression.
+        */
+       public IASNode getProgramNode() {
+               return m_programNode;
+       }
+
+       /**
+        * Sets the AST representing the expression.
+        */
+       public void setProgramNode(IASNode programNode) {
+               m_programNode = programNode;
+       }
+
+       /*
+        * @see flash.tools.debugger.expression.ValueExp#isLookupMembers()
+        */
+       public boolean isLookupMembers() {
+               return m_lookupMembers;
+       }
+
+       /**
+        * @see #isLookupMembers()
+        */
+       public void setLookupMembers(boolean value) {
+               m_lookupMembers = value;
+       }
+
+       /*
+        * @see flash.tools.debugger.expression.ValueExp#containsAssignment()
+        */
+       public boolean containsAssignment() {
+               return containsAssignment(m_programNode);
+       }
+
+       /**
+        * @param containsAssignment
+        */
+       private boolean containsAssignment(IASNode node) {
+               if (ASSIGN_OPRATORS.contains(node.getNodeID())) {
+                       return true;
+               }
+               for (int i = 0; i < node.getChildCount(); i++) {
+                       if (containsAssignment(node.getChild(i))) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       /*
+        * @see
+        * 
flash.tools.debugger.expression.ValueExp#evaluate(flash.tools.debugger
+        * .expression.Context)
+        */
+       public Object evaluate(Context context) throws NumberFormatException,
+                       NoSuchVariableException, PlayerFaultException, 
PlayerDebugException {
+               // assert m_cx.getScopeDepth() == 0;
+               // m_cx.pushScope(new ExpressionEvaluatorScope(context));
+               try {
+                       IExpressionEvaluator eval = new 
DebuggerExpressionEvaluator();
+                       DebuggerValue value = eval.evaluate(context, 
m_programNode);
+
+                       if (isLookupMembers()) {
+                               return 
context.lookupMembers(value.debuggerValue);
+                       } else {
+                               return value.debuggerValue;
+                       }
+               } catch (Exception e) {
+                       // e.printStackTrace();//TODO : ASC3 : remove
+                       if (e.getCause() instanceof NumberFormatException) {
+                               throw (NumberFormatException) e.getCause();
+                       } else if (e.getCause() instanceof 
NoSuchVariableException) {
+                               throw (NoSuchVariableException) e.getCause();
+                       } else if (e.getCause() instanceof 
PlayerFaultException) {
+                               throw (PlayerFaultException) e.getCause();
+                       } else if (e.getCause() instanceof 
PlayerDebugException) {
+                               throw (PlayerDebugException) e.getCause();
+                       } else {
+                               e.printStackTrace();
+                               throw new 
PlayerDebugException(e.getLocalizedMessage());
+                       }
+               } finally {
+                       // m_cx.popScope();
+               }
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/expression/DebuggerExpressionEvaluator.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/expression/DebuggerExpressionEvaluator.java
 
b/debugger/src/main/java/flash/tools/debugger/expression/DebuggerExpressionEvaluator.java
new file mode 100644
index 0000000..8536a51
--- /dev/null
+++ 
b/debugger/src/main/java/flash/tools/debugger/expression/DebuggerExpressionEvaluator.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.expression;
+
+import org.apache.flex.compiler.internal.projects.ASCProject;
+import org.apache.flex.compiler.internal.workspaces.Workspace;
+import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.tree.as.IASNode;
+
+/**
+ * @author ggv
+ * 
+ */
+public class DebuggerExpressionEvaluator implements IExpressionEvaluator {
+
+       private final ICompilerProject project;
+       private final IASTFolder logicalOperatorFolder;
+
+       /**
+        * 
+        */
+       public DebuggerExpressionEvaluator() {
+               project = new ASCProject(new Workspace(), true);
+               logicalOperatorFolder = new LogicalOperatorsFolder();
+
+       }
+
+       /**
+        * @param project2
+        */
+       public DebuggerExpressionEvaluator(ICompilerProject project2) {
+               logicalOperatorFolder = new LogicalOperatorsFolder();
+               this.project = project2;
+       }
+
+       @Override
+       public DebuggerValue evaluate(Context context, IASNode node)
+                       throws Exception {
+
+               if (node instanceof FoldedExpressionNode) {
+                       /*
+                        * Unfold the folded node, and if the unfolded subtree 
has a logical
+                        * operator, fold the RHS of that
+                        */
+                       node = logicalOperatorFolder
+                                       .unfoldOneLevel((FoldedExpressionNode) 
node);
+               } else {
+                       /*
+                        * Where ever it finds a logical operator, fold the rhs 
of that.
+                        */
+                       node = logicalOperatorFolder.fold(node);
+               }
+               AS3DebuggerBURM burm = new AS3DebuggerBURM();
+               burm.reducer = new AS3DebuggerReducer(context, project);
+
+               burm.burm(node, AS3DebuggerBURM.__expression_NT);
+               DebuggerValue value = (DebuggerValue) burm.getResult();
+               return value;
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/expression/DebuggerUtil.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/expression/DebuggerUtil.java 
b/debugger/src/main/java/flash/tools/debugger/expression/DebuggerUtil.java
new file mode 100644
index 0000000..c5492f2
--- /dev/null
+++ b/debugger/src/main/java/flash/tools/debugger/expression/DebuggerUtil.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.expression;
+
+import java.io.FileNotFoundException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.List;
+
+import org.apache.flex.compiler.common.SourceLocation;
+import org.apache.flex.compiler.filespecs.IFileSpecification;
+import org.apache.flex.compiler.internal.parsing.as.ASParser;
+import org.apache.flex.compiler.internal.scopes.ASFileScope;
+import org.apache.flex.compiler.internal.semantics.PostProcessStep;
+import org.apache.flex.compiler.internal.tree.as.NodeBase;
+import org.apache.flex.compiler.internal.tree.as.ScopedBlockNode;
+import org.apache.flex.compiler.internal.workspaces.Workspace;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.workspaces.IWorkspace;
+
+/**
+ * 
+ * @author ggv
+ */
+public class DebuggerUtil
+{
+
+    /**
+     * 
+     * @param code
+     * @param problems
+     * @return
+     */
+    public static IASNode parseExpression(String code, List<ICompilerProblem> 
problems)
+    {
+       IWorkspace workspace = new Workspace();
+        DebuggerUtil.InMemoryFileSpecification imfs = new 
DebuggerUtil.InMemoryFileSpecification(code);
+        EnumSet<PostProcessStep> empty = EnumSet.noneOf(PostProcessStep.class);
+        IASNode exprAST = ASParser.parseFile(imfs, workspace, empty, null, 
false, false, new ArrayList<String>(), null, null, null);
+
+        // Have to create a fake ScopedBlockNode so the expression can do 
things
+        // like resolve, which means it has to be able to find a scope.
+        // For parsing an expression in a file, one would hook up the 
expression
+        // AST to whatever the real scope was.
+        ScopedBlockNode scopedNode = new ScopedBlockNode();
+        scopedNode.addChild((NodeBase)exprAST);
+        scopedNode.setScope(new ASFileScope(workspace, "fake"));
+        
scopedNode.runPostProcess(EnumSet.of(PostProcessStep.CALCULATE_OFFSETS));
+
+        // return the first (and only child).  This is essentially unwrapping 
the
+        // FileNode that was wrapped around the expression being parsed
+        return exprAST.getChild(0);
+    }
+
+    public static class InMemoryFileSpecification implements IFileSpecification
+    {
+       public InMemoryFileSpecification(String s)
+       {
+               this.s = s;
+       }
+       
+       private String s;
+       
+       public String getPath()
+       {
+               return "flash.tools.debugger";
+       }
+       
+       public Reader createReader() throws FileNotFoundException
+       {
+               return new StringReader(s);
+       }
+       
+       public long getLastModified()
+       {
+               return 0;
+       }
+       
+       public boolean isOpenDocument()
+       {
+               return false;
+       }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/expression/DebuggerValue.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/expression/DebuggerValue.java 
b/debugger/src/main/java/flash/tools/debugger/expression/DebuggerValue.java
new file mode 100644
index 0000000..cd647bc
--- /dev/null
+++ b/debugger/src/main/java/flash/tools/debugger/expression/DebuggerValue.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flash.tools.debugger.expression;
+
+public class DebuggerValue {
+       public Object debuggerValue;
+
+       public DebuggerValue(Object v)
+       {
+               debuggerValue = v;
+       }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/expression/ECMA.java
----------------------------------------------------------------------
diff --git a/debugger/src/main/java/flash/tools/debugger/expression/ECMA.java 
b/debugger/src/main/java/flash/tools/debugger/expression/ECMA.java
new file mode 100644
index 0000000..39c3308
--- /dev/null
+++ b/debugger/src/main/java/flash/tools/debugger/expression/ECMA.java
@@ -0,0 +1,430 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flash.tools.debugger.expression;
+
+import flash.tools.debugger.Isolate;
+import flash.tools.debugger.PlayerDebugException;
+import flash.tools.debugger.Session;
+import flash.tools.debugger.Value;
+import flash.tools.debugger.VariableType;
+import flash.tools.debugger.concrete.DValue;
+import flash.tools.debugger.events.ExceptionFault;
+
+/**
+ * Implementations of some of the conversion functions defined by
+ * the ECMAScript spec ( 
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf ).
+ * Please note, these conversion functions should not be considered to
+ * be 100% accurate; they handle all the cases the debugger's expression
+ * evaluator is likely to run into, but there are some edge cases that
+ * fall through the cracks.
+ * 
+ * @author Mike Morearty
+ */
+public class ECMA
+{
+       /** Used by defaultValue() etc. */
+       private enum PreferredType { NUMBER, STRING }
+
+       /**
+        * ECMA 4.3.2
+        */
+       public static boolean isPrimitive(Value v)
+       {
+               v = safeValue(v, Isolate.DEFAULT_ID);
+               Object o = v.getValueAsObject();
+               return (o == Value.UNDEFINED || o == null || o instanceof 
Boolean
+                               || o instanceof Double || o instanceof String);
+       }
+
+       private static Value callFunction(Session session, Value v, String 
functionName, Value[] args, int isolateId)
+       {
+               v = safeValue(v, isolateId);
+
+               try
+               {
+                       return 
session.getWorkerSession(isolateId).callFunction(v, functionName, args);
+               }
+               catch (PlayerDebugException e)
+               {
+                       throw new ExpressionEvaluatorException(e);
+               }
+       }
+
+       /**
+        * Calls the valueOf() function of an object.
+        */
+       private static Value callValueOf(Session session, Value v, int 
isolateId)
+       {
+               v = safeValue(v, isolateId);
+               return callFunction(session, v, "valueOf", new Value[0], 
isolateId); //$NON-NLS-1$
+       }
+
+       /**
+        * Do not confuse this with toString()!  toString() represents the 
official
+        * ECMA definition of [[ToString]], as defined in ECMA section 9.8.  
This
+        * function, on the other hand, represents calling the toString() 
function
+        * of an object.
+        */
+       private static Value callToString(Session session, Value v, int 
isolateId)
+       {
+               v = safeValue(v, isolateId);
+               return callFunction(session, v, "toString", new Value[0], 
isolateId); //$NON-NLS-1$
+       }
+
+       /**
+        * ECMA 8.6.2.6
+        * 
+        * @param v
+        * @param optionalPreferredType
+        *            either NUMBER, STRING, or null.
+        */
+       public static Value defaultValue(Session session, Value v, 
+                       PreferredType optionalPreferredType,
+                       int isolateId)
+       {
+               v = safeValue(v, isolateId);
+               String typename = v.getTypeName();
+               int at = typename.indexOf('@');
+               if (at != -1)
+                       typename = typename.substring(0, at);
+
+               if (optionalPreferredType == null)
+               {
+                       if (typename.equals("Date")) //$NON-NLS-1$
+                               optionalPreferredType = PreferredType.STRING;
+                       else
+                               optionalPreferredType = PreferredType.NUMBER;
+               }
+
+               if (optionalPreferredType == PreferredType.NUMBER)
+               {
+                       Value result = callValueOf(session, v, isolateId);
+                       if (isPrimitive(result))
+                               return result;
+                       result = callToString(session, v, isolateId);
+                       if (isPrimitive(result))
+                               return result;
+                       throw new RuntimeException(new PlayerFaultException(new 
ExceptionFault(ASTBuilder.getLocalizationManager().getLocalizedTextString("typeError"),
 false, null, isolateId))); //$NON-NLS-1$
+               }
+               else
+               {
+                       Value result = callToString(session, v, isolateId);
+                       if (isPrimitive(result))
+                               return result;
+                       result = callValueOf(session, v, isolateId);
+                       if (isPrimitive(result))
+                               return result;
+                       throw new RuntimeException(new PlayerFaultException(new 
ExceptionFault(ASTBuilder.getLocalizationManager().getLocalizedTextString("typeError"),
 false, null, isolateId))); //$NON-NLS-1$
+               }
+       }
+
+       /**
+        * ECMA 9.1
+        * 
+        * @param v
+        * @param optionalPreferredType
+        *            either NUMBER_TYPE, STRING_TYPE, or null.
+        * @return
+        */
+       public static Value toPrimitive(Session session, Value v,
+                       PreferredType optionalPreferredType, int isolateId)
+       {
+               v = safeValue(v, isolateId);
+               switch (v.getType())
+               {
+               case VariableType.UNDEFINED:
+               case VariableType.NULL:
+               case VariableType.BOOLEAN:
+               case VariableType.NUMBER:
+               case VariableType.STRING:
+                       return v;
+
+               default:
+                       return defaultValue(session, v, optionalPreferredType, 
isolateId);
+               }
+       }
+
+       /** ECMA 9.2 */
+       public static boolean toBoolean(Value v)
+       {
+               v = safeValue(v, Isolate.DEFAULT_ID);
+               switch (v.getType())
+               {
+               case VariableType.UNDEFINED:
+               case VariableType.NULL:
+                       return false;
+               case VariableType.BOOLEAN:
+                       return ((Boolean) v.getValueAsObject()).booleanValue();
+               case VariableType.NUMBER:
+               {
+                       double d = ((Double) 
v.getValueAsObject()).doubleValue();
+                       if (d == 0 || Double.isNaN(d))
+                       {
+                               return false;
+                       }
+                       else
+                       {
+                               return true;
+                       }
+               }
+               case VariableType.STRING:
+                       return ((String) v.getValueAsObject()).length() != 0;
+               default:
+                       return true;
+               }
+       }
+
+       /** ECMA 9.3 */
+       public static double toNumber(Session session, Value v)
+       {
+               v = safeValue(v, Isolate.DEFAULT_ID);
+               switch (v.getType())
+               {
+               case VariableType.UNDEFINED:
+                       return Double.NaN;
+               case VariableType.NULL:
+                       return 0;
+               case VariableType.BOOLEAN:
+                       return ((Boolean) v.getValueAsObject()).booleanValue() 
? 1 : 0;
+               case VariableType.NUMBER:
+                       return ((Double) v.getValueAsObject()).doubleValue();
+               case VariableType.STRING:
+               {
+                       String s = (String) v.getValueAsObject();
+                       if (s.length() == 0)
+                       {
+                               return 0;
+                       }
+                       else
+                       {
+                               try
+                               {
+                                       return Double.parseDouble(s);
+                               }
+                               catch (NumberFormatException e)
+                               {
+                                       return Double.NaN;
+                               }
+                       }
+               }
+               default:
+                       return toNumber(session, toPrimitive(session, v, 
PreferredType.NUMBER, v.getIsolateId()));
+               }
+       }
+
+       private static final double _2pow31 = Math.pow(2, 31);
+       private static final double _2pow32 = Math.pow(2, 32);
+
+       /** ECMA 9.5 */
+       public static int toInt32(Session session, Value v)
+       {
+               v = safeValue(v, Isolate.DEFAULT_ID);
+               double d = toNumber(session, v);
+               if (d == Double.POSITIVE_INFINITY || d == 
Double.NEGATIVE_INFINITY)
+               {
+                       return 0;
+               }
+               else
+               {
+                       double sign = Math.signum(d);
+                       d = Math.floor(Math.abs(d));
+                       d %= _2pow32;
+                       while (d >= _2pow31)
+                               d -= _2pow32;
+                       return (int) (sign*d);
+               }
+       }
+
+       /** ECMA 9.6 */
+       public static long toUint32(Session session, Value v)
+       {
+               v = safeValue(v, Isolate.DEFAULT_ID);
+               long n = toInt32(session, v);
+               if (n < 0)
+                       n = n + (long) 0x10000 * (long) 0x10000;
+               return n;
+       }
+
+       /** ECMA 9.8 */
+       public static String toString(Session session, Value v)
+       {
+               v = safeValue(v, Isolate.DEFAULT_ID);
+               switch (v.getType())
+               {
+               case VariableType.UNDEFINED:
+               case VariableType.NULL:
+               case VariableType.BOOLEAN:
+               case VariableType.STRING:
+                       return v.getValueAsString();
+               case VariableType.NUMBER:
+               {
+                       double d = ((Double) 
v.getValueAsObject()).doubleValue();
+                       if (d == (long) d)
+                       {
+                               return Long.toString((long) d); // avoid the 
".0" on the end
+                       }
+                       else
+                       {
+                               return v.toString();
+                       }
+               }
+               default:
+                       return toString(session, toPrimitive(session, v, 
PreferredType.STRING, v.getIsolateId()));
+               }
+       }
+
+       /** ECMA 11.8.5.  Returns true, false, or undefined. */
+       public static Value lessThan(Session session, Value x, Value y)
+       {
+               x = safeValue(x, Isolate.DEFAULT_ID);
+               y = safeValue(y, Isolate.DEFAULT_ID);
+               Value px = toPrimitive(session, x, PreferredType.NUMBER, 
x.getIsolateId());
+               Value py = toPrimitive(session, y, PreferredType.NUMBER, 
y.getIsolateId());
+               if (px.getType() == VariableType.STRING
+                               && py.getType() == VariableType.STRING)
+               {
+                       String sx = px.getValueAsString();
+                       String sy = py.getValueAsString();
+                       return DValue.forPrimitive(new Boolean(sx.compareTo(sy) 
< 0), x.getIsolateId());
+               }
+               else
+               {
+                       double dx = toNumber(session, px);
+                       double dy = toNumber(session, py);
+                       if (Double.isNaN(dx) || Double.isNaN(dy))
+                               return DValue.forPrimitive(Value.UNDEFINED, 
x.getIsolateId());
+                       return DValue.forPrimitive(new Boolean(dx < dy), 
x.getIsolateId());
+               }
+       }
+
+       /** ECMA 11.9.3 */
+       public static boolean equals(Session session, Value xv, Value yv)
+       {
+               xv = safeValue(xv, Isolate.DEFAULT_ID);
+               yv = safeValue(yv, Isolate.DEFAULT_ID);
+
+               Object x = xv.getValueAsObject();
+               Object y = yv.getValueAsObject();
+
+               if (xv.getType() == yv.getType())
+               {
+                       if (x == Value.UNDEFINED)
+                               return true;
+                       if (x == null)
+                               return true;
+                       if (x instanceof Double)
+                       {
+                               double dx = ((Double) x).doubleValue();
+                               double dy = ((Double) y).doubleValue();
+                               return dx == dy;
+                       }
+                       if (x instanceof String || x instanceof Boolean)
+                               return x.equals(y);
+
+                       // see if they are the same object
+                       if (xv.getId() != -1 || yv.getId() != -1)
+                               return xv.getId() == yv.getId();
+                       return false;
+               }
+               else
+               {
+                       if (x == null && y == Value.UNDEFINED)
+                               return true;
+                       if (x == Value.UNDEFINED && y == null)
+                               return true;
+                       if (x instanceof Double && y instanceof String)
+                       {
+                               double dx = ((Double) x).doubleValue();
+                               double dy = toNumber(session, yv);
+                               return dx == dy;
+                       }
+                       if (x instanceof String && y instanceof Double)
+                       {
+                               double dx = toNumber(session, xv);
+                               double dy = ((Double) y).doubleValue();
+                               return dx == dy;
+                       }
+                       if (x instanceof Boolean)
+                               return equals(session, DValue.forPrimitive(new 
Double(toNumber(session, xv)), xv.getIsolateId()), yv);
+                       if (y instanceof Boolean)
+                               return equals(session, xv, 
DValue.forPrimitive(new Double(toNumber(session, yv)), xv.getIsolateId()));
+                       if ((x instanceof String || x instanceof Double) && 
yv.getType() == VariableType.OBJECT)
+                       {
+                               return equals(session, xv, toPrimitive(session, 
yv, null, yv.getIsolateId()));
+                       }
+                       if (xv.getType() == VariableType.OBJECT && (y 
instanceof String || y instanceof Double))
+                       {
+                               return equals(session, toPrimitive(session, xv, 
null, xv.getIsolateId()), yv);
+                       }
+                       return false;
+               }
+       }
+
+       /** ECMA 11.9.6 */
+       public static boolean strictEquals(Value xv, Value yv)
+       {
+               xv = safeValue(xv, Isolate.DEFAULT_ID);
+               yv = safeValue(yv, Isolate.DEFAULT_ID);
+
+               Object x = xv.getValueAsObject();
+               Object y = yv.getValueAsObject();
+
+               if (xv.getType() == yv.getType())
+               {
+                       if (x == Value.UNDEFINED)
+                               return true;
+                       if (x == null)
+                               return true;
+                       if (x instanceof Double)
+                       {
+                               double dx = ((Double) x).doubleValue();
+                               double dy = ((Double) y).doubleValue();
+                               return dx == dy;
+                       }
+                       if (x instanceof String || x instanceof Boolean)
+                               return x.equals(y);
+
+                       // see if they are the same object
+                       if (xv.getId() != -1 || yv.getId() != -1)
+                               return xv.getId() == yv.getId();
+                       return false;
+               }
+               else
+               {
+                       return false;
+               }
+       }
+
+       /**
+        * Returns a "safe" (non-null) form of the specified Value -- that is, 
if
+        * the specified Value is null, returns a non-null Value that 
*represents*
+        * null.
+        * 
+        * @param v
+        *            any Value, possibly null
+        * @return a non-null Value
+        */
+       public static Value safeValue(Value v, int isolateId)
+       {
+               if (v == null)
+               {
+                       v = DValue.forPrimitive(null, isolateId);
+                       assert v != null;
+               }
+               return v;
+       }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/expression/ExpressionEvaluatorException.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/expression/ExpressionEvaluatorException.java
 
b/debugger/src/main/java/flash/tools/debugger/expression/ExpressionEvaluatorException.java
new file mode 100644
index 0000000..d10485d
--- /dev/null
+++ 
b/debugger/src/main/java/flash/tools/debugger/expression/ExpressionEvaluatorException.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.expression;
+
+/**
+ * An exception raised while evaluating an expression.  This is a bit
+ * of a hack -- we need this to extend <code>RuntimeException</code>
+ * because the functions in the <code>Evaluator</code> interface don't
+ * throw anything, but our <code>DebuggerEvaluator</code> has many
+ * places where it needs to bail out.
+ * 
+ * @author Mike Morearty
+ */
+public class ExpressionEvaluatorException extends RuntimeException {
+       private static final long serialVersionUID = -7005526599250035578L;
+
+       public ExpressionEvaluatorException(String message) {
+               super(message);
+       }
+
+       public ExpressionEvaluatorException(Throwable cause) {
+               super(cause);
+       }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/expression/FoldedExpressionNode.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/expression/FoldedExpressionNode.java
 
b/debugger/src/main/java/flash/tools/debugger/expression/FoldedExpressionNode.java
new file mode 100644
index 0000000..e2fbac8
--- /dev/null
+++ 
b/debugger/src/main/java/flash/tools/debugger/expression/FoldedExpressionNode.java
@@ -0,0 +1,252 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.expression;
+
+import org.apache.flex.compiler.filespecs.IFileSpecification;
+import org.apache.flex.compiler.internal.tree.as.ExpressionNodeBase;
+import org.apache.flex.compiler.tree.ASTNodeID;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IExpressionNode;
+import org.apache.flex.compiler.tree.as.IScopedNode;
+
+/**
+ * @author ggv
+ * 
+ */
+public class FoldedExpressionNode extends ExpressionNodeBase implements
+               IExpressionNode {
+
+       private final IASNode rootNode;
+
+       /**
+        * 
+        */
+       public FoldedExpressionNode(IASNode rootNode) {
+               this.rootNode = rootNode;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see com.adobe.flash.compiler.common.ISourceLocation#getStart()
+        */
+       @Override
+       public int getStart() {
+               return getUnderLyingNode().getStart();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see com.adobe.flash.compiler.common.ISourceLocation#getEnd()
+        */
+       @Override
+       public int getEnd() {
+               return getUnderLyingNode().getEnd();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see com.adobe.flash.compiler.common.ISourceLocation#getLine()
+        */
+       @Override
+       public int getLine() {
+               return getUnderLyingNode().getLine();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see com.adobe.flash.compiler.common.ISourceLocation#getColumn()
+        */
+       @Override
+       public int getColumn() {
+               return 0;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see 
com.adobe.flash.compiler.common.ISourceLocation#getAbsoluteStart()
+        */
+       @Override
+       public int getAbsoluteStart() {
+               return getUnderLyingNode().getAbsoluteStart();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see com.adobe.flash.compiler.common.ISourceLocation#getAbsoluteEnd()
+        */
+       @Override
+       public int getAbsoluteEnd() {
+               return getUnderLyingNode().getAbsoluteEnd();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see com.adobe.flash.compiler.tree.as.IASNode#getNodeID()
+        */
+       @Override
+       public ASTNodeID getNodeID() {
+               return ASTNodeID.FoldedExpressionID;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see com.adobe.flash.compiler.tree.as.IASNode#contains(int)
+        */
+       @Override
+       public boolean contains(int offset) {
+               return getUnderLyingNode().contains(offset);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see
+        * com.adobe.flash.compiler.tree.as.IASNode#getAncestorOfType(java.lang.
+        * Class)
+        */
+       @Override
+       public IASNode getAncestorOfType(Class<? extends IASNode> nodeType) {
+               return getUnderLyingNode().getAncestorOfType(nodeType);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see com.adobe.flash.compiler.tree.as.IASNode#getChild(int)
+        */
+       @Override
+       public IASNode getChild(int i) {
+               return null;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see com.adobe.flash.compiler.tree.as.IASNode#getChildCount()
+        */
+       @Override
+       public int getChildCount() {
+               return 0;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see com.adobe.flash.compiler.tree.as.IASNode#getContainingNode(int)
+        */
+       @Override
+       public IASNode getContainingNode(int offset) {
+               return getUnderLyingNode().getContainingNode(offset);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see com.adobe.flash.compiler.tree.as.IASNode#getContainingScope()
+        */
+       @Override
+       public IScopedNode getContainingScope() {
+               return getUnderLyingNode().getContainingScope();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see com.adobe.flash.compiler.tree.as.IASNode#getPackageName()
+        */
+       @Override
+       public String getPackageName() {
+               return getUnderLyingNode().getPackageName();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see com.adobe.flash.compiler.tree.as.IASNode#getParent()
+        */
+       @Override
+       public IASNode getParent() {
+               return getUnderLyingNode().getParent();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see com.adobe.flash.compiler.tree.as.IASNode#getFileSpecification()
+        */
+       @Override
+       public IFileSpecification getFileSpecification() {
+               return getUnderLyingNode().getFileSpecification();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see com.adobe.flash.compiler.tree.as.IASNode#getSpanningStart()
+        */
+       @Override
+       public int getSpanningStart() {
+               return getUnderLyingNode().getSpanningStart();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see com.adobe.flash.compiler.tree.as.IASNode#getSucceedingNode(int)
+        */
+       @Override
+       public IASNode getSucceedingNode(int offset) {
+               return getUnderLyingNode().getSucceedingNode(offset);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see com.adobe.flash.compiler.tree.as.IASNode#isTerminal()
+        */
+       @Override
+       public boolean isTerminal() {
+               return true;
+       }
+
+       /**
+        * @return the rootNode
+        */
+       public IASNode getUnderLyingNode() {
+               return rootNode;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see 
com.adobe.flash.compiler.internal.tree.as.ExpressionNodeBase#copy()
+        */
+       @Override
+       protected ExpressionNodeBase copy() {
+               return null;
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/expression/IASTBuilder.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/expression/IASTBuilder.java 
b/debugger/src/main/java/flash/tools/debugger/expression/IASTBuilder.java
new file mode 100644
index 0000000..ba4bb72
--- /dev/null
+++ b/debugger/src/main/java/flash/tools/debugger/expression/IASTBuilder.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.expression;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.text.ParseException;
+
+public interface IASTBuilder
+{
+       /**
+        * A parser that should do a fairly good job at
+        * parsing a general expression string.
+        * 
+        * Exceptions:
+        *  ParseException - a general parsing error occurred.
+        * 
+        */
+       public ValueExp parse(Reader in) throws IOException, ParseException;
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/expression/IASTFolder.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/expression/IASTFolder.java 
b/debugger/src/main/java/flash/tools/debugger/expression/IASTFolder.java
new file mode 100644
index 0000000..30ac679
--- /dev/null
+++ b/debugger/src/main/java/flash/tools/debugger/expression/IASTFolder.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.expression;
+
+import org.apache.flex.compiler.tree.as.IASNode;
+
+/**
+ * @author ggv
+ * 
+ */
+public interface IASTFolder {
+
+       /**
+        * This will perform folding of certain nodes, based on implementation
+        * 
+        * @param rootNode
+        * @return
+        */
+       public IASNode fold(IASNode rootNode);
+
+       /**
+        * Unfolds onlevel, if required will fold the children
+        * 
+        * @param rootNode
+        * @return
+        */
+       public IASNode unfoldOneLevel(FoldedExpressionNode rootNode);
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/expression/IExpressionEvaluator.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/expression/IExpressionEvaluator.java
 
b/debugger/src/main/java/flash/tools/debugger/expression/IExpressionEvaluator.java
new file mode 100644
index 0000000..c1ffe03
--- /dev/null
+++ 
b/debugger/src/main/java/flash/tools/debugger/expression/IExpressionEvaluator.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.expression;
+
+import org.apache.flex.compiler.tree.as.IASNode;
+
+/**
+ * @author ggv
+ *
+ */
+public interface IExpressionEvaluator {
+
+       public abstract DebuggerValue evaluate(Context context, IASNode node) 
throws Exception;
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/expression/LogicalOperatorsFolder.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/expression/LogicalOperatorsFolder.java
 
b/debugger/src/main/java/flash/tools/debugger/expression/LogicalOperatorsFolder.java
new file mode 100644
index 0000000..84709bd
--- /dev/null
+++ 
b/debugger/src/main/java/flash/tools/debugger/expression/LogicalOperatorsFolder.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.expression;
+
+import 
org.apache.flex.compiler.internal.tree.as.BinaryOperatorLogicalAndAssignmentNode;
+import org.apache.flex.compiler.internal.tree.as.BinaryOperatorLogicalAndNode;
+import 
org.apache.flex.compiler.internal.tree.as.BinaryOperatorLogicalOrAssignmentNode;
+import org.apache.flex.compiler.internal.tree.as.BinaryOperatorLogicalOrNode;
+import org.apache.flex.compiler.internal.tree.as.ExpressionNodeBase;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.tree.as.IExpressionNode;
+
+/**
+ * The logical operator's right hand operands are folded into
+ * FoldedExperessionNode, so that they are not evaluated by the burm.
+ * 
+ * This is required for shortcircuit evaluation
+ * 
+ * @author ggv
+ * 
+ */
+public class LogicalOperatorsFolder implements IASTFolder {
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see
+        * 
flash.tools.debugger.expression.IASTFolder#fold(com.adobe.flash.compiler
+        * .tree.as.IASNode)
+        */
+       @Override
+       public IASNode fold(IASNode rootNode) {
+               foldLazyRHSOperandsForLogicalOperators(rootNode);
+               return rootNode;
+       }
+
+       /**
+        * @param node
+        */
+       private void foldLazyRHSOperandsForLogicalOperators(IASNode node) {
+
+               if (node instanceof BinaryOperatorLogicalAndNode
+                               || node instanceof 
BinaryOperatorLogicalAndAssignmentNode) {
+
+                       BinaryOperatorLogicalAndNode opNode = 
((BinaryOperatorLogicalAndNode) node);
+                       
opNode.setRightOperandNode(fold(opNode.getRightOperandNode()));
+                       
foldLazyRHSOperandsForLogicalOperators(opNode.getLeftOperandNode());
+
+               } else if (node instanceof BinaryOperatorLogicalOrNode
+                               || node instanceof 
BinaryOperatorLogicalOrAssignmentNode) {
+
+                       BinaryOperatorLogicalOrNode opNode = 
((BinaryOperatorLogicalOrNode) node);
+                       
opNode.setRightOperandNode(fold(opNode.getRightOperandNode()));
+                       
foldLazyRHSOperandsForLogicalOperators(opNode.getLeftOperandNode());
+
+               } else {
+                       int chCount = node.getChildCount();
+                       for (int i = 0; i < chCount; i++) {
+                               IASNode childNode = node.getChild(i);
+                               
foldLazyRHSOperandsForLogicalOperators(childNode);
+                       }
+               }
+       }
+
+       /**
+        * @param rightOperandNode
+        * @return
+        */
+       private ExpressionNodeBase fold(IExpressionNode rightOperandNode) {
+               return new FoldedExpressionNode(rightOperandNode);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see
+        * flash.tools.debugger.expression.IASTFolder#unfoldOneLevel(flash.tools
+        * .debugger.expression.FoldedExpressionNode)
+        */
+       @Override
+       public IASNode unfoldOneLevel(FoldedExpressionNode 
foldedExpressionNode) {
+               IASNode node = foldedExpressionNode.getUnderLyingNode();
+               fold(node);
+               return node;
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/expression/NoSuchVariableException.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/expression/NoSuchVariableException.java
 
b/debugger/src/main/java/flash/tools/debugger/expression/NoSuchVariableException.java
new file mode 100644
index 0000000..05e69ca
--- /dev/null
+++ 
b/debugger/src/main/java/flash/tools/debugger/expression/NoSuchVariableException.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.expression;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Thrown when a variable name cannot be resolved in the current scope
+ */
+public class NoSuchVariableException extends Exception
+{
+       private static final long serialVersionUID = -400396588945206074L;
+
+    public NoSuchVariableException(String s)   { super(s); }
+       public NoSuchVariableException(Object o)        { super(o.toString()); }
+
+       @Override
+       public String getLocalizedMessage()
+       {
+               Map<String, String> args = new HashMap<String, String>();
+               args.put("arg2", getMessage() ); //$NON-NLS-1$
+               return 
ASTBuilder.getLocalizationManager().getLocalizedTextString("noSuchVariable", 
args); //$NON-NLS-1$
+       }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/expression/PlayerFaultException.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/expression/PlayerFaultException.java
 
b/debugger/src/main/java/flash/tools/debugger/expression/PlayerFaultException.java
new file mode 100644
index 0000000..5cec3a1
--- /dev/null
+++ 
b/debugger/src/main/java/flash/tools/debugger/expression/PlayerFaultException.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.expression;
+
+import flash.tools.debugger.events.FaultEvent;
+
+/**
+ * Thrown when the player generates a fault.  For example, if
+ * an attempt to assign a value to a variable results in the player
+ * generating a fault because that value has no setter, or because
+ * the setter throws an exception for any other reason, then this
+ * exception will be generated.
+ */
+public class PlayerFaultException extends Exception {
+       private static final long serialVersionUID = 7754580337597815207L;
+    private FaultEvent m_event;
+
+       public PlayerFaultException(FaultEvent event)
+       {
+               m_event = event;
+       }
+       
+       public FaultEvent getFaultEvent()
+       {
+               return m_event;
+       }
+       
+       @Override
+       public String getMessage()
+       {
+               return m_event.information;
+       }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/expression/ValueExp.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/expression/ValueExp.java 
b/debugger/src/main/java/flash/tools/debugger/expression/ValueExp.java
new file mode 100644
index 0000000..988bf3f
--- /dev/null
+++ b/debugger/src/main/java/flash/tools/debugger/expression/ValueExp.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.expression;
+
+import flash.tools.debugger.PlayerDebugException;
+
+/**
+ * All objects in the abstract syntax tree must provide 
+ * this interface.  It allows the tree to resolve down
+ * to a single value.
+ * 
+ * The tree nodes are terminal and non-terminal.  Terminals
+ * are constants or variables, non-terminals are everything 
+ * else.  Each non-terminal is an operation which takes 
+ * its left hand child and right hand child as input
+ * and produces a result.  Performing evaluate() at the root of 
+ * the tree results in a single Object being returned.
+ */
+public interface ValueExp
+{
+       /**
+        * Evaluates the expression. For example, if this node is a "+" node, 
with a
+        * 2 left child and a 2 right child, then the return value will be a 
long
+        * (that is, a java.lang.Long) with the value 4.
+        * 
+        * @param context
+        *            the context in which the expression should be evaluated;
+        *            primarily used for looking up variables. For example, when
+        *            evaluating the expression "myvar", the context looks at
+        *            locals, members of "this", etc.; when evaluating "myfield"
+        *            node of the expression "myvar.myfield", the context looks 
at
+        *            members of the variable "myvar".
+        * @return the value of the expression. This might be a literal Java
+        *         constant (e.g. a Boolean, Integer, String, etc.); or it 
might be
+        *         an UndefinedExp, representing the value 'undefined'; or it 
might
+        *         be a Value; or it might be a Variable.
+        * 
+        * @see Context#lookup(Object)
+        */
+       public Object evaluate(Context context) throws NumberFormatException, 
NoSuchVariableException,
+                       PlayerFaultException, PlayerDebugException;
+
+       /**
+        * Returns whether the expression contains any assignments (= or ++ or 
--).
+        * Note, there are other kinds of expressions that can have side 
effects as
+        * well, such as function calls, or even simple expressions like "foo" 
if
+        * foo is a getter.
+        */
+       public boolean containsAssignment();
+
+       /**
+        * Returns whether <code>evaluate()</code> will return an object that
+        * explicitly shows the values of all members of the expression. For
+        * example, in fdb, if the user writes "print myvar", then 
isLookupMembers
+        * will be false, and the debugger will show just the value of
+        * <code>myvar</code>, but not the values of its members; but if the 
user
+        * writes "print myvar." (with a "." at the end), then the debugger will
+        * show the values of all of the members of <code>myvar</code>.
+        * 
+        * @see ASTBuilder#ASTBuilder(boolean)
+        * @see ASTBuilder#isIndirectionOperatorAllowed()
+        */
+       public boolean isLookupMembers();
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeASTBuilder.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeASTBuilder.java
 
b/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeASTBuilder.java
new file mode 100644
index 0000000..7c3f15d
--- /dev/null
+++ 
b/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeASTBuilder.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.threadsafe;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.text.ParseException;
+
+import flash.tools.debugger.expression.IASTBuilder;
+import flash.tools.debugger.expression.ValueExp;
+
+/**
+ * @author Mike Morearty
+ */
+public class ThreadSafeASTBuilder extends ThreadSafeDebuggerObject implements 
IASTBuilder
+{
+       private final IASTBuilder m_astBuilder;
+
+       /**
+        * @param syncObj
+        */
+       public ThreadSafeASTBuilder(Object syncObj, IASTBuilder astBuilder)
+       {
+               super(syncObj);
+               m_astBuilder = astBuilder;
+       }
+
+       /**
+        * Wraps an IASTBuilder inside a ThreadSafeASTBuilder. If the passed-in
+        * IASTBuilder is null, then this function returns null.
+        */
+       public static ThreadSafeASTBuilder wrap(Object syncObj, IASTBuilder 
astBuilder) {
+               if (astBuilder != null)
+                       return new ThreadSafeASTBuilder(syncObj, astBuilder);
+               else
+                       return null;
+       }
+
+       /*
+        * @see 
flash.tools.debugger.expression.IASTBuilder#parse(java.io.Reader)
+        */
+       public ValueExp parse(Reader in) throws IOException, ParseException
+       {
+               synchronized (getSyncObject()) {
+                       return ThreadSafeValueExp.wrap(getSyncObject(), 
m_astBuilder.parse(in));
+               }
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeBootstrap.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeBootstrap.java
 
b/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeBootstrap.java
new file mode 100644
index 0000000..37d016d
--- /dev/null
+++ 
b/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeBootstrap.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.threadsafe;
+
+import flash.tools.debugger.Bootstrap;
+
+/**
+ * Thread-safe wrapper for flash.tools.debugger.Bootstrap
+ * @author Mike Morearty
+ */
+public class ThreadSafeBootstrap {
+
+       private static ThreadSafeSessionManager fMgr;
+
+       private ThreadSafeBootstrap() {} // prevent instantiation
+
+       public static synchronized ThreadSafeSessionManager sessionManager()
+       {
+               if (fMgr == null) {
+                       fMgr = 
ThreadSafeSessionManager.wrap(Bootstrap.sessionManager());
+               }
+               return fMgr;
+       }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeDebuggerObject.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeDebuggerObject.java
 
b/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeDebuggerObject.java
new file mode 100644
index 0000000..02511ff
--- /dev/null
+++ 
b/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeDebuggerObject.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.threadsafe;
+
+/**
+ * Intended to be subclassed.
+ * 
+ * @author Mike Morearty
+ */
+class ThreadSafeDebuggerObject {
+
+       private Object fSyncObj;
+
+       protected ThreadSafeDebuggerObject(Object syncObj) {
+               fSyncObj = syncObj;
+       }
+
+       public final Object getSyncObject() {
+               return fSyncObj;
+       }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeFrame.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeFrame.java 
b/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeFrame.java
new file mode 100644
index 0000000..c39b2df
--- /dev/null
+++ 
b/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeFrame.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.threadsafe;
+
+import flash.tools.debugger.Frame;
+import flash.tools.debugger.Location;
+import flash.tools.debugger.NoResponseException;
+import flash.tools.debugger.NotConnectedException;
+import flash.tools.debugger.NotSuspendedException;
+import flash.tools.debugger.Session;
+import flash.tools.debugger.Variable;
+
+/**
+ * Thread-safe wrapper for flash.tools.debugger.Frame
+ * @author Mike Morearty
+ */
+public class ThreadSafeFrame extends ThreadSafeDebuggerObject implements Frame 
{
+       
+       private Frame fFrame;
+       
+       private ThreadSafeFrame(Object syncObj, Frame frame) {
+               super(syncObj);
+               fFrame = frame;
+       }
+
+       /**
+        * Wraps a Frame inside a ThreadSafeFrame.  If the passed-in Frame
+        * is null, then this function returns null.
+        */
+       public static ThreadSafeFrame wrap(Object syncObj, Frame frame) {
+               if (frame != null)
+                       return new ThreadSafeFrame(syncObj, frame);
+               else
+                       return null;
+       }
+
+       /**
+        * Wraps an array of Frames inside an array of ThreadSafeFrames.
+        */
+       public static ThreadSafeFrame[] wrapArray(Object syncObj, Frame[] 
frames) {
+               ThreadSafeFrame[] threadSafeFrames = new 
ThreadSafeFrame[frames.length];
+               for (int i=0; i<frames.length; ++i) {
+                       threadSafeFrames[i] = wrap(syncObj, frames[i]);
+               }
+               return threadSafeFrames;
+       }
+
+       public static Object getSyncObject(Frame f) {
+               return ((ThreadSafeFrame)f).getSyncObject();
+       }
+       
+       @Override
+       public int hashCode() {
+               synchronized (getSyncObject()) {
+                       return fFrame.hashCode();
+               }
+       }
+
+       @Override
+       public boolean equals(Object other) {
+               synchronized (getSyncObject()) {
+                       if (other == null)
+                               return false;
+                       if (other instanceof ThreadSafeFrame) {
+                               return 
(fFrame.equals(((ThreadSafeFrame)other).fFrame));
+                       }
+                       if (other instanceof Frame) {
+                               return (fFrame.equals(other));
+                       }
+                       return false;
+               }
+       }
+
+       @Override
+       public String toString() {
+               synchronized (getSyncObject()) {
+                       return fFrame.toString();
+               }
+       }
+
+       // -- beginning of delegate functions --
+
+       public Variable[] getArguments(Session s) throws NoResponseException, 
NotSuspendedException, NotConnectedException {
+               synchronized (getSyncObject()) {
+                       return ThreadSafeVariable.wrapArray(getSyncObject(), 
fFrame.getArguments(ThreadSafeSession.getRaw(s)));
+               }
+       }
+
+       public String getCallSignature() {
+               synchronized (getSyncObject()) {
+                       return fFrame.getCallSignature();
+               }
+       }
+
+       public Variable[] getLocals(Session s) throws NoResponseException, 
NotSuspendedException, NotConnectedException {
+               synchronized (getSyncObject()) {
+                       return ThreadSafeVariable.wrapArray(getSyncObject(), 
fFrame.getLocals(ThreadSafeSession.getRaw(s)));
+               }
+       }
+
+       public Location getLocation() {
+               synchronized (getSyncObject()) {
+                       return ThreadSafeLocation.wrap(getSyncObject(), 
fFrame.getLocation());
+               }
+       }
+
+       public Variable getThis(Session s) throws NoResponseException, 
NotSuspendedException, NotConnectedException {
+               synchronized (getSyncObject()) {
+                       return ThreadSafeVariable.wrap(getSyncObject(), 
fFrame.getThis(ThreadSafeSession.getRaw(s)));
+               }
+       }
+
+       public Variable[] getScopeChain(Session s) throws NoResponseException, 
NotSuspendedException, NotConnectedException {
+               synchronized (getSyncObject()) {
+                       return ThreadSafeVariable.wrapArray(getSyncObject(), 
fFrame.getScopeChain(ThreadSafeSession.getRaw(s)));
+               }
+       }
+
+       @Override
+       public int getIsolateId() {
+               synchronized (getSyncObject()) {
+                       return fFrame.getIsolateId();
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeIsolate.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeIsolate.java 
b/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeIsolate.java
new file mode 100644
index 0000000..0cc5619
--- /dev/null
+++ 
b/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeIsolate.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flash.tools.debugger.threadsafe;
+
+import flash.tools.debugger.Isolate;
+
+/**
+ * Thread-safe wrapper for flash.tools.debugger.Isolate
+ * @author Anirudh Sasikumar
+ */
+public class ThreadSafeIsolate extends ThreadSafeDebuggerObject implements 
Isolate {
+
+       private Isolate fIsolate;
+       
+       private ThreadSafeIsolate(Object syncObj, Isolate isolate) {
+               super(syncObj);
+               fIsolate = isolate;
+       }
+
+       /**
+        * Wraps a Watch inside a ThreadSafeWatch.  If the passed-in Watch
+        * is null, then this function returns null.
+        */
+       public static ThreadSafeIsolate wrap(Object syncObj, Isolate isolate) {
+               if (isolate != null)
+                       return new ThreadSafeIsolate(syncObj, isolate);
+               else
+                       return null;
+       }
+       
+       /**
+        * Wraps an array of Locations inside an array of ThreadSafeLocations.
+        */
+       public static ThreadSafeIsolate[] wrapArray(Object syncObj, Isolate[] 
isolates) {
+               ThreadSafeIsolate[] threadSafeIsolates = new 
ThreadSafeIsolate[isolates.length];
+               for (int i=0; i<isolates.length; ++i) {
+                       threadSafeIsolates[i] = wrap(syncObj, isolates[i]);
+               }
+               return threadSafeIsolates;
+       }
+
+       public int getId() {
+               synchronized (getSyncObject()) {
+                       return fIsolate.getId();
+               }
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeIsolateSession.java
----------------------------------------------------------------------
diff --git 
a/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeIsolateSession.java
 
b/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeIsolateSession.java
new file mode 100644
index 0000000..57f0820
--- /dev/null
+++ 
b/debugger/src/main/java/flash/tools/debugger/threadsafe/ThreadSafeIsolateSession.java
@@ -0,0 +1,285 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flash.tools.debugger.threadsafe;
+
+import flash.tools.debugger.Frame;
+import flash.tools.debugger.IsolateSession;
+import flash.tools.debugger.Location;
+import flash.tools.debugger.NoResponseException;
+import flash.tools.debugger.NotConnectedException;
+import flash.tools.debugger.NotSupportedException;
+import flash.tools.debugger.NotSuspendedException;
+import flash.tools.debugger.PlayerDebugException;
+import flash.tools.debugger.SuspendedException;
+import flash.tools.debugger.SwfInfo;
+import flash.tools.debugger.Value;
+import flash.tools.debugger.Variable;
+import flash.tools.debugger.VersionException;
+import flash.tools.debugger.Watch;
+import flash.tools.debugger.expression.PlayerFaultException;
+
+/**
+ * Thread-safe wrapper for flash.tools.debugger.IsolateSession
+ * @author Anirudh Sasikumar
+ */
+public class ThreadSafeIsolateSession extends ThreadSafeDebuggerObject
+               implements IsolateSession {
+
+       private IsolateSession fSession;
+       
+       private ThreadSafeIsolateSession(Object syncObj, IsolateSession 
session) {
+               super(syncObj);
+               fSession = session;
+       }
+       
+       /**
+        * Wraps a Value inside a ThreadSafeValue.  If the passed-in Value
+        * is null, then this function returns null.
+        */
+       public static ThreadSafeIsolateSession wrap(Object syncObj, 
IsolateSession session) {
+               if (session != null)
+                       return new ThreadSafeIsolateSession(syncObj, session);
+               else
+                       return null;
+       }
+
+       @Override
+       public void resume() throws NotSuspendedException, 
NotConnectedException,
+                       NoResponseException {
+               synchronized (getSyncObject()) {
+                       fSession.resume();
+               }               
+       }
+
+       @Override
+       public void suspend() throws SuspendedException, NotConnectedException,
+                       NoResponseException {
+               synchronized (getSyncObject()) {
+                       fSession.suspend();
+               }
+               
+       }
+
+       @Override
+       public boolean isSuspended() throws NotConnectedException {
+               synchronized (getSyncObject()) {
+                       return fSession.isSuspended();
+               }
+       }
+
+       @Override
+       public int suspendReason() throws NotConnectedException {
+               synchronized (getSyncObject()) {
+                       return fSession.suspendReason();
+               }
+       }
+
+       public void stepOver() throws NotSuspendedException, 
NoResponseException,
+       NotConnectedException {
+               synchronized (getSyncObject()) {
+                       fSession.stepOver();
+               }
+       }
+
+       public void stepContinue() throws NotSuspendedException,
+       NoResponseException, NotConnectedException {
+               synchronized (getSyncObject()) {
+                       fSession.stepContinue();
+               }
+       }
+
+       public void stepInto() throws NotSuspendedException, 
NoResponseException,
+       NotConnectedException {
+               synchronized (getSyncObject()) {
+                       fSession.stepInto();
+               }
+       }
+
+       public void stepOut() throws NotSuspendedException, NoResponseException,
+       NotConnectedException {
+               synchronized (getSyncObject()) {
+                       fSession.stepOut();
+               }
+       }
+
+       @Override
+       public Frame[] getFrames() throws NotConnectedException {
+               synchronized (getSyncObject()) {
+                       return ThreadSafeFrame.wrapArray(getSyncObject(), 
fSession.getFrames());
+               }
+       }
+       
+       @Override
+       public boolean evalIs(Value value, Value type)
+                       throws PlayerDebugException, PlayerFaultException {
+               synchronized (getSyncObject()) {
+                       return fSession.evalIs(value, type);
+               }
+       }
+
+       @Override
+       public boolean evalIs(Value value, String type)
+                       throws PlayerDebugException, PlayerFaultException {
+               synchronized (getSyncObject()) {
+                       return fSession.evalIs(value, type);
+               }
+       }
+
+       @Override
+       public boolean evalInstanceof(Value value, Value type)
+                       throws PlayerDebugException, PlayerFaultException {
+               synchronized (getSyncObject()) {
+                       return fSession.evalInstanceof(value, type);
+               }
+       }
+
+       @Override
+       public boolean evalInstanceof(Value value, String type)
+                       throws PlayerDebugException, PlayerFaultException {
+               synchronized (getSyncObject()) {
+                       return fSession.evalInstanceof(value, type);
+               }
+       }
+
+       @Override
+       public boolean evalIn(Value property, Value object)
+                       throws PlayerDebugException, PlayerFaultException {
+               synchronized (getSyncObject()) {
+                       return fSession.evalIn(property, object);
+               }
+       }
+
+       @Override
+       public Value evalAs(Value value, Value type)
+                       throws PlayerDebugException, PlayerFaultException {
+               synchronized (getSyncObject()) {
+                       return ThreadSafeValue.wrap(getSyncObject(), 
fSession.evalAs(value, type));
+               }
+       }
+
+       @Override
+       public Value callConstructor(String classname, Value[] args) 
+                               throws PlayerDebugException {
+               synchronized (getSyncObject()) {
+                       return ThreadSafeValue.wrap(getSyncObject(), 
fSession.callConstructor(classname, args));
+               }
+       }
+
+       @Override
+       public Watch[] getWatchList()
+                       throws NoResponseException, NotConnectedException {
+               synchronized (getSyncObject()) {
+                       return ThreadSafeWatch.wrapArray(getSyncObject(), 
fSession.getWatchList());
+               }
+       }
+       
+       /** @deprecated */
+       public Variable[] getVariableList() throws NotSuspendedException,
+                       NoResponseException, NotConnectedException, 
VersionException {
+               synchronized (getSyncObject()) {
+                       return ThreadSafeVariable.wrapArray(getSyncObject(), 
fSession.getVariableList());
+               }
+       }
+
+       public Value callFunction(Value thisObject, String functionName, 
Value[] args)
+       throws PlayerDebugException {
+               synchronized (getSyncObject()) {
+                       return ThreadSafeValue.wrap(getSyncObject(), 
fSession.callFunction(thisObject, functionName, args));
+               }
+       }
+       
+       public Value getGlobal(String name) throws NotSuspendedException, 
NoResponseException, NotConnectedException
+       {
+               synchronized (getSyncObject())
+               {
+                       return ThreadSafeValue.wrap(getSyncObject(), 
fSession.getGlobal(name));
+               }
+       }
+       
+       public SwfInfo[] getSwfs() throws NoResponseException {
+               synchronized (getSyncObject()) {
+                       return ThreadSafeSwfInfo.wrapArray(getSyncObject(), 
fSession.getSwfs());
+               }
+       }
+
+       public Value getValue(long valueId) throws NotSuspendedException,
+       NoResponseException, NotConnectedException
+       {
+               synchronized (getSyncObject()) {
+                       return ThreadSafeValue.wrap(getSyncObject(), 
fSession.getValue(valueId));
+               }
+       }
+
+       public Location setBreakpoint(int fileId, int lineNum)
+       throws NoResponseException, NotConnectedException {
+               synchronized (getSyncObject()) {
+                       return ThreadSafeLocation.wrap(getSyncObject(), 
fSession.setBreakpoint(fileId, lineNum));
+               }
+       }
+
+       @Override
+       public boolean setExceptionBreakpoint(String exceptionClass)
+                       throws NoResponseException, NotConnectedException {
+               synchronized (getSyncObject()) {
+                       return fSession.setExceptionBreakpoint(exceptionClass); 
+               }
+       }
+
+       @Override
+       public boolean clearExceptionBreakpoint(String exceptionClass)
+                       throws NoResponseException, NotConnectedException {
+               synchronized (getSyncObject()) {
+                       return 
fSession.clearExceptionBreakpoint(exceptionClass); 
+               }
+       }
+
+       @Override
+       public void breakOnCaughtExceptions(boolean b)
+                       throws NotSupportedException, NoResponseException {
+               synchronized (getSyncObject()) {
+                       fSession.breakOnCaughtExceptions(b); 
+               }
+       }
+
+       @Override
+       public boolean supportsWatchpoints() {
+               synchronized (getSyncObject()) {
+                       return fSession.supportsWatchpoints(); 
+               }
+       }
+
+       @Override
+       public boolean playerCanBreakOnAllExceptions() {
+               synchronized (getSyncObject()) {
+                       return fSession.playerCanBreakOnAllExceptions(); 
+               }
+       }
+
+       @Override
+       public boolean supportsWideLineNumbers() {
+               synchronized (getSyncObject()) {
+                       return fSession.supportsWideLineNumbers();
+               }
+       }
+
+       @Override
+       public boolean playerCanCallFunctions() {
+               synchronized (getSyncObject()) {
+                       return fSession.playerCanCallFunctions();
+               }
+       }
+}

Reply via email to