// Path: src/main/java/com/madisp/stupid/context/VarContext.java
// public class VarContext extends BaseContext {
// 
// 	/**
// 	 * The type of the VarContext.
// 	 */
// 	public static enum Type {
// 		/**
// 		 * No variables can be created, the variable set is immutable.
// 		 */
// 		NO_CREATE,
// 		/**
// 		 * Variables can (and will be created) with assignment
// 		 */
// 		CREATE_ON_SET,
// 		/**
// 		 * Variables will be created when getting a value even if they don't
// 		 * exist yet. A bit weird but useful later on.
// 		 */
// 		CREATE_ON_SET_OR_GET
// 	}
// 	private final Type type;
// 	private final Var base;
// 
// 	/**
// 	 * Create a new immutable context with a set of variables.
// 	 * @param vars The String->Object (identifier->value) map of variables
// 	 */
// 	public VarContext(Map<String, Object> vars) {
// 		this(Type.NO_CREATE, vars);
// 	}
// 
// 	/**
// 	 * Create a new context with the given type and no starting variables.
// 	 * @param type The type of the context
// 	 */
// 	public VarContext(Type type) {
// 		this(type, null);
// 	}
// 
// 	/**
// 	 * Create a new context with the given type and a set of variables
// 	 * @param type The type of the context
// 	 * @param vars The String->Object (identifier->value) map of variables
// 	 */
// 	public VarContext(Type type, Map<String, Object> vars) {
// 		this.type = type;
// 		this.base = new Var(null);
// 		if (vars != null) {
// 			for (Map.Entry<String, Object> entry : vars.entrySet()) {
// 				base.put(entry.getKey(), entry.getValue());
// 			}
// 		}
// 	}
// 
// 	@Override
// 	public Object getFieldValue(Object root, String identifier) throws NoSuchFieldException {
// 		Var obj = base;
// 		if (root != null) {
// 			if (root instanceof Var) {
// 				obj = (Var)root;
// 			} else {
// 				throw new NoSuchFieldException();
// 			}
// 		}
// 
// 		if (!obj.has(identifier)) {
// 			if (type != Type.CREATE_ON_SET_OR_GET) {
// 				throw new NoSuchFieldException();
// 			}
// 			obj.put(identifier, null);
// 		}
// 		return obj.get(identifier);
// 	}
// 
// 	@Override
// 	public Object setFieldValue(Object root, String identifier, Object value) throws NoSuchFieldException {
// 		Var obj = base;
// 		if (root != null) {
// 			if (root instanceof Var) {
// 				obj = (Var)root;
// 			} else {
// 				throw new NoSuchFieldException();
// 			}
// 		}
// 
// 		if (!obj.has(identifier)) {
// 			if (type == Type.NO_CREATE) {
// 				throw new NoSuchFieldException();
// 			}
// 		}
// 		return obj.put(identifier, new Var(value));
// 	}
// 
// 	private static class Var implements Value {
// 		private Object value = null;
// 		private final Map<String, Var> vars;
// 
// 		private Var(Object value) {
// 			this.value = value;
// 			this.vars = new HashMap<String, Var>();
// 		}
// 
// 		private boolean has(String identifier) {
// 			return vars.containsKey(identifier);
// 		}
// 
// 		private Object get(String identifier) {
// 			return vars.get(identifier);
// 		}
// 
// 		private Object put(String identifier, Object value) {
// 			vars.put(identifier, new Var(value));
// 			return value;
// 		}
// 
// 		@Override
// 		public Object value(ExecContext ctx) {
// 			return value;
// 		}
// 	}
// }


import com.madisp.stupid.context.VarContext;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertNotNull;
package com.madisp.stupid;




public class VarScopeTest extends BaseExpressionTest {
	@Test
	public void testNoCreate() throws Exception {
		Map<String, Object> vars = new HashMap<String, Object>();
		vars.put("foo", "foo");
		vars.put("bar", "bar");

		ctx.pushExecContext(new VarContext(vars));
		assertNotNull(eval("foo"));
		assertEquals("foo", eval("foo"));
		assertNotNull(eval("bar"));
		assertEquals("bar", eval("bar"));
		assertNull(eval("foobar"));
		assertEquals("foobar", eval("foo + bar"));
		ctx.popExecContext();
	}

	@Test
	public void testCreateOnSet() throws Exception {
		ctx.pushExecContext(new VarContext(VarContext.Type.CREATE_ON_SET));

		assertNull(eval("foo"));
		assertEquals("foo", eval("foo = 'foo'"));
		assertNull(eval("bar"));
		assertEquals("bar", eval("bar = 'bar'"));
		assertEquals("foobar", eval("foo + bar"));

		ctx.popExecContext();
	}

