/// <summary>
        /// Static method that converts arithmetic expression from infix to postfix
        /// Assumes infix input is valid arithmetic expression
        /// </summary>
        /// <param name="infix"></param>
        /// <returns></returns>
        public static string convertInfixToPostfix(string infix)
        {
            char[] inputChars                  = infix.ToCharArray();
            LinkedList <string>   tokens       = parseArithmeticExpression(inputChars);
            GenericStack <string> parsingStack = new GenericStack <string>();

            /*      Infix -> Postfix Rules
             * 1.	Print operands as they arrive.
             * 2.	If the stack is empty or contains a left parenthesis on top, push the incoming operator onto the stack.
             * 3.	If the incoming symbol is a left parenthesis, push it on the stack.
             * 4.	If the incoming symbol is a right parenthesis, pop the stack and print the operators until you see a left parenthesis. Discard the pair of parentheses.
             * 5.	If the incoming symbol has higher precedence than the top of the stack, push it on the stack.
             * 6.	If the incoming symbol has equal precedence with the top of the stack, use association. If the association is left to right, pop and print the top of the stack and then push the incoming operator. If the association is right to left, push the incoming operator.
             * 7.	If the incoming symbol has lower precedence than the symbol on the top of the stack, pop the stack and print the top operator. Then test the incoming operator against the new top of stack.
             * 8.	At the end of the expression, pop and print all operators on the stack. (No parentheses should remain.)
             */
            string postfix = "";

            for (int i = 0; i < tokens.Count(); i++)
            {
                //get incoming symbol s
                string s = tokens.ElementAt(i);

                //1. Print operands as they arrive.
                if (Regex.IsMatch(s, @"\d*\.?\d+"))
                {
                    postfix += s + " ";
                }
                //3.If the incoming symbol is a left parenthesis, push it on the stack.
                else if (s.Equals("("))
                {
                    parsingStack.push(s);
                }
                //4. If the incoming symbol is a right parenthesis, pop the stack and print the operators until you see a left parenthesis.
                //   Discard the pair of parentheses.
                else if (s.Equals(")"))
                {
                    while (!parsingStack.peek().Equals("("))
                    {
                        postfix += parsingStack.pop() + " ";
                    }
                    //pop the left parenthesis off stack to remove it
                    parsingStack.pop();
                }
                //else incoming symbol must be a left parenthesis or an operator
                else
                {
                    //2. If the stack is empty or contains a left parenthesis on top, push the incoming operator onto the stack.
                    if (parsingStack.isEmpty() || parsingStack.peek().Equals("("))
                    {
                        parsingStack.push(s);
                    }
                    //5. If the incoming symbol has higher precedence than the top of the stack, push it on the stack.
                    else if (isHighPrecedence(s) && !isHighPrecedence(parsingStack.peek()))
                    {
                        parsingStack.push(s);
                    }
                    //7. If the incoming symbol has lower precedence than the symbol on the top of the stack, pop the stack and print the top operator.
                    // Then test the incoming operator against the new top of stack.
                    else if (!isHighPrecedence(s) && isHighPrecedence(parsingStack.peek()))
                    {
                        postfix += parsingStack.pop() + " ";
                        //now we need to check the incoming operator against new top of stack
                        //decementing loop index i will force loop to re-evaluate the same symbol s against new stack top
                        i--;
                    }

                    //6. If the incoming symbol has equal precedence with the top of the stack, use association.
                    //   If the association is left to right, pop and print the top of the stack and then push the incoming operator.
                    //   If the association is right to left, push the incoming operator.
                    // We can probably remove this condition and assume that precedence is equal...
                    // Stack can contain only operators and parenthesis! All numbers have already been printed to output
                    // If incoming is higher precedence, if incoming is lower precedence are already covered
                    // therefore the only option left is equal precedence
                    else
                    {
                        postfix += parsingStack.pop() + " ";
                        parsingStack.push(s);
                    }
                }
            }
            //8. At the end of the expression, pop and print all operators on the stack. (No parentheses should remain.)
            while (!parsingStack.isEmpty())
            {
                postfix += parsingStack.pop() + " ";
            }

            return(postfix);
        }