public static ArrayList<ArrayList<Integer>> pathSum(TreeNode root, int sum) {
		ArrayList<ArrayList<Integer>> allPaths = new ArrayList<ArrayList<Integer>>();
		int curSum = 0;
		int[] path = new int[100];
		byte[] allChildrenVisited = new byte[100];
		int curIndex = 0;
		
		Stack<TreeNode> stack = new Stack<TreeNode>();
		TreeNode node = root;
		while(node != null || !stack.isEmpty()){
			while(node != null){
				//Add the node to stack
				stack.push(node);
				
				//Add node value to current sum
				curSum += node.val;
				
				//Add the node data to path
				path[curIndex] = node.val;
				//Update visit flag for the node
				allChildrenVisited[curIndex] = 0;
				curIndex ++;
				
				//If it is a leaf node, check whether current sum equals to the sum
				if(node.left == null && node.right == null){
					if(curSum == sum){
						ArrayList<Integer> onePath = new ArrayList<Integer>();
						for(int i=0; i<curIndex; i++){
							onePath.add(path[i]);
						}
						allPaths.add(onePath);
					}
				}
				
				node = node.left;
			}
			
			//If the peek node has no left node, pop it from stack
			node = stack.pop();
			curIndex --;
			curSum -= node.val;
			
			//If the peek node has right node, add the node back to stack again, and update current node to its right child
			if(node.right != null && allChildrenVisited[curIndex] == 0){
				stack.push(node);
				path[curIndex] = node.val;
				allChildrenVisited[curIndex] = 1;
				curIndex ++;
				curSum += node.val;
				
				node = node.right;
			}else{
				node = null;
			}
			
		}

		return allPaths;

	}