Language Basics JavaScript DHTML





    
        jsPro - Array
        
        
/**
 * +-------------------------------------------------------------------------+
 * | jsPro - Error                                                           |
 * +-------------------------------------------------------------------------+
 * | Copyright (C) 2001-2003 Stuart Wigley                                   |
 * +-------------------------------------------------------------------------+
 * | This library is free software; you can redistribute it and/or modify it |
 * | under the terms of the GNU Lesser General Public License as published by|
 * | the Free Software Foundation; either version 2.1 of the License, or (at |
 * | your option) any later version.                                         |
 * |                                                                         |
 * | This library is distributed in the hope that it will be useful, but     |
 * | WITHOUT ANY WARRANTY; without even the implied warranty of              |
 * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser |
 * | General Public License for more details.                                |
 * |                                                                         |
 * | You should have received a copy of the GNU Lesser General Public License|
 * | along with this library; if not, write to the Free Software Foundation, |
 * | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA             |
 * +-------------------------------------------------------------------------+
 * | Authors:   Stuart Wigley                      |
 * |            Randolph Fielding                   |
 * +-------------------------------------------------------------------------+
 * $Id: error.js,v 1.15 2003/09/22 04:41:10 gator4life Exp $
 */
/**
 * Property used in Error.handleError to specify how errors are
 * reported. Permissable values are:
 *
 * 0    No errors are reported.
 * 1    Report the error name and error message using the status bar of the
 *      active browser window.
 * 2    Report the error name and error message using an alert box.
 * 3    Report the error name, error message and debug message using an alert
 *      box.
 * 4    Report the error name, error message and debug message using a debug
 *      window. An instance of the Debug() class must be available.
 */
Error.prototype.debugLevel = 4;
/**
 * Uses Error.debugLevel to control how errors are reported. If
 * Error.debugLevel is set to 4, you must substitute the name of
 * your Debug() instance for oDebug in the line
 * var jsProDebugWindow = oDebug.
 *
 * @summary             handles thrown exceptions
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 09/03/03
 * @interface           Error.handleError()
 * @requires            Debug.print(vMixedValue, sMessageType)
 * @see                 Debug()
 * @see                 Debug.print()
 */
Error.prototype.handleError = function() {
    var sDebugMessage = this.debug;
    var sErrorMessage = (sDebugMessage) ? sDebugMessage : '';
    switch (this.debugLevel) {
        case 0 :
            break;
        case 1 :
            window.status = this.name + ': ' + this.message;
            break;
        case 2 :
            window.alert(this.name + '\n\n' + this.message);
            break;
        case 3 :
            window.alert(this.name + '\n\n' + this.message + '\n\n' + sErrorMessage);
            break;
        case 4 :
            var jsProDebugWindow = oDebug;
            if (jsProDebugWindow) {
                var oDebugWindow = jsProDebugWindow.debugWindow;
                if (oDebugWindow && !oDebugWindow.closed) {
                    jsProDebugWindow.print(this.name + ' ' + this.message + ' ' + sErrorMessage, 1);
                }
            }
    }
}
/**
 * Creates an object that is a subclass of Error for handling
 * ArrayIndexOutOfBounds exceptions.
 *
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 06/27/03
 * @interface           new ArrayIndexOutOfBoundsException(sMethodName,
 *                      iIndex, iArrayLength)

 * @param sMethodName   the name of the method where the exception was thrown
 * @param iIndex        the index of a hypothetical array member attempting to
 *                      be accessed
 * @param iArrayLength  the length of the array
 */
function ArrayIndexOutOfBoundsException(sMethodName, iIndex, iArrayLength) {
    this.name = 'ArrayIndexOutOfBoundsException';
    this.message = sMethodName + ' has been accessed with an illegal index that is either negative or greater than the size of the array.';
    this.debug = 'Attempting to access index ' + iIndex.toString() + ', but array has an index range of 0 to ' + (iArrayLength - 1).toString() + '.';
}
ArrayIndexOutOfBoundsException.prototype = new Error();
/**
 * Creates an object that is a subclass of Error for handling IllegalArgument
 * exceptions.
 *
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 07/24/03
 * @interface           new IllegalArgumentException(sMethodName,
 *                      vExpectedArgs, iActualArgs)

 * @param sMethodName   the name of the method where the exception was thrown
 * @param vExpectedArgs the number of arguments expected
 * @param iActualArgs   the number of arguments received
 */
function IllegalArgumentException(sMethodName, vExpectedArgs, iActualArgs) {
    this.name = 'IllegalArgumentException';
    this.message = sMethodName + ' has been passed an illegal number of arguments.';
    this.debug = 'Expected ' + vExpectedArgs.toString() + ' argument(s), but received ' + iActualArgs.toString() + ' argument(s).';
}
IllegalArgumentException.prototype = new Error();
/**
 * Creates an object that is a subclass of Error for handling IllegalValue
 * exceptions.
 *
 * @author              Randolph Fielding
 * @version             1.0, 09/22/03
 * @interface           new IllegalValueException(sMethodName,
 *                      sVariableName, vExpectedVal, vActualVal)

 * @param sMethodName   the name of the method where the exception was thrown
 * @param sVariableName the name of the variable containing the illegal value
 * @param vExpectedVal  the value expected in the variable containing the
 *                      illegal value
 * @param vActualVal    the value currently in the variable containing the
 *                      illegal value
 */
function IllegalValueException(sMethodName, sVariableName, vExpectedVal, vActualVal) {
    this.name = 'IllegalValueException';
    this.message = sMethodName + ' has encountered an illegal value in variable ' + sVariableName + '.'
    this.debug = 'Expected a value of ' + vExpectedVal.toString() + ', but contains a value of ' + vActualVal.toString() + '.'
}
IllegalValueException.prototype = new Error();
/**
 * Creates an object that is a subclass of Error for handling
 * MethodNotAvailable exceptions.
 *
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 06/27/03
 * @interface           new MethodNotAvailableException(sMethodName,
 *                      sMethodNameNA)

 * @param sMethodName   the name of the method where the exception was thrown
 * @param sMethodNameNA the name of the method that was not available
 */
