var sCharsAlphaLower    = "abcdefghijklmnopqrstuvwxyz";
var sCharsAlphaUpper    = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var sCharsAlpha         = sCharsAlphaUpper + sCharsAlphaLower;
var sCharsNumeric       = "0123456789";
var sCharsAlphaNumeric  = sCharsAlpha + sCharsNumeric;

/**
 *  This function removes all non-alphabetic characters from the 
 *  provided string and returns a string
 *
 *  @param  string   the String to be formatted
 *  @return string   the formatted String
 *  @see    strInvertStrip
 *  @see    strEmpty
 */

function formatAlpha(sAlpha)
{
    sAlpha = strInvertStrip(sAlpha, sCharsAlpha);

    if (strEmpty(sAlpha))
    {
        return("");
    }
    else
    {
        return(sAlpha);
    }
} // end formatAlpha

/**
 *  This function removes all non-alphabetic and numeric characters 
 *  from the provided string and returns a string
 *
 *
 *  @param  string   the String to be formatted
 *  @return string   the formatted String
 *  @see    strInvertStrip
 *  @see    strEmpty
 */

function formatAlphaNumeric(sAlphaNumeric)
{
    sAlphaNumeric = strInvertStrip(sAlphaNumeric, sCharsAlphaNumeric);

    if (strEmpty(sAlphaNumeric))
    {
        return("");
    }
    else
    {
        return(sAlphaNumeric);
    }
} // end formatAlphaNumeric

/**
 *  This function formats the provided string into a valid credit card number
 *
 *  @param  string   the String to be formatted
 *  @return string   the formatted String. null if isCC fails
 *  @see    isCC
 *  @see    strInvertStrip
 */

function formatCC(sCC)
{
    sCC = strInvertStrip(sCC, sCharsNumeric);

    if (!isCC(sCC))
    {
        return(null);
    }
    else
    {
        return(sCC);
    }
} // end formatCC

/**
 *  This function formats the provided string into a valid US currency
 *
 *  @param  string   the String to be formatted
 *  @return string   the formatted String, null is isCurrency fails
 *  @see    isCurrency
 *  @see    strInvertStrip
 *  @see    strEmpty
 */

function formatCurrency(sCurrency)
{
    var sTemp       = "";
    var sConversion = "";
    var sCents      = "";
    var lConversion = 0;
    var dCurrency   = 0;

    sTemp = strInvertStrip(sCurrency, sCharsAlpha);

    if (!isCurrency(sCurrency))
    {
        return(null);
    }
    if (sTemp.length > 0)
    {
        if (sTemp.length == 1)
        {
            if (!strEmpty(strInvertStrip(sTemp, "KMBTQZ")))
            {
                sConversion = sTemp;
            }
        }
    }

    sCurrency = strInvertStrip(sCurrency, sCharsNumeric + '.');

    if (!strEmpty(sConversion))
    {
        if (sConversion == "K")  lConversion = 1000;
        else if (sConversion =="M")  lConversion = 1000000;
        else if (sConversion == "B")  lConversion = 1000000000;
        else if (sConversion == "T")  lConversion = 1000000000000;
        else if (sConversion == "Q")  lConversion = 1000000000000000;
        else if (sConversion == "Z")  lConversion = 1000000000000000000;
        dCurrency = parseFloat(sCurrency) * lConversion;
    }
    else
    {
        dCurrency = parseFloat(sCurrency);
    }

    sCurrency = "" + dCurrency;

    if (sCurrency.indexOf(".") > 0)
    {
        sCents = sCurrency.substring(sCurrency.indexOf(".") + 1, sCurrency.length);

        if (sCents.length == 1)
        {
            sCents = sCents + "0";
        }
        else if (sCents.length > 2)
        {
            sCents = sCents.substring(0, 2);
        }

        sCurrency = sCurrency.substring(0, sCurrency.indexOf(".")) + "." + sCents;
    }
    else
    {
        sCurrency += ".00";
    }

    return(sCurrency);
} // end formatCurrency

/**
 *  This function formats the provided string into a valid date string
 *
 *  @param  string(alphanumeric_string)
 *  @return string(string), null if isDate fails
 *  @see    isDate
 */

