diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Closure.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Closure.java
index 6268f8a..6110be1 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Closure.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Closure.java
@@ -18,42 +18,143 @@
  */
 package org.apache.felix.gogo.runtime.shell;
 
+import java.io.EOFException;
+import java.util.AbstractList;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 
+import org.apache.felix.gogo.runtime.shell.Tokenizer.Type;
 import org.osgi.service.command.CommandSession;
 import org.osgi.service.command.Function;
 
-public class Closure extends Reflective implements Function
+public class Closure extends Reflective implements Function, Evaluate
 {
-    private static final long serialVersionUID = 1L;
-    final CharSequence source;
-    final Closure parent;
-    CommandSessionImpl session;
-    List<Object> parms;
+    public static final String LOCATION = ".location";
 
-    Closure(CommandSessionImpl session, Closure parent, CharSequence source)
+    private static final long serialVersionUID = 1L;
+    private static final ThreadLocal<String> location = new ThreadLocal<String>();
+
+    private final CommandSessionImpl session;
+    private final Closure parent;
+    private final CharSequence source;
+    private final List<List<List<Token>>> program;
+    private final Object script;
+
+    private Token errTok;
+    private List<Object> parms = null;
+    private List<Object> parmv = null;
+
+    public Closure(CommandSessionImpl session, Closure parent, CharSequence source) throws Exception
     {
         this.session = session;
         this.parent = parent;
         this.source = source;
+        script = session.get("0"); // by convention, $0 is script name
+
+        try
+        {
+            program = new Parser(source).program();
+        }
+        catch (Exception e)
+        {
+            throw setLocation(e);
+        }
+    }
+    
+    public CommandSessionImpl session()
+    {
+        return session;
     }
 
+    private Exception setLocation(Exception e)
+    {
+        String loc = location.get();
+        if (null == loc)
+        {
+            loc = (null == script ? "" : script + ":");
+
+            if (e instanceof SyntaxError)
+            {
+                SyntaxError se = (SyntaxError) e;
+                loc += se.line() + "." + se.column();
+
+                if (e instanceof EOFError)
+                { // map to public exception, so interactive clients can provide more input
+                    EOFException eofe = new EOFException(e.getMessage());
+                    eofe.initCause(e);
+                    e = eofe;
+                }
+            }
+            else if (null != errTok)
+            {
+                loc += errTok.line + "." + errTok.column;
+            }
+
+            location.set(loc);
+        }
+        else if (null != script && !loc.contains(":"))
+        {
+            location.set(script + ":" + loc);
+        }
+
+        session.put(LOCATION, location.get());
+
+        return e;
+    }
+
+    // implements Function interface
+    // XXX: session arg x not used?
     public Object execute(CommandSession x, List<Object> values) throws Exception
     {
-        parms = values;
-        Parser parser = new Parser(source);
-        List<List<List<CharSequence>>> program = parser.program();
-        Pipe last = null;
+        try
+        {
+            location.remove();
+            session.variables.remove(LOCATION);
+            return execute(values);
+        }
+        catch (Exception e)
+        {
+            throw setLocation(e);
+        }
+    }
 
-        for (List<List<CharSequence>> pipeline : program)
+    @SuppressWarnings("unchecked")
+    private Object execute(List<Object> values) throws Exception
+    {
+        if (null != values)
+        {
+            parmv = values;
+            parms = new ArgList(parmv);
+        }
+        else if (null != parent)
+        {
+            // inherit parent closure parameters
+            parms = parent.parms;
+            parmv = parent.parmv;
+        }
+        else
+        {
+            // inherit session parameters
+            Object args = session.get("args");
+            if (null != args && args instanceof List<?>)
+            {
+                parmv = (List<Object>) args;
+                parms = new ArgList(parmv);
+            }
+        }
+
+        Pipe last = null;
+        Object[] mark = Pipe.mark();
+
+        for (List<List<Token>> pipeline : program)
         {
             ArrayList<Pipe> pipes = new ArrayList<Pipe>();
 
-            for (List<CharSequence> statement : pipeline)
+            for (List<Token> statement : pipeline)
             {
                 Pipe current = new Pipe(this, statement);
 
@@ -97,19 +198,22 @@
                 if (pipe.exception != null)
                 {
                     // can't throw exception, as result is defined by last pipe
-                    session.err.println("pipe: " + pipe.exception);
+                    Object oloc = session.get(LOCATION);
+                    String loc = (String.valueOf(oloc).contains(":") ? oloc + ": "
+                        : "pipe: ");
+                    session.err.println(loc + pipe.exception);
                     session.put("pipe-exception", pipe.exception);
                 }
             }
 
             if (last.exception != null)
             {
-                Pipe.reset();
+                Pipe.reset(mark);
                 throw last.exception;
             }
         }
 
-        Pipe.reset(); // reset IO in case sshd uses same thread for new client
+        Pipe.reset(mark); // reset IO in case same thread used for new client
 
         if (last == null)
         {
@@ -120,110 +224,180 @@
         {
             return Arrays.asList((Object[]) last.result);
         }
+
         return last.result;
     }
 
-    Object executeStatement(List<CharSequence> statement) throws Exception
+    public Object eval(final Token t) throws Exception
+    {
+        Object v = null;
+
+        switch (t.type)
+        {
+            case WORD:
+                v = Tokenizer.expand(t, this);
+                if (t == v)
+                {
+                    String s = t.toString();
+                    if ("null".equals(s))
+                        v = null;
+                    else if ("false".equals(s))
+                        v = false;
+                    else if ("true".equals(s))
+                        v = true;
+                    else
+                        v = s;
+                }
+                break;
+
+            case CLOSURE:
+                v = new Closure(session, this, t);
+                break;
+
+            case EXECUTION:
+                v = new Closure(session, this, t).execute(session, parms);
+                break;
+
+            case ARRAY:
+                v = array(t);
+                break;
+
+            case ASSIGN:
+                v = t.type;
+                break;
+
+            default:
+                throw new SyntaxError(t.line, t.column, "unexpected token: " + t.type);
+        }
+
+        return v;
+    }
+
+    public Object executeStatement(List<Token> statement) throws Exception
     {
         // add set -x facility if echo is set
         if (Boolean.TRUE.equals(session.get("echo")))
         {
             StringBuilder buf = new StringBuilder("+");
-            for (CharSequence token : statement)
+            for (Token token : statement)
             {
                 buf.append(' ');
-                buf.append(token);
+                buf.append(token.source());
             }
             session.err.println(buf);
         }
 
-        if (statement.size() == 1 && statement.get(0).charAt(0) == '(')
-        {
-            return eval(statement.get(0));
-        }
-
-        Object result;
         List<Object> values = new ArrayList<Object>();
-        for (CharSequence token : statement)
+        errTok = statement.get(0);
+
+        for (Token t : statement)
         {
-            Object v = eval(token);
-            if (v != null && v == parms)
+            Object v = eval(t);
+
+            if ((Type.EXECUTION == t.type) && (statement.size() == 1))
             {
-                for (Object p : parms)
-                {
-                    values.add(p);
-                }
+                return v;
+            }
+
+            if (parms == v && parms != null)
+            {
+                values.addAll(parms); // explode $args array
             }
             else
             {
                 values.add(v);
             }
         }
-        result = execute(values.remove(0), values);
-        return result;
-    }
 
-    private Object execute(Object cmd, List<Object> values) throws Exception
-    {
+        Object cmd = values.remove(0);
         if (cmd == null)
         {
             if (values.isEmpty())
             {
                 return null;
             }
-            else
-            {
-                throw new IllegalArgumentException("Command name evaluates to null");
-            }
+
+            throw new RuntimeException("Command name evaluates to null: " + errTok);
         }
 
+        return execute(cmd, values);
+    }
+
+    private Object execute(Object cmd, List<Object> values) throws Exception
+    {
         // Now there are the following cases
         // <string> '=' statement // complex assignment
         // <string> statement // cmd call
         // <object> // value of <object>
         // <object> statement // method call
 
-        if (cmd instanceof CharSequence)
+        boolean dot = values.size() > 1 && ".".equals(String.valueOf(values.get(0)));
+
+        if (cmd instanceof CharSequence && !dot)
         {
             String scmd = cmd.toString();
 
-            if (values.size() > 0 && "=".equals(values.get(0)))
+            if (values.size() > 0 && Type.ASSIGN.equals(values.get(0)))
             {
+                Object value;
+
                 if (values.size() == 1)
                 {
                     return session.variables.remove(scmd);
                 }
-                else if (values.size() == 2)
+
+                if (values.size() == 2)
                 {
-                    Object value = values.get(1);
-                    if (value instanceof CharSequence)
-                    {
-                        value = eval((CharSequence) value);
-                    }
-                    return assignment(scmd, value);
+                    value = values.get(1);
                 }
                 else
                 {
-                    Object value = execute(values.get(1),
-                        values.subList(2, values.size()));
-                    return assignment(scmd, value);
+                    value = execute(values.get(1), values.subList(2, values.size()));
                 }
+
+                return assignment(scmd, value);
             }
             else
             {
                 String scopedFunction = scmd;
                 Object x = get(scmd);
+
                 if (!(x instanceof Function))
                 {
                     if (scmd.indexOf(':') < 0)
                     {
                         scopedFunction = "*:" + scmd;
                     }
+
                     x = get(scopedFunction);
+
                     if (x == null || !(x instanceof Function))
                     {
-                        throw new IllegalArgumentException("Command not found:  "
-                            + scopedFunction);
+                        // try default command handler
+                        if (session.get(".default.lock") == null)
+                        {
+                            x = get("default");
+                            if (x == null)
+                            {
+                                x = get("*:default");
+                            }
+
+                            if (x instanceof Function)
+                            {
+                                try
+                                {
+                                    session.put(".default.lock", "active");
+                                    values.add(0, scmd);
+                                    return ((Function) x).execute(session, values);
+                                }
+                                finally
+                                {
+                                    session.variables.remove(".default.lock");
+                                }
+                            }
+                        }
+
+                        throw new IllegalArgumentException("Command not found: " + scmd);
                     }
                 }
                 return ((Function) x).execute(session, values);
@@ -235,6 +409,33 @@
             {
                 return cmd;
             }
+            else if (dot)
+            {
+                // FELIX-1473 - allow methods calls on String objects
+                Object target = cmd;
+                ArrayList<Object> args = new ArrayList<Object>();
+                values.remove(0);
+
+                for (Object arg : values)
+                {
+                    if (".".equals(arg))
+                    {
+                        target = method(session, target, args.remove(0).toString(), args);
+                        args.clear();
+                    }
+                    else
+                    {
+                        args.add(arg);
+                    }
+                }
+
+                if (args.size() == 0)
+                {
+                    return target;
+                }
+
+                return method(session, target, args.remove(0).toString(), args);
+            }
             else
             {
                 return method(session, cmd, values.remove(0).toString(), values);
@@ -248,241 +449,58 @@
         return value;
     }
 
-    private Object eval(CharSequence seq) throws Exception
+    private Object array(Token array) throws Exception
     {
-        Object res = null;
-        StringBuilder sb = null;
-        Parser p = new Parser(seq);
-        int start = p.current;
-        while (!p.eof())
-        {
-            char c = p.peek();
-            if (!p.escaped)
-            {
-                if (c == '$' || c == '(' || c == '\'' || c == '"' || c == '[' || c == '{')
-                {
-                    if (start != p.current || res != null)
-                    {
-                        if (sb == null)
-                        {
-                            sb = new StringBuilder();
-                        }
-                        if (res != null)
-                        {
-                            if (res == parms)
-                            {
-                                for (int i = 0; i < parms.size(); i++)
-                                {
-                                    if (i > 0)
-                                    {
-                                        sb.append(' ');
-                                    }
-                                    sb.append(parms.get(i));
-                                }
-                            }
-                            else
-                            {
-                                sb.append(res);
-                            }
-                            res = null;
-                        }
-                        if (start != p.current)
-                        {
-                            sb.append(new Parser(p.text.subSequence(start, p.current)).unescape());
-                            start = p.current;
-                            continue;
-                        }
-                    }
-                    switch (c)
-                    {
-                        case '\'':
-                            p.next();
-                            p.quote(c);
-                            res = new Parser(p.text.subSequence(start + 1, p.current - 1)).unescape();
-                            start = p.current;
-                            continue;
-                        case '\"':
-                            p.next();
-                            p.quote(c);
-                            res = eval(p.text.subSequence(start + 1, p.current - 1));
-                            start = p.current;
-                            continue;
-                        case '[':
-                            p.next();
-                            res = array(seq.subSequence(start + 1, p.find(']', '[') - 1));
-                            start = p.current;
-                            continue;
-                        case '(':
-                            p.next();
-                            Closure cl = new Closure(session, this, p.text.subSequence(
-                                start + 1, p.find(')', '(') - 1));
-                            res = cl.execute(session, parms);
-                            start = p.current;
-                            continue;
-                        case '{':
-                            p.next();
-                            res = new Closure(session, this, p.text.subSequence(
-                                start + 1, p.find('}', '{') - 1));
-                            start = p.current;
-                            continue;
-                        case '$':
-                            p.next();
-                            res = var(p.findVar());
-                            start = p.current;
-                            continue;
-                    }
-                }
-            }
-            p.next();
-        }
-        if (start != p.current)
-        {
-            if (sb == null)
-            {
-                sb = new StringBuilder();
-            }
-            if (res != null)
-            {
-                if (res == parms)
-                {
-                    for (Object v : parms)
-                    {
-                        sb.append(v);
-                    }
-                }
-                else
-                {
-                    sb.append(res);
-                }
-                res = null;
-            }
-            sb.append(new Parser(p.text.subSequence(start, p.current)).unescape());
-        }
-        if (sb != null)
-        {
-            if (res != null)
-            {
-                if (res == parms)
-                {
-                    for (int i = 0; i < parms.size(); i++)
-                    {
-                        if (i > 0)
-                        {
-                            sb.append(' ');
-                        }
-                        sb.append(parms.get(i));
-                    }
-                }
-                else
-                {
-                    sb.append(res);
-                }
-            }
-            res = sb;
-        }
-        if (res instanceof CharSequence)
-        {
-            String r = res.toString();
-            if ("null".equals(r))
-            {
-                return null;
-            }
-            else if ("false".equals(r))
-            {
-                return false;
-            }
-            else if ("true".equals(r))
-            {
-                return true;
-            }
-            return r;
-        }
+        List<Token> list = new ArrayList<Token>();
+        Map<Token, Token> map = new LinkedHashMap<Token, Token>();
+        (new Parser(array)).array(list, map);
 
-        return res;
-    }
-
-    private Object array(CharSequence array) throws Exception
-    {
-        List<Object> list = new ArrayList<Object>();
-        Map<Object, Object> map = new LinkedHashMap<Object, Object>();
-        Parser p = new Parser(array);
-
-        while (!p.eof())
+        if (map.isEmpty())
         {
-            CharSequence token = p.value();
-
-            p.ws();
-            if (p.peek() == '=')
+            List<Object> olist = new ArrayList<Object>();
+            for (Token t : list)
             {
-                p.next();
-                p.ws();
-                if (!p.eof())
-                {
-                    CharSequence value = p.messy();
-                    map.put(eval(token), eval(value));
-                }
+                olist.add(eval(t));
             }
-            else
-            {
-                list.add(eval(token));
-            }
-
-            if (p.peek() == ',')
-            {
-                p.next();
-            }
-            p.ws();
-        }
-        p.ws();
-        if (!p.eof())
-        {
-            throw new IllegalArgumentException("Invalid array syntax: " + array);
-        }
-
-        if (map.size() != 0 && list.size() != 0)
-        {
-            throw new IllegalArgumentException("You can not mix maps and arrays: "
-                + array);
-        }
-
-        if (map.size() > 0)
-        {
-            return map;
+            return olist;
         }
         else
         {
-            return list;
+            Map<Object, Object> omap = new LinkedHashMap<Object, Object>();
+            for (Entry<Token, Token> e : map.entrySet())
+            {
+                Token key = e.getKey();
+                Object k = eval(key);
+                if (!(k instanceof String))
+                {
+                    throw new SyntaxError(key.line, key.column,
+                        "map key null or not String: " + key);
+                }
+                omap.put(k, eval(e.getValue()));
+            }
+            return omap;
         }
     }
 
-    private Object var(CharSequence var) throws Exception
-    {
-        if (var.charAt(0) == '{')
-        {
-            var = var.subSequence(1, var.length() - 1);
-        }
-        Object v = eval(var);
-        String name = v.toString();
-        return get(name);
-    }
-
-    /**
-     * @param name
-     * @return
-     */
-    private Object get(String name)
+    public Object get(String name)
     {
         if (parms != null)
         {
-            if ("it".equals(name))
-            {
-                return parms.get(0);
-            }
             if ("args".equals(name))
             {
                 return parms;
             }
 
+            if ("argv".equals(name))
+            {
+                return parmv;
+            }
+
+            if ("it".equals(name))
+            {
+                return parms.get(0);
+            }
+
             if (name.length() == 1 && Character.isDigit(name.charAt(0)))
             {
                 int i = name.charAt(0) - '0';
@@ -492,6 +510,67 @@
                 }
             }
         }
+
         return session.get(name);
     }
+
+    public Object put(String key, Object value)
+    {
+        return session.variables.put(key, value);
+    }
+
+    @Override
+    public String toString()
+    {
+        return source.toString().trim().replaceAll("\n+", "\n").replaceAll(
+            "([^\\\\{(\\[])\n", "\\1;").replaceAll("[ \\\\\t\n]+", " ");
+    }
+
+    /**
+     * List that overrides toString() for implicit $args expansion.
+     * Also checks for index out of bounds, so that $1 evaluates to null
+     * rather than throwing IndexOutOfBoundsException.
+     * e.g. x = { a$args }; x 1 2 => a1 2 and not a[1, 2]
+     */
+    class ArgList extends AbstractList<Object>
+    {
+        private List<Object> list;
+
+        public ArgList(List<Object> args)
+        {
+            this.list = args;
+        }
+
+        @Override
+        public String toString()
+        {
+            StringBuilder buf = new StringBuilder();
+            for (Object o : list)
+            {
+                if (buf.length() > 0)
+                    buf.append(' ');
+                buf.append(o);
+            }
+            return buf.toString();
+        }
+
+        @Override
+        public Object get(int index)
+        {
+            return index < list.size() ? list.get(index) : null;
+        }
+
+        @Override
+        public Object remove(int index)
+        {
+            return list.remove(index);
+        }
+
+        @Override
+        public int size()
+        {
+            return list.size();
+        }
+    }
+
 }
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandSessionImpl.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandSessionImpl.java
index d1b76cc..1a26221 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandSessionImpl.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandSessionImpl.java
@@ -35,14 +35,14 @@
     public static final String VARIABLES = ".variables";
     public static final String COMMANDS = ".commands";
     private static final String COLUMN = "%-20s %s\n";
-    InputStream in;
-    PrintStream out;
+    protected InputStream in;
+    protected PrintStream out;
     PrintStream err;
     CommandShellImpl service;
-    final Map<Object, Object> variables = new HashMap<Object, Object>();
-    private boolean closed; // derek
+    protected final Map<String, Object> variables = new HashMap<String, Object>();
+    private boolean closed;
 
-    CommandSessionImpl(CommandShellImpl service, InputStream in, PrintStream out, PrintStream err)
+    protected CommandSessionImpl(CommandShellImpl service, InputStream in, PrintStream out, PrintStream err)
     {
         this.service = service;
         this.in = in;
@@ -52,7 +52,7 @@
 
     public void close()
     {
-        this.closed = true; // derek
+        this.closed = true;
     }
 
     public Object execute(CharSequence commandline) throws Exception
@@ -62,7 +62,7 @@
 
         if (closed)
         {
-            throw new IllegalStateException("session is closed"); // derek
+            throw new IllegalStateException("session is closed");
         }
 
         Closure impl = new Closure(this, null, commandline);
@@ -77,7 +77,6 @@
 
     public Object get(String name)
     {
-        // XXX: derek.baum@paremus.com
         // there is no API to list all variables, so overload name == null
         if (name == null || VARIABLES.equals(name))
         {
@@ -93,7 +92,7 @@
             return variables.get(name);
         }
 
-        // XXX: derek: add SCOPE support
+        // add SCOPE support
         if (name.startsWith("*:"))
         {
             String path = variables.containsKey("SCOPE") ? variables.get("SCOPE").toString()
@@ -353,4 +352,4 @@
             return "<can not format " + result + ":" + e;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandShellImpl.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandShellImpl.java
index 13a1665..aa6f0c0 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandShellImpl.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandShellImpl.java
@@ -37,7 +37,7 @@
     Set<Converter> converters = new HashSet<Converter>();
     protected ThreadIO threadIO;
     public final static Object NO_SUCH_COMMAND = new Object();
-    Map<String, Object> commands = new LinkedHashMap<String, Object>();
+    protected Map<String, Object> commands = new LinkedHashMap<String, Object>();
 
     public CommandShellImpl()
     {
@@ -219,4 +219,4 @@
         }
         return null;
     }
-}
\ No newline at end of file
+}
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/EOFError.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/EOFError.java
new file mode 100644
index 0000000..4965e0d
--- /dev/null
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/EOFError.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 org.apache.felix.gogo.runtime.shell;
+
+public class EOFError extends SyntaxError
+{
+    private static final long serialVersionUID = 1L;
+    
+    public EOFError(int line, int column, String message)
+    {
+        super(line, column, message);
+    }
+}
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Evaluate.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Evaluate.java
new file mode 100644
index 0000000..4111912
--- /dev/null
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Evaluate.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.gogo.runtime.shell;
+
+public interface Evaluate
+{
+    Object eval(Token t) throws Exception;
+    
+    Object get(String key);
+    
+    Object put(String key, Object value);
+}
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Parser.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Parser.java
index 6c915ce..de11bfd 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Parser.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Parser.java
@@ -22,421 +22,155 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.gogo.runtime.shell.Tokenizer.Type;
 
 public class Parser
 {
-    int current = 0;
-    CharSequence text;
-    boolean escaped;
-    static final String SPECIAL = "<;|{[\"'$`(=";
+    private final Tokenizer tz;
 
     public Parser(CharSequence program)
     {
-        text = program;
+        tz = new Tokenizer(program);
     }
 
-    void ws()
+    public List<List<List<Token>>> program()
     {
-        // derek: BUGFIX: loop if comment  at beginning of input
-        //while (!eof() && Character.isWhitespace(peek())) {
-        while (!eof() && (!escaped && Character.isWhitespace(peek()) || current == 0))
-        {
-            if (current != 0 || !escaped && Character.isWhitespace(peek()))
-            {
-                current++;
-            }
-            if (peek() == '/' && current < text.length() - 2
-                && text.charAt(current + 1) == '/')
-            {
-                comment();
-            }
-            if (current == 0)
-            {
-                break;
-            }
-        }
-    }
-
-    private void comment()
-    {
-        while (!eof() && peek() != '\n' && peek() != '\r')
-        {
-            next();
-        }
-    }
-
-    boolean eof()
-    {
-        return current >= text.length();
-    }
-
-    char peek()
-    {
-        return peek(false);
-    }
-
-    char peek(boolean increment)
-    {
-        escaped = false;
-        if (eof())
-        {
-            return 0;
-        }
-
-        int last = current;
-        char c = text.charAt(current++);
-
-        if (c == '\\')
-        {
-            escaped = true;
-            if (eof())
-            {
-                throw new RuntimeException("Eof found after \\"); // derek
-            }
-
-            c = text.charAt(current++);
-
-            switch (c)
-            {
-                case 't':
-                    c = '\t';
-                    break;
-                case '\r':
-                case '\n':
-                    c = ' ';
-                    break;
-                case 'b':
-                    c = '\b';
-                    break;
-                case 'f':
-                    c = '\f';
-                    break;
-                case 'n':
-                    c = '\n';
-                    break;
-                case 'r':
-                    c = '\r';
-                    break;
-                case 'u':
-                    c = unicode();
-                    current += 4;
-                    break;
-                default:
-                // We just take the next character literally
-                // but have the escaped flag set, important for {},[] etc
-            }
-        }
-        if (!increment)
-        {
-            current = last;
-        }
-        return c;
-    }
-
-    public List<List<List<CharSequence>>> program()
-    {
-        List<List<List<CharSequence>>> program = new ArrayList<List<List<CharSequence>>>();
-        ws();
-        if (!eof())
+        List<List<List<Token>>> program = new ArrayList<List<List<Token>>>();
+        
+        while (tz.next() != Type.EOT)
         {
             program.add(pipeline());
-            while (peek() == ';')
+            
+            switch (tz.type())
             {
-                current++;
-                List<List<CharSequence>> pipeline = pipeline();
-                if (pipeline.get(0).get(0).length() != 0)
-                {
-                    program.add(pipeline);
-                }
+                case SEMICOLON:
+                case NEWLINE:
+                    continue;
             }
+            
+            break;
         }
-        if (!eof())
-        {
-            throw new RuntimeException("Program has trailing text: " + context(current));
-        }
+
+        if (tz.next() != Type.EOT)
+            throw new RuntimeException("Program has trailing text: " + tz.value());
 
         return program;
     }
 
-    CharSequence context(int around)
+    private List<List<Token>> pipeline()
     {
-        return text.subSequence(Math.max(0, current - 20), Math.min(text.length(),
-            current + 4));
+        List<List<Token>> pipeline = new ArrayList<List<Token>>();
+        
+        while (true)
+        {
+            pipeline.add(command());
+            switch (tz.type())
+            {
+                case PIPE:
+                    if (tz.next() == Type.EOT)
+                    {
+                        Token t = tz.token();
+                        throw new EOFError(t.line, t.column, "unexpected EOT after pipe '|'");
+                    }
+                    break;
+
+                default:
+                    return pipeline;
+            }
+        }
     }
 
-    public List<List<CharSequence>> pipeline()
+    private List<Token> command()
     {
-        List<List<CharSequence>> statements = new ArrayList<List<CharSequence>>();
-        statements.add(statement());
-        while (peek() == '|')
+        List<Token> command = new ArrayList<Token>();
+
+        while (true)
         {
-            current++;
-            ws();
-            if (!eof())
+            Token t = tz.token();
+            
+            switch (t.type)
             {
-                statements.add(statement());
+                case WORD:
+                case CLOSURE:
+                case EXECUTION:
+                case ARRAY:
+                case ASSIGN:
+                    break;
+                    
+                default:
+                    throw new SyntaxError(t.line, t.column, "unexpected token: " + t.type);
+            }
+            
+            command.add(t);
+            
+            switch (tz.next())
+            {
+                case PIPE:
+                case SEMICOLON:
+                case NEWLINE:
+                case EOT:
+                    return command;
+            }
+        }
+    }
+    
+    public void array(List<Token> list, Map<Token, Token> map) throws Exception
+    {
+        Token lt = null;
+        boolean isMap = false;
+
+        while (tz.next() != Type.EOT)
+        {
+            if (isMap)
+            {
+                Token key = lt;
+                lt = null;
+                if (null == key)
+                {
+                    key = tz.token();
+
+                    if (tz.next() != Type.ASSIGN)
+                    {
+                        Token t = tz.token();
+                        throw new SyntaxError(t.line, t.column,
+                            "map expected '=', found: " + t);
+                    }
+
+                    tz.next();
+                }
+
+                Token k = (list.isEmpty() ? key : list.remove(0));
+                Token v = tz.token();
+                map.put(k, v);
             }
             else
             {
-                throw new RuntimeException("Eof found after pipe |");
-            }
-        }
-        return statements;
-    }
-
-    public List<CharSequence> statement()
-    {
-        List<CharSequence> statement = new ArrayList<CharSequence>();
-        statement.add(value());
-        while (!eof())
-        {
-            ws();
-            if (peek() == '|' || peek() == ';')
-            {
-                break;
-            }
-
-            if (!eof())
-            {
-                statement.add(messy());
-            }
-        }
-        return statement;
-    }
-
-    public CharSequence messy()
-    {
-        char c = peek();
-        if (c > 0 && SPECIAL.indexOf(c) < 0)
-        {
-            int start = current++;
-            while (!eof())
-            {
-                c = peek();
-                if (!escaped && (c == ';' || c == '|' || Character.isWhitespace(c)))
+                switch (tz.type())
                 {
-                    break;
-                }
-                next();
-            }
-            return text.subSequence(start, current);
-        }
-        else
-        {
-            return value();
-        }
-    }
+                    case WORD:
+                    case CLOSURE:
+                    case EXECUTION:
+                    case ARRAY:
+                        lt = tz.token();
+                        list.add(lt);
+                        break;
 
-    CharSequence value()
-    {
-        ws();
-
-        int start = current;
-        char c = next();
-        if (!escaped)
-        {
-            switch (c)
-            {
-                case '{':
-                    return text.subSequence(start, find('}', '{'));
-                case '(':
-                    return text.subSequence(start, find(')', '('));
-                case '[':
-                    return text.subSequence(start, find(']', '['));
-                case '<':
-                    return text.subSequence(start, find('>', '<'));
-                case '=':
-                    return text.subSequence(start, current);
-                case '"':
-                case '\'':
-                    quote(c);
-                    break;
-            }
-        }
-
-        // Some identifier or number
-        while (!eof())
-        {
-            c = peek();
-            if (!escaped)
-            {
-                if (Character.isWhitespace(c) || c == ';' || c == '|' || c == '=')
-                {
-                    break;
-                }
-                else if (c == '{')
-                {
-                    next();
-                    find('}', '{');
-                }
-                else if (c == '(')
-                {
-                    next();
-                    find(')', '(');
-                }
-                else if (c == '<')
-                {
-                    next();
-                    find('>', '<');
-                }
-                else if (c == '[')
-                {
-                    next();
-                    find(']', '[');
-                }
-                else if (c == '\'' || c == '"')
-                {
-                    next();
-                    quote(c);
-                    next();
-                }
-                else
-                {
-                    next();
-                }
-            }
-            else
-            {
-                next();
-            }
-        }
-        return text.subSequence(start, current);
-    }
-
-    boolean escaped()
-    {
-        return escaped;
-    }
-
-    char next()
-    {
-        return peek(true);
-    }
-
-    char unicode()
-    {
-        if (current + 4 > text.length())
-        {
-            throw new IllegalArgumentException("Unicode \\u escape at eof at pos ..."
-                + context(current) + "...");
-        }
-
-        String s = text.subSequence(current, current + 4).toString();
-        int n = Integer.parseInt(s, 16);
-        return (char) n;
-    }
-
-    int find(char target, char deeper)
-    {
-        int start = current;
-        int level = 1;
-
-        while (level != 0)
-        {
-            if (eof())
-            {
-                throw new RuntimeException("Eof found in the middle of a compound for '"
-                    + target + deeper + "', begins at " + context(start));
-            }
-
-            char c = next();
-            if (!escaped)
-            {
-                if (c == target)
-                {
-                    level--;
-                }
-                else
-                {
-                    if (c == deeper)
-                    {
-                        level++;
-                    }
-                    else
-                    {
-                        if (c == '"')
+                    case ASSIGN:
+                        if (list.size() == 1)
                         {
-                            quote('"');
+                            isMap = true;
+                            break;
                         }
-                        else
-                        {
-                            if (c == '\'')
-                            {
-                                quote('\'');
-                            }
-                            else
-                            {
-                                if (c == '`')
-                                {
-                                    quote('`');
-                                }
-                            }
-                        }
-                    }
+                        // fall through
+                    default:
+                        lt = tz.token();
+                        throw new SyntaxError(lt.line, lt.column,
+                            "unexpected token in list: " + lt);
                 }
             }
         }
-        return current;
     }
 
-    int quote(char which)
-    {
-        while (!eof() && (peek() != which || escaped))
-        {
-            next();
-        }
-
-        return current++;
-    }
-
-    CharSequence findVar()
-    {
-        int start = current;
-        char c = peek();
-
-        if (c == '{')
-        {
-            next();
-            int end = find('}', '{');
-            return text.subSequence(start, end);
-        }
-        if (c == '(')
-        {
-            next();
-            int end = find(')', '(');
-            return text.subSequence(start, end);
-        }
-
-        if (Character.isJavaIdentifierPart(c))
-        {
-            while (c == '$')
-            {
-                c = next();
-            }
-            while (!eof() && (Character.isJavaIdentifierPart(c) || c == '.') && c != '$')
-            {
-                next();
-                c = peek();
-            }
-            return text.subSequence(start, current);
-        }
-        throw new IllegalArgumentException(
-            "Reference to variable does not match syntax of a variable: "
-            + context(start));
-    }
-
-    public String toString()
-    {
-        return "..." + context(current) + "...";
-    }
-
-    public String unescape()
-    {
-        StringBuilder sb = new StringBuilder();
-        while (!eof())
-        {
-            sb.append(next());
-        }
-        return sb.toString();
-    }
-}
\ No newline at end of file
+}
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Pipe.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Pipe.java
index d25c085..237b044 100644
--- a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Pipe.java
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Pipe.java
@@ -39,16 +39,22 @@
     Closure closure;
     Exception exception;
     Object result;
-    List<CharSequence> statement;
+    List<Token> statement;
 
-    public static void reset()
+    public static Object[] mark()
     {
-        tIn.set(null);
-        tOut.set(null);
-        tErr.set(null);
+        Object[] mark = {tIn.get(), tOut.get(), tErr.get() };
+        return mark;
     }
 
-    public Pipe(Closure closure, List<CharSequence> statement)
+    public static void reset(Object[] mark)
+    {
+        tIn.set((InputStream) mark[0]);
+        tOut.set((PrintStream) mark[1]);
+        tErr.set((PrintStream) mark[2]);
+    }
+
+    public Pipe(Closure closure, List<Token> statement)
     {
         super("pipe-" + statement);
         this.closure = closure;
@@ -94,14 +100,17 @@
         tIn.set(in);
         tOut.set(out);
         tErr.set(err);
-        closure.session.service.threadIO.setStreams(in, out, err);
-
+        closure.session().service.threadIO.setStreams(in, out, err);
+        
         try
         {
             result = closure.executeStatement(statement);
             if (result != null && pout != null)
             {
-                out.println(closure.session.format(result, Converter.INSPECT));
+                if (!Boolean.FALSE.equals(closure.session().get(".FormatPipe")))
+                {
+                    out.println(closure.session().format(result, Converter.INSPECT));
+                }
             }
         }
         catch (Exception e)
@@ -111,7 +120,7 @@
         finally
         {
             out.flush();
-            closure.session.service.threadIO.close();
+            closure.session().service.threadIO.close();
 
             try
             {
@@ -130,4 +139,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/SyntaxError.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/SyntaxError.java
new file mode 100644
index 0000000..bbaea93
--- /dev/null
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/SyntaxError.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.gogo.runtime.shell;
+
+public class SyntaxError extends RuntimeException
+{
+    private static final long serialVersionUID = 1L;
+    private final int line;
+    private final int column;
+
+    public SyntaxError(int line, int column, String message)
+    {
+        super(message);
+        this.line = line;
+        this.column = column;
+    }
+    
+    public int column()
+    {
+        return column;
+    }
+
+    public int line()
+    {
+        return line;
+    }
+}
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Token.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Token.java
new file mode 100644
index 0000000..097bf0b
--- /dev/null
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Token.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.gogo.runtime.shell;
+
+import org.apache.felix.gogo.runtime.shell.Tokenizer.Type;
+
+public class Token implements CharSequence
+{
+    Type type; 
+    CharSequence value;
+    short line;
+    short column;
+    
+    public Token(Type type, CharSequence value, short line, short column)
+    {
+        this.type = type;
+        this.value = value;
+        this.line = line;
+        this.column = column;
+    }
+
+    @Override
+    public String toString()
+    {
+        //return type + "<" + value + ">";
+        return null == value ? type.toString() : value.toString();
+    }
+    
+    public char charAt(int index)
+    {
+        return  value.charAt(index);
+    }
+
+    public int length()
+    {
+        return (null == value ? 0 : value.length());
+    }
+
+    public CharSequence subSequence(int start, int end)
+    {
+        return value.subSequence(start, end);
+    }
+    
+    public String source()
+    {
+        switch (type)
+        {
+            case WORD:
+                return value.toString();
+                
+            case CLOSURE:
+                return "{" + value + "}";
+                
+            case EXECUTION:
+                return "(" + value + ")";
+                
+            case ARRAY:
+                return "[" + value + "]";
+                
+            default:
+                return type.toString();
+        }
+    }
+}
diff --git a/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Tokenizer.java b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Tokenizer.java
new file mode 100644
index 0000000..f70cbe0
--- /dev/null
+++ b/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Tokenizer.java
@@ -0,0 +1,755 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.gogo.runtime.shell;
+
+
+/**
+ * Bash-like tokenizer.
+ * 
+ * Single and double quotes are just like Bash - single quotes escape everything
+ * (including backslashes), newlines are allowed in quotes.
+ * backslash-newline indicates a line continuation and is removed.
+ * 
+ * Variable expansion is just like Bash: $NAME or ${NAME[[:][-+=?WORD]},
+ * except it can yield any Object. Variables expanded within double-quotes,
+ * or adjacent to a String are converted to String.
+ * 
+ * Unlike bash, indirect variable expansion is supported using ${$NAME}.
+ * 
+ * Only a single variable assignment is recognized, with '=' being the second token.
+ * (Bash allows name1=value1 name2=value2 ... command args)
+ * 
+ * Comments can only start where white space is allowed:
+ * # or // starts a line comment, /* starts a block comment.
+ * The following common uses do NOT start comments:
+ *    ls http://example.com#anchor
+ *    ls $dir/*.java
+ * 
+ * @see http://wiki.bash-hackers.org/syntax/basicgrammar
+ */
+public class Tokenizer
+{
+    public enum Type
+    {
+        ASSIGN('='), PIPE('|'), SEMICOLON(';'), NEWLINE, ARRAY, CLOSURE, EXECUTION, WORD, EOT;
+
+        private char c;
+
+        Type()
+        {
+        }
+
+        Type(char c)
+        {
+            this.c = c;
+        }
+
+        @Override
+        public String toString()
+        {
+            return (c == 0 ? super.toString() : "'" + c + "'");
+        }
+    }
+
+    private static final boolean DEBUG = false;
+    private static final char EOT = (char) -1;
+
+    private final CharSequence text;
+    private final Evaluate evaluate;
+    private final boolean inArray;
+    private final boolean inQuote;
+
+    private Type type = Type.NEWLINE;
+    private CharSequence value;
+    private Token token;
+
+    private short line;
+    private short column;
+    private char ch;
+    private int index;
+    private boolean firstWord;
+
+    public Tokenizer(CharSequence text)
+    {
+        this(text, null, false);
+    }
+
+    public Tokenizer(CharSequence text, Evaluate evaluate, boolean inQuote)
+    {
+        this.text = text;
+        this.evaluate = evaluate;
+        this.inQuote = inQuote;
+        index = 0;
+        line = column = 1;
+
+        boolean array = false;
+
+        if (text instanceof Token)
+        {
+            Token t = (Token) text;
+            line = t.line;
+            column = t.column;
+            array = (Type.ARRAY == t.type);
+        }
+
+        inArray = array;
+        getch();
+
+        if (DEBUG)
+        {
+            if (inArray)
+                System.err.println("Tokenizer[" + text + "]");
+            else
+                System.err.println("Tokenizer<" + text + ">");
+        }
+    }
+
+    public Type type()
+    {
+        return type;
+    }
+
+    public CharSequence value()
+    {
+        return value;
+    }
+
+    public Token token()
+    {
+        return token;
+    }
+
+    public Type next()
+    {
+        final Type prevType = type;
+        token = null;
+        value = null;
+
+        short tLine;
+        short tColumn;
+
+        while (true)
+        {
+            skipSpace();
+            tLine = line;
+            tColumn = column;
+
+            switch (ch)
+            {
+                case EOT:
+                    type = Type.EOT;
+                    break;
+
+                case '\n':
+                    getch();
+                    if (inArray)
+                        continue;
+                    // only return NEWLINE once and not if not preceded by ; or |
+                    switch (prevType)
+                    {
+                        case PIPE:
+                        case SEMICOLON:
+                        case NEWLINE:
+                            continue;
+
+                        default:
+                            type = Type.NEWLINE;
+                            break;
+                    }
+                    break;
+
+                case '{':
+                case '(':
+                case '[':
+                    value = group();
+                    getch();
+                    break;
+
+                case ';':
+                    getch();
+                    type = Type.SEMICOLON;
+                    break;
+
+                case '|':
+                    getch();
+                    type = Type.PIPE;
+                    break;
+
+                case '=':
+                    if (firstWord || inArray)
+                    {
+                        getch();
+                        type = Type.ASSIGN;
+                        break;
+                    }
+                    // fall through
+                default:
+                    value = word();
+                    type = Type.WORD;
+            }
+
+            firstWord = (Type.WORD == type && (Type.WORD != prevType && Type.ASSIGN != prevType));
+            token = new Token(type, value, tLine, tColumn);
+
+            if (DEBUG)
+            {
+                System.err.print("<" + type + ">");
+                if (Type.EOT == type)
+                {
+                    System.err.println();
+                }
+            }
+
+            return type;
+        }
+    }
+
+    private CharSequence word()
+    {
+        int start = index - 1;
+        int skipCR = 0;
+
+        do
+        {
+            switch (ch)
+            {
+                case '\n':
+                    if (index >= 2 && text.charAt(index - 2) == '\r')
+                        skipCR = 1;
+                    // fall through
+                case '=':
+                    if ((Type.WORD == type || Type.ASSIGN == type) && '=' == ch
+                        && !inArray)
+                        continue;
+                    // fall through
+                case ' ':
+                case '\t':
+                case '|':
+                case ';':
+                    return text.subSequence(start, index - 1 - skipCR);
+
+                case '{':
+                    group();
+                    break;
+
+                case '\\':
+                    escape();
+                    break;
+
+                case '\'':
+                case '"':
+                    skipQuote();
+                    break;
+            }
+        }
+        while (getch() != EOT);
+
+        return text.subSequence(start, index - 1);
+    }
+
+    private CharSequence group()
+    {
+        final char push = ch;
+        final char pop;
+
+        switch (ch)
+        {
+            case '{':
+                type = Type.CLOSURE;
+                pop = '}';
+                break;
+            case '(':
+                type = Type.EXECUTION;
+                pop = ')';
+                break;
+            case '[':
+                type = Type.ARRAY;
+                pop = ']';
+                break;
+            default:
+                assert false;
+                pop = 0;
+        }
+
+        short sLine = line;
+        short sCol = column;
+        int start = index;
+        int depth = 1;
+
+        while (true)
+        {
+            boolean comment = false;
+
+            switch (ch)
+            {
+                case '{':
+                case '(':
+                case '[':
+                case '\n':
+                    comment = true;
+                    break;
+            }
+
+            if (getch() == EOT)
+            {
+                throw new EOFError(sLine, sCol, "unexpected EOT looking for matching '"
+                    + pop + "'");
+            }
+
+            // don't recognize comments that start within a word
+            if (comment || isBlank(ch))
+                skipSpace();
+
+            switch (ch)
+            {
+                case '"':
+                case '\'':
+                    skipQuote();
+                    break;
+
+                case '\\':
+                    ch = escape();
+                    break;
+
+                default:
+                    if (push == ch)
+                        depth++;
+                    else if (pop == ch && --depth == 0)
+                        return text.subSequence(start, index - 1);
+            }
+        }
+
+    }
+
+    private char escape()
+    {
+        assert '\\' == ch;
+
+        switch (getch())
+        {
+            case 'u':
+                getch();
+                getch();
+                getch();
+                getch();
+
+                if (EOT == ch)
+                {
+                    throw new EOFError(line, column, "unexpected EOT in \\u escape");
+                }
+
+                String u = text.subSequence(index - 4, index).toString();
+
+                try
+                {
+                    return (char) Integer.parseInt(u, 16);
+                }
+                catch (NumberFormatException e)
+                {
+                    throw new SyntaxError(line, column, "bad unicode escape: \\u" + u);
+                }
+
+            case EOT:
+                throw new EOFError(line, column, "unexpected EOT in \\ escape");
+
+            case '\n':
+                return '\0'; // line continuation
+
+            case '\\':
+            case '\'':
+            case '"':
+            case '$':
+                return ch;
+
+            default:
+                return ch;
+        }
+    }
+
+    private void skipQuote()
+    {
+        assert '\'' == ch || '"' == ch;
+        final char quote = ch;
+        final short sLine = line;
+        final short sCol = column;
+
+        while (getch() != EOT)
+        {
+            if (quote == ch)
+                return;
+
+            if ((quote == '"') && ('\\' == ch))
+                escape();
+        }
+
+        throw new EOFError(sLine, sCol, "unexpected EOT looking for matching quote: "
+            + quote);
+    }
+
+    private void skipSpace()
+    {
+        while (true)
+        {
+            while (isBlank(ch))
+            {
+                getch();
+            }
+
+            // skip continuation lines, but not other escapes
+            if (('\\' == ch) && (peek() == '\n'))
+            {
+                getch();
+                getch();
+                continue;
+            }
+
+            // skip comments
+            if (('/' == ch) || ('#' == ch))
+            {
+                if (('#' == ch) || (peek() == '/'))
+                {
+                    while ((getch() != EOT) && ('\n' != ch))
+                    {
+                    }
+                    continue;
+                }
+                else if ('*' == peek())
+                {
+                    short sLine = line;
+                    short sCol = column;
+                    getch();
+
+                    while ((getch() != EOT) && !(('*' == ch) && (peek() == '/')))
+                    {
+                    }
+
+                    if (EOT == ch)
+                    {
+                        throw new EOFError(sLine, sCol,
+                            "unexpected EOT looking for closing comment: */");
+                    }
+
+                    getch();
+                    getch();
+                    continue;
+                }
+            }
+
+            break;
+        }
+    }
+
+    private boolean isBlank(char ch)
+    {
+        return ' ' == ch || '\t' == ch;
+    }
+
+    private boolean isName(char ch)
+    {
+        return Character.isJavaIdentifierPart(ch) && (ch != '$') || ('.' == ch);
+    }
+
+    /**
+     * expand variables, quotes and escapes in word.
+     * @param vars
+     * @return
+     */
+    public static Object expand(CharSequence word, Evaluate eval)
+    {
+        return expand(word, eval, false);
+    }
+
+    private static Object expand(CharSequence word, Evaluate eval,
+        boolean inQuote)
+    {
+        final String special = "$\\\"'";
+        int i = word.length();
+
+        while ((--i >= 0) && (special.indexOf(word.charAt(i)) == -1))
+        {
+        }
+
+        // shortcut if word doesn't contain any special characters
+        if (i < 0)
+            return word;
+
+        return new Tokenizer(word, eval, inQuote).expand();
+    }
+
+    public Object expand(CharSequence word, short line, short column)
+    {
+        return expand(new Token(Type.WORD, word, line, column), evaluate, inQuote);
+    }
+
+    private Token word(CharSequence value)
+    {
+        return new Token(Type.WORD, value, line, column);
+    }
+
+    private Object expand()
+    {
+        StringBuilder buf = new StringBuilder();
+
+        while (ch != EOT)
+        {
+            int start = index;
+
+            switch (ch)
+            {
+                case '$':
+                    Object val = expandVar();
+
+                    if (EOT == ch && buf.length() == 0)
+                    {
+                        return val;
+                    }
+
+                    if (null != val)
+                    {
+                        buf.append(val);
+                    }
+
+                    continue; // expandVar() has already read next char
+
+                case '\\':
+                    ch = (inQuote && ("u$\\\n\"".indexOf(peek()) == -1)) ? '\\'
+                        : escape();
+
+                    if (ch != '\0') // ignore line continuation
+                    {
+                        buf.append(ch);
+                    }
+
+                    break;
+
+                case '"':
+                    Token ww = word(null);
+                    skipQuote();
+                    ww.value = text.subSequence(start, index - 1);
+                    value = ww;
+                    Object expand = expand(value, evaluate, true);
+
+                    if (eot() && buf.length() == 0 && value.equals(expand))
+                    {
+                        return ww.value;
+                    }
+
+                    if (null != expand)
+                    {
+                        buf.append(expand.toString());
+                    }
+                    break;
+
+                case '\'':
+                    if (!inQuote)
+                    {
+                        skipQuote();
+                        value = text.subSequence(start, index - 1);
+
+                        if (eot() && buf.length() == 0)
+                        {
+                            return value;
+                        }
+
+                        buf.append(value);
+                        break;
+                    }
+                    // else fall through
+                default:
+                    buf.append(ch);
+            }
+
+            getch();
+        }
+
+        return buf.toString();
+    }
+
+    private Object expandVar()
+    {
+        assert '$' == ch;
+        Object val;
+
+        if (getch() != '{')
+        {
+            int start = index - 1;
+            while (isName(ch))
+            {
+                getch();
+            }
+
+            if (index - 1 == start)
+            {
+                val = "$";
+            }
+            else
+            {
+                String name = text.subSequence(start, index - 1).toString();
+                val = evaluate.get(name);
+            }
+        }
+        else
+        {
+            // ${NAME[[:]-+=?]WORD}
+            short sLine = line;
+            short sCol = column;
+            CharSequence group = group();
+            char c;
+            int i = 0;
+
+            while (i < group.length())
+            {
+                switch (group.charAt(i))
+                {
+                    case ':':
+                    case '-':
+                    case '+':
+                    case '=':
+                    case '?':
+                        break;
+
+                    default:
+                        ++i;
+                        continue;
+                }
+                break;
+            }
+
+            sCol += i;
+
+            String name = String.valueOf(expand(group.subSequence(0, i), sLine, sCol));
+
+            for (int j = 0; j < name.length(); ++j)
+            {
+                if (!isName(name.charAt(j)))
+                {
+                    throw new SyntaxError(sLine, sCol, "bad name: ${" + group + "}");
+                }
+            }
+
+            val = evaluate.get(name);
+
+            if (i < group.length())
+            {
+                c = group.charAt(i++);
+                if (':' == c)
+                {
+                    c = (i < group.length() ? group.charAt(i++) : EOT);
+                }
+
+                CharSequence word = group.subSequence(i, group.length());
+
+                switch (c)
+                {
+                    case '-':
+                    case '=':
+                        if (null == val)
+                        {
+                            val = expand(word, evaluate, false);
+                            if ('=' == c)
+                            {
+                                evaluate.put(name, val);
+                            }
+                        }
+                        break;
+
+                    case '+':
+                        if (null != val)
+                        {
+                            val = expand(word, evaluate, false);
+                        }
+                        break;
+
+                    case '?':
+                        if (null == val)
+                        {
+                            val = expand(word, evaluate, false);
+                            if (null == val || val.toString().length() == 0)
+                            {
+                                val = "parameter not set";
+                            }
+                            throw new IllegalArgumentException(name + ": " + val);
+                        }
+                        break;
+
+                    default:
+                        throw new SyntaxError(sLine, sCol, "bad substitution: ${" + group
+                            + "}");
+                }
+            }
+            getch();
+        }
+
+        return val;
+    }
+
+    /**
+     * returns true if getch() will return EOT
+     * @return
+     */
+    private boolean eot()
+    {
+        return index >= text.length();
+    }
+
+    private char getch()
+    {
+        return ch = getch(false);
+    }
+
+    private char peek()
+    {
+        return getch(true);
+    }
+
+    private char getch(boolean peek)
+    {
+        if (eot())
+        {
+            if (!peek)
+            {
+                ++index;
+                ch = EOT;
+            }
+            return EOT;
+        }
+
+        int current = index;
+        char c = text.charAt(index++);
+
+        if (('\r' == c) && !eot() && (text.charAt(index) == '\n'))
+            c = text.charAt(index++);
+
+        if (peek)
+        {
+            index = current;
+        }
+        else if ('\n' == c)
+        {
+            ++line;
+            column = 0;
+        }
+        else
+            ++column;
+
+        return c;
+    }
+
+}
diff --git a/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/Context.java b/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/Context.java
index afb8284..505713b 100644
--- a/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/Context.java
+++ b/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/Context.java
@@ -41,7 +41,16 @@
 
     public Object execute(CharSequence source) throws Exception
     {
-        return session.execute(source);
+        Object result = new Exception();
+        try
+        {
+            return result = session.execute(source);
+        }
+        finally
+        {
+            System.err.println("execute<" + source + "> = ("
+                + (null == result ? "Null" : result.getClass().getSimpleName()) + ")(" + result + ")\n");
+        }
     }
 
     public void addCommand(String name, Object target)
diff --git a/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestParser.java b/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestParser.java
index b75ec82..c18139d 100644
--- a/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestParser.java
+++ b/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestParser.java
@@ -126,14 +126,14 @@
         Context c = new Context();
         c.addCommand("echo", this);
         c.addCommand("grep", this);
-        assertEquals("a", c.execute("a = a; echo $$a"));
+        assertEquals("a", c.execute("a = a; echo ${$a}"));
 
         assertEquals("hello", c.execute("echo hello"));
         assertEquals("hello", c.execute("a = (echo hello)"));
-        assertEquals("a", c.execute("a = a; echo $(echo a)"));
+      //assertEquals("a", c.execute("a = a; echo $(echo a)")); // #p2 - no eval in var expansion
         assertEquals("3", c.execute("a=3; echo $a"));
         assertEquals("3", c.execute("a = 3; echo $a"));
-        assertEquals("a", c.execute("a = a; echo $$a"));
+        assertEquals("a", c.execute("a = a; echo ${$a}"));
     }
 
     public void testComment() throws Exception
@@ -149,12 +149,6 @@
         c.addCommand("echo", this);
         c.addCommand("capture", this);
 
-        assertEquals("http://www.aqute.biz?com=2&biz=1",
-            c.execute("['http://www.aqute.biz?com=2&biz=1'] get 0"));
-        assertEquals("{a=2, b=3}", c.execute("[a=2 b=3]").toString());
-        assertEquals("3", c.execute("[a=2 b=3] get b"));
-        assertEquals("[3, 4]", c.execute("[1 2 [3 4] 5 6] get 2").toString());
-        assertEquals(5, c.execute("[1 2 [3 4] 5 6] size"));
         assertEquals("a", c.execute("e = { echo $1 } ; e a   b"));
         assertEquals("b", c.execute("e = { echo $2 } ; e a   b"));
         assertEquals("b", c.execute("e = { $args } ; e echo  b"));
@@ -166,6 +160,7 @@
     public void testArray() throws Exception
     {
         Context c = new Context();
+        c.set("echo", true);
         assertEquals("http://www.aqute.biz?com=2&biz=1",
             c.execute("['http://www.aqute.biz?com=2&biz=1'] get 0"));
         assertEquals("{a=2, b=3}", c.execute("[a=2 b=3]").toString());
@@ -174,24 +169,15 @@
         assertEquals(5, c.execute("[1 2 [3 4] 5 6] size"));
     }
 
-    public void testEscape()
-    {
-        Parser parser = new Parser("'a|b;c'");
-        CharSequence cs = parser.messy();
-        assertEquals("'a|b;c'", cs.toString());
-        assertEquals("'a|b;c'", new Parser(cs).unescape());
-        assertEquals("$a", new Parser("\\$a").unescape());
-    }
-
     public void testParentheses()
     {
         Parser parser = new Parser("(a|b)|(d|f)");
-        List<List<List<CharSequence>>> p = parser.program();
-        assertEquals("(a|b)", p.get(0).get(0).get(0));
+        List<List<List<Token>>> p = parser.program();
+        assertEquals("a|b", p.get(0).get(0).get(0).toString());
 
         parser = new Parser("grep (d.*)|grep (d|f)");
         p = parser.program();
-        assertEquals("(d.*)", p.get(0).get(0).get(1));
+        assertEquals("d.*", p.get(0).get(0).get(1).toString());
     }
 
     public void testEcho() throws Exception
@@ -322,41 +308,42 @@
 
     public void testProgram()
     {
-        List<List<List<CharSequence>>> x = new Parser("abc def|ghi jkl;mno pqr|stu vwx").program();
-        assertEquals("abc", x.get(0).get(0).get(0));
-        assertEquals("def", x.get(0).get(0).get(1));
-        assertEquals("ghi", x.get(0).get(1).get(0));
-        assertEquals("jkl", x.get(0).get(1).get(1));
-        assertEquals("mno", x.get(1).get(0).get(0));
-        assertEquals("pqr", x.get(1).get(0).get(1));
-        assertEquals("stu", x.get(1).get(1).get(0));
-        assertEquals("vwx", x.get(1).get(1).get(1));
+        List<List<List<Token>>> x = new Parser("abc def|ghi jkl;mno pqr|stu vwx").program();
+        assertEquals("abc", x.get(0).get(0).get(0).toString());
+        assertEquals("def", x.get(0).get(0).get(1).toString());
+        assertEquals("ghi", x.get(0).get(1).get(0).toString());
+        assertEquals("jkl", x.get(0).get(1).get(1).toString());
+        assertEquals("mno", x.get(1).get(0).get(0).toString());
+        assertEquals("pqr", x.get(1).get(0).get(1).toString());
+        assertEquals("stu", x.get(1).get(1).get(0).toString());
+        assertEquals("vwx", x.get(1).get(1).get(1).toString());
     }
 
     public void testStatements()
     {
-        List<List<CharSequence>> x = new Parser("abc def|ghi jkl|mno pqr").pipeline();
-        assertEquals("abc", x.get(0).get(0));
-        assertEquals("def", x.get(0).get(1));
-        assertEquals("ghi", x.get(1).get(0));
-        assertEquals("jkl", x.get(1).get(1));
-        assertEquals("mno", x.get(2).get(0));
-        assertEquals("pqr", x.get(2).get(1));
+        List<List<Token>> x = new Parser("abc def|ghi jkl|mno pqr").program().get(0);
+        assertEquals("abc", x.get(0).get(0).toString());
+        assertEquals("def", x.get(0).get(1).toString());
+        assertEquals("ghi", x.get(1).get(0).toString());
+        assertEquals("jkl", x.get(1).get(1).toString());
+        assertEquals("mno", x.get(2).get(0).toString());
+        assertEquals("pqr", x.get(2).get(1).toString());
     }
 
     public void testSimpleValue()
     {
-        List<CharSequence> x = new Parser(
-            "abc def.ghi http://www.osgi.org?abc=&x=1 [1,2,3] {{{{{{{xyz}}}}}}} (immediate) {'{{{{{'} {\\}} 'abc{}'").statement();
-        assertEquals("abc", x.get(0));
-        assertEquals("def.ghi", x.get(1));
-        assertEquals("http://www.osgi.org?abc=&x=1", x.get(2));
-        assertEquals("[1,2,3]", x.get(3));
-        assertEquals("{{{{{{{xyz}}}}}}}", x.get(4));
-        assertEquals("(immediate)", x.get(5));
-        assertEquals("{'{{{{{'}", x.get(6));
-        assertEquals("{\\}}", x.get(7));
-        assertEquals("'abc{}'", x.get(8));
+        List<Token> x = new Parser(
+            "abc def.ghi http://www.osgi.org?abc=&x=1 [1,2,3] {{{{{{{xyz}}}}}}} (immediate) {'{{{{{'} {\\{} 'abc{}'")
+            .program().get(0).get(0);
+        assertEquals("abc", x.get(0).toString());
+        assertEquals("def.ghi", x.get(1).toString());
+        assertEquals("http://www.osgi.org?abc=&x=1", x.get(2).toString());
+        assertEquals("1,2,3", x.get(3).toString());
+        assertEquals("{{{{{{xyz}}}}}}", x.get(4).toString());
+        assertEquals("immediate", x.get(5).toString());
+        assertEquals("'{{{{{'", x.get(6).toString());
+        assertEquals("\\{", x.get(7).toString());
+        assertEquals("'abc{}'", x.get(8).toString());
     }
 
     void each(CommandSession session, Collection<Object> list, Function closure)
diff --git a/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestParser2.java b/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestParser2.java
new file mode 100644
index 0000000..175a8fd
--- /dev/null
+++ b/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestParser2.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.gogo.runtime.shell;
+
+import java.io.EOFException;
+
+import junit.framework.TestCase;
+
+/*
+ * Test features of the new parser/tokenizer, many of which are not supported
+ * by the original parser.
+ */
+public class TestParser2 extends TestCase
+{
+    public void testComment() throws Exception
+    {
+        Context c = new Context();
+        c.addCommand("echo", this);
+
+        assertEquals("file://wibble#tag", c.execute("echo file://wibble#tag"));
+        assertEquals("file:", c.execute("echo file: //wibble#tag"));
+        
+        assertEquals("PWD/*.java", c.execute("echo PWD/*.java"));
+        try
+        {
+            c.execute("echo PWD /*.java");
+            fail("expected EOFException");
+        }
+        catch (EOFException e)
+        {
+            // expected
+        }
+        
+        assertEquals("ok", c.execute("// can't quote\necho ok\n"));
+        
+        // quote in comment in closure
+        assertEquals("ok", c.execute("x = { // can't quote\necho ok\n}; x"));
+        assertEquals("ok", c.execute("x = {\n// can't quote\necho ok\n}; x"));
+        assertEquals("ok", c.execute("x = {// can't quote\necho ok\n}; x"));
+    }
+
+    public CharSequence echo(Object args[])
+    {
+        if (args == null)
+        {
+            return "";
+        }
+
+        StringBuilder sb = new StringBuilder();
+        for (Object arg : args)
+        {
+            if (arg != null)
+            {
+                if (sb.length() > 0)
+                    sb.append(' ');
+                sb.append(arg);
+            }
+        }
+        return sb.toString();
+    }
+
+}
diff --git a/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestTokenizer.java b/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestTokenizer.java
new file mode 100644
index 0000000..714a45c
--- /dev/null
+++ b/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestTokenizer.java
@@ -0,0 +1,277 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.gogo.runtime.shell;
+
+import java.io.File;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.naming.OperationNotSupportedException;
+
+import org.apache.felix.gogo.runtime.shell.Tokenizer.Type;
+
+import junit.framework.TestCase;
+
+public class TestTokenizer extends TestCase
+{
+    private final Map<String, Object> vars = new HashMap<String, Object>();
+    private final Evaluate evaluate;
+
+    public TestTokenizer()
+    {
+        evaluate = new Evaluate()
+        {
+            public Object eval(Token t) throws Exception
+            {
+                throw new OperationNotSupportedException();
+            }
+
+            public Object get(String key)
+            {
+                return vars.get(key);
+            }
+
+            public Object put(String key, Object value)
+            {
+                return vars.put(key, value);
+            }
+        };
+    }
+
+    public void testHello() throws Exception
+    {
+        testHello("hello world\n");
+        testHello("hello world\n\n"); // multiple \n reduced to single Token.NL
+        testHello("hello world\r\n"); // \r\n -> \n
+
+        // escapes
+
+        testHello("hello \\\nworld\n");
+        try
+        {
+            testHello("hello\\u20world\n");
+            fail("bad unicode accepted");
+        }
+        catch (SyntaxError e)
+        {
+            // expected
+        }
+
+        // whitespace and comments
+
+        testHello(" hello  world    \n ");
+        testHello("hello world // comment\n\n");
+        testHello("hello world #\\ comment\n\n");
+        testHello("// comment\nhello world\n");
+        testHello("// comment ?\\ \nhello world\n");
+        testHello("hello /*\n * comment\n */ world\n");
+    }
+
+    // hello world
+    private void testHello(CharSequence text) throws Exception
+    {
+        Tokenizer t = new Tokenizer(text);
+        assertEquals(Type.WORD, t.next());
+        assertEquals("hello", t.value().toString());
+        assertEquals(Type.WORD, t.next());
+        assertEquals("world", t.value().toString());
+        assertEquals(Type.NEWLINE, t.next());
+        assertEquals(Type.EOT, t.next());
+    }
+
+    public void testString() throws Exception
+    {
+        testString("'single $quote' \"double $quote\"\n");
+    }
+
+    // 'single quote' "double quote"
+    private void testString(CharSequence text) throws Exception
+    {
+        Tokenizer t = new Tokenizer(text);
+        assertEquals(Type.WORD, t.next());
+        assertEquals("'single $quote'", t.value().toString());
+        assertEquals(Type.WORD, t.next());
+        assertEquals("\"double $quote\"", t.value().toString());
+        assertEquals(Type.NEWLINE, t.next());
+        assertEquals(Type.EOT, t.next());
+    }
+
+    public void testClosure() throws Exception
+    {
+        testClosure2("x = { echo '}' $args //comment's\n}\n");
+        testClosure2("x={ echo '}' $args //comment's\n}\n");
+        assertEquals(Type.CLOSURE, token1("{ echo \\{ $args \n}"));
+        assertEquals(Type.CLOSURE, token1("{ echo \\} $args \n}"));
+    }
+
+    /*
+     * x = {echo $args};
+     */
+    private void testClosure2(CharSequence text) throws Exception
+    {
+        Tokenizer t = new Tokenizer(text);
+        assertEquals(Type.WORD, t.next());
+        assertEquals("x", t.value().toString());
+        assertEquals(Type.ASSIGN, t.next());
+        assertEquals(Type.CLOSURE, t.next());
+        assertEquals(" echo '}' $args //comment's\n", t.value().toString());
+        assertEquals(Type.NEWLINE, t.next());
+        assertEquals(Type.EOT, t.next());
+    }
+
+    private Type token1(CharSequence text) throws Exception
+    {
+        Tokenizer t = new Tokenizer(text);
+        Type type = t.next();
+        assertEquals(Type.EOT, t.next());
+        return type;
+    }
+
+    public void testExpand() throws Exception
+    {
+        final URI home = new URI("/home/derek");
+        final File pwd = new File("/tmp");
+        final String user = "derek";
+
+        vars.clear();
+        vars.put("HOME", home);
+        vars.put("PWD", pwd);
+        vars.put("USER", user);
+        vars.put(user, "Derek Baum");
+
+        // quote removal
+        assertEquals("hello", expand("hello"));
+        assertEquals("hello", expand("'hello'"));
+        assertEquals("\"hello\"", expand("'\"hello\"'"));
+        assertEquals("hello", expand("\"hello\""));
+        assertEquals("'hello'", expand("\"'hello'\""));
+
+        // escapes
+        assertEquals("hello\\w", expand("hello\\\\w"));
+        assertEquals("hellow", expand("hello\\w"));
+        assertEquals("hello\\w", expand("\"hello\\\\w\""));
+        assertEquals("hello\\w", expand("\"hello\\w\""));
+        assertEquals("hello\\\\w", expand("'hello\\\\w'"));
+        assertEquals("hello", expand("he\\\nllo"));
+        assertEquals("he\\llo", expand("'he\\llo'"));
+        assertEquals("he'llo", expand("'he'\\''llo'"));
+        assertEquals("he\"llo", expand("\"he\\\"llo\""));
+        assertEquals("he'llo", expand("he\\'llo"));
+        assertEquals("he$llo", expand("\"he\\$llo\""));
+        assertEquals("he\\'llo", expand("\"he\\'llo\""));
+        assertEquals("hello\\w", expand("\"hello\\w\""));
+
+        // unicode
+
+        // Note: we could use literal Unicode pound '£' instead of \u00a3 in next test.
+        // if above is not UK currency symbol, then your locale is not configured for UTF-8.
+        // Java on Macs cannot handle UTF-8 unless you explicitly set '-Dfile.encoding=UTF-8'.
+        assertEquals("pound\u00a3cent\u00a2", expand("pound\\u00a3cent\\u00a2"));
+        assertEquals("euro\\u20ac", expand("'euro\\u20ac'"));
+        try
+        {
+            expand("eot\\u20a");
+            fail("EOT in unicode");
+        }
+        catch (SyntaxError e)
+        {
+            // expected
+        }
+        try
+        {
+            expand("bad\\u20ag");
+            fail("bad unicode");
+        }
+        catch (SyntaxError e)
+        {
+            // expected
+        }
+
+        // simple variable expansion - quoting or concatenation converts result to String
+        assertEquals(user, expand("$USER"));
+        assertEquals(home, expand("$HOME"));
+        assertEquals(home.toString(), expand("$HOME$W"));
+        assertEquals(pwd, expand("$PWD"));
+        assertEquals("$PWD", expand("'$PWD'"));
+        assertEquals("$PWD", expand("\\$PWD"));
+        assertEquals(pwd.toString(), expand("\"$PWD\""));
+        assertEquals("W" + pwd, expand("W$PWD"));
+        assertEquals(pwd + user, expand("$PWD$USER"));
+
+        // variable substitution  ${NAME:-WORD} etc
+        assertNull(expand("$JAVA_HOME"));
+        assertEquals(user, expand("${USER}"));
+        assertEquals(user + "W", expand("${USER}W"));
+        assertEquals("java_home", expand("${JAVA_HOME:-java_home}"));
+        assertEquals(pwd, expand("${NOTSET:-$PWD}"));
+        assertNull(vars.get("JAVA_HOME"));
+        assertEquals("java_home", expand("${JAVA_HOME:=java_home}"));
+        assertEquals("java_home", vars.get("JAVA_HOME"));
+        assertEquals("java_home", expand("$JAVA_HOME"));
+        assertEquals("yes", expand("${JAVA_HOME:+yes}"));
+        assertNull(expand("${NOTSET:+yes}"));
+        assertEquals("", expand("\"${NOTSET:+yes}\""));
+        try
+        {
+            expand("${NOTSET:?}");
+            fail("expected 'not set' exception");
+        }
+        catch (IllegalArgumentException e)
+        {
+            // expected
+        }
+
+        // bad variable names
+        assertEquals("$ W", expand("$ W"));
+        assertEquals("$ {W}", expand("$ {W}"));
+        try
+        {
+            expand("${W }");
+            fail("expected syntax error");
+        }
+        catch (SyntaxError e)
+        {
+            // expected
+        }
+
+        assertEquals(user, expand("${USER\\\n:?}"));
+        assertEquals(user, expand("${US\\u0045R:?}"));
+
+        // bash doesn't supported nested expansions
+        // gogo only supports them in the ${} syntax
+        assertEquals("Derek Baum", expand("${$USER}"));
+        assertEquals("x", expand("${$USR:-x}"));
+        assertEquals("$" + user, expand("$$USER"));
+    }
+
+    private Object expand(CharSequence word) throws Exception
+    {
+        return Tokenizer.expand(word, evaluate);
+    }
+
+    public void testParser() throws Exception
+    {
+        new Parser("// comment\n" + "a=\"who's there?\"; ps -ef;\n" + "ls | \n grep y\n").program();
+        String p1 = "a=1 \\$b=2 c={closure}\n";
+        new Parser(p1).program();
+        new Parser(new Token(Type.ARRAY, p1, (short) 0, (short) 0)).program();
+    }
+
+}