function MethodNotAvailableException(sMethodName, sMethodNameNA) {
    this.name = 'MethodNotAvailableException';
    this.message = 'A method has been called that is not available.';
    this.debug = sMethodName + ' attempted to call ' + sMethodNameNA + '.';
}
MethodNotAvailableException.prototype = new Error();
/**
 * Creates an object that is a subclass of Error for handling
 * PropertyNotAvailable exceptions.
 *
 * @author              Randolph Fielding
 * @version             1.1, 08/01/03
 * @interface           new PropertyNotAvailableException(sMethodName,
 *                      sPropNameNA)

 * @param sMethodName   the name of the method where the exception was thrown
 * @param sPropNameNA   the name of the property that was not available
 */
function PropertyNotAvailableException(sMethodName, sPropNameNA) {
    this.name = 'PropertyNotAvailableException';
    this.message = 'A property has been accessed that is not available.';
    this.debug = sMethodName + ' attempted to access ' + sPropNameNA + '.';
}
PropertyNotAvailableException.prototype = new Error();
/**
 * Creates an object that is a subclass of Error for handling TypeMismatch
 * exceptions.
 *
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 07/24/03
 * @interface           new TypeMismatchException(sMethodName,
 *                      sExpectedType, sActualType)

 * @param sMethodName   the name of the method where the exception was thrown
 * @param sExpectedType the name of the expected type of an argument
 * @param sActualType   the name of the actual type of an argument
 */
function TypeMismatchException(sMethodName, sExpectedType, sActualType) {
    this.name = 'TypeMismatchException';
    this.message = sMethodName + ' has been passed an argument with an illegal or inappropriate type.';
    this.debug = 'Expected an argument with a type of ' + sExpectedType + ', but received an argument with a type of ' + sActualType + '.';
}
TypeMismatchException.prototype = new Error();
/**
 * Creates an object that is a subclass of Error for handling Unknown
 * exceptions.
 *
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 06/27/03
 * @interface           new UnknownException(sMethodName)
 * @param sMethodName   the name of the method where the exception was thrown
 */
function UnknownException(sMethodName) {
    this.name = 'UnknownException';
    this.message = 'An unknown error has occurred in ' + sMethodName + '.';
}
UnknownException.prototype = new Error();
        
        
        
/**
 * +-------------------------------------------------------------------------+
 * | jsPro - Debug                                                           |
 * +-------------------------------------------------------------------------+
 * | Copyright (C) 2001-2003 Stuart Wigley                                   |
 * +-------------------------------------------------------------------------+
 * | This library is free software; you can redistribute it and/or modify it |
 * | under the terms of the GNU Lesser General Public License as published by|
 * | the Free Software Foundation; either version 2.1 of the License, or (at |
 * | your option) any later version.                                         |
 * |                                                                         |
 * | This library is distributed in the hope that it will be useful, but     |
 * | WITHOUT ANY WARRANTY; without even the implied warranty of              |
 * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser |
 * | General Public License for more details.                                |
 * |                                                                         |
 * | You should have received a copy of the GNU Lesser General Public License|
 * | along with this library; if not, write to the Free Software Foundation, |
 * | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA             |
 * +-------------------------------------------------------------------------+
 * | Authors:   Stuart Wigley                      |
 * |            Randolph Fielding                   |
 * +-------------------------------------------------------------------------+
 * $Id: debug.js,v 1.6 2003/09/22 05:07:41 gator4life Exp $
 */
/**
 * Creates an object that opens a window for debugging.
 *
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 09/05/03
 * @interface           new Debug()
 */
function Debug() {
    this.debugWindow = window.open('../debug/debug.html', 'debug', 'width=400,height=600,resizable=yes,scrollbars=yes');
}
/**
 * Clears the contents of the debug window.
 *
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 09/05/03
 * @interface           Debug.clear()
 * @return              true if no exceptions are encountered
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              UnknownException
 */
Debug.prototype.clear = function() {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 0) {
            throw vError = new IllegalArgumentException('Debug.clear', 0, iNumArguments);
        }
        var oMessageContainer = document.getElementById('messageContainer');
        if (!oMessageContainer) {
            throw vError = new UnknownException('Debug.clear');
        }
        while (oMessageContainer.hasChildNodes()) {
            oMessageContainer.removeChild(oMessageContainer.firstChild);
        }
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : true;
    }
}
/**
 * Displays content within the debug window.
 *
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 09/05/03
 * @interface           Debug.print(vMixedValue)
 * @interface           Debug.print(vMixedValue, iMessageType)
 * @param vMixedValue   content to be displayed within the debug window
 * @param iMessageType  an integer representing the type of content to display
 *                      within the debug window (information: 0; error: 1)
 *                      (optional)
 * @return              true if no exceptions are encountered
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              IllegalValueException
 * @throws              TypeMismatchException
 * @throws              UnknownException
 */
Debug.prototype.print = function(vMixedValue) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        var iMessageType = 0;
        if ((iNumArguments < 1) || (iNumArguments > 2)) {
            throw vError = new IllegalArgumentException('Debug.print', '1 or 2', iNumArguments);
        } else if (iNumArguments == 2) {
            iMessageType = arguments[1];
        }
        if ((typeof iMessageType != 'number') || (iMessageType.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Debug.print', 'integer', typeof iMessageType);
        }
        if ((iMessageType != 0) && (iMessageType != 1)) {
            throw vError = new IllegalValueException('Debug.print', 'iMessageType', '0 or 1', iMessageType);
        }
        var oDebugWindow = this.debugWindow;
        if (!oDebugWindow || oDebugWindow.closed) {
            throw vError = new UnknownException('Debug.print');
        }
        var oDocument = oDebugWindow.document;
        if (!oDocument) {
            throw vError = new UnknownException('Debug.print');
        }
        var oMessageContainer = oDocument.getElementById('messageContainer');
        if (!oMessageContainer) {
            throw vError = new UnknownException('Debug.print');
        }
        var oTitleRow = oDocument.createElement('tr');
        var oTitleCell = oDocument.createElement('td');
        var oBodyRow = oDocument.createElement('tr');
        var oBodyCell = oDocument.createElement('td');
        if (!oTitleRow || !oTitleCell || !oBodyRow || !oBodyCell) {
            throw vError = new UnknownException('Debug.print');
        }
        var oTitleRowStyle = oTitleRow.style;
        if (oTitleRowStyle) {
            oTitleRowStyle.backgroundColor = '#EEE';
            oTitleRowStyle.fontWeight = 700;
        }
        var sOutputString = vMixedValue.toString();
        var sTitle = 'info';
        var sBody = sOutputString;
        if (iMessageType == 1) {
            sTitle = sOutputString.match(/\w+/);
            sBody = sOutputString.replace(/\w+/, '');
            var oBodyCellStyle = oBodyCell.style;
            if (oBodyCellStyle) {
                oBodyCell.style.backgroundColor = '#FCC';
            }
        }
        oMessageContainer.appendChild(oTitleRow);
        oTitleRow.appendChild(oTitleCell);
        oTitleCell.appendChild(oDocument.createTextNode(sTitle));
        oMessageContainer.appendChild(oBodyRow);
        oBodyRow.appendChild(oBodyCell);
        oBodyCell.appendChild(oDocument.createTextNode(sBody));
        oDebugWindow.focus();
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : true;
    }
}
        
        
        
