/**********************************************************************
 * Copyright (c) 2007 IBM Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.ptp.pldt.mpi.analysis.analysis;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;

import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTContinueStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement;
import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializerList;
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
import org.eclipse.cdt.core.dom.ast.IASTProblemStatement;
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement;
import org.eclipse.ptp.pldt.mpi.analysis.analysis.BarrierExpression.BarrierExpressionOP;
import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.ICallGraph;
import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.ICallGraphNode;

public class MPIBarrierExprModified extends ASTVisitor {
	protected BarrierTable bTable_;
	protected ICallGraph cg_;
	/** One stack for each communicator */
	protected Hashtable<String,Stack<BarrierExpression>> stacks_; 
	private static final boolean traceOn=false;
	
	protected MPICallGraphNode currentNode_;
	
	/** 
	 * switch statement may be nested 
	 */
	protected int depth = 0;
	
	/** 
	 * This field is used to recognize the associated case body. The idea is 
	 * the case body should have the same parent with the "case" statement. 
	 * One element in this stack is shared by all cases (and default) in one 
	 * switch statement. This is possible because of the tree structure. 
	 */
	protected Stack<IASTNode> caseParent = null;
	
	/** 
	 * This field is used to record whether the current case has "break"
	 * statement. Same as above, one element is shared by all cases and default 
	 * in a switch statement.
	 */
	protected Stack<Boolean> withBreak = null;
	
	/**
	 *  Each bucket in this hashtable is a List, hashed by communicator.
	 * The List records the current barrier 
	 * expression for each case statement in the current (nested)switch statement.
	 * So: Hashtable(for each communicator) -->
	 *     Stack(for each nested switch statement) -->
	 *     ArrayList(for each case body) --> 
	 *     Tuple(caseStatement, CaseBarrierExpr) 
	 */
	protected Hashtable<String,Stack<List>> caseBE = null;
	
	public MPIBarrierExprModified(BarrierTable btable, ICallGraph cg){
		bTable_ = btable;
		cg_ = cg;
	}
	
	private void init(){
		stacks_ = new Hashtable<String,Stack<BarrierExpression>>();
		for(Enumeration<String> e = bTable_.getTable().keys(); e.hasMoreElements();){
			String comm = e.nextElement();
			stacks_.put(comm, new Stack<BarrierExpression>());
		}
		
		depth = 0;
		caseParent = new Stack<IASTNode>();
		withBreak = new Stack<Boolean>();
		caseBE = new Hashtable<String,Stack<List>>();
		for(Enumeration<String> e = bTable_.getTable().keys(); e.hasMoreElements();){
			String comm = e.nextElement();
			caseBE.put(comm, new Stack<List>());
		}
	}
	
	
	public void run(){
		if(bTable_.isEmpty()) return;
		this.shouldVisitExpressions = true;
		this.shouldVisitStatements = true;
		this.shouldVisitDeclarations = true;
		for(ICallGraphNode n = cg_.botEntry(); n != null; n = n.botNext()){
			currentNode_ = (MPICallGraphNode)n;
			if(!currentNode_.marked) continue;
			if(!currentNode_.barrierRelated()) continue;
			//System.out.println("Barrier related function " + currentNode_.getFuncName());
			init();
			IASTFunctionDefinition func = currentNode_.getFuncDef();
			func.accept(this);
			for(Enumeration<String> e = stacks_.keys(); e.hasMoreElements();){
				String comm = e.nextElement();
				Stack<BarrierExpression> sk = stacks_.get(comm);
				BarrierExpression be = sk.pop();
				if(traceOn)System.out.println(currentNode_.getFuncName() + "(" + comm + "): " + be.prettyPrinter()); //$NON-NLS-1$ //$NON-NLS-2$
				if(traceOn)System.out.println(" "); //$NON-NLS-1$
				currentNode_.setBarrierExpr(comm, be);
			}
		}
		if(traceOn)System.out.println("Total number of nodes: " + BarrierExpression.count_node); //$NON-NLS-1$
	}
	
	public int visit(IASTStatement stmt){
		if(stmt instanceof IASTSwitchStatement){
			for(Enumeration<Stack<List>> e = caseBE.elements(); e.hasMoreElements();){
				Stack<List> caseBEsk = e.nextElement();
				caseBEsk.push(new ArrayList<Object>());
			}
			withBreak.push(new Boolean(false));
			depth ++;
		}
		return PROCESS_CONTINUE;
	}
	
	public int leave(IASTStatement stmt){
		BarrierExpression be = null;
		BarrierExpression operand1 = null;
		BarrierExpression operand2 = null;
		BarrierExpression condBE = null;
		
		if(stmt instanceof IASTAmbiguousStatement){
			
		}
		else if(stmt instanceof IASTBreakStatement){
			IASTBreakStatement bkStmt = (IASTBreakStatement)stmt;
			if(inCaseStmt(bkStmt)){
				for(Enumeration<String> e = caseBE.keys(); e.hasMoreElements();){
					String comm = e.nextElement();
					Stack<List> caseBEsk = caseBE.get(comm);
					Stack<BarrierExpression> sk = stacks_.get(comm);
					be = new BarrierExpression(BarrierExpression.BE_bot);
					sk.push(be);
					List list = caseBEsk.peek();
					for(int i=1; i<list.size(); i+=2){
						CaseBarrierExpr cbe = (CaseBarrierExpr)list.get(i);
						cbe.close();
					}
				}
			}
			else{
				for(Enumeration<String> e = caseBE.keys(); e.hasMoreElements();){
					String comm = e.nextElement();
					Stack<BarrierExpression> sk = stacks_.get(comm);
					be = new BarrierExpression(BarrierExpression.BE_bot);
					sk.push(be);
				}
			}
		}
		else if(stmt instanceof IASTCaseStatement){
			IASTCaseStatement caseStmt = (IASTCaseStatement)stmt;
			/* Override the old parent if it exists */
			if(!caseParent.empty()) caseParent.pop();
			caseParent.push(caseStmt.getParent());
			
			for(Enumeration e = caseBE.keys(); e.hasMoreElements();){
				String comm = (String)e.nextElement();
				Stack<List> caseBEsk = caseBE.get(comm);
				Stack<BarrierExpression> sk = stacks_.get(comm);
				be = new BarrierExpression(BarrierExpression.BE_bot);
				sk.push(be);
				List list = caseBEsk.peek();
				list.add(caseStmt);
				list.add(new CaseBarrierExpr(be, caseStmt.getExpression()));
			}
			
			/* Toggle the withBreak sign of the previous case */
			if(!withBreak.empty()) withBreak.pop();
			withBreak.push(new Boolean(false));
		}
		else if(stmt instanceof IASTCompoundStatement){
			IASTCompoundStatement cmpStmt = (IASTCompoundStatement)stmt;
			IASTStatement [] s = cmpStmt.getStatements();
			if(s.length == 0) return PROCESS_CONTINUE;

			for(Enumeration<String> e = stacks_.keys(); e.hasMoreElements();){
				String comm = e.nextElement();
				Stack<BarrierExpression> sk = stacks_.get(comm);
				/* The concatenate operator is left-associative */
				int count = 0;
				int i;
				BarrierExpression[] BElist = new BarrierExpression[s.length];
				for(i=0; i<s.length; i++){
					if(s[i] == null) continue;
					BElist[count] = sk.pop();
					count ++;
				}
				operand1 = BElist[count-1];
				for (i = count-2; i >= 0; i-- ) {
					operand2 = BElist[i];
					be = BarrierExpression.concatBE(operand1, operand2);
					operand1 = be;
				}
				sk.push(operand1);
				fixSwitch(comm, cmpStmt, operand1);
			}
		}
		else if(stmt instanceof IASTContinueStatement){
			for(Enumeration<String> e = caseBE.keys(); e.hasMoreElements();){
				String comm = e.nextElement();
				Stack<BarrierExpression> sk = stacks_.get(comm);
				be = new BarrierExpression(BarrierExpression.BE_bot);
				sk.push(be);
			}
		}
		else if(stmt instanceof IASTDeclarationStatement){
			boolean initialized = false;
			IASTDeclarationStatement declStmt = (IASTDeclarationStatement)stmt;
			IASTDeclaration decl = declStmt.getDeclaration();
			if(decl instanceof IASTSimpleDeclaration){
				IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration)decl;
				IASTDeclarator[] declarators = simpleDecl.getDeclarators();
				for(int i=0; i<declarators.length; i++){
					IASTInitializer init = declarators[i].getInitializer();
					if(init != null){
						initialized = true;
						for(Enumeration<String> e = stacks_.keys(); e.hasMoreElements();){
							String comm = e.nextElement();
							Stack<BarrierExpression> sk = stacks_.get(comm);
							be = getInitializerBE(sk, init);
							sk.push(be);
						}
					}
				}
			}
			if(!initialized){
				for(Enumeration<String> e = stacks_.keys(); e.hasMoreElements();){
					String comm = e.nextElement();
					Stack<BarrierExpression> sk = stacks_.get(comm);
					be = new BarrierExpression(BarrierExpression.BE_bot);
					sk.push(be);
				}
			}
		}
		else if(stmt instanceof IASTDefaultStatement){
			/* DefaultStatement = CaseStatement + BreakStatement */
			IASTDefaultStatement dfStmt = (IASTDefaultStatement)stmt;
			/* Override the old parent if it exists */
			if(!caseParent.empty()) caseParent.pop();
			caseParent.push(dfStmt.getParent());
			
			for(Enumeration<String> e = caseBE.keys(); e.hasMoreElements();){
				String comm = e.nextElement();
				Stack<List> caseBEsk = caseBE.get(comm);
				Stack<BarrierExpression> sk = stacks_.get(comm);
				be = new BarrierExpression(BarrierExpression.BE_bot);
				List list = caseBEsk.peek();
				list.add(dfStmt);
				list.add(new CaseBarrierExpr(be, null));
			}
		}
		else if(stmt instanceof IASTDoStatement){
			IASTDoStatement doStmt = (IASTDoStatement)stmt;
			for(Enumeration<String> e = stacks_.keys(); e.hasMoreElements();){
				String comm = e.nextElement();
				Stack<BarrierExpression> sk = stacks_.get(comm);
				/* condition */
				if(doStmt.getCondition() != null)
					condBE = (BarrierExpression)sk.pop();
				else
					condBE = new BarrierExpression(BarrierExpression.BE_bot);
				/* loop body */
				if(doStmt.getBody() != null)
					operand1 = (BarrierExpression)sk.pop();
				else
					operand1 = new BarrierExpression(BarrierExpression.BE_bot);
				/* BE = body . cond. (body . cond)* */
				be = BarrierExpression.concatBE(operand1, condBE, 
						BarrierExpression.repeatBE(
							BarrierExpression.concatBE(operand1, condBE), 
								doStmt.getCondition(), stmt));
				sk.push(be);
				fixSwitch(comm, stmt, be);
			}
		}
		else if(stmt instanceof IASTExpressionStatement){
			for(Enumeration<String> e = stacks_.keys(); e.hasMoreElements();){
				String comm = e.nextElement();
				Stack<BarrierExpression> sk = stacks_.get(comm);
				be = sk.pop();
				sk.push(be);
				fixSwitch(comm, stmt, be);
			}
		}
		else if(stmt instanceof IASTForStatement){
			IASTForStatement forStmt = (IASTForStatement)stmt;
			BarrierExpression initBE = null;
			BarrierExpression iterBE = null;
			for(Enumeration<String> e = stacks_.keys(); e.hasMoreElements();){
				String comm = e.nextElement();
				Stack<BarrierExpression> sk = stacks_.get(comm);
				/* loop body */
				if(forStmt.getBody() != null)
					operand1 = sk.pop();
				else
					operand1 = new BarrierExpression(BarrierExpression.BE_bot);
				/* iterator */
				if(forStmt.getIterationExpression() != null)
					iterBE = sk.pop();
				else
					iterBE = new BarrierExpression(BarrierExpression.BE_bot);
				/* condition */
				if(forStmt.getConditionExpression() != null)
					condBE = sk.pop();
				else
					condBE = new BarrierExpression(BarrierExpression.BE_bot);
				/* initializer */
				if(forStmt.getInitializerStatement() != null)
					initBE = sk.pop();
				else
					initBE = new BarrierExpression(BarrierExpression.BE_bot);
				/* BE = init . cond. (body . iter . cond)* */
				be = BarrierExpression.concatBE(initBE, condBE, 
						BarrierExpression.repeatBE(
							BarrierExpression.concatBE(operand1, iterBE, condBE), 
							forStmt.getConditionExpression(), stmt));
				sk.push(be);
				fixSwitch(comm, stmt, be);
			}
		} 
		else if(stmt instanceof IASTGotoStatement){
			/* TODO */
		}
		else if(stmt instanceof IASTIfStatement){
			IASTIfStatement ifStmt = (IASTIfStatement)stmt;
			for(Enumeration<String> e = stacks_.keys(); e.hasMoreElements();){
				String comm = e.nextElement();
				Stack<BarrierExpression> sk = stacks_.get(comm);
				/* else clause */
				if(ifStmt.getElseClause() != null)
					operand2 = sk.pop();
				else 
					operand2 = new BarrierExpression(BarrierExpression.BE_bot);
				/* then clause */
				if(ifStmt.getThenClause() != null)
					operand1 = sk.pop();
				else
					operand1 = new BarrierExpression(BarrierExpression.BE_bot);
				/* condition*/
				if(ifStmt.getConditionExpression() != null)
					condBE = sk.pop();
				else
					condBE = new BarrierExpression(BarrierExpression.BE_bot);
				/* BE = cond. (then | else) */
				be = BarrierExpression.concatBE(condBE, 
						BarrierExpression.branchBE(operand1, operand2, 
							ifStmt.getConditionExpression(), stmt));
				sk.push(be); 		
				fixSwitch(comm, stmt, be);
			}
		}
		else if(stmt instanceof IASTLabelStatement){
			/* TODO */
		}
		else if(stmt instanceof IASTNullStatement){
			for(Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();){
				Stack<BarrierExpression> sk = e.nextElement();
				be = new BarrierExpression(BarrierExpression.BE_bot);
				sk.push(be);
			}
		}
		else if(stmt instanceof IASTProblemStatement){
			for(Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();){
				Stack<BarrierExpression> sk = e.nextElement();
				be = new BarrierExpression(BarrierExpression.BE_bot);
				sk.push(be);
			}
		}
		else if(stmt instanceof IASTReturnStatement){
			IASTReturnStatement rStmt = (IASTReturnStatement)stmt;
			if(rStmt.getReturnValue() == null){
				for(Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();){
					Stack<BarrierExpression> sk = e.nextElement();
					be = new BarrierExpression(BarrierExpression.BE_bot);
					sk.push(be);
				}
			} else {
				for(Enumeration<String> e = caseBE.keys(); e.hasMoreElements();){
					String comm = e.nextElement();
					Stack<BarrierExpression> sk = stacks_.get(comm);
					be = sk.pop();
					sk.push(be);
					if(!withBreak.empty()){
						withBreak.pop();
						withBreak.push(new Boolean(true));
					}
					fixSwitch(comm, rStmt, be);
				}
			}
		}
		else if(stmt instanceof IASTSwitchStatement){
			IASTSwitchStatement swStmt = (IASTSwitchStatement)stmt;
			for(Enumeration<String> e = caseBE.keys(); e.hasMoreElements();){
				String comm = e.nextElement();
				Stack<List> caseBEsk = caseBE.get(comm);
				List list = caseBEsk.pop();
				CaseBarrierExpr cbe = (CaseBarrierExpr)list.get(1);
				operand1 = (BarrierExpression)cbe.getBE();
				for(int i=3; i<list.size(); i+=2){
					cbe = (CaseBarrierExpr)list.get(i);
					operand2 = (BarrierExpression)cbe.getBE();
					be = BarrierExpression.branchBE(operand1, operand2, 
							swStmt.getControllerExpression(), stmt);
					operand1 = be;
				}
				Stack<BarrierExpression> sk = stacks_.get(comm);
				sk.pop();
				sk.push(operand1);
			}
			withBreak.pop();
			caseParent.pop();
			depth --;
		}
		else if(stmt instanceof IASTWhileStatement){
			IASTWhileStatement whStmt = (IASTWhileStatement)stmt;
			for(Enumeration<String> e = stacks_.keys(); e.hasMoreElements();){
				String comm = e.nextElement();
				Stack<BarrierExpression> sk = stacks_.get(comm);
				/* loop body */
				if(whStmt.getBody() != null)
					operand1 = sk.pop();
				else
					operand1 = new BarrierExpression(BarrierExpression.BE_bot);
				/* condition */
				if(whStmt.getCondition() != null) 
					condBE = sk.pop();
				else
					condBE = new BarrierExpression(BarrierExpression.BE_bot);
				/* BE = cond . (body . cond)*  */
				be = BarrierExpression.concatBE(condBE, 
						BarrierExpression.repeatBE(
							BarrierExpression.concatBE(operand1, condBE), 
								whStmt.getCondition(), stmt));
				sk.push(be);
				fixSwitch(comm, stmt, be);
			}
		}

		return PROCESS_CONTINUE;
	}
	
	/** 
	 * If the current statement is a case body
	 */
	private void fixSwitch(String key, IASTStatement stmt, BarrierExpression BE){
		if(depth <= 0) return;
		if(stmt.getParent() == caseParent.peek()){
			Stack<List> caseBEsk = caseBE.get(key);
			List list = caseBEsk.peek();
			boolean flag = ((Boolean)withBreak.peek()).booleanValue();
			for(int i = 1; i<list.size(); i+=2){
				CaseBarrierExpr cbe = (CaseBarrierExpr)list.get(i);
				if(flag)
					cbe.addFinalBEElement(BE);
				else 
					cbe.addBEElement(BE);
			}
		}
	}
	
	private boolean inCaseStmt(IASTBreakStatement stmt){
		IASTNode parent = stmt.getParent();
		while(parent != null){
			if(parent instanceof IASTForStatement ||
			   parent instanceof IASTDoStatement ||
			   parent instanceof IASTWhileStatement)
				return false;
			else if(parent instanceof IASTSwitchStatement)
				return true;
			else if(parent instanceof IASTFunctionDefinition)
				return false;
			else
				parent = parent.getParent();
		}
		return false;
	}
	
	private BarrierExpression getInitializerBE(Stack sk, IASTInitializer init){		
		BarrierExpression BE = null;
		if(init instanceof IASTInitializerExpression){
			BE = (BarrierExpression)sk.pop();
		}
		else if(init instanceof IASTInitializerList){
			IASTInitializerList list = (IASTInitializerList)init;
			IASTInitializer[] inits = list.getInitializers();
			for(int j = 0; j<inits.length; j++){
				if(BE == null)
					BE = getInitializerBE(sk, inits[j]);
				else
					BE = BarrierExpression.concatBE(BE, 
							getInitializerBE(sk, inits[j]));
			}
		}
		return BE;
	}
	
	/*
	 * An expression which doesn't have any "expression" 
	 * field is a terminal. 
	 */
	public int leave(IASTExpression expr){
		BarrierExpression be = null;
		BarrierExpression operand1 = null;
		BarrierExpression operand2 = null;
		BarrierExpression operand3 = null;
		
		if(expr instanceof IASTAmbiguousExpression){
			/* nothing */
		}
		else if(expr instanceof IASTArraySubscriptExpression){
			for(Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();){
				Stack<BarrierExpression> sk = e.nextElement();
				operand2 = sk.pop();  //subscript
				operand1 = sk.pop();  //array
				be = BarrierExpression.concatBE(operand1, operand2);
				sk.push(be);
			}
		}
		else if(expr instanceof IASTBinaryExpression){
			for(Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();){
				Stack<BarrierExpression> sk = e.nextElement();
				operand2 = sk.pop();
				operand1 = sk.pop();
				be = BarrierExpression.concatBE(operand1, operand2);
				sk.push(be);
			}
		}
		else if(expr instanceof IASTCastExpression){
			/* Has only one operator, leave it there */
		}
		else if(expr instanceof IASTConditionalExpression){
			IASTConditionalExpression cExpr = (IASTConditionalExpression)expr;
			IASTNode parent = expr.getParent();
			while(! (parent instanceof IASTStatement) )
				parent = parent.getParent();
			for(Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();){
				Stack<BarrierExpression> sk = e.nextElement();
				operand2 = sk.pop(); /* negative */
				operand1 = sk.pop(); /* positive */
				operand3 = sk.pop(); /* condition */
				/* E = C ( P | N ) */
				be = BarrierExpression.concatBE(operand3, 
						BarrierExpression.branchBE(operand1, operand2, 
								cExpr.getLogicalConditionExpression(), 
								(IASTStatement)parent));
				sk.push(be);
			}
		}
		else if(expr instanceof IASTExpressionList){
			IASTExpressionList exprList = (IASTExpressionList)expr;
			IASTExpression[] exps = exprList.getExpressions();
			if(exps.length == 0) return PROCESS_CONTINUE;
			for(Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();){
				Stack<BarrierExpression> sk = e.nextElement();
				int count = 0;
				int i;
				BarrierExpression[] BElist = new BarrierExpression[exps.length];
				for(i=0; i<exps.length; i++){
					if(exps[i] == null) continue;
					BElist[count] = sk.pop();
					count ++;
				}
				operand1 = BElist[count-1];
				for (i = count-2; i >= 0; i-- ) {
					operand2 = BElist[i];
					be = BarrierExpression.concatBE(operand1, operand2);
					operand1 = be;
				}
				sk.push(operand1);
			}
		}
		else if(expr instanceof IASTFieldReference){
			/*
			for(Enumeration e = stacks_.elements(); e.hasMoreElements();){
				Stack sk = (Stack)e.nextElement();
				operand2 = (BarrierExpression)sk.pop(); //name
				operand1 = (BarrierExpression)sk.pop(); //owner
				be = BarrierExpression.concatBE(operand1, operand2);
				sk.push(be);
			}
			*/
		}
		else if(expr instanceof IASTFunctionCallExpression){
			IASTFunctionCallExpression fExpr = (IASTFunctionCallExpression)expr;
			IASTExpression funcname = fExpr.getFunctionNameExpression();
			IASTExpression parameter = fExpr.getParameterExpression();
			String signature = funcname.getRawSignature();
			int id = bTable_.isBarrier(fExpr);
			if(id != -1){ /* barrier */
				be = new BarrierExpression(id);
				String comm = bTable_.getComm(id);
				for(Enumeration<String> e = stacks_.keys(); e.hasMoreElements();){
					String commkey = e.nextElement();
					Stack<BarrierExpression> sk = stacks_.get(commkey);
					if(parameter != null) sk.pop(); //parameter 
					sk.pop(); //functionName
					if(commkey.equals(comm)) sk.push(be);
					else sk.push(new BarrierExpression(BarrierExpression.BE_bot));
				}
			}
			else{
				MPICallGraphNode node = (MPICallGraphNode)cg_.getNode(currentNode_.getFileName(), signature);
				if(node != null && node.barrierRelated()){ 
					/* a function (directly or indirectly) with barriers */
					for(Enumeration<String> e = stacks_.keys(); e.hasMoreElements();){
						String comm = e.nextElement();
						Stack<BarrierExpression> sk = stacks_.get(comm);
						BarrierExpression funcBE = node.getBarrierExpr().get(comm);
						if(parameter != null) sk.pop(); //parameter
						sk.pop(); //functionName
						if(node == currentNode_){ //recursive functions
							be = new BarrierExpression(node.getFuncName());
						}
						else if(funcBE.isBot()){
							be = new BarrierExpression(BarrierExpression.BE_bot);
						} 
						else{
							be = new BarrierExpression(signature);
						}
						sk.push(be);
					}
				} else { //not a barrier related function
					be = new BarrierExpression(BarrierExpression.BE_bot);
					for(Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();){
						Stack<BarrierExpression> sk = e.nextElement();
						if(parameter != null) sk.pop(); //parameter
						sk.pop(); //functionName
						sk.push(be);
					}
				}
			}
		}
		else if(expr instanceof IASTIdExpression){ //terminal
			//System.out.println(((IASTIdExpression)expr).getName().toString());
			for(Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();){
				Stack<BarrierExpression> sk = e.nextElement();
				be = new BarrierExpression(BarrierExpression.BE_bot);
				sk.push(be);
			}
		}
		else if(expr instanceof IASTLiteralExpression){ //terminal
			//System.out.println(((IASTLiteralExpression)expr).toString());
			for(Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();){
				Stack<BarrierExpression> sk = e.nextElement();
				be = new BarrierExpression(BarrierExpression.BE_bot);
				sk.push(be);
			}
		}
		/*
		else if(expr instanceof IASTProblemExpression){
			System.out.println("IASTProblemExpression");
		}
		*/
		else if(expr instanceof IASTTypeIdExpression){
			for(Enumeration<Stack<BarrierExpression>> e = stacks_.elements(); e.hasMoreElements();){
				Stack<BarrierExpression> sk = e.nextElement();
				be = new BarrierExpression(BarrierExpression.BE_bot);
				sk.push(be);
			}
		}
		else if(expr instanceof IASTUnaryExpression){
			/* has only one operand, leave it there */
		}
		/*
		else if(expr instanceof ICASTTypeIdInitializerExpression){
			System.out.println("ICASTTypeIdInitializerExpression");
		}
		*/
		return PROCESS_CONTINUE;
	}

	class CaseBarrierExpr{
		protected BarrierExpression BE;
		protected boolean closed;
		protected IASTExpression cond;
		
		CaseBarrierExpr(BarrierExpression be, IASTExpression cond){
			BE = be;
			closed = false;
			this.cond = cond;
		}
		
		public void close() { closed = true; }
		public BarrierExpression getBE() {return BE;}
		public IASTExpression getCond() {return cond;}

		public void addBEElement(BarrierExpression be){
			if(closed) return;
			if(BE == null){
				BE = be;
			} else {
				BE = BarrierExpression.concatBE(BE, be);
			}
		}
		
		public void addFinalBEElement(BarrierExpression be){
			addBEElement(be);
			close();
		}
	}
	
	protected void checkBarrierRecursion(){
		for(Iterator<List<ICallGraphNode>> i=cg_.getCycles().iterator(); i.hasNext();){
			List<ICallGraphNode> cycle = i.next();
			boolean barrierRelated = false;
			for(Iterator<ICallGraphNode> ii = cycle.iterator(); ii.hasNext();){
				MPICallGraphNode node = (MPICallGraphNode)ii.next();
				if(node.barrierRelated){
					barrierRelated = true;
					break;
				}
			}
			if(!barrierRelated) continue;
			if(cycle.size() > 1){
				System.out.println("Multi-Function barrier related cycles"); //$NON-NLS-1$
				return;
			}
			currentNode_ = (MPICallGraphNode)cycle.get(0);
			for(Enumeration<String> e = currentNode_.getBarrierExpr().keys(); e.hasMoreElements();){
				String comm = e.nextElement();
				BarrierExpression BE = currentNode_.getBarrierExpr().get(comm);
				if(recursion(BE) == recursionError){
					System.out.println("Recursion Error in " + comm); //$NON-NLS-1$
				}
			}
			
		}
	}
	
	protected final int recursionCorrect = 0;
	protected final int recursionError = 1;
	protected final int noRecursion = 2;
	
	protected int recursion(BarrierExpression BE){
		System.out.println(BE.prettyPrinter());
		BarrierExpressionOP OP = BE.getOP();
		if(OP == null){
			if(BE.isFunc()){ //function call
				String funcName = BE.getFuncName();
				MPICallGraphNode fnode = (MPICallGraphNode)cg_.getNode(currentNode_.getFileName(), funcName);
				if(fnode == currentNode_)
					return recursionCorrect;
				else 
					return noRecursion;
			}
			else
				return noRecursion;
		}
		else if(OP.getOperator() == BarrierExpressionOP.op_concat){
			int v1 = recursion(BE.getOP1());
			int v2 = recursion(BE.getOP2());
			if(v1 == recursionError || v2 == recursionError)
				return recursionError;
			else if(v1 == recursionCorrect || v2 == recursionCorrect)
				return recursionCorrect;
			else 
				return noRecursion;

		}
		else if(OP.getOperator() == BarrierExpressionOP.op_branch){
			int v1 = recursion(BE.getOP1());
			int v2 = recursion(BE.getOP2());
			if(v1 == noRecursion && v2 == noRecursion)
				return noRecursion;
			else
				return recursionError;
		}
		else { //BarrierExpressionOP.op_repeat
			return recursion(BE.getOP1());

		}
	}


}

