public static bool TryParse(char[] inData, int offset, int len, IFormatProvider provider, out BigDecimal value,
                                    out Exception exception)
        {
            if (inData == null || inData.Length == 0)
            {
                exception = new FormatException("Cannot parse an empty string.");
                value     = null;
                return(false);
            }

            var numberformatInfo = provider.GetFormat(typeof(NumberFormatInfo)) as NumberFormatInfo;

            if (numberformatInfo == null)
            {
                numberformatInfo = NumberFormatInfo.CurrentInfo;
            }

            var decSep = numberformatInfo.NumberDecimalSeparator;

            if (decSep.Length > 1)
            {
                exception = new NotSupportedException("More than one decimal separator not yet supported");
                value     = null;
                return(false);
            }

            var cDecSep = decSep[0];

            int begin = offset;             // first index to be copied
            int last  = offset + (len - 1); // last index to be copied

            if ((last >= inData.Length) || (offset < 0) || (len <= 0) || (last < 0))
            {
                exception = new FormatException();
                value     = null;
                return(false);
            }

            var v = new BigDecimal();

            try {
                var unscaledBuffer = new StringBuilder(len);
                int bufLength      = 0;
                // To skip a possible '+' symbol
                if ((offset <= last) && (inData[offset] == '+'))
                {
                    offset++;
                    begin++;
                }

                int  counter    = 0;
                bool wasNonZero = false;
                // Accumulating all digits until a possible decimal point
                for (;
                     (offset <= last) &&
                     (inData[offset] != cDecSep) &&
                     (inData[offset] != 'e') &&
                     (inData[offset] != 'E');
                     offset++)
                {
                    if (!wasNonZero)
                    {
                        if (inData[offset] == '0')
                        {
                            counter++;
                        }
                        else
                        {
                            wasNonZero = true;
                        }
                    }
                }

                unscaledBuffer.Append(inData, begin, offset - begin);
                bufLength += offset - begin;
                // A decimal point was found
                if ((offset <= last) && (inData[offset] == cDecSep))
                {
                    offset++;
                    // Accumulating all digits until a possible exponent
                    begin = offset;
                    for (;
                         (offset <= last) &&
                         (inData[offset] != 'e') &&
                         (inData[offset] != 'E');
                         offset++)
                    {
                        if (!wasNonZero)
                        {
                            if (inData[offset] == '0')
                            {
                                counter++;
                            }
                            else
                            {
                                wasNonZero = true;
                            }
                        }
                    }

                    v.Scale    = offset - begin;
                    bufLength += v.Scale;
                    unscaledBuffer.Append(inData, begin, v.Scale);
                }
                else
                {
                    v.Scale = 0;
                }
                // An exponent was found
                if ((offset <= last) && ((inData[offset] == 'e') || (inData[offset] == 'E')))
                {
                    offset++;
                    // Checking for a possible sign of scale
                    begin = offset;
                    if ((offset <= last) && (inData[offset] == '+'))
                    {
                        offset++;
                        if ((offset <= last) && (inData[offset] != '-'))
                        {
                            begin++;
                        }
                    }

                    // Accumulating all remaining digits
                    string scaleString = new String(inData, begin, last + 1 - begin);                     // buffer for scale
                    // Checking if the scale is defined
                    long newScale = (long)v.Scale - Int32.Parse(scaleString, provider);                   // the new scale
                    v.Scale = (int)newScale;
                    if (newScale != v.Scale)
                    {
                        // math.02=Scale out of range.
                        throw new FormatException(Messages.math02);                         //$NON-NLS-1$
                    }
                }

                // Parsing the unscaled value
                if (bufLength < 19)
                {
                    long smallValue;
                    if (!Int64.TryParse(unscaledBuffer.ToString(), NumberStyles.Integer, provider, out smallValue))
                    {
                        value     = null;
                        exception = new FormatException();
                        return(false);
                    }

                    v.SmallValue = smallValue;
                    v.BitLength  = BigDecimal.CalcBitLength(v.SmallValue);
                }
                else
                {
                    v.SetUnscaledValue(BigInteger.Parse(unscaledBuffer.ToString()));
                }

                v.Precision = unscaledBuffer.Length - counter;
                if (unscaledBuffer[0] == '-')
                {
                    v.Precision--;
                }

                value     = v;
                exception = null;
                return(true);
            } catch (Exception ex) {
                exception = ex;
                value     = null;
                return(false);
            }
        }