/**
 * +-------------------------------------------------------------------------+
 * | jsPro - Test                                                            |
 * +-------------------------------------------------------------------------+
 * | Copyright (C) 2001-2003 Stuart Wigley                                   |
 * +-------------------------------------------------------------------------+
 * | This library is free software; you can redistribute it and/or modify it |
 * | under the terms of the GNU Lesser General Public License as published by|
 * | the Free Software Foundation; either version 2.1 of the License, or (at |
 * | your option) any later version.                                         |
 * |                                                                         |
 * | This library is distributed in the hope that it will be useful, but     |
 * | WITHOUT ANY WARRANTY; without even the implied warranty of              |
 * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser |
 * | General Public License for more details.                                |
 * |                                                                         |
 * | You should have received a copy of the GNU Lesser General Public License|
 * | along with this library; if not, write to the Free Software Foundation, |
 * | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA             |
 * +-------------------------------------------------------------------------+
 * | Authors:   Stuart Wigley                      |
 * |            Randolph Fielding                   |
 * +-------------------------------------------------------------------------+
 * $Id: test.js,v 1.6 2003/09/15 05:07:09 gator4life Exp $
 */
/**
 * Creates an object that provides methods for testing all jsPro libraries.
 *
 * @author              Stuart Wigley
 * @version             1.0, 07/24/03
 * @interface           new Test()
 */
function Test() { }
/**
 * Evaluates and returns the result of a jsPro method using assumptions about
 * the structure and ids of HTML elements in the jsPro HTML test files.
 *
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 08/20/03
 * @interface           Test.evaluateMethod(oButton, sClass)
 * @param oButton       the HTML input-button element that is clicked
 * @param sClass        the name of the jsPro class instance being tested
 * @return              the result of attempting to evaluate a jsPro method
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Test.prototype.evaluateMethod = function(oButton, sClass) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 2) {
            throw vError = new IllegalArgumentException('Error.evaluateMethod', 2, iNumArguments);
        }
        if (typeof oButton != 'object') {
            throw vError = new TypeMismatchException('Error.evaluateMethod', 'object', typeof oButton);
        }
        if (typeof sClass != 'string') {
            throw vError = new TypeMismatchException('Error.evaluateMethod', 'string', typeof sClass);
        }
        var sMethodName = oButton.id;
        var oInput1 = document.getElementById(sMethodName + '1');
        var oInput2 = document.getElementById(sMethodName + '2');
        var oInput3 = document.getElementById(sMethodName + '3');
        var oOutput = document.getElementById(sMethodName + 'Result');
        var sArguments = '';
        if (oInput1) {
            var sInput1Value = oInput1.value;
            if (sInput1Value != '') {
                var fInput1Value = parseFloat(sInput1Value);
                sArguments += (isNaN(fInput1Value)) ? '\'' + sInput1Value + '\'' : fInput1Value;
            }
        }
        if (oInput2) {
            var sInput2Value = oInput2.value;
            if (sInput2Value != '') {
                var fInput2Value = parseFloat(sInput2Value);
                sArguments += (isNaN(fInput2Value)) ? ', \'' + sInput2Value + '\'' : ', ' + fInput2Value;
            }
        }
        if (oInput3) {
            var sInput3Value = oInput3.value;
            if (sInput3Value != '') {
                var fInput3Value = parseFloat(sInput3Value);
                sArguments += (isNaN(fInput3Value)) ? ', \'' + sInput3Value + '\'' : ', ' + fInput3Value;
            }
        }
        var vResult = eval(sClass + '.' + sMethodName + '(' + sArguments + ')');
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        if (oOutput) {
            oOutput.value = vResult;
        }
    }
}
        
        
        
/**
 * +-------------------------------------------------------------------------+
 * | jsPro - Array                                                           |
 * +-------------------------------------------------------------------------+
 * | Copyright (C) 2001-2003 Stuart Wigley                                   |
 * +-------------------------------------------------------------------------+
 * | This library is free software; you can redistribute it and/or modify it |
 * | under the terms of the GNU Lesser General Public License as published by|
 * | the Free Software Foundation; either version 2.1 of the License, or (at |
 * | your option) any later version.                                         |
 * |                                                                         |
 * | This library is distributed in the hope that it will be useful, but     |
 * | WITHOUT ANY WARRANTY; without even the implied warranty of              |
 * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser |
 * | General Public License for more details.                                |
 * |                                                                         |
 * | You should have received a copy of the GNU Lesser General Public License|
 * | along with this library; if not, write to the Free Software Foundation, |
 * | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA             |
 * +-------------------------------------------------------------------------+
 * | Authors:   Stuart Wigley                      |
 * |            Randolph Fielding                   |
 * +-------------------------------------------------------------------------+
 * $Id: array.js,v 1.28 2003/09/22 06:02:21 gator4life Exp $
 */
/**
 * Calculates and returns the average deviation of all array members or of a
 * subset of array members (if the optional start and length arguments are
 * specified).
 *
 * @summary             average deviation
 * @author              Stuart Wigley
 * @version             1.0, 09/19/03
 * @interface           Array.averageDev()
 * @interface           Array.averageDev(iStart)
 * @interface           Array.averageDev(iStart, iLength)
 * @requires            Array.mean(iStart, iLength)
 * @param iStart        the index of the array member to start at (optional)
 * @param iLength       the number of array members to evaluate beginning at
 *                      iStart (optional)
 * @return              the average deviation of all array members or of a
 *                      subset of array members
 * @return              null if an exception is encountered
 * @throws              ArrayIndexOutOfBoundsException
 * @throws              IllegalArgumentException
 * @throws              MethodNotAvailableException
 * @throws              TypeMismatchException
 * @throws              UnknownException
 * @see                 Array.mean()
 */