function formatDate(sDate)
{
    var aDate       = new Array();
    var sDay        = null;
    var sMonth      = null;
    var sYear       = null;
    var iDay        = 0;
    var iMonth      = 0;
    var iYear       = 0;
    var bFound      = false;
    var aSeparator  = new Array("-"," ","/",".");
    var aMonth      = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
    var i           = 0;

    if (!isDate(sDate))
    {
        return(null);
    }
    else
    {
        for (i = 0; i < aSeparator.length; i++)
        {
            if (sDate.indexOf(aSeparator[i]) != -1)
            {
                aDate   = sDate.split(aSeparator[i]);
                sMonth  = aDate[0];
                sDay    = aDate[1];
                sYear   = aDate[2];
                bFound  = true;
            }
        }

        if (bFound == false)
        {
            if (sDate.length > 5)
            {
                sMonth  = sDate.substring(0, 2);
                sDay    = sDate.substring(2, 4);
                sYear   = sDate.substring(4);
            }
        }

        if (sYear.length == 2)
        {
            sYear = "20" + sYear;
        }

        iDay = parseInt(sDay, 10); //Integer.parseInt(sDay, 10);
        iMonth = parseInt(sMonth, 10); //Integer.parseInt(sMonth, 10);

        if (!isInteger(toString(iMonth)))//
        {
            for (i = 0; i < 12; i++)
            {
                sMonth = sMonth.substring(0, 3);

                if (sMonth.toUpperCase() == aMonth[i].toUpperCase())
                {
                    iMonth = i + 1;
                    sMonth = aMonth[i];
                    i = 12;
                }
            }
        }

        iYear = parseInt(sYear, 10);
	dateStr = "";
	dateStr += (iMonth < 10) ? ("0" + iMonth) : iMonth;
	dateStr += "-";
	dateStr += (iDay < 10) ? ("0" + iDay) : iDay;
	dateStr += "-";
	dateStr += iYear;
	return dateStr;
    }
} // end formatDate

/**
 *  This function removes all non-numeric characters (except for
 *  decimal points) from the provided string and returns a double
 *
 *  @param  string   the String to be converted
 *  @return double   the converted number, '0.0' if isDecimal fails
 *  @see    strInvertStrip
 */

function formatDecimal(sDouble)
{
    sDouble = strInvertStrip(sDouble, sCharsNumeric + ".");
    var test = 0;

    if (!isDecimal(sDouble))
    {
        return(0.0);
    }
    else
    {
        return(parseFloat(sDouble));
    }
} // end formatDecimal

/**
 *  This function formats the provided string into a valid email address
 *
 *  @param  string   the String to be formatted
 *  @return string   the formatted String, null if isEmail fails
 *  @see    isEmail
 *  @see    strTest
 */

function formatEmail(sEmail)
{
    if (!isEmail(sEmail))
    {
        return(null);
    }
    else
    {
        var aEmail      = new Array();
        var sUsername   = "";
        var sDomain     = "";
        
        // split the user @ domain
        aEmail      = sEmail.split("@");
        sUsername   = aEmail[0];
        sDomain     = aEmail[1];
        
        // format username
        if (!strTest(sUsername, "\""))
        {
            sUsername = sUsername.toLowerCase();
        }
        
        // format domain name
        sDomain = sDomain.toLowerCase();
        
        sEmail = sUsername + "@" + sDomain;
        
        return(sEmail);
    }
} // end formatEmail

/**
 *  This function converts all alphabetical characters
 *  to lower case.
 *
 *  @param  string   the String to be formatted
 *  @return string   the formatted String.  Null if parameter was null.
 *  @see    strEmpty
 */

function formatLowerCase(sLower)
{
    if (strEmpty(sLower))
    {
        return(null);
    }
    else
    {
        return( sLower.toLowerCase() );
    }
} // end formatLowerCase

