public Expression parse() {
        Token token = getNext();
        Token.Type tokenValue = token.getType();
        Token.Type nextTokenValue = seeNext().getType();
        
        // if the token is a NUMBER, return a number expression if its not the first element
        if (tokenValue.equals(Token.Type.NUMBER)){
            Expression num = new Number(token);
            if (index != 0){
                return num;
            }
            else throw new InvalidInputException("First element is a number");
        }
        
        // if the token is a VARIABLE, return a variable expression if its not the first element
        if (tokenValue.equals(Token.Type.VARIABLE)){
            Expression var = new Variable(token);
            if (index != 0){
                return var;
            }
            else throw new InvalidInputException("First element is a variable");
        }
        
        // if the token is a MULTIPLICATION, return a multiply expression if its not the first element
        //else if (tokenValue.equals(Token.Type.MULTIPLICATION)){
            // Make sure the next token is the start of an expression, i.e. a number, a variable, or an open parens.
            // If it is, parse the next token and return it as the right side of the expression
            // Else throw an exception
//            if (nextTokenValue.equals(Token.Type.NUMBER) || nextTokenValue.equals(Token.Type.VARIABLE) || nextTokenValue.equals(Token.Type.OPEN_PARENS)){
//                if (index != 0){
//                    return multiplier(left, right);
//                }
//                else throw new InvalidInputException("First element is a multiplication");
//            }
//            else throw new InvalidInputException("A non expression follows a multiplication");
//        }
        
     // if the token is an ADDITION, return an ADDITION expression
//        else if (tokenValue.equals(Token.Type.ADDITION)){
            // Make sure the next token is the start of an expression, i.e. a number, a variable, or an open parens.
            // If it is, parse the next token and return it as the right side of the expression
            // Else throw an exception
//            if (nextTokenValue.equals(Token.Type.NUMBER) || nextTokenValue.equals(Token.Type.VARIABLE) || nextTokenValue.equals(Token.Type.OPEN_PARENS)){
//                if (index != 0){
//                    return adder();
//                }
//                else throw new InvalidInputException("First element is an addition");
//            }
//            else throw new InvalidInputException("A non expression follows an addition");
//        }
        
        //An open parens marks the beginning of an expression
        if (tokenValue.equals(Token.Type.OPEN_PARENS)){
            
            // Balance is used to check the balance of the expression, i.e. equal numbers of open and closed parens
            //balance++;
            
            // Check to see if the next token is a variable, a number or an open parens. If not, it is an invalid sequence
            if (!(nextTokenValue.equals(Token.Type.NUMBER) || nextTokenValue.equals(Token.Type.VARIABLE) || nextTokenValue.equals(Token.Type.OPEN_PARENS))){
                throw new InvalidInputException("An invalid sequence follows an Open Parens");
            }
            
            // Else if the next token is a variable or number, check if the following token is an operator or a close parens 
            // If it is an operator, the variable or number becomes the left variable of an operator expression 
            // The operator expression is returned provided there is a matching close parens
            // Else if the token following the initial variable or number is a closed paren, the variable or number is returned as an expression.
            if (nextTokenValue.equals(Token.Type.NUMBER) || nextTokenValue.equals(Token.Type.VARIABLE)){
                Expression left = parse();
                Token.Type operator = seeNext().getType();
                if (operator.equals(Token.Type.MULTIPLICATION) || operator.equals(Token.Type.ADDITION)){
                    Token operand = getNext();
                    // Right hand side of the expression
                    Expression right = parse();
                    Token afterRight = getNext();
                    
                    if (!(afterRight.getType().equals(Token.Type.CLOSE_PARENS) || afterRight.getType().equals(Token.Type.END))) throw new InvalidInputException("Missing close parens or too many");
                    
                    // Have not reached end, continue to parse
                    if (afterRight.equals(Token.Type.CLOSE_PARENS)){
                        if (operand.getType().equals(Token.Type.MULTIPLICATION)){
                            return multiplier(left, right);
                        }
                        else {return adder(left, right);}
                        }
                    // Have reached end
                    else{
                        //if (balance == 0){
                            if (operand.getType().equals(Token.Type.MULTIPLICATION)){
                                //exp = multiplier();
                                return multiplier(left, right);
                            }
                            else {
                                //exp = adder();
                                return adder(left, right);}
                        //    }
                        //else {throw new InvalidInputException("Unbalanced parentheses");}
                    }
                }
                if (operator.equals(Token.Type.CLOSE_PARENS)){
                    //exp = left;
                    return left;
                } else throw new InvalidInputException("An invalid sequence follows a variable or number");
            } throw new RuntimeException("Invalid Input");
            
//            // Else if the next token is another open parens, that becomes the left variable of a potential expression and check there is a matching close parens.
//            else if (nextTokenValue.equals(Token.Type.OPEN_PARENS)){
//                left = parse();
//                Token.Type afterLeft = seeNext().getType();
//                if (!(afterLeft.equals(Token.Type.CLOSE_PARENS) || (afterLeft.equals(Token.Type.END)))) throw new InvalidInputException("Missing close parens or too many");
//                // Have not reached end, continue to parse
//                else if(afterLeft.equals(Token.Type.CLOSE_PARENS)){
//                    return parse();
//                }
//                // Have reached end
//                else{
//                    if (balance == 0){
//                        return exp;
//                    }
//                    else {throw new InvalidInputException("Unbalanced parentheses");}
//                }
//            }
        }
        
//        else if (tokenValue.equals(Token.Type.CLOSE_PARENS)){
//            balance--;
//            if (index == 0) throw new InvalidInputException("Close parens is first element");
//            else{
//                if (!(nextTokenValue.equals(Token.Type.MULTIPLICATION) || nextTokenValue.equals(Token.Type.ADDITION)
//                        || nextTokenValue.equals(Token.Type.CLOSE_PARENS) || nextTokenValue.equals(Token.Type.END))) 
//                        throw new InvalidInputException("illegal sequence following close parens");
//                
//                // End of the entire expression
//                else if (nextTokenValue.equals(Token.Type.END)){
//                    if (balance == 0){
//                        return exp;
//                    } else {throw new InvalidInputException("Unbalanced parentheses");}
//                }
//                // Beginning of a new expression, therefore whatever was in enclosed by this parens is the left side of an op expression
//                else if (nextTokenValue.equals(Token.Type.MULTIPLICATION) || nextTokenValue.equals(Token.Type.ADDITION)){                  
//                    left = exp;
//                    exp = parse();
//                    Token.Type afterExp = seeNext().getType();
//                    if (!(afterExp.equals(Token.Type.CLOSE_PARENS) || afterExp.equals(Token.Type.END))) throw new InvalidInputException("Missing close parens or too many");
//                    // Have not reached end, continue to parse
//                    if (afterExp.equals(Token.Type.CLOSE_PARENS)){
//                        return parse();
//                        }
//                    // Have reached end
//                    else{
//                        if (balance == 0){
//                            return exp;
//                        }
//                        else {throw new InvalidInputException("Unbalanced parentheses");}
//                    }
//                }
//                // It is another close parens - recurse
//                else{
//                    return parse();
//                }
//            }
//        }
//        
//        else if (tokenValue.equals(Token.Type.END)){
//            if (index == 0) throw new InvalidInputException("String had no tokens");
//            else{
//                // At the end
//                return exp;
//                }
//        }
        // Should not get to this case
        //throw new RuntimeException("Invalid input");
        return parse();
    }