output: #fixed code
                                  public Object execute(Object ctx, Map tokens, TemplateRegistry registry) {
  
          if (nodes == null) {
              return new String(expression);
          }
          else if (nodes.length == 2) {
              /**
               * This is an optimization for property expressions.
               */
              switch (nodes[0].getToken()) {
                  case PROPERTY_EX:
                      //noinspection unchecked
                      if (CACHE_DISABLE || !cacheAggressively) {
                          char[] seg = new char[expression.length - 3];
                          //      arraycopy(expression, 2, seg, 0, seg.length);
                          for (int i = 0; i < seg.length; i++)
                              seg[i] = expression[i + 2];
  
                          return MVEL.eval(seg, ctx, tokens);
                      }
                      else {
                          String s = new String(expression, 2, expression.length - 3);
                          if (!EX_PRECOMP_CACHE.containsKey(s)) {
                              synchronized (EX_PRECOMP_CACHE) {
                                  EX_PRECOMP_CACHE.put(s, compileExpression(s));
                                  return executeExpression(EX_PRECOMP_CACHE.get(s), ctx, tokens);
                              }
                          }
                          else {
                              return executeExpression(EX_PRECOMP_CACHE.get(s), ctx, tokens);
                          }
  
                      }
                  case LITERAL:
                      return new String(expression);
  
              }
  
              return new String(expression);
          }
  
          Object register = null;
  
          StringAppender sbuf = new StringAppender(10);
          Node currNode = null;
  
          try {
              //noinspection unchecked
              MVELInterpretedRuntime oParser = new MVELInterpretedRuntime(ctx, tokens);
  
              initStack();
              pushAndForward();
  
              while ((currNode = pop()) != null) {
                  node = currNode.getNode();
  
                  switch (currNode.getToken()) {
                      case LITERAL: {
                          sbuf.append(register = new String(expression, currNode.getStartPos(),
                                  currNode.getEndPos() - currNode.getStartPos()));
                          break;
                      }
                      case PROPERTY_EX: {
                          sbuf.append(
                                  valueOf(register = oParser.setExpressionArray(getInternalSegment(currNode)).parse())
                          );
                          break;
                      }
                      case IF:
                      case ELSEIF: {
                          try {
                              if (!((Boolean) oParser.setExpressionArray(getInternalSegment(currNode)).parse())) {
                                  exitContext();
                              }
                          }
                          catch (ClassCastException e) {
                              throw new CompileException("IF expression does not return a boolean: " + new String(getSegment(currNode)));
                          }
                          break;
                      }
                      case FOREACH: {
  
                          if (tokens == null) {
                              tokens = new HashMap();
                          }
  
                          ForeachContext foreachContext;
                          String[] names;
                          String[] aliases;
  
                          if (!(localStack.peek() instanceof ForeachContext)) {
  
                              // create a clone of the context
                              foreachContext = ((ForeachContext) currNode.getRegister()).clone();
                              names = foreachContext.getNames();
                              aliases = foreachContext.getAliases();
  
                              try {
                                  Iterator[] iters = new Iterator[names.length];
                                  for (int i = 0; i < names.length; i++) {
                                      //noinspection unchecked
                                      Object listObject = new MVELInterpretedRuntime(names[i], ctx, tokens).parse();
                                      if (listObject instanceof Object[]) {
                                          listObject = Arrays.asList((Object[]) listObject);
                                      }
  
  
                                      iters[i] = ((Collection) listObject).iterator(); // this throws null pointer exception in thread race
                                  }
  
                                  // set the newly created iterators into the context
                                  foreachContext.setIterators(iters);
  
                                  // push the context onto the local stack.
                                  localStack.push(foreachContext);
                              }
                              catch (ClassCastException e) {
                                  throw new CompileException("expression for collections does not return a collections object: " + new String(getSegment(currNode)), e);
                              }
                              catch (NullPointerException e) {
                                  throw new CompileException("null returned for foreach in expression: " + (getForEachSegment(currNode)), e);
                              }
                          }
                          else {
                              foreachContext = (ForeachContext) localStack.peek();
                        //      names = foreachContext.getNames();
                              aliases = foreachContext.getAliases();
                          }
  
                          Iterator[] iters = foreachContext.getItererators();
  
  
                          if (iters[0].hasNext()) {
                              push();
  
                              //noinspection unchecked
                              for (int i = 0; i < iters.length; i++) {
  
                                  //noinspection unchecked
                                  tokens.put(aliases[i], iters[i].next());
                              }
  
  
                              int c;
                              tokens.put("i0", c = foreachContext.getCount());
  
                              if (c != 0) {
                                  sbuf.append(foreachContext.getSeperator());
                              }
                              //noinspection unchecked
                              foreachContext.incrementCount();
                          }
                          else {
                              for (int i = 0; i < iters.length; i++) {
                                  tokens.remove(aliases[i]);
                              }
                       //       foreachContext.setIterators(null);
                       //       foreachContext.setCount(0);
                              localStack.pop();
                              exitContext();
                          }
                          break;
                      }
                      case ELSE:
                      case END:
                          if (stack.isEmpty()) forwardAndPush();
                          continue;
                      case GOTO:
                          pushNode(currNode.getEndNode());
                          continue;
                      case TERMINUS: {
                          if (nodes.length != 2) {
                              return sbuf.toString();
                          }
                          else {
                              return register;
                          }
                      }
                      case INCLUDE_BY_REF: {
                          IncludeRef includeRef = (IncludeRef) nodes[node].getRegister();
  
                          IncludeRefParam[] params = includeRef.getParams();
                          Map<String, Object> vars = new HashMap<String, Object>(params.length * 2);
                          for (IncludeRefParam param : params) {
                              vars.put(param.getIdentifier(), MVEL.eval(param.getValue(), ctx, tokens));
                          }
  
                          if (registry == null) {
                              throw new CompileException("No TemplateRegistry specified, cannot load template='" + includeRef.getName() + "'");
                          }
                          String template = registry.getTemplate(includeRef.getName());
  
                          if (template == null) {
                              throw new CompileException("Template does not exist in the TemplateRegistry, cannot load template='" + includeRef.getName() + "'");
                          }
  
                          sbuf.append(TemplateInterpreter.parse(template, ctx, vars, registry));
                      }
                  }
  
                  forwardAndPush();
              }
              throw new CompileException("expression did not end properly: expected TERMINUS node");
          }
          catch (CompileException e) {
              throw e;
          }
          catch (Exception e) {
              if (currNode != null) {
                  throw new CompileException("problem encountered at node [" + currNode.getNode() + "] "
                          + currNode.getToken() + "{" + currNode.getStartPos() + "," + currNode.getEndPos() + "}: " + e.getMessage(), e);
              }
              throw new CompileException("unhandled fatal exception (node:" + node + ")", e);
          }
  
      }
