/*******************************************************************************
 * 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 org.ofbiz.base.util;

import java.sql.Timestamp;
import java.util.Collection;
import java.util.Map;

import org.apache.commons.validator.routines.EmailValidator;
import org.ofbiz.base.lang.IsEmpty;

import com.ibm.icu.util.Calendar;

/**
 * General input/data validation methods
 * Utility methods for validating data, especially input.
 * See detailed description below.
 *
 * <br/> SUMMARY
 * <br/>
 * <br/> This is a set of meethods for validating input. Functions are provided to validate:
 * <br/>    - U.S. and international phone/fax numbers
 * <br/>    - U.S. ZIP codes(5 or 9 digit postal codes)
 * <br/>    - U.S. Postal Codes(2 letter abbreviations for names of states)
 * <br/>    - U.S. Social Security Numbers(abbreviated as SSNs)
 * <br/>    - email addresses
 * <br/>       - dates(entry of year, month, and day and validity of combined date)
 * <br/>       - credit card numbers
 * <br/>
 * <br/> Supporting utility functions validate that:
 * <br/>    - characters are Letter, Digit, or LetterOrDigit
 * <br/>    - strings are a Signed, Positive, Negative, Nonpositive, or Nonnegative integer
 * <br/>    - strings are a Float or a SignedFloat
 * <br/>    - strings are Alphabetic, Alphanumeric, or Whitespace
 * <br/>    - strings contain an integer within a specified range
 * <br/>
 * <br/> Other utility functions are provided to:
 * <br/>    - remove from a string characters which are/are not in a "bag" of selected characters
 * <br/>       - strip whitespace/leading whitespace from a string
 * <br/>
 * <br/> ==============================================================================
 * <br/> NOTE: This code was adapted from the Netscape JavaScript form validation code,
 * <br/> usually found in "FormChek.js". Credit card verification functions Originally
 * <br/> included as Starter Application 1.0.0 in LivePayment.
 * <br/> ==============================================================================
 */
public class UtilValidate {

    public static final String module = UtilValidate.class.getName();

    /** boolean specifying by default whether or not it is okay for a String to be empty */
    public static final boolean defaultEmptyOK = true;

    /** digit characters */
    public static final String digits = "0123456789";

    /** hex digit characters */
    public static final String hexDigits = digits + "abcdefABCDEF";

    /** lower-case letter characters */
    public static final String lowercaseLetters = "abcdefghijklmnopqrstuvwxyz";

    /** upper-case letter characters */
    public static final String uppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    /** letter characters */
    public static final String letters = lowercaseLetters + uppercaseLetters;

    /** whitespace characters */
    public static final String whitespace = " \t\n\r";

    /** decimal point character differs by language and culture */
    public static final String decimalPointDelimiter = ".";

    /** non-digit characters which are allowed in phone numbers */
    public static final String phoneNumberDelimiters = "()- ";

    /** characters which are allowed in US phone numbers */
    public static final String validUSPhoneChars = digits + phoneNumberDelimiters;

    /** characters which are allowed in international phone numbers(a leading + is OK) */
    public static final String validWorldPhoneChars = digits + phoneNumberDelimiters + "+";

    /** non-digit characters which are allowed in Social Security Numbers */
    public static final String SSNDelimiters = "- ";

    /** characters which are allowed in Social Security Numbers */
    public static final String validSSNChars = digits + SSNDelimiters;

    /** U.S. Social Security Numbers have 9 digits. They are formatted as 123-45-6789. */
    public static final int digitsInSocialSecurityNumber = 9;

    /** U.S. phone numbers have 10 digits. They are formatted as 123 456 7890 or(123) 456-7890. */
    public static final int digitsInUSPhoneNumber = 10;
    public static final int digitsInUSPhoneAreaCode = 3;
    public static final int digitsInUSPhoneMainNumber = 7;

    /** non-digit characters which are allowed in ZIP Codes */
    public static final String ZipCodeDelimiters = "-";

    /** our preferred delimiter for reformatting ZIP Codes */
    public static final String ZipCodeDelimeter = "-";

    /** characters which are allowed in Social Security Numbers */
    public static final String validZipCodeChars = digits + ZipCodeDelimiters;

    /** U.S. ZIP codes have 5 or 9 digits. They are formatted as 12345 or 12345-6789. */
    public static final int digitsInZipCode1 = 5;

    /** U.S. ZIP codes have 5 or 9 digits. They are formatted as 12345 or 12345-6789. */
    public static final int digitsInZipCode2 = 9;

    /** non-digit characters which are allowed in credit card numbers */
    public static final String creditCardDelimiters = " -";

    public static final String isNotEmptyMsg = "This field cannot be empty, please enter a value.";
    public static final String isStateCodeMsg = "The State Code must be a valid two character U.S. state abbreviation(like CA for California).";
    public static final String isContiguousStateCodeMsg = "The State Code must be a valid two character U.S. state abbreviation for one of the 48 contiguous United States (like CA for California).";
    public static final String isZipCodeMsg = "The ZIP Code must be a 5 or 9 digit U.S. ZIP Code(like 94043).";
    public static final String isUSPhoneMsg = "The US Phone must be a 10 digit U.S. phone number(like 415-555-1212).";
    public static final String isUSPhoneAreaCodeMsg = "The Phone Number Area Code must be 3 digits.";
    public static final String isUSPhoneMainNumberMsg = "The Phone Number must be 7 digits.";
    public static final String isContiguousZipCodeMsg = "Zip Code is not a valid Zip Code for one of the 48 contiguous United States .";
    public static final String isInternationalPhoneNumberMsg = "The World Phone must be a valid international phone number.";
    public static final String isSSNMsg = "The SSN must be a 9 digit U.S. social security number(like 123-45-6789).";
    public static final String isEmailMsg = "The Email must be a valid email address(like john@email.com). Please re-enter it now.";
    public static final String isAnyCardMsg = "The credit card number is not a valid card number.";
    public static final String isCreditCardPrefixMsg = " is not a valid ";
    public static final String isCreditCardSuffixMsg = " credit card number.";
    public static final String isDayMsg = "The Day must be a day number between 1 and 31. ";
    public static final String isMonthMsg = "The Month must be a month number between 1 and 12. ";
    public static final String isYearMsg = "The Year must be a 2 or 4 digit year number. ";
    public static final String isDatePrefixMsg = "The Day, Month, and Year for ";
    public static final String isDateSuffixMsg = " do not form a valid date.  Please reenter them now.";
    public static final String isHourMsg = "The Hour must be a number between 0 and 23.";
    public static final String isMinuteMsg = "The Minute must be a number between 0 and 59.";
    public static final String isSecondMsg = "The Second must be a number between 0 and 59.";
    public static final String isTimeMsg = "The Time must be a valid time formed like: HH:MM or HH:MM:SS.";
    public static final String isDateMsg = "The Date must be a valid date formed like: MM/YY, MM/YYYY, MM/DD/YY, or MM/DD/YYYY.";
    public static final String isDateAfterToday = "The Date must be a valid date after today, and formed like: MM/YY, MM/YYYY, MM/DD/YY, or MM/DD/YYYY.";
    public static final String isIntegerMsg = "The Number must be a valid unsigned whole decimal number.";
    public static final String isSignedIntegerMsg = "The Number must be a valid signed whole decimal number.";
    public static final String isLongMsg = "The Number must be a valid unsigned whole decimal number.";
    public static final String isSignedLongMsg = "The Number must be a valid signed whole decimal number.";
    public static final String isFloatMsg = "The Number must be a valid unsigned decimal number.";
    public static final String isSignedFloatMsg = "The Number must be a valid signed decimal number.";
    public static final String isSignedDoubleMsg = "The Number must be a valid signed decimal number.";