/**
 *  This function converts the first letter of a completely lower-case
 *  name to upper case, including Hyphenated or compound names. ('jean-luc'
 *  will become 'Jean-Luc', but 'du Maurier' will remain 'du Maurier'.)
 *
 *  @param  string  the String to be formatted
 *  @return string  the formatted String. Null if paramter was null.
 *  @see    strTest
 */

function formatName(sUpper)
{
    var sUpperFirst = "";
    var sUpperMid   = "";
    var sUpperLast  = "";
    
    // Check to make sure the name is less than 60 characters and contains valid characters
    if (sUpper.length <= 60 && strTest(sUpper, sCharsAlpha + "'- "))
    {
        // Check to see if there are no upper-case characters
        if (strTest(sUpper, sCharsAlphaLower + sCharsNumeric + "'- "))
        {
            var bFoundFirstLetter = false;
            // Look for the first letter in the name
            for (var i = 0; i < sUpper.length; i++)
            {
                sUpperMid = sUpper.substring(i, i + 1);

                if (isAlpha(sUpper.substring(i, i+1)) && !bFoundFirstLetter)
                {
                    bFoundFirstLetter = true;

                    if (i > 0)
                    {
                        sUpperFirst = sUpper.substring(0, i);
                    }
                    else
                    {
                        sUpperFirst = "";
                    }
                    
                    if (i < sUpper.length + 1)
                    {
                        sUpperLast = sUpper.substring(i + 1, sUpper.length);
                    }
                    else
                    {
                        sUpperLast = "";
                    }

                    sUpper = sUpperFirst + sUpperMid.toUpperCase() + sUpperLast;
                }
                else if (strTest(sUpper.substring(i, i+1), "- "))
                {
                    bFoundFirstLetter = false;
                }
            }
        }
    }
    
    return(sUpper);
} // end formatUpperCase

/**
 *  This function removes all non-numeric characters from the 
 *  provided string and returns an integer
 *
 *  @param  string   the String to be converted
 *  @return string   the formatted string
 *  @see    strInvertStrip
 *  @see    strEmpty
 */

function formatNumber(sNumber)
{
    sNumber = strInvertStrip(sNumber, sCharsNumeric);

    if (strEmpty(sNumber) || (sNumber == "0"))
    {
        return("0");
    }
    else
    {
        return(strInvertStrip(sNumber, sCharsNumeric));
    }
} // end formatNumber

/**
 *  This function formats the provided string into a valid US phone number
 *
 *  @param  string   the String to be formatted
 *  @return string   the formatted String, null if isPhone fails
 *  @see    isPhone
 *  @see    strInvertStrip
 */

function formatPhone(sPhone)
{
    var sReturn = "";
    sPhone = strInvertStrip(sPhone, sCharsNumeric);

    if (!isPhone(sPhone))
    {
        return(null);
    }
    else
    {
        if (sPhone.substring(0, 1) == "1")
        {
            sPhone = sPhone.substring(1, sPhone.length);
        }

        sReturn += sPhone.substring(0, 3);
        sReturn += '-';
        sReturn += sPhone.substring(3, 6);
        sReturn += '-';
        sReturn += sPhone.substring(6, 10);

        return(sReturn);
    }
} // end formatPhone

/**
 *  This function formats the provided string into a valid social security number
 *
 *  @param  string   the String to be formatted
 *  @return string   the formatted String, null if isSSN fails
 *  @see    isSSN
 *  @see    strInvertStrip
 */

function formatSSN(sSSN)
{
    sSSN = strInvertStrip(sSSN, sCharsNumeric);

    if (!isSSN(sSSN))
    {
        return(null);
    }
    else
    {
        return(sSSN.substring(0, 3) + '-' + sSSN.substring(3, 5) + '-' + sSSN.substring(5, 9));
    }
} // end formatSSN

/**
 *  This function converts all alphabetical characters
 *  to upper case.  
 *
 *  @param  string   the String to be formatted
 *  @return string   the formatted String.  Null if parameter was null.
 *  @see    strEmpty
 */

function formatUpperCase(sUpper)
{
    if (strEmpty(sUpper))
    {
        return(null);
    }
    else
    {
        return(sUpper.toUpperCase());
    }
} // end formatUpperCase