	@Test
	public void testNestedCreates() throws Exception {
// Path: src/main/java/com/madisp/stupid/context/VarContext.java
// public class VarContext extends BaseContext {
// 
// 	/**
// 	 * The type of the VarContext.
// 	 */
// 	public static enum Type {
// 		/**
// 		 * No variables can be created, the variable set is immutable.
// 		 */
// 		NO_CREATE,
// 		/**
// 		 * Variables can (and will be created) with assignment
// 		 */
// 		CREATE_ON_SET,
// 		/**
// 		 * Variables will be created when getting a value even if they don't
// 		 * exist yet. A bit weird but useful later on.
// 		 */
// 		CREATE_ON_SET_OR_GET
// 	}
// 	private final Type type;
// 	private final Var base;
// 
// 	/**
// 	 * Create a new immutable context with a set of variables.
// 	 * @param vars The String->Object (identifier->value) map of variables
// 	 */
// 	public VarContext(Map<String, Object> vars) {
// 		this(Type.NO_CREATE, vars);
// 	}
// 
// 	/**
// 	 * Create a new context with the given type and no starting variables.
// 	 * @param type The type of the context
// 	 */
// 	public VarContext(Type type) {
// 		this(type, null);
// 	}
// 
// 	/**
// 	 * Create a new context with the given type and a set of variables
// 	 * @param type The type of the context
// 	 * @param vars The String->Object (identifier->value) map of variables
// 	 */
// 	public VarContext(Type type, Map<String, Object> vars) {
// 		this.type = type;
// 		this.base = new Var(null);
// 		if (vars != null) {
// 			for (Map.Entry<String, Object> entry : vars.entrySet()) {
// 				base.put(entry.getKey(), entry.getValue());
// 			}
// 		}
// 	}
// 
// 	@Override
// 	public Object getFieldValue(Object root, String identifier) throws NoSuchFieldException {
// 		Var obj = base;
// 		if (root != null) {
// 			if (root instanceof Var) {
// 				obj = (Var)root;
// 			} else {
// 				throw new NoSuchFieldException();
// 			}
// 		}
// 
// 		if (!obj.has(identifier)) {
// 			if (type != Type.CREATE_ON_SET_OR_GET) {
// 				throw new NoSuchFieldException();
// 			}
// 			obj.put(identifier, null);
// 		}
// 		return obj.get(identifier);
// 	}
// 
// 	@Override
// 	public Object setFieldValue(Object root, String identifier, Object value) throws NoSuchFieldException {
// 		Var obj = base;
// 		if (root != null) {
// 			if (root instanceof Var) {
// 				obj = (Var)root;
// 			} else {
// 				throw new NoSuchFieldException();
// 			}
// 		}
// 
// 		if (!obj.has(identifier)) {
// 			if (type == Type.NO_CREATE) {
// 				throw new NoSuchFieldException();
// 			}
// 		}
// 		return obj.put(identifier, new Var(value));
// 	}
// 
// 	private static class Var implements Value {
// 		private Object value = null;
// 		private final Map<String, Var> vars;
// 
// 		private Var(Object value) {
// 			this.value = value;
// 			this.vars = new HashMap<String, Var>();
// 		}
// 
// 		private boolean has(String identifier) {
// 			return vars.containsKey(identifier);
// 		}
// 
// 		private Object get(String identifier) {
// 			return vars.get(identifier);
// 		}
// 
// 		private Object put(String identifier, Object value) {
// 			vars.put(identifier, new Var(value));
// 			return value;
// 		}
// 
// 		@Override
// 		public Object value(ExecContext ctx) {
// 			return value;
// 		}
// 	}
// }


// Path: src/test/java/com/madisp/stupid/VarScopeTest.java
import com.madisp.stupid.context.VarContext;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertNotNull;

package com.madisp.stupid;




public class VarScopeTest extends BaseExpressionTest {
	@Test
	public void testNoCreate() throws Exception {
		Map<String, Object> vars = new HashMap<String, Object>();
		vars.put("foo", "foo");
		vars.put("bar", "bar");

		ctx.pushExecContext(new VarContext(vars));
		assertNotNull(eval("foo"));
		assertEquals("foo", eval("foo"));
		assertNotNull(eval("bar"));
		assertEquals("bar", eval("bar"));
		assertNull(eval("foobar"));
		assertEquals("foobar", eval("foo + bar"));
		ctx.popExecContext();
	}

	@Test
	public void testCreateOnSet() throws Exception {
		ctx.pushExecContext(new VarContext(VarContext.Type.CREATE_ON_SET));

		assertNull(eval("foo"));
		assertEquals("foo", eval("foo = 'foo'"));
		assertNull(eval("bar"));
		assertEquals("bar", eval("bar = 'bar'"));
		assertEquals("foobar", eval("foo + bar"));

		ctx.popExecContext();
	}

	@Test
	public void testNestedCreates() throws Exception {
		ctx.pushExecContext(new VarContext(VarContext.Type.CREATE_ON_SET_OR_GET));