/* 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.
 */
package java.util;

import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.CharBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.charset.Charset;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * A parser that parses a text string of primitive types and strings with the
 * help of regular expressions. It supports localized numbers and various
 * radixes. The input is broken into tokens by the delimiter pattern, which is
 * whitespace by default. The primitive types can be obtained via corresponding
 * next* methods. If the token is not in a valid format, an
 * {@code InputMismatchException} is thrown.
 * <p>
 * For example:
 * <pre>
 * Scanner s = new Scanner("1A true");
 * System.out.println(s.nextInt(16));
 * System.out.println(s.nextBoolean());
 * </pre>
 * <p>
 * Yields the result: {@code 26 true}
 * <p>A {@code Scanner} can also find or skip specific patterns without regard for the
 * delimiter. All these methods and the various next* and hasNext* methods may
 * block.
 * <p>
 * The {@code Scanner} class is not thread-safe.
 */
public final class Scanner implements Iterator<String> {

    // Default delimiting pattern.
    private static final Pattern DEFAULT_DELIMITER = Pattern
            .compile("\\p{javaWhitespace}+"); //$NON-NLS-1$

    // The boolean's pattern.
    private static final Pattern BOOLEAN_PATTERN = Pattern.compile(
            "true|false", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$

    // Pattern used to recognize line terminator.
    private static final Pattern LINE_TERMINATOR;

    // Pattern used to recognize multiple line terminators.
    private static final Pattern MULTI_LINE_TERMINATOR;

    // Pattern used to recognize a line with a line terminator.
    private static final Pattern LINE_PATTERN;

    static {
        String terminator = "\n|\r\n|\r|\u0085|\u2028|\u2029"; //$NON-NLS-1$

        LINE_TERMINATOR = Pattern.compile(terminator);

        StringBuilder multiTerminator = new StringBuilder();
        MULTI_LINE_TERMINATOR = Pattern.compile(multiTerminator.append("(") //$NON-NLS-1$
                .append(terminator).append(")+").toString()); //$NON-NLS-1$
        StringBuilder line = new StringBuilder();
        LINE_PATTERN = Pattern.compile(line.append(".*(") //$NON-NLS-1$
                .append(terminator).append(")|.+(") //$NON-NLS-1$
                .append(terminator).append(")?").toString()); //$NON-NLS-1$
    }

    // The pattern matches anything.
    private static final Pattern ANY_PATTERN = Pattern.compile("(?s).*"); //$NON-NLS-1$

    private static final int DIPLOID = 2;

    // Default radix.
    private static final int DEFAULT_RADIX = 10;

    private static final int DEFAULT_TRUNK_SIZE = 1024;

    // The input source of scanner.
    private Readable input;

    private CharBuffer buffer;

    private Pattern delimiter = DEFAULT_DELIMITER;

    private Matcher matcher;

    private int integerRadix = DEFAULT_RADIX;

    private Locale locale = Locale.getDefault();

    // The position where find begins.
    private int findStartIndex = 0;

    // The last find start position.
    private int preStartIndex = findStartIndex;

    // The length of the buffer.
    private int bufferLength = 0;

    // Record the status of this scanner. True if the scanner
    // is closed.
    private boolean closed = false;

    private IOException lastIOException;

    private boolean matchSuccessful = false;

    private DecimalFormat decimalFormat;

    // Records whether the underlying readable has more input.
    private boolean inputExhausted = false;

    private Object cacheHasNextValue = null;

    private int cachehasNextIndex = -1;

    private enum DataType {
        /*
         * Stands for Integer
         */
        INT,
        /*
         * Stands for Float
         */
        FLOAT;
    }

    /**
     * Creates a {@code Scanner} with the specified {@code File} as input. The default charset
     * is applied when reading the file.
     * 
     * @param src
     *            the file to be scanned.
     * @throws FileNotFoundException
     *             if the specified file does not exist.
     */
    public Scanner(File src) throws FileNotFoundException {
        this(src, Charset.defaultCharset().name());
    }

    /**
     * Creates a {@code Scanner} with the specified {@code File} as input. The specified charset
     * is applied when reading the file.
     * 
     * @param src
     *            the file to be scanned.
     * @param charsetName
     *            the name of the encoding type of the file.
     * @throws FileNotFoundException
     *             if the specified file does not exist.
     * @throws IllegalArgumentException
     *             if the specified coding does not exist.
     */
    public Scanner(File src, String charsetName) throws FileNotFoundException {
        if (null == src) {
            throw new NullPointerException(org.apache.harmony.luni.util.Msg
                    .getString("KA00a")); //$NON-NLS-1$
        }
        FileInputStream fis = new FileInputStream(src);
        if (null == charsetName) {
            throw new IllegalArgumentException(org.apache.harmony.luni.util.Msg
                    .getString("KA009")); //$NON-NLS-1$
        }
        try {
            input = new InputStreamReader(fis, charsetName);
        } catch (UnsupportedEncodingException e) {
            try {
                fis.close();
            } catch (IOException ioException) {
                // ignore
            }
            throw new IllegalArgumentException(e.getMessage());
        }
        initialization();
    }

    /**
     * Creates a {@code Scanner} on the specified string.
     * 
     * @param src
     *            the string to be scanned.
     */
    public Scanner(String src) {
        input = new StringReader(src);
        initialization();
    }

    /**
     * Creates a {@code Scanner} on the specified {@code InputStream}. The default charset is
     * applied when decoding the input.
     * 
     * @param src
     *            the {@code InputStream} to be scanned.
     */
    public Scanner(InputStream src) {
        this(src, Charset.defaultCharset().name());
    }

    /**
     * Creates a {@code Scanner} on the specified {@code InputStream}. The specified charset is
     * applied when decoding the input.
     * 
     * @param src
     *            the {@code InputStream} to be scanned.
     * @param charsetName
     *            the encoding type of the {@code InputStream}.
     * @throws IllegalArgumentException
     *             if the specified character set is not found.
     */
    public Scanner(InputStream src, String charsetName) {
        if (null == src) {
            throw new NullPointerException(org.apache.harmony.luni.util.Msg
                    .getString("KA00b")); //$NON-NLS-1$
        }
        try {
            input = new InputStreamReader(src, charsetName);
        } catch (UnsupportedEncodingException e) {
            throw new IllegalArgumentException(e.getMessage());
        }
        initialization();
    }

    /**
     * Creates a {@code Scanner} with the specified {@code Readable} as input.
     * 
     * @param src
     *            the {@code Readable} to be scanned.
     */
    public Scanner(Readable src) {
        if (null == src) {
            throw new NullPointerException();
        }
        input = src;
        initialization();
    }

    /**
     * Creates a {@code Scanner} with the specified {@code ReadableByteChannel} as
     * input. The default charset is applied when decoding the input.
     * 
     * @param src
     *            the {@code ReadableByteChannel} to be scanned.
     */
    public Scanner(ReadableByteChannel src) {
        this(src, Charset.defaultCharset().name());
    }

    /**
     * Creates a {@code Scanner} with the specified {@code ReadableByteChannel} as
     * input. The specified charset is applied when decoding the input.
     * 
     * @param src
     *            the {@code ReadableByteChannel} to be scanned.
     * @param charsetName
     *            the encoding type of the content.
     * @throws IllegalArgumentException
     *             if the specified character set is not found.
     */
    public Scanner(ReadableByteChannel src, String charsetName) {
        if (null == src) {
            throw new NullPointerException(org.apache.harmony.luni.util.Msg
                    .getString("KA00d")); //$NON-NLS-1$
        }
        if (null == charsetName) {
            throw new IllegalArgumentException(org.apache.harmony.luni.util.Msg
                    .getString("KA009")); //$NON-NLS-1$
        }
        input = Channels.newReader(src, charsetName);
        initialization();
    }

    /**
     * Closes this {@code Scanner} and the underlying input if the input implements
     * {@code Closeable}. If the {@code Scanner} has been closed, this method will have
     * no effect. Any scanning operation called after calling this method will throw
     * an {@code IllegalStateException}.
     * 
     * @see Closeable
     */
    public void close() {
        if (closed) {
            return;
        }
        if (input instanceof Closeable) {
            try {
                ((Closeable) input).close();
            } catch (IOException e) {
                lastIOException = e;
            }
        }
        closed = true;
    }

    /**
     * Returns the delimiter {@code Pattern} in use by this {@code Scanner}.
     * 
     * @return the delimiter {@code Pattern} in use by this {@code Scanner}.
     */
    public Pattern delimiter() {
        return delimiter;
    }

    /**
     * Tries to find the pattern in the input. Delimiters are ignored. If the
     * pattern is found before line terminator, the matched string will be
     * returned, and the {@code Scanner} will advance to the end of the matched string.
     * Otherwise, {@code null} will be returned and the {@code Scanner} will not advance.
     * When waiting for input, the {@code Scanner} may be blocked. All the
     * input may be cached if no line terminator exists in the buffer.
     * 
     * @param pattern
     *            the pattern to find in the input.
     * @return the matched string or {@code null} if the pattern is not found
     *         before the next line terminator.
     * @throws IllegalStateException
     *             if the {@code Scanner} is closed.
     */
    public String findInLine(Pattern pattern) {
        checkClosed();
        checkNull(pattern);
        int horizonLineSeparator = 0;

        matcher.usePattern(MULTI_LINE_TERMINATOR);
        matcher.region(findStartIndex, bufferLength);

        boolean findComplete = false;
        int terminatorLength = 0;
        while (!findComplete) {
            if (matcher.find()) {
                horizonLineSeparator = matcher.start();
                terminatorLength = matcher.end() - matcher.start();
                findComplete = true;
            } else {
                if (!inputExhausted) {
                    readMore();
                    resetMatcher();
                } else {
                    horizonLineSeparator = bufferLength;
                    findComplete = true;
                }
            }
        }

        matcher.usePattern(pattern);

        /*
         * TODO The following 2 statements are used to deal with regex's bug.
         * java.util.regex.Matcher.region(int start, int end) implementation
         * does not have any effects when called. They will be removed once the
         * bug is fixed.
         */
        int oldLimit = buffer.limit();
        // Considering the look ahead feature, the line terminator should be involved as RI
        buffer.limit(horizonLineSeparator + terminatorLength);
        // ========== To deal with regex bug ====================

        // Considering the look ahead feature, the line terminator should be involved as RI
        matcher.region(findStartIndex, horizonLineSeparator + terminatorLength);
        if (matcher.find()) {
            // The scanner advances past the input that matched
            findStartIndex = matcher.end();
            // If the matched pattern is immediately followed by line
            // terminator.
            if (horizonLineSeparator == matcher.end()) {
                findStartIndex += terminatorLength;
            }
            // the line terminator itself should not be a part of
            // the match result according to the Spec
            if (horizonLineSeparator != bufferLength
                    && (horizonLineSeparator + terminatorLength == matcher
                            .end())) {
                // ========== To deal with regex bug ====================
                buffer.limit(oldLimit);
                // ========== To deal with regex bug ====================

                matchSuccessful = false;
                return null;
            }
            matchSuccessful = true;

            // ========== To deal with regex bug ====================
            buffer.limit(oldLimit);
            // ========== To deal with regex bug ====================

            return matcher.group();
        }

        // ========== To deal with regex bug ====================
        buffer.limit(oldLimit);
        // ========== To deal with regex bug ====================

        matchSuccessful = false;
        return null;
    }

    /**
     * Compiles the pattern string and tries to find a substing matching it in the input data. The
     * delimiter will be ignored. This is the same as invoking
     * {@code findInLine(Pattern.compile(pattern))}.
     * 
     * @param pattern
     *            a string used to construct a pattern which is in turn used to
     *            match a substring of the input data.
     * @return the matched string or {@code null} if the pattern is not found
     *         before the next line terminator.
     * @throws IllegalStateException
     *             if the {@code Scanner} is closed.
     * @see #findInLine(Pattern)
     */
    public String findInLine(String pattern) {
        return findInLine(Pattern.compile(pattern));
    }

    /**
     * Tries to find the pattern in the input between the current position and the specified
     * horizon. Delimiters are ignored. If the pattern is found, the matched
     * string will be returned, and the {@code Scanner} will advance to the end of the
     * matched string. Otherwise, null will be returned and {@code Scanner} will not
     * advance. When waiting for input, the {@code Scanner} may be blocked.
     * <p>
     * The {@code Scanner}'s search will never go more than {@code horizon} code points from current
     * position. The position of {@code horizon} does have an effect on the result of the
     * match. For example, when the input is "123" and current position is at zero,
     * {@code findWithinHorizon(Pattern.compile("\\p&#123;Digit&#125;&#123;3&#125;"), 2)}
     * will return {@code null}. While
     * {@code findWithinHorizon(Pattern.compile("\\p&#123;Digit&#125;&#123;3&#125;"), 3)}
     * will return {@code "123"}. {@code horizon} is treated as a transparent,
     * non-anchoring bound. (refer to
     * {@link Matcher#useTransparentBounds(boolean)} and
     * {@link Matcher#useAnchoringBounds(boolean)})
     * <p>
     * A {@code horizon} whose value is zero will be ignored and the whole input will be
     * used for search. In this situation, all the input may be cached.
     *
     * @param pattern
     *            the pattern used to scan.
     * @param horizon
     *            the search limit.
     * @return the matched string or {@code null} if the pattern is not found
     *         within the specified {@code horizon}.
     * @throws IllegalStateException
     *             if the {@code Scanner} is closed.
     * @throws IllegalArgumentException
     *             if {@code horizon} is less than zero.
     */
    public String findWithinHorizon(Pattern pattern, int horizon) {
        checkClosed();
        checkNull(pattern);
        if (horizon < 0) {
            throw new IllegalArgumentException(org.apache.harmony.luni.util.Msg
                    .getString("KA00e")); //$NON-NLS-1$
        }
        matcher.usePattern(pattern);

        String result = null;
        int findEndIndex = 0;
        int horizonEndIndex = 0;
        if (horizon == 0) {
            horizonEndIndex = Integer.MAX_VALUE;
        } else {
            horizonEndIndex = findStartIndex + horizon;
        }
        while (true) {
            findEndIndex = bufferLength;

            // If horizon > 0, then search up to
            // min( bufferLength, findStartIndex + horizon).
            // Otherwise search until readable is exhausted.
            findEndIndex = Math.min(horizonEndIndex, bufferLength);
            // If horizon == 0, consider horizon as always outside buffer.
            boolean isHorizonInBuffer = (horizonEndIndex <= bufferLength);
            // First, try to find pattern within buffer. If pattern can not be
            // found in buffer, then expand the buffer and try again,
            // util horizonEndIndex is exceeded or no more input left.
            matcher.region(findStartIndex, findEndIndex);
            if (matcher.find()) {
                if (isHorizonInBuffer || inputExhausted) {
                    result = matcher.group();
                    break;
                }
            } else {
                // Pattern is not found in buffer while horizonEndIndex is
                // within buffer, or input is exhausted. Under this situation,
                // it can be judged that find fails.
                if (isHorizonInBuffer || inputExhausted) {
                    break;
                }
            }

            // Expand buffer and reset matcher if needed.
            if (!inputExhausted) {
                readMore();
                resetMatcher();
            }
        }
        if (null != result) {
            findStartIndex = matcher.end();
            matchSuccessful = true;
        } else {
            matchSuccessful = false;
        }
        return result;
    }

    /**
     * Tries to find the pattern in the input between the current position and the specified
     * {@code horizon}. Delimiters are ignored. This call is the same as invoking
     * {@code findWithinHorizon(Pattern.compile(pattern))}.
     * 
     * @param pattern
     *            the pattern used to scan.
     * @param horizon
     *            the search limit.
     * @return the matched string, or {@code null} if the pattern is not found
     *         within the specified horizon.
     * @throws IllegalStateException
     *             if the {@code Scanner} is closed.
     * @throws IllegalArgumentException
     *             if {@code horizon} is less than zero.
     * @see #findWithinHorizon(Pattern, int)
     */
    public String findWithinHorizon(String pattern, int horizon) {
        return findWithinHorizon(Pattern.compile(pattern), horizon);
    }

    /**
     * Returns whether this {@code Scanner} has one or more tokens remaining to parse.
     * This method will block if the data is still being read.
     * 
     * @return {@code true} if this {@code Scanner} has one or more tokens remaining,
     *         otherwise {@code false}.
     * @throws IllegalStateException
     *             if the {@code Scanner} has been closed.
     */
    public boolean hasNext() {
        return hasNext(ANY_PATTERN);
    }

    /**
     * Returns whether this {@code Scanner} has one or more tokens remaining to parse
     * and the next token matches the given pattern. This method will block if the data is
     * still being read.
     * 
     * @param pattern
     *            the pattern to check for.
     * @return {@code true} if this {@code Scanner} has more tokens and the next token
     *         matches the pattern, {@code false} otherwise.
     * @throws IllegalStateException
     *             if the {@code Scanner} has been closed.
     */
    public boolean hasNext(Pattern pattern) {
        checkClosed();
        checkNull(pattern);
        matchSuccessful = false;
        saveCurrentStatus();
        // if the next token exists, set the match region, otherwise return
        // false
        if (!setTokenRegion()) {
            recoverPreviousStatus();
            return false;
        }
        matcher.usePattern(pattern);
        boolean hasNext = false;
        // check whether next token matches the specified pattern
        if (matcher.matches()) {
            cachehasNextIndex = findStartIndex;
            matchSuccessful = true;
            hasNext = true;
        }
        recoverPreviousStatus();
        return hasNext;
    }

    /**
     * Returns {@code true} if this {@code Scanner} has one or more tokens remaining to parse
     * and the next token matches a pattern compiled from the given string. This method will
     * block if the data is still being read. This call is equivalent to
     * {@code hasNext(Pattern.compile(pattern))}.
     * 
     * @param pattern
     *            the string specifying the pattern to scan for
     * @return {@code true} if the specified pattern matches this {@code Scanner}'s
     *         next token, {@code false} otherwise.
     * @throws IllegalStateException
     *             if the {@code Scanner} has been closed.
     */
    public boolean hasNext(String pattern) {
        return hasNext(Pattern.compile(pattern));
    }

    /**
     * Returns whether the next token can be translated into a valid
     * {@code BigDecimal}.
     * 
     * @return {@code true} if the next token can be translated into a valid
     *         {@code BigDecimal}, otherwise {@code false.}
     * @throws IllegalStateException
     *             if the {@code Scanner} has been closed.
     */
    public boolean hasNextBigDecimal() {
        Pattern floatPattern = getFloatPattern();
        boolean isBigDecimalValue = false;
        if (hasNext(floatPattern)) {
            String floatString = matcher.group();
            floatString = removeLocaleInfoFromFloat(floatString);
            try {
                cacheHasNextValue = new BigDecimal(floatString);
                isBigDecimalValue = true;
            } catch (NumberFormatException e) {
                matchSuccessful = false;
            }
        }
        return isBigDecimalValue;
    }

    /**
     * Returns whether the next token can be translated into a valid
     * {@code BigInteger} in the default radix.
     * 
     * @return {@code true} if the next token can be translated into a valid
     *         {@code BigInteger}, otherwise {@code false}.
     * @throws IllegalStateException
     *             if the {@code Scanner} has been closed.
     */
    public boolean hasNextBigInteger() {
        return hasNextBigInteger(integerRadix);
    }

    /**
     * Returns whether the next token can be translated into a valid
     * {@code BigInteger} in the specified radix.
     * 
     * @param radix
     *            the radix used to translate the token into a
     *            {@code BigInteger}.
     * @return {@code true} if the next token can be translated into a valid
     *         {@code BigInteger}, otherwise {@code false}.
     * @throws IllegalStateException
     *             if the {@code Scanner} has been closed.
     */
    public boolean hasNextBigInteger(int radix) {
        Pattern integerPattern = getIntegerPattern(radix);
        boolean isBigIntegerValue = false;
        if (hasNext(integerPattern)) {
            String intString = matcher.group();
            intString = removeLocaleInfo(intString, DataType.INT);
            try {
                cacheHasNextValue = new BigInteger(intString, radix);
                isBigIntegerValue = true;
            } catch (NumberFormatException e) {
                matchSuccessful = false;
            }
        }
        return isBigIntegerValue;
    }

    /**
     * Returns whether the next token can be translated into a valid
     * {@code boolean} value.
     * 
     * @return {@code true} if the next token can be translated into a valid
     *         {@code boolean} value, otherwise {@code false}.
     * @throws IllegalStateException
     *             if the {@code Scanner} has been closed.
     */
    public boolean hasNextBoolean() {
        return hasNext(BOOLEAN_PATTERN);
    }

    /**
     * Returns whether the next token can be translated into a valid
     * {@code byte} value in the default radix.
     * 
     * @return {@code true} if the next token can be translated into a valid
     *         {@code byte} value, otherwise {@code false}.
     * @throws IllegalStateException
     *             if the {@code Scanner} has been closed.
     */
    public boolean hasNextByte() {
        return hasNextByte(integerRadix);
    }

    /**
     * Returns whether the next token can be translated into a valid
     * {@code byte} value in the specified radix.
     * 
     * @param radix
     *            the radix used to translate the token into a {@code byte}
     *            value
     * @return {@code true} if the next token can be translated into a valid
     *         {@code byte} value, otherwise {@code false}.
     * @throws IllegalStateException
     *             if the {@code Scanner} has been closed.
     */
    public boolean hasNextByte(int radix) {
        Pattern integerPattern = getIntegerPattern(radix);
        boolean isByteValue = false;
        if (hasNext(integerPattern)) {
            String intString = matcher.group();
            intString = removeLocaleInfo(intString, DataType.INT);
            try {
                cacheHasNextValue = Byte.valueOf(intString, radix);
                isByteValue = true;
            } catch (NumberFormatException e) {
                matchSuccessful = false;
            }
        }
        return isByteValue;
    }

    /**
     * Returns whether the next token translated into a valid {@code double}
     * value.
     * 
     * @return {@code true} if the next token can be translated into a valid
     *         {@code double} value, otherwise {@code false}.
     * @throws IllegalStateException
     *             if the {@code Scanner} has been closed.
     */
    public boolean hasNextDouble() {
        Pattern floatPattern = getFloatPattern();
        boolean isDoubleValue = false;
        if (hasNext(floatPattern)) {
            String floatString = matcher.group();
            floatString = removeLocaleInfoFromFloat(floatString);
            try {
                cacheHasNextValue = Double.valueOf(floatString);
                isDoubleValue = true;
            } catch (NumberFormatException e) {
                matchSuccessful = false;
            }
        }
        return isDoubleValue;
    }

    /**
     * Returns whether the next token can be translated into a valid
     * {@code float} value.
     * 
     * @return {@code true} if the next token can be translated into a valid
     *         {@code float} value, otherwise {@code false}.
     * @throws IllegalStateException
     *             if the {@code Scanner} has been closed.
     */
    public boolean hasNextFloat() {
        Pattern floatPattern = getFloatPattern();
        boolean isFloatValue = false;
        if (hasNext(floatPattern)) {
            String floatString = matcher.group();
            floatString = removeLocaleInfoFromFloat(floatString);
            try {
                cacheHasNextValue = Float.valueOf(floatString);
                isFloatValue = true;
            } catch (NumberFormatException e) {
                matchSuccessful = false;
            }
        }
        return isFloatValue;
    }

    /**
     * Returns whether the next token can be translated into a valid {@code int}
     * value in the default radix.
     * 
     * @return {@code true} if the next token can be translated into a valid
     *         {@code int} value, otherwise {@code false}.
     * @throws IllegalStateException
     *             if the {@code Scanner} has been closed,
     */
    public boolean hasNextInt() {
        return hasNextInt(integerRadix);
    }

    /**
     * Returns whether the next token can be translated into a valid {@code int}
     * value in the specified radix.
     * 
     * @param radix
     *            the radix used to translate the token into an {@code int}
     *            value.
     * @return {@code true} if the next token in this {@code Scanner}'s input can be
     *         translated into a valid {@code int} value, otherwise
     *         {@code false}.
     * @throws IllegalStateException
     *             if the {@code Scanner} has been closed.
     */
    public boolean hasNextInt(int radix) {
        Pattern integerPattern = getIntegerPattern(radix);
        boolean isIntValue = false;
        if (hasNext(integerPattern)) {
            String intString = matcher.group();
            intString = removeLocaleInfo(intString, DataType.INT);
            try {
                cacheHasNextValue = Integer.valueOf(intString, radix);
                isIntValue = true;
            } catch (NumberFormatException e) {
                matchSuccessful = false;
            }
        }
        return isIntValue;
    }

    /**
     * Returns whether there is a line terminator in the input.
     * This method may block.
     * 
     * @return {@code true} if there is a line terminator in the input,
     *         otherwise, {@code false}.
     * @throws IllegalStateException
     *             if the {@code Scanner} is closed.
     */
    public boolean hasNextLine() {
        checkClosed();
        matcher.usePattern(LINE_PATTERN);
        matcher.region(findStartIndex, bufferLength);

        boolean hasNextLine = false;
        while (true) {
            if (matcher.find()) {
                if (inputExhausted || matcher.end() != bufferLength) {
                    matchSuccessful = true;
                    hasNextLine = true;
                    break;
                }
            } else {
                if (inputExhausted) {
                    matchSuccessful = false;
                    break;
                }
            }
            if (!inputExhausted) {
                readMore();
                resetMatcher();
            }
        }
        return hasNextLine;
    }

    /**
     * Returns whether the next token can be translated into a valid
     * {@code long} value in the default radix.
     * 
     * @return {@code true} if the next token can be translated into a valid
     *         {@code long} value, otherwise {@code false}.
     * @throws IllegalStateException
     *             if the {@code Scanner} has been closed.
     */
    public boolean hasNextLong() {
        return hasNextLong(integerRadix);
    }

    /**
     * Returns whether the next token can be translated into a valid
     * {@code long} value in the specified radix.
     * 
     * @param radix
     *            the radix used to translate the token into a {@code long}
     *            value.
     * @return {@code true} if the next token can be translated into a valid
     *         {@code long} value, otherwise {@code false}.
     * @throws IllegalStateException
     *             if the {@code Scanner} has been closed.
     */
    public boolean hasNextLong(int radix) {
        Pattern integerPattern = getIntegerPattern(radix);
        boolean isLongValue = false;
        if (hasNext(integerPattern)) {
            String intString = matcher.group();
            intString = removeLocaleInfo(intString, DataType.INT);
            try {
                cacheHasNextValue = Long.valueOf(intString, radix);
                isLongValue = true;
            } catch (NumberFormatException e) {
                matchSuccessful = false;
            }
        }
        return isLongValue;
    }

    /**
     * Returns whether the next token can be translated into a valid
     * {@code short} value in the default radix.
     * 
     * @return {@code true} if the next token can be translated into a valid
     *         {@code short} value, otherwise {@code false}.
     * @throws IllegalStateException
     *             if the {@code Scanner} has been closed.
     */
    public boolean hasNextShort() {
        return hasNextShort(integerRadix);
    }

    /**
     * Returns whether the next token can be translated into a valid
     * {@code short} value in the specified radix.
     * 
     * @param radix
     *            the radix used to translate the token into a {@code short}
     *            value.
     * @return {@code true} if the next token can be translated into a valid
     *         {@code short} value, otherwise {@code false}.
     * @throws IllegalStateException
     *             if the {@code Scanner} has been closed.
     */
    public boolean hasNextShort(int radix) {
        Pattern integerPattern = getIntegerPattern(radix);
        boolean isShortValue = false;
        if (hasNext(integerPattern)) {
            String intString = matcher.group();
            intString = removeLocaleInfo(intString, DataType.INT);
            try {
                cacheHasNextValue = Short.valueOf(intString, radix);
                isShortValue = true;
            } catch (NumberFormatException e) {
                matchSuccessful = false;
            }
        }
        return isShortValue;
    }

    /**
     * Returns the last {@code IOException} that was raised while reading from the underlying
     * input.
     * 
     * @return the last thrown {@code IOException}, or {@code null} if none was thrown.
     */
    public IOException ioException() {
        return lastIOException;
    }

    /**
     * Return the {@code Locale} of this {@code Scanner}.
     * 
     * @return the {@code Locale} of this {@code Scanner}.
     */
    public Locale locale() {
        return locale;
    }

    /**
     * Returns the result of the last matching operation.
     * <p>
     * The next* and find* methods return the match result in the case of a
     * successful match.
     * 
     * @return the match result of the last successful match operation
     * @throws IllegalStateException
     *             if the match result is not available, of if the last match
     *             was not successful.
     */
    public MatchResult match() {
        if (!matchSuccessful) {
            throw new IllegalStateException();
        }
        return matcher.toMatchResult();
    }

    /**
     * Returns the next token. The token will be both prefixed and postfixed by
     * the delimiter that is currently being used (or a string that matches the
     * delimiter pattern). This method will block if input is being read.
     * 
     * @return the next complete token.
     * @throws IllegalStateException
     *             if this {@code Scanner} has been closed.
     * @throws NoSuchElementException
     *             if input has been exhausted.
     */
    public String next() {
        return next(ANY_PATTERN);
    }

    /**
     * Returns the next token if it matches the specified pattern. The token
     * will be both prefixed and postfixed by the delimiter that is currently
     * being used (or a string that matches the delimiter pattern). This method will block
     * if input is being read.
     * 
     * @param pattern
     *            the specified pattern to scan.
     * @return the next token.
     * @throws IllegalStateException
     *             if this {@code Scanner} has been closed.
     * @throws NoSuchElementException
     *             if input has been exhausted.
     * @throws InputMismatchException
     *             if the next token does not match the pattern given.
     */
    public String next(Pattern pattern) {
        checkClosed();
        checkNull(pattern);
        matchSuccessful = false;
        saveCurrentStatus();
        if (!setTokenRegion()) {
            recoverPreviousStatus();
            // if setting match region fails
            throw new NoSuchElementException();
        }
        matcher.usePattern(pattern);
        if (!matcher.matches()) {
            recoverPreviousStatus();
            throw new InputMismatchException();

        }
        matchSuccessful = true;
        return matcher.group();
    }

    /**
     * Returns the next token if it matches the specified pattern. The token
     * will be both prefixed and postfixed by the delimiter that is currently
     * being used (or a string that matches the delimiter pattern). This method will block
     * if input is being read. Calling this methods is equivalent to
     * {@code next(Pattern.compile(pattern))}.
     * 
     * @param pattern
     *            the string specifying the pattern to scan for.
     * @return the next token.
     * @throws IllegalStateException
     *             if this {@code Scanner} has been closed.
     * @throws NoSuchElementException
     *             if input has been exhausted.
     * @throws InputMismatchException
     *             if the next token does not match the pattern given.
     */
    public String next(String pattern) {
        return next(Pattern.compile(pattern));
    }

    /**
     * Returns the next token as a {@code BigDecimal}. This method will block if input is
     * being read. If the next token can be translated into a {@code BigDecimal}
     * the following is done: All {@code Locale}-specific prefixes, group separators,
     * and {@code Locale}-specific suffixes are removed. Then non-ASCII digits are
     * mapped into ASCII digits via {@link Character#digit(char, int)}, and a
     * negative sign (-) is added if the {@code Locale}-specific negative prefix or
     * suffix was present. Finally the resulting string is passed to
     * {@code BigDecimal(String) }.
     * 
     * @return the next token as a {@code BigDecimal}.
     * @throws IllegalStateException
     *             if this {@code Scanner} has been closed.
     * @throws NoSuchElementException
     *             if input has been exhausted.
     * @throws InputMismatchException
     *             if the next token can not be translated into a valid
     *             {@code BigDecimal}.
     */
    public BigDecimal nextBigDecimal() {
        checkClosed();
        Object obj = cacheHasNextValue;
        cacheHasNextValue = null;
        if (obj instanceof BigDecimal) {
            findStartIndex = cachehasNextIndex;
            return (BigDecimal) obj;
        }
        Pattern floatPattern = getFloatPattern();
        String floatString = next(floatPattern);
        floatString = removeLocaleInfoFromFloat(floatString);
        BigDecimal bigDecimalValue;
        try {
            bigDecimalValue = new BigDecimal(floatString);
        } catch (NumberFormatException e) {
            matchSuccessful = false;
            recoverPreviousStatus();
            throw new InputMismatchException();
        }
        return bigDecimalValue;
    }

    /**
     * Returns the next token as a {@code BigInteger}. This method will block if input is
     * being read. Equivalent to {@code nextBigInteger(DEFAULT_RADIX)}.
     * 
     * @return the next token as {@code BigInteger}.
     * @throws IllegalStateException
     *             if this {@code Scanner} has been closed.
     * @throws NoSuchElementException
     *             if input has been exhausted.
     * @throws InputMismatchException
     *             if the next token can not be translated into a valid
     *             {@code BigInteger}.
     */
    public BigInteger nextBigInteger() {
        return nextBigInteger(integerRadix);
    }

    /**
     * Returns the next token as a {@code BigInteger} with the specified radix.
     * This method will block if input is being read. If the next token can be translated
     * into a {@code BigInteger} the following is done: All {@code Locale}-specific
     * prefixes, group separators, and {@code Locale}-specific suffixes are removed.
     * Then non-ASCII digits are mapped into ASCII digits via
     * {@link Character#digit(char, int)}, and a negative sign (-) is added if the
     * {@code Locale}-specific negative prefix or suffix was present. Finally the
     * resulting String is passed to {@link BigInteger#BigInteger(String, int)}}
     * with the specified radix.
     * 
     * @param radix
     *            the radix used to translate the token into a
     *            {@code BigInteger}.
     * @return the next token as a {@code BigInteger}
     * @throws IllegalStateException
     *             if this {@code Scanner} has been closed.
     * @throws NoSuchElementException
     *             if input has been exhausted.
     * @throws InputMismatchException
     *             if the next token can not be translated into a valid
     *             {@code BigInteger}.
     */
    public BigInteger nextBigInteger(int radix) {
        checkClosed();
        Object obj = cacheHasNextValue;
        cacheHasNextValue = null;
        if (obj instanceof BigInteger) {
            findStartIndex = cachehasNextIndex;
            return (BigInteger) obj;
        }
        Pattern integerPattern = getIntegerPattern(radix);
        String intString = next(integerPattern);
        intString = removeLocaleInfo(intString, DataType.INT);
        BigInteger bigIntegerValue;
        try {
            bigIntegerValue = new BigInteger(intString, radix);
        } catch (NumberFormatException e) {
            matchSuccessful = false;
            recoverPreviousStatus();
            throw new InputMismatchException();
        }
        return bigIntegerValue;
    }

    /**
     * Returns the next token as a {@code boolean}. This method will block if input is
     * being read.
     * 
     * @return the next token as a {@code boolean}.
     * @throws IllegalStateException
     *             if this {@code Scanner} has been closed.
     * @throws NoSuchElementException
     *             if input has been exhausted.
     * @throws InputMismatchException
     *             if the next token can not be translated into a valid
     *             {@code boolean} value.
     */
    public boolean nextBoolean() {
        return Boolean.parseBoolean(next(BOOLEAN_PATTERN));
    }

    /**
     * Returns the next token as a {@code byte}. This method will block if input is being
     * read. Equivalent to {@code nextByte(DEFAULT_RADIX)}.
     * 
     * @return the next token as a {@code byte}.
     * @throws IllegalStateException
     *             if this {@code Scanner} has been closed.
     * @throws NoSuchElementException
     *             if input has been exhausted.
     * @throws InputMismatchException
     *             if the next token can not be translated into a valid
     *             {@code byte} value.
     */
    public byte nextByte() {
        return nextByte(integerRadix);
    }

    /**
     * Returns the next token as a {@code byte} with the specified radix. Will
     * block if input is being read. If the next token can be translated into a
     * {@code byte} the following is done: All {@code Locale}-specific prefixes, group
     * separators, and {@code Locale}-specific suffixes are removed. Then non-ASCII
     * digits are mapped into ASCII digits via
     * {@link Character#digit(char, int)}, and a negative sign (-) is added if the
     * {@code Locale}-specific negative prefix or suffix was present. Finally the
     * resulting String is passed to {@link Byte#parseByte(String, int)}} with
     * the specified radix.
     * 
     * @param radix
     *            the radix used to translate the token into {@code byte} value.
     * @return the next token as a {@code byte}.
     * @throws IllegalStateException
     *             if this {@code Scanner} has been closed.
     * @throws NoSuchElementException
     *             if input has been exhausted.
     * @throws InputMismatchException
     *             if the next token can not be translated into a valid
     *             {@code byte} value.
     */
    @SuppressWarnings("boxing")
    public byte nextByte(int radix) {
        checkClosed();
        Object obj = cacheHasNextValue;
        cacheHasNextValue = null;
        if (obj instanceof Byte) {
            findStartIndex = cachehasNextIndex;
            return (Byte) obj;
        }
        Pattern integerPattern = getIntegerPattern(radix);
        String intString = next(integerPattern);
        intString = removeLocaleInfo(intString, DataType.INT);
        byte byteValue = 0;
        try {
            byteValue = Byte.parseByte(intString, radix);
        } catch (NumberFormatException e) {
            matchSuccessful = false;
            recoverPreviousStatus();
            throw new InputMismatchException();
        }
        return byteValue;
    }

    /**
     * Returns the next token as a {@code double}. This method will block if input is being
     * read. If the next token can be translated into a {@code double} the
     * following is done: All {@code Locale}-specific prefixes, group separators, and
     * {@code Locale}-specific suffixes are removed. Then non-ASCII digits are mapped
     * into ASCII digits via {@link Character#digit(char, int)}, and a negative
     * sign (-) is added if the {@code Locale}-specific negative prefix or suffix was
     * present. Finally the resulting String is passed to
     * {@link Double#parseDouble(String)}}. If the token matches the localized
     * NaN or infinity strings, it is also passed to
     * {@link Double#parseDouble(String)}}.
     * 
     * @return the next token as a {@code double}.
     * @throws IllegalStateException
     *             if this {@code Scanner} has been closed.
     * @throws NoSuchElementException
     *             if input has been exhausted.
     * @throws InputMismatchException
     *             if the next token can not be translated into a valid
     *             {@code double} value.
     */
    @SuppressWarnings("boxing")
    public double nextDouble() {
        checkClosed();
        Object obj = cacheHasNextValue;
        cacheHasNextValue = null;
        if (obj instanceof Double) {
            findStartIndex = cachehasNextIndex;
            return (Double) obj;
        }
        Pattern floatPattern = getFloatPattern();
        String floatString = next(floatPattern);
        floatString = removeLocaleInfoFromFloat(floatString);
        double doubleValue = 0;
        try {
            doubleValue = Double.parseDouble(floatString);
        } catch (NumberFormatException e) {
            matchSuccessful = false;
            recoverPreviousStatus();
            throw new InputMismatchException();
        }
        return doubleValue;
    }

    /**
     * Returns the next token as a {@code float}. This method will block if input is being
     * read. If the next token can be translated into a {@code float} the
     * following is done: All {@code Locale}-specific prefixes, group separators, and
     * {@code Locale}-specific suffixes are removed. Then non-ASCII digits are mapped
     * into ASCII digits via {@link Character#digit(char, int)}, and a negative
     * sign (-) is added if the {@code Locale}-specific negative prefix or suffix was
     * present. Finally the resulting String is passed to
     * {@link Float#parseFloat(String)}}.If the token matches the localized NaN
     * or infinity strings, it is also passed to
     * {@link Float#parseFloat(String)}}.
     * 
     * @return the next token as a {@code float}.
     * @throws IllegalStateException
     *             if this {@code Scanner} has been closed.
     * @throws NoSuchElementException
     *             if input has been exhausted.
     * @throws InputMismatchException
     *             if the next token can not be translated into a valid
     *             {@code float} value.
     */
    @SuppressWarnings("boxing")
    public float nextFloat() {
        checkClosed();
        Object obj = cacheHasNextValue;
        cacheHasNextValue = null;
        if (obj instanceof Float) {
            findStartIndex = cachehasNextIndex;
            return (Float) obj;
        }
        Pattern floatPattern = getFloatPattern();
        String floatString = next(floatPattern);
        floatString = removeLocaleInfoFromFloat(floatString);
        float floatValue = 0;
        try {
            floatValue = Float.parseFloat(floatString);
        } catch (NumberFormatException e) {
            matchSuccessful = false;
            recoverPreviousStatus();
            throw new InputMismatchException();
        }
        return floatValue;
    }

    /**
     * Returns the next token as an {@code int}. This method will block if input is being
     * read. Equivalent to {@code nextInt(DEFAULT_RADIX)}.
     * 
     * @return the next token as an {@code int}
     * @throws IllegalStateException
     *             if this {@code Scanner} has been closed.
     * @throws NoSuchElementException
     *             if input has been exhausted.
     * @throws InputMismatchException
     *             if the next token can not be translated into a valid
     *             {@code int} value.
     */
    public int nextInt() {
        return nextInt(integerRadix);
    }

    /**
     * Returns the next token as an {@code int} with the specified radix. This method will
     * block if input is being read. If the next token can be translated into an
     * {@code int} the following is done: All {@code Locale}-specific prefixes, group
     * separators, and {@code Locale}-specific suffixes are removed. Then non-ASCII
     * digits are mapped into ASCII digits via
     * {@link Character#digit(char, int)}, and a negative sign (-) is added if the
     * {@code Locale}-specific negative prefix or suffix was present. Finally the
     * resulting String is passed to {@link Integer#parseInt(String, int)} with
     * the specified radix.
     * 
     * @param radix
     *            the radix used to translate the token into an {@code int}
     *            value.
     * @return the next token as an {@code int}.
     * @throws IllegalStateException
     *             if this {@code Scanner} has been closed.
     * @throws NoSuchElementException
     *             if input has been exhausted.
     * @throws InputMismatchException
     *             if the next token can not be translated into a valid
     *             {@code int} value.
     */
    @SuppressWarnings("boxing")
    public int nextInt(int radix) {
        checkClosed();
        Object obj = cacheHasNextValue;
        cacheHasNextValue = null;
        if (obj instanceof Integer) {
            findStartIndex = cachehasNextIndex;
            return (Integer) obj;
        }
        Pattern integerPattern = getIntegerPattern(radix);
        String intString = next(integerPattern);
        intString = removeLocaleInfo(intString, DataType.INT);
        int intValue = 0;
        try {
            intValue = Integer.parseInt(intString, radix);
        } catch (NumberFormatException e) {
            matchSuccessful = false;
            recoverPreviousStatus();
            throw new InputMismatchException();
        }
        return intValue;
    }

    /**
     * Returns the skipped input and advances the {@code Scanner} to the beginning of
     * the next line. The returned result will exclude any line terminator. When
     * searching, if no line terminator is found, then a large amount of input
     * will be cached. If no line at all can be found, a {@code NoSuchElementException}
     * will be thrown.
     * 
     * @return the skipped line.
     * @throws IllegalStateException
     *             if the {@code Scanner} is closed.
     * @throws NoSuchElementException
     *             if no line can be found, e.g. when input is an empty string.
     */
    public String nextLine() {
        checkClosed();

        matcher.usePattern(LINE_PATTERN);
        matcher.region(findStartIndex, bufferLength);
        String result = null;
        while (true) {
            if (matcher.find()) {
                if (inputExhausted || matcher.end() != bufferLength
                        || bufferLength < buffer.capacity()) {
                    matchSuccessful = true;
                    findStartIndex = matcher.end();
                    result = matcher.group();
                    break;
                }
            } else {
                if (inputExhausted) {
                    matchSuccessful = false;
                    throw new NoSuchElementException();
                }
            }
            if (!inputExhausted) {
                readMore();
                resetMatcher();
            }
        }
        // Find text without line terminator here.
        if (null != result) {
            Matcher terminatorMatcher = LINE_TERMINATOR.matcher(result);
            if (terminatorMatcher.find()) {
                result = result.substring(0, terminatorMatcher.start());
            }
        }
        return result;
    }

    /**
     * Returns the next token as a {@code long}. This method will block if input is being
     * read. Equivalent to {@code nextLong(DEFAULT_RADIX)}.
     * 
     * @return the next token as a {@code long}.
     * @throws IllegalStateException
     *             if this {@code Scanner} has been closed.
     * @throws NoSuchElementException
     *             if input has been exhausted.
     * @throws InputMismatchException
     *             if the next token can not be translated into a valid
     *             {@code long} value.
     */
    public long nextLong() {
        return nextLong(integerRadix);
    }

    /**
     * Returns the next token as a {@code long} with the specified radix. This method will
     * block if input is being read. If the next token can be translated into a
     * {@code long} the following is done: All {@code Locale}-specific prefixes, group
     * separators, and {@code Locale}-specific suffixes are removed. Then non-ASCII
     * digits are mapped into ASCII digits via
     * {@link Character#digit(char, int)}, and a negative sign (-) is added if the
     * {@code Locale}-specific negative prefix or suffix was present. Finally the
     * resulting String is passed to {@link Long#parseLong(String, int)}} with
     * the specified radix.
     * 
     * @param radix
     *            the radix used to translate the token into a {@code long}
     *            value.
     * @return the next token as a {@code long}.
     * @throws IllegalStateException
     *             if this {@code Scanner} has been closed.
     * @throws NoSuchElementException
     *             if input has been exhausted.
     * @throws InputMismatchException
     *             if the next token can not be translated into a valid
     *             {@code long} value.
     */
    @SuppressWarnings("boxing")
    public long nextLong(int radix) {
        checkClosed();
        Object obj = cacheHasNextValue;
        cacheHasNextValue = null;
        if (obj instanceof Long) {
            findStartIndex = cachehasNextIndex;
            return (Long) obj;
        }
        Pattern integerPattern = getIntegerPattern(radix);
        String intString = next(integerPattern);
        intString = removeLocaleInfo(intString, DataType.INT);
        long longValue = 0;
        try {
            longValue = Long.parseLong(intString, radix);
        } catch (NumberFormatException e) {
            matchSuccessful = false;
            recoverPreviousStatus();
            throw new InputMismatchException();
        }
        return longValue;
    }

    /**
     * Returns the next token as a {@code short}. This method will block if input is being
     * read. Equivalent to {@code nextShort(DEFAULT_RADIX)}.
     * 
     * @return the next token as a {@code short}.
     * @throws IllegalStateException
     *             if this {@code Scanner} has been closed.
     * @throws NoSuchElementException
     *             if input has been exhausted.
     * @throws InputMismatchException
     *             if the next token can not be translated into a valid
     *             {@code short} value.
     */
    public short nextShort() {
        return nextShort(integerRadix);
    }

    /**
     * Returns the next token as a {@code short} with the specified radix. This method will
     * block if input is being read. If the next token can be translated into a
     * {@code short} the following is done: All {@code Locale}-specific prefixes, group
     * separators, and {@code Locale}-specific suffixes are removed. Then non-ASCII
     * digits are mapped into ASCII digits via
     * {@link Character#digit(char, int)}, and a negative sign (-) is added if the
     * {@code Locale}-specific negative prefix or suffix was present. Finally the
     * resulting String is passed to {@link Short#parseShort(String, int)}}
     * with the specified radix.
     * 
     * @param radix
     *            the radix used to translate the token into {@code short}
     *            value.
     * @return the next token as a {@code short}.
     * @throws IllegalStateException
     *             if this {@code Scanner} has been closed.
     * @throws NoSuchElementException
     *             if input has been exhausted.
     * @throws InputMismatchException
     *             if the next token can not be translated into a valid
     *             {@code short} value.
     */
    @SuppressWarnings("boxing")
    public short nextShort(int radix) {
        checkClosed();
        Object obj = cacheHasNextValue;
        cacheHasNextValue = null;
        if (obj instanceof Short) {
            findStartIndex = cachehasNextIndex;
            return (Short) obj;
        }
        Pattern integerPattern = getIntegerPattern(radix);
        String intString = next(integerPattern);
        intString = removeLocaleInfo(intString, DataType.INT);
        short shortValue = 0;
        try {
            shortValue = Short.parseShort(intString, radix);
        } catch (NumberFormatException e) {
            matchSuccessful = false;
            recoverPreviousStatus();
            throw new InputMismatchException();
        }
        return shortValue;
    }

    /**
     * Return the radix of this {@code Scanner}.
     * 
     * @return the radix of this {@code Scanner}
     */
    public int radix() {
        return integerRadix;
    }

    /**
     * Tries to use specified pattern to match input starting from the current position.
     * The delimiter will be ignored. If a match is found, the matched input will be
     * skipped. If an anchored match of the specified pattern succeeds, the corresponding input
     * will also be skipped. Otherwise, a {@code NoSuchElementException} will be thrown.
     * Patterns that can match a lot of input may cause the {@code Scanner} to read
     * in a large amount of input.
     * 
     * @param pattern
     *            used to skip over input.
     * @return the {@code Scanner} itself.
     * @throws IllegalStateException
     *             if the {@code Scanner} is closed.
     * @throws NoSuchElementException
     *             if the specified pattern match fails.
     */
    public Scanner skip(Pattern pattern) {
        checkClosed();
        checkNull(pattern);
        matcher.usePattern(pattern);
        matcher.region(findStartIndex, bufferLength);
        while (true) {
            if (matcher.lookingAt()) {
                boolean matchInBuffer = matcher.end() < bufferLength
                        || (matcher.end() == bufferLength && inputExhausted);
                if (matchInBuffer) {
                    matchSuccessful = true;
                    findStartIndex = matcher.end();
                    break;
                }
            } else {
                if (inputExhausted) {
                    matchSuccessful = false;
                    throw new NoSuchElementException();
                }
            }
            if (!inputExhausted) {
                readMore();
                resetMatcher();
            }
        }
        return this;
    }

    /**
     * Tries to use the specified string to construct a pattern and then uses
     * the constructed pattern to match input starting from the current position. The
     * delimiter will be ignored. This call is the same as invoke
     * {@code skip(Pattern.compile(pattern))}.
     * 
     * @param pattern
     *            the string used to construct a pattern which in turn is used to
     *            match input.
     * @return the {@code Scanner} itself.
     * @throws IllegalStateException
     *             if the {@code Scanner} is closed.
     */
    public Scanner skip(String pattern) {
        return skip(Pattern.compile(pattern));
    }

    /**
     * Returns a string representation of this {@code Scanner}. The information
     * returned may be helpful for debugging. The format of the string is unspecified.
     * 
     * @return a string representation of this {@code Scanner}.
     */
    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(this.getClass()).append(": ") //$NON-NLS-1$
                .append("{(delimiter:") //$NON-NLS-1$
                .append(delimiter).append(")(findStartIndex=") //$NON-NLS-1$
                .append(findStartIndex).append(")(match succeed=") //$NON-NLS-1$
                .append(matchSuccessful).append(")(closed=") //$NON-NLS-1$
                .append(closed).append(")}"); //$NON-NLS-1$
        return stringBuilder.toString();
    }

