/// <summary>
        /// 
        /// </summary>
        /// <param name="number1"></param>
        /// <param name="number2"></param>
        /// <param name="setValueIndicated">this is true if the return value is a clone and not the 
        /// same instance as number1</param>
        /// <returns></returns>
        private static INumeric Add(INumeric number1, INumeric number2, out bool isReplace)
        {
            //the default value is false, as most cases don't need a clone operation
            isReplace = false;

            if (number1 == null)
            {
                isReplace = true;
                return number2;
            }
            if (number2 == null)
                return number1;

            INumeric rv = null;

            //determine the longer number
            bool? num1IsLonger = Numeric.AbsoluteValueCompare(number1.As<Numeric>(),
                number2.As<Numeric>());

            //note: below we clone the 2nd arg if it is being modified as part of the operation
            //we don't clone the 1st arg as it is
            if (number1.IsPositive && number2.IsPositive)
            {
                rv = Increment(number1, number2);
            }
            else if (number1.IsPositive && number2.IsPositive == false)
            {
                switch (num1IsLonger)
                {
                    case null:
                        rv = Decrement(number1, number2);
                        break;
                    case true:
                        rv = Decrement(number1, number2);
                        break;
                    case false:
                        isReplace = true;
                        var cloneNum2 = number2.Clone();
                        rv = Decrement(cloneNum2, number1);
                        rv.As<Numeric>().IsPositive = false;
                        break;
                }
            }
            else if (number1.IsPositive == false && number2.IsPositive)
            {
                switch (num1IsLonger)
                {
                    case null:
                        rv = Decrement(number1, number2);
                        break;
                    case true:
                        rv = Decrement(number1, number2);
                        break;
                    case false:
                        isReplace = true;
                        rv = Decrement(number2.Clone(), number1);
                        rv.As<Numeric>().IsPositive = true;
                        break;
                }
            }
            else if (number1.IsPositive == false && number2.IsPositive == false)
            {
                rv = Increment(number1, number2);
                rv.As<Numeric>().IsPositive = false;
            }

            return rv;
        }
        public void Subtract(INumeric numeric)
        {
            if (numeric == null)
                return;

            //if (!this.HasCompatibleNumberSystem(numeric))
            //    throw new InvalidOperationException("incompatible number system");

            numeric.As<Numeric>().SwitchSign();
            bool isClone = false;
            var val = Add(this, numeric, out isClone);
            numeric.As<Numeric>().SwitchSign(); //we don't want to return a modified arg

            if (isClone)
                this.As<Numeric>().SetValue(val);
        }