/**
 *  This function converts every letter found after a space 
 *  to upper case.  In other words, the first letter of every
 *  word is capitalized.
 *
 *  @param  string   the String to be formatted
 *  @return string   the formatted String.  Null if parameter was null.
 *  @see    strEmpty
 */

function formatUpperCaseFirst(sUpperFirst)
{
    if (strEmpty(sUpperFirst))
    {
        return(null);
    }
    else
    {
        var sBuffer     = "";   //buffer to build new string
        var sChar       = "";   // One of the characters in sUpperFirst.
        var sPrevChar   = "";   // The character that comes before ch in the string.
        var i           = 0;    // A position in sUpperFirst, from 0 to sUpperFirst.length-1.
        
        sPrevChar       = " ";  // Prime the loop with a space.

        for ( i = 0;  i < sUpperFirst.length;  i++ )
        {
            sChar = sUpperFirst.charAt(i);

            if (Character.isLetter(sChar)  &&  (sPrevChar == ' '))
            {
                sBuffer.append(Character.toUpperCase(sChar));
            }
            else
            {
                sBuffer.append(sChar);
            }
            sPrevChar = sChar;
        }

        return (sBuffer.toString());
    }
} // end formatUpperCaseFirst

/**
 *  This function formats the provided string into a valid US zip code
 *
 *  @param  string   the String to be formatted
 *  @return string   the formatted String, null if isZip fails
 *  @see    isZip
 *  @see    strInvertStrip
 */

function formatZip(sZip)
{
    sZip = strInvertStrip(sZip, sCharsNumeric);

    if (!isZip(sZip))
    {
        return(null);
    }
    else
    {
        if (sZip.length == 5)
        {
            return(sZip);
        }
        else if (sZip.length == 9)
        {
            return(sZip.substring(0, 5) + '-' + sZip.substring(5, 9));
        }
        else
        {
            return("");
        }
    }
} // end formatZip

/**
 *  This function validates that the provided string only contains
 *  alphabetic characters
 *
 *  @param  sAlpha   the string to test
 *  @return boolean
 *  @see    strEmpty
 *  @see    strTest
 */

function isAlpha(sAlpha)
{
    if (strEmpty(sAlpha))
    {
        return(false);
    }
    else if (strTest(sAlpha, sCharsAlpha))
    {
        return(true);
    }
    else
    {
        return(false);
    }
} // end isAlpha




/**
 *  This function validates that the provided string only contains
 *  alphabetic and/or numeric characters
 *
 *  @param  sAlphaNumeric   the string to test
 *  @param  mustContainBoth boolean value to determine if String to be tested
 *          is required to contain both alpha AND numeric 
 *          (true passed in) or may contain alpha AND/OR 
 *          numeric (false passed in) [Note: an example of
 *          wanting to enforce both alpha AND numeric is if
 *          you want to force a password to contain both
 *          letters and numbers.]
 *  @return boolean 
 *  @see    strEmpty
 *  @see    strTest
 */

function isAlphaNumeric(sAlphaNumeric, mustContainBoth)
{
    var sTemp1 = "";
    var sTemp2 = "";

    if (strEmpty(sAlphaNumeric))
    {
        return(false);
    }
    else
    {
        // this is sort of a special case because of the way that strTest works
        if (strTest(sAlphaNumeric, sCharsAlphaNumeric))
        {
            // at this point we know all characters passed in are alpha 
            // and/or numeric.  If that's all the caller cared about, 
            // go ahead and return true
            if (!mustContainBoth)
            {
                return (true);
            }
            // otherwise if the caller wanted the string to have to contain
            // alpha and numeric both, check if it does or not
            else
            {
                sTemp1 = strInvertStrip(sAlphaNumeric, sCharsAlpha);
                sTemp2 = strInvertStrip(sAlphaNumeric, sCharsNumeric);

                if ((strEmpty(sTemp1) || !strTest(sTemp1, sCharsAlpha)) || (strEmpty(sTemp2) || !strTest(sTemp2, sCharsNumeric)))
                {
                    return(false);
                }
                else
                {
                    return(true);
                }
            }
        }
        else
        {
            return(false);
        }
    }
} // end isAlphaNumeric

