    function XMLDoc() {
        var me = this;
        var req = null;
        if (window.XMLHttpRequest) {
            try {
                req = new XMLHttpRequest();
            } catch (e) {
                req = null;
            }
        } else if (window.ActiveXObject) {
            try {
                req = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                    req = new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {
                    req = null;
                }
            }
        } else {
            alert("This example requires a browser with XML support, such as IE5+/Windows, Mozilla, Safari 1.2, or Opera 8.");
        }
        this.request = req;
        this.loadXMLDoc = function(url, loadHandler) {
            if (this.request) {
                this.request.open("GET", url, true);
                this.request.onreadystatechange = function() {loadHandler(me)};
                this.request.setRequestHeader("Content-Type", "text/xml");
                this.request.send("");
            }
        };
    }
    
    function initXML(url) {
        var outlineRequest = new XMLDoc();
        if (url.indexOf("-asis.") == -1) {
            outlineRequest.loadXMLDoc(url, writeResults)
        } else {
            outlineRequest.loadXMLDoc(url, writeResultsAlt);
        }
    }
    
    function writeResultsAlt(req) {
        req = req.request;
        if (req.readyState == 4 && req.status == 200) {
            var d = document.getElementById("race-results");
            d.innerHTML = req.responseText;
        }
    }
    
    function writeResults(req) {
        req = req.request;
        if (req.readyState == 4) {
            if (req.status == 404) {
                document.getElementById("race-results").innerHTML = '\n<p><center>The specified results are not available at this time. Please try back later</center></p>';
                return;
            } 
            else if (req.status != 200) {
                return;
            }
            
            var xDoc = req.responseXML;
            
            // gather event parameters and construct html
            var t = xDoc.getElementsByTagName("event");
            if (t.length == 0) {
                document.getElementById("race-results").innerHTML = '\n<p><center>The specified results are not available at this time. Please try back later</center></p>';
                return;
            }
            var opt = t[0].getElementsByTagName("opt");
            if (opt && opt.length != 0) {
                opt = opt[0].firstChild.nodeValue;
            } else {
                opt = '0';
            }
            var eName = t[0].getElementsByTagName("name")[0].firstChild.nodeValue;
            var eDate = t[0].getElementsByTagName("date")[0].firstChild.nodeValue;
            var eType = t[0].getElementsByTagName("type")[0].firstChild.nodeValue;
            var ePermit = t[0].getElementsByTagName("permit")[0].firstChild.nodeValue;
            var ePDF = t[0].getElementsByTagName("pdf");
            ePDF = (ePDF.length > 0) ? ePDF[0].firstChild.nodeValue : '';
            
            var s = '\n<div><span style="float: left"><h3>' + eName;
            if (opt == '0') {
                s += ' on ' + eDate + ' (USCF Permit ' + ePermit + ')';
            }
            s += '</h3>';
            var rNote = t[0].getElementsByTagName("note");
            if (rNote.length > 0) {
                s += '<p>' + rNote[0].firstChild.nodeValue + '</p>';
            }
            s += '</span><br />';
            if (ePDF.length > 0) {
                s += '<span style="float: right"><a href="results/' + ePDF 
                    + '" target="_results"><img src="images/pdficon_small.gif" width="17" height="17" style="background: #E8E8E8; border: none; vertical-align: middle" />download</a></span>';
            }
            s += '</div>';

            // For each race (1) gather info and results, (2) construct  hmtl
            var r = xDoc.getElementsByTagName("race");
            if (r.length == 0) {
                document.getElementById("race-results").innerHTML = s;
                //document.getElementById("race-results").innerHTML = s + '\n<p><center>The specified results are not available in HTML format at this time. Please try back later</center></p>';
                return;
            }
            s += '\n<table class="results" style="clear: both">';
            
            var data,row,i,j,k,cnt,rider,isPrime;
            if (opt == '1') {
                var colNum = 5;
                for (i = 0; i < r.length; i++) {
                    var rCat = r[i].getElementsByTagName("category")[0].firstChild.nodeValue;
                    var rStart = r[i].getElementsByTagName("start")[0].firstChild.nodeValue;
                    
                    // Parse results, constructing one row per finishing place
                    cnt = 0;
                    isPrime = false;
                    data = r[i].getElementsByTagName("results")[0].firstChild.nodeValue;
                    data = data.split('\n');
                    for (j = 0; j < data.length; j++) {
                        row = data[j].split(',');
                        if (row.length < 6) {
                            continue;
                        } else if (row[0].toLowerCase() == 'name')  {
                            colNum = row.length-1;
                            var header = '\n<tr><th>name</th><th>&nbsp;</th><th>team</th>';
                            for (k=4; k<row.length-1; k++) {
                                header += '<th>' + row[k] + '</th>';
                                //header += '<th>R' + (k - 3) + '</th>';
                            }
                            header += '<th>total</th></tr>';
                            s += '\n<tr><td colspan="' + (row.length - 2) +'">&#160;<br />&#160;<br /><strong>Race Category: &#160; '
                                + rCat + '</strong></td><td>&#160;<br />&#160;<br /><strong>' 
                                + rStart + '</strong></td></tr>';
                            s += header;
                            continue;
                        }
                    
                        // isPrime?(actually, is subTotal) If yes, insert delimiter
                        if (row[3].toLowerCase() == 'sub-total') {
                            isPrime = true;
                            cnt = 0;
                            s += '\n<tr class="prime"><th colspan="' + (row.length - 1) + '"></th></tr>';
                        }
                        s += '\n<tr class="';
                        s += (++cnt % 2 > 0) ? 'row-a' : 'row-b';
                        s += '"><td>';
                        // construct rider's name from first and last
                        rider = (row[0] != 'na') ? row[0] : '';
                        if (row[1] != 'na') {
                            rider += (rider.length > 0) ? ' ' + row[1] : row[1];
                        }
                        s += (rider.length > 0) ? rider : '&#160';
                        s += '</td><td>' + row[2];
                        s += isPrime ? '</td><td style="text-align: right">' : '</td><td>';
                        s += row[3];
                        for (k=4; k<row.length; k++) {
                            s += '</td><td>' + row[k];
                        }
                        s += '</td></tr>';
                    }
                    
                    // Add any notes below table
                    var rNote = r[i].getElementsByTagName("note");
                    if (rNote.length > 0) {
                        s += '\n<tr class="raceNote"><td colspan="' + colNum +'">&#160;<br />' 
                            + rNote[0].firstChild.nodeValue + '</td></tr>';
                    }
                }
            } else if (opt == '2') {
                var colNum = 3;
                for (i = 0; i < r.length; i++) {
                    var rCat = r[i].getElementsByTagName("category")[0].firstChild.nodeValue;
                    var rStart = r[i].getElementsByTagName("start")[0].firstChild.nodeValue;
                    
                    // Parse results, constructing one row per finishing place
                    cnt = 0;
                    isPrime = false;
                    data = r[i].getElementsByTagName("results")[0].firstChild.nodeValue;
                    data = data.split('\n');
                    for (j = 0; j < data.length; j++) {
                        row = data[j].split(',');
                        if (row.length < 3) {
                            continue;
                        } else if (row[0].toLowerCase() == 'team')  {
                            colNum = row.length;
                            var header = '\n<tr><th>team</th>';
                            for (k=1; k<row.length-1; k++) {
                                header += '<th>' + row[k] + '</th>';
                            }
                            header += '<th>total</th></tr>';
                            s += '\n<tr><td colspan="' + (row.length - 1) +'">&#160;<br />&#160;<br /><strong>Race Category: &#160; '
                                + rCat + '</strong></td><td>&#160;<br />&#160;<br /><strong>' 
                                + rStart + '</strong></td></tr>';
                            s += header;
                            continue;
                        }
                    
                        // isPrime?(actually, is subTotal) If yes, insert delimiter
                        if (row[0].toLowerCase() == 'sub-total') {
                            isPrime = true;
                            cnt = 0;
                            s += '\n<tr class="prime"><th colspan="' + row.length + '"></th></tr>';
                        }
                        s += '\n<tr class="';
                        s += (++cnt % 2 > 0) ? 'row-a' : 'row-b';
                        s += '">';
                        s += isPrime ? '<td style="text-align: right">' : '<td>';
                        s += row[0];
                        for (k=1; k<row.length; k++) {
                            s += '</td><td>' + row[k];
                        }
                        s += '</td></tr>';
                    }
                    
                    // Add any notes below table
                    var rNote = r[i].getElementsByTagName("note");
                    if (rNote.length > 0) {
                        s += '\n<tr class="raceNote"><td colspan="' + colNum +'">&#160;<br />' 
                            + rNote[0].firstChild.nodeValue + '</td></tr>';
                    }
                }
            } else {
                var tableHeader = '\n<tr><th>place</th><th>name</th><th>license</th><th>bib</th><th>team</th><th>points</th></tr>';
                for (i = 0; i < r.length; i++) {
                    var rCat = r[i].getElementsByTagName("category")[0].firstChild.nodeValue;
                    var rStart = r[i].getElementsByTagName("start")[0].firstChild.nodeValue;
                    var rTime = r[i].getElementsByTagName("duration")[0].firstChild.nodeValue;
                    var rNum = r[i].getElementsByTagName("entries")[0].firstChild.nodeValue;
                    s += '\n<tr><td colspan="5">&#160;<br />&#160;<br /><strong>Race Category: &#160; '
                        + rCat + '</strong><br />Time: &#160; ' 
                        + rTime + ' minutes<br />Entries: &#160; ' 
                        + rNum + '</td><td><strong>' 
                        + rStart + '</strong></td></tr>';
                        
                    // Parse results, constructing one row per finishing place
                    cnt = 0;
                    isPrime = false;
                    var lastPrime = '';
                    data = r[i].getElementsByTagName("results");
                    if (data.length > 0) {
                        data = data[0].firstChild.nodeValue;
                        data = data.split('\n');
                        s += tableHeader;
                    }
                    for (j = 0; j < data.length; j++) {
                        row = data[j].split(',');
                        if (row.length < 7 || row[0].toLowerCase() == 'place')  {
                            continue;
                        }
                    
                        // prime? If yes, insert delimiter
                        /*
                        if (!isPrime && row[0].toLowerCase() == 'prime') {
                            isPrime = true;
                            cnt = 0;
                            s += '\n<tr class="prime"><th colspan="6"></th></tr>';
                        }
                        else if (isPrime && cnt == 2) {
                            cnt = 0;
                            s += '\n<tr class="prime"><th colspan="6"></th></tr>';
                        }
                        */
                        if (!isPrime && row[0].toLowerCase().indexOf('prime') > -1) {
                            isPrime = true;
                        }
                        if (isPrime) {
                            var c = row[0].charAt(row[0].length-1);
                            if (lastPrime != c) {
                                lastPrime = c;
                                cnt = 0;
                                s += '\n<tr class="prime"><th colspan="6"></th></tr>';
                            }
                            row[0] = 'Prime';
                        }
                        s += '\n<tr class="';
                        s += (++cnt % 2 > 0) ? 'row-a' : 'row-b';
                        s += '"><td>'+ row[0] + '</td><td>';
                        // construct rider's name from first and last
                        rider = (row[2] != 'na') ? row[2] : '';
                        if (row[3] != 'na') {
                            rider += (rider.length > 0) ? ' ' + row[3] : row[3];
                        }
                        s += (rider.length > 0) ? rider : '&#160';
                        s += '</td><td>';
                        if (row[4].length == 0 || row[4] == 'na') {
                            s += '&#160;';
                        } else if (row[4].toLowerCase() == 'pending') {
                            s +=  'pending';
                        } else if (row[4].toLowerCase() == '1-day') {
                            s +=  '1-Day';
                        } else if ("1234567890".indexOf(row[4].charAt(0)) == -1) {
                            s +=  row[4];
                        } else {
                            s += '<a href="http://www.usacycling.org/results/index.php?compid=' 
                                + row[4] + '" target="_usacycling">' 
                                + row[4] + '</a>';
                        }
                        s += '</td><td>' + row[1] + '</td><td>' + row[5] 
                            + '</td><td>' + row[6] + '</td></tr>';
                    }
                    
                    // Add any notes below table
                    var rNote = r[i].getElementsByTagName("note");
                    if (rNote.length > 0) {
                        s += '\n<tr class="raceNote"><td colspan="6">&#160;<br />' 
                            + rNote[0].firstChild.nodeValue + '</td></tr>';
                    }
                }
            }
            s += '\n</table>';
            document.getElementById("race-results").innerHTML = s;
        }
    }
    
    function initResults() {
        var s = document.forms[1].elements[0];
        initXML(s.options[s.selectedIndex].value);
    }