Array.prototype.averageDev = function() {
    try {
        var vError = null;
        var iArrayLength = this.length;
        var iNumArguments = arguments.length;
        var iStart = 0;
        var iLength = iArrayLength;
        if (!('mean' in this)) {
            throw vError = new MethodNotAvailableException('Array.averageDev', 'Array.mean');
        }
        if (iNumArguments > 2) {
            throw vError = new IllegalArgumentException('Array.averageDev', '0, 1 or 2', iNumArguments);
        } else if (iNumArguments == 2) {
            iStart = arguments[0];
            iLength = arguments[1];
        } else if (iNumArguments == 1) {
            iStart = arguments[0];
            iLength -= iStart;
        }
        if ((typeof iStart != 'number') || (iStart.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.averageDev', 'integer', typeof iStart);
        }
        if ((typeof iLength != 'number') || (iLength.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.averageDev', 'integer', typeof iLength);
        }
        var iEnd = iStart + iLength;
        if (iStart < 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.averageDev', iStart, iArrayLength);
        }
        if (iLength <= 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.averageDev', iLength, iArrayLength);
        }
        if (iEnd > iArrayLength) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.averageDev', iEnd, iArrayLength);
        }
        var fMean = this.mean(iStart, iEnd);
        if (!fMean) {
            throw vError = new UnknownException('Array.averageDev');
        }
        var aAbsoluteDevs = new Array();
        var iCount = 0;
        for (var i = iStart; i < iEnd; i++) {
            if (typeof this[i] == 'number') {
                aAbsoluteDevs[iCount] = Math.abs(this[i] - fMean);
                iCount++;
            }
        }
        var fAverageDev = aAbsoluteDevs.mean();
        if (!fAverageDev) {
            throw vError = new UnknownException('Array.averageDev');
        }
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fAverageDev;
    }
}
/**
 * Changes the case of all array keys to lowercase or uppercase.
 *
 * @summary             change key case
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 09/14/03
 * @interface           Array.changeKeyCase(iCase)
 * @param iCase         an integer representing the case to change array keys
 *                      to (lowercase: 0; uppercase: 1)
 * @return              an array with keys changed to lowercase or uppercase
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 * @throws              IllegalValueException
 * @throws              TypeMismatchException
 */
Array.prototype.changeKeyCase = function(iCase) {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Array.changeKeyCase', 1, iNumArguments);
        }
        if ((typeof iCase != 'number') || (iCase.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.changeKeyCase', 'integer', typeof iCase);
        }
        if ((iCase != 0) && (iCase != 1)) {
            throw vError = new IllegalValueException('Array.changeKeyCase', 'iCase', '0 or 1', iCase);
        }
        for (var sKey in this) {
            if (this.hasOwnProperty(sKey)) {
                var sKeyCase = (iCase == 1) ? sKey.toUpperCase() : sKey.toLowerCase();
                if (sKeyCase != sKey) {
                    this[sKeyCase] = this[sKey];
                    delete this[sKey];
                }
            }
        }
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : this;
    }
}
/**
 * Returns an array of 'chunks' where each 'chunk' is an array of
 * iChunkSize formed from this array.
 *
 * @summary             split into chunks
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 06/27/03
 * @interface           Array.chunk(iChunkSize)
 * @param iChunkSize    the size of a 'chunk' formed from this array
 * @return              an array of 'chunks' formed from this array
 * @return              null if an exception is encountered
 * @throws              ArrayIndexOutOfBoundsException
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Array.prototype.chunk = function(iChunkSize) {
    try {
        var vError = null;
        var iArrayLength = this.length;
        var iNumArguments = arguments.length;
        if (iNumArguments != 1) {
            throw vError = new IllegalArgumentException('Array.chunk', 1, iNumArguments);
        }
        if ((typeof iChunkSize != 'number') || (iChunkSize.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.chunk', 'integer', typeof iChunkSize);
        }
        if ((iChunkSize <= 0) || (iChunkSize > iArrayLength)) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.chunk', iChunkSize, iArrayLength);
        }
        var iChunkedArrayLength = Math.ceil(iArrayLength / iChunkSize);
        var aChunkedArray = new Array(iChunkedArrayLength);
        var iSourceArrayIndex = 0;
        for (var i = 0; i < iChunkedArrayLength; i++) {
            aChunkedArray[i] = new Array(iChunkSize);
            for (var j = 0; j < iChunkSize; j++) {
                aChunkedArray[i][j] = this[iSourceArrayIndex++];
            }
        }
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : aChunkedArray;
    }
}
/**
 * Returns an associative array keyed on the values of this array. Each member
 * of the associative array contains an integer value representing the number
 * of occurrences of that member's key in this array.
 *
 * @summary             count occurrence of values
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 06/29/03
 * @interface           Array.count()
 * @return              an associative array of counted values
 * @return              null if an exception is encountered
 * @throws              IllegalArgumentException
 */
Array.prototype.count = function() {
    try {
        var vError = null;
        var iNumArguments = arguments.length;
        if (iNumArguments > 0) {
            throw vError = new IllegalArgumentException('Array.count', 0, iNumArguments);
        }
        var iArrayLength = this.length;
        var aCountedArray = new Array();
        for (var i = 0; i < iArrayLength; i++) {
            var sValue = this[i].toString();
            aCountedArray[sValue] = (aCountedArray[sValue] == undefined) ? 1 : ++aCountedArray[sValue];
        }
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : aCountedArray;
    }
}
/**
 * Calculates and returns the coefficient of variation of all array members or
 * of a subset of array members (if the optional start and length arguments are
 * specified).
 *
 * @summary             coefficient of variation
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.4, 08/08/03
 * @interface           Array.covar()
 * @interface           Array.covar(iStart)
 * @interface           Array.covar(iStart, iLength)
 * @requires            Array.mean(iStart, iLength)
 * @requires            Array.standardDev(iStart, iLength)
 * @param iStart        the index of the array member to start at (optional)
 * @param iLength       the number of array members to evaluate beginning at
 *                      iStart (optional)
 * @return              the coefficient of variation of all array members or of
 *                      a subset of array members
 * @return              null if an exception is encountered
 * @throws              ArrayIndexOutOfBoundsException
 * @throws              IllegalArgumentException
 * @throws              MethodNotAvailableException
 * @throws              TypeMismatchException
 * @throws              UnknownException
 * @see                 Array.mean()
 * @see                 Array.standardDev()
 */