/**
 *  This function validates that the provided string is a valid credit card number
 *
 *  @param  sCC   the string to test
 *  @return boolean
 *  @see    strEmpty
 *  @see    strInvertStrip
 */

function isCC(sCC)
{
    var iTogglePrimary      = 0;
    var iToggleSecondary    = 0;
    var iToggleCheck        = 0;
    var sHolder             = "";
    var iTemp               = 0;
    var sTemp               = "";

    sCC = strInvertStrip(sCC, sCharsNumeric);

    if (strEmpty(sCC))
    {
        return(false);
    }
    else
    {
        for (var i = (sCC.length - 1); i > -1; i = (i - 2))
        {
            iTogglePrimary += parseInt(sCC.substring(i, i + 1));
        }

        for (var j = (sCC.length - 2); j > -1; j = (j - 2))
        {
            iTemp = parseInt(sCC.substring(j, j + 1)) * 2;
            sHolder += iTemp;
        }

        for (var k = 0; k < sHolder.length; k++)
        {
            iTemp = parseInt(sHolder.substring(k, k + 1));
            iToggleSecondary += iTemp;
        }

        iToggleCheck = iTogglePrimary + iToggleSecondary;
        sTemp = "" + iToggleCheck;
        sTemp = sTemp.substring((sTemp.length - 1), sTemp.length);

        if (sTemp == "0")
        {
            return(true);
        }
        else
        {
            return(false);
        }
    }
} // end isCC



/**
 *  This function validates that the provided string is a valid US currency
 *  number containing only one decimal point.
 *
 *  @param  sCurrency   the string to test
 *  @return boolean
 *  @see    strEmpty
 *  @see    strInvertStrip, 
 */

function isCurrency(sCurrency)
{
    var sTemp       = "";
    var sConversion = "";

    /*  For Reference:
        aConversion['K'] = 1000;
        aConversion['M'] = 1000000;
        aConversion['B'] = 1000000000;
        aConversion['T'] = 1000000000000;
        aConversion['Q'] = 1000000000000000;
        aConversion['Z'] = 1000000000000000000;
    */   

    if (strEmpty(sCurrency))
    {
        return(false);
    }
    // strip everything but alpha characters, to check for K M B T Q or Z 
    sTemp = strInvertStrip(sCurrency, sCharsAlpha);

    if (sTemp.length > 0)
    {
        if (sTemp.length != 1)
        {
            return(false);
        }
        else
        {
            if (strEmpty(strInvertStrip(sTemp, "KMBTQZ")))
            {
                return(false);
            }
            else
            {
                sConversion = sTemp;
            }
        }
    }

    sCurrency = strInvertStrip(sCurrency, sCharsNumeric + '.');

    if (strEmpty(sCurrency))
    {
        return(false);
    }
    else if ((sCurrency.indexOf(".")) != (sCurrency.lastIndexOf(".")))
    {
        return(false);
    }
    else
    {
        return (true);
    }
} // end isCurrency

/**
 *  This function validates that the provided string is a valid date
 *
 *  @param  sDate   the string to test
 *  @return boolean
 *  @see    strEmpty
 *  @see    isInteger
 *  @see    isLeapYear
 */

