function testClientComputerAttributes(
        operatingSystems, browsers, dotNetVersion) {

    this.operatingSystems = operatingSystems;
    this.browsers = browsers;
    this.dotNetVersion = dotNetVersion;

    this.userAgent = navigator.userAgent;
    this.dotNetPattern = /.NET CLR [0-9.]+/g;
    this.splitDotNetText = '.NET CLR ';
    this.ANYDOTNETVERSION = 0.0001;


    this.initClassAttributes = function() {
        this.operatingSystems = this._ensureIsList(this.operatingSystems);
        this.browsers = this._ensureIsList(this.browsers);

        // Ensure dotNetVersion is a number. On error, set to ANYDOTNETVERSION
        try {
            this.dotNetVersion = parseFloat(this.dotNetVersion);

            if (isNaN(this.dotNetVersion)) {
                this.dotNetVersion = this.ANYDOTNETVERSION;
            }
        } catch(error) {
            this.dotNetVersion = this.ANYDOTNETVERSION;
        }
    };

    this.hasCompatibleOS = function() {
        for (var i=0; i<operatingSystems.length; i++) {
            if (this.userAgent.toLowerCase().indexOf(
                        this.operatingSystems[i].toLowerCase()) >= 0) {
                return true;
            }
        }
        return false;
    };

    this.hasCompatibleBrowser = function() {
        //#TODO: beef this guy up
        for (var i=0; i<browsers.length; i++) {
            if(this.userAgent.toLowerCase().indexOf(
                        this.browsers[i].toLowerCase()) >= 0) {
                return true;
            }
        }
        return false;
    };

    this.hasCompatibleDotNet = function() {
        var dotNets = this._getAndCleanDotNetVersions();

        if (dotNets == null) {
            return false;
        }

        for (var i=0; i<dotNets.length; i++) {
            var version = dotNets[i];
            if (parseFloat(dotNets[i]) >= this.dotNetVersion) {
                return true;
            }
        }

        return false
    };

    this.isToolbarCompatible = function() {
        var compatible = (this.hasCompatibleOS() && 
                          //this.hasCompatibleDotNet() &&
                          this.hasCompatibleBrowser());
        return compatible;
    };

    this._ensureIsList = function(param) {
        if (param == undefined) {
            return [];
        }

        if (!(param.push)) { // cheap array/list test
            return [param];
        }

        return param;
    };

    this._getAndCleanDotNetVersions = function() {
        var dotNets = this.userAgent.match(this.dotNetPattern);

        if (dotNets == null) {
            return [];
        }

        for (var i=0; i<dotNets.length; i++) {
            try {
                var dotNetVersion = 
                    parseFloat(dotNets[i].split(this.splitDotNetText)[1]);
            } catch(e) {
                var dotNetVersion = 0.0;
            }
            dotNets[i] = dotNetVersion;
        }
        
        return dotNets;
    };

    this.initClassAttributes();
}
