function WAF_UserInterface(_pageAssemblyName, _baseUrl, _sessionId, _requestId, _windowId, _serviceUrl, _flashUrl) {

    // PUBLIC GENERAL
    this.IsProxy = false;
    this.NewGuid = newGuid;
    this.WindowId = _windowId;
    this.SetSessionId = function (sessionId) { _sessionId = sessionId; };
    this.BaseUrl = _baseUrl;
    this.StartUp = startUp;
    this.RegisterEditor = registerEditor;
    this.Trace = trace;
    this.StartUpChildWindow = startUpChildWindow;
    this.TryGetWindow = tryGetWindow;
    this.UpdateUI = updateUI;
    this.UpdateUISoon = updateUISoon;
    this.DisableSelect = disableSelect;
    this.Edit = edit;
    this.WindowHeight = windowHeight;
    this.WindowWidth = windowWidth;
    this.WorkflowUpdatePulse = workflowUpdatePulse; ;
    this.SetAllowTextSelect = function (value) { _allowTextSelect = value; }
    this.SetClipboard = setClipboard;
    this.GetClipboard = getClipboard;
    this.RequestId = _requestId;
    this.DecodeClipboardString = decodeClipboardString;
    this.IsDataClipboardEncoded = isDataClipboardEncoded;
    this.SetNoEventBubble = setNoEventBubble;
    this.GetNoEventBubble = function () { return _doNotBubble; }
    this.MoveElementToMousePos = moveElementToMousePos;
    this.DisableNextRightClickMenu = disableNextRightClickMenu;
    this.Utf8Encode = utf8Encode;
    this.QueToolTip = queToolTip;
    this.ShowToolTip = showToolTip;
    this.HideToolTip = hideToolTip;
    this.HideToolTipNow = hideToolTipNow;
    this.DeQueToolTip = deQueToolTip;
    this.RefreshHtmlEditorImages = refreshHtmlEditorImages;

    // PUBLIC DIALOGUES
    this.IsMovingElement = isMovingElement;
    this.MoveWindowToFront = moveWindowToFront;
    this.SetMovingElement = function (element) { _movingElement = element; }
    this.GetMovingElement = function () { return _movingElement; }
    this.SetMoveCompleteScript = function (script) { _moveCompleteScript = script; }
    this.SetDesktopWindow = setDesktopWindow;
    this.StartWindowResize = startWindowResize;

    // PUBLIC WORKFLOW
    this.StartWorkflow = startWorkflow;
    this.StartWorkflowMethod = startWorkflowMethod;
    this.TerminateWorkflow = terminateWorkflow;
    this.SuspendWorkflow = suspendWorkflow;
    this.ResumeWorkflow = resumeWorkflow;
    this.SendExchange = sendExchange;
    this.SendExchangeValue = sendExchangeValue;
    this.CloseExchange = closeExchange;
    this.CloseProgress = closeProgress;
    this.OpenExchange = openExchange;
    this.OpenProgress = openProgress;
    this.Ask = ask;
    this.Notify = notify;

    // PUBLIC PREVIEW
    this.HidePreview = hidePreview;
    this.ShowPreview = showPreview;
    this.RefreshPreview = refreshPreview;

    // PUBLIC RESIZE
    this.ResizeUI = resizeUI;
    this.QueSetScroll = queSetScroll;
    this.InitScrollTop = initScrollTop;
    this.InitScrollLeft = initScrollLeft;

    this.AddSizeHeightElements = addSizeHeightElements;
    this.AddSizeHeightElementsDelta = addSizeHeightElementsDelta;
    this.AddSizeWidthElements = addSizeWidthElements;
    this.AddSizeWidthElementsDelta = addSizeWidthElementsDelta;

    // PUBLIC KEYPRESS
    this.RegisterShortCutKey = registerShortCutKey;
    this.RegisterShortCutKeyCtrl = registerShortCutKeyCtrl;
    this.RegisterShortCutKeyAlt = registerShortCutKeyAlt;

    // PUBLIC DRAG DROP
    this.StartGeneralDrag = startGeneralDrag;
    this.IsGeneralDragInProgress = isGeneralDragInProgress;
    this.GetDragDistance = getDragDistance;
    this.RegisterDragStartScript = registerDragStartScript;
    this.StartDrag = startDrag;
    this.StartSliderDrag = startSliderDrag;
    this.GetShouldBeginDragNow = getShouldBeginDragNow;
    this.RegisterDropTarget = registerDropTarget;
    this.UnRegisterDropTarget = unRegisterDropTarget;
    this.GetDropTargetPosition = getDropTargetPosition;
    this.GetMouseHoverFraction = getMouseHoverFraction;
    this.GetElementX = getElementX;
    this.GetElementY = getElementY;
    this.SetElementXY = setElementXY;

    // PUBLIC MISC
    this.FixHtml = filterHtml;
    this.UpdatePreviewIfAny = updatePreviewIfAny;

    // PUBLIC AJAX
    this.Ajax = ajax;
    this.SetSessionSettingObject = setSessionSettingObject;
    this.SetSessionSettingString = setSessionSettingString;
    this.SetSessionSettingInt = setSessionSettingInt;
    this.SetUserSettingString = setUserSettingString;
    this.SetUserSettingInt = setUserSettingInt;
    this.SetUserSettingObject = setUserSettingObject;
    this.GetSessionSettingString = getSessionSettingString;
    this.GetSafeStringFromArray = getSafeStringFromArray;
    this.GetArrayFromSafeString = getArrayFromSafeString;
    this.UrlEncode = urlEncode;
    this.UrlDecode = urlDecode;

    // LOCAL variables 
    var _browserIsFirefox = navigator.userAgent.indexOf("Firefox") > 0;
    var _browserIsOpera = window.opera != null;
    var _browserIsExplorer = navigator.userAgent.indexOf("MSIE") > 0;
    var _browserIsSafari = navigator.userAgent.indexOf("Safari") > 0;
    var _browserIsUnknown = !(_browserIsFirefox || _browserIsOpera || _browserIsExplorer || _browserIsSafari);

    this.BrowserIsFirefox = _browserIsFirefox;
    this.BrowserIsOpera = _browserIsOpera;
    this.BrowserIsExplorer = _browserIsExplorer;
    this.BrowserIsUnknown = _browserIsUnknown;
    this.BrowserIsSafari = _browserIsSafari;




























    // *************************
    // GENERAL
    // *************************
    function startUp() {
        setEvents(window);
        workflowUpdatePulse(true);
    }
    function startUpChildWindow(childWindow) {
        setEvents(childWindow);
    }
    var _editorFrames = new Array();
    function registerEditor(editFrame) {
        setEvents(editFrame.contentWindow);
        _editorFrames.push(editFrame);
    }
    var _doNotBubble = false;
    var _bubbleTimeOutId;
    var _allowTextSelect = true;
    var _lastdisableSelectTimeout = null;
    function setEvents(win) {
        // DOCUMENT EVENTS
        if (_browserIsFirefox) win.document.captureEvents(Event.MOUSEDOWN | Event.MOUSEMOVE | Event.MOUSEUP);
        win.document.oncontextmenu = function (e) { return contextMenu(e == null ? win.event : e); };
        win.document.onmousedown = function (e) { mouseDown(e == null ? win.event : e); };
        win.document.onmousemove = function (e) { mouseMove(e == null ? win.event : e); };
        win.document.onmouseup = function (e) { mouseUp(e == null ? win.event : e); };
        win.onresize = function (e) { return resizeUIAll(e == null ? win.event : e); };
        win.document.onkeydown = function (e) { onKeyDownHandler(e == null ? win.event : e); };
        win.document.onkeypress = function (e) { onKeyPressHandler(e == null ? win.event : e); };
        win.document.onkeyup = function (e) { onKeyUpHandler(e == null ? win.event : e); };
        if (typeof win.document.onselectstart != "undefined") win.document.onselectstart = onSelectStart;
    }
    function disableSelect() { // Disables text selection for the next 2 sec.
        _allowTextSelect = false;
        if (_lastdisableSelectTimeout != null) window.clearTimeout(_lastdisableSelectTimeout); // clear previeous timers, to extend with two new sec...
        _lastdisableSelectTimeout = window.setTimeout("WAF.SetAllowTextSelect(true);_lastdisableSelectTimeout=null;", 2000);
    }
    var _disableNextRightClickMenu = false;
    function disableNextRightClickMenu() {
        _disableNextRightClickMenu = true;
    }
    function contextMenu(e) {
        if (_disableNextRightClickMenu) {
            _disableNextRightClickMenu = false;
            return false;
        } else {
            return true
        }
    }
    function setNoEventBubble(bubble) {
        if (bubble == null || bubble == true) {
            if (_bubbleTimeOutId != null) {
                window.clearTimeout(_bubbleTimeOutId);
            }
            _doNotBubble = true;
            window.setTimeout("WAF.SetNoEventBubble(false);", 200)
        } else {
            _bubbleTimeOutId = null;
            _doNotBubble = false;
        }
    }
    function edit(nodeId) {
        _desktopWindow.location = WAF.Ajax("WAF.Presentation.Web.GetEditUrl", nodeId + "");
    }
    function onSelectStart() {
        return _allowTextSelect;
    }
    function windowHeight() {
        var myHeight = 0;
        //Non-IE
        if (typeof (window.innerHeight) == 'number') {
            myHeight = window.innerHeight;
        } else if (document.documentElement && (document.documentElement.clientHeight)) {
            //IE 6+ in 'standards compliant mode'
            myHeight = document.documentElement.clientHeight;
        } else if (document.body && (document.body.clientHeight)) {
            //IE 4 compatible
            myHeight = document.body.clientHeight;
        }
        return myHeight - 1;
    }
    function windowWidth() {
        var myWidth = 0;
        if (typeof (window.innerWidth) == 'number') {
            //Non-IE
            myWidth = window.innerWidth;
        } else if (document.documentElement && (document.documentElement.clientWidth)) {
            //IE 6+ in 'standards compliant mode'
            myWidth = document.documentElement.clientWidth;
        } else if (document.body && (document.body.clientWidth)) {
            //IE 4 compatible
            myWidth = document.body.clientWidth;
        }
        return myWidth - 1;
    }
    var _clipboardStartMarker = "##WAF_PASTE_START##";
    var _clipboardEndMarker = "##WAF_PASTE_END##";
    function setClipboard(data, encode) {
        if (encode) {
            encodedData = new Array();
            encodedData.push(_clipboardStartMarker);
            for (var n = 0; n < data.length; n++) {
                encodedData.push(data.charCodeAt(n));
                encodedData.push(";");
            }
            if (data.length > 0) encodedData.pop(); // removing last ";"
            encodedData.push(_clipboardEndMarker);
            encodedData = encodedData.join("");
            setSessionSettingString("Clipboard", encodedData);
        } else {
            setSessionSettingString("Clipboard", data);
        }
    }
    function isDataClipboardEncoded(data) {
        return data.indexOf(_clipboardStartMarker) > -1;
    }
    function decodeClipboardString(data) {
        encoded = data;
        // Strip markers:
        start = encoded.indexOf(_clipboardStartMarker);
        end = encoded.indexOf(_clipboardEndMarker);
        if (start > -1 && end > -1 && start < end) { // WAF paste
            var encoded = encoded.substring(start + _clipboardStartMarker.length, end); // stripping markers
            // Decode char codes 
            encoded = encoded.split(";");
            decoded = new Array();
            for (var n in encoded) {
                decoded.push(String.fromCharCode(encoded[n]));
            }
            return decoded.join("");
        }
        return data; // no marked as encoded, so return as is
    }
    function getClipboard() {
        return decodeClipboardString(getSessionSettingString("Clipboard"));
    }

    function setElementXY(element, x, y) { // relative to document upper left corner
        if (x == null) x = _mouseLastX;
        if (y == null) y = _mouseLastY;
        if (_browserIsFirefox) {
            element.style.top = y + "px";
            element.style.left = x + "px";
        } else {
            element.style.pixelTop = y;
            element.style.pixelLeft = x;
        }
    }
    function moveElement(element, dx, dy) {
        if (element != null) {
            if (_browserIsFirefox) {
                element.style.left = (getElementX(element) + dx) + "px";
                element.style.top = (getElementY(element) + dy) + "px";
            } else {
                element.style.pixelLeft = getElementX(element) + dx;
                element.style.pixelTop = getElementY(element) + dy;
            }
        }
    }
    function getElementX(element) { // relative to document upper left corner
        if (element == null) return 0;
        var doc = element.ownerDocument;
        var value = 0;
        while (element != null) {
            value += element.offsetLeft;
            if (element.scrollLeft != null) value -= element.scrollLeft;
            element = element.offsetParent;
        }
        if (!_browserIsOpera && !_browserIsFirefox) {
            value += doc.body.scrollLeft + doc.documentElement.scrollLeft;
        }
        return value;
    }
    function getElementYScrollOffset(element) {
        var value = 0;
        var doc = element.ownerDocument;
        while (element != null) {
            if (element.scrollTop > 0) value -= element.scrollTop;
            element = element.parentNode;
        }
        value += doc.body.scrollTop + doc.documentElement.scrollTop;
        return value;
    }
    function getElementY(element) { // relative to document upper left corner
        if (element == null) return 0;
        var value = getElementYScrollOffset(element);
        while (element != null) {
            if (element.offsetTop != null) value += element.offsetTop;
            element = element.offsetParent;
        }
        return value;
    }
    function getFrameElement(element) {
        if (_browserIsExplorer) {
            if (element.document == null) return null;
            if (element.document.parentWindow == null) return null;
            return element.document.parentWindow.frameElement;
        } else {
            return element.ownerDocument.defaultView.frameElement;
        }
    }
    function getFrameOffsetX(element) { return getElementX(getFrameElement(element)); }
    function getFrameOffsetY(element) { return getElementY(getFrameElement(element)); }
    function getEventSrcElement(e) {
        var el = e.srcElement;
        if (el == null) {
            el = e.target;
            if (el != null) return e.target;
        } else {
            return el;
        }
    }

    function getMouseX(e) { return getMouseXRelWindow(e) + getFrameOffsetX(getEventSrcElement(e)); }
    function getMouseY(e) { return getMouseYRelWindow(e) + getFrameOffsetY(getEventSrcElement(e)); }
    function getMouseXRelWindow(e) {
        try {
            return _browserIsFirefox ? e.pageX : e.clientX + document.documentElement.scrollLeft;
        } catch (exp) {
            return 0;
        }
    }
    function getMouseYRelWindow(e) {
        try {
            return _browserIsFirefox ? e.pageY : e.clientY + document.documentElement.scrollTop;
        } catch (exp) {
            return 0;
        }
    }


    function getMouseElementOffsetX(e) { return _browserIsFirefox ? e.layerX : e.offsetX; }
    function getMouseElementOffsetY(e) { return _browserIsFirefox ? e.layerY : e.offsetY; }
    function alwaysSetElementOpacity2(element, opacityInPercentage) {
        if (element != null) {
            if (!_browserIsExplorer) {
                element.style.opacity = opacityInPercentage / 100;
            } else {
                element.style.filter = "alpha(opacity=" + opacityInPercentage + ")";
            }
        }
    }
    function alwaysSetElementOpacity(element, opacityInPercentage) {
        if (element != null) {
            if (!_browserIsExplorer) {
                element.style.opacity = opacityInPercentage / 100;
            } else {
                element.style.filter = "alpha(opacity=" + opacityInPercentage + ")";
            }
            if (opacityInPercentage < 1) {
                element.style.display = "none";
            } else {
                element.style.display = "";
            }
        }
    }
    function setElementOpacity(element, opacityInPercentage) {
        if (element != null) {
            if (_browserIsFirefox) {
                //element.style.opacity = opacityInPercentage / 100;
            } else {
                //element.style.filter = "alpha(opacity=" + opacityInPercentage + ")";
            }
            if (opacityInPercentage < 1) {
                element.style.display = "none";
            } else {
                element.style.display = "";
            }
        }
    }

    function fadeIn(element) {
        setElementOpacity(element, 0);
        var fpms = 30 / 1000;  // frames per millisec
        var duration = 1 / fpms; //(!_browserIsFirefox)?1/fpms:300; // in ms
        for (var i = 0; i <= duration; i += 1 / fpms) {
            (function () {
                var opac = Math.round(100 * i / duration);
                window.setTimeout(function () {
                    setElementOpacity(element, opac);
                }, Math.round(i));
            })();
        }
    }
    function fadeOut(element, removeElement) {
        setElementOpacity(element, 100);
        var fpms = 30 / 1000;  // frames per millisec
        var duration = 1 / fpms; //(!_browserIsFirefox)?1/fpms:500; // in ms
        for (var i = 0; i <= duration; i += 1 / fpms) {
            (function () {
                var opac = 100 - Math.round(100 * i / duration);
                window.setTimeout(function () {
                    setElementOpacity(element, opac);
                }, Math.round(i));
            })();
        }
        if (removeElement) {
            window.setTimeout(function () {
                if (element != null) {
                    element.style.display = "none";
                    if (!_browserIsFirefox) try { document.body.removeChild(element) } catch (exp) { };
                }
            }, duration);
        }
    }
    function moveElementToMousePos(element, dx, dy) {
        element.style.top = "0px";
        element.style.left = "0px";
        element.style.top = _mouseLastYRelWindow - getElementY(element) + dy + "px";
        element.style.left = _mouseLastXRelWindow - getElementX(element) + dx + "px";
    }

    var _toolTipElement;
    var _quedToolTip;
    var _toolTipTimer;
    var _toolTipHideTimer;
    var _toolTipIsShowing;
    var _timeToToolTip = 300;
    var _timeToToolTip2 = 200;
    function queToolTip(e, tip) {
        if (_keyPressed || _movingElement != null || _mouseDragScript != null || _generalDragCallBack != null) return;
        _quedToolTip = tip;
        if (_toolTipHideTimer != null) window.clearTimeout(_toolTipHideTimer); _toolTipHideTimer = null;
        if (_toolTipTimer != null) window.clearTimeout(_toolTipTimer); _toolTipTimer = null;
        if (!_toolTipIsShowing) {
            _toolTipTimer = window.setTimeout(function () { showToolTip(); }, _timeToToolTip);
        } else {
            _toolTipTimer = window.setTimeout(function () { showToolTip(); }, _timeToToolTip2); // time to show if not 
        }
    }
    function deQueToolTip() {
        if (_toolTipTimer != null) window.clearTimeout(_toolTipTimer); _toolTipTimer = null;
        if (_toolTipHideTimer != null) window.clearTimeout(_toolTipHideTimer); _toolTipHideTimer = null;
        _toolTipHideTimer = window.setTimeout("WAF.HideToolTip();", 200);
    }
    function hideToolTipNow() {
        _timeToToolTip = 1000;
        if (_toolTipTimer != null) window.clearTimeout(_toolTipTimer); _toolTipTimer = null;
        if (_toolTipElement != null) {
            setElementOpacity(_toolTipElement, 0);
            _toolTipIsShowing = false;
        }
    }
    function hideToolTip() {
        if (!_toolTipIsShowing) return;
        if (_toolTipElement != null) {
            fadeOut(_toolTipElement, false);
            _toolTipIsShowing = false;
        }
    }

    function showToolTip() {
        var toolTip;
        if (typeof (_quedToolTip) == "function") {
            try {
                toolTip = _quedToolTip();
            } catch (err) {
                toolTip = err;
            }
        } else {
            toolTip = _quedToolTip;
        }
        if (toolTip == null) return;
        if (toolTip.name == "Error") return;
        _timeToToolTip = 300;
        _toolTipTimer = null;
        if (toolTip == null) return;
        if (_toolTipHideTimer != null) window.clearTimeout(_toolTipHideTimer); _toolTipHideTimer = null;
        if (_toolTipElement == null) {
            _toolTipElement = document.createElement("div");
            _toolTipElement.id = "WAF_ToolTipElement";
            _toolTipElement.className = "WAF_ToolTip";
            setElementOpacity(_toolTipElement, 0);
            document.body.appendChild(_toolTipElement);
        }
        _toolTipElement.innerHTML = toolTip;
        var x = _mouseLastX + 20;
        var y = _mouseLastY + 30;
        if (x > windowWidth() / 2) x = x - _toolTipElement.clientWidth - 40;
        if (y > windowHeight() / 2) y = y - _toolTipElement.clientHeight - 50;
        setElementXY(_toolTipElement, x, y);
        if (!_toolTipIsShowing) {
            window.setTimeout(function () {
                if (x > windowWidth() / 2) x = x - _toolTipElement.clientWidth - 40;
                if (y > windowHeight() / 2) y = y - _toolTipElement.clientHeight - 50;
                setElementXY(_toolTipElement, x, y);
            }, 300);
        }
        if (!_toolTipIsShowing) {
            fadeIn(_toolTipElement);
        } else {
            setElementOpacity(_toolTipElement, 100);
        }
        _toolTipIsShowing = true;
    }


    function newGuid() {
        var guid, i, j;
        guid = "";
        for (j = 0; j < 32; j++) {
            if (j == 8 || j == 12 || j == 16 || j == 20) guid = guid + '-';
            i = Math.floor(Math.random() * 16).toString(16).toLowerCase();
            guid = guid + i;
        }
        return guid;
    }






    // *************************
    // PREVIEW
    // *************************

    function hidePreview() {
        parent.parent.WAF_HidePreview();
    }
    function showPreview() {
        parent.parent.WAF_ShowPreview();
    }
    function refreshPreview() {
        parent.parent.WAF_RefreshPreview();
    }






    // *************************
    // RESIZE
    // *************************
    var _setScrollQue = null;
    function queSetScroll(element, scrollKey) {
        _setScrollQue = "&SetScroll=" + scrollKey + "," + element.scrollTop + "," + element.scrollLeft;
    }
    function initScrollTop(element, v) {
        window.setTimeout(function () { try { if (element.scrollTop == 0) element.scrollTop = v; } catch (err) { } }, 0);
        window.setTimeout(function () { try { if (element.scrollTop == 0) element.scrollTop = v; } catch (err) { } }, 500);
        window.setTimeout(function () { try { if (element.scrollTop == 0) element.scrollTop = v; } catch (err) { } }, 1000);
    }
    function initScrollLeft(element, v) {
        window.setTimeout(function () { try { if (element.scrollLeft == 0) element.scrollLeft = v; } catch (err) { } }, 0);
        window.setTimeout(function () { try { if (element.scrollLeft == 0) element.scrollLeft = v; } catch (err) { } }, 500);
        window.setTimeout(function () { try { if (element.scrollLeft == 0) element.scrollLeft = v; } catch (err) { } }, 1000);
    }

    var _sizeHeightElements = new Array(0);
    var _sizeHeightElementsDelta = new Array(0);
    var _sizeWidthElements = new Array(0);
    var _sizeWidthElementsDelta = new Array(0);
    var _resizeUIHasRun = false;

    function addSizeHeightElements(id) { _sizeHeightElements.push(id); }
    function addSizeHeightElementsDelta(value) { _sizeHeightElementsDelta.push(value); }
    function addSizeWidthElements(id) { _sizeWidthElements.push(id); }
    function addSizeWidthElementsDelta(value) { _sizeWidthElementsDelta.push(value); }
    var resizeCallback = null;
    function resizeUIAll() {
        if (resizeCallback != null) window.clearTimeout(resizeCallback);
        resizeCallback = window.setTimeout(resizeUIAllNow, 500);
    }
    function resizeUIAllNow() {
        var wins = getAllWindows();
        for (var i in wins) {
            if (wins[i].WAF != null) {
                wins[i].WAF.ResizeUI();
            }
        }
        resizeCallback = null;
    }
    function resizeUI() {
        if (isMovingElement()) return;
        var i;
        for (i = 0; i < _sizeHeightElements.length; i++) {
            eval("WCH_" + _sizeHeightElements[i] + "(" + (windowHeight() - _sizeHeightElementsDelta[i]) + ");");
        }
        for (i = 0; i < _sizeWidthElements.length; i++) {
            eval("WCW_" + _sizeWidthElements[i] + "(" + (windowWidth() - _sizeWidthElementsDelta[i]) + ");");
        }
        _resizeUIHasRun = true;
    }



























    // *************************
    // KEY PRESS EVENTS
    // *************************
    var _shortCuts = new Array(255);
    var _shortCutsCtrl = new Array(255);
    var _shortCutsAlt = new Array(255);
    var _isCtrlPressed = false;
    var _isShiftPressed = false;
    var _isAltPressed = false;
    var _keyPressed = null;
    function registerShortCutKey(key, script) {
        _shortCuts[key] = script;
    }
    function registerShortCutKeyCtrl(key, script) {
        _shortCutsCtrl[key] = script;
    }
    function registerShortCutKeyAlt(key, script) {
        _shortCutsAlt[key] = script;
    }

    function onKeyDownHandler(evt) {
        hideToolTipNow();
        _isCtrlPressed = isCtrlPressed(evt);
        _isShiftPressed = isShiftPressed(evt);
        _isAltPressed = isAltPressed(evt);
        evt = evt || window.event;
        var keyCode = evt.keyCode || evt.which || 0;
        _keyPressed = keyCode;
        //trace("onKeyDownHandler:" + _keyPressed);
        updateDragIcon();
        if (_keyPressed == 27 && _sliderDragCancelCallback != null) cancelSliderDrag();
        if (_keyPressed == 27) {
            if (_generalDragCancelCallBack != null) _generalDragCancelCallBack(_generalDragStateInfo);
            _generalDragStateInfo = null;
            _sliderDragCancelCallback = null;
            _generalDragCallBack = null;
            _generalDragCompleteCallBack = null;
            _generalDragCancelCallBack = null;
        }

        if (keyCode && evt.ctrlKey) {
            if (evt.type == "keydown" && evt.keyCode != 17) {
                if (_shortCutsCtrl[keyCode] != null) {
                    _shortCutsCtrl[keyCode]();
                    return false;
                } else {
                    return true;
                }
            } else {
                return true;
            }
        }
        return true;
    }
    function onKeyPressHandler(evt) {
        _isCtrlPressed = isCtrlPressed(evt);
        _isShiftPressed = isShiftPressed(evt);
        _isAltPressed = isAltPressed(evt);
        evt = evt || window.event;
        var keyCode = evt.keyCode || evt.which || 0;
        _keyPressed = keyCode;
        //trace("onKeyPressHandler:" + _keyPressed);
        updateDragIcon();
        if (_shortCuts[keyCode] != null) {
            try {
                _shortCuts[keyCode]();
            } catch (err) {
            }
            return false;
        } else {
            return true;
        }
    }
    function onKeyUpHandler(evt) {
        _isCtrlPressed = false;
        _isShiftPressed = false;
        _isAltPressed = false;
        _keyPressed = null;
        updateDragIcon();
    }
    function isCtrlPressed(e) {
        if (e != null) return e.ctrlKey;
        return event.ctrlKey;
    }
    function isShiftPressed(e) {
        if (e != null) return e.shiftKey;
        return event.shiftKey;
    }
    function isAltPressed(e) {
        if (e != null) return e.altKey;
        return event.altKey;
    }

    // *************************
    // UI DIALOGUES
    // *************************
    var _windowIds = new Array(0);
    var _closingWindow = false;
    var _enableWindowUpdate = true;
    var _htmlChangeReg = new Object(); // register of update html, keeps track of changes

    var _updateSoonInterval = 100; // when system is expecting a new UI update soon (ie just after answering a dialogue)
    var _updateIntervalShort = 1500; // when something is happeing (dialogue or mouse move)
    var _updateIntervalLong = 10000; // when nothing is happening (no dialgues and no mouse move) -> idle state

    var _updateInterval = _updateIntervalShort + 0;
    function workflowUpdatePulse(repeat) {
        if (!_resizeUIHasRun) resizeUIAll();
        if (_enableWindowUpdate) {
            if (_ajaxRequestInProgressCount == 0) updateUI(null, true);
            if (repeat) window.setTimeout("WAF.WorkflowUpdatePulse(true);", _updateInterval);
        }
    }
    function oneWorkflowUpdatePulse(result) { workflowUpdatePulse(false); }
    function updateUISoon() { window.setTimeout("WAF.UpdateUI();", _updateSoonInterval); window.setTimeout("WAF.UpdateUI();", _updateSoonInterval * 2); window.setTimeout("WAF.UpdateUI();", _updateSoonInterval * 4); }
    function updateUISoonIfLongSinceLast() {
        if (new Date() - _lastSetUI > _updateIntervalShort) {
            _lastSetUI = new Date();
            _updateInterval = _updateIntervalShort;
            updateUISoon();
        }
    }
    function updateUI(params, async) {
        if (params == null) {
            params = getReportPostionsParams();
        } else {
            params = getReportPostionsParams() + "&" + params;
        }
        params += "&WAF_UI_ID=" + _requestId;
        if (async == null) async = true; // default...
        if (async) {
            ajaxRequest("UIUpdate", params, setUI, async);
        } else {
            setUI(ajaxRequest("UIUpdate", params, null, false));
        }
    }
    function getReportPostionsParams() {
        // report all window postions
        var wId = new Array(0);
        var wTop = new Array(0);
        var wLeft = new Array(0);
        var wHeight = new Array(0);
        var wWidth = new Array(0);
        var wLevel = new Array(0);
        var i;
        var element;
        for (i = 0; i < _windowIds.length; ++i) {
            element = document.getElementById(_windowIds[i]);
            if (element != null) {
                wId.push(_windowIds[i]);
                wTop.push(getElementY(element));
                wLeft.push(getElementX(element));
                var frameElement = document.getElementById(_windowIds[i] + "_iframe");
                if (frameElement != null) {
                    wHeight.push(frameElement.clientHeight);
                    wWidth.push(frameElement.clientWidth);
                } else {
                    wHeight.push(0);
                    wWidth.push(0);
                }
                wLevel.push(element.style.zIndex);
            }
        }
        var params = new Array();
        for (i = 0; i < wTop.length; ++i) {
            if (params.length > 0) params.push("&");
            params.push("Id=")
            params.push(wId[i]);
            params.push("&TopPx=")
            params.push(wTop[i]);
            params.push("&LeftPx=")
            params.push(wLeft[i]);
            params.push("&HeightPx=")
            params.push(wHeight[i]);
            params.push("&WidthPx=")
            params.push(wWidth[i]);
            params.push("&Level=")
            params.push(wLevel[i]);
        }
        params.push("&ClientWindowHeight=")
        params.push(windowHeight());
        params.push("&ClientWindowWidth=")
        params.push(windowWidth());
        if (_setScrollQue != null) {
            params.push(_setScrollQue);
            _setScrollQue = null;
        }
        return params.join("");
    }
    function getAllElementsFromOpenWindows(elementId) {
        var els = new Array();
        var el;
        el = _desktopWindow.document.getElementById(elementId);
        if (el != null) els.push(el);
        for (var i = 0; i < _windowIds.length; ++i) {
            var frameElement = document.getElementById(_windowIds[i] + "_iframe");
            if (frameElement != null) {
                el = frameElement.contentWindow.document.getElementById(elementId);
                if (el != null) els.push(el);
            }
        }
        return els;
    }
    var _lastSetUI;
    var _desktopWindow = window;
    function setDesktopWindow(desktopWindow) {
        _desktopWindow = desktopWindow;
    }
    function getAllWindows() {
        var wins = new Array();
        wins.push(window);
        if (_desktopWindow != null) wins.push(_desktopWindow);
        for (var i = 0; i < _windowIds.length; ++i) {
            var frameElement = document.getElementById(_windowIds[i] + "_iframe");
            if (frameElement != null) wins.push(frameElement.contentWindow);
        }
        return wins;
    }
    function tryGetWindow(windowId, requestId) {
        if (windowId == null && requestId == null) return _desktopWindow;
        var wins = getAllWindows();
        for (var i in wins) {
            var w = wins[i];
            if (w.WAF != null) {
                if (requestId != null) {
                    if (w.WAF.RequestId == requestId) return w;
                } else {
                    if (w.WAF.WindowId == windowId) return w;
                }
            }
        }
        return null;
    }

    function tryExecuteCodeInWindow(windowId, requestId, script, tries) {
        if (tries == null) tries = 0;
        if (tries > 10) return // give up...
        var theWindow = tryGetWindow(windowId, requestId);
        if (theWindow != null) {
            theWindow.eval(script);
        } else {
            tries++;
            window.setTimeout(function () { tryExecuteCodeInWindow(windowId, requestId, script, tries); }, 300);
        }
    }

    function setUI(ui) {
        if (ui.Valid == null) return;
        _lastSetUI = new Date();
        var found;
        // perform ui actions
        var i;
        if (ui.UIAction != null) {
            for (i = 0; i < ui.UIAction.Count; i++) {
                var script = ui.UIAction["Script" + i];
                var requestId = ui.UIAction["Request" + i];
                var windowId = ui.UIAction["Window" + i];
                tryExecuteCodeInWindow(windowId, requestId, script);
            }
        }
        // submit completed workflows
        if (ui.CompletedWorkflows != null) {
            for (i = 0; i < ui.CompletedWorkflows.length; i++) {
                if (_workflowStartUpGuids[ui.CompletedWorkflows[i]] != null) {
                    var res = ui["CompletedWorkflowsResult" + i];
                    var onComplete = _workflowStartUpGuids[ui.CompletedWorkflows[i]];
                    _workflowStartUpGuids[ui.CompletedWorkflows[i]] = null;
                    onComplete(res);
                }
            }
        }
        if (new Date() - _lastMouseMove > _updateIntervalLong && ui.NoWindows == 0) {
            _updateInterval = _updateIntervalLong;
        } else {
            _updateInterval = _updateIntervalShort;
        }

        // open or update existing windows
        for (i = 0; i < ui.NoWindows; i++) {
            var w = ui["Window" + i];
            var showWindow = true;
            if (_closedDialogues[w.Id] != null) {
                if (new Date() - _closedDialogues[w.Id] < 3000) {
                    // if the window was closed less than two sec. ago. 
                    // Do not open it as it is probably open just because close exchange has not reached the server yet
                    showWindow = false;
                } else {
                    _closedDialogues[w.Id] = null;
                }
            }
            if (showWindow) {
                if (w.WindowType == "PROGRESS") {
                    if (document.getElementById(w.Id) == null) {
                        var html = "";
                        for (var r = 0; r < w.Html.length; ++r) { // concat html
                            html = html + w.Html[r];
                        }
                        _htmlChangeReg[w.Id + "_Icon"] = w.Html[1];
                        _htmlChangeReg[w.Id + "_Caption"] = w.Html[3];
                        _htmlChangeReg[w.Id + "_Description"] = w.Html[5];
                        _htmlChangeReg[w.Id + "_Progress"] = w.Html[7];
                        _htmlChangeReg[w.Id + "_Buttons"] = w.Html[9];
                        openDialogue(w.Id, html, w.Title, w.MinScript, w.TopPx, w.LeftPx, w.Modal == "YES"); // not already open so open new
                    } else {
                        updateElementIfChanged(w.Id + "_Icon", w.Html[1]);
                        updateElementIfChanged(w.Id + "_Caption", w.Html[3]);
                        updateElementIfChanged(w.Id + "_Description", w.Html[5]);
                        updateElementIfChanged(w.Id + "_Progress", w.Html[7]);
                        updateElementIfChanged(w.Id + "_Buttons", w.Html[9]);
                    }
                    WAF_InitProgress(w.Id + "_prg", w.PercentageEstimated, '100', w.PercentagePerMS, 400); // script to start progressbar movement
                } else if (w.WindowType == "NO-UPDATE") {
                    openDialogue(w.Id, w.Html, w.Title, w.MinScript, w.TopPx, w.LeftPx, w.Modal == "YES"); // not already open so open new
                }
            }
        }
        // close old windows:
        for (o = 0; o < _windowIds.length; ++o) {
            found = false;
            for (i = 0; i < ui.NoWindows; i++) {
                if (ui["Window" + i].Id == _windowIds[o]) found = true;
            }
            if (!found) closeDialogue(_windowIds[o]);
        }
        // update footer
        if (ui.Footer != null) {
            updateElementIfChanged("WAF_Footer", ui.Footer.Html);
            if ((ui.Footer.Script + "").length > 0) _desktopWindow.eval(ui.Footer.Script);
        }
        updateModalBackground(ui.Modal == "YES");
    }
    function updateElementIfChanged(elementId, newHtml) {
        var element = document.getElementById(elementId);
        var htmlChangeReg = _htmlChangeReg;
        if (element == null) {
            element = _desktopWindow.document.getElementById(elementId);
            if (_desktopWindow._htmlChangeReg == null) _desktopWindow._htmlChangeReg = new Object();
            htmlChangeReg = _desktopWindow._htmlChangeReg;
        }
        if (element != null) {
            if (htmlChangeReg[elementId] != newHtml) {
                htmlChangeReg[elementId] = newHtml;
                element.innerHTML = newHtml;
            }
        }
    }

    function openDialogue(id, html, title, minButtScript, top, left, modal) {
        var element = document.getElementById(id);
        if (element == null) { // only open window if element does not already exist..
            _windowIds.push(id);
            var level = _windowIds.length;
            element = document.createElement("div");
            element.setAttribute("id", id);
            element.setAttribute("className", "WAF_DialogueWindow");
            var windowHtml = new Array();
            windowHtml.push("<table onmousedown='WAF.MoveWindowToFront(\"" + id + "\");' border=0 cellpadding=0 cellspacing=0 class='WAF_DialogueWindow_OuterTable'>");
            windowHtml.push("<tr >");
            windowHtml.push("<td class='WAF_DialogueWindow_A1' onmousedown='WAF.StartWindowResize(\"" + id + "\",-1,1);'><div class='WAF_DialogueWindow_A1'></div></td>");
            windowHtml.push("<td style='cursor:move' colspan=2 class='WAF_DialogueWindow_A2'>");
            if (minButtScript != null) {
                //if(_desktopWindow.document.getElementById("WAF_Footer")!=null){
                if (minButtScript.length > 0 && !modal) {
                    windowHtml.push("<div style='float:right' class='WAF_DialogueWindow_MinButt1' ");
                    windowHtml.push(" onmousedown=\"" + minButtScript + "; return false;\"></div>");
                }
                //}
            }
            windowHtml.push("<div class='WAF_DialogueWindow_Title' id='" + id + "_Title' onmousedown='WAF.SetMovingElement(document.getElementById(\"" + id + "\")); WAF.SetMoveCompleteScript(\";\");WAF.MoveWindowToFront(WAF.GetMovingElement.id);'>" + title + "</div></td>");
            windowHtml.push("<td class='WAF_DialogueWindow_A3' onmousedown='WAF.StartWindowResize(\"" + id + "\",1,1);'><div class='WAF_DialogueWindow_A3'></div></td>");
            windowHtml.push("</tr>");

            windowHtml.push("<tr>");
            windowHtml.push("<td class='WAF_DialogueWindow_B1' onmousedown='WAF.StartWindowResize(\"" + id + "\",-1,0);'></td>");
            windowHtml.push("<td colspan=2 class='WAF_DialogueWindow_B2' id='" + id + "_Content' >" + html + "</td>");
            windowHtml.push("<td class='WAF_DialogueWindow_B3' onmousedown='WAF.StartWindowResize(\"" + id + "\",1,0);'>&nbsp;</td>");
            windowHtml.push("</tr>");

            windowHtml.push("<tr>");
            windowHtml.push("<td class='WAF_DialogueWindow_C1' onmousedown='WAF.StartWindowResize(\"" + id + "\",-1,-1);'> </td>");
            windowHtml.push("<td colspan=2 class='WAF_DialogueWindow_C2' onmousedown='WAF.StartWindowResize(\"" + id + "\",0,-1);'> </td>");
            windowHtml.push("<td class='WAF_DialogueWindow_C3' onmousedown='WAF.StartWindowResize(\"" + id + "\",1,-1);'> </td>");
            windowHtml.push("</tr>");

            windowHtml.push("</table>");

            element.innerHTML = windowHtml.join("");
            element.style.zIndex = level + 10;

            element.style.top = top;
            element.style.left = left;
            element.style.position = "absolute";

            var valueElement = document.createElement("input");
            valueElement.type = "hidden";
            valueElement.id = id + "_ResultValue";
            valueElement.style.width = "200px";
            document.body.appendChild(element);
            element.appendChild(valueElement);
            fadeIn(element);

        }
    }
    function updateModalBackground(modal) {
        if (!modal) {
            var mp = document.getElementById("WAF_modal_panel");
            if (mp != null) document.body.removeChild(mp);
        } else {
            var modalElement = document.getElementById("WAF_modal_panel");
            if (modalElement == null) {
                modalElement = document.createElement("div");
                modalElement.setAttribute("id", "WAF_modal_panel");
                modalElement.style.zIndex = 1;
                modalElement.style.height = "100%";
                modalElement.style.width = "100%";
                modalElement.style.backgroundColor = "#FFFFFF";
                alwaysSetElementOpacity(modalElement, 60);
                modalElement.style.position = "fixed";
                modalElement.style.top = "0";
                modalElement.style.left = "0";
                document.body.appendChild(modalElement);
            }
        }
    }
    function startWindowResize(windowId, ddX, ddY) {
        var stateInfo = new Object();
        stateInfo.windowId = windowId;
        stateInfo.borderWidth = 6;
        var dWindow = document.getElementById(windowId);
        var element = document.createElement("div");
        element.style.backgroundColor = "#DDDDDD";
        element.style.border = "solid " + stateInfo.borderWidth + "px #777777";
        element.style.top = getElementY(dWindow) + "px";
        element.style.left = getElementX(dWindow) + "px";
        element.style.width = dWindow.offsetWidth - (stateInfo.borderWidth * 2) + "px";
        element.style.height = dWindow.offsetHeight - (stateInfo.borderWidth * 2) + "px";
        element.style.position = "absolute";
        element.style.opacity = "0.2";

        var filter = "alpha(Opacity=0, FinishOpacity=40, Style=1, "
        if (ddX == 1) {
            filter += "StartX=0, FinishX=100";
        } else if (ddX == -1) {
            filter += "StartX=100, FinishX=0";
        } else {
            filter += "StartX=0, FinishX=0";
        }
        if (ddY == 1) {
            filter += ", StartY=100, FinishY=0)";
        } else if (ddY == -1) {
            filter += ", StartY=0, FinishY=100)";
        } else {
            filter += ", StartY=0, FinishY=0)";
        }
        element.style.filter = filter;
        element.style.zIndex = 100;
        document.body.appendChild(element);
        stateInfo.element = element;

        stateInfo.iX = element.offsetWidth;
        stateInfo.iY = element.offsetHeight;
        stateInfo.x = getElementX(element);
        stateInfo.y = getElementY(element);
        stateInfo.ddX = ddX;
        stateInfo.ddY = ddY;

        startGeneralDrag(stateInfo, onWRDrag, onWRDragComplete, onWRDragCancel);
    }
    function onWRDrag(stateInfo, dx, dy) {
        if ((stateInfo.iX + stateInfo.ddX * dx) < 500) dx = (500 - stateInfo.iX) / stateInfo.ddX;
        if ((stateInfo.iY + stateInfo.ddY * dy) < 150) dy = (150 - stateInfo.iY) / stateInfo.ddY;
        stateInfo.element.style.width = -(stateInfo.borderWidth * 2) + (stateInfo.iX + stateInfo.ddX * dx) + "px";
        stateInfo.element.style.height = -(stateInfo.borderWidth * 2) + (stateInfo.iY + stateInfo.ddY * dy) + "px";
        if (stateInfo.ddX < 0) stateInfo.element.style.left = stateInfo.x + dx + "px";
        if (stateInfo.ddY > 0) stateInfo.element.style.top = stateInfo.y - dy + "px";
    }
    function onWRDragComplete(stateInfo, dx, dy) {
        if ((stateInfo.iX + stateInfo.ddX * dx) < 500) dx = (500 - stateInfo.iX) / stateInfo.ddX;
        if ((stateInfo.iY + stateInfo.ddY * dy) < 150) dy = (150 - stateInfo.iY) / stateInfo.ddY;
        var dialogue = document.getElementById(stateInfo.windowId);
        dialogue.style.left = getElementX(stateInfo.element) + "px";
        dialogue.style.top = getElementY(stateInfo.element) + "px";
        var dialogueWindowFrame = tryGetWindow(stateInfo.windowId).frameElement;
        dialogueWindowFrame.style.width = dialogueWindowFrame.offsetWidth + stateInfo.ddX * dx + "px";
        dialogueWindowFrame.style.height = dialogueWindowFrame.offsetHeight + stateInfo.ddY * dy + "px";
        document.body.removeChild(stateInfo.element);
    }
    function onWRDragCancel(stateInfo) {
        if (stateInfo.iX != null) stateInfo.window.style.width = stateInfo.iX + "px";
        if (stateInfo.iY != null) stateInfo.window.style.height = stateInfo.iY + "px";
    }
    var _closedDialogues = new Object();
    function closeDialogue(id) {
        _closedDialogues[id] = new Date();
        var element = document.getElementById(id);
        var new_windowIds = new Array(0); // new array holding only open windows
        if (element != null) {
            var currLevel = element.style.zIndex;
            for (i = 0; i < _windowIds.length; ++i) {
                if (id != _windowIds[i]) {
                    var winEl = document.getElementById(_windowIds[i]);
                    if (winEl != null) {
                        new_windowIds.push(_windowIds[i]);
                        if (winEl.style.zIndex > currLevel) winEl.style.zIndex = winEl.style.zIndex - 1; // update level list
                    }
                }
            }
            _closingWindow = true;
            fadeOut(element, true);
            _closingWindow = false;
        } else {
            for (i = 0; i < _windowIds.length; ++i) {
                if (id != _windowIds[i]) new_windowIds.push(_windowIds[i]);
            }
        }
        _windowIds = new_windowIds;
    }

    function moveWindowToFront(id) {
        var element = document.getElementById(id);
        if (element != null) {
            // moving others back one
            var elW;
            var currentLevel = element.style.zIndex;
            for (i = 0; i < _windowIds.length; ++i) {
                elW = document.getElementById(_windowIds[i]);
                if (elW != null) {
                    if (elW.style.zIndex > currentLevel) elW.style.zIndex = elW.style.zIndex - 1;
                }
            }
            // moving this to the front
            element.style.zIndex = _windowIds.length + 10;
        }
    }













    // *************************
    // WORKFLOWS
    // *************************

    function startWorkflowMethod(workflowMethod, params, onComplete, modal, inBackground, confirmQuestion, assemblyHint, pageRequestId, windowId) {
        if (pageRequestId == null) pageRequestId = _requestId;
        params = WAF_CreateClientRequestFromObject(params);
        params.AddString("WorkflowMethodTypeName", workflowMethod);
        if (confirmQuestion != null) params.AddString("ConfirmQuestion", confirmQuestion);
        startWorkflow('WAF.Engine.Workflow.WorkflowMethodCaller', params, onComplete, modal, inBackground, assemblyHint, pageRequestId, windowId);
    }
    function startWorkflow(workflow, params, onComplete, modal, inBackground, assemblyHint, pageRequestId, windowId) {
        if (pageRequestId == null) pageRequestId = _requestId;
        if (windowId == null) windowId = _windowId;
        if (assemblyHint == null) assemblyHint = _pageAssemblyName;
        assemblyHint = escape(assemblyHint);
        var startUpGuid;
        if (workflow.indexOf("-") > 0) { // Param Guid (type and other params set serverside)
            startUpGuid = workflow;
            if (onComplete != null) _workflowStartUpGuids[startUpGuid] = onComplete;
            updateUISoon();
            if (params == null) params = "";
            updateUI("StartWorkflowPageRequestId=" + pageRequestId + "&StartWorkflowWindowId=" + windowId + "&StartWorkflowParamsId=" + workflow + "&" + params.toString(), false);
        } else { // Start by typename (all params set client side)
            params = WAF_CreateClientRequestFromObject(params);
            typeName = workflow;
            if (typeName.indexOf(".") == -1) typeName = "WAF.Engine.Workflow." + typeName;
            var querystring = "StartWorkflowPageRequestId=" + pageRequestId + "&StartWorkflowWindowId=" + windowId + "&WorkflowTypeName=" + typeName + "&AssemblyHint=" + assemblyHint;
            if (params != null) querystring = querystring + "&" + params;
            if (modal) querystring = querystring + "&Modal=true";
            if (inBackground) querystring = querystring + "&InBackground=true";
            var cr = ajaxRequest("StartWorkflowFromTypeName", querystring, null, false);
            startUpGuid = cr.StartWorkflowParamsId;
            if (onComplete != null) _workflowStartUpGuids[startUpGuid] = onComplete;
            setUI(cr);
            updateUISoon();
        }
        // store on complete script, will be evaluated on workflow complete... usually a postback causing a complete event on the workflow control
        return startUpGuid;
    }
    //function startWorkflowControl(controlId,params){
    //    if(params!=null)params=params.toString().replace("'","\'");
    //    eval("WAF_StartWorkflowControl_" + controlId + "('" + params + "');");   
    //}
    function terminateWorkflow(id, reason) { ajaxRequest("TerminateWorkflow", "Id=" + id + "&Reason=" + escape(reason), null, false); updateUISoon(); }
    function suspendWorkflow(id, reason) { ajaxRequest("SuspendWorkflow", "Id=" + id + "&Reason=" + escape(reason)); updateUISoon(); }
    function resumeWorkflow(id) { ajaxRequest("ResumeWorkflow", "Id=" + id); }
    function sendExchange(id, result) {
        if (result == null) result = "OK";
        var resultValue = document.getElementById(id + "_ResultValue").value;
        sendExchangeValue(id, result, resultValue);
    }
    function sendExchangeValue(id, result, resultValue) {
        closeDialogue(id);
        ajaxRequest("SendExchangeValue", "Id=" + id + "&Result=" + result + "&ResultValue=" + escape(resultValue), null, true);
        updateUISoon();
    }
    function closeExchange(id) { closeDialogue(id); ajaxRequest("CloseExchange", "Id=" + id); }
    function closeProgress(id) { closeDialogue(id); ajaxRequest("CloseProgress", "Id=" + id); }
    function openExchange(id) { ajaxRequest("OpenExchange", "Id=" + id); updateUISoon(); }
    function openProgress(id) { ajaxRequest("OpenProgress", "Id=" + id); updateUISoon(); }

    function notify(caption, message, icon) {
        if (caption == null) caption = "";
        if (message == null) message = "";
        if (icon == null) icon = "Info";
        var params = new WAF_ClientRequest();
        params.AddString("Caption", caption);
        params.AddString("Message", message);
        params.AddDialogueIcon("Icon", icon);
        ajaxRequest("Notify", params.toString(), null, true);
        updateUISoon();
    }
    function ask(caption, question, onAnswer, buttons, icon, title) {
        if (caption == null) caption = "";
        if (question == null) question = "";
        if (icon == null) icon = "Question";
        if (title == null) title = "Question";
        if (buttons == null) buttons = "YesNo";
        var params = new WAF_ClientRequest();
        params.AddString("Caption", caption);
        params.AddString("Question", question);
        params.AddString("Title", title);
        params.AddUIButtons("Buttons", buttons);
        params.AddDialogueIcon("Icon", icon);
        startWorkflow("Ask", params, function (result) { onAnswer(result.Answer); }, null, true, true);
    }












    // *************************
    // DRAG DROP AND MOUSE
    // *************************
    var _allRules = new Array();
    var _rulesById = new Object();
    var _sourceHasDropTarget = new Object();
    var _mouseButtonIsPressed = false;
    var _mouseDownX = 0;
    var _mouseDownY = 0;
    var _mouseUpX = 0;
    var _mouseUpY = 0;
    var _mouseLastX = 0;
    var _mouseLastY = 0;
    var _mouseLastXRelWindow;
    var _mouseLastYRelWindow;
    var _mouseLastDragX = 0;
    var _mouseLastDragY = 0;
    var _dragDistance = 0;
    var _dragDistanceX = 0;
    var _dragDistanceY = 0;
    var _dropTargetInfo = null;
    var _dragSourceInfo = null;
    var _dropTargetScript = "";
    var _dropAction = "";
    var _moveCompleteScript = "";
    var _movingElement = null;
    var _dropCallback = null;
    var _moveStartOffsetX = 0;
    var _moveStartOffsetY = 0;
    var _mouseDragScript = null;
    var _workflowStartUpGuids = new Object();
    var _dragStartDistanceLimit = 2;
    var _dragIconElement;
    var _sliderDragCallback;
    var _sliderDragEndCallback;
    var _sliderDragCancelCallback;
    var _dragElementIconAbove;
    var _dragElementIconBelow;
    var _dragElementIconBetween;
    var _dragElementIconOver;
    var _dragElementIconAll;
    var _dragElementIconMove;
    var _dragElementIconCopy;
    var _dragElementIconRemove;
    var _dragElementIconNone;
    var _orgDocumentBodyStyleOverflow = "";
    var _dragStartScript = null;
    var _aboveNextEqualsBelowPrevious;
    var _noItems = 0;
    function mouseDown(e) {
        _mouseButtonIsPressed = true;
        hideToolTipNow();
        if (_movingElement != null) {
            if (!_closingWindow) {
                setElementOpacity(_movingElement, 70);
            }
            disableSelect();
            _moveStartOffsetX = getMouseElementOffsetX(e);
            _moveStartOffsetY = getMouseElementOffsetY(e);
            return false;
        }
        if (_generalDragCallBack != null) disableSelect();
        _mouseDownX = getMouseX(e);
        _mouseDownY = getMouseY(e);
        if (_disableNextRightClickMenu) {
            return false;
        }
    }
    function getDragDistance() {
        if (_mouseButtonIsPressed) {
            return _dragDistance;
        } else {
            return 0;
        }
    }
    function getShouldBeginDragNow() {
        if (_movingElement != null) return false;
        return getDragDistance() > _dragStartDistanceLimit;
    }
    _lastMouseMove = new Date();
    this.GetMouseX = function () { return _mouseLastX; }
    this.GetMouseY = function () { return _mouseLastY; }
    function mouseMove(e) {
        var newX = getMouseX(e);
        var newY = getMouseY(e);
        if (newX + "_" + newY != _mouseLastX + "_" + _mouseLastY) {
            _lastMouseMove = new Date();
            updateUISoonIfLongSinceLast();
        }
        _mouseLastX = newX;
        _mouseLastY = newY;
        _mouseLastXRelWindow = getMouseXRelWindow(e);
        _mouseLastYRelWindow = getMouseYRelWindow(e);
        if (_mouseButtonIsPressed) {
            _mouseLastDragX = _mouseLastX;
            _mouseLastDragY = _mouseLastY;
            _dragDistanceX = _mouseLastDragX - _mouseDownX;
            _dragDistanceY = _mouseDownY - _mouseLastDragY;
            _dragDistance = Math.round(Math.sqrt(_dragDistanceX * _dragDistanceX + _dragDistanceY * _dragDistanceY));
            if (_sliderDragCallback != null) callSliderDrag(_dragDistanceX, _dragDistanceY);
            if (_generalDragCallBack != null) _generalDragCallBack(_generalDragStateInfo, _dragDistanceX, _dragDistanceY);
        }
        if (_mouseDragScript != null) eval(_mouseDragScript);
        if (_movingElement != null) {
            updateDragIcon(e);
            setElementXY(_movingElement, getMouseX(e) - _moveStartOffsetX, getMouseY(e) - _moveStartOffsetY);
            if (_browserIsOpera) _movingElement.focus(); // prevents text selection
            return false;
        }
        if (_generalDragCallBack != null) return false;
        if (getShouldBeginDragNow()) {
            if (_dragStartScript != null)
                try {
                    _dragStartScript(e);
                } catch (err) {
                }
        }
    }
    function mouseUp(e) {
        _mouseUpX = getMouseX(e);
        _mouseUpY = getMouseY(e);
        if (_movingElement != null) {
            if (_browserIsFirefox) { // disable design mode to enable window events
                for (var n in _editorFrames) {
                    try {
                        _editorFrames[n].contentDocument.designMode = 'on';
                    } catch (err) {
                    }
                }
            }
            if (_dragSourceInfo != null) {
                _dragSourceInfo.OnDragComplete(_dragSourceInfo, _dropTargetInfo, _dropAction, _currentDragIcon);
                _dragSourceInfo = null;
                _dropTargetInfo = null;
                _dropAction = null;
            }
            if (_dropTargetScript.length > 0) {
                eval(_dropTargetScript);
                _dropTargetScript = "";
            }
            if (_moveCompleteScript.length > 0) {
                eval(_moveCompleteScript);
                _moveCompleteScript = "";
            }
            if (!_closingWindow) {
                setElementOpacity(_movingElement, 100);
            }
        }
        if (_sliderDragEndCallback != null) endSliderDrag();
        if (_generalDragCompleteCallBack != null) {
            _generalDragCompleteCallBack(_generalDragStateInfo, _dragDistanceX, _dragDistanceY);
            if (_browserIsFirefox) { // disable design mode to enable window events
                for (var nn in _editorFrames) {
                    try {
                        _editorFrames[nn].contentDocument.designMode = 'on';
                    } catch (err) {
                    }
                }
            }
            _generalDragStateInfo = null;
            _generalDragCallBack = null;
            _generalDragCompleteCallBack = null;
            _generalDragCancelCallBack = null;
        }
        _movingElement = null;
        _mouseDragScript = null;
        _moveCompleteScript = "";
        _dragStartScript = null;
        _mouseButtonIsPressed = false;
        _moveStartOffsetY = 0;
        _moveStartOffsetX = 0;
        //if(!_browserIsExplorer) document.body.style.overflow = _orgDocumentBodyStyleOverflow;
        return true;
    }
    function isMovingElement() { return _movingElement != null; }

    function registerDragStartScript(func) {
        _dragStartScript = func;
    }

    var _generalDragCallBack = null;
    var _generalDragCancelCallBack = null;
    var _generalDragCompleteCallBack = null;
    var _generalDragStateInfo = null;
    function isGeneralDragInProgress() {
        return _generalDragCallBack != null;
    }
    function startGeneralDrag(stateInfo, dragCallBack, dragCompleteCallBack, dragCancelCallBack) {
        if (_browserIsFirefox) { // disable design mode to enable window events
            for (var n in _editorFrames) {
                try {
                    _editorFrames[n].contentDocument.designMode = 'off';
                } catch (err) {
                }
            }
        }
        _generalDragStateInfo = stateInfo;
        _generalDragCallBack = dragCallBack;
        _generalDragCompleteCallBack = dragCompleteCallBack;
        _generalDragCancelCallBack = dragCancelCallBack;
    }
    var _sliderCallbackArgs;
    function startSliderDrag() {
        _sliderCallbackArgs = new Array();
        for (var n = 0; n < arguments.length - 3; n++) _sliderCallbackArgs.push(arguments[n]);
        _sliderDragCallback = arguments[arguments.length - 3];
        _sliderDragCancelCallback = arguments[arguments.length - 2];
        _sliderDragEndCallback = arguments[arguments.length - 1];
        disableSelect();
        callSliderDrag(0, 0);
    }
    function callSliderDrag(dx, dy) {
        if (_sliderCallbackArgs.length == 0) _sliderDragCallback(dx, dy);
        else if (_sliderCallbackArgs.length == 1) _sliderDragCallback(_sliderCallbackArgs[0], dx, dy);
        else if (_sliderCallbackArgs.length == 2) _sliderDragCallback(_sliderCallbackArgs[0], _sliderCallbackArgs[1], dx, dy);
        else if (_sliderCallbackArgs.length == 3) _sliderDragCallback(_sliderCallbackArgs[0], _sliderCallbackArgs[1], _sliderCallbackArgs[2], dx, dy);
        else if (_sliderCallbackArgs.length == 4) _sliderDragCallback(_sliderCallbackArgs[0], _sliderCallbackArgs[1], _sliderCallbackArgs[2], _sliderCallbackArgs[3], dx, dy);
        else if (_sliderCallbackArgs.length == 5) _sliderDragCallback(_sliderCallbackArgs[0], _sliderCallbackArgs[1], _sliderCallbackArgs[2], _sliderCallbackArgs[3], _sliderCallbackArgs[4], dx, dy);
        else if (_sliderCallbackArgs.length == 6) _sliderDragCallback(_sliderCallbackArgs[0], _sliderCallbackArgs[1], _sliderCallbackArgs[2], _sliderCallbackArgs[3], _sliderCallbackArgs[4], _sliderCallbackArgs[5], dx, dy);
        else if (_sliderCallbackArgs.length == 7) _sliderDragCallback(_sliderCallbackArgs[0], _sliderCallbackArgs[1], _sliderCallbackArgs[2], _sliderCallbackArgs[3], _sliderCallbackArgs[4], _sliderCallbackArgs[5], _sliderCallbackArgs[6], dx, dy);
        else alert("To many _sliderCallbackArgs in slider callback!");
    }
    function endSliderDrag() {
        if (_sliderCallbackArgs.length == 0) _sliderDragEndCallback();
        else if (_sliderCallbackArgs.length == 1) _sliderDragEndCallback(_sliderCallbackArgs[0]);
        else if (_sliderCallbackArgs.length == 2) _sliderDragEndCallback(_sliderCallbackArgs[0], _sliderCallbackArgs[1]);
        else if (_sliderCallbackArgs.length == 3) _sliderDragEndCallback(_sliderCallbackArgs[0], _sliderCallbackArgs[1], _sliderCallbackArgs[2]);
        else if (_sliderCallbackArgs.length == 4) _sliderDragEndCallback(_sliderCallbackArgs[0], _sliderCallbackArgs[1], _sliderCallbackArgs[2], _sliderCallbackArgs[3]);
        else if (_sliderCallbackArgs.length == 5) _sliderDragEndCallback(_sliderCallbackArgs[0], _sliderCallbackArgs[1], _sliderCallbackArgs[2], _sliderCallbackArgs[3], _sliderCallbackArgs[4]);
        else if (_sliderCallbackArgs.length == 6) _sliderDragEndCallback(_sliderCallbackArgs[0], _sliderCallbackArgs[1], _sliderCallbackArgs[2], _sliderCallbackArgs[3], _sliderCallbackArgs[4], _sliderCallbackArgs[5]);
        else if (_sliderCallbackArgs.length == 7) _sliderDragEndCallback(_sliderCallbackArgs[0], _sliderCallbackArgs[1], _sliderCallbackArgs[2], _sliderCallbackArgs[3], _sliderCallbackArgs[4], _sliderCallbackArgs[5], _sliderCallbackArgs[6]);
        _sliderDragCallback = null;
        _sliderDragCancelCallback = null;
        _sliderDragEndCallback = null;
    }
    function cancelSliderDrag() {
        if (_sliderCallbackArgs.length == 0) _sliderDragCancelCallback();
        else if (_sliderCallbackArgs.length == 1) _sliderDragCancelCallback(_sliderCallbackArgs[0]);
        else if (_sliderCallbackArgs.length == 2) _sliderDragCancelCallback(_sliderCallbackArgs[0], _sliderCallbackArgs[1]);
        else if (_sliderCallbackArgs.length == 3) _sliderDragCancelCallback(_sliderCallbackArgs[0], _sliderCallbackArgs[1], _sliderCallbackArgs[2]);
        else if (_sliderCallbackArgs.length == 4) _sliderDragCancelCallback(_sliderCallbackArgs[0], _sliderCallbackArgs[1], _sliderCallbackArgs[2], _sliderCallbackArgs[3]);
        else if (_sliderCallbackArgs.length == 5) _sliderDragCancelCallback(_sliderCallbackArgs[0], _sliderCallbackArgs[1], _sliderCallbackArgs[2], _sliderCallbackArgs[3], _sliderCallbackArgs[4]);
        else if (_sliderCallbackArgs.length == 6) _sliderDragCancelCallback(_sliderCallbackArgs[0], _sliderCallbackArgs[1], _sliderCallbackArgs[2], _sliderCallbackArgs[3], _sliderCallbackArgs[4], _sliderCallbackArgs[5]);
        else if (_sliderCallbackArgs.length == 7) _sliderDragCancelCallback(_sliderCallbackArgs[0], _sliderCallbackArgs[1], _sliderCallbackArgs[2], _sliderCallbackArgs[3], _sliderCallbackArgs[4], _sliderCallbackArgs[5], _sliderCallbackArgs[6]);
        _sliderDragCallback = null;
        _sliderDragCancelCallback = null;
        _sliderDragEndCallback = null;
    }
    function startDrag(dragSourceInfo) {
        _dragSourceInfo = dragSourceInfo;
        if (_browserIsFirefox) { // disable design mode to enable window events
            for (var n in _editorFrames) {
                try {
                    _editorFrames[n].contentDocument.designMode = 'off';
                } catch (err) {
                }
            }
        }
        if (!_browserIsExplorer) {
            //       _orgDocumentBodyStyleOverflow = document.body.style.overflow + "";
            //        if(_orgDocumentBodyStyleOverflow.length==0)_orgDocumentBodyStyleOverflow="auto";
            //        document.body.style.overflow="hidden";
        }
        var dragElementContent = document.createElement("div");
        dragElementContent.innerHTML = dragSourceInfo.Html;
        dragElementContent.className = "WAF_DragContent";
        dragElementContent.style.margin = "30px 0px 0px 0px";

        //dragElementContent.style.filter = "alpha(opacity=70)";
        dragElementContent.style.opacity = "0.7";

        var dragElement = document.createElement("div");
        dragElement.style.position = "absolute";
        dragElement.style.margin = "5px 0px 0px 5px";

        _dragElementIconAbove = document.createElement("div");
        _dragElementIconAbove.className = "WAF_IconDropAbove";
        dragElement.appendChild(_dragElementIconAbove);

        _dragElementIconOver = document.createElement("div");
        _dragElementIconOver.className = "WAF_IconDropOver";
        dragElement.appendChild(_dragElementIconOver);

        _dragElementIconBelow = document.createElement("div");
        _dragElementIconBelow.className = "WAF_IconDropBelow";
        dragElement.appendChild(_dragElementIconBelow);

        _dragElementIconAll = document.createElement("div");
        _dragElementIconAll.className = "WAF_IconDropAll";
        dragElement.appendChild(_dragElementIconAll);

        _dragElementIconMove = document.createElement("div");
        _dragElementIconMove.className = "WAF_IconDropMove";
        dragElement.appendChild(_dragElementIconMove);

        _dragElementIconBetween = document.createElement("div");
        _dragElementIconBetween.className = "WAF_IconDropBetween";
        dragElement.appendChild(_dragElementIconBetween);

        _dragElementIconCopy = document.createElement("div");
        _dragElementIconCopy.className = "WAF_IconDropCopy";
        dragElement.appendChild(_dragElementIconCopy);

        _dragElementIconRemove = document.createElement("div");
        _dragElementIconRemove.className = "WAF_IconDropRemove";
        dragElement.appendChild(_dragElementIconRemove);

        _dragElementIconNone = document.createElement("div");
        _dragElementIconNone.className = "WAF_IconDropNone";
        dragElement.appendChild(_dragElementIconNone);

        dragElement.appendChild(dragElementContent);
        setElementXY(dragElement, _mouseLastDragX, _mouseLastDragY);

        alwaysSetElementOpacity(_movingElement, 70);

        dragElement.style.zIndex = 100;

        document.body.appendChild(dragElement);
        _movingElement = dragElement;
        _moveCompleteScript = "_movingElement.parentNode.removeChild(_movingElement);";
        _dropAction = "Move";
        updateDragIcon();
    }
    function updateDragIcon(e) {
        if (_movingElement != null && _dragElementIconAbove != null) {
            if (_dragSourceInfo != null) {
                if (_dropTargetInfo == null) {
                    showHideDragIcon(_dragSourceInfo.AllowRemoveDrag ? "Remove" : "None");
                    showHideDragIconMoveCopy();
                } else {
                    if (_dropTargetInfo.AboveNextEqualsBelowPrevious && (_dropTargetInfo.Position == "Above" || _dropTargetInfo.Position == "Below")) {
                        showHideDragIcon("Between");
                    } else {
                        showHideDragIcon(_dropTargetInfo.Position);
                    }
                    _dropAction = _isCtrlPressed ? "Copy" : "Move";
                    showHideDragIconMoveCopy(_dropAction);
                }
            }
        }
        if (_keyPressed == 27) cancelDrag(e);
    }
    function showHideDragIconMoveCopy(iconName) {
        if (_browserIsExplorer) {
            _dragElementIconMove.style.left = "-3000px";
            _dragElementIconCopy.style.left = "-3000px";
            if (iconName == null) { return; }
            if (iconName == "Move") { _dragElementIconMove.style.left = "0px"; return; }
            if (iconName == "Copy") { _dragElementIconCopy.style.left = "0px"; return; }
        } else {
            _dragElementIconMove.style.display = "none";
            _dragElementIconCopy.style.display = "none";
            if (iconName == null) { return; }
            if (iconName == "Move") { _dragElementIconMove.style.display = ""; return; }
            if (iconName == "Copy") { _dragElementIconCopy.style.display = ""; return; }
        }
    }
    var _currentDragIcon;
    this.GetCurrentDragIcon = function () { return _currentDragIcon; }
    function showHideDragIcon(iconName) {
        if (_browserIsExplorer) {
            _currentDragIcon = iconName;
            _dragElementIconAbove.style.left = "-3000px";
            _dragElementIconBelow.style.left = "-3000px";
            _dragElementIconBetween.style.left = "-3000px";
            _dragElementIconOver.style.left = "-3000px";
            _dragElementIconAll.style.left = "-3000px";
            _dragElementIconRemove.style.left = "-3000px";
            _dragElementIconNone.style.left = "-3000px";
            if (iconName == null) { return; }
            if (iconName == "Between") { _dragElementIconBetween.style.left = "0px"; return; }
            if (iconName == "Above") { _dragElementIconAbove.style.left = "0px"; return; }
            if (iconName == "Below") { _dragElementIconBelow.style.left = "0px"; return; }
            if (iconName == "Over") { _dragElementIconOver.style.left = "0px"; return; }
            if (iconName == "All") { _dragElementIconAll.style.left = "0px"; return; }
            if (iconName == "Remove") { _dragElementIconRemove.style.left = "0px"; return; }
            if (iconName == "None") { _dragElementIconNone.style.left = "0px"; return; }
        } else {
            _currentDragIcon = iconName;
            _dragElementIconAbove.style.display = "none";
            _dragElementIconBelow.style.display = "none";
            _dragElementIconBetween.style.display = "none";
            _dragElementIconOver.style.display = "none";
            _dragElementIconAll.style.display = "none";
            _dragElementIconRemove.style.display = "none";
            _dragElementIconNone.style.display = "none";
            if (iconName == null) { return; }
            if (iconName == "Between") { _dragElementIconBetween.style.display = ""; return; }
            if (iconName == "Above") { _dragElementIconAbove.style.display = ""; return; }
            if (iconName == "Below") { _dragElementIconBelow.style.display = ""; return; }
            if (iconName == "Over") { _dragElementIconOver.style.display = ""; return; }
            if (iconName == "All") { _dragElementIconAll.style.display = ""; return; }
            if (iconName == "Remove") { _dragElementIconRemove.style.display = ""; return; }
            if (iconName == "None") { _dragElementIconNone.style.display = ""; return; }
        }
    }
    function registerDropTarget(dropTargetInfo) {
        if (_movingElement != null) _dropTargetInfo = dropTargetInfo;
    }

    function cancelDrag(e) {
        if (_movingElement != null) {
            if (_moveCompleteScript.length > 0) {
                eval(_moveCompleteScript);
                _moveCompleteScript = "";
            }
            _dropTargetScript = "";
            alwaysSetElementOpacity(_movingElement, 100);
        }
        if (_browserIsFirefox) { // disable design mode to enable window events
            for (var n in _editorFrames) {
                try {
                    _editorFrames[n].contentDocument.designMode = 'on';
                } catch (err) {
                }
            }
        }
        _dragStartScript = null;
        _movingElement = null;
        _dropTargetInfo = null;
        _dragSourceInfo = null;
        _mouseDragScript = null;
        _moveCompleteScript = "";
        _mouseButtonIsPressed = false;
        _moveStartOffsetY = 0;
        _moveStartOffsetX = 0;
    }
    function unRegisterDropTarget() {
        _dropTargetInfo = null;
        _dropTargetScript = "";
    }
    function getMouseHoverFraction(element, e) {
        //return Math.round(100*(e.clientY- getElementY(element) + _desktopWindow.document.documentElement.scrollTop)/element.offsetHeight);
        return Math.round(100 * (e.clientY - getElementY(element) + _desktopWindow.document.documentElement.scrollTop) / element.offsetHeight);
    }
    function getDropTargetPosition(element, allowDrop, allowDropOver, allowDropBetween, e) {
        var fraction = Math.round(100 * (e.clientY - getElementY(element) + document.documentElement.scrollTop) / element.offsetHeight);
        if (allowDrop) {
            if (!allowDropOver && !allowDropBetween) {
                return "All";
            } else if (allowDropOver && allowDropBetween) {
                if (fraction < 25) {
                    return "Above";
                } else if (fraction > 75) {
                    return "Below";
                }
                return "Over";
            } else if (allowDropBetween) {
                if (fraction < 50) {
                    return "Above";
                }
                return "Below";
            } else if (allowDropOver) {
                return "Over";
            }
        }
        return "None";
    }





    // *************************
    // MISCELLANEOUS
    // *************************
    function filterHtml(html) {
        return ajax("WAF.Presentation.Web.Ajax.FilterHtml", html);
    }
    function addTagElements(elArray, tagName, doc) {
    }
    function addEditorsOfWindow(editors, win, doc) {
        var iframes = new Array();
        var els = doc.getElementsByTagName("iframe");
        for (var i2 = 0; i2 < els.length; i2++) iframes.push(els[i2]);
        for (var i = 0; i < iframes.length; ++i) {
            if (iframes[i].src.indexOf("WAF_Action=HtmlEditor") > -1) {
                var editorId = iframes[i].id + "_editor";
                var editor = win[editorId];
                if (editor != null) editors.push(editor);
            }
        }
    }
    function updateHtml(html) {
        return WAF.Ajax("WAF.Presentation.Web.Ajax.RefreshImageUrls", html);
    }
    function refreshHtmlEditorImages() {
        var wins = getAllWindows();
        for (var i in wins) {
            var w = wins[i];
            if (w.WAFHtmlControl_UpdateImages != null) {
                try {
                    w.WAFHtmlControl_UpdateImages(updateHtml);
                } catch (err) {
                }
            }
        }
    }
    function updatePreviewIfAny() {
        try {
            parent.window.WAF_RefreshPreview();
        } catch (xcp) {
        }
    }


    // *************************
    // AJAX CALLS
    // *************************
    var _ajaxRequestInProgressCount = 0;
    function setSessionSettingString(key, value) {
        ajaxRequest("SetSessionSettingString", "key=" + key + "&value=" + urlEncode(value)); // must add encoding later.......
    }
    function setSessionSettingObject(key, clientResponseObject) {
        ajaxRequest("SetSessionSettingObject", "key=" + key + "&cro_key=" + clientResponseObject.GetKey() + clientResponseObject.toString());
    }
    function setSessionSettingInt(key, value) {
        ajaxRequest("SetSessionSettingInt", "key=" + key + "&value=" + urlEncode(value));
    }
    function setUserSettingString(key, value) {
        ajaxRequest("SetSessionSettingString", "key=" + key + "&value=" + urlEncode(value)); // must add encoding later.......
    }
    function setUserSettingObject(key, clientResponseObject) {
        ajaxRequest("SetUserSettingObject", "key=" + key + "&cro_key=" + clientResponseObject.GetKey() + clientResponseObject.toString());
    }
    function setUserSettingInt(key, value) {
        ajaxRequest("SetSessionSettingInt", "key=" + key + "&value=" + urlEncode(value));
    }
    function getSessionSettingString(key) {
        return ajaxRequest("GetSessionSettingString", "key=" + key, null, false).data;
    }
    function ajaxRequest(action, parameters, onComplete, async) {
        _ajaxRequestInProgressCount++;
        if (parameters == null) parameters = "";
        if (async == null) async = true; // the default is a asyncronous call
        var url = _serviceUrl + "?WAFSessionId=" + _sessionId + "&WAFRequestId=" + _requestId + "&Action=" + action;
        var xmlHttp;
        if (window.XMLHttpRequest) {
            xmlHttp = new XMLHttpRequest();
        } else {
            try {
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {
                window.status = "Browser does not support AJAX";
            }
        }
        xmlHttp.open("POST", url, async);
        xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
        //xmlHttp.setRequestHeader("Content-length", parameters.length); // commentet due to err message in chrome and firefox
        //xmlHttp.setRequestHeader("Connection", "close"); // commentet due to err message in chrome and firefox
        if (async) {
            //if(window.status != "Please wait...") window.status = " .";
            xmlHttp.onreadystatechange = function () {
                try {
                    if (xmlHttp.readyState == 1) {
                        //if(window.status != "Please wait...") window.status = ".";
                    } else if (xmlHttp.readyState == 2) {
                        //if(window.status != "Please wait...") window.status = " ..";
                    } else if (xmlHttp.readyState == 3) {
                        //if(window.status != "Please wait...") window.status = "...";
                    } else if (xmlHttp.readyState == 4) {
                        _ajaxRequestInProgressCount--;
                        //if(window.status != "Please wait...") window.status = "....";
                        if (xmlHttp.status == 200) {
                            var resObject = getResponseObject(xmlHttp.responseText, onComplete, async);
                            // if(resObject.Restarting!=null) ;
                            if (resObject.Error != null) trace(resObject.Error);
                            if (resObject.NewSessionId != null) _sessionId = resObject.NewSessionId;
                            if (onComplete != null) onComplete(resObject);
                            //if(window.status != "Please wait...") window.status = "";
                        } else {
                            window.status = "Ajax HTTP error: " + xmlHttp.status;
                            //trace("AJAX HTTP error: " + xmlHttp.status); 
                        }
                        xmlHttp.onreadystatechange = null;
                        xmlHttp = null;
                    }
                } catch (e) {
                    // trace("AJAX error: " + e);
                }
            }
            xmlHttp.send(parameters);
            return null;
        } else {
            //window.status = "Please wait...";
            xmlHttp.send(parameters);
            //window.status = "";
            var resObject = getResponseObject(xmlHttp.responseText);
            xmlHttp = null;
            _ajaxRequestInProgressCount--;
            if (resObject.Error != null) alert(resObject.Error);
            if (resObject.NewSessionId != null) _sessionId = resObject.NewSessionId;
            return resObject;
        }
    }
    function ajax(name, params, onComplete, assemblyHint) {
        if (assemblyHint == null) assemblyHint = _pageAssemblyName;
        assemblyHint = escape(assemblyHint);
        if (typeof (params) == "string") { // then simplefied method
            params = params + "";
            var cr = new WAF_ClientRequest();
            cr.AddString("InputValue", params);
            if (onComplete == null) {
                return ajaxRequest("Method&AssemblyHint=" + assemblyHint + "&ParamType=String&Name=" + name, cr.toString(), null, false).OutputValue + "";
            } else {
                ajaxRequest("Method&AssemblyHint=" + assemblyHint + "&ParamType=String&Name=" + name, cr.toString(), function (cr2) { onComplete(cr2.OutputValue + ""); }, onComplete != null);
            }
        } else { // full call
            params = WAF_CreateClientRequestFromObject(params);
            return ajaxRequest("Method&AssemblyHint=" + assemblyHint + "&Name=" + name, params.toString(), onComplete, onComplete != null);
        }
    }

    function getSafeStringFromArray(dataValues) {
        var newArray = new Array();
        for (var n in dataValues) {
            if ((dataValues[n] + "").indexOf("|") > -1) {
                newArray.push(dataValues[n].replace("|", "[#SPLIT#]"));
            } else {
                newArray.push(dataValues[n]);
            }
        }
        return newArray.join("|");
    }
    function getArrayFromSafeString(stringValue) {
        var dataValues = stringValue.split("|");
        for (var n in dataValues) {
            if (dataValues[n].indexOf("[#SPLIT#]") > -1) {
                dataValues[n] = dataValues[n].replace("[#SPLIT#]", "|");
            }
        }
        return dataValues;
    }
    var hasShownAjaxError = false;
    function getResponseObject(responseText) {
        try {
            var responseArray = responseText.split("#BOUNDARY#");
            var response = new Object();
            for (var i = 0; i < responseArray.length; i = i + 2) {
                var keys = responseArray[i].split("#");
                var value = responseArray[i + 1];
                var valueNode = response;
                var t;
                for (t = 0; t < keys.length - 1; t++) {
                    if (valueNode[keys[t]] == null) valueNode[keys[t]] = new Object();
                    valueNode = valueNode[keys[t]];
                }
                if (keys[t].substring(0, 1) == "*") {
                    keys[t] = keys[t].substring(1);
                    var arr = value.split("*");
                    for (var n = 0; n < arr.length; n++) {
                        arr[n] = (arr[n]).replace(/#STAR#/, "*");
                    }
                    valueNode[keys[t]] = arr;
                } else {
                    valueNode[keys[t]] = value;
                }
            }
        } catch (e) {
            if (!hasShownAjaxError) {
                hasShownAjaxError = true;
                alert("AJAX send error: " + responseText);
            }
        }
        if (response.Error != null) {
            if (!hasShownAjaxError) {
                hasShownAjaxError = true;
                alert("AJAX response error: " + response.Error);
            }
        }
        return response;
    }

    //function urlEncode(string) { return escape((string)); }
    function urlEncode(string) { return escape(utf8Encode(string)); }
    function urlDecode(string) { return utf8Decode(unescape(string)); }
    function utf8Encode(string) {
        string = ("" + string).replace(/\r\n/g, "\n");
        var utftext = new Array();
        for (var n = 0; n < string.length; n++) {
            var c = string.charCodeAt(n);
            if (c < 128) {
                utftext.push(String.fromCharCode(c));
            }
            else if ((c > 127) && (c < 2048)) {
                utftext.push(String.fromCharCode((c >> 6) | 192));
                utftext.push(String.fromCharCode((c & 63) | 128));
            }
            else {
                utftext.push(String.fromCharCode((c >> 12) | 224));
                utftext.push(String.fromCharCode(((c >> 6) & 63) | 128));
                utftext.push(String.fromCharCode((c & 63) | 128));
            }
        }
        return utftext.join("");
    }
    function utf8Decode(utftext) {
        var string = new Array();
        var i = 0;
        var c = c1 = c2 = 0;
        while (i < utftext.length) {
            c = utftext.charCodeAt(i);
            if (c < 128) {
                string.push(String.fromCharCode(c));
                i++;
            }
            else if ((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i + 1);
                string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63)));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i + 1);
                c3 = utftext.charCodeAt(i + 2);
                string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)));
                i += 3;
            }
        }
        return string.join();
    }

    var nnn = 0;
    function trace(text) {
        if (nnn > 100) return;
        var el = document.createElement("div");
        el.innerHTML = ++nnn + ": " + text;
        el.style.position = "absolute";
        el.style.zIndex = "1000";
        el.style.top = nnn * 10 + "px";
        el.style.left = "700px";
        document.body.appendChild(el);
    }

}


