function SortDataSet($aArray, $sField, $bDescending = false)
{
    $bIsNumeric = IsNumeric($aArray);
    $aKeys = array_keys($aArray);
    $nSize = sizeof($aArray);
    for ($nIndex = 0; $nIndex < $nSize - 1; $nIndex++) {
        $nMinIndex = $nIndex;
        $objMinValue = $aArray[$aKeys[$nIndex]][$sField];
        $sKey = $aKeys[$nIndex];
        for ($nSortIndex = $nIndex + 1; $nSortIndex < $nSize; ++$nSortIndex) {
            if ($aArray[$aKeys[$nSortIndex]][$sField] < $objMinValue) {
                $nMinIndex = $nSortIndex;
                $sKey = $aKeys[$nSortIndex];
                $objMinValue = $aArray[$aKeys[$nSortIndex]][$sField];
            }
        }
        $aKeys[$nMinIndex] = $aKeys[$nIndex];
        $aKeys[$nIndex] = $sKey;
    }
    $aReturn = array();
    for ($nSortIndex = 0; $nSortIndex < $nSize; ++$nSortIndex) {
        $nIndex = $bDescending ? $nSize - $nSortIndex - 1 : $nSortIndex;
        $aReturn[$aKeys[$nIndex]] = $aArray[$aKeys[$nIndex]];
    }
    return $bIsNumeric ? array_values($aReturn) : $aReturn;
}
function GetTokens($s_str, $s_quotes = "'\"")
{
    $b_allow_strings = $s_quotes !== "" ? true : false;
    $ii = 0;
    $i_len = strlen($s_str);
    $a_toks = array();
    while ($ii < $i_len) {
        switch ($ch = $s_str[$ii]) {
            case " ":
            case "\t":
            case "\n":
            case "\r":
                $ii++;
                continue;
        }
        //
        // start of a token
        //
        $i_start = $ii;
        if ($ch == "_" || IsAlpha($ch)) {
            //
            // a word
            //
            $i_count = 1;
            while (++$ii < $i_len && ($s_str[$ii] == "_" || IsAlnum($s_str[$ii]))) {
                ++$i_count;
            }
            $a_toks[] = substr($s_str, $i_start, $i_count);
        } elseif ($ch == "." && $ii < $i_len - 1 && IsNumeric($s_str[$ii + 1]) || IsNumeric($ch)) {
            //
            // a number
            //
            $b_had_dot = $ch == ".";
            $i_count = 1;
            while (++$ii < $i_len) {
                if (IsNumeric($s_str[$ii])) {
                    ++$i_count;
                } elseif ($s_str[$ii] == "." && !$b_had_dot) {
                    ++$i_count;
                    $b_had_dot = true;
                } else {
                    break;
                }
            }
            $a_toks[] = substr($s_str, $i_start, $i_count);
        } elseif ($b_allow_strings && strpos($s_quotes, $ch) !== false) {
            $c_quote = $ch;
            //
            // a quoted string
            //
            while (++$ii < $i_len) {
                if ($s_str[$ii] == $c_quote) {
                    ++$ii;
                    // include the terminating quote
                    break;
                }
            }
            $a_toks[] = substr($s_str, $i_start, $ii - $i_start);
        } else {
            $s_punct = "~!@#\$%^&*()-+={}[]|:;<>,.?/`\\";
            if (!$b_allow_strings) {
                $s_punct .= "'\"";
            }
            if (strpos($s_punct, $ch) !== false) {
                $a_toks[] = $ch;
            }
            ++$ii;
        }
    }
    return $a_toks;
}