* @param root
     * @param decimalPlaces
     * @param a_RoundingMode
     * @return The rootRoundIfNecessary of x to decimalPlaces precision
     */
    public static BigDecimal rootRoundIfNecessary(
            BigDecimal x,
            BigInteger root,
            //Generic_BigDecimal a_Generic_BigDecimal,
            int decimalPlaces,
            RoundingMode a_RoundingMode) {
        // The current (Java6) limit for n in x.pow(n)
        // for BigDecimal x and int n is
        // -999999999 < n < 999999999
        if (root.compareTo(BigInteger.valueOf(999999999)) != 1) {
            BigDecimal result = rootRoundIfNecessary(
                    x,
                    root.intValue(),
                    //a_Generic_BigDecimal,
                    decimalPlaces,
                    a_RoundingMode);
            // return result;
            return roundIfNecessary(result, decimalPlaces, a_RoundingMode);
        } else {
            // Deal with special cases
            // x <= 0
            if (x.compareTo(BigDecimal.ZERO) != 1) {
                // Complex roots are not handled!
                throw new IllegalArgumentException(
                        "x <= 0 in " + Generic_BigDecimal.class
                        + ".root(BigDecimal,BigInteger,int,RoundingMode)");
            }
            // x = 1
            if (x.compareTo(BigDecimal.ONE) == 0) {
                return BigDecimal.ONE;
            }
            // rootRoundIfNecessary = 1
            if (root.compareTo(BigInteger.ONE) == 0) {
                BigDecimal result = new BigDecimal(x.toString());
                if (result.scale() > decimalPlaces) {
                    return roundIfNecessary(result, decimalPlaces, a_RoundingMode);
                }
                return result;
            }
            // x < 1
            if (x.compareTo(BigDecimal.ONE) == -1) {
                int xscale = x.scale();
                // Optimisation (untested if it is faster) for a large x.scale()
                int rootLength = root.toString().length();
                if (xscale < 10) {
                    BigDecimal numeratorUnrooted = new BigDecimal(x.unscaledValue());
                    BigDecimal denominatorUnrooted = new BigDecimal(BigInteger.ONE, (-1 * xscale));
                    // numerator will be greater than denominator and both will
                    // be close to a value of 1, a large number of decimal 
                    // places for both numerator and denominator are required!
                    BigDecimal denominator = rootRoundIfNecessary(
                            denominatorUnrooted,
                            root,
                            decimalPlaces + xscale + rootLength, // Can we cope with less or do we need more?
                            a_RoundingMode);
                    int denominatorScale = denominator.scale();
                    BigDecimal numerator = rootRoundIfNecessary(
                            numeratorUnrooted,
                            root,
                            decimalPlaces + xscale + rootLength, // Can we cope with less or do we need more?
                            a_RoundingMode);
                    BigDecimal result = Generic_BigDecimal.divideRoundIfNecessary(
                            numerator,
                            denominator,
                            decimalPlaces,
                            a_RoundingMode);
                    return result;
                } else {
                    BigDecimal result = rootLessThanOne(
                            x,
                            root,
                            //a_Generic_BigDecimal,
                            decimalPlaces,
                            a_RoundingMode);
                    return roundIfNecessary(result, decimalPlaces, a_RoundingMode);
                }
            }
            // x > 1
            //int safeDecimalPlaces = decimalPlaces + 5;
            BigDecimal epsilon_BigDecimal =
                    new BigDecimal(BigInteger.ONE, decimalPlaces);
            // Check there is a rootRoundIfNecessary in the precision and return 0 if not
            BigDecimal comparator = BigDecimal.ONE.add(epsilon_BigDecimal);
            boolean powerTest = powerTestAbove(
                    x,
                    comparator,
                    root,
                    256,
                    decimalPlaces,
                    a_RoundingMode);
            if (powerTest) {
                System.out.println(
                        "No root in the precision returning BigDecimal.ONE"
                        + "in " + Generic_BigDecimal.class
                        + ".root(BigDecimal,BigInteger,int,RoundingMode)");

                return BigDecimal.ONE;
            }
            BigDecimal result;// = new BigDecimal("1");
            int rootInitialisationMaxIte = 10;
            result = rootInitialisation(
                    x,
                    root,
                    epsilon_BigDecimal,
                    rootInitialisationMaxIte,
                    decimalPlaces,
                    a_RoundingMode);
            // Newton Raphson
            //int newtonRaphsonMaxite = 100;
            result = newtonRaphson(
                    x,
                    result,
                    root,
                    epsilon_BigDecimal,
                    //newtonRaphsonMaxite,
                    decimalPlaces + 1);
//                    a_RoundingMode);
            // return result;
            return roundIfNecessary(result, decimalPlaces, a_RoundingMode);
        }
    }