    /** An array of ints representing the number of days in each month of the year.
     *  Note: February varies depending on the year */
    public static final int[] daysInMonth = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    /** Delimiter for USStateCodes String */
    public static final String USStateCodeDelimiter = "|";

    /** Valid U.S. Postal Codes for states, territories, armed forces, etc.
     * See http://www.usps.gov/ncsc/lookups/abbr_state.txt. */
    public static final String USStateCodes = "AL|AK|AS|AZ|AR|CA|CO|CT|DE|DC|FM|FL|GA|GU|HI|ID|IL|IN|IA|KS|KY|LA|ME|MH|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|MP|OH|OK|OR|PW|PA|PR|RI|SC|SD|TN|TX|UT|VT|VI|VA|WA|WV|WI|WY|AE|AA|AE|AE|AP";

    /** Valid contiguous U.S. postal codes */
    public static final String ContiguousUSStateCodes = "AL|AZ|AR|CA|CO|CT|DE|DC|FL|GA|ID|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY";

    public static boolean areEqual(Object obj, Object obj2) {
        if (obj == null) {
            return obj2 == null;
        } else {
            return obj.equals(obj2);
        }
    }

    /** Check whether an object is empty, will see if it is a String, Map, Collection, etc. */
    public static boolean isEmpty(Object o) {
        return ObjectType.isEmpty(o);
    }

    /** Check whether an object is NOT empty, will see if it is a String, Map, Collection, etc. */
    public static boolean isNotEmpty(Object o) {
        return !ObjectType.isEmpty(o);
    }

    /** Check whether IsEmpty o is empty. */
    public static boolean isEmpty(IsEmpty o) {
        return o == null || o.isEmpty();
    }

    /** Check whether IsEmpty o is NOT empty. */
    public static boolean isNotEmpty(IsEmpty o) {
        return o != null && !o.isEmpty();
    }

    /** Check whether string s is empty. */
    public static boolean isEmpty(String s) {
        return (s == null) || s.length() == 0;
    }

    /** Check whether collection c is empty. */
    public static <E> boolean isEmpty(Collection<E> c) {
        return (c == null) || c.isEmpty();
    }

    /** Check whether map m is empty. */
    public static <K,E> boolean isEmpty(Map<K,E> m) {
        return (m == null) || m.isEmpty();
    }

    /** Check whether charsequence c is empty. */
    public static <E> boolean isEmpty(CharSequence c) {
        return (c == null) || c.length() == 0;
    }

    /** Check whether string s is NOT empty. */
    public static boolean isNotEmpty(String s) {
        return (s != null) && s.length() > 0;
    }

    /** Check whether collection c is NOT empty. */
    public static <E> boolean isNotEmpty(Collection<E> c) {
        return (c != null) && !c.isEmpty();
    }

    /** Check whether charsequence c is NOT empty. */
    public static <E> boolean isNotEmpty(CharSequence c) {
        return ((c != null) && (c.length() > 0));
    }

    public static boolean isString(Object obj) {
        return ((obj != null) && (obj instanceof java.lang.String));
    }

    /** Returns true if string s is empty or whitespace characters only. */
    public static boolean isWhitespace(String s) {
        // Is s empty?
        if (isEmpty(s)) return true;

        // Search through string's characters one by one
        // until we find a non-whitespace character.
        // When we do, return false; if we don't, return true.
        for (int i = 0; i < s.length(); i++) {
            // Check that current character isn't whitespace.
            char c = s.charAt(i);

            if (whitespace.indexOf(c) == -1) return false;
        }
        // All characters are whitespace.
        return true;
    }

    /** Removes all characters which appear in string bag from string s. */
    public static String stripCharsInBag(String s, String bag) {
        int i;
        StringBuilder stringBuilder = new StringBuilder("");

        // Search through string's characters one by one.
        // If character is not in bag, append to returnString.
        for (i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            if (bag.indexOf(c) == -1) stringBuilder.append(c);
        }
        return stringBuilder.toString();
    }

    /** Removes all characters which do NOT appear in string bag from string s. */
    public static String stripCharsNotInBag(String s, String bag) {
        int i;
        StringBuilder stringBuilder = new StringBuilder("");

        // Search through string's characters one by one.
        // If character is in bag, append to returnString.
        for (i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            if (bag.indexOf(c) != -1) stringBuilder.append(c);
        }
        return stringBuilder.toString();
    }

    /** Removes all whitespace characters from s.
     *  Member whitespace(see above) defines which characters are considered whitespace. */
    public static String stripWhitespace(String s) {
        return stripCharsInBag(s, whitespace);
    }

    /** Returns true if single character c(actually a string) is contained within string s. */
    public static boolean charInString(char c, String s) {
        return (s.indexOf(c) != -1);
        // for(int i = 0; i < s.length; i++) {
        // if (s.charAt(i) == c) return true;
        // }
        // return false;
    }

    /** Removes initial(leading) whitespace characters from s.
     *  Member whitespace(see above) defines which characters are considered whitespace. */
    public static String stripInitialWhitespace(String s) {
        int i = 0;

        while ((i < s.length()) && charInString(s.charAt(i), whitespace)) i++;
        return s.substring(i);
        // return s.substring(i, s.length);
    }

    /** Returns true if character c is an English letter (A .. Z, a..z).
     *
     *  NOTE: Need i18n version to support European characters.
     *  This could be tricky due to different character
     *  sets and orderings for various languages and platforms. */
    public static boolean isLetter(char c) {
        return Character.isLetter(c);
    }

