public LargeInteger Pow(ulong power)
        {
            LargeInteger.Logger.Debug($"Entering Pow. this: {this}, power: {power}");

            this.Ensure();

            if (this == 0 && power == 0)
            {
                throw new DivideByZeroException("LargeInteger: divide by zero");
            }

            var result = new LargeInteger(1);

            for (var i = 0uL; i < power; i++)
            {
                result *= this;
            }

            LargeInteger.Logger.Debug($"Exiting Pow. result: {result.PrintLargeInteger()}");
            return result;
        }
        /// <summary>
        /// Divides the current instance by the divisor.
        /// </summary>
        /// <param name="divisor">Divisor</param>
        /// <returns>Tuple&lt;Quotient, Remainder&gt;</returns>
        public Tuple<LargeInteger, LargeInteger> Divide(LargeInteger divisor)
        {
            LargeInteger.Logger.Debug($"Entering Divide. this (dividend): {this.PrintLargeInteger()}, divisor: {divisor.PrintLargeInteger()}");

            this.Ensure().Ensure(ref divisor);

            if (this < divisor)
            {
                return new Tuple<LargeInteger, LargeInteger>(0, this);
            }

            // This is long division.

            var quotient = new LargeInteger { data = new List<uint>() };

            var testDividend = new LargeInteger { data = new List<uint>() };
            int dividendPosition = this.data.Count - 1;

            for (int i = 0; i < divisor.data.Count; i++)
            {
                testDividend.data.Insert(0, this.data[dividendPosition--]);
            }
            if (testDividend < divisor)
            {
                testDividend.data.Insert(0, this.data[dividendPosition--]);
            }

            int numberOfPlacesAddedToLastTestDividend = 0;

            do
            {
                int adjusterLength = testDividend.data.Count - divisor.data.Count + 1;
                QuotienScratchAdjuster adjuster = new LargeInteger
                {
                    data = new List<uint>(adjusterLength)
                };

                for (int i = 0; i < adjusterLength; i++)
                {
                    ((LargeInteger)adjuster).data.Add(0);
                }

                ((LargeInteger)adjuster).data.Add(1);

                LargeInteger quotientScratch = ((LargeInteger)adjuster).Clone();

                LargeInteger compareDividend;
                do
                {
                    compareDividend = quotientScratch * divisor;
                    if (compareDividend > testDividend)
                    {
                        if (adjuster == 1)
                        {
                            quotientScratch--;
                            compareDividend -= divisor;
                            if (compareDividend < testDividend)
                            {
                                break;
                            }
                        }
                        else
                        {
                            adjuster.Halve();
                            quotientScratch -= adjuster;
                        }
                    }
                    else if (compareDividend < testDividend)
                    {
                        if (adjuster == 1)
                        {
                            LargeInteger tempCompareDividend = compareDividend;
                            compareDividend += divisor;
                            if (compareDividend > testDividend)
                            {
                                compareDividend = tempCompareDividend;
                                break;
                            }
                            quotientScratch++;
                        }
                        else
                        {
                            adjuster.Halve();
                            quotientScratch += adjuster;
                        }
                    }
                    else
                    {
                        break;
                    }

                } while (true);

                if (numberOfPlacesAddedToLastTestDividend > quotientScratch.data.Count)
                {
                    if (numberOfPlacesAddedToLastTestDividend + 1 != quotientScratch.data.Count)
                    {
                        throw new ApplicationException(
                            $"Internal error: numberOfPlacesAddedToLastTestDividend > quotientScratch.data.Count && numberOfPlacesAddedToLastTestDividend {numberOfPlacesAddedToLastTestDividend} + 1 != quotientScratch.data.Count {quotientScratch.data.Count}. \r\nDividend:\r\n{this.PrintLargeInteger()}\r\nDivisor:\r\n{divisor.PrintLargeInteger()}");
                    }

                    quotient.data.Insert(0, 0);
                }

                for (int i = quotientScratch.data.Count - 1; i >= 0; i--)
                {
                    quotient.data.Insert(0, quotientScratch.data[i]);
                }

                testDividend -= compareDividend;

                numberOfPlacesAddedToLastTestDividend = 0;
                for (int i = 0; i < divisor.data.Count; i++)
                {
                    if (dividendPosition < 0)
                    {
                        break;
                    }
                    testDividend.data.Insert(0, this.data[dividendPosition--]);
                    numberOfPlacesAddedToLastTestDividend++;
                }

                if (testDividend < divisor)
                {
                    if (dividendPosition < 0)
                    {
                        LargeInteger.Logger.Debug($"Exiting Divide. quotient: {quotient.PrintLargeInteger()}, remainder: {testDividend.PrintLargeInteger()}");
                        return new Tuple<LargeInteger, LargeInteger>(quotient, testDividend);
                    }
                    testDividend.data.Insert(0, this.data[dividendPosition--]);
                    numberOfPlacesAddedToLastTestDividend++;
                }

            } while (true);
        }