public void RightNestedComponentsAreInlined()
		{
			// x*(y*z) = x*y*z
			var innerComponent = new DualFactorComponent(new AlphabeticFactor("y"), new AlphabeticFactor("z"), true);
			var outerComponent = new DualFactorComponent(new AlphabeticFactor("x"), Factorizer.ToFactor(innerComponent), true);
			var componentList = new ComponentList(outerComponent);

			Assert.AreEqual(3, componentList.Factors.Count);
			Assert.IsTrue(componentList.Factors[0].Factor is AlphabeticFactor);
			Assert.IsTrue(componentList.Factors[0].IsInNumerator);
			Assert.IsTrue(componentList.Factors[1].Factor is AlphabeticFactor);
			Assert.IsTrue(componentList.Factors[1].IsInNumerator);
			Assert.IsTrue(componentList.Factors[2].Factor is AlphabeticFactor);
			Assert.IsTrue(componentList.Factors[2].IsInNumerator);

			Assert.AreEqual("x*y*z", componentList.ToString());
		}
		public void DoubleNestedComponentsAreInlined()
		{
			// (w*x)*(y*z) = w*x*y*z
			var leftInnerComponent = new DualFactorComponent(new AlphabeticFactor("w"), new AlphabeticFactor("x"), true);
			var rightInnerComponent = new DualFactorComponent(new AlphabeticFactor("y"), new AlphabeticFactor("z"), true);
			var outerComponent = new DualFactorComponent(Factorizer.ToFactor(leftInnerComponent), Factorizer.ToFactor(rightInnerComponent), true);
			var componentList = new ComponentList(outerComponent);

			Assert.AreEqual(4, componentList.Factors.Count);
			Assert.IsTrue(componentList.Factors[0].Factor is AlphabeticFactor);
			Assert.IsTrue(componentList.Factors[0].IsInNumerator);
			Assert.IsTrue(componentList.Factors[1].Factor is AlphabeticFactor);
			Assert.IsTrue(componentList.Factors[1].IsInNumerator);
			Assert.IsTrue(componentList.Factors[2].Factor is AlphabeticFactor);
			Assert.IsTrue(componentList.Factors[2].IsInNumerator);
			Assert.IsTrue(componentList.Factors[3].Factor is AlphabeticFactor);
			Assert.IsTrue(componentList.Factors[3].IsInNumerator);

			Assert.AreEqual("w*x*y*z", componentList.ToString());
		}
		private static Expression ParsePostfix(IEnumerable<Token> tokens, Dictionary<string, Expression> variableMap)
		{
			var stack = new Stack<Evaluatable>();
			foreach (var token in tokens)
			{
				if (token.Type.IsOperand())
				{
					if (token is ExpressionListToken)
					{
						stack.Push(((ExpressionListToken)token).List);
					}
					else
					{
						stack.Push(new SingleFactorComponent(ParseOperand(token, variableMap)));
					}
				}
				else if (token.Type == TokenType.Function)
				{
					var operands = new List<Expression>();
					var operatorCount = FunctionRepository.Get(token.Value).ArgumentCount;
					for (var i = 0; i < operatorCount; i++)
					{
						operands.Add(Expressionizer.ToExpression(stack.Pop()));
					}

					operands.Reverse();
					stack.Push(new FunctionComponent(token.Value, operands));
				}
				else if (token.Type.IsOperator())
				{
					Evaluatable parent;

					if (token.Type == TokenType.Factorial || token.Type == TokenType.Negate)
					{
						var argument = stack.Pop();
						parent = new FunctionComponent(token.Value, new List<Expression> { Expressionizer.ToExpression(argument) });
					}
					else if (token.Type == TokenType.Root)
					{
						var argument = stack.Pop();
						parent = new FunctionComponent("√", new List<Expression> { Expressionizer.ToExpression(argument) });
					}
					else
					{
						var right = stack.Pop();
						var left = stack.Pop();

						switch (token.Type)
						{
							case TokenType.Plus:
							case TokenType.Minus:
								parent = new DualComponentExpression(Componentizer.ToComponent(left), Componentizer.ToComponent(right), token.Type == TokenType.Plus);
								break;
							case TokenType.Multiply:
							case TokenType.Divide:
								parent = new DualFactorComponent(Factorizer.ToFactor(left), Factorizer.ToFactor(right), token.Type == TokenType.Multiply);
								break;
							case TokenType.Assign:
								parent = new FunctionComponent(new Assign(variableMap), new List<Expression>
								{
									Expressionizer.ToExpression(left),
									Expressionizer.ToExpression(right)
								});
								break;
							default:
								throw new SyntaxErrorException("Token {0} not expected", token.Value);
						}
					}

					stack.Push(parent);
				}
			}

			if (stack.Count != 1)
			{
				throw new SyntaxErrorException("Stack not parseable");
			}

			var result = stack.Pop();

			if (result is Expression)
			{
				return (Expression)result;
			}

			if (result is Component)
			{
				return new SingleComponentExpression((Component)result);
			}

			if (result is Factor)
			{
				return new SingleComponentExpression(new SingleFactorComponent((Factor)result));
			}

			throw new SyntaxErrorException("Expression tree not parseable");
		}