    /**
     * Sets the delimiting pattern of this {@code Scanner}.
     * 
     * @param pattern
     *            the delimiting pattern to use.
     * @return this {@code Scanner}.
     */
    public Scanner useDelimiter(Pattern pattern) {
        delimiter = pattern;
        return this;
    }

    /**
     * Sets the delimiting pattern of this {@code Scanner} with a pattern compiled from
     * the supplied string value.
     * 
     * @param pattern
     *            a string from which a {@code Pattern} can be compiled.
     * @return this {@code Scanner}.
     */
    public Scanner useDelimiter(String pattern) {
        return useDelimiter(Pattern.compile(pattern));
    }

    /**
     * Sets the {@code Locale} of this {@code Scanner} to a specified {@code Locale}.
     *
     * @param l
     *            the specified {@code Locale} to use.
     * @return this {@code Scanner}.
     */
    public Scanner useLocale(Locale l) {
        if (null == l) {
            throw new NullPointerException();
        }
        this.locale = l;
        return this;
    }

    /**
     * Sets the radix of this {@code Scanner} to the specified radix.
     *
     * @param radix
     *            the specified radix to use.
     * @return this {@code Scanner}.
     */
    public Scanner useRadix(int radix) {
        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
            throw new IllegalArgumentException(org.apache.harmony.luni.util.Msg
                    .getString("KA008", radix)); //$NON-NLS-1$
        }
        this.integerRadix = radix;
        return this;
    }

    /**
     * Remove is not a supported operation on {@code Scanner}.
     * 
     * @throws UnsupportedOperationException
     *             if this method is invoked.
     */
    public void remove() {
        throw new UnsupportedOperationException();
    }

    /*
     * Initialize some components.
     */
    private void initialization() {
        buffer = CharBuffer.allocate(DEFAULT_TRUNK_SIZE);
        buffer.limit(0);
        matcher = delimiter.matcher(buffer);
    }

    /*
     * Check the {@code Scanner}'s state, if it is closed, IllegalStateException will be
     * thrown.
     */
    private void checkClosed() {
        if (closed) {
            throw new IllegalStateException();
        }
    }

    /*
     * Check the inputed pattern. If it is null, then a NullPointerException
     * will be thrown out.
     */
    private void checkNull(Pattern pattern) {
        if (null == pattern) {
            throw new NullPointerException();
        }
    }

    /*
     * Change the matcher's string after reading input
     */
    private void resetMatcher() {
        if (null == matcher) {
            matcher = delimiter.matcher(buffer);
        } else {
            matcher.reset(buffer);
        }
        matcher.region(findStartIndex, bufferLength);
    }

    /*
     * Save the matcher's last find position
     */
    private void saveCurrentStatus() {
        preStartIndex = findStartIndex;
    }

    /*
     * Change the matcher's status to last find position
     */
    private void recoverPreviousStatus() {
        findStartIndex = preStartIndex;
    }

    /*
     * Get integer's pattern
     */
    private Pattern getIntegerPattern(int radix) {
        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
            throw new IllegalArgumentException(org.apache.harmony.luni.util.Msg
                    .getString("KA00e", radix)); //$NON-NLS-1$
        }
        decimalFormat = (DecimalFormat) NumberFormat.getInstance(locale);

        String allAvailableDigits = "0123456789abcdefghijklmnopqrstuvwxyz"; //$NON-NLS-1$ 
        String ASCIIDigit = allAvailableDigits.substring(0, radix);
        String nonZeroASCIIDigit = allAvailableDigits.substring(1, radix);

        StringBuilder digit = new StringBuilder("((?i)[").append(ASCIIDigit) //$NON-NLS-1$ 
                .append("]|\\p{javaDigit})"); //$NON-NLS-1$
        StringBuilder nonZeroDigit = new StringBuilder("((?i)[").append( //$NON-NLS-1$
                nonZeroASCIIDigit).append("]|([\\p{javaDigit}&&[^0]]))"); //$NON-NLS-1$
        StringBuilder numeral = getNumeral(digit, nonZeroDigit);

        StringBuilder integer = new StringBuilder("(([-+]?(").append(numeral) //$NON-NLS-1$
                .append(")))|(").append(addPositiveSign(numeral)).append(")|(") //$NON-NLS-1$ //$NON-NLS-2$
                .append(addNegativeSign(numeral)).append(")"); //$NON-NLS-1$

        Pattern integerPattern = Pattern.compile(integer.toString());
        return integerPattern;
    }

    /*
     * Get pattern of float
     */
    private Pattern getFloatPattern() {
        decimalFormat = (DecimalFormat) NumberFormat.getInstance(locale);

        StringBuilder digit = new StringBuilder("([0-9]|(\\p{javaDigit}))"); //$NON-NLS-1$
        StringBuilder nonZeroDigit = new StringBuilder("[\\p{javaDigit}&&[^0]]"); //$NON-NLS-1$
        StringBuilder numeral = getNumeral(digit, nonZeroDigit);

        String decimalSeparator = "\\" + decimalFormat.getDecimalFormatSymbols()//$NON-NLS-1$
                        .getDecimalSeparator();
        StringBuilder decimalNumeral = new StringBuilder("(").append(numeral) //$NON-NLS-1$
                .append("|").append(numeral) //$NON-NLS-1$
                .append(decimalSeparator).append(digit).append("*+|").append( //$NON-NLS-1$
                        decimalSeparator).append(digit).append("++)"); //$NON-NLS-1$
        StringBuilder exponent = new StringBuilder("([eE][+-]?").append(digit) //$NON-NLS-1$
                .append("+)?"); //$NON-NLS-1$

        StringBuilder decimal = new StringBuilder("(([-+]?").append( //$NON-NLS-1$
                decimalNumeral).append("(").append(exponent).append("?)") //$NON-NLS-1$ //$NON-NLS-2$
                .append(")|(").append(addPositiveSign(decimalNumeral)).append( //$NON-NLS-1$
                        "(").append(exponent).append("?)").append(")|(") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                .append(addNegativeSign(decimalNumeral)).append("(").append( //$NON-NLS-1$
                        exponent).append("?)").append("))"); //$NON-NLS-1$ //$NON-NLS-2$

        StringBuilder hexFloat = new StringBuilder("([-+]?0[xX][0-9a-fA-F]*") //$NON-NLS-1$
                .append("\\.").append(//$NON-NLS-1$
                        "[0-9a-fA-F]+([pP][-+]?[0-9]+)?)"); //$NON-NLS-1$
        String localNaN = decimalFormat.getDecimalFormatSymbols().getNaN();
        String localeInfinity = decimalFormat.getDecimalFormatSymbols()
                .getInfinity();
        StringBuilder nonNumber = new StringBuilder("(NaN|\\Q").append(localNaN) //$NON-NLS-1$
                .append("\\E|Infinity|\\Q").append(localeInfinity).append("\\E)"); //$NON-NLS-1$ //$NON-NLS-2$
        StringBuilder singedNonNumber = new StringBuilder("((([-+]?(").append( //$NON-NLS-1$
                nonNumber).append(")))|(").append(addPositiveSign(nonNumber)) //$NON-NLS-1$
                .append(")|(").append(addNegativeSign(nonNumber)).append("))"); //$NON-NLS-1$ //$NON-NLS-2$

        StringBuilder floatString = new StringBuilder().append(decimal).append(
                "|").append(hexFloat).append("|").append(singedNonNumber); //$NON-NLS-1$ //$NON-NLS-2$
        Pattern floatPattern = Pattern.compile(floatString.toString());
        return floatPattern;
    }

    private StringBuilder getNumeral(StringBuilder digit,
            StringBuilder nonZeroDigit) {
        String groupSeparator = "\\"//$NON-NLS-1$
                + decimalFormat.getDecimalFormatSymbols()
                        .getGroupingSeparator();
        StringBuilder groupedNumeral = new StringBuilder("(").append( //$NON-NLS-1$
                nonZeroDigit).append(digit).append("?").append(digit).append( //$NON-NLS-1$
                "?(").append(groupSeparator).append(digit).append(digit) //$NON-NLS-1$
                .append(digit).append(")+)"); //$NON-NLS-1$
        StringBuilder numeral = new StringBuilder("((").append(digit).append( //$NON-NLS-1$
                "++)|").append(groupedNumeral).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
        return numeral;
    }

    /*
     * Add the locale specific positive prefixes and suffixes to the pattern
     */
    private StringBuilder addPositiveSign(StringBuilder unSignNumeral) {
        String positivePrefix = ""; //$NON-NLS-1$
        String positiveSuffix = ""; //$NON-NLS-1$
        if (!decimalFormat.getPositivePrefix().equals("")) { //$NON-NLS-1$
            positivePrefix = "\\Q" + decimalFormat.getPositivePrefix() + "\\E"; //$NON-NLS-1$ //$NON-NLS-2$
        }
        if (!decimalFormat.getPositiveSuffix().equals("")) { //$NON-NLS-1$
            positiveSuffix = "\\Q" + decimalFormat.getPositiveSuffix() + "\\E"; //$NON-NLS-1$ //$NON-NLS-2$
        }
        StringBuilder signedNumeral = new StringBuilder()
                .append(positivePrefix).append(unSignNumeral).append(
                        positiveSuffix);
        return signedNumeral;
    }

    /*
     * Add the locale specific negative prefixes and suffixes to the pattern
     */
    private StringBuilder addNegativeSign(StringBuilder unSignNumeral) {
        String negativePrefix = ""; //$NON-NLS-1$
        String negativeSuffix = ""; //$NON-NLS-1$
        if (!decimalFormat.getNegativePrefix().equals("")) { //$NON-NLS-1$
            negativePrefix = "\\Q" + decimalFormat.getNegativePrefix() + "\\E"; //$NON-NLS-1$//$NON-NLS-2$
        }
        if (!decimalFormat.getNegativeSuffix().equals("")) { //$NON-NLS-1$
            negativeSuffix = "\\Q" + decimalFormat.getNegativeSuffix() + "\\E"; //$NON-NLS-1$//$NON-NLS-2$
        }
        StringBuilder signedNumeral = new StringBuilder()
                .append(negativePrefix).append(unSignNumeral).append(
                        negativeSuffix);
        return signedNumeral;
    }

    /*
     * Remove locale related information from float String
     */
    private String removeLocaleInfoFromFloat(String floatString) {
        // If the token is HexFloat
        if (-1 != floatString.indexOf('x') || -1 != floatString.indexOf('X')) {
            return floatString;
        }

        int exponentIndex;
        String decimalNumeralString;
        String exponentString;
        // If the token is scientific notation
        if (-1 != (exponentIndex = floatString.indexOf('e'))
                || -1 != (exponentIndex = floatString.indexOf('E'))) {
            decimalNumeralString = floatString.substring(0, exponentIndex);
            exponentString = floatString.substring(exponentIndex + 1,
                    floatString.length());
            decimalNumeralString = removeLocaleInfo(decimalNumeralString,
                    DataType.FLOAT);
            return decimalNumeralString + "e" + exponentString; //$NON-NLS-1$ 
        }
        return removeLocaleInfo(floatString, DataType.FLOAT);
    }

    /*
     * Remove the locale specific prefixes, group separators, and locale
     * specific suffixes from input string
     */
    private String removeLocaleInfo(String token, DataType type) {
        StringBuilder tokenBuilder = new StringBuilder(token);
        boolean negative = removeLocaleSign(tokenBuilder);
        // Remove group separator
        String groupSeparator = String.valueOf(decimalFormat
                .getDecimalFormatSymbols().getGroupingSeparator());
        int separatorIndex = -1;
        while (-1 != (separatorIndex = tokenBuilder.indexOf(groupSeparator))) {
            tokenBuilder.delete(separatorIndex, separatorIndex + 1);
        }
        // Remove decimal separator
        String decimalSeparator = String.valueOf(decimalFormat
                .getDecimalFormatSymbols().getDecimalSeparator());
        separatorIndex = tokenBuilder.indexOf(decimalSeparator);
        StringBuilder result = new StringBuilder(""); //$NON-NLS-1$
        if (DataType.INT == type) {
            for (int i = 0; i < tokenBuilder.length(); i++) {
                if (-1 != Character.digit(tokenBuilder.charAt(i),
                        Character.MAX_RADIX)) {
                    result.append(tokenBuilder.charAt(i));
                }
            }
        }
        if (DataType.FLOAT == type) {
            if (tokenBuilder.toString().equals(
                    decimalFormat.getDecimalFormatSymbols().getNaN())) {
                result.append("NaN");//$NON-NLS-1$ 
            } else if (tokenBuilder.toString().equals(
                    decimalFormat.getDecimalFormatSymbols().getInfinity())) {
                result.append("Infinity");//$NON-NLS-1$ 
            } else {
                for (int i = 0; i < tokenBuilder.length(); i++) {
                    if (-1 != Character.digit(tokenBuilder.charAt(i), 10)) {
                        result.append(Character.digit(tokenBuilder.charAt(i),
                                10));
                    }
                }
            }
        }
        // Token is NaN or Infinity
        if (0 == result.length()) {
            result = tokenBuilder;
        }
        if (-1 != separatorIndex) {
            result.insert(separatorIndex, "."); //$NON-NLS-1$
        }
        // If input is negative
        if (negative) {
            result.insert(0, '-');
        }
        return result.toString();
    }

    /*
     * Remove positive and negative sign from the parameter stringBuilder, and
     * return whether the input string is negative
     */
    private boolean removeLocaleSign(StringBuilder tokenBuilder) {
        String positivePrefix = decimalFormat.getPositivePrefix();
        String positiveSuffix = decimalFormat.getPositiveSuffix();
        String negativePrefix = decimalFormat.getNegativePrefix();
        String negativeSuffix = decimalFormat.getNegativeSuffix();

        if (0 == tokenBuilder.indexOf("+")) { //$NON-NLS-1$
            tokenBuilder.delete(0, 1);
        }
        if (!positivePrefix.equals("") //$NON-NLS-1$
                && 0 == tokenBuilder.indexOf(positivePrefix)) {
            tokenBuilder.delete(0, positivePrefix.length());
        }
        if (!positiveSuffix.equals("") //$NON-NLS-1$
                && -1 != tokenBuilder.indexOf(positiveSuffix)) {
            tokenBuilder.delete(
                    tokenBuilder.length() - positiveSuffix.length(),
                    tokenBuilder.length());
        }
        boolean negative = false;
        if (0 == tokenBuilder.indexOf("-")) { //$NON-NLS-1$
            tokenBuilder.delete(0, 1);
            negative = true;
        }
        if (!negativePrefix.equals("") //$NON-NLS-1$
                && 0 == tokenBuilder.indexOf(negativePrefix)) {
            tokenBuilder.delete(0, negativePrefix.length());
            negative = true;
        }
        if (!negativeSuffix.equals("") //$NON-NLS-1$
                && -1 != tokenBuilder.indexOf(negativeSuffix)) {
            tokenBuilder.delete(
                    tokenBuilder.length() - negativeSuffix.length(),
                    tokenBuilder.length());
            negative = true;
        }
        return negative;
    }

    /*
     * Find the prefixed delimiter and posefixed delimiter in the input resource
     * and set the start index and end index of Matcher region. If postfixed
     * delimiter does not exist, the end index is set to be end of input.
     */
    private boolean setTokenRegion() {
        // The position where token begins
        int tokenStartIndex = 0;
        // The position where token ends
        int tokenEndIndex = 0;
        // Use delimiter pattern
        matcher.usePattern(delimiter);
        matcher.region(findStartIndex, bufferLength);

        tokenStartIndex = findPreDelimiter();
        if (setHeadTokenRegion(tokenStartIndex)) {
            return true;
        }
        tokenEndIndex = findPostDelimiter();
        // If the second delimiter is not found
        if (-1 == tokenEndIndex) {
            // Just first Delimiter Exists
            if (findStartIndex == bufferLength) {
                return false;
            }
            tokenEndIndex = bufferLength;
            findStartIndex = bufferLength;
        }

        matcher.region(tokenStartIndex, tokenEndIndex);
        return true;
    }

    /*
     * Find prefix delimiter
     */
    private int findPreDelimiter() {
        int tokenStartIndex;
        boolean findComplete = false;
        while (!findComplete) {
            if (matcher.find()) {
                findComplete = true;
                // If just delimiter remains
                if (matcher.start() == findStartIndex
                        && matcher.end() == bufferLength) {
                    // If more input resource exists
                    if (!inputExhausted) {
                        readMore();
                        resetMatcher();
                        findComplete = false;
                    }
                }
            } else {
                if (!inputExhausted) {
                    readMore();
                    resetMatcher();
                } else {
                    return -1;
                }
            }
        }
        tokenStartIndex = matcher.end();
        findStartIndex = matcher.end();
        return tokenStartIndex;
    }

    /*
     * Handle some special cases
     */
    private boolean setHeadTokenRegion(int findIndex) {
        int tokenStartIndex;
        int tokenEndIndex;
        boolean setSuccess = false;
        // If no delimiter exists, but something exites in this scanner
        if (-1 == findIndex && preStartIndex != bufferLength) {
            tokenStartIndex = preStartIndex;
            tokenEndIndex = bufferLength;
            findStartIndex = bufferLength;
            matcher.region(tokenStartIndex, tokenEndIndex);
            setSuccess = true;
        }
        // If the first delimiter of scanner is not at the find start position
        if (-1 != findIndex && preStartIndex != matcher.start()) {
            tokenStartIndex = preStartIndex;
            tokenEndIndex = matcher.start();
            findStartIndex = matcher.start();
            // set match region and return
            matcher.region(tokenStartIndex, tokenEndIndex);
            setSuccess = true;
        }
        return setSuccess;
    }

    /*
     * Find postfix delimiter
     */
    private int findPostDelimiter() {
        int tokenEndIndex = 0;
        boolean findComplete = false;
        while (!findComplete) {
            if (matcher.find()) {
                findComplete = true;
                if (matcher.start() == findStartIndex
                        && matcher.start() == matcher.end()) {
                    findComplete = false;
                }
            } else {
                if (!inputExhausted) {
                    readMore();
                    resetMatcher();
                } else {
                    return -1;
                }
            }
        }
        tokenEndIndex = matcher.start();
        findStartIndex = matcher.start();
        return tokenEndIndex;
    }

    /*
     * Read more data from underlying Readable. If nothing is available or I/O
     * operation fails, global boolean variable inputExhausted will be set to
     * true, otherwise set to false.
     */
    private void readMore() {
        int oldPosition = buffer.position();
        int oldBufferLength = bufferLength;
        // Increase capacity if empty space is not enough
        if (bufferLength >= buffer.capacity()) {
            expandBuffer();
        }

        // Read input resource
        int readCount = 0;
        try {
            buffer.limit(buffer.capacity());
            buffer.position(oldBufferLength);
            while ((readCount = input.read(buffer)) == 0) {
                // nothing to do here
            }
        } catch (IOException e) {
            // Consider the scenario: readable puts 4 chars into
            // buffer and then an IOException is thrown out. In this case,
            // buffer is
            // actually grown, but readable.read() will never return.
            bufferLength = buffer.position();
            /*
             * Uses -1 to record IOException occurring, and no more input can be
             * read.
             */
            readCount = -1;
            lastIOException = e;
        }

        buffer.flip();
        buffer.position(oldPosition);
        if (-1 == readCount) {
            inputExhausted = true;
        } else {
            bufferLength = readCount + bufferLength;
        }
    }

    // Expand the size of internal buffer.
    private void expandBuffer() {
        int oldPosition = buffer.position();
        int oldCapacity = buffer.capacity();
        int oldLimit = buffer.limit();
        int newCapacity = oldCapacity * DIPLOID;
        char[] newBuffer = new char[newCapacity];
        System.arraycopy(buffer.array(), 0, newBuffer, 0, oldLimit);
        buffer = CharBuffer.wrap(newBuffer, 0, newCapacity);
        buffer.position(oldPosition);
        buffer.limit(oldLimit);
    }
}
