/*
 * Copyright 2009 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 * INCLUDES MODIFICATIONS BY RICHARD ZSCHECH AS WELL AS GOOGLE.
 */
package java.math;

import static javaemul.internal.InternalPreconditions.checkCriticalArgument;
import static javaemul.internal.InternalPreconditions.checkNotNull;

import java.io.Serializable;
import java.util.Random;

/**
 * This class represents immutable integer numbers of arbitrary length. Large
 * numbers are typically used in security applications and therefore BigIntegers
 * offer dedicated functionality like the generation of large prime numbers or
 * the computation of modular inverse.
 * <p>
 * Since the class was modeled to offer all the functionality as the
 * {@link Integer} class does, it provides even methods that operate bitwise on
 * a two's complement representation of large integers. Note however that the
 * implementations favors an internal representation where magnitude and sign
 * are treated separately. Hence such operations are inefficient and should be
 * discouraged. In simple words: Do NOT implement any bit fields based on
 * BigInteger.
 */
public class BigInteger extends Number implements Comparable<BigInteger>,
    Serializable {

  /**
   * The {@code BigInteger} constant 1.
   */
  public static final BigInteger ONE = new BigInteger(1, 1);

  /* Fields used for the internal representation. */

  /**
   * The {@code BigInteger} constant 10.
   */
  public static final BigInteger TEN = new BigInteger(1, 10);

  /**
   * The {@code BigInteger} constant 0.
   */
  public static final BigInteger ZERO = new BigInteger(0, 0);

  /**
   * The {@code BigInteger} constant 0 used for comparison.
   */
  static final int EQUALS = 0;

  /**
   * The {@code BigInteger} constant 1 used for comparison.
   */
  static final int GREATER = 1;

  /**
   * The {@code BigInteger} constant -1 used for comparison.
   */
  static final int LESS = -1;

  /**
   * The {@code BigInteger} constant -1.
   */
  static final BigInteger MINUS_ONE = new BigInteger(-1, 1);

  /**
   * 2^32.
   */
  static final double POW32 = 4294967296d;

  /**
   * All the {@code BigInteger} numbers in the range [0,10] are cached.
   */
  static final BigInteger[] SMALL_VALUES = {
      ZERO, ONE, new BigInteger(1, 2), new BigInteger(1, 3),
      new BigInteger(1, 4), new BigInteger(1, 5), new BigInteger(1, 6),
      new BigInteger(1, 7), new BigInteger(1, 8), new BigInteger(1, 9), TEN};

  static final BigInteger[] TWO_POWS;

  /**
   * This is the serialVersionUID used by the sun implementation.
   */
  private static final long serialVersionUID = -8287574255936472291L;

  static {
    TWO_POWS = new BigInteger[32];
    for (int i = 0; i < TWO_POWS.length; i++) {
      TWO_POWS[i] = BigInteger.valueOf(1L << i);
    }
  }

  /**
   * Returns a random positive {@code BigInteger} instance in the range [0,
   * 2^(bitLength)-1] which is probably prime. The probability that the returned
   * {@code BigInteger} is prime is beyond (1-1/2^80).
   * <p>
   * <b>Implementation Note:</b> Currently {@code rnd} is ignored.
   *
   * @param bitLength length of the new {@code BigInteger} in bits.
   * @param rnd random generator used to generate the new {@code BigInteger}.
   * @return probably prime random {@code BigInteger} instance.
   * @throws ArithmeticException if {@code bitLength < 2}.
   */
  public static BigInteger probablePrime(int bitLength, Random rnd) {
    return new BigInteger(bitLength, 100, rnd);
  }

  public static BigInteger valueOf(long val) {
    if (val < 0) {
      if (val != -1) {
        return new BigInteger(-1, -val);
      }
      return MINUS_ONE;
    } else if (val <= 10) {
      return SMALL_VALUES[(int) val];
    } else {
      // (val > 10)
      return new BigInteger(1, val);
    }
  }

  static BigInteger getPowerOfTwo(int exp) {
    if (exp < TWO_POWS.length) {
      return TWO_POWS[exp];
    }
    int intCount = exp >> 5;
    int bitN = exp & 31;
    int resDigits[] = new int[intCount + 1];
    resDigits[intCount] = 1 << bitN;
    return new BigInteger(1, intCount + 1, resDigits);
  }

  static BigInteger valueOf(double val) {
    if (val < 0) {
      if (val != -1) {
        return new BigInteger(-1, -val);
      }
      return MINUS_ONE;
    } else if (val <= 10) {
      return SMALL_VALUES[(int) val];
    } else {
      // (val > 10)
      return new BigInteger(1, val);
    }
  }

  /**
   * @see BigInteger#BigInteger(String, int)
   */
  private static void setFromString(BigInteger bi, String val, int radix) {
    int sign;
    int[] digits;
    int numberLength;
    int stringLength = val.length();
    int startChar;
    int endChar = stringLength;

    if (val.charAt(0) == '-') {
      sign = -1;
      startChar = 1;
      stringLength--;
    } else {
      sign = 1;
      startChar = 0;
    }
    /*
     * We use the following algorithm: split a string into portions of n
     * characters and convert each portion to an integer according to the radix.
     * Then convert an exp(radix, n) based number to binary using the
     * multiplication method. See D. Knuth, The Art of Computer Programming,
     * vol. 2.
     */

    int charsPerInt = Conversion.digitFitInInt[radix];
    int bigRadixDigitsLength = stringLength / charsPerInt;
    int topChars = stringLength % charsPerInt;

    if (topChars != 0) {
      bigRadixDigitsLength++;
    }
    digits = new int[bigRadixDigitsLength];
    // Get the maximal power of radix that fits in int
    int bigRadix = Conversion.bigRadices[radix - 2];
    // Parse an input string and accumulate the BigInteger's magnitude
    int digitIndex = 0; // index of digits array
    int substrEnd = startChar + ((topChars == 0) ? charsPerInt : topChars);
    int newDigit;

    for (int substrStart = startChar; substrStart < endChar; substrStart = substrEnd, substrEnd = substrStart
        + charsPerInt) {
      int bigRadixDigit = Integer.parseInt(
          val.substring(substrStart, substrEnd), radix);
      newDigit = Multiplication.multiplyByInt(digits, digitIndex, bigRadix);
      newDigit += Elementary.inplaceAdd(digits, digitIndex, bigRadixDigit);
      digits[digitIndex++] = newDigit;
    }
    numberLength = digitIndex;
    bi.sign = sign;
    bi.numberLength = numberLength;
    bi.digits = digits;
    bi.cutOffLeadingZeroes();
  }

  /**
   * Converts an integral double to an unsigned integer; ie 2^31 will be
   * returned as 0x80000000.
   *
   * @param val
   * @return val as an unsigned int
   */
  @SuppressWarnings("unusable-by-js")
  private static native int toUnsignedInt(double val) /*-{
    return val | 0;
  }-*/;

  /**
   * The magnitude of this big integer. This array is in little endian order and
   * each "digit" is a 32-bit unsigned integer. For example: {@code 13} is
   * represented as [ 13 ] {@code -13} is represented as [ 13 ] {@code 2^32 +
   * 13} is represented as [ 13, 1 ] {@code 2^64 + 13} is represented as [ 13,
   * 0, 1 ] {@code 2^31} is represented as [ Integer.MIN_VALUE ] The magnitude
   * array may be longer than strictly necessary, which results in additional
   * trailing zeros.
   *
   * <p>TODO(jat): consider changing to 24-bit integers for better performance
   * in browsers.
   */
  transient int digits[];

  /**
   * The length of this in measured in ints. Can be less than digits.length().
   */
  transient int numberLength;

  /**
   * The sign of this.
   */
  transient int sign;

  private transient int firstNonzeroDigit = -2;

  /**
   * Cache for the hash code.
   */
  private transient int hashCode = 0;

  /**
   * Constructs a new {@code BigInteger} from the given two's complement
   * representation. The most significant byte is the entry at index 0. The most
   * significant bit of this entry determines the sign of the new {@code
   * BigInteger} instance. The given array must not be empty.
   *
   * @param val two's complement representation of the new {@code BigInteger}.
   * @throws NullPointerException if {@code val == null}.
   * @throws NumberFormatException if the length of {@code val} is zero.
   */
  public BigInteger(byte[] val) {
    if (val.length == 0) {
      // math.12=Zero length BigInteger
      throw new NumberFormatException("Zero length BigInteger"); //$NON-NLS-1$
    }
    if (val[0] < 0) {
      sign = -1;
      putBytesNegativeToIntegers(val);
    } else {
      sign = 1;
      putBytesPositiveToIntegers(val);
    }
    cutOffLeadingZeroes();
  }

  /**
   * Constructs a new {@code BigInteger} instance with the given sign and the
   * given magnitude. The sign is given as an integer (-1 for negative, 0 for
   * zero, 1 for positive). The magnitude is specified as a byte array. The most
   * significant byte is the entry at index 0.
   *
   * @param signum sign of the new {@code BigInteger} (-1 for negative, 0 for
   *          zero, 1 for positive).
   * @param magnitude magnitude of the new {@code BigInteger} with the most
   *          significant byte first.
   * @throws NullPointerException if {@code magnitude == null}.
   * @throws NumberFormatException if the sign is not one of -1, 0, 1 or if the
   *           sign is zero and the magnitude contains non-zero entries.
   */
  public BigInteger(int signum, byte[] magnitude) {
    checkNotNull(magnitude);

    if ((signum < -1) || (signum > 1)) {
      // math.13=Invalid signum value
      throw new NumberFormatException("Invalid signum value"); //$NON-NLS-1$
    }
    if (signum == 0) {
      for (byte element : magnitude) {
        if (element != 0) {
          // math.14=signum-magnitude mismatch
          throw new NumberFormatException("signum-magnitude mismatch"); //$NON-NLS-1$
        }
      }
    }
    if (magnitude.length == 0) {
      sign = 0;
      numberLength = 1;
      digits = new int[] {0};
    } else {
      sign = signum;
      putBytesPositiveToIntegers(magnitude);
      cutOffLeadingZeroes();
    }
  }

  /**
   * Constructs a random {@code BigInteger} instance in the range [0,
   * 2^(bitLength)-1] which is probably prime. The probability that the returned
   * {@code BigInteger} is prime is beyond (1-1/2^certainty).
   *
   * @param bitLength length of the new {@code BigInteger} in bits.
   * @param certainty tolerated primality uncertainty.
   * @param rnd is an optional random generator to be used.
   * @throws ArithmeticException if {@code bitLength} < 2.
   */
  public BigInteger(int bitLength, int certainty, Random rnd) {
    if (bitLength < 2) {
      // math.1C=bitLength < 2
      throw new ArithmeticException("bitLength < 2"); //$NON-NLS-1$
    }
    BigInteger me = Primality.consBigInteger(bitLength, certainty, rnd);
    sign = me.sign;
    numberLength = me.numberLength;
    digits = me.digits;
  }

  /**
   * Constructs a random non-negative {@code BigInteger} instance in the range
   * [0, 2^(numBits)-1].
   *
   * @param numBits maximum length of the new {@code BigInteger} in bits.
   * @param rnd is an optional random generator to be used.
   * @throws IllegalArgumentException if {@code numBits} < 0.
   */
  public BigInteger(int numBits, Random rnd) {
    checkCriticalArgument(numBits >= 0, "numBits must be non-negative");

    if (numBits == 0) {
      sign = 0;
      numberLength = 1;
      digits = new int[] {0};
    } else {
      sign = 1;
      numberLength = (numBits + 31) >> 5;
      digits = new int[numberLength];
      for (int i = 0; i < numberLength; i++) {
        digits[i] = rnd.nextInt();
      }
      // Using only the necessary bits
      digits[numberLength - 1] >>>= (-numBits) & 31;
      cutOffLeadingZeroes();
    }
  }

  /**
   * Constructs a new {@code BigInteger} instance from the string
   * representation. The string representation consists of an optional minus
   * sign followed by a non-empty sequence of decimal digits.
   *
   * @param val string representation of the new {@code BigInteger}.
   * @throws NullPointerException if {@code val == null}.
   * @throws NumberFormatException if {@code val} is not a valid representation
   *           of a {@code BigInteger}.
   */
  public BigInteger(String val) {
    this(val, 10);
  }

  /**
   * Constructs a new {@code BigInteger} instance from the string
   * representation. The string representation consists of an optional minus
   * sign followed by a non-empty sequence of digits in the specified radix. For
   * the conversion the method {@code Character.digit(char, radix)} is used.
   *
   * @param val string representation of the new {@code BigInteger}.
   * @param radix the base to be used for the conversion.
   * @throws NullPointerException if {@code val == null}.
   * @throws NumberFormatException if {@code val} is not a valid representation
   *           of a {@code BigInteger} or if {@code radix < Character.MIN_RADIX}
   *           or {@code radix > Character.MAX_RADIX}.
   */
  public BigInteger(String val, int radix) {
    checkNotNull(val);

    if ((radix < Character.MIN_RADIX) || (radix > Character.MAX_RADIX)) {
      // math.11=Radix out of range
      throw new NumberFormatException("Radix out of range"); //$NON-NLS-1$
    }
    if (val.isEmpty()) {
      // math.12=Zero length BigInteger
      throw new NumberFormatException("Zero length BigInteger"); //$NON-NLS-1$
    }
    setFromString(this, val, radix);
  }

  /**
   * Constructs a number which array is of size 1.
   *
   * @param sign the sign of the number
   * @param value the only one digit of array
   */
  BigInteger(int sign, int value) {
    this.sign = sign;
    numberLength = 1;
    digits = new int[] {value};
  }

  /**
   * Creates a new {@code BigInteger} with the given sign and magnitude. This
   * constructor does not create a copy, so any changes to the reference will
   * affect the new number.
   *
   * @param signum The sign of the number represented by {@code digits}
   * @param digits The magnitude of the number
   */
  BigInteger(int signum, int digits[]) {
    if (digits.length == 0) {
      sign = 0;
      numberLength = 1;
      this.digits = new int[] {0};
    } else {
      sign = signum;
      numberLength = digits.length;
      this.digits = digits;
      cutOffLeadingZeroes();
    }
  }

  /**
   * Constructs a number without to create new space. This construct should be
   * used only if the three fields of representation are known.
   *
   * @param sign the sign of the number
   * @param numberLength the length of the internal array
   * @param digits a reference of some array created before
   */
  BigInteger(int sign, int numberLength, int[] digits) {
    this.sign = sign;
    this.numberLength = numberLength;
    this.digits = digits;
  }

  /**
   * Creates a new {@code BigInteger} whose value is equal to the specified
   * {@code long}.
   *
   * @param sign the sign of the number
   * @param val the value of the new {@code BigInteger}.
   */
  BigInteger(int sign, long val) {
    // PRE: (val >= 0) && (sign >= -1) && (sign <= 1)
    this.sign = sign;
    if ((val & 0xFFFFFFFF00000000L) == 0) {
      // It fits in one 'int'
      numberLength = 1;
      digits = new int[] {(int) val};
    } else {
      numberLength = 2;
      digits = new int[] {(int) val, (int) (val >> 32)};
    }
  }

  /**
   * Creates a new {@code BigInteger} whose value is equal to the specified
   * {@code double} (which must be an integral value).
   *
   * @param sign the sign of the number
   * @param val the value of the new {@code BigInteger}.
   */
  private BigInteger(int sign, double val) {
    // PRE: (val >= 0) && (sign >= -1) && (sign <= 1)
    this.sign = sign;
    if (val < POW32) {
      // It fits in one 'int'
      numberLength = 1;
      digits = new int[] { toUnsignedInt(val) };
    } else {
      numberLength = 2;
      digits = new int[] { toUnsignedInt(val % POW32), toUnsignedInt(val / POW32) };
    }
  }

  /**
   * Returns a (new) {@code BigInteger} whose value is the absolute value of
   * {@code this}.
   *
   * @return {@code abs(this)}.
   */
  public BigInteger abs() {
    return ((sign < 0) ? new BigInteger(1, numberLength, digits) : this);
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this + val}.
   *
   * @param val value to be added to {@code this}.
   * @return {@code this + val}.
   * @throws NullPointerException if {@code val == null}.
   */
  public BigInteger add(BigInteger val) {
    return Elementary.add(this, val);
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this & val}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @param val value to be and'ed with {@code this}.
   * @return {@code this & val}.
   * @throws NullPointerException if {@code val == null}.
   */
  public BigInteger and(BigInteger val) {
    return Logical.and(this, val);
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this & ~val}.
   * Evaluating {@code x.andNot(val)} returns the same result as {@code
   * x.and(val.not())}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @param val value to be not'ed and then and'ed with {@code this}.
   * @return {@code this & ~val}.
   * @throws NullPointerException if {@code val == null}.
   */
  public BigInteger andNot(BigInteger val) {
    return Logical.andNot(this, val);
  }

  /**
   * Use {@code bitLength(0)} if you want to know the length of the binary value
   * in bits.
   * <p>
   * Returns the number of bits in the binary representation of {@code this}
   * which differ from the sign bit. If {@code this} is positive the result is
   * equivalent to the number of bits set in the binary representation of
   * {@code this}. If {@code this} is negative the result is equivalent to the
   * number of bits set in the binary representation of {@code -this-1}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @return number of bits in the binary representation of {@code this} which
   *         differ from the sign bit
   */
  public int bitCount() {
    return BitLevel.bitCount(this);
  }

  /**
   * Returns the length of the value's two's complement representation without
   * leading zeros for positive numbers / without leading ones for negative
   * values.
   * <p>
   * The two's complement representation of {@code this} will be at least
   * {@code bitLength() + 1} bits long.
   * <p>
   * The value will fit into an {@code int} if {@code bitLength() < 32} or into
   * a {@code long} if {@code bitLength() < 64}.
   *
   * @return the length of the minimal two's complement representation for
   *         {@code this} without the sign bit.
   */
  public int bitLength() {
    return BitLevel.bitLength(this);
  }

  /**
   * Converts value of this {@code BigInteger} to a {@code byte} if it fits it,
   * otherwise {@code ArithmeticException} is thrown.
   *
   * @return this {@code BigInteger} converted to a {@code byte}.
   * @throws ArithmeticException if the value of this {@code BigInteger}
   *         does not fit in a {@code byte}.
   */
  public byte byteValueExact() {
    if (numberLength <= 1 && bitLength() < Byte.SIZE) {
      return byteValue();
    }
    throw new ArithmeticException("out of byte range");
  }

  /**
   * Returns a new {@code BigInteger} which has the same binary representation
   * as {@code this} but with the bit at position n cleared. The result is
   * equivalent to {@code this & ~(2^n)}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @param n position where the bit in {@code this} has to be cleared.
   * @return {@code this & ~(2^n)}.
   * @throws ArithmeticException if {@code n < 0}.
   */
  public BigInteger clearBit(int n) {
    if (testBit(n)) {
      return BitLevel.flipBit(this, n);
    }
    return this;
  }

  /**
   * Compares this {@code BigInteger} with {@code val}. Returns one of the three
   * values 1, 0, or -1.
   *
   * @param val value to be compared with {@code this}.
   * @return {@code 1} if {@code this > val}, {@code -1} if {@code this < val} ,
   *         {@code 0} if {@code this == val}.
   * @throws NullPointerException if {@code val == null}.
   */
  @Override
  public int compareTo(BigInteger val) {
    if (sign > val.sign) {
      return GREATER;
    }
    if (sign < val.sign) {
      return LESS;
    }
    if (numberLength > val.numberLength) {
      return sign;
    }
    if (numberLength < val.numberLength) {
      return -val.sign;
    }
    // Equal sign and equal numberLength
    return (sign * Elementary.compareArrays(digits, val.digits, numberLength));
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this / divisor}.
   *
   * @param divisor value by which {@code this} is divided.
   * @return {@code this / divisor}.
   * @throws NullPointerException if {@code divisor == null}.
   * @throws ArithmeticException if {@code divisor == 0}.
   */
  public BigInteger divide(BigInteger divisor) {
    if (divisor.sign == 0) {
      // math.17=BigInteger divide by zero
      throw new ArithmeticException("BigInteger divide by zero"); //$NON-NLS-1$
    }
    int divisorSign = divisor.sign;
    if (divisor.isOne()) {
      return ((divisor.sign > 0) ? this : this.negate());
    }
    int thisSign = sign;
    int thisLen = numberLength;
    int divisorLen = divisor.numberLength;
    if (thisLen + divisorLen == 2) {
      long val = (digits[0] & 0xFFFFFFFFL) / (divisor.digits[0] & 0xFFFFFFFFL);
      if (thisSign != divisorSign) {
        val = -val;
      }
      return valueOf(val);
    }
    int cmp = ((thisLen != divisorLen) ? ((thisLen > divisorLen) ? 1 : -1)
        : Elementary.compareArrays(digits, divisor.digits, thisLen));
    if (cmp == EQUALS) {
      return ((thisSign == divisorSign) ? ONE : MINUS_ONE);
    }
    if (cmp == LESS) {
      return ZERO;
    }
    int resLength = thisLen - divisorLen + 1;
    int resDigits[] = new int[resLength];
    int resSign = ((thisSign == divisorSign) ? 1 : -1);
    if (divisorLen == 1) {
      Division.divideArrayByInt(resDigits, digits, thisLen, divisor.digits[0]);
    } else {
      Division.divide(resDigits, resLength, digits, thisLen, divisor.digits,
          divisorLen);
    }
    BigInteger result = new BigInteger(resSign, resLength, resDigits);
    result.cutOffLeadingZeroes();
    return result;
  }

  /**
   * Returns a {@code BigInteger} array which contains {@code this / divisor} at
   * index 0 and {@code this % divisor} at index 1.
   *
   * @param divisor value by which {@code this} is divided.
   * @return {@code [this / divisor, this % divisor]}.
   * @throws NullPointerException if {@code divisor == null}.
   * @throws ArithmeticException if {@code divisor == 0}.
   * @see #divide
   * @see #remainder
   */
  public BigInteger[] divideAndRemainder(BigInteger divisor) {
    int divisorSign = divisor.sign;
    if (divisorSign == 0) {
      // math.17=BigInteger divide by zero
      throw new ArithmeticException("BigInteger divide by zero"); //$NON-NLS-1$
    }
    int divisorLen = divisor.numberLength;
    int[] divisorDigits = divisor.digits;
    if (divisorLen == 1) {
      return Division.divideAndRemainderByInteger(this, divisorDigits[0],
          divisorSign);
    }
    // res[0] is a quotient and res[1] is a remainder:
    int[] thisDigits = digits;
    int thisLen = numberLength;
    int cmp = (thisLen != divisorLen) ? ((thisLen > divisorLen) ? 1 : -1)
        : Elementary.compareArrays(thisDigits, divisorDigits, thisLen);
    if (cmp < 0) {
      return new BigInteger[] {ZERO, this};
    }
    int thisSign = sign;
    int quotientLength = thisLen - divisorLen + 1;
    int remainderLength = divisorLen;
    int quotientSign = ((thisSign == divisorSign) ? 1 : -1);
    int quotientDigits[] = new int[quotientLength];
    int remainderDigits[] = Division.divide(quotientDigits, quotientLength,
        thisDigits, thisLen, divisorDigits, divisorLen);
    BigInteger result0 = new BigInteger(quotientSign, quotientLength,
        quotientDigits);
    BigInteger result1 = new BigInteger(thisSign, remainderLength,
        remainderDigits);
    result0.cutOffLeadingZeroes();
    result1.cutOffLeadingZeroes();
    return new BigInteger[] {result0, result1};
  }

  /**
   * Returns this {@code BigInteger} as an double value. If {@code this} is too
   * big to be represented as an double, then {@code Double.POSITIVE_INFINITY}
   * or {@code Double.NEGATIVE_INFINITY} is returned. Note, that not all
   * integers x in the range [-Double.MAX_VALUE, Double.MAX_VALUE] can be
   * represented as a double. The double representation has a mantissa of length
   * 53. For example, 2^53+1 = 9007199254740993 is returned as double
   * 9007199254740992.0.
   *
   * @return this {@code BigInteger} as a double value
   */
  @Override
  public double doubleValue() {
    return Double.parseDouble(this.toString());
  }

  /**
   * Returns {@code true} if {@code x} is a BigInteger instance and if this
   * instance is equal to this {@code BigInteger}.
   *
   * @param x object to be compared with {@code this}.
   * @return true if {@code x} is a BigInteger and {@code this == x}, {@code
   *         false} otherwise.
   */
  @Override
  public boolean equals(Object x) {
    if (this == x) {
      return true;
    }
    if (x instanceof BigInteger) {
      BigInteger x1 = (BigInteger) x;
      return sign == x1.sign && numberLength == x1.numberLength
          && equalsArrays(x1.digits);
    }
    return false;
  }

  /**
   * Returns a new {@code BigInteger} which has the same binary representation
   * as {@code this} but with the bit at position n flipped. The result is
   * equivalent to {@code this ^ 2^n}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @param n position where the bit in {@code this} has to be flipped.
   * @return {@code this ^ 2^n}.
   * @throws ArithmeticException if {@code n < 0}.
   */
  public BigInteger flipBit(int n) {
    if (n < 0) {
      // math.15=Negative bit address
      throw new ArithmeticException("Negative bit address"); //$NON-NLS-1$
    }
    return BitLevel.flipBit(this, n);
  }

  /**
   * Returns this {@code BigInteger} as an float value. If {@code this} is too
   * big to be represented as an float, then {@code Float.POSITIVE_INFINITY} or
   * {@code Float.NEGATIVE_INFINITY} is returned. Note, that not all integers x
   * in the range [-Float.MAX_VALUE, Float.MAX_VALUE] can be represented as a
   * float. The float representation has a mantissa of length 24. For example,
   * 2^24+1 = 16777217 is returned as float 16777216.0.
   *
   * @return this {@code BigInteger} as a float value.
   */
  @Override
  public float floatValue() {
    return Float.parseFloat(this.toString());
  }

  /**
   * Returns a new {@code BigInteger} whose value is greatest common divisor of
   * {@code this} and {@code val}. If {@code this==0} and {@code val==0} then
   * zero is returned, otherwise the result is positive.
   *
   * @param val value with which the greatest common divisor is computed.
   * @return {@code gcd(this, val)}.
   * @throws NullPointerException if {@code val == null}.
   */
  public BigInteger gcd(BigInteger val) {
    BigInteger val1 = this.abs();
    BigInteger val2 = val.abs();
    // To avoid a possible division by zero
    if (val1.signum() == 0) {
      return val2;
    } else if (val2.signum() == 0) {
      return val1;
    }

    // Optimization for small operands
    // (op2.bitLength() < 64) and (op1.bitLength() < 64)
    if (((val1.numberLength == 1) || ((val1.numberLength == 2) && (val1.digits[1] > 0)))
        && (val2.numberLength == 1 || (val2.numberLength == 2 && val2.digits[1] > 0))) {
      return BigInteger.valueOf(Division.gcdBinary(val1.longValue(),
          val2.longValue()));
    }

    return Division.gcdBinary(val1.copy(), val2.copy());
  }

  /**
   * Returns the position of the lowest set bit in the two's complement
   * representation of this {@code BigInteger}. If all bits are zero (this=0)
   * then -1 is returned as result.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @return position of lowest bit if {@code this != 0}, {@code -1} otherwise
   */
  public int getLowestSetBit() {
    if (sign == 0) {
      return -1;
    }
    // (sign != 0) implies that exists some non zero digit
    int i = getFirstNonzeroDigit();
    return ((i << 5) + Integer.numberOfTrailingZeros(digits[i]));
  }

  /**
   * Returns a hash code for this {@code BigInteger}.
   *
   * @return hash code for {@code this}.
   */
  @Override
  public int hashCode() {
    if (hashCode != 0) {
      return hashCode;
    }
    for (int i = 0; i < digits.length; i++) {
      hashCode = (hashCode * 33 + (digits[i] & 0xffffffff));
    }
    hashCode = hashCode * sign;
    return hashCode;
  }

  /**
   * Returns this {@code BigInteger} as an int value. If {@code this} is too big
   * to be represented as an int, then {@code this} % 2^32 is returned.
   *
   * @return this {@code BigInteger} as an int value.
   */
  @Override
  public int intValue() {
    int i = digits[0];
    // i is always positive except for Integer.MIN_VALUE because of int overflow
    return (sign > 0 || i == Integer.MIN_VALUE) ? i : -i;
  }

  /**
   * Converts value of this {@code BigInteger} to an {@code int} if it fits it,
   * otherwise {@code ArithmeticException} is thrown.
   *
   * @return this {@code BigInteger} converted to an {@code int}.
   * @throws ArithmeticException if the value of this {@code BigInteger}
   *         does not fit in an {@code int}.
   */
  public int intValueExact() {
    if (numberLength <= 1 && bitLength() < Integer.SIZE) {
      return intValue();
    }
    throw new ArithmeticException("out of int range");
  }

  /**
   * Tests whether this {@code BigInteger} is probably prime. If {@code true} is
   * returned, then this is prime with a probability beyond (1-1/2^certainty).
   * If {@code false} is returned, then this is definitely composite. If the
   * argument {@code certainty} <= 0, then this method returns true.
   *
   * @param certainty tolerated primality uncertainty.
   * @return {@code true}, if {@code this} is probably prime, {@code false}
   *         otherwise.
   */
  public boolean isProbablePrime(int certainty) {
    return Primality.isProbablePrime(abs(), certainty);
  }

  /**
   * Returns this {@code BigInteger} as an long value. If {@code this} is too
   * big to be represented as an long, then {@code this} % 2^64 is returned.
   *
   * @return this {@code BigInteger} as a long value.
   */
  @Override
  public long longValue() {
    long value = (numberLength > 1) ? (((long) digits[1]) << 32)
        | (digits[0] & 0xFFFFFFFFL) : (digits[0] & 0xFFFFFFFFL);
    return (sign * value);
  }

  /**
   * Converts value of this {@code BigInteger} to a {@code long} if it fits it,
   * otherwise {@code ArithmeticException} is thrown.
   *
   * @return this {@code BigInteger} converted to a {@code long}.
   * @throws ArithmeticException if the value of this {@code BigInteger}
   *         does not fit in a {@code long}.
   */
  public long longValueExact() {
    if (numberLength <= 2 && bitLength() < Long.SIZE) {
      return longValue();
    }
    throw new ArithmeticException("out of long range");
  }

  /**
   * Returns the maximum of this {@code BigInteger} and {@code val}.
   *
   * @param val value to be used to compute the maximum with {@code this}
   * @return {@code max(this, val)}
   * @throws NullPointerException if {@code val == null}
   */
  public BigInteger max(BigInteger val) {
    return ((this.compareTo(val) == GREATER) ? this : val);
  }

  /**
   * Returns the minimum of this {@code BigInteger} and {@code val}.
   *
   * @param val value to be used to compute the minimum with {@code this}.
   * @return {@code min(this, val)}.
   * @throws NullPointerException if {@code val == null}.
   */
  public BigInteger min(BigInteger val) {
    return ((this.compareTo(val) == LESS) ? this : val);
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this mod m}. The
   * modulus {@code m} must be positive. The result is guaranteed to be in the
   * interval {@code [0, m)} (0 inclusive, m exclusive). The behavior of this
   * function is not equivalent to the behavior of the % operator defined for
   * the built-in {@code int}'s.
   *
   * @param m the modulus.
   * @return {@code this mod m}.
   * @throws NullPointerException if {@code m == null}.
   * @throws ArithmeticException if {@code m < 0}.
   */
  public BigInteger mod(BigInteger m) {
    if (m.sign <= 0) {
      // math.18=BigInteger: modulus not positive
      throw new ArithmeticException("BigInteger: modulus not positive"); //$NON-NLS-1$
    }
    BigInteger rem = remainder(m);
    return ((rem.sign < 0) ? rem.add(m) : rem);
  }

  // @Override
  // public double doubleValue() {
  // return Conversion.bigInteger2Double(this);
  // }

  /**
   * Returns a new {@code BigInteger} whose value is {@code 1/this mod m}. The
   * modulus {@code m} must be positive. The result is guaranteed to be in the
   * interval {@code [0, m)} (0 inclusive, m exclusive). If {@code this} is not
   * relatively prime to m, then an exception is thrown.
   *
   * @param m the modulus.
   * @return {@code 1/this mod m}.
   * @throws NullPointerException if {@code m == null}
   * @throws ArithmeticException if {@code m < 0 or} if {@code this} is not
   *           relatively prime to {@code m}
   */
  public BigInteger modInverse(BigInteger m) {
    if (m.sign <= 0) {
      // math.18=BigInteger: modulus not positive
      throw new ArithmeticException("BigInteger: modulus not positive"); //$NON-NLS-1$
    }
    // If both are even, no inverse exists
    if (!(testBit(0) || m.testBit(0))) {
      // math.19=BigInteger not invertible.
      throw new ArithmeticException("BigInteger not invertible."); //$NON-NLS-1$
    }
    if (m.isOne()) {
      return ZERO;
    }

    // From now on: (m > 1)
    BigInteger res = Division.modInverseMontgomery(abs().mod(m), m);
    if (res.sign == 0) {
      // math.19=BigInteger not invertible.
      throw new ArithmeticException("BigInteger not invertible."); //$NON-NLS-1$
    }

    res = ((sign < 0) ? m.subtract(res) : res);
    return res;
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this^exponent mod m}
   * . The modulus {@code m} must be positive. The result is guaranteed to be in
   * the interval {@code [0, m)} (0 inclusive, m exclusive). If the exponent is
   * negative, then {@code this.modInverse(m)^(-exponent) mod m)} is computed.
   * The inverse of this only exists if {@code this} is relatively prime to m,
   * otherwise an exception is thrown.
   *
   * @param exponent the exponent.
   * @param m the modulus.
   * @return {@code this^exponent mod val}.
   * @throws NullPointerException if {@code m == null} or {@code exponent ==
   *           null}.
   * @throws ArithmeticException if {@code m < 0} or if {@code exponent<0} and
   *           this is not relatively prime to {@code m}.
   */
  public BigInteger modPow(BigInteger exponent, BigInteger m) {
    if (m.sign <= 0) {
      // math.18=BigInteger: modulus not positive
      throw new ArithmeticException("BigInteger: modulus not positive"); //$NON-NLS-1$
    }
    BigInteger base = this;

    if (m.isOne() | (exponent.sign > 0 & base.sign == 0)) {
      return BigInteger.ZERO;
    }
    if (base.sign == 0 && exponent.sign == 0) {
      return BigInteger.ONE;
    }
    if (exponent.sign < 0) {
      base = modInverse(m);
      exponent = exponent.negate();
    }
    // From now on: (m > 0) and (exponent >= 0)
    BigInteger res = (m.testBit(0)) ? Division.oddModPow(base.abs(), exponent,
        m) : Division.evenModPow(base.abs(), exponent, m);
    if ((base.sign < 0) && exponent.testBit(0)) {
      // -b^e mod m == ((-1 mod m) * (b^e mod m)) mod m
      res = m.subtract(BigInteger.ONE).multiply(res).mod(m);
    }
    // else exponent is even, so base^exp is positive
    return res;
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this * val}.
   *
   * @param val value to be multiplied with {@code this}.
   * @return {@code this * val}.
   * @throws NullPointerException if {@code val == null}.
   */
  public BigInteger multiply(BigInteger val) {
    // This let us to throw NullPointerException when val == null
    if (val.sign == 0) {
      return ZERO;
    }
    if (sign == 0) {
      return ZERO;
    }
    return Multiplication.multiply(this, val);
  }

  /**
   * Returns a new {@code BigInteger} whose value is the {@code -this}.
   *
   * @return {@code -this}.
   */
  public BigInteger negate() {
    return ((sign == 0) ? this : new BigInteger(-sign, numberLength, digits));
  }

  /**
   * Returns the smallest integer x > {@code this} which is probably prime as a
   * {@code BigInteger} instance. The probability that the returned {@code
   * BigInteger} is prime is beyond (1-1/2^80).
   *
   * @return smallest integer > {@code this} which is robably prime.
   * @throws ArithmeticException if {@code this < 0}.
   */
  public BigInteger nextProbablePrime() {
    if (sign < 0) {
      // math.1A=start < 0: {0}
      throw new ArithmeticException("start < 0: " + this); //$NON-NLS-1$
    }
    return Primality.nextProbablePrime(this);
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code ~this}. The result
   * of this operation is {@code -this-1}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @return {@code ~this}.
   */
  public BigInteger not() {
    return Logical.not(this);
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this | val}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @param val value to be or'ed with {@code this}.
   * @return {@code this | val}.
   * @throws NullPointerException if {@code val == null}.
   */
  public BigInteger or(BigInteger val) {
    return Logical.or(this, val);
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this ^ exp}.
   *
   * @param exp exponent to which {@code this} is raised.
   * @return {@code this ^ exp}.
   * @throws ArithmeticException if {@code exp < 0}.
   */
  public BigInteger pow(int exp) {
    if (exp < 0) {
      // math.16=Negative exponent
      throw new ArithmeticException("Negative exponent"); //$NON-NLS-1$
    }
    if (exp == 0) {
      return ONE;
    } else if (exp == 1 || equals(ONE) || equals(ZERO)) {
      return this;
    }

    // if even take out 2^x factor which we can
    // calculate by shifting.
    if (!testBit(0)) {
      int x = 1;
      while (!testBit(x)) {
        x++;
      }
      return getPowerOfTwo(x * exp).multiply(this.shiftRight(x).pow(exp));
    }
    return Multiplication.pow(this, exp);
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this % divisor}.
   * Regarding signs this methods has the same behavior as the % operator on
   * int's, i.e. the sign of the remainder is the same as the sign of this.
   *
   * @param divisor value by which {@code this} is divided.
   * @return {@code this % divisor}.
   * @throws NullPointerException if {@code divisor == null}.
   * @throws ArithmeticException if {@code divisor == 0}.
   */
  public BigInteger remainder(BigInteger divisor) {
    if (divisor.sign == 0) {
      // math.17=BigInteger divide by zero
      throw new ArithmeticException("BigInteger divide by zero"); //$NON-NLS-1$
    }
    int thisLen = numberLength;
    int divisorLen = divisor.numberLength;
    if (((thisLen != divisorLen) ? ((thisLen > divisorLen) ? 1 : -1)
        : Elementary.compareArrays(digits, divisor.digits, thisLen)) == LESS) {
      return this;
    }
    int resLength = divisorLen;
    int resDigits[] = new int[resLength];
    if (resLength == 1) {
      resDigits[0] = Division.remainderArrayByInt(digits, thisLen,
          divisor.digits[0]);
    } else {
      int qLen = thisLen - divisorLen + 1;
      resDigits = Division.divide(null, qLen, digits, thisLen, divisor.digits,
          divisorLen);
    }
    BigInteger result = new BigInteger(sign, resLength, resDigits);
    result.cutOffLeadingZeroes();
    return result;
  }

  /**
   * Returns a new {@code BigInteger} which has the same binary representation
   * as {@code this} but with the bit at position n set. The result is
   * equivalent to {@code this | 2^n}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @param n position where the bit in {@code this} has to be set.
   * @return {@code this | 2^n}.
   * @throws ArithmeticException if {@code n < 0}.
   */
  public BigInteger setBit(int n) {
    if (!testBit(n)) {
      return BitLevel.flipBit(this, n);
    }
    return this;
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this << n}. The
   * result is equivalent to {@code this * 2^n} if n >= 0. The shift distance
   * may be negative which means that {@code this} is shifted right. The result
   * then corresponds to {@code floor(this / 2^(-n))}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method on negative values is not
   * recommended as the current implementation is not efficient.
   *
   * @param n shift distance.
   * @return {@code this << n} if {@code n >= 0}; {@code this >> (-n)}.
   *         otherwise
   */
  public BigInteger shiftLeft(int n) {
    if ((n == 0) || (sign == 0)) {
      return this;
    }
    return ((n > 0) ? BitLevel.shiftLeft(this, n) : BitLevel.shiftRight(this,
        -n));
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this >> n}. For
   * negative arguments, the result is also negative. The shift distance may be
   * negative which means that {@code this} is shifted left.
   * <p>
   * <b>Implementation Note:</b> Usage of this method on negative values is not
   * recommended as the current implementation is not efficient.
   *
   * @param n shift distance
   * @return {@code this >> n} if {@code n >= 0}; {@code this << (-n)} otherwise
   */
  public BigInteger shiftRight(int n) {
    if ((n == 0) || (sign == 0)) {
      return this;
    }
    return ((n > 0) ? BitLevel.shiftRight(this, n) : BitLevel.shiftLeft(this,
        -n));
  }

  /**
   * Converts value of this {@code BigInteger} to a {@code short} if it fits it,
   * otherwise {@code ArithmeticException} is thrown.
   *
   * @return this {@code BigInteger} converted to a {@code short}.
   * @throws ArithmeticException if the value of this {@code BigInteger}
   *         does not fit in a {@code short}.
   */
  public short shortValueExact() {
    if (numberLength <= 1 && bitLength() < Short.SIZE) {
      return shortValue();
    }
    throw new ArithmeticException("out of short range");
  }

  /**
   * Returns the sign of this {@code BigInteger}.
   *
   * @return {@code -1} if {@code this < 0}, {@code 0} if {@code this == 0},
   *         {@code 1} if {@code this > 0}.
   */
  public int signum() {
    return sign;
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this - val}.
   *
   * @param val value to be subtracted from {@code this}.
   * @return {@code this - val}.
   * @throws NullPointerException if {@code val == null}.
   */
  public BigInteger subtract(BigInteger val) {
    return Elementary.subtract(this, val);
  }

  /**
   * Tests whether the bit at position n in {@code this} is set. The result is
   * equivalent to {@code this & (2^n) != 0}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @param n position where the bit in {@code this} has to be inspected.
   * @return {@code this & (2^n) != 0}.
   * @throws ArithmeticException if {@code n < 0}.
   */
  public boolean testBit(int n) {
    if (n == 0) {
      return ((digits[0] & 1) != 0);
    }
    if (n < 0) {
      // math.15=Negative bit address
      throw new ArithmeticException("Negative bit address"); //$NON-NLS-1$
    }
    int intCount = n >> 5;
    if (intCount >= numberLength) {
      return (sign < 0);
    }
    int digit = digits[intCount];
    n = (1 << (n & 31)); // int with 1 set to the needed position
    if (sign < 0) {
      int firstNonZeroDigit = getFirstNonzeroDigit();
      if (intCount < firstNonZeroDigit) {
        return false;
      } else if (firstNonZeroDigit == intCount) {
        digit = -digit;
      } else {
        digit = ~digit;
      }
    }
    return ((digit & n) != 0);
  }

  /**
   * Returns the two's complement representation of this BigInteger in a byte
   * array.
   *
   * @return two's complement representation of {@code this}.
   */
  public byte[] toByteArray() {
    if (this.sign == 0) {
      return new byte[] {0};
    }
    BigInteger temp = this;
    int bitLen = bitLength();
    int iThis = getFirstNonzeroDigit();
    int bytesLen = (bitLen >> 3) + 1;
    /*
     * Puts the little-endian int array representing the magnitude of this
     * BigInteger into the big-endian byte array.
     */
    byte[] bytes = new byte[bytesLen];
    int firstByteNumber = 0;
    int highBytes;
    int digitIndex = 0;
    int bytesInInteger = 4;
    int digit;
    int hB;

    if (bytesLen - (numberLength << 2) == 1) {
      bytes[0] = (byte) ((sign < 0) ? -1 : 0);
      highBytes = 4;
      firstByteNumber++;
    } else {
      hB = bytesLen & 3;
      highBytes = (hB == 0) ? 4 : hB;
    }

    digitIndex = iThis;
    bytesLen -= iThis << 2;

    if (sign < 0) {
      digit = -temp.digits[digitIndex];
      digitIndex++;
      if (digitIndex == numberLength) {
        bytesInInteger = highBytes;
      }
      for (int i = 0; i < bytesInInteger; i++, digit >>= 8) {
        bytes[--bytesLen] = (byte) digit;
      }
      while (bytesLen > firstByteNumber) {
        digit = ~temp.digits[digitIndex];
        digitIndex++;
        if (digitIndex == numberLength) {
          bytesInInteger = highBytes;
        }
        for (int i = 0; i < bytesInInteger; i++, digit >>= 8) {
          bytes[--bytesLen] = (byte) digit;
        }
      }
    } else {
      while (bytesLen > firstByteNumber) {
        digit = temp.digits[digitIndex];
        digitIndex++;
        if (digitIndex == numberLength) {
          bytesInInteger = highBytes;
        }
        for (int i = 0; i < bytesInInteger; i++, digit >>= 8) {
          bytes[--bytesLen] = (byte) digit;
        }
      }
    }
    return bytes;
  }

  /**
   * Returns a string representation of this {@code BigInteger} in decimal form.
   *
   * @return a string representation of {@code this} in decimal form.
   */
  @Override
  public String toString() {
    return Conversion.toDecimalScaledString(this, 0);
  }

  /**
   * Returns a string containing a string representation of this {@code
   * BigInteger} with base radix. If {@code radix} is less than
   * {@link Character#MIN_RADIX} or greater than {@link Character#MAX_RADIX}
   * then a decimal representation is returned. The characters of the string
   * representation are generated with method {@link Character#forDigit}.
   *
   * @param radix base to be used for the string representation.
   * @return a string representation of this with radix 10.
   */
  public String toString(int radix) {
    return Conversion.bigInteger2String(this, radix);
  }

  /**
   * Returns a new {@code BigInteger} whose value is {@code this ^ val}.
   * <p>
   * <b>Implementation Note:</b> Usage of this method is not recommended as the
   * current implementation is not efficient.
   *
   * @param val value to be xor'ed with {@code this}
   * @return {@code this ^ val}
   * @throws NullPointerException if {@code val == null}
   */
  public BigInteger xor(BigInteger val) {
    return Logical.xor(this, val);
  }

  /*
   * Returns a copy of the current instance to achieve immutability
   */
  BigInteger copy() {
    int[] copyDigits = new int[numberLength];
    System.arraycopy(digits, 0, copyDigits, 0, numberLength);
    return new BigInteger(sign, numberLength, copyDigits);
  }

  /* Private Methods */

  /**
   * Decreases {@code numberLength} if there are zero high elements.
   */
  final void cutOffLeadingZeroes() {
    while ((numberLength > 0) && (digits[--numberLength] == 0)) {
      // Empty
    }
    if (digits[numberLength++] == 0) {
      sign = 0;
    }
  }

  boolean equalsArrays(final int[] b) {
    int i;
    for (i = numberLength - 1; (i >= 0) && (digits[i] == b[i]); i--) {
      // Empty
    }
    return i < 0;
  }

  int getFirstNonzeroDigit() {
    if (firstNonzeroDigit == -2) {
      int i;
      if (this.sign == 0) {
        i = -1;
      } else {
        for (i = 0; digits[i] == 0; i++) {
          // Empty
        }
      }
      firstNonzeroDigit = i;
    }
    return firstNonzeroDigit;
  }

  /**
   * Tests if {@code this.abs()} is equals to {@code ONE}.
   */
  boolean isOne() {
    return ((numberLength == 1) && (digits[0] == 1));
  }

  BigInteger shiftLeftOneBit() {
    return (sign == 0) ? this : BitLevel.shiftLeftOneBit(this);
  }

  void unCache() {
    firstNonzeroDigit = -2;
  }

  /**
   * Puts a big-endian byte array into a little-endian applying two complement.
   */
  private void putBytesNegativeToIntegers(byte[] byteValues) {
    int bytesLen = byteValues.length;
    int highBytes = bytesLen & 3;
    numberLength = (bytesLen >> 2) + ((highBytes == 0) ? 0 : 1);
    digits = new int[numberLength];
    int i = 0;
    // Setting the sign
    digits[numberLength - 1] = -1;
    // Put bytes to the int array starting from the end of the byte array
    while (bytesLen > highBytes) {
      digits[i] = (byteValues[--bytesLen] & 0xFF)
          | (byteValues[--bytesLen] & 0xFF) << 8
          | (byteValues[--bytesLen] & 0xFF) << 16
          | (byteValues[--bytesLen] & 0xFF) << 24;
      if (digits[i] != 0) {
        digits[i] = -digits[i];
        firstNonzeroDigit = i;
        i++;
        while (bytesLen > highBytes) {
          digits[i] = (byteValues[--bytesLen] & 0xFF)
              | (byteValues[--bytesLen] & 0xFF) << 8
              | (byteValues[--bytesLen] & 0xFF) << 16
              | (byteValues[--bytesLen] & 0xFF) << 24;
          digits[i] = ~digits[i];
          i++;
        }
        break;
      }
      i++;
    }
    if (highBytes != 0) {
      // Put the first bytes in the highest element of the int array
      if (firstNonzeroDigit != -2) {
        for (int j = 0; j < bytesLen; j++) {
          digits[i] = (digits[i] << 8) | (byteValues[j] & 0xFF);
        }
        digits[i] = ~digits[i];
      } else {
        for (int j = 0; j < bytesLen; j++) {
          digits[i] = (digits[i] << 8) | (byteValues[j] & 0xFF);
        }
        digits[i] = -digits[i];
      }
    }
  }

  /**
   * Puts a big-endian byte array into a little-endian int array.
   */
  private void putBytesPositiveToIntegers(byte[] byteValues) {
    int bytesLen = byteValues.length;
    int highBytes = bytesLen & 3;
    numberLength = (bytesLen >> 2) + ((highBytes == 0) ? 0 : 1);
    digits = new int[numberLength];
    int i = 0;
    // Put bytes to the int array starting from the end of the byte array
    while (bytesLen > highBytes) {
      digits[i++] = (byteValues[--bytesLen] & 0xFF)
          | (byteValues[--bytesLen] & 0xFF) << 8
          | (byteValues[--bytesLen] & 0xFF) << 16
          | (byteValues[--bytesLen] & 0xFF) << 24;
    }
    // Put the first bytes in the highest element of the int array
    for (int j = 0; j < bytesLen; j++) {
      digits[i] = (digits[i] << 8) | (byteValues[j] & 0xFF);
    }
  }
}