    /** Returns true if character c is a digit (0 .. 9). */
    public static boolean isDigit(char c) {
        return Character.isDigit(c);
    }

    /** Returns true if character c is a letter or digit. */
    public static boolean isLetterOrDigit(char c) {
        return Character.isLetterOrDigit(c);
    }

    /** Returns true if character c is a letter or digit. */
    public static boolean isHexDigit(char c) {
        return hexDigits.indexOf(c) >= 0;
    }

    /** Returns true if all characters in string s are numbers.
     *
     *  Accepts non-signed integers only. Does not accept floating
     *  point, exponential notation, etc.
     */
    public static boolean isInteger(String s) {
        if (isEmpty(s)) return defaultEmptyOK;

        // Search through string's characters one by one
        // until we find a non-numeric character.
        // When we do, return false; if we don't, return true.
        for (int i = 0; i < s.length(); i++) {
            // Check that current character is number.
            char c = s.charAt(i);

            if (!isDigit(c)) return false;
        }

        // All characters are numbers.
        return true;
    }

    /** Returns true if all characters are numbers;
     *  first character is allowed to be + or - as well.
     *
     *  Does not accept floating point, exponential notation, etc.
     */
    public static boolean isSignedInteger(String s) {
        if (isEmpty(s)) return defaultEmptyOK;
        try {
            Integer.parseInt(s);
            return true;
        } catch (Exception e) {
            return false;
        }

        // int startPos = 0;
        // boolean secondArg = defaultEmptyOK;

        // if (isSignedInteger.arguments.length > 1) secondArg = isSignedInteger.arguments[1];

        // skip leading + or -
        // if ((s.charAt(0) == "-") ||(s.charAt(0) == "+")) startPos = 1;
        // return(isInteger(s.substring(startPos, s.length), secondArg))
    }