Array.prototype.covar = function() {
    try {
        var vError = null;
        var iArrayLength = this.length;
        var iNumArguments = arguments.length;
        var iStart = 0;
        var iLength = iArrayLength;
        if (!('mean' in this)) {
            throw vError = new MethodNotAvailableException('Array.covar', 'Array.mean');
        }
        if (!('standardDev' in this)) {
            throw vError = new MethodNotAvailableException('Array.covar', 'Array.standardDev');
        }
        if (iNumArguments > 2) {
            throw vError = new IllegalArgumentException('Array.covar', '0, 1 or 2', iNumArguments);
        } else if (iNumArguments == 2) {
            iStart = arguments[0];
            iLength = arguments[1];
        } else if (iNumArguments == 1) {
            iStart = arguments[0];
            iLength -= iStart;
        }
        if ((typeof iStart != 'number') || (iStart.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.covar', 'integer', typeof iStart);
        }
        if ((typeof iLength != 'number') || (iLength.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.covar', 'integer', typeof iLength);
        }
        var iEnd = iStart + iLength;
        if (iStart < 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.covar', iStart, iArrayLength);
        }
        if (iLength <= 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.covar', iLength, iArrayLength);
        }
        if (iEnd > iArrayLength) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.covar', iEnd, iArrayLength);
        }
        var fMean = this.mean(iStart, iLength);
        var fStandardDev = this.standardDev(iStart, iLength);
        if (!fMean || !fStandardDev) {
            throw vError = new UnknownException('Array.covar');
        }
        var fCovar = fStandardDev / fMean;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fCovar;
    }
}
/**
 * Fills this array or a subset of array members (if the optional start and
 * length arguments are specified) with a value of any data type.
 *
 * @summary             fill
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 06/28/03
 * @interface           Array.fill(vFill)
 * @interface           Array.fill(vFill, iStart)
 * @interface           Array.fill(vFill, iStart, iLength)
 * @param vFill         a value of any data type to fill this array or a
 *                      subset of array members with
 * @param iStart        the index of the array member to start at (optional)
 * @param iLength       the number of array members to fill beginning at
 *                      iStart (optional)
 * @return              a modified array
 * @return              null if an exception is encountered
 * @throws              ArrayIndexOutOfBoundsException
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Array.prototype.fill = function(vFill) {
    try {
        var vError = null;
        var iArrayLength = this.length;
        var iNumArguments = arguments.length;
        var iStart = 0;
        var iLength = iArrayLength;
        if ((iNumArguments < 1) || (iNumArguments > 3)) {
            throw vError = new IllegalArgumentException('Array.fill', '1, 2 or 3', iNumArguments);
        } else if (iNumArguments == 3) {
            iStart = arguments[1];
            iLength = arguments[2];
        } else if (iNumArguments == 2) {
            iStart = arguments[1];
            iLength -= iStart;
        }
        if ((typeof iStart != 'number') || (iStart.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.fill', 'integer', typeof iStart);
        }
        if ((typeof iLength != 'number') || (iLength.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.fill', 'integer', typeof iLength);
        }
        var iEnd = iStart + iLength;
        if (iStart < 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.fill', iStart, iArrayLength);
        }
        if (iLength <= 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.fill', iLength, iArrayLength);
        }
        if (iEnd > iArrayLength) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.fill', iEnd, iArrayLength);
        }
        for (var i = iStart; i < iEnd; i++) {
            this[i] = vFill;
        }
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : this;
    }
}
/**
 * Returns the maximum numerical value contained in this array or in a subset
 * of array members (if the optional start and length arguments are specified).
 *
 * @summary             maximum value
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 06/27/03
 * @interface           Array.max()
 * @interface           Array.max(iStart)
 * @interface           Array.max(iStart, iLength)
 * @param iStart        the index of the array member to start at (optional)
 * @param iLength       the number of array members to evaluate beginning at
 *                      iStart (optional)
 * @return              the maximum numerical value contained in this array or
 *                      in a subset of array members
 * @return              null if no array members are numbers
 * @return              null if an exception is encountered
 * @throws              ArrayIndexOutOfBoundsException
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Array.prototype.max = function() {
    try {
        var vError = null;
        var iArrayLength = this.length;
        var iNumArguments = arguments.length;
        var iStart = 0;
        var iLength = iArrayLength;
        if (iNumArguments > 2) {
            throw vError = new IllegalArgumentException('Array.max', '0, 1 or 2', iNumArguments);
        } else if (iNumArguments == 2) {
            iStart = arguments[0];
            iLength = arguments[1];
        } else if (iNumArguments == 1) {
            iStart = arguments[0];
            iLength -= iStart;
        }
        if ((typeof iStart != 'number') || (iStart.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.max', 'integer', typeof iStart);
        }
        if ((typeof iLength != 'number') || (iLength.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.max', 'integer', typeof iLength);
        }
        var iEnd = iStart + iLength;
        if (iStart < 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.max', iStart, iArrayLength);
        }
        if (iLength <= 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.max', iLength, iArrayLength);
        }
        if (iEnd > iArrayLength) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.max', iEnd, iArrayLength);
        }
        var fMax = null;
        for (var i = iStart; i < iEnd; i++) {
            if ((typeof this[i] == 'number') && ((fMax == null) || (this[i] > fMax))) {
                fMax = this[i];
            }
        }
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fMax;
    }
}
/**
 * Calculates and returns the mean of all array members or of a subset of array
 * members (if the optional start and length arguments are specified).
 *
 * @summary             mean
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.5, 08/08/03
 * @interface           Array.mean()
 * @interface           Array.mean(iStart)
 * @interface           Array.mean(iStart, iLength)
 * @param iStart        the index of the array member to start at (optional)
 * @param iLength       the number of array members to evaluate beginning at
 *                      iStart (optional)
 * @return              the mean of all array members or of a subset of array
 *                      members
 * @return              null if no array members are numbers
 * @return              null if an exception is encountered
 * @throws              ArrayIndexOutOfBoundsException
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Array.prototype.mean = function() {
    try {
        var vError = null;
        var iArrayLength = this.length;
        var iNumArguments = arguments.length;
        var iStart = 0;
        var iLength = iArrayLength;
        if (iNumArguments > 2) {
            throw vError = new IllegalArgumentException('Array.mean', '0, 1 or 2', iNumArguments);
        } else if (iNumArguments == 2) {
            iStart = arguments[0];
            iLength = arguments[1];
        } else if (iNumArguments == 1) {
            iStart = arguments[0];
            iLength -= iStart;
        }
        if ((typeof iStart != 'number') || (iStart.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.mean', 'integer', typeof iStart);
        }
        if ((typeof iLength != 'number') || (iLength.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.mean', 'integer', typeof iLength);
        }
        var iEnd = iStart + iLength;
        if (iStart < 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.mean', iStart, iArrayLength);
        }
        if (iLength <= 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.mean', iLength, iArrayLength);
        }
        if (iEnd > iArrayLength) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.mean', iEnd, iArrayLength);
        }
        var fSum = 0;
        var iCount = 0;
        for (var i = iStart; i < iEnd; i++) {
            if (typeof this[i] == 'number') {
                fSum += this[i];
                iCount++;
            }
        }
        var fMean = (iCount == 0) ? null : fSum / iCount;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fMean;
    }
}
/**
 * Calculates and returns the median of all array members or of a subset of
 * array members (if the optional start and length arguments are specified).
 *
 * @summary             median
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Array.median()
 * @interface           Array.median(iStart)
 * @interface           Array.median(iStart, iLength)
 * @param iStart        the index of the array member to start at (optional)
 * @param iLength       the number of array members to evaluate beginning at
 *                      iStart (optional)
 * @return              the median of all array members or of a subset of array
 *                      members
 * @return              null if no array members are numbers
 * @return              null if an exception is encountered
 * @throws              ArrayIndexOutOfBoundsException
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Array.prototype.median = function() {
    try {
        var vError = null;
        var iArrayLength = this.length;
        var iNumArguments = arguments.length;
        var iStart = 0;
        var iLength = iArrayLength;
        if (iNumArguments > 2) {
            throw vError = new IllegalArgumentException('Array.median', '0, 1 or 2', iNumArguments);
        } else if (iNumArguments == 2) {
            iStart = arguments[0];
            iLength = arguments[1];
        } else if (iNumArguments == 1) {
            iStart = arguments[0];
            iLength -= iStart;
        }
        if ((typeof iStart != 'number') || (iStart.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.median', 'integer', typeof iStart);
        }
        if ((typeof iLength != 'number') || (iLength.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.median', 'integer', typeof iLength);
        }
        var iEnd = iStart + iLength;
        if (iStart < 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.median', iStart, iArrayLength);
        }
        if (iLength <= 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.median', iLength, iArrayLength);
        }
        if (iEnd > iArrayLength) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.median', iEnd, iArrayLength);
        }
        var aTempArray = new Array();
        var iTempArrayIndex = 0;
        for (var i = iStart; i < iEnd; i++) {
            if (typeof this[i] == 'number') {
                aTempArray[iTempArrayIndex++] = this[i];
            }
        }
        var iTempArrayLength = aTempArray.length;
        var iModTempArrayLength = iTempArrayLength - 1;
        for (var j = 0; j < iModTempArrayLength; j++) {
            for (var k = j + 1; k < iTempArrayLength; k++) {
                if (aTempArray[k] < aTempArray[j]) {
                    var fValue = aTempArray[j];
                    aTempArray[j] = aTempArray[k];
                    aTempArray[k] = fValue;
                }
            }
        }
        var fMedian = (iTempArrayLength == 0) ? null : (iTempArrayLength % 2 == 1) ? aTempArray[Math.floor(iTempArrayLength / 2)] : (aTempArray[iTempArrayLength / 2] + aTempArray[(iTempArrayLength / 2) - 1]) / 2;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fMedian;
    }
}
/**
 * Returns the minimum numerical value contained in this array or in a subset
 * of array members (if the optional start and length arguments are specified).
 *
 * @summary             minimum value
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 06/27/03
 * @interface           Array.min()
 * @interface           Array.min(iStart)
 * @interface           Array.min(iStart, iLength)
 * @param iStart        the index of the array member to start at (optional)
 * @param iLength       the number of array members to evaluate beginning at
 *                      iStart (optional)
 * @return              the minimum numerical value contained in this array or
 *                      in a subset of array members
 * @return              null if no array members are numbers
 * @return              null if an exception is encountered
 * @throws              ArrayIndexOutOfBoundsException
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Array.prototype.min = function() {
    try {
        var vError = null;
        var iArrayLength = this.length;
        var iNumArguments = arguments.length;
        var iStart = 0;
        var iLength = iArrayLength;
        if (iNumArguments > 2) {
            throw vError = new IllegalArgumentException('Array.min', '0, 1 or 2', iNumArguments);
        } else if (iNumArguments == 2) {
            iStart = arguments[0];
            iLength = arguments[1];
        } else if (iNumArguments == 1) {
            iStart = arguments[0];
            iLength -= iStart;
        }
        if ((typeof iStart != 'number') || (iStart.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.min', 'integer', typeof iStart);
        }
        if ((typeof iLength != 'number') || (iLength.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.min', 'integer', typeof iLength);
        }
        var iEnd = iStart + iLength;
        if (iStart < 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.min', iStart, iArrayLength);
        }
        if (iLength <= 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.min', iLength, iArrayLength);
        }
        if (iEnd > iArrayLength) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.min', iEnd, iArrayLength);
        }
        var fMin = null;
        for (var i = iStart; i < iEnd; i++) {
            if ((typeof this[i] == 'number') && ((fMin == null) || (this[i] < fMin))) {
                fMin = this[i];
            }
        }
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fMin;
    }
}
/**
 * Calculates and returns the product of all array members or of a subset of
 * array members (if the optional start and length arguments are specified).
 *
 * @summary             product
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Array.product()
 * @interface           Array.product(iStart)
 * @interface           Array.product(iStart, iLength)
 * @param iStart        the index of the array member to start at (optional)
 * @param iLength       the number of array members to evaluate beginning at
 *                      iStart (optional)
 * @return              the product of all array members or of a subset of
 *                      array members
 * @return              null if no array members are numbers
 * @return              null if an exception is encountered
 * @throws              ArrayIndexOutOfBoundsException
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Array.prototype.product = function() {
    try {
        var vError = null;
        var iArrayLength = this.length;
        var iNumArguments = arguments.length;
        var iStart = 0;
        var iLength = iArrayLength;
        if (iNumArguments > 2) {
            throw vError = new IllegalArgumentException('Array.product', '0, 1 or 2', iNumArguments);
        } else if (iNumArguments == 2) {
            iStart = arguments[0];
            iLength = arguments[1];
        } else if (iNumArguments == 1) {
            iStart = arguments[0];
            iLength -= iStart;
        }
        if ((typeof iStart != 'number') || (iStart.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.product', 'integer', typeof iStart);
        }
        if ((typeof iLength != 'number') || (iLength.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.product', 'integer', typeof iLength);
        }
        var iEnd = iStart + iLength;
        if (iStart < 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.product', iStart, iArrayLength);
        }
        if (iLength <= 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.product', iLength, iArrayLength);
        }
        if (iEnd > iArrayLength) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.product', iEnd, iArrayLength);
        }
        var fProduct = 1;
        var iCount = 0;
        for (var i = iStart; i < iEnd; i++) {
            if (typeof this[i] == 'number') {
                fProduct *= this[i];
                iCount++;
            }
        }
        fProduct = (iCount == 0) ? null : fProduct;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fProduct;
    }
}
/**
 * Calculates and returns the range of all array members or of a subset of
 * array members (if the optional start and length arguments are specified).
 *
 * @summary             range
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Array.range()
 * @interface           Array.range(iStart)
 * @interface           Array.range(iStart, iLength)
 * @requires            Array.max(iStart, iLength)
 * @requires            Array.min(iStart, iLength)
 * @param iStart        the index of the array member to start at (optional)
 * @param iLength       the number of array members to evaluate beginning at
 *                      iStart (optional)
 * @return              the range of all array members or of a subset of array
 *                      members
 * @return              null if an exception is encountered
 * @throws              ArrayIndexOutOfBoundsException
 * @throws              IllegalArgumentException
 * @throws              MethodNotAvailableException
 * @throws              TypeMismatchException
 * @throws              UnknownException
 * @see                 Array.max()
 * @see                 Array.min()
 */
Array.prototype.range = function() {
    try {
        var vError = null;
        var iArrayLength = this.length;
        var iNumArguments = arguments.length;
        var iStart = 0;
        var iLength = iArrayLength;
        if (!('max' in this)) {
            throw vError = new MethodNotAvailableException('Array.range', 'Array.max');
        }
        if (!('min' in this)) {
            throw vError = new MethodNotAvailableException('Array.range', 'Array.min');
        }
        if (iNumArguments > 2) {
            throw vError = new IllegalArgumentException('Array.range', '0, 1 or 2', iNumArguments);
        } else if (iNumArguments == 2) {
            iStart = arguments[0];
            iLength = arguments[1];
        } else if (iNumArguments == 1) {
            iStart = arguments[0];
            iLength -= iStart;
        }
        if ((typeof iStart != 'number') || (iStart.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.range', 'integer', typeof iStart);
        }
        if ((typeof iLength != 'number') || (iLength.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.range', 'integer', typeof iLength);
        }
        var iEnd = iStart + iLength;
        if (iStart < 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.range', iStart, iArrayLength);
        }
        if (iLength <= 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.range', iLength, iArrayLength);
        }
        if (iEnd > iArrayLength) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.range', iEnd, iArrayLength);
        }
        var fMax = this.max(iStart, iLength);
        var fMin = this.min(iStart, iLength);
        if (!fMax || !fMin) {
            throw vError = new UnknownException('Array.range');
        }
        var fRange = fMax - fMin;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fRange;
    }
}
/**
 * Calculates and returns the standard deviation of all array members or of a
 * subset of array members (if the optional start and length arguments are
 * specified).
 *
 * @summary             standard deviation
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.4, 08/08/03
 * @interface           Array.standardDev()
 * @interface           Array.standardDev(iStart)
 * @interface           Array.standardDev(iStart, iLength)
 * @requires            Array.variance(iStart, iLength)
 * @param iStart        the index of the array member to start at (optional)
 * @param iLength       the number of array members to evaluate beginning at
 *                      iStart (optional)
 * @return              the standard deviation of all array members or of a
 *                      subset of array members
 * @return              null if an exception is encountered
 * @throws              ArrayIndexOutOfBoundsException
 * @throws              IllegalArgumentException
 * @throws              MethodNotAvailableException
 * @throws              TypeMismatchException
 * @throws              UnknownException
 * @see                 Array.variance()
 */
Array.prototype.standardDev = function() {
    try {
        var vError = null;
        var iArrayLength = this.length;
        var iNumArguments = arguments.length;
        var iStart = 0;
        var iLength = iArrayLength;
        if (!('variance' in this)) {
            throw vError = new MethodNotAvailableException('Array.standardDev', 'Array.variance');
        }
        if (iNumArguments > 2) {
            throw vError = new IllegalArgumentException('Array.standardDev', '0, 1 or 2', iNumArguments);
        } else if (iNumArguments == 2) {
            iStart = arguments[0];
            iLength = arguments[1];
        } else if (iNumArguments == 1) {
            iStart = arguments[0];
            iLength -= iStart;
        }
        if ((typeof iStart != 'number') || (iStart.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.standardDev', 'integer', typeof iStart);
        }
        if ((typeof iLength != 'number') || (iLength.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.standardDev', 'integer', typeof iLength);
        }
        var iEnd = iStart + iLength;
        if (iStart < 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.standardDev', iStart, iArrayLength);
        }
        if (iLength <= 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.standardDev', iLength, iArrayLength);
        }
        if (iEnd > iArrayLength) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.standardDev', iEnd, iArrayLength);
        }
        var fVariance = this.variance(iStart, iLength);
        if (!fVariance) {
            throw vError = new UnknownException('Array.standardDev');
        }
        var fStandardDev = Math.sqrt(fVariance);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fStandardDev;
    }
}
/**
 * Calculates and returns the sum of all array members or of a subset of array
 * members (if the optional start and length arguments are specified).
 *
 * @summary             sum
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.2, 08/08/03
 * @interface           Array.sum()
 * @interface           Array.sum(iStart)
 * @interface           Array.sum(iStart, iLength)
 * @param iStart        the index of the array member to start at (optional)
 * @param iLength       the number of array members to evaluate beginning at
 *                      iStart (optional)
 * @return              the sum of all array members or of a subset of array
 *                      members
 * @return              null if no array members are numbers
 * @return              null if an exception is encountered
 * @throws              ArrayIndexOutOfBoundsException
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Array.prototype.sum = function() {
    try {
        var vError = null;
        var iArrayLength = this.length;
        var iNumArguments = arguments.length;
        var iStart = 0;
        var iLength = iArrayLength;
        if (iNumArguments > 2) {
            throw vError = new IllegalArgumentException('Array.sum', '0, 1 or 2', iNumArguments);
        } else if (iNumArguments == 2) {
            iStart = arguments[0];
            iLength = arguments[1];
        } else if (iNumArguments == 1) {
            iStart = arguments[0];
            iLength -= iStart;
        }
        if ((typeof iStart != 'number') || (iStart.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.sum', 'integer', typeof iStart);
        }
        if ((typeof iLength != 'number') || (iLength.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.sum', 'integer', typeof iLength);
        }
        var iEnd = iStart + iLength;
        if (iStart < 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.sum', iStart, iArrayLength);
        }
        if (iLength <= 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.sum', iLength, iArrayLength);
        }
        if (iEnd > iArrayLength) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.sum', iEnd, iArrayLength);
        }
        var fSum = 0;
        var iCount = 0;
        for (var i = iStart; i < iEnd; i++) {
            if (typeof this[i] == 'number') {
                fSum += this[i];
                iCount++;
            }
        }
        fSum = (iCount == 0) ? null : fSum;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fSum;
    }
}
/**
 * Swaps the values of two array members at the specified indices.
 *
 * @summary             swap two members
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.1, 06/27/03
 * @interface           Array.swap(iIndex1, iIndex2)
 * @param iIndex1       the index of an array member
 * @param iIndex2       the index of an array member
 * @return              a modified array
 * @return              null if an exception is encountered
 * @throws              ArrayIndexOutOfBoundsException
 * @throws              IllegalArgumentException
 * @throws              TypeMismatchException
 */
Array.prototype.swap = function(iIndex1, iIndex2) {
    try {
        var vError = null;
        var iArrayLength = this.length;
        var iNumArguments = arguments.length;
        if (iNumArguments != 2) {
            throw vError = new IllegalArgumentException('Array.swap', 2, iNumArguments);
        }
        if ((typeof iIndex1 != 'number') || (iIndex1.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.swap', 'integer', typeof iIndex1);
        }
        if ((typeof iIndex2 != 'number') || (iIndex2.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.swap', 'integer', typeof iIndex2);
        }
        if ((iIndex1 < 0) || (iIndex1 >= iArrayLength)) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.swap', iIndex1, iArrayLength);
        }
        if ((iIndex2 < 0) || (iIndex2 >= iArrayLength)) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.swap', iIndex2, iArrayLength);
        }
        var vTempValue = this[iIndex1];
        this[iIndex1] = this[iIndex2];
        this[iIndex2] = vTempValue;
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : this;
    }
}
/**
 * Calculates and returns the unbiased variance of all array members or of a
 * subset of array members (if the optional start and length arguments are
 * specified).
 *
 * @summary             unbiased variance
 * @author              Stuart Wigley
 * @author              Randolph Fielding
 * @version             1.4, 08/08/03
 * @interface           Array.variance()
 * @interface           Array.variance(iStart)
 * @interface           Array.variance(iStart, iLength)
 * @requires            Array.mean(iStart, iLength)
 * @param iStart        the index of the array member to start at (optional)
 * @param iLength       the number of array members to evaluate beginning at
 *                      iStart (optional)
 * @return              the unbiased variance of all array members or of a
 *                      subset of array members
 * @return              null if no array members are numbers
 * @return              null if an exception is encountered
 * @throws              ArrayIndexOutOfBoundsException
 * @throws              IllegalArgumentException
 * @throws              MethodNotAvailableException
 * @throws              TypeMismatchException
 * @throws              UnknownException
 * @see                 Array.mean()
 */
Array.prototype.variance = function() {
    try {
        var vError = null;
        var iArrayLength = this.length;
        var iNumArguments = arguments.length;
        var iStart = 0;
        var iLength = iArrayLength;
        if (!('mean' in this)) {
            throw vError = new MethodNotAvailableException('Array.variance', 'Array.mean');
        }
        if (iNumArguments > 2) {
            throw vError = new IllegalArgumentException('Array.variance', '0, 1 or 2', iNumArguments);
        } else if (iNumArguments == 2) {
            iStart = arguments[0];
            iLength = arguments[1];
        } else if (iNumArguments == 1) {
            iStart = arguments[0];
            iLength -= iStart;
        }
        if ((typeof iStart != 'number') || (iStart.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.variance', 'integer', typeof iStart);
        }
        if ((typeof iLength != 'number') || (iLength.toString().indexOf('.') != -1)) {
            throw vError = new TypeMismatchException('Array.variance', 'integer', typeof iLength);
        }
        var iEnd = iStart + iLength;
        if (iStart < 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.variance', iStart, iArrayLength);
        }
        if (iLength <= 0) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.variance', iLength, iArrayLength);
        }
        if (iEnd > iArrayLength) {
            throw vError = new ArrayIndexOutOfBoundsException('Array.variance', iEnd, iArrayLength);
        }
        var fMean = this.mean(iStart, iLength);
        if (!fMean) {
            throw vError = new UnknownException('Array.variance');
        }
        var fSum = 0;
        var iCount = 0;
        for (var i = iStart; i < iEnd; i++) {
            if (typeof this[i] == 'number') {
                fSum += Math.pow((this[i] - fMean), 2);
                iCount++;
            }
        }
        if (iCount == 1) {
            throw vError = new UnknownException('Array.variance');
        }
        var fVariance = (iCount == 0) ? null : fSum / (iCount - 1);
    }
    catch (vError) {
        if (vError instanceof Error) {
            vError.handleError();
        }
    }
    finally {
        return vError ? null : fVariance;
    }
}
        
        
            var oTest = new Test();
            var oDebug = new Debug();
            var aSample = new Array(1, 2, 3, 4, 5, 'a', 'b', 'c', 'd', 'e');
            aSample['hello'] = 'hesdllo';
        
    
    
        
            
                
                    Starting Array = [1, 2, 3, 4, 5, 'a', 'b', 'c', 'd', 'e']
                

                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
                
                    
                    
                    
                    
                
            
        
Array.averageDev()
                        
                        
                    
Array.changeKeyCase()
Array.chunk()
Array.count() 
Array.covar()
                        
                        
                    
Array.fill()
                        
                        
                        
                    
Array.max()
                        
                        
                    
Array.mean()
                        
                        
                    
Array.median()
                        
                        
                    
Array.min()
                        
                        
                    
Array.product()
                        
                        
                    
Array.range()
                        
                        
                    
Array.standardDev()
                        
                        
                    
Array.sum()
                        
                        
                    
Array.swap()
                        
                        
                    
Array.variance()