    var dougObjectCache = {};
    var dougDate = new Date();
    var dougTimestamp = dougDate.getTime();

    function dougPreparePayload(dougObject) {
        var payload = Array();
        for (i = 0; i < dougObject.fields.length; i++) {
            var element = document.getElementById(dougObject.fields[i]);
            if (element) {
                payload.push(dougObject.columns[i] + "=" + encodeURIComponent(element.value)); 
            } else {
                // maybe a radiobutton
                var elements = document.getElementsByName(dougObject.fields[i]);
                for (var j = 0; j < elements.length; j++) {
                    if (elements[j].checked) {
                        payload.push(dougObject.columns[i] + "=" + encodeURIComponent(elements[j].value)); 
                    }
                }
                //                alert("Fatal: dougPreparePayload failed on " + dougObject.fields[i]);
            }
        }

        if (dougObject.extras) {
            for (key in dougObject.extras) {
                payload.push(key + "=" + encodeURIComponent(dougObject.extras[key]));
            }
        }

        payload.push("module=" + dougObject.module);
        payload.push("function=" + dougObject["function"]);  // inconvinient naming of property function

        return payload.join("&");
    }

    
    function dougCallIdle(dougObjectIdentifier, delay) {
        var dougObject = dougObjectCache[dougObjectIdentifier];

        function idle() {
            clearInterval(dougObject.interval);
            dougObject.interval = null;
            dougCall(dougObjectIdentifier);
        }

        if (dougObject.interval) {
            clearInterval(dougObject.interval);
            dougObject.interval = setInterval(idle, delay);
            return;

        }

        dougObject.interval = setInterval(idle, delay);
    }

    function dougCallPoll(dougObjectIdentifier, delay) {
        var dougObject = dougObjectCache[dougObjectIdentifier];

        function poll() {
            if (!dougObject.polling) {
                dougObject.polling = true;
                dougCall(dougObjectIdentifier);
            }
        }

        if (!dougObject.interval) {
            dougObject.interval = setInterval(poll, delay);
        }
    }

    function dougCall(dougObjectIdentifier) {
        var dougObject = dougObjectCache[dougObjectIdentifier];
        var payload = dougPreparePayload(dougObject);

        var callback = { 
    	  success: function(o) { 
    
                dougObject = o.argument;
    
                var spos=o.responseText.indexOf('<json>');
                var epos=o.responseText.indexOf('</json>');
                json_string = o.responseText.substring(spos+6,epos);
                var returnObject = eval('(' + json_string + ')');  // user safer json-function
    
                if (dougObject.value_element_id && returnObject.value) {
                    var element = document.getElementById(dougObject.value_element_id);
                    if (element) {
                        element.value = returnObject.value;
                    }
                }
    
                if (dougObject.inner_element_id && returnObject.innerHTML) {
                    var element = document.getElementById(dougObject.inner_element_id);
                    if (element) {
                        element.innerHTML = returnObject.innerHTML;
                    }
                }
    
                if (returnObject.return_function) {   // EXPERIMENTAL
                    eval(returnObject["return_function"] + "(returnObject)");
                }
            
                if (dougObject.poll) {
                    dougObject.polling = false;
                    if (returnObject.pollControl) {
                        if (returnObject.pollControl == "stop") {
                            clearInterval(dougObject.interval);
                        }
                        
                        if (!isNaN(parseInt(returnObject.pollControl))) {
                            clearInterval(dougObject.interval);
                            dougObject.interval = null;
                            dougCallPoll(dougObjectIdentifier, returnObject.pollControl);
                        }

                    }
                }

          }, 
    	  failure: function(o) { 
                alert(o.statusText);
          }, 
          timeout: 5000,
          argument:dougObject
    	} 
    
        var transaction = YAHOO.util.Connect.asyncRequest('POST', "/doug/dispatch.php", callback, payload); 
    }     



    function dougAddObject(dougObjectIdentifier, dougObjectString) { 
        var dougObject = eval(dougObjectString);
        dougObject.timestamp = dougTimestamp;
        dougObject.polling = false;
        dougObjectCache[dougObjectIdentifier] = dougObject;
    }