function isDate(sDate)
{
    var aDate       = new Array();
    var sDay        = "";
    var sMonth      = "";
    var sYear       = "";
    var iDay        = 0;
    var iMonth      = 0;
    var iYear       = 0;
    var bFound      = false;
    var aSeparator  = new Array("-"," ","/",".");
    var aMonth      = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
    var i           = 0;

    if (strEmpty(sDate))
    {
        return(false);
    }
    else
    {
        for (i = 0; i < aSeparator.length; i++)
        {
            if (sDate.indexOf(aSeparator[i]) != -1)
            {
                aDate = sDate.split(aSeparator[i]);
                if (aDate.length != 3)
                {
                    // we need at least three items to make
                    // up a valid date
                    return(false);
                }
                else
                {
                    sMonth  = aDate[0];
                    sDay    = aDate[1];
                    sYear   = aDate[2];
                }
                bFound = true;
            }
        }
        if (bFound == false)
        {
            if (sDate.length > 5)
            {
                sMonth  = sDate.substring(0, 2);
                sDay    = sDate.substring(2, 4);
                sYear   = sDate.substring(4);
            }
        }
        if (sYear.length == 2)
        {
            sYear = "20" + sYear;
        }

        // The day needs to be a number.  Test if numeric first
        // because parseInt throws an exception.  If not numeric
        // we need to return false, not throw an exception.

        if (isInteger(sDay))
        {
            iDay = parseInt(sDay, 10);
        }
        else
        {
            return(false);
        }

        // The month may or may not be a number.  Test if numeric first
        // because parseInt throws an exception.  If not numeric
        // we need to do something else, not throw an exception.
        if (isInteger(sMonth))
        {
            iMonth = parseInt(sMonth, 10);
        }
        else // sMonth should be in the aMonth array
        {
            for (i = 0; i < 12; i++)
            {
                sMonth = sMonth.substring(0, 3);

                if (sMonth.toUpperCase() == aMonth[i].toUpperCase())
                {
                    iMonth = i + 1;
                    sMonth = aMonth[i];
                    i = 12;
                }
            }

            // If iMonth was never set to anything besides zero.
            // then sMonth never showed up in the aMonth array.
            // Thus the month passed in was invalid.
            if (iMonth==0)
            {
                return(false);
            }
        }

        // The year needs to be a number.  Test if numeric first
        // because parseInt throws an exception.  If not numeric
        // we need to return false, not throw an exception.
        if (isInteger(sYear))
        {
            iYear = parseInt(sYear, 10);
        }
        else 
        {
            return(false);
        }

        if (iDay < 1)
        {
            // the day has to be greater than 1
            return(false);
        }

        if (iMonth > 12 || iMonth < 1)
        {
            // the month needs to be between 1 and 12
            return(false);
        }

        if ((iMonth == 1 || iMonth == 3 || iMonth == 5 || iMonth == 7 || iMonth == 8 || iMonth == 10 || iMonth == 12) && (iDay > 31))
        {
            // the months jan, mar, may, jul, aug,
            // oct, dec cannot have dates above 31
            return(false);
        }

        if ((iMonth == 4 || iMonth == 6 || iMonth == 9 || iMonth == 11) && (iDay > 30))
        {
            // the months apr, jun, sep, nov cannot
            // have dates above 30
            return(false);
        }

        if (iMonth == 2)
        {
            if (isLeapYear(iYear))
            {
                if (iDay > 29)
                {
                    // a leap year only has 29 days
                    return(false);
                }
            }
            else
            {
                if (iDay > 28)
                {
                    // only leap years have more than 28 days
                    return(false);
                }
            }
        }

        return(true);
    }
} // end isDate

/**
 *  This function validates that the provided string only contains
 *  numerical characters and a single decimal point
 *
 *  @param  sDecimal   the string to test
 *  @return boolean
 *  @see    strEmpty
 *  @see    strTest
 */

function isDecimal(sDecimal)
{
    if (strEmpty(sDecimal))
    {
        return(false);
    }
    else if (strTest(sDecimal, sCharsNumeric + '.'))
    {
        // NOTE: Need to add code to account for the possibility
        // of there being more than one decimal point
        return(true);
    }
    else
    {
        return(false);
    }
}

/**
 *  This function validates that the provided string is a valid email address
 *
 *  @param  string   the string to test
 *  @return boolean  
 *  @see    strEmpty
 *  @see    strTest
 *  @see    strInvertStrip
 */

