* @param decimalPlaces
     * @param a_RoundingMode
     * @return e^y where e is the Euler constant. The result is returned correct
     * to decimalPlaces decimal place precision.
     */
    public static BigDecimal exp(
            BigDecimal y,
            Generic_BigDecimal a_Generic_BigDecimal,
            int decimalPlaces,
            RoundingMode a_RoundingMode) {
        BigDecimal result;
        // Deal with special cases
        if (y.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ONE;
        }
        // Check a_Generic_BigDecimal
        if (a_Generic_BigDecimal == null) {
            a_Generic_BigDecimal = new Generic_BigDecimal();
        }
        if (y.compareTo(BigDecimal.ONE) == 0) {
            return a_Generic_BigDecimal.getEulerConstantToAFixedDecimalPlacePrecision(
                    decimalPlaces,
                    a_RoundingMode);
        }
        int safeDecimalPlaces;
        if (y.compareTo(BigDecimal.ZERO) == -1) {
            safeDecimalPlaces = y.scale() + decimalPlaces;
            BigDecimal exp = exp(
                    y.negate(),
                    a_Generic_BigDecimal,
                    safeDecimalPlaces,
                    a_RoundingMode);
            result = reciprocal(
                    exp,
                    decimalPlaces,
                    a_RoundingMode);
            return result;
        }
        int divisionDecimalPlaces = decimalPlaces + 3;
        result = BigDecimal.ONE.add(y);
//        if (a_Generic_BigDecimal._Generic_BigInteger == null) {
//            a_Generic_BigDecimal.init_Factorial_Generic_BigInteger(maxite);
//        } else {
//            a_Generic_BigDecimal._Generic_BigInteger.factorial(maxite);
//        }
        BigDecimal factorial;
        BigDecimal xpow;
        BigDecimal xpowOverFactorial;
        BigDecimal tollerance = new BigDecimal(
                BigInteger.ONE, decimalPlaces + 1);
        // Use Taylor Series
        BigInteger i_BigInteger = BigInteger.ONE;
        Integer factorialKey = 1;
        while (true) {
            i_BigInteger = i_BigInteger.add(BigInteger.ONE);
            factorialKey = factorialKey + 1;
            factorial = new BigDecimal(
                    a_Generic_BigDecimal._Generic_BigInteger.factorial(factorialKey));
            xpow = power(
                    y,
                    i_BigInteger,
                    64,
                    decimalPlaces, // Maybe there is need for more even though the bottom of the Taylor series grows fast
                    a_RoundingMode);
            xpowOverFactorial = divideRoundIfNecessary(
                    xpow,
                    factorial,
                    divisionDecimalPlaces,
                    a_RoundingMode);
            result = result.add(xpowOverFactorial);
            if (xpowOverFactorial.compareTo(tollerance) == -1) {
                break;
            }
        }
        return roundIfNecessary(result, decimalPlaces, a_RoundingMode);
    }

//    /**
//     * This method was not necessary. However something like it might be 
//     * useful for none Euler constant based exponentiation so for the time 
//     * being the code is just commented out rather than deleted. If the power
//     * methods are fully operational, this commented code should be deleted.
//     * @param y 0 < y < 1
//     * @param decimalPlaces
//     * @return e^y accurate to decimalPlaces
//     */
//    private static BigDecimal expLessThanOne(
//            BigDecimal y,
//            Generic_BigDecimal a_Generic_BigDecimal,
//            int decimalPlaces,
//            RoundingMode a_RoundingMode) {
//        BigDecimal result;
//        BigDecimal epsilon_BigDecimal = new BigDecimal(BigInteger.ONE, decimalPlaces);
//        BigDecimal x0 = new BigDecimal(a_Generic_BigDecimal._E.toString());
//        BigDecimal element;
//        BigInteger elementUnscaled;
//        BigDecimal elementOne;
//        BigInteger elementOneReciprocal;
//        BigDecimal rootRoundIfNecessary;
//        BigDecimal rootMultiple;
//        int maxite = x0.precision();
//        result = BigDecimal.ONE;
//        while (true) {
//        for (int i = 0; i < maxite; i++) {
//            element = floorSignificantDigit(x0);
//            elementUnscaled = element.unscaledValue();
//            System.out.println("element " + element + " elementUnscaled " + elementUnscaled);
//            if (elementUnscaled.compareTo(BigInteger.ZERO) == 1) {
//                elementOne = divideRoundIfNecessary(
//                        element,
//                        elementUnscaled,
//                        decimalPlaces,
//                        a_RoundingMode);
//                if (elementOne.compareTo(BigDecimal.ZERO) == 0) {
//                    break;
//                }
//                System.out.println("element " + element + " elementUnscaled " + elementUnscaled);
//                elementOneReciprocal = reciprocalWillBeIntegerReturnBigInteger(elementOne);
//                rootRoundIfNecessary = rootRoundIfNecessary(
//                        y,
//                        elementOneReciprocal,
//                        decimalPlaces,
//                        a_RoundingMode);
//                if (rootRoundIfNecessary.compareTo(BigDecimal.ZERO) == 1) {
//                    rootMultiple = power(
//                            rootRoundIfNecessary,
//                            elementUnscaled,
//                            64,
//                            decimalPlaces, // @TODO Is this sufficient?
//                            a_RoundingMode);
//                    result = multiplyRoundIfNecessary(
//                            result,
//                            rootMultiple,
//                            decimalPlaces + 3, // @TODO Is this sufficient or ott?
//                            a_RoundingMode);
//                }
//            }
//            x0 = x0.subtract(element);
//        }