public static OperationResult DoOperation(BinaryOperationToken operation, ValueToken leftOperand, ValueToken rightOperand)
        {
            if (!(operation is BinaryOperationToken))
            {
                throw new Exception("Invalid token passed as operation into simplification");
            }

            ValueToken result = null;

            if (operation.Value == Const.Add.ToString())
            {
                var add = Add(leftOperand, rightOperand);
                if (add.Success)
                {
                    result = add.Result;
                }
                else
                {
                    return(OperationResult.CreateFailure(add.ErrorMessage));
                }
            }
            if (operation.Value == Const.Subtract.ToString())
            {
                var sub = Subtract(leftOperand, rightOperand);
                if (sub.Success)
                {
                    result = sub.Result;
                }
                else
                {
                    return(OperationResult.CreateFailure(sub.ErrorMessage));
                }
            }
            if (operation.Value == Const.Multiply.ToString())
            {
                var mult = Multiply(leftOperand, rightOperand);
                if (mult.Success)
                {
                    result = mult.Result;
                }
                else
                {
                    return(OperationResult.CreateFailure(mult.ErrorMessage));
                }
            }
            if (operation.Value == Const.Divide.ToString())
            {
                var div = Divide(leftOperand, rightOperand);
                if (div.Success)
                {
                    result = div.Result;
                }
                else
                {
                    return(OperationResult.CreateFailure(div.ErrorMessage));
                }
            }
            if (operation.Value == Const.Exponentiate.ToString())
            {
                var exp = Exponentiate(leftOperand, rightOperand);
                if (exp.Success)
                {
                    result = exp.Result;
                }
                else
                {
                    return(OperationResult.CreateFailure(exp.ErrorMessage));
                }
            }

            if (result != null)
            {
                if (result is VariableToken vToken)
                {
                    if (vToken.Quotient == 0)
                    {
                        return(OperationResult.CreateSuccess(new ConstantToken(0)));
                    }
                }
                if (result is ExpressionToken exToken)
                {
                    foreach (var memer in exToken.Members.ToList())
                    {
                        if (memer is ConstantToken c && c.NumericValue == 0)
                        {
                            DeleteFromExpression(c, exToken);
                        }

                        if (memer is VariableToken v && v.Quotient == 0)
                        {
                            DeleteFromExpression(v, exToken);
                        }
                    }

                    if (exToken.Members.Count == 1)
                    {
                        return(OperationResult.CreateSuccess((ValueToken)exToken.Members[0]));
                    }

                    if (exToken.Members.Count == 0)
                    {
                        return(OperationResult.CreateSuccess((new ConstantToken(0))));
                    }
                }
                if (result is FractionToken)
                {
                    if (((FractionToken)result).Numerator is IHasNumericValue)
                    {
                        if (((IHasNumericValue)((FractionToken)result).Numerator).NumericValue == 0)
                        {
                            return(OperationResult.CreateSuccess(new ConstantToken(0)));
                        }
                    }

                    var gcd = result.GreatestCommonDivisor();
                    return(OperationResult.CreateSuccess(((IEliminatable)result).Eliminate(gcd)));
                }

                return(OperationResult.CreateSuccess(result));
            }

            throw new Exception($"Couldnt find an appropriate operation method for sign '{((BinaryOperationToken)operation).Value}'");
        }