public static BigInteger GCD(BigInteger x, BigInteger y) {

		if (x.equals(BigInteger.ZERO)) {
			return y;
		}

		if (y.equals(BigInteger.ZERO)) {
			return x;
		}

		if (isEven(x) && isEven(y)) {

			x = x.shiftRight(1);
			y = y.shiftRight(1);

			return TWO.multiply(GCD(x, y));

		}

		if (isOdd(x) && isEven(y)) {
			return GCD(x, y.shiftRight(1));
		}

		if (isEven(x) && isOdd(y)) {
			//return GCD(y, x.shiftRight(1));
			return GCD(x.shiftRight(1), y);
		}

		if (x.compareTo(y) <= 0) {
			return GCD(x, y.subtract(x));
		} else {
			return GCD(y, x.subtract(y));
		}

	}