input: #vulnerable code 
                                  public Object execute(Object ctx, Map tokens, TemplateRegistry registry) {
  
          if (nodes == null) {
              return new String(expression);
          }
          else if (nodes.length == 2) {
              /**
               * This is an optimization for property expressions.
               */
              switch (nodes[0].getToken()) {
                  case PROPERTY_EX:
                      //noinspection unchecked
                      if (CACHE_DISABLE || !cacheAggressively) {
                          char[] seg = new char[expression.length - 3];
                          //      arraycopy(expression, 2, seg, 0, seg.length);
                          for (int i = 0; i < seg.length; i++)
                              seg[i] = expression[i + 2];
  
                          return MVEL.eval(seg, ctx, tokens);
                      }
                      else {
                          String s = new String(expression, 2, expression.length - 3);
                          if (!EX_PRECOMP_CACHE.containsKey(s)) {
                              synchronized (EX_PRECOMP_CACHE) {
                                  EX_PRECOMP_CACHE.put(s, compileExpression(s));
                                  return executeExpression(EX_PRECOMP_CACHE.get(s), ctx, tokens);
                              }
                          }
                          else {
                              return executeExpression(EX_PRECOMP_CACHE.get(s), ctx, tokens);
                          }
  
                      }
                  case LITERAL:
                      return new String(expression);
  
              }
  
              return new String(expression);
          }
  
          Object register = null;
  
          StringAppender sbuf = new StringAppender(10);
          Node currNode = null;
  
          try {
              //noinspection unchecked
              MVELInterpretedRuntime oParser = new MVELInterpretedRuntime(ctx, tokens);
  
              initStack();
              pushAndForward();
  
              while ((currNode = pop()) != null) {
                  node = currNode.getNode();
  
                  switch (currNode.getToken()) {
                      case LITERAL: {
                          sbuf.append(register = new String(expression, currNode.getStartPos(),
                                  currNode.getEndPos() - currNode.getStartPos()));
                          break;
                      }
                      case PROPERTY_EX: {
                          sbuf.append(
                                  valueOf(register = oParser.setExpressionArray(getInternalSegment(currNode)).parse())
                          );
                          break;
                      }
                      case IF:
                      case ELSEIF: {
                          try {
                              if (!((Boolean) oParser.setExpressionArray(getInternalSegment(currNode)).parse())) {
                                  exitContext();
                              }
                          }
                          catch (ClassCastException e) {
                              throw new CompileException("IF expression does not return a boolean: " + new String(getSegment(currNode)));
                          }
                          break;
                      }
                      case FOREACH: {
  
                          if (tokens == null) {
                              tokens = new HashMap();
                          }
  
                          ForeachContext foreachContext;
  
                          if (!(localStack.peek() instanceof ForeachContext)) {
                               foreachContext = ((ForeachContext) currNode.getRegister()).clone();
  
                        //  if (foreachContext.getItererators() == null) {
                              try {
                                  String[] lists = getForEachSegment(currNode).split(",");
                                  Iterator[] iters = new Iterator[lists.length];
                                  for (int i = 0; i < lists.length; i++) {
                                      //noinspection unchecked
                                      Object listObject = new MVELInterpretedRuntime(lists[i], ctx, tokens).parse();
                                      if (listObject instanceof Object[]) {
                                          listObject = Arrays.asList((Object[]) listObject);
                                      }
                                      iters[i] = ((Collection) listObject).iterator();
                                  }
  
                                  foreachContext.setIterators(iters);
                                  localStack.push(foreachContext);
                              }
                              catch (ClassCastException e) {
                                  throw new CompileException("expression for collections does not return a collections object: " + new String(getSegment(currNode)));
                              }
                              catch (NullPointerException e) {
                                  throw new CompileException("null returned for foreach in expression: " + (getForEachSegment(currNode)));
                              }
                          }
  
                          foreachContext = (ForeachContext) localStack.peek();
  
                          Iterator[] iters = foreachContext.getItererators();
                          String[] alias = currNode.getAlias().split(",");
                          // must trim vars
                          for (int i = 0; i < alias.length; i++) {
                              alias[i] = alias[i].trim();
                          }
  
                          if (iters[0].hasNext()) {
                              push();
  
                              //noinspection unchecked
                              for (int i = 0; i < iters.length; i++) {
  
                                  //noinspection unchecked
                                  tokens.put(alias[i], iters[i].next());
                              }
                              if (foreachContext.getCount() != 0) {
                                  sbuf.append(foreachContext.getSeperator());
                              }
                              //noinspection unchecked
                              tokens.put("i0", foreachContext.getCount());
                              foreachContext.setCount(foreachContext.getCount() + 1);
                          }
                          else {
                              for (int i = 0; i < iters.length; i++) {
                                  tokens.remove(alias[i]);
                              }
                              foreachContext.setIterators(null);
                              foreachContext.setCount(0);
                              localStack.pop();
                              exitContext();
                          }
                          break;
                      }
                      case ELSE:
                      case END:
                          if (stack.isEmpty()) forwardAndPush();
                          continue;
                      case GOTO:
                          pushNode(currNode.getEndNode());
                          continue;
                      case TERMINUS: {
                          if (nodes.length != 2) {
                              return sbuf.toString();
                          }
                          else {
                              return register;
                          }
                      }
                      case INCLUDE_BY_REF: {
                          IncludeRef includeRef = (IncludeRef) nodes[node].getRegister();
  
                          IncludeRefParam[] params = includeRef.getParams();
                          Map<String, Object> vars = new HashMap<String, Object>(params.length * 2);
                          for (IncludeRefParam param : params) {
                              vars.put(param.getIdentifier(), MVEL.eval(param.getValue(), ctx, tokens));
                          }
  
                          if (registry == null) {
                              throw new CompileException("No TemplateRegistry specified, cannot load template='" + includeRef.getName() + "'");
                          }
                          String template = registry.getTemplate(includeRef.getName());
  
                          if (template == null) {
                              throw new CompileException("Template does not exist in the TemplateRegistry, cannot load template='" + includeRef.getName() + "'");
                          }
  
                          sbuf.append(TemplateInterpreter.parse(template, ctx, vars, registry));
                      }
                  }
  
                  forwardAndPush();
              }
              throw new CompileException("expression did not end properly: expected TERMINUS node");
          }
          catch (CompileException e) {
              throw e;
          }
          catch (Exception e) {
              if (currNode != null) {
                  throw new CompileException("problem encountered at node [" + currNode.getNode() + "] "
                          + currNode.getToken() + "{" + currNode.getStartPos() + "," + currNode.getEndPos() + "}: " + e.getMessage(), e);
              }
              throw new CompileException("unhandled fatal exception (node:" + node + ")", e);
          }
  
      } 
                              #location 122 
                              #vulnerability type THREAD_SAFETY_VIOLATION