    /** Returns true if all characters are numbers;
     *  first character is allowed to be + or - as well.
     *
     *  Does not accept floating point, exponential notation, etc.
     */
    public static boolean isSignedLong(String s) {
        if (isEmpty(s)) return defaultEmptyOK;
        try {
            Long.parseLong(s);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /** Returns true if string s is an integer > 0. NOTE: using the Java Long object for greatest precision */
    public static boolean isPositiveInteger(String s) {
        if (isEmpty(s)) return defaultEmptyOK;

        try {
            long temp = Long.parseLong(s);

            if (temp > 0) return true;
            return false;
        } catch (Exception e) {
            return false;
        }

        // return(isSignedInteger(s, secondArg)
        // &&((isEmpty(s) && secondArg)  ||(parseInt(s) > 0)));
    }

    /** Returns true if string s is an integer >= 0. */
    public static boolean isNonnegativeInteger(String s) {
        if (isEmpty(s)) return defaultEmptyOK;

        try {
            int temp = Integer.parseInt(s);

            if (temp >= 0) return true;
            return false;
        } catch (Exception e) {
            return false;
        }

        // return(isSignedInteger(s, secondArg)
        // &&((isEmpty(s) && secondArg)  ||(parseInt(s) >= 0)));
    }

    /** Returns true if string s is an integer < 0. */
    public static boolean isNegativeInteger(String s) {
        if (isEmpty(s)) return defaultEmptyOK;

        try {
            int temp = Integer.parseInt(s);

            if (temp < 0) return true;
            return false;
        } catch (Exception e) {
            return false;
        }

        // return(isSignedInteger(s, secondArg)
        // &&((isEmpty(s) && secondArg)  ||(parseInt(s) < 0)));
    }

    /** Returns true if string s is an integer <= 0. */
    public static boolean isNonpositiveInteger(String s) {
        if (isEmpty(s)) return defaultEmptyOK;

        try {
            int temp = Integer.parseInt(s);

            if (temp <= 0) return true;
            return false;
        } catch (Exception e) {
            return false;
        }

        // return(isSignedInteger(s, secondArg)
        // &&((isEmpty(s) && secondArg)  ||(parseInt(s) <= 0)));
    }

    /** True if string s is an unsigned floating point(real) number.
     *
     *  Also returns true for unsigned integers. If you wish
     *  to distinguish between integers and floating point numbers,
     *  first call isInteger, then call isFloat.
     *
     *  Does not accept exponential notation.
     */
    public static boolean isFloat(String s) {
        if (isEmpty(s)) return defaultEmptyOK;

        boolean seenDecimalPoint = false;

        if (s.startsWith(decimalPointDelimiter)) return false;

        // Search through string's characters one by one
        // until we find a non-numeric character.
        // When we do, return false; if we don't, return true.
        for (int i = 0; i < s.length(); i++) {
            // Check that current character is number.
            char c = s.charAt(i);

            if (c == decimalPointDelimiter.charAt(0)) {
                if (!seenDecimalPoint) {
                    seenDecimalPoint = true;
                } else {
                    return false;
                }
            } else {
                if (!isDigit(c)) return false;
            }
        }
        // All characters are numbers.
        return true;
    }

    /** General routine for testing whether a string is a float.
     */
    public static boolean isFloat(String s, boolean allowNegative, boolean allowPositive, int minDecimal, int maxDecimal) {
        if (isEmpty(s)) return defaultEmptyOK;

        try {
            float temp = Float.parseFloat(s);
            if (!allowNegative && temp < 0) return false;
            if (!allowPositive && temp > 0) return false;
            int decimalPoint = s.indexOf(".");
            if (decimalPoint == -1) {
                if (minDecimal > 0) return false;
                return true;
            }
            // 1.2345; length=6; point=1; num=4
            int numDecimals = s.length() - decimalPoint - 1;
            if (minDecimal >= 0 && numDecimals < minDecimal) return false;
            if (maxDecimal >= 0 && numDecimals > maxDecimal) return false;
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /** General routine for testing whether a string is a double.
     */
    public static boolean isDouble(String s, boolean allowNegative, boolean allowPositive, int minDecimal, int maxDecimal) {
        if (isEmpty(s)) return defaultEmptyOK;

        try {
            double temp = Double.parseDouble(s);
            if (!allowNegative && temp < 0) return false;
            if (!allowPositive && temp > 0) return false;
            int decimalPoint = s.indexOf(".");
            if (decimalPoint == -1) {
                if (minDecimal > 0) return false;
                return true;
            }
            // 1.2345; length=6; point=1; num=4
            int numDecimals = s.length() - decimalPoint - 1;
            if (minDecimal >= 0 && numDecimals < minDecimal) return false;
            if (maxDecimal >= 0 && numDecimals > maxDecimal) return false;
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /** True if string s is a signed or unsigned floating point
     *  (real) number. First character is allowed to be + or -.
     *
     *  Also returns true for unsigned integers. If you wish
     *  to distinguish between integers and floating point numbers,
     *  first call isSignedInteger, then call isSignedFloat.
     */
    public static boolean isSignedFloat(String s) {
        if (isEmpty(s)) return defaultEmptyOK;
        try {
            Float.parseFloat(s);
            return true;
        } catch (Exception e) {
            return false;
        }

        //The old way:
        // int startPos = 0;
        // if (isSignedFloat.arguments.length > 1) secondArg = isSignedFloat.arguments[1];
        // skip leading + or -
        // if ((s.charAt(0) == "-") ||(s.charAt(0) == "+")) startPos = 1;
        // return(isFloat(s.substring(startPos, s.length), secondArg))
    }

    /** True if string s is a signed or unsigned floating point
     *  (real) number. First character is allowed to be + or -.
     *
     *  Also returns true for unsigned integers. If you wish
     *  to distinguish between integers and floating point numbers,
     *  first call isSignedInteger, then call isSignedFloat.
     */
    public static boolean isSignedDouble(String s) {
        if (isEmpty(s)) return defaultEmptyOK;
        try {
            Double.parseDouble(s);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /** Returns true if string s is letters only.
     *
     *  NOTE: This should handle i18n version to support European characters, etc.
     *  since it now uses Character.isLetter()
     */
    public static boolean isAlphabetic(String s) {
        if (isEmpty(s)) return defaultEmptyOK;

        // Search through string's characters one by one
        // until we find a non-alphabetic character.
        // When we do, return false; if we don't, return true.
        for (int i = 0; i < s.length(); i++) {
            // Check that current character is letter.
            char c = s.charAt(i);

            if (!isLetter(c))
                return false;
        }

        // All characters are letters.
        return true;
    }

    /** Returns true if string s is English letters (A .. Z, a..z) and numbers only.
     *
     *  NOTE: Need i18n version to support European characters.
     *  This could be tricky due to different character
     *  sets and orderings for various languages and platforms.
     */
    public static boolean isAlphanumeric(String s) {
        if (isEmpty(s)) return defaultEmptyOK;

        // Search through string's characters one by one
        // until we find a non-alphanumeric character.
        // When we do, return false; if we don't, return true.
        for (int i = 0; i < s.length(); i++) {
            // Check that current character is number or letter.
            char c = s.charAt(i);

            if (!isLetterOrDigit(c)) return false;
        }

        // All characters are numbers or letters.
        return true;
    }

    /* ================== METHODS TO CHECK VARIOUS FIELDS. ==================== */

    /** isSSN returns true if string s is a valid U.S. Social Security Number.  Must be 9 digits. */
    public static boolean isSSN(String s) {
        if (isEmpty(s)) return defaultEmptyOK;

        String normalizedSSN = stripCharsInBag(s, SSNDelimiters);

        return (isInteger(normalizedSSN) && normalizedSSN.length() == digitsInSocialSecurityNumber);
    }

    /** isUSPhoneNumber returns true if string s is a valid U.S. Phone Number.  Must be 10 digits. */
    public static boolean isUSPhoneNumber(String s) {
        if (isEmpty(s)) return defaultEmptyOK;
        String normalizedPhone = stripCharsInBag(s, phoneNumberDelimiters);

        return (isInteger(normalizedPhone) && normalizedPhone.length() == digitsInUSPhoneNumber);
    }

    /** isUSPhoneAreaCode returns true if string s is a valid U.S. Phone Area Code.  Must be 3 digits. */
    public static boolean isUSPhoneAreaCode(String s) {
        if (isEmpty(s)) return defaultEmptyOK;
        String normalizedPhone = stripCharsInBag(s, phoneNumberDelimiters);

        return (isInteger(normalizedPhone) && normalizedPhone.length() == digitsInUSPhoneAreaCode);
    }

    /** isUSPhoneMainNumber returns true if string s is a valid U.S. Phone Main Number.  Must be 7 digits. */
    public static boolean isUSPhoneMainNumber(String s) {
        if (isEmpty(s)) return defaultEmptyOK;
        String normalizedPhone = stripCharsInBag(s, phoneNumberDelimiters);

        return (isInteger(normalizedPhone) && normalizedPhone.length() == digitsInUSPhoneMainNumber);
    }

    /** isInternationalPhoneNumber returns true if string s is a valid
     *  international phone number.  Must be digits only; any length OK.
     *  May be prefixed by + character.
     */
    public static boolean isInternationalPhoneNumber(String s) {
        if (isEmpty(s)) return defaultEmptyOK;

        String normalizedPhone = stripCharsInBag(s, phoneNumberDelimiters);

        return isPositiveInteger(normalizedPhone);
    }

    /** isZIPCode returns true if string s is a valid U.S. ZIP code.  Must be 5 or 9 digits only. */
    public static boolean isZipCode(String s) {
        if (isEmpty(s)) return defaultEmptyOK;

        String normalizedZip = stripCharsInBag(s, ZipCodeDelimiters);

        return (isInteger(normalizedZip) && ((normalizedZip.length() == digitsInZipCode1) || (normalizedZip.length() == digitsInZipCode2)));
    }

    /** Returns true if string s is a valid contiguous U.S. Zip code.  Must be 5 or 9 digits only. */
    public static boolean isContiguousZipCode(String s) {
        boolean retval = false;
        if (isZipCode(s)) {
            if (isEmpty(s)) retval = defaultEmptyOK;
            else {
                String normalizedZip = s.substring(0,5);
                int iZip = Integer.parseInt(normalizedZip);
                if ((iZip >= 96701 && iZip <= 96898) || (iZip >= 99501 && iZip <= 99950)) retval = false;
                else retval = true;
            }
        }
        return retval;
    }

    /** Return true if s is a valid U.S. Postal Code (abbreviation for state). */
    public static boolean isStateCode(String s) {
        if (isEmpty(s)) return defaultEmptyOK;
        return ((USStateCodes.indexOf(s) != -1) && (s.indexOf(USStateCodeDelimiter) == -1));
    }

    /** Return true if s is a valid contiguous U.S. Postal Code (abbreviation for state). */
    public static boolean isContiguousStateCode(String s) {
        if (isEmpty(s)) return defaultEmptyOK;
        return ((ContiguousUSStateCodes.indexOf(s) != -1) && (s.indexOf(USStateCodeDelimiter) == -1));
    }

    public static boolean isEmail(String s) {
        if (isEmpty(s)) return defaultEmptyOK;
        return EmailValidator.getInstance().isValid(s);
    }

    /** isUrl returns true if the string contains ://
     * @param s String to validate
     * @return true if s contains ://
     */
    public static boolean isUrl(String s) {
        if (isEmpty(s)) return defaultEmptyOK;
        if (s.indexOf("://") != -1)
            return true;
        return false;
    }

    /** isYear returns true if string s is a valid
     *  Year number.  Must be 2 or 4 digits only.
     *
     *  For Year 2000 compliance, you are advised
     *  to use 4-digit year numbers everywhere.
     */
    public static boolean isYear(String s) {
        if (isEmpty(s)) return defaultEmptyOK;

        if (!isNonnegativeInteger(s)) return false;
        return ((s.length() == 2) || (s.length() == 4));
    }

    /** isIntegerInRange returns true if string s is an integer
     *  within the range of integer arguments a and b, inclusive.
     */
    public static boolean isIntegerInRange(String s, int a, int b) {
        if (isEmpty(s)) return defaultEmptyOK;
        // Catch non-integer strings to avoid creating a NaN below,
        // which isn't available on JavaScript 1.0 for Windows.
        if (!isSignedInteger(s)) return false;
        // Now, explicitly change the type to integer via parseInt
        // so that the comparison code below will work both on
        // JavaScript 1.2(which typechecks in equality comparisons)
        // and JavaScript 1.1 and before(which doesn't).
        int num = Integer.parseInt(s);

        return ((num >= a) && (num <= b));
    }

    /** isMonth returns true if string s is a valid month number between 1 and 12. */
    public static boolean isMonth(String s) {
        if (isEmpty(s)) return defaultEmptyOK;
        return isIntegerInRange(s, 1, 12);
    }

    /** isDay returns true if string s is a valid day number between 1 and 31. */
    public static boolean isDay(String s) {
        if (isEmpty(s)) return defaultEmptyOK;
        return isIntegerInRange(s, 1, 31);
    }

    /** Given integer argument year, returns number of days in February of that year. */
    public static int daysInFebruary(int year) {
        // February has 29 days in any year evenly divisible by four,
        // EXCEPT for centurial years which are not also divisible by 400.
        return (((year % 4 == 0) && ((!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28);
    }

    /** isHour returns true if string s is a valid number between 0 and 23. */
    public static boolean isHour(String s) {
        if (isEmpty(s)) return defaultEmptyOK;
        return isIntegerInRange(s, 0, 23);
    }

    /** isMinute returns true if string s is a valid number between 0 and 59. */
    public static boolean isMinute(String s) {
        if (isEmpty(s)) return defaultEmptyOK;
        return isIntegerInRange(s, 0, 59);
    }

    /** isSecond returns true if string s is a valid number between 0 and 59. */
    public static boolean isSecond(String s) {
        if (isEmpty(s)) return defaultEmptyOK;
        return isIntegerInRange(s, 0, 59);
    }

    /** isDate returns true if string arguments year, month, and day form a valid date. */
    public static boolean isDate(String year, String month, String day) {
        // catch invalid years(not 2- or 4-digit) and invalid months and days.
        if (!(isYear(year) && isMonth(month) && isDay(day))) return false;

        int intYear = Integer.parseInt(year);
        int intMonth = Integer.parseInt(month);
        int intDay = Integer.parseInt(day);

        // catch invalid days, except for February
        if (intDay > daysInMonth[intMonth - 1]) return false;
        if ((intMonth == 2) && (intDay > daysInFebruary(intYear))) return false;
        return true;
    }

    /** isDate returns true if string argument date forms a valid date. */
    public static boolean isDate(String date) {
        if (isEmpty(date)) return defaultEmptyOK;
        String month;
        String day;
        String year;

        int dateSlash1 = date.indexOf("/");
        int dateSlash2 = date.lastIndexOf("/");

        if (dateSlash1 <= 0 || dateSlash1 == dateSlash2) return false;
        month = date.substring(0, dateSlash1);
        day = date.substring(dateSlash1 + 1, dateSlash2);
        year = date.substring(dateSlash2 + 1);

        return isDate(year, month, day);
    }

    /** isDate returns true if string argument date forms a valid date and is after today. */
    public static boolean isDateAfterToday(String date) {
        if (isEmpty(date)) return defaultEmptyOK;
        int dateSlash1 = date.indexOf("/");
        int dateSlash2 = date.lastIndexOf("/");

        if (dateSlash1 <= 0) return false;

        java.util.Date passed = null;
        if (dateSlash1 == dateSlash2) {
            // consider the day to be optional; use the first day of the following month for comparison since this is an is after test
            String month = date.substring(0, dateSlash1);
            String day = "28";
            String year = date.substring(dateSlash1 + 1);
            if (!isDate(year, month, day)) return false;

            try {
                int monthInt = Integer.parseInt(month);
                int yearInt = Integer.parseInt(year);
                Calendar calendar = Calendar.getInstance();
                calendar.set(yearInt, monthInt - 1, 0, 0, 0, 0);
                calendar.add(Calendar.MONTH, 1);
                passed = new java.util.Date(calendar.getTime().getTime());
            } catch (Exception e) {
                passed = null;
            }
        } else {
            String month = date.substring(0, dateSlash1);
            String day = date.substring(dateSlash1 + 1, dateSlash2);
            String year = date.substring(dateSlash2 + 1);
            if (!isDate(year, month, day)) return false;
            passed = UtilDateTime.toDate(month, day, year, "0", "0", "0");
        }

        java.util.Date now = UtilDateTime.nowDate();
        if (passed != null) {
            return passed.after(now);
        } else {
            return false;
        }
    }

    /** isDate returns true if string argument date forms a valid date and is before today. */
    public static boolean isDateBeforeToday(String date) {
        if (isEmpty(date)) return defaultEmptyOK;
        int dateSlash1 = date.indexOf("/");
        int dateSlash2 = date.lastIndexOf("/");

        if (dateSlash1 <= 0) return defaultEmptyOK; // In this case an issue number has been provided (requires a javascript check in template!)

        java.util.Date passed = null;
        if (dateSlash1 == dateSlash2) {
            // consider the day to be optional; use the first day of the following month for comparison since this is an is after test
            String month = date.substring(0, dateSlash1);
            String day = "28";
            String year = date.substring(dateSlash1 + 1);
            if (!isDate(year, month, day)) return false;

            try {
                int monthInt = Integer.parseInt(month);
                int yearInt = Integer.parseInt(year);
                Calendar calendar = Calendar.getInstance();
                calendar.set(yearInt, monthInt - 1, 0, 0, 0, 0);
                calendar.add(Calendar.MONTH, 1);
                passed = new java.util.Date(calendar.getTime().getTime());
            } catch (Exception e) {
                passed = null;
            }
        } else {
            String month = date.substring(0, dateSlash1);
            String day = date.substring(dateSlash1 + 1, dateSlash2);
            String year = date.substring(dateSlash2 + 1);
            if (!isDate(year, month, day)) return false;
            passed = UtilDateTime.toDate(month, day, year, "0", "0", "0");
        }

        java.util.Date now = UtilDateTime.nowDate();
        if (passed != null) {
            return passed.before(now);
        } else {
            return false;
        }
    }

    public static boolean isDateBeforeNow(Timestamp  date) {
        Timestamp now = UtilDateTime.nowTimestamp();
        if (date != null) {
            return date.before(now);
        } else {
            return false;
        }
    }

    public static boolean isDateAfterNow(Timestamp  date) {
        Timestamp now = UtilDateTime.nowTimestamp();
        if (date != null) {
            return date.after(now);
        } else {
            return false;
        }
    }
    /** isTime returns true if string arguments hour, minute, and second form a valid time. */
    public static boolean isTime(String hour, String minute, String second) {
        // catch invalid years(not 2- or 4-digit) and invalid months and days.
        if (isHour(hour) && isMinute(minute) && isSecond(second))
            return true;
        else
            return false;
    }

    /** isTime returns true if string argument time forms a valid time. */
    public static boolean isTime(String time) {
        if (isEmpty(time)) return defaultEmptyOK;

        String hour;
        String minute;
        String second;

        int timeColon1 = time.indexOf(":");
        int timeColon2 = time.lastIndexOf(":");

        if (timeColon1 <= 0) return false;
        hour = time.substring(0, timeColon1);
        if (timeColon1 == timeColon2) {
            minute = time.substring(timeColon1 + 1);
            second = "0";
        } else {
            minute = time.substring(timeColon1 + 1, timeColon2);
            second = time.substring(timeColon2 + 1);
        }
        return isTime(hour, minute, second);
    }

    /** Check to see if a card number is a valid ValueLink Gift Card
     *
     * @param stPassed a string representing a valuelink gift card
     * @return true, if the number passed simple checks
     */
    public static boolean isValueLinkCard(String stPassed) {
        if (isEmpty(stPassed)) return defaultEmptyOK;
        String st = stripCharsInBag(stPassed, creditCardDelimiters);
        if (st.length() == 16 && (st.startsWith("7") || st.startsWith("6"))) {
            return true;
        }
        return false;
    }

    /** Check to see if a card number is a valid OFB Gift Card (Certifiicate)
     *
     * @param stPassed a string representing a gift card
     * @return tru, if the number passed simple checks
     */
    public static boolean isOFBGiftCard(String stPassed) {
        if (isEmpty(stPassed)) return defaultEmptyOK;
        String st = stripCharsInBag(stPassed, creditCardDelimiters);
        if (st.length() == 15 && sumIsMod10(getLuhnSum(st))) {
            return true;
        }
        return false;
    }

    /** Check to see if a card number is a supported Gift Card
     *
     * @param stPassed a string representing a gift card
     * @return true, if the number passed simple checks
     */
    public static boolean isGiftCard(String stPassed) {
        if (isOFBGiftCard(stPassed)) {
            return true;
        } else if (isValueLinkCard(stPassed)) {
            return true;
        }
        return false;
    }

    public static int getLuhnSum(String stPassed) {
        stPassed = stPassed.replaceAll("\\D", ""); // nuke any non-digit characters

        int len = stPassed.length();
        int sum = 0;
        int mul = 1;
        for (int i = len - 1; i >= 0; i--) {
            int digit = Character.digit(stPassed.charAt(i), 10);
            digit *= (mul == 1) ? mul++ : mul--;
            sum += (digit >= 10) ? (digit % 10) + 1 : digit;
        }

        return sum;
    }

    public static int getLuhnCheckDigit(String stPassed) {
        int sum = getLuhnSum(stPassed);
        int mod = ((sum / 10 + 1) * 10 - sum) % 10;
        return (10 - mod);
    }

    public static boolean sumIsMod10(int sum) {
        return ((sum % 10) == 0);
    }

    public static String appendCheckDigit(String stPassed) {
        String checkDigit = Integer.toString(getLuhnCheckDigit(stPassed));
        return stPassed + checkDigit;
    }

    /** Checks credit card number with Luhn Mod-10 test
     *
     * @param stPassed a string representing a credit card number
     * @return true, if the credit card number passes the Luhn Mod-10 test, false otherwise
     */
    public static boolean isCreditCard(String stPassed) {
        if (isEmpty(stPassed)) return defaultEmptyOK;
        String st = stripCharsInBag(stPassed, creditCardDelimiters);
		
		if (!isInteger(st)) return false;
		
        // encoding only works on cars with less the 19 digits
        if (st.length() > 19) return false;
        return sumIsMod10(getLuhnSum(st));
    }

    /** Checks to see if the cc number is a valid Visa number
     *
     * @param cc a string representing a credit card number; Sample number: 4111 1111 1111 1111(16 digits)
     * @return true, if the credit card number is a valid VISA number, false otherwise
     */
    public static boolean isVisa(String cc) {
        if (((cc.length() == 16) || (cc.length() == 13)) && (cc.substring(0, 1).equals("4")))
            return isCreditCard(cc);
        return false;
    }

    /** Checks to see if the cc number is a valid Master Card number
     *
     * @param cc a string representing a credit card number; Sample number: 5500 0000 0000 0004(16 digits)
     * @return true, if the credit card number is a valid MasterCard  number, false otherwise
     */
    public static boolean isMasterCard(String cc) {
        int firstdig = Integer.parseInt(cc.substring(0, 1));
        int seconddig = Integer.parseInt(cc.substring(1, 2));

        if ((cc.length() == 16) && (firstdig == 5) && ((seconddig >= 1) && (seconddig <= 5)))
            return isCreditCard(cc);
        return false;

    }

    /** Checks to see if the cc number is a valid American Express number
     *   @param    cc - a string representing a credit card number; Sample number: 340000000000009(15 digits)
     *   @return  true, if the credit card number is a valid American Express number, false otherwise
     */
    public static boolean isAmericanExpress(String cc) {
        int firstdig = Integer.parseInt(cc.substring(0, 1));
        int seconddig = Integer.parseInt(cc.substring(1, 2));

        if ((cc.length() == 15) && (firstdig == 3) && ((seconddig == 4) || (seconddig == 7)))
            return isCreditCard(cc);
        return false;

    }

    /** Checks to see if the cc number is a valid Diners Club number
     *   @param    cc - a string representing a credit card number; Sample number: 30000000000004(14 digits)
     *   @return  true, if the credit card number is a valid Diner's Club number, false otherwise
     */
    public static boolean isDinersClub(String cc) {
        int firstdig = Integer.parseInt(cc.substring(0, 1));
        int seconddig = Integer.parseInt(cc.substring(1, 2));

        if ((cc.length() == 14) && (firstdig == 3) && ((seconddig == 0) || (seconddig == 6) || (seconddig == 8)))
            return isCreditCard(cc);
        return false;
    }

    /** Checks to see if the cc number is a valid Carte Blanche number
     *   @param    cc - a string representing a credit card number; Sample number: 30000000000004(14 digits)
     *   @return  true, if the credit card number is a valid Carte Blanche number, false otherwise
     */
    public static boolean isCarteBlanche(String cc) {
        return isDinersClub(cc);
    }

    /** Checks to see if the cc number is a valid Discover number
     *   @param    cc - a string representing a credit card number; Sample number: 6011000000000004(16 digits)
     *   @return  true, if the credit card number is a valid Discover card number, false otherwise
     */
    public static boolean isDiscover(String cc) {
        String first4digs = cc.substring(0, 4);

        if ((cc.length() == 16) && (first4digs.equals("6011")))
            return isCreditCard(cc);
        return false;
    }

    /** Checks to see if the cc number is a valid EnRoute number
     *   @param    cc - a string representing a credit card number; Sample number: 201400000000009(15 digits)
     *   @return  true, if the credit card number is a valid enRoute card number, false, otherwise
     */
    public static boolean isEnRoute(String cc) {
        String first4digs = cc.substring(0, 4);

        if ((cc.length() == 15) && (first4digs.equals("2014") || first4digs.equals("2149")))
            return isCreditCard(cc);
        return false;
    }

    /** Checks to see if the cc number is a valid JCB number
     *   @param     cc - a string representing a credit card number; Sample number: 3088000000000009(16 digits)
     *   @return  true, if the credit card number is a valid JCB card number, false otherwise
     */
    public static boolean isJCB(String cc) {
        String first4digs = cc.substring(0, 4);

        if ((cc.length() == 16) &&
            (first4digs.equals("3088") ||
                first4digs.equals("3096") ||
                first4digs.equals("3112") ||
                first4digs.equals("3158") ||
                first4digs.equals("3337") ||
                first4digs.equals("3528")))
            return isCreditCard(cc);
        return false;
    }

    /** Checks to see if the cc number is a valid Switch number
     *   @param     cc - a string representing a credit card number; Sample number: 6331100000000096(16 digits)
     *   @return  true, if the credit card number is a valid Switch card number, false otherwise
     */
    public static boolean isswitch (String cc) {
        String first4digs = cc.substring(0, 4);
        String first6digs = cc.substring(0, 6);

        if (((cc.length() == 16) || (cc.length() == 18) || (cc.length() == 19)) &&
            (first4digs.equals("4903") ||
                first4digs.equals("4905") ||
                first4digs.equals("4911") ||
                first4digs.equals("4936") ||
                first6digs.equals("564182") ||
                first6digs.equals("633110") ||
                first4digs.equals("6333") ||
                first4digs.equals("6759")))
            return isCreditCard(cc);
        return false;
    }

    /** Checks to see if the cc number is a valid Solo number
     *   @param     cc - a string representing a credit card number; Sample number: 6331100000000096 (16 digits)
     *   @return  true, if the credit card number is a valid Solo card number, false otherwise
     */
    public static boolean isSolo(String cc) {
        String first4digs = cc.substring(0, 4);
        String first2digs = cc.substring(0, 2);
        if (((cc.length() == 16) || (cc.length() == 18) || (cc.length() == 19)) &&
                (first2digs.equals("63") || first4digs.equals("6767")))
            return isCreditCard(cc);
        return false;
    }

    /** Checks to see if the cc number is a valid Visa Electron number
     *   @param    cc - a string representing a credit card number; Sample number: 4175000000000001(16 digits)
     *   @return  true, if the credit card number is a valid Visa Electron card number, false otherwise
     */
    public static boolean isVisaElectron(String cc) {
        String first6digs = cc.substring(0, 6);
        String first4digs = cc.substring(0, 4);

        if ((cc.length() == 16) &&
            (first6digs.equals("417500") ||
                first4digs.equals("4917") ||
                first4digs.equals("4913") ||
                first4digs.equals("4508") ||
                first4digs.equals("4844") ||
                first4digs.equals("4027")))
            return isCreditCard(cc);
        return false;
    }


    /** Checks to see if the cc number is a valid number for any accepted credit card
     *   @param     ccPassed - a string representing a credit card number
     *   @return  true, if the credit card number is any valid credit card number for any of the accepted card types, false otherwise
     */
    public static boolean isAnyCard(String ccPassed) {
        if (isEmpty(ccPassed)) return defaultEmptyOK;

        String cc = stripCharsInBag(ccPassed, creditCardDelimiters);

        if (!isCreditCard(cc)) return false;
        if (isMasterCard(cc) || isVisa(cc) || isAmericanExpress(cc) || isDinersClub(cc) ||
                isDiscover(cc) || isEnRoute(cc) || isJCB(cc) || isSolo(cc)|| isswitch (cc)|| isVisaElectron(cc))
            return true;
        return false;
    }

    /** Checks to see if the cc number is a valid number for any accepted credit card, and return the name of that type
     *   @param     ccPassed - a string representing a credit card number
     *   @return  true, if the credit card number is any valid credit card number for any of the accepted card types, false otherwise
     */
    public static String getCardType(String ccPassed) {
        if (isEmpty(ccPassed)) return "Unknown";
        String cc = stripCharsInBag(ccPassed, creditCardDelimiters);

        if (!isCreditCard(cc)) return "Unknown";

        if (isMasterCard(cc)) return "MasterCard";
        if (isVisa(cc)) return "Visa";
        if (isAmericanExpress(cc)) return "AmericanExpress";
        if (isDinersClub(cc)) return "DinersClub";
        if (isDiscover(cc)) return "Discover";
        if (isEnRoute(cc)) return "EnRoute";
        if (isJCB(cc)) return "JCB";
        if (isSolo(cc)) return "Solo";
        if (isswitch (cc)) return "Switch";
        if (isVisaElectron(cc)) return "VisaElectron";
        return "Unknown";
    }

    /** Checks to see if the cc number is a valid number for the specified type
     *   @param    cardType - a string representing the credit card type
     *   @param    cardNumberPassed - a string representing a credit card number
     *   @return  true, if the credit card number is valid for the particular credit card type given in "cardType", false otherwise
     */
    public static boolean isCardMatch(String cardType, String cardNumberPassed) {
        if (isEmpty(cardType)) return defaultEmptyOK;
        if (isEmpty(cardNumberPassed)) return defaultEmptyOK;
        String cardNumber = stripCharsInBag(cardNumberPassed, creditCardDelimiters);

        if ((cardType.equalsIgnoreCase("VISA")) && (isVisa(cardNumber))) return true;
        if ((cardType.equalsIgnoreCase("MASTERCARD")) && (isMasterCard(cardNumber))) return true;
        if (((cardType.equalsIgnoreCase("AMERICANEXPRESS")) || (cardType.equalsIgnoreCase("AMEX"))) && (isAmericanExpress(cardNumber))) return true;
        if ((cardType.equalsIgnoreCase("DISCOVER")) && (isDiscover(cardNumber))) return true;
        if ((cardType.equalsIgnoreCase("JCB")) && (isJCB(cardNumber))) return true;
        if (((cardType.equalsIgnoreCase("DINERSCLUB")) || (cardType.equalsIgnoreCase("DINERS"))) && (isDinersClub(cardNumber))) return true;
        if ((cardType.equalsIgnoreCase("CARTEBLANCHE")) && (isCarteBlanche(cardNumber))) return true;
        if ((cardType.equalsIgnoreCase("ENROUTE")) && (isEnRoute(cardNumber))) return true;
        if ((cardType.equalsIgnoreCase("SOLO")) && (isSolo(cardNumber))) return true;
        if ((cardType.equalsIgnoreCase("SWITCH")) && (isswitch (cardNumber))) return true;
        if ((cardType.equalsIgnoreCase("VISAELECTRON")) && (isVisaElectron(cardNumber))) return true;
        return false;
    }


    /** isNotPoBox returns true if address argument does not contain anything that looks like a a PO Box. */
    public static boolean isNotPoBox(String s) {
        if (isEmpty(s)) return defaultEmptyOK;

        // strings to check from Greg's program
        // "P.O. B"
        // "P.o.B"
        // "P.O B"
        // "PO. B"
        // "P O B"
        // "PO B"
        // "P.0. B"
        // "P0 B"

        String sl = s.toLowerCase();
        if (sl.indexOf("p.o. b") != -1) return false;
        if (sl.indexOf("p.o.b") != -1) return false;
        if (sl.indexOf("p.o b") != -1) return false;
        if (sl.indexOf("p o b") != -1) return false;
        if (sl.indexOf("po b") != -1) return false;
        if (sl.indexOf("pobox") != -1) return false;
        if (sl.indexOf("po#") != -1) return false;
        if (sl.indexOf("po #") != -1) return false;

        // now with 0's for them sneaky folks
        if (sl.indexOf("p.0. b") != -1) return false;
        if (sl.indexOf("p.0.b") != -1) return false;
        if (sl.indexOf("p.0 b") != -1) return false;
        if (sl.indexOf("p 0 b") != -1) return false;
        if (sl.indexOf("p0 b") != -1) return false;
        if (sl.indexOf("p0box") != -1) return false;
        if (sl.indexOf("p0#") != -1) return false;
        if (sl.indexOf("p0 #") != -1) return false;
        return true;
    }

    public static boolean isValidUpc(String upc) {
        if (upc == null || upc.length() != 12) {
            throw new IllegalArgumentException("Invalid UPC length; must be 12 characters");
        }

        char csum = upc.charAt(11);
        char calcSum = calcUpcChecksum(upc);
        return csum == calcSum;
    }

    public static char calcUpcChecksum(String upc) {
        return calcChecksum(upc, 12);
    }

    public static boolean isValidEan(String ean) {
        if (ean == null || ean.length() != 13) {
            throw new IllegalArgumentException("Invalid EAN length; must be 13 characters");
        }
        char csum = ean.charAt(13);
        char calcSum = calcChecksum(ean, 13);
        return csum == calcSum;
    }

    public static char calcChecksum(String value, int length) {
        if (value != null && value.length() == length + 1) {
            value = value.substring(0, length);
        }
        if (value == null || value.length() != length) {
            throw new IllegalArgumentException("Illegal size of value; must be either" + length + " or " + (length + 1) + " characters");
        }
        int oddsum = 0;
        int evensum = 0;
        for (int i = value.length() - 1; i >= 0; i--) {
            if ((value.length() - i) % 2 == 0) {
                evensum += Character.digit(value.charAt(i), 10);
            } else {
                oddsum += Character.digit(value.charAt(i), 10);
            }
        }
        int check = 10 - ((evensum + 3 * oddsum) % 10);
        if (check >= 10) check = 0;
        return Character.forDigit(check, 10);
    }

    public static String checkValidDatabaseId(String fieldStr) {
        if (fieldStr.indexOf(' ') >= 0) {
            return "[space found at position " + (fieldStr.indexOf(' ') + 1) + "]";
        }
        if (fieldStr.indexOf('"') >= 0) {
            return "[double-quote found at position " + (fieldStr.indexOf('"') + 1) + "]";
        }
        if (fieldStr.indexOf('\'') >= 0) {
            return "[single-quote found at position " + (fieldStr.indexOf('\'') + 1) + "]";
        }
        if (fieldStr.indexOf('&') >= 0) {
            return "[ampersand found at position " + (fieldStr.indexOf('&') + 1) + "]";
        }
        if (fieldStr.indexOf('?') >= 0) {
            return "[question mark found at position " + (fieldStr.indexOf('?') + 1) + "]";
        }
        if (fieldStr.indexOf('<') >= 0) {
            return "[less-than sign found at position " + (fieldStr.indexOf('<') + 1) + "]";
        }
        if (fieldStr.indexOf('>') >= 0) {
            return "[greater-than sign found at position " + (fieldStr.indexOf('>') + 1) + "]";
        }
        if (fieldStr.indexOf('\\') >= 0) {
            return "[back-slash found at position " + (fieldStr.indexOf('\\') + 1) + "]";
        }
        if (fieldStr.indexOf('/') >= 0) {
            return "[forward-slash found at position " + (fieldStr.indexOf('/') + 1) + "]";
        }
        return null;
    }

    public static boolean isValidDatabaseId(String fieldStr, StringBuffer errorDetails) {
        boolean isValid = true;
        String checkMessage = checkValidDatabaseId(fieldStr);
        if (checkMessage != null) {
            isValid = false;
            errorDetails.append(checkMessage);
        }
        return isValid;
    }

    public static boolean isValidDatabaseId(String fieldStr, StringBuilder errorDetails) {
        boolean isValid = true;
        String checkMessage = checkValidDatabaseId(fieldStr);
        if (checkMessage != null) {
            isValid = false;
            errorDetails.append(checkMessage);
        }
        return isValid;
    }
}