function isEmail(sEmail)
{
    var aEmail      = new Array();
    var aIP         = new Array();
    var sUsername   = "";
    var sDomain     = "";
    var sTemp       = "";
    var bUsername   = false;
    var bDomain     = false;
    var i           = 0;
    var iTemp       = 0;
    
    // first test for a parameter at all
    if (strEmpty(sEmail))
    {
        return(false);
    }
    
    // first test for the very basic things
    if (strInvertStrip(sEmail, "@") != "@")
    {
        // without an '@' sign this can't be a valid email address
        return(false);
    }
    else
    {
        // split the user @ domain
        aEmail      = sEmail.split("@");
        sUsername   = aEmail[0];
        sDomain     = aEmail[1];
        
        if (sUsername.length == 0 || sUsername == null || sDomain.length == 0 || sDomain == null) return false;
        // test the different username syntaxes
        if (strTest(sUsername, "\""))
        {
            // test this as a quoted username
            if ((sUsername.substring(0, 1) != "\"") || (sUsername.substring(sUsername.length - 1, sUsername.length) != "\""))
            {
                // we did find a quote in this username but we did
                // not find a double quote at the beginning and end
                return(false);
            }
            else
            {
                // this is all we needed to know about the username
                // since it is a quoted username
                bUsername = true;
            }
        }
        else
        {
            sTemp = strInvertStrip(sUsername, sCharsAlphaNumeric + "-_.");
            
            if (sTemp.length != sUsername.length)
            {
                // the username contained characters that we don't want to
                // allow in a normal email username
                return(false);
            }
            else
            {
                bUsername = true;
            }
        }
        
        // test the different domain syntaxes
        if (strInvertStrip(sDomain, "[]").length == 2)
        {
            // test this as an ip based domain
            if ((sDomain.substring(0, 1) != "[") || (sDomain.substring(sDomain.length - 1, sDomain.length) != "]"))
            {
                // we did find either an open or close square bracket
                // but we didn't find an open bracket at the beginning
                // or a closing bracket at the end
                return(false);
            }
            else
            {
                // let's make sure there are four numbers provided each
                // between 0 and 255
                sTemp = sDomain.substring(1, sDomain.length - 1);
                aIP = sTemp.split(".");
                if (aIP.length == 4)
                {
                    for (i = 0; i < aIP.length; i++)
                    {
                        iTemp = Integer.parseInt(aIP[1]);
                        if ((iTemp < 0) || (iTemp > 255))
                        {
                            return(false);
                        }
                    }
                    
                    // must have passed validation
                    bDomain = true;
                }
                else
                {
                    // this appears to be an invalid ip address
                    return(false);
                }
            }
        }
        else if (strInvertStrip(sDomain, sCharsAlphaNumeric + "-_.").length == sDomain.length)
        {
            // this domain has letters or numbers or other acceptable characters as
            // well as at least one period so let's move on
            bDomain = true;
        }
        
        if (bUsername && bDomain)
        {
            // both username and domain test passed
            return(true);
        }
        else
        {
            return(false);
        }
    }
} // end isEmail

/**
 *  This function validates that the provided string only contains
 *  numerical characters
 *
 *  @param  sInteger   the string to test
 *  @return boolean
 *  @see    strEmpty
 *  @see    strTest
 */

function isInteger(sInteger)
{
    if (strEmpty(sInteger))
    {
        return(false);
    }
    else if (strTest(sInteger, sCharsNumeric))
    {
        return(true);
    }
    else
    {
        return(false);
    }
} // end isInteger

/**
 *  This function validates that the provided integer is a valid leap year
 *
 *  @param  iYear   the integer to test
 *  @return boolean
 */

function isLeapYear(iYear)
{
    if (iYear % 100 == 0)
    {
        if (iYear % 400 == 0)
        {
            return(true);
        }
    }
    else
    {
        if ((iYear % 4) == 0)
        {
            return(true);
        }
    }

    return(false);
} // end isLeapYear

/**
 *  This function validates that the provided string is a valid US phone number
 *
 *  @param  sPhone   the string to test
 *  @return boolean
 *  @see    strEmpty
 *  @see    strInvertStrip
 */

function isPhone(sPhone)
{
    sPhone = strInvertStrip(sPhone, sCharsNumeric);

    if (strEmpty(sPhone))
    {
        return(false);
    }
    else
    {
        // area codes begin with 2-9.  If 1 was entered in front, strip off.
        if (sPhone.substring(0, 1) == "1")
        {
            sPhone = sPhone.substring(1, sPhone.length);
        }

        if (sPhone.length != 10)
        {
            return(false);
        }
        else
        {
            return(true);
        }
    }
} // end isPhone

/**
 *  This function validates that the provided string is a valid social security number
 *
 *  @param  sSSN   the string to test
 *  @return boolean
 *  @see    strEmpty
 *  @see    strInvertStrip
 */

function isSSN(sSSN)
{
    var iSSN1    = 0;
    var iSSN2    = 0;
    var iSSN3    = 0;

    sSSN = strInvertStrip(sSSN, sCharsNumeric);

    if (strEmpty(sSSN))
    {
        return(false);
    }
    else
    {
        if (sSSN.length != 9)
        {
            return(false);
        }
        else
        {
            iSSN1 = parseInt(sSSN.substring(0, 3));
            iSSN2 = parseInt(sSSN.substring(3, 5));
            iSSN3 = parseInt(sSSN.substring(5, 9));

            if ((iSSN1 == 0) || (iSSN1 > 740))
            {
                return(false);
            }
            else if (iSSN2 == 0)
            {
                return(false);
            }
            else if (iSSN3 == 0)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
    }
} // end isSSN

/**
 *  This function validates that the provided string is a valid US zip code
 *
 *  @param  sZip   the string to test
 *  @return boolean
 *  @see    strInvertStrip
 *  @see    strEmpty
 */

function isZip(sZip)
{
    sZip = strInvertStrip(sZip, sCharsNumeric);

    if (strEmpty(sZip))
    {
        return(false);
    }
    else
    {
        if ((sZip.length != 5) && (sZip.length != 9))
        {
            return(false);
        }
        else
        {
            return(true);
        }
    }
} // end isZip

/**
 *  This function validates whether a provided string
 *  is empty or not
 *
 *  @param  sString   the string to test 
 *  @return boolean
 */

function strEmpty(sString)
{
    if ((sString != null) && (sString != ""))
    {
        return(false);
    }
    else
    {
        return(true);
    }
} // end strEmpty

/**
 *  This function strips unwanted characters from a string
 *  This function does the exact opposite of strStrip by
 *  removing all characters except for the ones provided
 *
 *  @param  sString       the string to strip
 *  @param  sWantedChars  the string containing characters not to remove
 *  @return String        the stripped string
 *  @see    strEmpty
 */

function strInvertStrip(sString, sWantedChars)
{
    var sReturn = "";
    var sTemp   = "";

    if (strEmpty(sString) || strEmpty(sWantedChars))
    {
        return(null);
    }
    
    for (var i = 0; i < sString.length; i++)
    {
        sTemp = sString.substring(i, i+1);
        if (sWantedChars.indexOf(sTemp) >= 0)
        {
            sReturn += sTemp;
        }
    }

    return(sReturn);
} // end strInvertStrip

/**
 *  This function strips unwanted characters from a string
 *
 *  @param  sString         the string to strip
 *  @param  sUnwantedChars  the string containing characters to strip out
 *  @return String          the stripped String
 *  @see    strEmpty
 */

function strStrip(sString, sUnwantedChars)
{
    var sReturn = "";
    var sTemp   = "";

    if (strEmpty(sString) || strEmpty(sUnwantedChars))
    {
        return(null);
    }
    
    for (var i = 0; i < sString.length; i++)
    {
        sTemp = sString.substring(i, i+1);
        if (sUnwantedChars.indexOf(sTemp) < 0)
        {
            sReturn += sTemp;
        }
    }

    return(sReturn);
} // end strStrip

/**
 *  This function determines whether the provided string
 *  is a subset of the allowable characters or not
 *
 *  @param  sString          the string to test
 *  @param  sAllowableChars  the string containing characters allowed in the tested string
 *  @return boolean
 *  @see    strEmpty
 */

function strTest(sString, sAllowableChars)
{
    var sTemp = "";
    
    if (strEmpty(sString) || strEmpty(sAllowableChars))
    {
        return(false);
    }

    for (var i = 0; i < sString.length; i++)
    {
        sTemp = sString.substring(i, i + 1);

        if (sAllowableChars.indexOf(sTemp) < 0)
        {
            return(false);
        }
    }

    return(true);
}


