﻿
/**
 * ====================================================================
 * About
 * ====================================================================
 * Sarissa is an ECMAScript library acting as a cross-browser wrapper for native XML APIs.
 * The library supports Gecko based browsers like Mozilla and Firefox,
 * Internet Explorer (5.5+ with MSXML3.0+), Konqueror, Safari and a little of Opera
 * @version 0.9.7.3
 * @author: Manos Batsis, mailto: mbatsis at users full stop sourceforge full stop net
 * ====================================================================
 * Licence
 * ====================================================================
 * Sarissa is free software distributed under the GNU GPL version 2 (see <a href="gpl.txt">gpl.txt</a>) or higher, 
 * GNU LGPL version 2.1 (see <a href="lgpl.txt">lgpl.txt</a>) or higher and Apache Software License 2.0 or higher 
 * (see <a href="asl.txt">asl.txt</a>). This means you can choose one of the three and use that if you like. If 
 * you make modifications under the ASL, i would appreciate it if you submitted those.
 * In case your copy of Sarissa does not include the license texts, you may find
 * them online in various formats at <a href="http://www.gnu.org">http://www.gnu.org</a> and 
 * <a href="http://www.apache.org">http://www.apache.org</a>.
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 
 * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 
 * WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE 
 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ 
/**
 * <p>Sarissa is a utility class. Provides "static" methods for DOMDocument, 
 * DOM Node serialization to XML strings and other utility goodies.</p>
 * @constructor
 */
function Sarissa(){};
Sarissa.PARSED_OK = "Document contains no parsing errors";
Sarissa.PARSED_EMPTY = "Document is empty";
Sarissa.PARSED_UNKNOWN_ERROR = "Not well-formed or other error";
var _sarissa_iNsCounter = 0;
var _SARISSA_IEPREFIX4XSLPARAM = "";
var _SARISSA_HAS_DOM_IMPLEMENTATION = document.implementation && true;
var _SARISSA_HAS_DOM_CREATE_DOCUMENT = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.createDocument;
var _SARISSA_HAS_DOM_FEATURE = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.hasFeature;
var _SARISSA_IS_MOZ = _SARISSA_HAS_DOM_CREATE_DOCUMENT && _SARISSA_HAS_DOM_FEATURE;
var _SARISSA_IS_SAFARI = (navigator.userAgent && navigator.vendor && (navigator.userAgent.toLowerCase().indexOf("applewebkit") != -1 || navigator.vendor.indexOf("Apple") != -1));
var _SARISSA_IS_IE = document.all && window.ActiveXObject && navigator.userAgent.toLowerCase().indexOf("msie") > -1  && navigator.userAgent.toLowerCase().indexOf("opera") == -1;
if(!window.Node || !Node.ELEMENT_NODE){
    Node = {ELEMENT_NODE: 1, ATTRIBUTE_NODE: 2, TEXT_NODE: 3, CDATA_SECTION_NODE: 4, ENTITY_REFERENCE_NODE: 5,  ENTITY_NODE: 6, PROCESSING_INSTRUCTION_NODE: 7, COMMENT_NODE: 8, DOCUMENT_NODE: 9, DOCUMENT_TYPE_NODE: 10, DOCUMENT_FRAGMENT_NODE: 11, NOTATION_NODE: 12};
};

// IE initialization
if(_SARISSA_IS_IE){
    // for XSLT parameter names, prefix needed by IE
    _SARISSA_IEPREFIX4XSLPARAM = "xsl:";
    // used to store the most recent ProgID available out of the above
    var _SARISSA_DOM_PROGID = "";
    var _SARISSA_XMLHTTP_PROGID = "";
    var _SARISSA_DOM_XMLWRITER = "";
    /**
     * Called when the Sarissa_xx.js file is parsed, to pick most recent
     * ProgIDs for IE, then gets destroyed.
     * @private
     * @param idList an array of MSXML PROGIDs from which the most recent will be picked for a given object
     * @param enabledList an array of arrays where each array has two items; the index of the PROGID for which a certain feature is enabled
     */
    Sarissa.pickRecentProgID = function (idList){
        // found progID flag
        var bFound = false;
        for(var i=0; i < idList.length && !bFound; i++){
            try{
                var oDoc = new ActiveXObject(idList[i]);
                o2Store = idList[i];
                bFound = true;
            }catch (objException){
                // trap; try next progID
            };
        };
        if (!bFound) {
            throw "Could not retreive a valid progID of Class: " + idList[idList.length-1]+". (original exception: "+e+")";
        };
        idList = null;
        return o2Store;
    };
    // pick best available MSXML progIDs
    _SARISSA_DOM_PROGID = null;
    _SARISSA_THREADEDDOM_PROGID = null;
    _SARISSA_XSLTEMPLATE_PROGID = null;
    _SARISSA_XMLHTTP_PROGID = null;
    if(!window.XMLHttpRequest){
        /**
         * Emulate XMLHttpRequest
         * @constructor
         */
        XMLHttpRequest = function() {
			var retValue = null;
            if(!_SARISSA_XMLHTTP_PROGID){
                _SARISSA_XMLHTTP_PROGID = Sarissa.pickRecentProgID(["Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"]);
            };
            retValue = new ActiveXObject(_SARISSA_XMLHTTP_PROGID);
            return retValue;
        };
    };
    // we dont need this anymore
    //============================================
    // Factory methods (IE)
    //============================================
    // see non-IE version
    Sarissa.getDomDocument = function(sUri, sName){
        if(!_SARISSA_DOM_PROGID){
            _SARISSA_DOM_PROGID = Sarissa.pickRecentProgID(["Msxml2.DOMDocument.5.0", "Msxml2.DOMDocument.4.0", "Msxml2.DOMDocument.3.0", "MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XMLDOM"]);
        };
        var oDoc = new ActiveXObject(_SARISSA_DOM_PROGID);
        // if a root tag name was provided, we need to load it in the DOM object
        if (sName){
            // create an artifical namespace prefix 
            // or reuse existing prefix if applicable
            var prefix = "";
            if(sUri){
                if(sName.indexOf(":") > 1){
                    prefix = sName.substring(0, sName.indexOf(":"));
                    sName = sName.substring(sName.indexOf(":")+1); 
                }else{
                    prefix = "a" + (_sarissa_iNsCounter++);
                };
            };
            // use namespaces if a namespace URI exists
            if(sUri){
                oDoc.loadXML('<' + prefix+':'+sName + " xmlns:" + prefix + "=\"" + sUri + "\"" + " />");
            } else {
                oDoc.loadXML('<' + sName + " />");
            };
        };
        return oDoc;
    };
    // see non-IE version   
    Sarissa.getParseErrorText = function (oDoc) {
        var parseErrorText = Sarissa.PARSED_OK;
        if(oDoc.parseError.errorCode != 0){
            parseErrorText = "XML Parsing Error: " + oDoc.parseError.reason + 
                "\nLocation: " + oDoc.parseError.url + 
                "\nLine Number " + oDoc.parseError.line + ", Column " + 
                oDoc.parseError.linepos + 
                ":\n" + oDoc.parseError.srcText +
                "\n";
            for(var i = 0;  i < oDoc.parseError.linepos;i++){
                parseErrorText += "-";
            };
            parseErrorText +=  "^\n";
        }
        else if(oDoc.documentElement == null){
            parseErrorText = Sarissa.PARSED_EMPTY;
        };
        return parseErrorText;
    };
    // see non-IE version
    Sarissa.setXpathNamespaces = function(oDoc, sNsSet) {
        oDoc.setProperty("SelectionLanguage", "XPath");
        oDoc.setProperty("SelectionNamespaces", sNsSet);
    };   
    /**
     * Basic implementation of Mozilla's XSLTProcessor for IE. 
     * Reuses the same XSLT stylesheet for multiple transforms
     * @constructor
     */
    XSLTProcessor = function(){
        if(!_SARISSA_XSLTEMPLATE_PROGID){
            _SARISSA_XSLTEMPLATE_PROGID = Sarissa.pickRecentProgID(["Msxml2.XSLTemplate.5.0", "Msxml2.XSLTemplate.4.0", "MSXML2.XSLTemplate.3.0"]);
        };
        this.template = new ActiveXObject(_SARISSA_XSLTEMPLATE_PROGID);
        this.processor = null;
    };
    /**
     * Imports the given XSLT DOM and compiles it to a reusable transform
     * <b>Note:</b> If the stylesheet was loaded from a URL and contains xsl:import or xsl:include elements,it will be reloaded to resolve those
     * @argument xslDoc The XSLT DOMDocument to import
     */
    XSLTProcessor.prototype.importStylesheet = function(xslDoc){
        if(!_SARISSA_THREADEDDOM_PROGID){
            _SARISSA_THREADEDDOM_PROGID = Sarissa.pickRecentProgID(["Msxml2.FreeThreadedDOMDocument.5.0", "MSXML2.FreeThreadedDOMDocument.4.0", "MSXML2.FreeThreadedDOMDocument.3.0"]);
            _SARISSA_DOM_XMLWRITER = Sarissa.pickRecentProgID(["Msxml2.MXXMLWriter.5.0", "Msxml2.MXXMLWriter.4.0", "Msxml2.MXXMLWriter.3.0", "MSXML2.MXXMLWriter", "MSXML.MXXMLWriter", "Microsoft.XMLDOM"]);
        };
        xslDoc.setProperty("SelectionLanguage", "XPath");
        xslDoc.setProperty("SelectionNamespaces", "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
        // convert stylesheet to free threaded
        var converted = new ActiveXObject(_SARISSA_THREADEDDOM_PROGID);
        // make included/imported stylesheets work if exist and xsl was originally loaded from url
        if(xslDoc.url && xslDoc.selectSingleNode("//xsl:*[local-name() = 'import' or local-name() = 'include']") != null){
            converted.async = false;
            converted.load(xslDoc.url);
        } else {
            converted.loadXML(xslDoc.xml);
        };
        converted.setProperty("SelectionNamespaces", "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
        var output = converted.selectSingleNode("//xsl:output");
        this.outputMethod = output ? output.getAttribute("method") : "html";
        this.template.stylesheet = converted;
        this.processor = this.template.createProcessor();
        // (re)set default param values
        this.paramsSet = new Array();
    };

    /**
     * Transform the given XML DOM and return the transformation result as a new DOM document
     * @argument sourceDoc The XML DOMDocument to transform
     * @return The transformation result as a DOM Document
     */
    XSLTProcessor.prototype.transformToDocument = function(sourceDoc){
        this.processor.input = sourceDoc;
        var outDoc = new ActiveXObject(_SARISSA_DOM_XMLWRITER);
        this.processor.output = outDoc; 
        this.processor.transform();
        var oDoc = new ActiveXObject(_SARISSA_DOM_PROGID);
        oDoc.loadXML(outDoc.output+"");
        return oDoc;
    };
    
    /**
     * Transform the given XML DOM and return the transformation result as a new DOM fragment.
     * <b>Note</b>: The xsl:output method must match the nature of the owner document (XML/HTML).
     * @argument sourceDoc The XML DOMDocument to transform
     * @argument ownerDoc The owner of the result fragment
     * @return The transformation result as a DOM Document
     */
    XSLTProcessor.prototype.transformToFragment = function (sourceDoc, ownerDoc) {
        this.processor.input = sourceDoc;
        this.processor.transform();
        var s = this.processor.output;
        var f = ownerDoc.createDocumentFragment();
        if (this.outputMethod == 'text') {
            f.appendChild(ownerDoc.createTextNode(s));
        } else if (ownerDoc.body && ownerDoc.body.innerHTML) {
            var container = ownerDoc.createElement('div');
            container.innerHTML = s;
            while (container.hasChildNodes()) {
                f.appendChild(container.firstChild);
            }
            ownerDoc.removeChild(container);
        }
        else {
            var oDoc = new ActiveXObject(_SARISSA_DOM_PROGID);
            if (s.substring(0, 5) == '<?xml') {
                s = s.substring(s.indexOf('?>') + 2);
            }
            var xml = ''.concat('<my>', s, '</my>');
            oDoc.loadXML(xml);
            var container = oDoc.documentElement;
            while (container.hasChildNodes()) {
                f.appendChild(container.firstChild);
            }
            oDoc.removeChild(container);
        }
        return f;
    };
    
    /**
     * Set global XSLT parameter of the imported stylesheet
     * @argument nsURI The parameter namespace URI
     * @argument name The parameter base name
     * @argument value The new parameter value
     */
    XSLTProcessor.prototype.setParameter = function(nsURI, name, value){
        /* nsURI is optional but cannot be null */
        if(nsURI){
            this.processor.addParameter(name, value, nsURI);
        }else{
            this.processor.addParameter(name, value);
        };
        /* update updated params for getParameter */
        if(!this.paramsSet[""+nsURI]){
            this.paramsSet[""+nsURI] = new Array();
        };
        this.paramsSet[""+nsURI][name] = value;
    };
    /**
     * Gets a parameter if previously set by setParameter. Returns null
     * otherwise
     * @argument name The parameter base name
     * @argument value The new parameter value
     * @return The parameter value if reviously set by setParameter, null otherwise
     */
    XSLTProcessor.prototype.getParameter = function(nsURI, name){
        nsURI = nsURI || "";
        if(this.paramsSet[nsURI] && this.paramsSet[nsURI][name]){
            return this.paramsSet[nsURI][name];
        }else{
            return null;
        };
    };
}else{ /* end IE initialization, try to deal with real browsers now ;-) */
    if(_SARISSA_HAS_DOM_CREATE_DOCUMENT){
        /**
         * <p>Ensures the document was loaded correctly, otherwise sets the
         * parseError to -1 to indicate something went wrong. Internal use</p>
         * @private
         */
        Sarissa.__handleLoad__ = function(oDoc){
            Sarissa.__setReadyState__(oDoc, 4);
        };
        /**
        * <p>Attached by an event handler to the load event. Internal use.</p>
        * @private
        */
        _sarissa_XMLDocument_onload = function(){
            Sarissa.__handleLoad__(this);
        };
        /**
         * <p>Sets the readyState property of the given DOM Document object.
         * Internal use.</p>
         * @private
         * @argument oDoc the DOM Document object to fire the
         *          readystatechange event
         * @argument iReadyState the number to change the readystate property to
         */
        Sarissa.__setReadyState__ = function(oDoc, iReadyState){
            oDoc.readyState = iReadyState;
            oDoc.readystate = iReadyState;
            if (oDoc.onreadystatechange != null && typeof oDoc.onreadystatechange == "function")
                oDoc.onreadystatechange();
        };
        Sarissa.getDomDocument = function(sUri, sName){
            var oDoc = document.implementation.createDocument(sUri?sUri:null, sName?sName:null, null);
            if(!oDoc.onreadystatechange){
            
                /**
                * <p>Emulate IE's onreadystatechange attribute</p>
                */
                oDoc.onreadystatechange = null;
            };
            if(!oDoc.readyState){
                /**
                * <p>Emulates IE's readyState property, which always gives an integer from 0 to 4:</p>
                * <ul><li>1 == LOADING,</li>
                * <li>2 == LOADED,</li>
                * <li>3 == INTERACTIVE,</li>
                * <li>4 == COMPLETED</li></ul>
                */
                oDoc.readyState = 0;
            };
            oDoc.addEventListener("load", _sarissa_XMLDocument_onload, false);
            return oDoc;
        };
        if(window.XMLDocument){
        
        //if(window.XMLDocument) , now mainly for opera  
        }// TODO: check if the new document has content before trying to copynodes, check  for error handling in DOM 3 LS
        else if(document.implementation && document.implementation.hasFeature && document.implementation.hasFeature('LS', '3.0')){
        
            /**
            * <p>Factory method to obtain a new DOM Document object</p>
            * @argument sUri the namespace of the root node (if any)
            * @argument sUri the local name of the root node (if any)
            * @returns a new DOM Document
            */
            Sarissa.getDomDocument = function(sUri, sName){
                var oDoc = document.implementation.createDocument(sUri?sUri:null, sName?sName:null, null);
                return oDoc;
            };
        }
        else {
            Sarissa.getDomDocument = function(sUri, sName){
                var oDoc = document.implementation.createDocument(sUri?sUri:null, sName?sName:null, null);
                // looks like safari does not create the root element for some unknown reason
                if(oDoc && (sUri || sName) && !oDoc.documentElement){
                    oDoc.appendChild(oDoc.createElementNS(sUri, sName));
                };
                return oDoc;
            };
        };
    };//if(_SARISSA_HAS_DOM_CREATE_DOCUMENT)
};
//==========================================
// Common stuff
//==========================================
if(!window.DOMParser){
    if(_SARISSA_IS_SAFARI){
        /*
         * DOMParser is a utility class, used to construct DOMDocuments from XML strings
         * @constructor
         */
        DOMParser = function() { };
        /** 
        * Construct a new DOM Document from the given XMLstring
        * @param sXml the given XML string
        * @param contentType the content type of the document the given string represents (one of text/xml, application/xml, application/xhtml+xml). 
        * @return a new DOM Document from the given XML string
        */
        DOMParser.prototype.parseFromString = function(sXml, contentType){
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.open("GET", "data:text/xml;charset=utf-8," + encodeURIComponent(sXml), false);
            xmlhttp.send(null);
            return xmlhttp.responseXML;
        };
    }else if(Sarissa.getDomDocument && Sarissa.getDomDocument() && Sarissa.getDomDocument(null, "bar").xml){
        DOMParser = function() { };
        DOMParser.prototype.parseFromString = function(sXml, contentType){
            var doc = Sarissa.getDomDocument();
            doc.loadXML(sXml);
            return doc;
        };
    };
};

if(!document.importNode && _SARISSA_IS_IE){
    try{
        /**
        * Implementation of importNode for the context window document in IE
        * @param oNode the Node to import
        * @param bChildren whether to include the children of oNode
        * @returns the imported node for further use
        */
        document.importNode = function(oNode, bChildren){
            var tmp = document.createElement("div");
            if(bChildren){
                tmp.innerHTML = oNode.xml ? oNode.xml : oNode.innerHTML;
            }else{
                tmp.innerHTML = oNode.xml ? oNode.cloneNode(false).xml : oNode.cloneNode(false).innerHTML;
            };
            return tmp.getElementsByTagName("*")[0];
        };
    }catch(e){ };
};
if(!Sarissa.getParseErrorText){
    /**
     * <p>Returns a human readable description of the parsing error. Usefull
     * for debugging. Tip: append the returned error string in a &lt;pre&gt;
     * element if you want to render it.</p>
     * <p>Many thanks to Christian Stocker for the initial patch.</p>
     * @argument oDoc The target DOM document
     * @returns The parsing error description of the target Document in
     *          human readable form (preformated text)
     */
    Sarissa.getParseErrorText = function (oDoc){
        var parseErrorText = Sarissa.PARSED_OK;
        if(!oDoc.documentElement){
            parseErrorText = Sarissa.PARSED_EMPTY;
        } else if(oDoc.documentElement.tagName == "parsererror"){
            parseErrorText = oDoc.documentElement.firstChild.data;
            parseErrorText += "\n" +  oDoc.documentElement.firstChild.nextSibling.firstChild.data;
        } else if(oDoc.getElementsByTagName("parsererror").length > 0){
            var parsererror = oDoc.getElementsByTagName("parsererror")[0];
            parseErrorText = Sarissa.getText(parsererror, true)+"\n";
        } else if(oDoc.parseError && oDoc.parseError.errorCode != 0){
            parseErrorText = Sarissa.PARSED_UNKNOWN_ERROR;
        };
        return parseErrorText;
    };
};
Sarissa.getText = function(oNode, deep){
    var s = "";
    var nodes = oNode.childNodes;
    for(var i=0; i < nodes.length; i++){
        var node = nodes[i];
        var nodeType = node.nodeType;
        if(nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE){
            s += node.data;
        } else if(deep == true
                    && (nodeType == Node.ELEMENT_NODE
                        || nodeType == Node.DOCUMENT_NODE
                        || nodeType == Node.DOCUMENT_FRAGMENT_NODE)){
            s += Sarissa.getText(node, true);
        };
    };
    return s;
};
if(!window.XMLSerializer 
    && Sarissa.getDomDocument 
    && Sarissa.getDomDocument("","foo", null).xml){
    /**
     * Utility class to serialize DOM Node objects to XML strings
     * @constructor
     */
    XMLSerializer = function(){};
    /**
     * Serialize the given DOM Node to an XML string
     * @param oNode the DOM Node to serialize
     */
    XMLSerializer.prototype.serializeToString = function(oNode) {
        return oNode.xml;
    };
};

/**
 * strips tags from a markup string
 */
Sarissa.stripTags = function (s) {
    return s.replace(/<[^>]+>/g,"");
};
/**
 * <p>Deletes all child nodes of the given node</p>
 * @argument oNode the Node to empty
 */
Sarissa.clearChildNodes = function(oNode) {
    // need to check for firstChild due to opera 8 bug with hasChildNodes
    while(oNode.firstChild) {
        oNode.removeChild(oNode.firstChild);
    };
};
/**
 * <p> Copies the childNodes of nodeFrom to nodeTo</p>
 * <p> <b>Note:</b> The second object's original content is deleted before 
 * the copy operation, unless you supply a true third parameter</p>
 * @argument nodeFrom the Node to copy the childNodes from
 * @argument nodeTo the Node to copy the childNodes to
 * @argument bPreserveExisting whether to preserve the original content of nodeTo, default is false
 */
Sarissa.copyChildNodes = function(nodeFrom, nodeTo, bPreserveExisting) {
    if((!nodeFrom) || (!nodeTo)){
        throw "Both source and destination nodes must be provided";
    };
    if(!bPreserveExisting){
        Sarissa.clearChildNodes(nodeTo);
    };
    var ownerDoc = nodeTo.nodeType == Node.DOCUMENT_NODE ? nodeTo : nodeTo.ownerDocument;
    var nodes = nodeFrom.childNodes;
    if(ownerDoc.importNode)  {
        for(var i=0;i < nodes.length;i++) {
            nodeTo.appendChild(ownerDoc.importNode(nodes[i], true));
        };
    } else {
        for(var i=0;i < nodes.length;i++) {
            nodeTo.appendChild(nodes[i].cloneNode(true));
        };
    };
};

/**
 * <p> Moves the childNodes of nodeFrom to nodeTo</p>
 * <p> <b>Note:</b> The second object's original content is deleted before 
 * the move operation, unless you supply a true third parameter</p>
 * @argument nodeFrom the Node to copy the childNodes from
 * @argument nodeTo the Node to copy the childNodes to
 * @argument bPreserveExisting whether to preserve the original content of nodeTo, default is
 */ 
Sarissa.moveChildNodes = function(nodeFrom, nodeTo, bPreserveExisting) {
    if((!nodeFrom) || (!nodeTo)){
        throw "Both source and destination nodes must be provided";
    };
    if(!bPreserveExisting){
        Sarissa.clearChildNodes(nodeTo);
    };
    var nodes = nodeFrom.childNodes;
    // if within the same doc, just move, else copy and delete
    if(nodeFrom.ownerDocument == nodeTo.ownerDocument){
        while(nodeFrom.firstChild){
            nodeTo.appendChild(nodeFrom.firstChild);
        };
    } else {
        var ownerDoc = nodeTo.nodeType == Node.DOCUMENT_NODE ? nodeTo : nodeTo.ownerDocument;
        if(ownerDoc.importNode) {
           for(var i=0;i < nodes.length;i++) {
               nodeTo.appendChild(ownerDoc.importNode(nodes[i], true));
           };
        }else{
           for(var i=0;i < nodes.length;i++) {
               nodeTo.appendChild(nodes[i].cloneNode(true));
           };
        };
        Sarissa.clearChildNodes(nodeFrom);
    };
};

/** 
 * <p>Serialize any object to an XML string. All properties are serialized using the property name
 * as the XML element name. Array elements are rendered as <code>array-item</code> elements, 
 * using their index/key as the value of the <code>key</code> attribute.</p>
 * @argument anyObject the object to serialize
 * @argument objectName a name for that object
 * @return the XML serializationj of the given object as a string
 */
Sarissa.xmlize = function(anyObject, objectName, indentSpace){
    indentSpace = indentSpace?indentSpace:'';
    var s = indentSpace  + '<' + objectName + '>';
    var isLeaf = false;
    if(!(anyObject instanceof Object) || anyObject instanceof Number || anyObject instanceof String 
        || anyObject instanceof Boolean || anyObject instanceof Date){
        s += Sarissa.escape(""+anyObject);
        isLeaf = true;
    }else{
        s += "\n";
        var itemKey = '';
        var isArrayItem = anyObject instanceof Array;
        for(var name in anyObject){
            s += Sarissa.xmlize(anyObject[name], (isArrayItem?"array-item key=\""+name+"\"":name), indentSpace + "   ");
        };
        s += indentSpace;
    };
    return s += (objectName.indexOf(' ')!=-1?"</array-item>\n":"</" + objectName + ">\n");
};

/** 
 * Escape the given string chacters that correspond to the five predefined XML entities
 * @param sXml the string to escape
 */
Sarissa.escape = function(sXml){
    return sXml.replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&apos;");
};

/** 
 * Unescape the given string. This turns the occurences of the predefined XML 
 * entities to become the characters they represent correspond to the five predefined XML entities
 * @param sXml the string to unescape
 */
Sarissa.unescape = function(sXml){
    return sXml.replace(/&apos;/g,"'")
        .replace(/&quot;/g,"\"")
        .replace(/&gt;/g,">")
        .replace(/&lt;/g,"<")
        .replace(/&amp;/g,"&");
};
//   EOF
/*	SWFObject v2.0 <http://code.google.com/p/swfobject/>
	Copyright (c) 2007 Geoff Stearns, Michael Williams, and Bobby van der Sluis
	This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
*/
var swfobject=function(){var Z="undefined",P="object",B="Shockwave Flash",h="ShockwaveFlash.ShockwaveFlash",W="application/x-shockwave-flash",K="SWFObjectExprInst",G=window,g=document,N=navigator,f=[],H=[],Q=null,L=null,T=null,S=false,C=false;var a=function(){var l=typeof g.getElementById!=Z&&typeof g.getElementsByTagName!=Z&&typeof g.createElement!=Z&&typeof g.appendChild!=Z&&typeof g.replaceChild!=Z&&typeof g.removeChild!=Z&&typeof g.cloneNode!=Z,t=[0,0,0],n=null;if(typeof N.plugins!=Z&&typeof N.plugins[B]==P){n=N.plugins[B].description;if(n){n=n.replace(/^.*\s+(\S+\s+\S+$)/,"$1");t[0]=parseInt(n.replace(/^(.*)\..*$/,"$1"),10);t[1]=parseInt(n.replace(/^.*\.(.*)\s.*$/,"$1"),10);t[2]=/r/.test(n)?parseInt(n.replace(/^.*r(.*)$/,"$1"),10):0}}else{if(typeof G.ActiveXObject!=Z){var o=null,s=false;try{o=new ActiveXObject(h+".7")}catch(k){try{o=new ActiveXObject(h+".6");t=[6,0,21];o.AllowScriptAccess="always"}catch(k){if(t[0]==6){s=true}}if(!s){try{o=new ActiveXObject(h)}catch(k){}}}if(!s&&o){try{n=o.GetVariable("$version");if(n){n=n.split(" ")[1].split(",");t=[parseInt(n[0],10),parseInt(n[1],10),parseInt(n[2],10)]}}catch(k){}}}}var v=N.userAgent.toLowerCase(),j=N.platform.toLowerCase(),r=/webkit/.test(v)?parseFloat(v.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,i=false,q=j?/win/.test(j):/win/.test(v),m=j?/mac/.test(j):/mac/.test(v);/*@cc_on i=true;@if(@_win32)q=true;@elif(@_mac)m=true;@end@*/return{w3cdom:l,pv:t,webkit:r,ie:i,win:q,mac:m}}();var e=function(){if(!a.w3cdom){return }J(I);if(a.ie&&a.win){try{g.write("<script id=__ie_ondomload defer=true src=//:><\/script>");var i=c("__ie_ondomload");if(i){i.onreadystatechange=function(){if(this.readyState=="complete"){this.parentNode.removeChild(this);V()}}}}catch(j){}}if(a.webkit&&typeof g.readyState!=Z){Q=setInterval(function(){if(/loaded|complete/.test(g.readyState)){V()}},10)}if(typeof g.addEventListener!=Z){g.addEventListener("DOMContentLoaded",V,null)}M(V)}();function V(){if(S){return }if(a.ie&&a.win){var m=Y("span");try{var l=g.getElementsByTagName("body")[0].appendChild(m);l.parentNode.removeChild(l)}catch(n){return }}S=true;if(Q){clearInterval(Q);Q=null}var j=f.length;for(var k=0;k<j;k++){f[k]()}}function J(i){if(S){i()}else{f[f.length]=i}}function M(j){if(typeof G.addEventListener!=Z){G.addEventListener("load",j,false)}else{if(typeof g.addEventListener!=Z){g.addEventListener("load",j,false)}else{if(typeof G.attachEvent!=Z){G.attachEvent("onload",j)}else{if(typeof G.onload=="function"){var i=G.onload;G.onload=function(){i();j()}}else{G.onload=j}}}}}function I(){var l=H.length;for(var j=0;j<l;j++){var m=H[j].id;if(a.pv[0]>0){var k=c(m);if(k){H[j].width=k.getAttribute("width")?k.getAttribute("width"):"0";H[j].height=k.getAttribute("height")?k.getAttribute("height"):"0";if(O(H[j].swfVersion)){if(a.webkit&&a.webkit<312){U(k)}X(m,true)}else{if(H[j].expressInstall&&!C&&O("6.0.65")&&(a.win||a.mac)){D(H[j])}else{d(k)}}}}else{X(m,true)}}}function U(m){var k=m.getElementsByTagName(P)[0];if(k){var p=Y("embed"),r=k.attributes;if(r){var o=r.length;for(var n=0;n<o;n++){if(r[n].nodeName.toLowerCase()=="data"){p.setAttribute("src",r[n].nodeValue)}else{p.setAttribute(r[n].nodeName,r[n].nodeValue)}}}var q=k.childNodes;if(q){var s=q.length;for(var l=0;l<s;l++){if(q[l].nodeType==1&&q[l].nodeName.toLowerCase()=="param"){p.setAttribute(q[l].getAttribute("name"),q[l].getAttribute("value"))}}}m.parentNode.replaceChild(p,m)}}function F(i){if(a.ie&&a.win&&O("8.0.0")){G.attachEvent("onunload",function(){var k=c(i);if(k){for(var j in k){if(typeof k[j]=="function"){k[j]=function(){}}}k.parentNode.removeChild(k)}})}}function D(j){C=true;var o=c(j.id);if(o){if(j.altContentId){var l=c(j.altContentId);if(l){L=l;T=j.altContentId}}else{L=b(o)}if(!(/%$/.test(j.width))&&parseInt(j.width,10)<310){j.width="310"}if(!(/%$/.test(j.height))&&parseInt(j.height,10)<137){j.height="137"}g.title=g.title.slice(0,47)+" - Flash Player Installation";var n=a.ie&&a.win?"ActiveX":"PlugIn",k=g.title,m="MMredirectURL="+G.location+"&MMplayerType="+n+"&MMdoctitle="+k,p=j.id;if(a.ie&&a.win&&o.readyState!=4){var i=Y("div");p+="SWFObjectNew";i.setAttribute("id",p);o.parentNode.insertBefore(i,o);o.style.display="none";G.attachEvent("onload",function(){o.parentNode.removeChild(o)})}R({data:j.expressInstall,id:K,width:j.width,height:j.height},{flashvars:m},p)}}function d(j){if(a.ie&&a.win&&j.readyState!=4){var i=Y("div");j.parentNode.insertBefore(i,j);i.parentNode.replaceChild(b(j),i);j.style.display="none";G.attachEvent("onload",function(){j.parentNode.removeChild(j)})}else{j.parentNode.replaceChild(b(j),j)}}function b(n){var m=Y("div");if(a.win&&a.ie){m.innerHTML=n.innerHTML}else{var k=n.getElementsByTagName(P)[0];if(k){var o=k.childNodes;if(o){var j=o.length;for(var l=0;l<j;l++){if(!(o[l].nodeType==1&&o[l].nodeName.toLowerCase()=="param")&&!(o[l].nodeType==8)){m.appendChild(o[l].cloneNode(true))}}}}}return m}function R(AE,AC,q){var p,t=c(q);if(typeof AE.id==Z){AE.id=q}if(a.ie&&a.win){var AD="";for(var z in AE){if(AE[z]!=Object.prototype[z]){if(z=="data"){AC.movie=AE[z]}else{if(z.toLowerCase()=="styleclass"){AD+=' class="'+AE[z]+'"'}else{if(z!="classid"){AD+=" "+z+'="'+AE[z]+'"'}}}}}var AB="";for(var y in AC){if(AC[y]!=Object.prototype[y]){AB+='<param name="'+y+'" value="'+AC[y]+'" />'}}t.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+AD+">"+AB+"</object>";F(AE.id);p=c(AE.id)}else{if(a.webkit&&a.webkit<312){var AA=Y("embed");AA.setAttribute("type",W);for(var x in AE){if(AE[x]!=Object.prototype[x]){if(x=="data"){AA.setAttribute("src",AE[x])}else{if(x.toLowerCase()=="styleclass"){AA.setAttribute("class",AE[x])}else{if(x!="classid"){AA.setAttribute(x,AE[x])}}}}}for(var w in AC){if(AC[w]!=Object.prototype[w]){if(w!="movie"){AA.setAttribute(w,AC[w])}}}t.parentNode.replaceChild(AA,t);p=AA}else{var s=Y(P);s.setAttribute("type",W);for(var v in AE){if(AE[v]!=Object.prototype[v]){if(v.toLowerCase()=="styleclass"){s.setAttribute("class",AE[v])}else{if(v!="classid"){s.setAttribute(v,AE[v])}}}}for(var u in AC){if(AC[u]!=Object.prototype[u]&&u!="movie"){E(s,u,AC[u])}}t.parentNode.replaceChild(s,t);p=s}}return p}function E(k,i,j){var l=Y("param");l.setAttribute("name",i);l.setAttribute("value",j);k.appendChild(l)}function c(i){return g.getElementById(i)}function Y(i){return g.createElement(i)}function O(k){var j=a.pv,i=k.split(".");i[0]=parseInt(i[0],10);i[1]=parseInt(i[1],10);i[2]=parseInt(i[2],10);return(j[0]>i[0]||(j[0]==i[0]&&j[1]>i[1])||(j[0]==i[0]&&j[1]==i[1]&&j[2]>=i[2]))?true:false}function A(m,j){if(a.ie&&a.mac){return }var l=g.getElementsByTagName("head")[0],k=Y("style");k.setAttribute("type","text/css");k.setAttribute("media","screen");if(!(a.ie&&a.win)&&typeof g.createTextNode!=Z){k.appendChild(g.createTextNode(m+" {"+j+"}"))}l.appendChild(k);if(a.ie&&a.win&&typeof g.styleSheets!=Z&&g.styleSheets.length>0){var i=g.styleSheets[g.styleSheets.length-1];if(typeof i.addRule==P){i.addRule(m,j)}}}function X(k,i){var j=i?"visible":"hidden";if(S){c(k).style.visibility=j}else{A("#"+k,"visibility:"+j)}}return{registerObject:function(l,i,k){if(!a.w3cdom||!l||!i){return }var j={};j.id=l;j.swfVersion=i;j.expressInstall=k?k:false;H[H.length]=j;X(l,false)},getObjectById:function(l){var i=null;if(a.w3cdom&&S){var j=c(l);if(j){var k=j.getElementsByTagName(P)[0];if(!k||(k&&typeof j.SetVariable!=Z)){i=j}else{if(typeof k.SetVariable!=Z){i=k}}}}return i},embedSWF:function(n,u,r,t,j,m,k,p,s){if(!a.w3cdom||!n||!u||!r||!t||!j){return }r+="";t+="";if(O(j)){X(u,false);var q=(typeof s==P)?s:{};q.data=n;q.width=r;q.height=t;var o=(typeof p==P)?p:{};if(typeof k==P){for(var l in k){if(k[l]!=Object.prototype[l]){if(typeof o.flashvars!=Z){o.flashvars+="&"+l+"="+k[l]}else{o.flashvars=l+"="+k[l]}}}}J(function(){R(q,o,u);if(q.id==u){X(u,true)}})}else{if(m&&!C&&O("6.0.65")&&(a.win||a.mac)){X(u,false);J(function(){var i={};i.id=i.altContentId=u;i.width=r;i.height=t;i.expressInstall=m;D(i)})}}},getFlashPlayerVersion:function(){return{major:a.pv[0],minor:a.pv[1],release:a.pv[2]}},hasFlashPlayerVersion:O,createSWF:function(k,j,i){if(a.w3cdom&&S){return R(k,j,i)}else{return undefined}},createCSS:function(j,i){if(a.w3cdom){A(j,i)}},addDomLoadEvent:J,addLoadEvent:M,getQueryParamValue:function(m){var l=g.location.search||g.location.hash;if(m==null){return l}if(l){var k=l.substring(1).split("&");for(var j=0;j<k.length;j++){if(k[j].substring(0,k[j].indexOf("="))==m){return k[j].substring((k[j].indexOf("=")+1))}}}return""},expressInstallCallback:function(){if(C&&L){var i=c(K);if(i){i.parentNode.replaceChild(L,i);if(T){X(T,true);if(a.ie&&a.win){L.style.display="block"}}L=null;T=null;C=false}}}}}();var tenduke={};
var tenduke = tenduke || {};
tenduke.util = tenduke.util || {};
/**
 * Utility class for working with dates and time.
 */
(function() {

    var DateAndTimeUtils = {};

    /**
     * Parse a date / timestamp string of Iso 8601 Utc format, example: 2009-10-06T10:23:19.569Z.
     * @param timeStampString Node to start search from
     * @return Date instance if parsing is successful
     *
     */
    DateAndTimeUtils.parseIso8601UtcDate = function(timeStampString) {
        //
        //
        var retValue = null;
        //
        //
        if(timeStampString!=null && timeStampString!=undefined && timeStampString.length>=10) {
            //
            //
            var datePart = timeStampString.substring(0,10);
            //
            //
            var yearNum = parseInt(datePart.substring(0,4));
            var monthNum = parseInt(datePart.substring(5,7));
            var dateNum = parseInt(datePart.substring(8,10));
            //            
            // naive sanity check: require all parsed date related values to be numbers with some additional range checks...
            // Note: JS Date expects month value between 0-11
            if(isNaN(yearNum)==false && isNaN(monthNum)==false && (monthNum-1)>=0 && monthNum<=12 && isNaN(dateNum)==false && dateNum>=1 && dateNum<=31) {
                //
                //
                retValue = new Date();
                //
                //
                retValue.setYear(yearNum);
                retValue.setMonth(monthNum-1); // Note: JS Date expects month value between 0-11
                retValue.setDate(dateNum);
                //
                //
                var timePart = timeStampString.substring(11);
                var hourNum = parseInt(timePart.substring(0,2));
                var minuteNum = parseInt(timePart.substring(3,5));
                var secondNum = parseInt(timePart.substring(6,8));
                //
                // naive check, require all parsed date related values to be numbers with some additional range checks...
                if(isNaN(hourNum)==false && hourNum>=0 && isNaN(minuteNum)==false && minuteNum>=0 && isNaN(secondNum)==false && secondNum>=0) {
                    retValue.setHours(hourNum);
                    retValue.setMinutes(minuteNum);
                    retValue.setSeconds(secondNum);
                }
            }
        }
        //
        //
        return retValue;
    }

    /**
     * Format a date to Iso 8601 Utc format, example: 2009-10-06.
     * @param dateObject
     * @return String with iso-8601 format
     *
     */
    DateAndTimeUtils.formatIso8601UtcDate = function(dateObject) {
        //
        //
        var retValue = null;
        //
        //
        if(dateObject!=null && dateObject!=undefined) {
            //
            //
            var yearNum = dateObject.getFullYear();
            var monthNum = dateObject.getMonth()+1; // months go from 0...11
            var dayNum = dateObject.getDate();
            //
            //
            retValue = "" + yearNum + "-" + monthNum + "-" + dayNum;
        }
        //
        //
        return retValue;
    }

    //
    //
    tenduke.util.DateAndTimeUtils = DateAndTimeUtils;

})();
/**
 * Utility class for creating SHA-1 message digests based on input string data.
 * Usage: var hash = tenduke.util.SHA1.doFinal(yourStringData);
 *
 */
(function() {

    var SHA1 = {};

/**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info/
*
**/

    SHA1.rotate_left = function (n,s) {
		var t4 = ( n<<s ) | (n>>>(32-s));
		return t4;
	}

	SHA1.lsb_hex = function(val) {
		var str="";
		var i;
		var vh;
		var vl;

		for( i=0; i<=6; i+=2 ) {
			vh = (val>>>(i*4+4))&0x0f;
			vl = (val>>>(i*4))&0x0f;
			str += vh.toString(16) + vl.toString(16);
		}
		return str;
	}

	SHA1.cvt_hex = function(val) {
		var str="";
		var i;
		var v;

		for( i=7; i>=0; i-- ) {
			v = (val>>>(i*4))&0x0f;
			str += v.toString(16);
		}
		return str;
	}


	SHA1.Utf8Encode = function(string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}

		return utftext;
	},

    SHA1.doFinal = function (msg) {
        var blockstart;
        var i, j;
        var W = new Array(80);
        var H0 = 0x67452301;
        var H1 = 0xEFCDAB89;
        var H2 = 0x98BADCFE;
        var H3 = 0x10325476;
        var H4 = 0xC3D2E1F0;
        var A, B, C, D, E;
        var temp;

        msg = SHA1.Utf8Encode(msg);

        var msg_len = msg.length;

        var word_array = new Array();
        for( i=0; i<msg_len-3; i+=4 ) {
            j = msg.charCodeAt(i)<<24 | msg.charCodeAt(i+1)<<16 |
            msg.charCodeAt(i+2)<<8 | msg.charCodeAt(i+3);
            word_array.push( j );
        }

        switch( msg_len % 4 ) {
            case 0:
                i = 0x080000000;
            break;
            case 1:
                i = msg.charCodeAt(msg_len-1)<<24 | 0x0800000;
            break;

            case 2:
                i = msg.charCodeAt(msg_len-2)<<24 | msg.charCodeAt(msg_len-1)<<16 | 0x08000;
            break;

            case 3:
                i = msg.charCodeAt(msg_len-3)<<24 | msg.charCodeAt(msg_len-2)<<16 | msg.charCodeAt(msg_len-1)<<8	| 0x80;
            break;
        }

        word_array.push( i );

        while( (word_array.length % 16) != 14 ) word_array.push( 0 );

        word_array.push( msg_len>>>29 );
        word_array.push( (msg_len<<3)&0x0ffffffff );


        for ( blockstart=0; blockstart<word_array.length; blockstart+=16 ) {

            for( i=0; i<16; i++ ) W[i] = word_array[blockstart+i];
            for( i=16; i<=79; i++ ) W[i] = SHA1.rotate_left(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);

            A = H0;
            B = H1;
            C = H2;
            D = H3;
            E = H4;

            for( i= 0; i<=19; i++ ) {
                temp = (SHA1.rotate_left(A,5) + ((B&C) | (~B&D)) + E + W[i] + 0x5A827999) & 0x0ffffffff;
                E = D;
                D = C;
                C = SHA1.rotate_left(B,30);
                B = A;
                A = temp;
            }

            for( i=20; i<=39; i++ ) {
                temp = (SHA1.rotate_left(A,5) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff;
                E = D;
                D = C;
                C = SHA1.rotate_left(B,30);
                B = A;
                A = temp;
            }

            for( i=40; i<=59; i++ ) {
                temp = (SHA1.rotate_left(A,5) + ((B&C) | (B&D) | (C&D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff;
                E = D;
                D = C;
                C = SHA1.rotate_left(B,30);
                B = A;
                A = temp;
            }

            for( i=60; i<=79; i++ ) {
                temp = (SHA1.rotate_left(A,5) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6) & 0x0ffffffff;
                E = D;
                D = C;
                C = SHA1.rotate_left(B,30);
                B = A;
                A = temp;
            }

            H0 = (H0 + A) & 0x0ffffffff;
            H1 = (H1 + B) & 0x0ffffffff;
            H2 = (H2 + C) & 0x0ffffffff;
            H3 = (H3 + D) & 0x0ffffffff;
            H4 = (H4 + E) & 0x0ffffffff;

        }

        temp = SHA1.cvt_hex(H0) + SHA1.cvt_hex(H1) + SHA1.cvt_hex(H2) + SHA1.cvt_hex(H3) + SHA1.cvt_hex(H4);

        return temp.toLowerCase();

    }
	//
	//
	tenduke.util.SHA1 = SHA1;
})();// JavaScript Document
(function() {
	//
	// Package
	var _package=tenduke.util;
	//
	// Constructor
/**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info/
*
**/

var Base64 = {

    // private property
    _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

    // public method for encoding
    encode64 : function (input) {
		if(input == null || input == undefined){
        	return null;
		}
 		if(input == ""){
        	return "";
		}
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var i = 0;

        input = Base64._utf8_encode(input);

        while (i < input.length) {

            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);

            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;

            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }

            output = output +
            this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
            this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

        }

        return output;
    },

    // public method for decoding
    decode64 : function (input) {
		if(input == null || input == undefined){
        	return null;
		}
 		if(input == ""){
        	return "";
		}
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;

        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

        while (i < input.length) {

            enc1 = this._keyStr.indexOf(input.charAt(i++));
            enc2 = this._keyStr.indexOf(input.charAt(i++));
            enc3 = this._keyStr.indexOf(input.charAt(i++));
            enc4 = this._keyStr.indexOf(input.charAt(i++));

            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;

            output = output + String.fromCharCode(chr1);

            if (enc3 != 64) {
                output = output + String.fromCharCode(chr2);
            }
            if (enc4 != 64) {
                output = output + String.fromCharCode(chr3);
            }

        }

        output = Base64._utf8_decode(output);

        return output;

    },

    // private method for UTF-8 encoding
    _utf8_encode : function (string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";

        for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }

        }

        return utftext;
    },

    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;

        while ( i < utftext.length ) {

            c = utftext.charCodeAt(i);

            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }

        }

        return string;
    }

}
	//
	//
	_package.Base64=Base64;
})();/**
 * Utility class for working with XML and text that represents XML documents.
 */
(function() {

    var XmlUtils = {};

    /**
     * Iterate XML DOM and return first node by the specified name.
     * @param startNode Node to start search from
     * @param nodeName Node name to search for
     * @return Handle to node in XML document with the specified name
     *
     */
    XmlUtils.findFirstNodeByName = function(startNode, nodeName) {
        //
        //
        var retValue = null;
        if(startNode && nodeName && startNode.nodeName==nodeName) {
            retValue = startNode;
        }
        else if(startNode && startNode.childNodes) {
            for(var i=0; i<startNode.childNodes.length; i++) {
                retValue = findFirstNodeByName(startNode.childNodes[i], nodeName);
                if(retValue) {
                    break;
                }
            }
        }
        return retValue;
    }

    /**
     * Create a JS Dom object by text.
     * @param xmlAsText
     * @return DOM object based on parser processed text
     */
    XmlUtils.createDomDocumentFromText = function(xmlAsText) {
        //
        //
        var aParser = new DOMParser();
        //
        //
        var retValue = null;
        if(xmlAsText!=null && xmlAsText!=undefined) {
            try {
                retValue = aParser.parseFromString(xmlAsText, "text/xml");
            }
            catch(xmlParserE) {
            }
        }
        //
        //
        return retValue;
    }
    //
    //
    tenduke.util.XmlUtils = XmlUtils;

})();
tenduke.util.html={};tenduke.util.js={};//
(function() {
    var Function_ = {};
    
    /**
     * 
     */
    Function_.createScopedFunction = function(scope, func) {
        return function() {
            if(func) {
                func.apply(scope, arguments);
            }
        };
    }
    
    tenduke.util.js.Function = Function_;
})();
var tenduke = tenduke || {};
tenduke.util = tenduke.util || {};
tenduke.util.html = tenduke.util.html || {};
(function() {
	//
	// Package
	var _package=tenduke.util.html;
	//
	// Imports
	//
	// Constructor
	/*
	* The History object is a singleton. History COntructor shall not be called outside this class.
	* When the History class is inluded in the build/html page the history object is automaticly created.
	* and accessible through tenduke.util.History
	*/
	var DOMUtils=function(){}
	//
	//
	/** */
	
	/*
	* get the dom element handle based on argument. If the argument is a dom node the we just return it.
	*/
	DOMUtils.prototype.getDOMElement=function(arg){
		if(typeof arg == "string"){
			return document.getElementById(arg);
		}
		else{
			return arg;
		}
	}
	//
	//
	DOMUtils.prototype.hideElement=function(element){
	    return this.setAttribute(element,"style","display:none; visibility:hidden;");
	}
	//
	//
	DOMUtils.prototype.showElement=function(element, clientStyle){
		return this.setAttribute(element,"style", clientStyle);
	}
	//
	//
	DOMUtils.prototype.getAppliedCSSValue=function(el,styleProp){
	    var element = this.getDOMElement(el);
	    if(element){
		    var y = null;
		    if (element.currentStyle) {
		        y = element.currentStyle[styleProp];
		    }
		    else if (window.getComputedStyle) {
		        y = document.defaultView.getComputedStyle(element,null).getPropertyValue(styleProp);
		    }
		    return y;
	    }
	    return null;
	}
	//
	//
	DOMUtils.prototype.setAttribute=function(element,atr,value){
		element= this.getDOMElement(element);
		var retVal=null;
		if(element){
			if(atr=="class"){
				retVal=element.className;
				if(value===null){
					element.removeAttribute(atr);
				}
				else{
					element.className=value;
				}
			}
			else if(atr=="style"){
				retVal=element.style.cssText;
				if(value===null){
					element.removeAttribute(atr);
				}
				else{
					element.style.cssText=value;
				}
			}
			else{
				retVal=element.getAttribute(atr);
				if(value===null){
					element.removeAttribute(atr);
				}
				else{
					element.setAttribute(atr,value);
				}
			}
		}
		return retVal;
	}
	//
	//
	DOMUtils.prototype.getAttribute=function(element,atr){
		element= this.getDOMElement(element);
		var retVal=null;
		if(element){
			if(atr=="class"){
				retVal=element.className;
			}
			else if(atr=="style"){
				retVal=element.style.cssText;
			}
			else{
				retVal=el.getAttribute(atr);
			}
		}
		return retVal;
	}
	DOMUtils.prototype.appendToAttribute=function(element,atr,value){
		var t=this.getAttribute(element,atr);
		return this.setAttribute(element,atr,t+value);
	}
	DOMUtils.prototype.spliceFromAttribute=function(element,atr,value){
		var t=this.getAttribute(element,atr);
		t=t.replace(value,"");
		return this.setAttribute(element,atr,t);
	}
	DOMUtils.prototype.removeAttribute=function(element,atr){
		return this.setAttribute(element,atr,null);
	}
	
	DOMUtils.prototype.matchAttribute=function(element,atr,value){
		var t= this.getAttribute(element,atr);
		if(t!==null){
			return t.indexOf(value);
		}
		else{
			return null;
		}
	}
	
	
	/** */
	DOMUtils.prototype.attachEventToElement=function(element,eventname,eventHandler){
		element=this.getDOMElement(element);
	    if(element){
	        if(element.addEventListener){
	            element.addEventListener(eventname,eventHandler,false);
	        }
	        else if(element.attachEvent){
	            element.attachEvent("on"+eventname,eventHandler);
	        }
	        else {
	        	element['on'+eventname] = eventHandler;
	    	}
	    }
	}
	DOMUtils.prototype.removeEventFromElement=function( element, eventname, eventHandler ) {
		element=this.getDOMElement(element);
	    if ( element.removeEventListener ) {
	        element.removeEventListener( eventname, eventHandler, false );
	    }
	    else if ( element.detachEvent ) {        
	        element.detachEvent( "on"+eventname, eventHandler );
	    }
	    else {
	        element['on'+eventname] = null;
	    }
	}

    /**
     * Return the node value for the first node with name nodeName (depth first search)
     * @param node The node to start search in (given root node is part of search)
     * @param nodeName A node name to search for.
     * @return node's text content
     */
	DOMUtils.prototype.getNodeValueByNodeName = function(node, nodeName){
        //
        //
        var retValue = null;
		//
        //
        if(node){
            //
            //
            if(node.nodeName!=null && node.nodeName!=undefined && node.nodeName==nodeName) {
                retValue = DOMUtils.prototype.getNodesTextContent(node);
            }
            else if(node.localName!=null && node.localName!=undefined && node.localName==nodeName) {
                retValue = DOMUtils.prototype.getNodesTextContent(node);
            }
            //
            //
            if(retValue==null) {
                var nodeChildren = node.childNodes;
                if(nodeChildren && nodeChildren.length>0){
                    var i = nodeChildren.length;
                    while(i>0){
                        i--;
                        retValue = this.getNodeValueByNodeName(nodeChildren[i], nodeName);
                        if(retValue!=null) {
                            break;
                        }
                    }
                }
            }
        }
        //
        //
        return retValue;
	}

    /**
     * Return the elements text content as string value
     * @param node The node whos text content is requested.
     * @return node's text content as string (null for error or if no text content is found)
     */
	DOMUtils.prototype.getNodesTextContent = function(node) {
        //
        //
        var retValue = null;
		//
        //
        if(node!=null && node!=undefined) {
            //
            //
            retValue = node.nodeValue;
            if(retValue==null || retValue==undefined) {
                retValue = node.textContent;
            }
            //
            //
            if(retValue==null || retValue==undefined) {
                //
                //
                var nodeChildren = node.childNodes;
                if(nodeChildren && nodeChildren.length>0){
                    //
                    //
                    var i = nodeChildren.length;
                    while(i>0){
                        i--;
                        if(nodeChildren[i] && nodeChildren[i].nodeType==Node.TEXT_NODE) {
                            retValue = nodeChildren[i].nodeValue;
                            if(retValue==null || retValue==undefined) {
                                retValue = node.textContent;
                                break;
                            }
                        }
                    }
                }
            }
        }
        //
        //
        return retValue;
	}

    /**
     * Dump information about a DOM node.
     * @param node The start node to start iteration from
     * @param level The current iteration level (optional)
     */
    DOMUtils.prototype.dumpNode = function(node, level) {
        //
        //
        if(node) {
            //
            //
            if(level==null || level==undefined) {
                level = 0;
            }
            //
            //
            showAlert("Node(" + level + "):\n node.localName = " + node.localName + ", node.nodeName = " + node.nodeName + ", node.nodeType = " + node.nodeType + "\nnode.nodeValue = " + node.nodeValue);
            //
            //
            var nodeChildren = node.childNodes;
            if(nodeChildren && nodeChildren.length>0){
                var i = nodeChildren.length;
                var localLevel = level + 1;
                while(i>0){
                    i--;
                    this.dumpNode(nodeChildren[i], localLevel);
                }
            }
        }
    }
	//
	//
	_package.DOMUtils=new DOMUtils();
})();//
//
var tenduke = tenduke || {};
tenduke.util = tenduke.util || {};
tenduke.util.html = tenduke.util.html || {};
(function() {
	//
	// Package
	var _package=tenduke.util.html;
	//
	//
	// Imports
	//
	//
	// Constructor
	var Cookies=function(){};
	//
	//
	//variables
	/** */
	Cookies.prototype.TEST_SESSION_COOKIE_NAME = "tsc";
	/** */
	Cookies.prototype.TEST_SESSION_COOKIE_VALUE = "enabled";
	/** */
	Cookies.prototype.TEST_PERSISTENT_COOKIE_NAME = "tpc";
	/** */
	Cookies.prototype.TEST_PERSISTENT_COOKIE_VALUE = "enabled";
	/** */
	Cookies.prototype.TEST_PERSISTENT_COOKIE_SCOPE = "minutes";
	/** */
	Cookies.prototype.EP_TYPE_YEAR = 0;
	/** */
	Cookies.prototype.EP_TYPE_MONTH = 1;
	/** */
	Cookies.prototype.EP_TYPE_DAY = 2;
	/** */
	Cookies.prototype.EP_TYPE_HOUR = 3;
	/** */
	Cookies.prototype.EP_TYPE_MINUTE = 4;
	/** */
	Cookies.prototype._sessionCookiesSupported = null;
	/** */
	Cookies.prototype._persistentCookiesSupported = null;
	/**
	 *
	 */
	Cookies.prototype.writeSessionCookie =function (cookieName, cookieValue) {
	    if (this.testSessionCookie()==true) {
	        document.cookie = escape(cookieName) + "=" + escape(cookieValue) + "; path=/";
	        return true;
	    }
	    else {
	        return false;
	   	}
	}
	/**
	 *
	 */
	Cookies.prototype.writePersistentCookie = function (cookieName, cookieValue, periodType, offset) {
		if(this.testPersistentCookie()==true){
		    //
		    //
		    var expireDate = new Date ();
		    offset = offset / 1;
		    //
		    //
		    switch (periodType) {
		        case 0:
		            expireDate.setYear(expireDate.getFullYear()+offset);
		            break;
		        case 1:
		            expireDate.setMonth(expireDate.getMonth()+offset);
		            break;
		        case 2:
		            expireDate.setDate(expireDate.getDate()+offset);
		            break;
		        case 3:
		            expireDate.setHours(expireDate.getHours()+offset);
		            break;
		        case 4:
		            expireDate.setMinutes(expireDate.getMinutes()+offset);
		            break;
		        default:
		            //alert ("Invalid periodType parameter for writePersistentCookie()");
		            break;
		    } 
		
		    document.cookie = escape(cookieName ) + "=" + escape(cookieValue) + "; expires=" + expireDate.toGMTString() + "; path=/";
		}
	}  

	/**
	 *
	 */
	Cookies.prototype.deleteCookie = function (cookieName) {
	    //
	    //
	    if (this.getCookie(cookieName)) {
	        this.writePersistentCookie (cookieName,"Pending delete","years", -1);  
	    }
	    return true;     
	}

	/**
	 *
	 */
	Cookies.prototype.getCookie = function(cookieName) {
	    var exp = new RegExp (escape(cookieName) + "=([^;]+)");
	    if (exp.test (document.cookie + ";")) {
	        exp.exec (document.cookie + ";");
	        return unescape(RegExp.$1);
	    }
	    else return false;
	}

	/**
	 *
	 */
	Cookies.prototype.testSessionCookie = function() {
		if(this._sessionCookiesSupported===null){
		    document.cookie = this.TEST_SESSION_COOKIE_NAME + "=" + this.TEST_SESSION_COOKIE_VALUE;
		    if ( this.getCookie(this.TEST_SESSION_COOKIE_NAME)==this.TEST_SESSION_COOKIE_VALUE ){
		    	this._sessionCookiesSupported=true;
		    }
		    else{
		    	this._sessionCookiesSupported=false;
		    }
		}
		return this._sessionCookiesSupported;
	}

	/**
	 *
	 */
	Cookies.prototype.testPersistentCookie = function() {
		if(this._persistentCookiesSupported===null){
			var expireDate=new Date();
			expireDate.setYear(expireDate.getFullYear()+1);
			document.cookie = escape(this.TEST_PERSISTENT_COOKIE_NAME ) + "=" + escape(this.TEST_PERSISTENT_COOKIE_VALUE) + "; expires=" + expireDate.toGMTString() + "; path=/";
		    if (this.getCookie(this.TEST_PERSISTENT_COOKIE_NAME)==this.TEST_PERSISTENT_COOKIE_VALUE){
		        this._persistentCookiesSupported=true;
		    }
		    else{
		    	this._persistentCookiesSupported=false;
		    }
		}
		return this._persistentCookiesSupported;
	}
	//
	//
	_package.Cookies=new Cookies();
})();// JavaScript Document
(function() {
	//
	// Package
	var _package=tenduke.util;
	//
	//
	var DOMUtils=tenduke.util.html.DOMUtils;
	//
	// Constructor
	/*
	* The ResourceImporter object is a singleton. ResourceImporter Constructor shall not be called outside this class.
	* When the ResourceImporter class is inluded in the build/html page the ResourceImporter object is automaticly created.
	* and accessible through tenduke.util.ResourceImporter
	*/
	var ResourceImporter=function(){}
	//
	// properties
	// "STATIC"
	ResourceImporter.prototype.JS_FILE=0;
	ResourceImporter.prototype.CSS_FILE=1;
	//
	//
	ResourceImporter.prototype._importedResources={};
	//
	// functions
	ResourceImporter.prototype.importJS=function(url,callback){
		this.importResource(this.JS_FILE,url,callback);
	}
	ResourceImporter.prototype.importCSS=function(url,callback){
		this.importResource(this.CSS_FILE,url,callback);
	}
	ResourceImporter.prototype.importResource = function(type,url,callback){
		if(type!=null){	
			if(this._importedResources[type] && this._importedResources[type][url]){
				if(callback){
					return callback();
				}
			}
			else{
				var head = document.getElementsByTagName("head")[0];         
				if(head){
					var newChild;
					if(type==this.JS_FILE){
						newChild = document.createElement('script');
						newChild.setAttribute("type","text/javascript");
						newChild.setAttribute("language","javascript");
					}
					else if(type==this.CSS_FILE){
						newChild = document.createElement('link');
						newStyle.setAttribute("rel","stylesheet");
						newStyle.setAttribute("type","text/css");
					}
					head.appendChild(newChild);
					
					if(callback){
						if(isIE()==true){
							var f=function(e){
								if(window.event.srcElement.readyState=="loaded"){
									return callback();
								}
							}			
							newChild.onreadystatechange=f;
						}
						else{
							DOMUtils.attachEventToElement(newChild,"load",callback);
						}
					}
					
					if(type==this.JS_FILE){
						newChild.setAttribute("src",url);
					}
					else if(type==this.CSS_FILE){
						newStyle.setAttribute("href",url);
					}
					if(!this._importedResources[type]){
						this._importedResources[type]={};
					}
					this._importedResources[type][url]=true;
				}
			}
		}
	}
	ResourceImporter.prototype.importJSCollection=function(urlArray,callback){
		this.importResourceCollection([this.JS_FILE],urlArray,callback);
	}
	ResourceImporter.prototype.importCSSCollection=function(urlArray,callback){
		this.importResourceCollection([this.CSS_FILE],urlArray,callback);
	}
	ResourceImporter.prototype.importResourceCollection=function(typeArray,urlArray,callback){
		if(urlArray && urlArray.length>0 && typeArray && typeArray.length>0){
			var len=urlArray.length;
			var ind=0;
			
			var c=function(){
				ind++;
				if(ind>=len){
					return callback();
				}
				
			}
			for(var i=0; i<urlArray.length; i++){
				if(i>=typeArray.length){
					this.importResource(typeArray[typeArray.length-1],urlArray[i],c);
				}
				else{
					this.importResource(typeArray[i],urlArray[i],c);
				}
			}
		}
	}
	
	_package.ResourceImporter=new ResourceImporter();
})();//
// initialize package
var tenduke = tenduke || {};
tenduke.objectmodel = tenduke.objectmodel || {};

/**
 * An "annotation" class that is used to control object model field serialization.
 */
(function() {

    //
    // Constructor
    var SerializableField = function(name, relation, length) {
        if(relation!=undefined) {
            this._relation = relation;
        }
        if(length!=undefined) {
            this._length = length;
        }
        if(name!=undefined) {
            this._name = name;
        }
    };

    /**
     * Static constants describing object model relations
     */
    SerializableField.RELATION_ONE_TO_ONE = 0;
    SerializableField.RELATION_MANY_TO_ONE = 1;
    SerializableField.RELATION_ONE_TO_MANY = 2;
    SerializableField.RELATION_MANY_TO_MANY = 3;

    /** */
    SerializableField.prototype._relation = null;

    /** */
    SerializableField.prototype._length = null;

    /** */
    SerializableField.prototype._name = null;

    /**
     * Name of the field used for serialization
     */
    SerializableField.prototype.getName = function() {
        return this._name;
    }
    
    /**
     * Name of the field used for serialization
     */
    SerializableField.prototype.setName = function(rhs) {
        this._name = rhs;
    }
    
    /**
     * Length of the field, negative value means undefined / unlimited
     */
    SerializableField.prototype.getLength = function() {
        return this._length;
    }
    
    /**
     * Length of the field, negative value means undefined / unlimited
     */
    SerializableField.prototype.setLength = function(rhs) {
        this._length = rhs;
    }

    /**
     * Get relation between the object that contains the annotated field and the object(s) referred to by the field.
     * By default the relation is decided based on type of the field so that default relation for List fields is
     * RELATION_ONE_TO_MANY and default for singleton fields is RELATION_ONE_TO_ONE.
     */
    SerializableField.prototype.getRelation = function() {
        return this._relation;
    }

    /**
     * Set relation between the object that contains the annotated field and the object(s) referred to by the field.
     * By default the relation is decided based on type of the field so that default relation for List fields is
     * RELATION_ONE_TO_MANY and default for singleton fields is RELATION_ONE_TO_ONE.
     */
    SerializableField.prototype.setRelation = function(rhs) {
        this._relation = rhs;
    }

    tenduke.objectmodel.SerializableField = SerializableField;

})();
//
// initialize package
var tenduke = tenduke || {};
tenduke.objectmodel = tenduke.objectmodel || {};

/**
 * Base class for all object model objects
 */
(function() {

    // Imports
    var SerializableField = tenduke.objectmodel.SerializableField;
    //
    // Constructor
    var TendukeObject = function() {
    };
    TendukeObject.classSimpleName = "TendukeObject";

    //
    // Introduce using annotations
    TendukeObject.annotations = {};
    
    /** */
    TendukeObject.annotations._id = [ new SerializableField("id") ];
    TendukeObject.prototype._id = null;
    
    /** */
    TendukeObject.prototype.getId = function() {
        return this._id;
    }
    
    /** */
    TendukeObject.prototype.setId = function(anId) {
        this._id = anId;
    }  

    tenduke.objectmodel.TendukeObject = TendukeObject;

})();
//
// initialize package
var tenduke = tenduke || {};
tenduke.objectmodel = tenduke.objectmodel || {};

/**
 * Object model class for Account
 */
(function() {
    //
    // Imports
    var SerializableField = tenduke.objectmodel.SerializableField;
    var TendukeObject = tenduke.objectmodel.TendukeObject;

    //
    // Constructor
    var Account = function() {
        Account.prototype.superClass.constructor.call();
    };

    //
    //
    Account.classSimpleName = "Account";
    copyPrototype(Account,TendukeObject);
    Account.prototype.superClass = TendukeObject.prototype;

    //
    // Introduce using annotations
    Account.annotations = {};

    /** */
    Account.annotations._accountId = [ new SerializableField("id") ];
    Account.prototype._accountId = null;

    /** */
    Account.annotations._primaryPrincipal = [ new SerializableField("primaryPrincipal") ];
    Account.prototype._primaryPrincipal = null;

    /** */
    Account.annotations._primaryEmail = [ new SerializableField("primaryEmail") ];
    Account.prototype._primaryEmail = null;

    /** */
    Account.annotations._primaryPassword = [ new SerializableField("primaryPassword") ];
    Account.prototype._primaryPassword = null;


    /** */
    Account.prototype.getAccountId = function() {
        return this._accountId;
    }
    
    /** */
    Account.prototype.setAccountId = function(rhs) {
        this._accountId = rhs;
    }

    /** */
    Account.prototype.getPrimaryPrincipal = function() {
        return this._primaryPrincipal;
    }

    /** */
    Account.prototype.setPrimaryPrincipal = function(rhs) {
        this._primaryPrincipal = rhs;
    }

    /** */
    Account.prototype.getPrimaryEmail = function() {
        return this._primaryEmail;
    }

    /** */
    Account.prototype.setPrimaryEmail = function(rhs) {
        this._primaryEmail = rhs;
    }

    /** */
    Account.prototype.getPrimaryPassword = function() {
        return this._primaryPassword;
    }

    /** */
    Account.prototype.setPrimaryPassword = function(rhs) {
        this._primaryPassword = rhs;
    }
    
    //
    //
    tenduke.objectmodel.Account = Account;

})();
//
// initialize package
var tenduke = tenduke || {};
tenduke.objectmodel = tenduke.objectmodel || {};

/**
 * Object model class for Profile
 */
(function() {
    //
    // Imports
    var SerializableField = tenduke.objectmodel.SerializableField;
    var TendukeObject = tenduke.objectmodel.TendukeObject;
    var DateAndTimeUtils = tenduke.util.DateAndTimeUtils;
    

    //
    // Constructor
    var Profile = function() {
        Profile.prototype.superClass.constructor.call();
    };
    Profile.classSimpleName = "Profile";
    copyPrototype(Profile,TendukeObject);
    Profile.prototype.superClass=TendukeObject.prototype;

    //
    // Introduce using annotations
    Profile.annotations = {};

    /** */
    Profile.annotations._profileId = [ new SerializableField("id") ];
    Profile.prototype._profileId = null;

    /** */
    Profile.prototype._accountId = null;

    /** */
    Profile.annotations._shortName = [ new SerializableField("shortName") ];
    Profile.prototype._shortName = null;

    /** */
    Profile.annotations._displayName = [ new SerializableField("displayName") ];
    Profile.prototype._displayName = null;

    /** */
    Profile.annotations._description = [ new SerializableField("description") ];
    Profile.prototype._description = null;
    
    /** */
    Profile.annotations._profileImageUrl = [ new SerializableField("profileImageUrl") ];
    Profile.prototype._profileImageUrl = null;

    /** */
    Profile.annotations._joined = [ new SerializableField("joined") ];
    Profile.prototype._joined = null;

    /** */
    Profile.annotations._birthday = [ new SerializableField("birthday") ];
    Profile.prototype._birthday = null;

    /** */
    Profile.annotations._gender = [ new SerializableField("gender") ];
    Profile.prototype._gender = null;

    /** */
    Profile.annotations._contactDetails = [ new SerializableField("contactDetails") ];
    Profile.prototype._contactDetails = null;


    /** */
    Profile.prototype.getProfileId = function() {
        return this._profileId;
    }
    
    /** */
    Profile.prototype.setProfileId = function(rhs) {
        this._profileId = rhs;
    }
    
    /** */
    Profile.prototype.getAccountId = function() {
        return this._accountId;
    }
    
    /** */
    Profile.prototype.setAccountId = function(rhs) {
        this._accountId = rhs;
    }

    /** */
    Profile.prototype.getShortName = function() {
        return this._shortName;
    }

    /** */
    Profile.prototype.setShortName = function(rhs) {
        this._shortName = rhs;
    }

    /** */
    Profile.prototype.getDisplayName = function() {
        return this._displayName;
    }

    /** */
    Profile.prototype.setDisplayName = function(rhs) {
        this._displayName = rhs;
    }

    /** */
    Profile.prototype.getDescription = function() {
        return this._description;
    }

    /** */
    Profile.prototype.setDescription = function(rhs) {
        this._description = rhs;
    }

    /** */
    Profile.prototype.getJoined = function() {
        return this._joined;
    }

    /** */
    Profile.prototype.setJoined = function(rhs) {
        //
        //
        if(rhs!=null && rhs!=undefined && rhs.constructor == (new Date()).constructor) {
            rhs = DateAndTimeUtils.formatIso8601UtcDate(rhs);
        }
        this._joined = rhs;
    }

    /** */
    Profile.prototype.getBirthday = function() {
        return this._birthday;
    }

    /** */
    Profile.prototype.setBirthday = function(rhs) {
        //
        //
        if(rhs!=null && rhs!=undefined && rhs.constructor == (new Date()).constructor) {
            rhs = DateAndTimeUtils.formatIso8601UtcDate(rhs);
        }
        this._birthday = rhs;
    }

    /** */
    Profile.prototype.getProfileImageUrl = function() {
        return this._profileImageUrl;
    }

    /** */
    Profile.prototype.setProfileImageUrl = function(rhs) {
        this._profileImageUrl = rhs;
    }
    
    /** */
    Profile.prototype.getGender = function() {
        return this._gender;
    }

    /** */
    Profile.prototype.setGender = function(rhs) {
        this._gender = rhs;
    }

    /** */
    Profile.prototype.setContactDetails = function(rhs) {
        this._contactDetails = new Array();
        this._contactDetails.push(rhs);
    }

    /** */
    Profile.prototype.getContactDetails = function() {
        var retValue = null;
        if(this._contactDetails  && this._contactDetails.length>0) {
            retValue = this._contactDetails[0];
        }
        return retValue;
    }

    tenduke.objectmodel.Profile = Profile;

})();
//
// initialize package
var tenduke = tenduke || {};
tenduke.objectmodel = tenduke.objectmodel || {};

/**
 * Object model class for ContactDetails
 */
(function() {
    //
    // Imports
    var SerializableField = tenduke.objectmodel.SerializableField;
    var TendukeObject = tenduke.objectmodel.TendukeObject;

    //
    // Constructor
    var ContactDetails = function() {
        ContactDetails.prototype.superClass.constructor.call();
    };

    //
    //
    ContactDetails.classSimpleName = "ContactDetails";
    copyPrototype(ContactDetails, TendukeObject);
    ContactDetails.prototype.superClass = TendukeObject.prototype;

    //
    // Introduce using annotations
    ContactDetails.annotations = {};

    /** */
    ContactDetails.annotations._contactDetailsId = [ new SerializableField("id") ];
    ContactDetails.prototype._contactDetailsId = null;

    /** */
    ContactDetails.prototype._profileId = null;

    /** */
    ContactDetails.annotations._formattedName = [ new SerializableField("formattedName") ];
    ContactDetails.prototype._formattedName = null;

    /** */
    ContactDetails.annotations._givenName = [ new SerializableField("givenName") ];
    ContactDetails.prototype._givenName = null;

    /** */
    ContactDetails.annotations._familyName = [ new SerializableField("familyName") ];
    ContactDetails.prototype._familyName = null;

    /** */
    ContactDetails.annotations._title = [ new SerializableField("title") ];
    ContactDetails.prototype._title = null;

    /** */
    ContactDetails.annotations._emails = [ new SerializableField("emails") ];
    ContactDetails.prototype._emails = new Array();

    /** */
    ContactDetails.annotations._postalAddress = [ new SerializableField("postalAddress") ];
    ContactDetails.prototype._postalAddress = new Array();

    /** */
    ContactDetails.prototype.getContactDetailsId = function() {
        return this._contactDetailsId;
    }
    
    /** */
    ContactDetails.prototype.setContactDetailsId = function(rhs) {
        this._contactDetailsId = rhs;
    }
    
    /** */
    ContactDetails.prototype.getProfileId = function() {
        return this._profileId;
    }
    
    /** */
    ContactDetails.prototype.setProfileId = function(rhs) {
        this._profileId = rhs;
    }

    /** */
    ContactDetails.prototype.getFormattedName = function() {
        return this._formattedName;
    }

    /** */
    ContactDetails.prototype.setFormattedName = function(rhs) {
        this._formattedName = rhs;
    }

    /** */
    ContactDetails.prototype.getGivenName = function() {
        return this._givenName;
    }

    /** */
    ContactDetails.prototype.setGivenName = function(rhs) {
        this._givenName = rhs;
    }

    /** */
    ContactDetails.prototype.getFamilyName = function() {
        return this._familyName;
    }

    /** */
    ContactDetails.prototype.setFamilyName = function(rhs) {
        this._familyName = rhs;
    }

    /** */
    ContactDetails.prototype.getTitle = function() {
        return this._title;
    }

    /** */
    ContactDetails.prototype.setTitle = function(rhs) {
        this._title = rhs;
    }
    
    /** */
    ContactDetails.prototype.setEmail = function(rhs) {
        this._emails = new Array();
        this._emails.push(rhs);
    }

    /** */
    ContactDetails.prototype.getEmail = function() {
        var retValue = null;
        if(this._emails  && this._emails.length>0) {
            retValue = this._emails[0];
        }
        return retValue;
    }
    
    /** */
    ContactDetails.prototype.setPostalAddress = function(rhs) {
        this._postalAddress = new Array();
        this._postalAddress.push(rhs);
    }

    /** */
    ContactDetails.prototype.getPostalAddress = function() {
        var retValue = null;
        if(this._postalAddress  && this._postalAddress.length>0) {
            retValue = this._postalAddress[0];
        }
        return retValue;
    }

    //
    //
    tenduke.objectmodel.ContactDetails = ContactDetails;

})();
//
// initialize package
var tenduke = tenduke || {};
tenduke.objectmodel = tenduke.objectmodel || {};

/**
 * Object model class for EmailAddress
 */
(function() {
    //
    // Imports
    var SerializableField = tenduke.objectmodel.SerializableField;
    var TendukeObject = tenduke.objectmodel.TendukeObject;

    //
    // Constructor
    var EmailAddress = function() {
        EmailAddress.prototype.superClass.constructor.call();
    };

    //
    //
    EmailAddress.classSimpleName = "EmailAddress";
    copyPrototype(EmailAddress, TendukeObject);
    EmailAddress.prototype.superClass = TendukeObject.prototype;

    //
    // Introduce using annotations
    EmailAddress.annotations = {};

    /** */
    EmailAddress.annotations._emailAddressId = [ new SerializableField("id") ];
    EmailAddress.prototype._emailAddressId = null;

    /** */
    EmailAddress.prototype._contactDetailsId = null;

    /** */
    EmailAddress.annotations._isPreferred = [ new SerializableField("isPreferred") ];
    EmailAddress.prototype._isPreferred = null;

    /** */
    EmailAddress.annotations._value = [ new SerializableField("value") ];
    EmailAddress.prototype._value = null;


    /** */
    EmailAddress.prototype.getEmailAddressId = function() {
        return this._emailAddressId;
    }
    
    /** */
    EmailAddress.prototype.setEmailAddressId = function(rhs) {
        this._emailAddressId = rhs;
    }
    
    /** */
    EmailAddress.prototype.getContactDetailsId = function() {
        return this._contactDetailsId;
    }
    
    /** */
    EmailAddress.prototype.setContactDetailsId = function(rhs) {
        this._contactDetailsId = rhs;
    }

    /** */
    EmailAddress.prototype.getValue = function() {
        return this._value;
    }

    /** */
    EmailAddress.prototype.setValue = function(rhs) {
        this._value = rhs;
    }

    /** */
    EmailAddress.prototype.getIsPreferred = function() {
        return this._isPreferred;
    }

    /** */
    EmailAddress.prototype.setIsPreferred = function(rhs) {
        this._isPreferred = rhs;
    }

    //
    //
    tenduke.objectmodel.EmailAddress = EmailAddress;

})();
//
// initialize package
var tenduke = tenduke || {};
tenduke.objectmodel = tenduke.objectmodel || {};

/**
 * Object model class for PostalAddress
 */
(function() {
    //
    // Imports
    var SerializableField = tenduke.objectmodel.SerializableField;
    var TendukeObject = tenduke.objectmodel.TendukeObject;

    //
    // Constructor
    var PostalAddress = function() {
        PostalAddress.prototype.superClass.constructor.call();
    };

    //
    //
    PostalAddress.classSimpleName = "PostalAddress";
    copyPrototype(PostalAddress, TendukeObject);
    PostalAddress.prototype.superClass = TendukeObject.prototype;

    //
    // Introduce using annotations
    PostalAddress.annotations = {};

    /** */
    PostalAddress.annotations._postalAddressId = [ new SerializableField("id") ];
    PostalAddress.prototype._postalAddressId = null;

    /** */
    PostalAddress.prototype._contactDetailsId = null;

    /** */
    PostalAddress.annotations._streetAddress = [ new SerializableField("streetAddress") ];
    PostalAddress.prototype._streetAddress = null;

    /** */
    PostalAddress.annotations._state = [ new SerializableField("state") ];
    PostalAddress.prototype._state = null;

    /** */
    PostalAddress.annotations._city = [ new SerializableField("city") ];
    PostalAddress.prototype._city = null;

    /** */
    PostalAddress.annotations._postalCode = [ new SerializableField("postalCode") ];
    PostalAddress.prototype._postalCode = null;

    /** */
    PostalAddress.annotations._country = [ new SerializableField("country") ];
    PostalAddress.prototype._country = null;


    /** */
    PostalAddress.prototype.getPostalAddressId = function() {
        return this._postalAddressId;
    }
    
    /** */
    PostalAddress.prototype.setPostalAddressId = function(rhs) {
        this._postalAddressId = rhs;
    }
    
    /** */
    PostalAddress.prototype.getContactDetailsId = function() {
        return this._contactDetailsId;
    }
    
    /** */
    PostalAddress.prototype.setContactDetailsId = function(rhs) {
        this._contactDetailsId = rhs;
    }

    /** */
    PostalAddress.prototype.getStreetAddress = function() {
        return this._streetAddress;
    }

    /** */
    PostalAddress.prototype.setStreetAddress = function(rhs) {
        this._streetAddress = rhs;
    }

    /** */
    PostalAddress.prototype.getState = function() {
        return this._state;
    }

    /** */
    PostalAddress.prototype.setState = function(rhs) {
        this._state = rhs;
    }
    
    /** */
    PostalAddress.prototype.getCity = function() {
        return this._city;
    }

    /** */
    PostalAddress.prototype.setCity = function(rhs) {
        this._city = rhs;
    }
    
    /** */
    PostalAddress.prototype.getPostalCode = function() {
        return this._postalCode;
    }

    /** */
    PostalAddress.prototype.setPostalCode = function(rhs) {
        this._postalCode = rhs;
    }
    
    /** */
    PostalAddress.prototype.getCountry = function() {
        return this._country;
    }

    /** */
    PostalAddress.prototype.setCountry = function(rhs) {
        this._country = rhs;
    }

    //
    //
    tenduke.objectmodel.PostalAddress = PostalAddress;

})();
var tenduke = tenduke || {};
tenduke.networking = tenduke.networking || {} ;
(function() {
	//IMPORTS
    var Response = function(){
    	
    };
    Response.prototype.success=null;
    Response.prototype.responseCode=null;
    Response.prototype.error=null;
    Response.prototype.data=null;
    tenduke.networking.Response = Response;
})();var tenduke = tenduke || {};
tenduke.networking = tenduke.networking || {};
(function() {
	//IMPORTS
   	var RequestParameters={};
   	/*
   	* "text/xml","text/plain"
   	*/
    RequestParameters.CONTENT_TYPE	=	"content_type";
    RequestParameters.HEADERS		=	"headers";
    /*
    * "GET" or "POST"
    */
    RequestParameters.METHOD		=	"method";
    RequestParameters.POST_DATA		=	"post_data";
 
    tenduke.networking.RequestParameters = RequestParameters;
})();var tenduke = tenduke || {};
tenduke.networking = tenduke.networking || {};
(function() {
    //IMPORTS
    Response = tenduke.networking.Response;
    
    var Request = function(url,params){
        this._url=url;
        this._params=params;
    };
    //
    //
    Request.prototype._url = null;
    Request.prototype._params = null;
    //
    //
    Request.makeRequest=function(url,params) {
        return new Request(url,params);
    }
    Request.prototype.execute=function(calback) {
    
    }
    Request.prototype.setUrl=function(url) {
        this._url=url;
    }
    Request.prototype.getUrl=function() {
        return this._url;
    }
    Request.prototype.setParams=function(params) {
        this._params=params;
    }
    Request.prototype.getParams=function() {
        return this._params;
    }
    tenduke.networking.Request = Request;
})();var tenduke = tenduke || {};
tenduke.networking = tenduke.networking || {};
(function() {
    /*
	* IMPORTS
	* sarissa.js
	*/
    Request = tenduke.networking.Request;
    RequestParameters = tenduke.networking.RequestParameters;
    Response = tenduke.networking.Response;
    
    var XmlHttpRequest = function(url,params){
        XmlHttpRequest.prototype.superClass.constructor.call(this,url,params);
    };
    //
    //
    copyPrototype(XmlHttpRequest,Request);
    //
    //
    XmlHttpRequest.prototype.superClass=Request.prototype;
    
    /**
     *
     */
    XmlHttpRequest.makeRequest = function(url, params) {
        return new XmlHttpRequest(url, params);
    }

    /**
     *
     */
    XmlHttpRequest.prototype._initRequest=function(){
        var retVal = new XMLHttpRequest();
        this._xmlHttpRequest = retVal;
        if(this._url){
            if(this._params){
                if(this._params[RequestParameters.METHOD]){
                    this._xmlHttpRequest.open(this._params[RequestParameters.METHOD], this._url, true);
                }
                else if(this._params[RequestParameters.POST_DATA]){
                    this._xmlHttpRequest.open("POST", this._url, true);
                }
                else{
                    this._xmlHttpRequest.open("GET", this._url, true);
                }
            }
            else{
                this._xmlHttpRequest.open("GET", this._url, true);
            }
        }
        return retVal;
    }

    /**
     * Execute request
     * @param callback Callback function to handle response
     */
    XmlHttpRequest.prototype.execute=function(callback) {
        //
        //
        var retValue=null;
        var xmlHttpRequest=this._initRequest();
        //
        //
        if(xmlHttpRequest){
            //
            //
            xmlHttpRequest.onreadystatechange = function (aRespEvt) {
                //
                //
                var resp = null;
                if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status=='200') {
                    //
                    //
                    resp = new Response();
                    resp.responseCode = xmlHttpRequest.status;
                    resp.success=true;
                    //
                    //
                    if(this._params && this._params[RequestParameters.CONTENT_TYPE]=="text/plain"){
                        resp.data=xmlHttpRequest.responseText;
                    }
                    else if(this._params==null || (this._params && this._params[RequestParameters.CONTENT_TYPE]=="text/xml")) {
                        if(xmlHttpRequest.responseXML){
                            resp.data = xmlHttpRequest.responseXML;
                        }
                        else if(xmlHttpRequest.responseText){
                            var xmlDoc = null;
                            var aParser = new DOMParser();
                            try {
                                xmlDoc = aParser.parseFromString(xmlHttpRequest.responseText, "text/xml");
                            }
                            catch(xmlE) {
                            }
                            resp.data = xmlDoc;
                        }
                    }
                    if(callback) {
                        callback(resp);
                    }
                }
            };
            try {
                if(this._params && this._params[RequestParameters.POST_DATA]){
                    xmlHttpRequest.send(this._params[RequestParameters.POST_DATA]);
                }
                else{
                    xmlHttpRequest.send("");
                }
                retValue = xmlHttpRequest;
            }
            catch(cmdSendE) {
                retValue = null;
            }
        }
        return retValue;
    }
    tenduke.networking.XmlHttpRequest = XmlHttpRequest;
})();var tenduke = tenduke || {};
tenduke.serverinterface = tenduke.serverinterface || {};
(function() {
    //
    //IMPORTS

    /**
     * Abstract base class definition of a a server interface request
     */
    var Request = function(params) {
        this._url = "/servlets/XMLCommandServlet";
        this._params = params;
    };

    /** */
    Request.prototype._url = null;
    /** */
    Request.prototype._params = null;

    /**
     * Signature for constructing request (implementation class shall declare and define)
     */
    Request.makeRequest=function(params) {
    }

    /**
     * Request can specify if the related commands shall be propagated.
     * This abstract base class returns false always
     * @return null
     */
    Request.prototype.propagateIsRequired = function() {
    	return false;
    }

    /**
     * Request can allow access to command XML for batch usage.
     * This abstract base class returns null always
     * @return null
     */
    Request.prototype.getCommandXml=function() {
        return null;
    }

    /**
     * @return <COMMANDS PROPAGATE="true | false">
     */
    Request.prototype.getCommandsHeadXml=function() {
        return "<COMMANDS PROPAGATE=\"" + this.propagateIsRequired() + "\">";
    }

    /**
     * @return </COMMANDS>
     */
    Request.prototype.getCommandsTailXml=function() {
        return "</COMMANDS>";
    }

    /**
     * Signature for executing request (implementation class shall declare and define)
     */
    Request.prototype.execute=function(callback) {
    	
    }

    /** setter for request url*/
    Request.prototype.setUrl=function(url) {
    	this._url = url;
    }

    /** getter for request url*/
    Request.prototype.getUrl=function() {
    	return this._url;
    }

    /** setter for request parameters */
    Request.prototype.setParams=function(params) {
        this._params = params;
    }

    /** getter for request parameters object */
    Request.prototype.getParams=function() {
    	return this._params;
    }
    //
    //
    tenduke.serverinterface.Request = Request;
})();var tenduke = tenduke || {};
tenduke.serverinterface = tenduke.serverinterface || {};
(function() {
    //
    //IMPORTS
    var Request = tenduke.serverinterface.Request;
    var _NetworkRequest = tenduke.networking.Request;
    var Cookies = tenduke.util.html.Cookies;

    /**
     * Constructor takes a single argument params, which is an instance of Object
     * that must contain following attributes:
     * 1. loginOperation: LOGIN_OPERATION_LOGIN or LOGIN_OPERATION_LOGOUT
     * 2. userName: The user to log in.
     * optional attributes:
     * 1. password: The password to login with (may be null in the case that other credentials are used, e.g. cookies)
     * 2. returnParameter Authenticate servlet supported return parameter name.
     */
    var LoginRequest = function(params){
    	LoginRequest.prototype.superClass.constructor.call(this, params);
    };
    //
    //
    copyPrototype(LoginRequest, Request);
    LoginRequest.prototype.superClass = Request.prototype;
    //
    //
    LoginRequest.makeRequest = function(params) {
    	return new LoginRequest(params);
    }

    /**
     * @return false
     */
    LoginRequest.prototype.propagateIsRequired = function() {
    	return false;
    }

    /**
     * @return null
     */
    LoginRequest.prototype.getCommandXml=function() {
        return null;
    }

    /**
     *
     */
    LoginRequest.prototype.execute=function(callback) {
        //
        //
        var resultObject = {};
        resultObject.request = this;
        //
        //
        if(this._params!=null) {
            //
            //
            var loginOperation = this._params.loginOperation;
            var returnParameter = this._params.returnParameter;
            var returnParameterValue = null;
            var userName = this._params.userName;
            var password = this._params.password;
            var url = "/s/AuthenticateServlet?function=" + loginOperation + (returnParameter ? "&returnParameter=" + returnParameter:"") + "&" + LOGIN_PRINCIPAL_FIELD_NAME + "=" + userName + (password ? "&PASSWORD=" + password:"");
            var anAuthRequest = new tenduke.networking.Request(url, null);
            //
            //
            anAuthRequest.execute(function(result) {
                //
                //
                var response = ( result.data ? result.data : null);
                //
                //
                var returnParamsElements = (response ? response.getElementsByTagName('RETURN_PARAMETERS') : null);
                var returnParamsElement = (returnParamsElements && returnParamsElements.length>0 ? returnParamsElements[0] : null);
                if(returnParamsElement) {
                    var returnParameterValueElement = findFirstNodeByName(returnParamsElement, returnParameter);
                    if(returnParameterValueElement && returnParameterValueElement.getAttribute("VALUE")) {
                        returnParameterValue = returnParameterValueElement.getAttribute("VALUE").toString();
                    }
                }
                //
                //
                var cmdLoginInfoElement = (response ? response.getElementsByTagName('LOGIN_INFORMATION') : null);
                if(cmdLoginInfoElement && cmdLoginInfoElement.length>0){
                    cmdLoginInfoElement=cmdLoginInfoElement[0];
                }
                var loginResult = LOGIN_FAILED;
                if(cmdLoginInfoElement){
                    var authResult=cmdLoginInfoElement.getAttribute("AUTHENTICATION_RESULT");
                    if(authResult){
                        if(authResult=="LOGIN_OK") {
                            //
                            //
                            resultObject.hasDetailedLoginInformation = true;
                            loginResult = LOGIN_SUCCESS;
                            var accountState = cmdLoginInfoElement.getAttribute("ACCOUNT_STATE");
                            resultObject.principalName = cmdLoginInfoElement.getAttribute("PRINCIPAL_NAME");
                            var accountDataComplete = cmdLoginInfoElement.getAttribute("ACCOUNT_DATA_IS_COMPLETE")
                            var accountValidated = cmdLoginInfoElement.getAttribute("ACCOUNT_VALIDATED")
                            var noEmail = cmdLoginInfoElement.getAttribute("ACCOUNT_HAS_NO_EMAIL");
                            //
                            //
                            resultObject.principalName = resultObject.principalName.replace(/\u0000/,"");
                            //
                            //
                            if(accountState=="ACCOUNT_IS_DISABLED" || accountState=="LOCKED"){
                                loginResult=LOGIN_FAILED;
                            }
                            else if(emailValidationRequired==true && accountValidated!=null && accountValidated!=undefined){
                                emailValidated = accountValidated=="true";
                                Cookies.writeSessionCookie(ACCOUNT_VALIDATED_COOKIE_NAME, ""+accountValidated);
                            }
                            if(accountDataComplete=="ACCOUNT_REGISTRATION_IS_COMPLETE"){

                            }
                            if(noEmail==false){

                            }
                        }
                        else if(authResult=="LOGIN_FAILED") {
                            loginResult = AUTHENTICATION_FAILED;
                        }
                    }
                }
                //
                //
                resultObject.loginResult = loginResult;
                resultObject.returnParameters = new Array();
                var returnParameterWrapper = {};
                returnParameterWrapper.name = returnParameter;
                returnParameterWrapper.value = returnParameterValue;
                resultObject.returnParameters.push(returnParameterWrapper);
                //
                //
                if(callback) {
                    //
                    //
                    callback.call(this, resultObject);
                }
            });
        }
    }
    LoginRequest.prototype.setUrl=function(url) {
    	this._networkingRequest.setUrl(url);
    }
    LoginRequest.prototype.getUrl=function() {
    	return this._networkingRequest.getUrl();
    }
    LoginRequest.prototype.setParams=function(params) {
    	this._networkingRequest.setParams(params);
    }
    LoginRequest.prototype.getParams=function() {
    	return this._networkingRequest.getParams();
    }
    tenduke.serverinterface.LoginRequest = LoginRequest;
})();var tenduke = tenduke || {};
tenduke.serverinterface = tenduke.serverinterface || {};
(function() {
    //
    //IMPORTS
    var Request = tenduke.serverinterface.Request;
    var RequestParameters = tenduke.networking.RequestParameters;
    var _NetworkRequest = tenduke.networking.Request;

    /**
     * Abstract base class definition of a a server interface batch
     */
    var Batch = function(params) {
        this._requests = new Array();
    };

    /** */
    Batch.prototype._networkingRequest = null;
    /** */
    Batch.prototype._url = null;
    /** */
    Batch.prototype._params = null;
    /** */
    Batch.prototype._requests = null;

    /**
     * Signature for constructing batch (implementation class shall declare and define)
     */
    Batch.newBatch = function(params) {
        return new Batch(params);
    }

    /**
     * Signature for adding a request to batch (implementation class shall declare and define)
     * @param requestName
     * @param request
     */
    Batch.prototype.add = function(requestName, request) {
        //
        //
        if(requestName && request) {
            var requestWrapper = {};
            requestWrapper.requestName = requestName;
            requestWrapper.request = request;
            this._requests.push(requestWrapper);
        }
        //
        //
        return this;
    }

    /**
     * Signature for executing requests in batch (implementation class shall declare and define)
     */
    Batch.prototype.execute = function(callback) {
    	//
        //
        var i = 0;
        var commandsHeadXml = "";
        var commandsTailXml = "";
        var batchedCommandXml = "";
        for(i=0; i<this._requests.length; i++) {
            //
            //
            var requestWrapper = this._requests[i];
            if(requestWrapper) {
                //
                //
                var requestName = requestWrapper.requestName;
                var request = requestWrapper.request;
                //
                // todo: extend requests to support command xml access
                if(request) {
                    if(i==0) {
                        commandsHeadXml = request.getCommandsHeadXml();
                    }
                    batchedCommandXml += request.getCommandXml();
                    if(i==0) {
                        commandsTailXml = request.getCommandsTailXml();
                    }
                }
            }
        }
        //
        //
        var url = "/servlets/XMLCommandServlet";
        var requestParams = {};
        requestParams[RequestParameters.POST_DATA] = commandsHeadXml + batchedCommandXml + commandsTailXml;
        requestParams[RequestParameters.CONTENT_TYPE] = "text/xml";
        //
        //
        var networkRequest = new tenduke.networking.Request(url, requestParams);
        networkRequest.execute(function(result) {
            //
            // todo: parse result and construct requestName based result object
            if(callback) {
                var cmdResultElements = (result && result.data ? result.data.getElementsByTagName('COMMAND') : null);
                var resultObject = {};
                resultObject.response = result;
                resultObject.commandResults = cmdResultElements;
                resultObject.request = this;
                callback.call(this, resultObject);
            }
        });
    }

    /** setter for underlying network request url*/
    Batch.prototype.setUrl=function(url) {
    	this._url = url;
    }

    /** getter for underlying network request url*/
    Batch.prototype.getUrl=function() {
    	return this._url;
    }

    /** setter for parameters object for request and underlying network request */
    Batch.prototype.setParams=function(params) {
        this._params = params;
    }

    /** getter for request parameters object */
    Batch.prototype.getParams=function() {
    	return this._params;
    }

    /** getter for batch requests array */
    Batch.prototype.getRequests = function() {
    	return this._requests;
    }

    //
    //
    tenduke.serverinterface.Batch = Batch;

})();
var tenduke = tenduke || {};
tenduke.serverinterface = tenduke.serverinterface || {};
(function() {
    //
    //IMPORTS
    var Request = tenduke.serverinterface.Request;
    var _NetworkRequest = tenduke.networking.Request;
    var _NetworkRequestParameters = tenduke.networking.RequestParameters;
    var Account = tenduke.objectmodel.Account;

    /**
     * Constructor takes a single argument params, which is an instance of Object
     * that must contain following attributes:
     * 1. account: instance of tenduke.objectmodel.Account with relevant member attributes set
     * optional attributes:
     * 1. updateByPrimaryPrincipal: true | false
     */
    var CreateOrUpdateAccount = function(params){
    	CreateOrUpdateAccount.prototype.superClass.constructor.call(this, params);
    };

    //
    //
    copyPrototype(CreateOrUpdateAccount, Request);
    CreateOrUpdateAccount.prototype.superClass = Request.prototype;

    /**
     * Construct new request object
     */
    CreateOrUpdateAccount.makeRequest = function(params) {
    	return new CreateOrUpdateAccount(params);
    }
    
    /**
     * @return true
     */
    CreateOrUpdateAccount.prototype.propagateIsRequired = function() {
    	return true;
    }


    /**
     * The command xml for creating or updating an account.
     * @return Command xml for creating or updating an account
     */
    CreateOrUpdateAccount.prototype.getCommandXml=function() {
        //
        //
        var retValue = null;
        //
        //
        if(this._params!=null && this._params.account) {
            //
            //
            var account = this._params.account;
            var params = new Array();
            var accountId = account.getAccountId();
            //
            //
            var userId = account.getPrimaryPrincipal();
            if(userId){
                userId=userId.replace(/\W/g,"_");
            }
            //
            //
            if(accountId) {
                params.push(new Array("ACCOUNT_ID", accountId));
            }
            if(account.getPrimaryEmail()) {
                params.push(new Array("EMAIL", account.getPrimaryEmail()));
            }
            if(userId) {
                params.push(new Array("primaryPrincipal", userId));
            }
            //
            //
            var commandAttributes = new Array();
            if(this._params.updateByPrimaryPrincipal) {
                commandAttributes.push(new Array("UPDATE_BY_PRIMARY_PRINCIPAL", "true"));
            }
            if(this._params.generatePassword) {
                commandAttributes.push(new Array("GENERATE_PASSWORD", "true"));
            }
            //
            //
            retValue = getCreateAccountCommand(params, commandAttributes);
        }
        //
        //
        return retValue;
    }

    /**
     * Execute request
     * @param callback, Signature: function(resultObject) {... where resultObject:
     */
    CreateOrUpdateAccount.prototype.execute=function(callback) {
        //
        //
        var resultObject = {};
        //
        //
        resultObject.request = this;
        //
        //
        if(this._params!=null && this._params.account) {
            //
            //
            resultObject.account = this._params.account;
            //
            //
            var createAccountCommand = this.getCommandXml();
            //
            //
            var commands = this.getCommandsHeadXml() + createAccountCommand + this.getCommandsTailXml();
            //
            //
            var requestParams = {};
            requestParams[_NetworkRequestParameters.POST_DATA] = commands;
            requestParams[RequestParameters.CONTENT_TYPE] = "text/xml";
            //
            //
            var networkRequest = new _NetworkRequest(this.getUrl(), requestParams);
            networkRequest.execute(function(result) {
                //
                //
                var resultXml = null;
                if(result!=null && result!=undefined) {
                    if(result.data!=null && result.data!=undefined) {
                        if(result.data.documentElement!=null && result.data.documentElement!=undefined) {
                            resultXml = result.data.documentElement;
                        }
                        else {
                            if(!resultObject.error) {
                                resultObject.error = {};
                            }
                            resultObject.error.defaultMessage = "Unkown result object received from server for create/initialize account command response";
                            resultObject.error.messageId = "CreateOrUpdateAccount.error.unkownServerResultObjectType";
                        }
                    }
                }
                else {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    resultObject.error.defaultMessage = "No result object received from server for CreateOrUpdateAccount request";
                    resultObject.error.messageId = "CreateOrUpdateAccount.error.missingServerResultObject";
                }
                //
                //
                if(resultXml!=null && resultXml!=undefined) {
                    //
                    //
                    var accountId = DOMUtils.getNodeValueByNodeName(resultXml, "ACCOUNT_ID");
                    //
                    //
                    if(accountId) {
                        resultObject.account.setAccountId(accountId);
                    }
                    else {
                        resultObject.account.setAccountId(null);
                        if(!resultObject.error) {
                            resultObject.error = {};
                        }
                        resultObject.error.defaultMessage = "Id of created account not found";
                        resultObject.error.messageId = "TendukeAccountAndProfile.error.createAccountResultMissingAccountId";
                    }
                    //
                    //
                    if(callback) {
                        callback(resultObject);
                    }
                }
                else {
                    if(callback) {
                        if(!resultObject.error) {
                            resultObject.error = {};
                        }
                        resultObject.error.defaultMessage = "No response data received in CreateOrUpdateAccount response";
                        resultObject.error.messageId = "TendukeAccountAndProfile.error.noResponseDataInCreateOrUpdateAccount";
                        callback(resultObject);
                    }
                }
            });
        }
    }

    //
    //
    tenduke.serverinterface.CreateOrUpdateAccount = CreateOrUpdateAccount;
    
})();
var tenduke = tenduke || {};
tenduke.serverinterface = tenduke.serverinterface || {};
(function() {
    //
    //IMPORTS
    var DateAndTimeUtils = tenduke.util.DateAndTimeUtils;
    var Request = tenduke.serverinterface.Request;
    var _NetworkRequest = tenduke.networking.Request;
    var _NetworkRequestParameters = tenduke.networking.RequestParameters;
    var Profile = tenduke.objectmodel.Profile;
    var Base64 = tenduke.util.Base64;

    /**
     * Constructor takes a single argument params, which is an instance of Object
     * that must contain following attributes:
     * 1. profile: instance of tenduke.objectmodel.Profile with relevant member attributes set
     */
    var CreateOrUpdateProfile = function(params){
    	CreateOrUpdateProfile.prototype.superClass.constructor.call(this, params);
    };

    //
    //
    copyPrototype(CreateOrUpdateProfile, Request);
    CreateOrUpdateProfile.prototype.superClass = Request.prototype;

    /**
     * Construct new request object
     */
    CreateOrUpdateProfile.makeRequest = function(params) {
    	return new CreateOrUpdateProfile(params);
    }

    /**
     * @return true
     */
    CreateOrUpdateProfile.prototype.propagateIsRequired = function() {
    	return true;
    }


    /**
     * The command xml for creating or updating a profile.
     * @return Command xml for creating or updating an account
     */
    CreateOrUpdateProfile.prototype.getCommandXml=function() {
        //
        //
        var retValue = null;
        //
        //
        if(this._params!=null && this._params.profile) {
            //
            //
            var profile = this._params.profile;
            var contactDetails = this._params.profile.getContactDetails();
            var emailAddress = contactDetails.getEmail();
            var postalAddress = contactDetails.getPostalAddress();
            //
            // get registered params
            var principalName = profile.getShortName();
            var gender = profile.getGender();
            var dob = profile.getBirthday();
            if(dob!=null && dob!=undefined && dob.constructor == (new Date()).constructor) {
                dob = DateAndTimeUtils.formatIso8601UtcDate(dob);
            }
            //
            //
            var email = emailAddress.getValue();
            //
            //
            var name = contactDetails.getFormattedName()
            var firstName = contactDetails.getGivenName();
            var lastName =  contactDetails.getFamilyName();
            var formattedName = contactDetails.getFormattedName()
            //
            //
            var country = postalAddress.getCountry();
            //
            //
            var displayName = profile.getDisplayName();
            var thumbnailUrl = profile.getProfileImageUrl();
            //
            // Write local profile basic data
            var primaryProfileData = new Properties();
            primaryProfileData.setParametersAreEncoded(true);
            primaryProfileData.setRootElementName("PROFILE");
            if(displayName) {
                primaryProfileData.setValue("DISPLAY_NAME", displayName);
            }
            if(principalName) {
                primaryProfileData.setValue("SHORT_NAME", principalName);
            }
            primaryProfileData.setValue("IS_PUBLIC", "true");
            if(gender) {
                primaryProfileData.setValue("GENDER", gender);
            }
            if(thumbnailUrl) {
                primaryProfileData.setValue("IMG_URL", thumbnailUrl);
            }
            if(dob) {
                primaryProfileData.setValue("BIRTHDAY", dob);
            }
            //
            //
            if(profile.getDescription()) {
                primaryProfileData.setValue("DESCRIPTION", profile.getDescription());
            }
            //
            //
            if(profile.getProfileId()) {
                primaryProfileData.setValue("PROFILE_ID", profile.getProfileId());
            }
            if(profile.getAccountId()) {
                primaryProfileData.setValue("ACCOUNT_ID", profile.getAccountId());
            }
            //
            // contact details initialization
            // create the top level contact props
            var contactProperties = new ContactProperties();
            contactProperties.basic.setParametersAreEncoded(true);
            contactProperties.basic.setRootElementName("BASIC");
            if(formattedName) {
                contactProperties.basic.setValue("FORMATTED_NAME", formattedName);
            }
            if(lastName) {
                contactProperties.basic.setValue("FAMILY_NAME", lastName);
            }
            if(firstName) {
                contactProperties.basic.setValue("GIVEN_NAME", firstName);
            }
            if(profile.getProfileId()) {
                contactProperties.basic.setValue("PROFILE_ID", profile.getProfileId());
            }
            var contactDetailsID = randomUUID();
            contactProperties.basic.setValue("CONTACT_DETAILS_ID", contactDetailsID);
            //
            // email fields initialied by the primary email registered by
            var emailEntryProps = null;
            if(email) {
                emailEntryProps = new Properties();
                emailEntryProps.setParametersAreEncoded(true);
                emailEntryProps.setRootElementName("EMAIL_ADDRESS");
                emailEntryProps.setValue("EMAIL", email);
                emailEntryProps.setValue("IS_PREFERED", "true");
                emailEntryProps.setValue("CONTACT_DETAILS_ID", contactDetailsID);
                var emailID = randomUUID();
                emailEntryProps.setValue("EMAIL_ADDRESS_ID", emailID);
                contactProperties.emails.putEntry(email, emailEntryProps);
            }
            //
            // postal props initialized with country asked in reg form
            contactProperties.postalAddress.setParametersAreEncoded(true);
            contactProperties.postalAddress.setRootElementName("POSTAL_ADDRESS");
            contactProperties.postalAddress.setValue("CONTACT_DETAILS_ID", contactDetailsID);
            var postalID=randomUUID();
            contactProperties.postalAddress.setValue("POSTAL_ADDRESS_ID", postalID);
            if(country) {
                contactProperties.postalAddress.setValue("COUNTRY", country);
            }
            //
            //
            retValue = _getCreateOrUpdateProfileCommand(profile.getProfileId(), primaryProfileData, contactProperties, null, null, true);
        }
        //
        //
        return retValue;
    }

    /**
     * Execute request
     * @param callback, Signature: function(resultObject) {... where resultObject:
     */
    CreateOrUpdateProfile.prototype.execute=function(callback) {
        //
        //
        var resultObject = {};
        //
        //
        resultObject.request = this;
        //
        //
        if(this._params!=null && this._params.account) {
            //
            //
            resultObject.profile = this._params.profile;
            //
            //
            var createProfileCommand = this.getCommandXml();
            //
            //
            var commands = this.getCommandsHeadXml() + createProfileCommand + this.getCommandsTailXml();
            //
            //
            var requestParams = {};
            requestParams[_NetworkRequestParameters.POST_DATA] = commands;
            requestParams[RequestParameters.CONTENT_TYPE] = "text/xml";
            //
            //
            var networkRequest = new _NetworkRequest(this.getUrl(), requestParams);
            networkRequest.execute(function(result) {
                //
                //
                var resultXml = null;
                if(result!=null && result!=undefined) {
                    if(result.data!=null && result.data!=undefined) {
                        if(result.data.documentElement!=null && result.data.documentElement!=undefined) {
                            resultXml = result.data.documentElement;
                        }
                        else {
                            if(!resultObject.error) {
                                resultObject.error = {};
                            }
                            resultObject.error.defaultMessage = "Unkown result object received from server for create/initialize account command response";
                            resultObject.error.messageId = "CreateOrUpdateProfile.error.unkownServerResultObjectType";
                        }
                    }
                }
                else {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    resultObject.error.defaultMessage = "No result object received from server for CreateOrUpdateProfile request";
                    resultObject.error.messageId = "CreateOrUpdateProfile.error.missingServerResultObject";
                }
                //
                //
                if(resultXml!=null && resultXml!=undefined) {
                    //
                    //
                    resultObject.resultXml = resultXml;
                    if(callback) {
                        callback(resultObject);
                    }
                }
                else {
                    if(callback) {
                        if(!resultObject.error) {
                            resultObject.error = {};
                        }
                        resultObject.error.defaultMessage = "No response data received in CreateOrUpdateProfile response";
                        resultObject.error.messageId = "TendukeAccountAndProfile.error.noResponseDataInCreateOrUpdateProfile";
                        callback(resultObject);
                    }
                }
            });
        }
    }
    
    /**
	 * Create a new profile or update an existing one and adds it optionally to a named group (group shall exist).
	 * @param profileId profile to update (may be null if scenario is create).
	 * @param profileParams Properties instance of parameters used to create an profile in the system (see PROFILE_REQUIRED_PROFILE_PARAMS for create scenarios).
	 * @param contactParams Instance that implements signature toXML(), used to serialize payload for CreateOrUpdateProfileCommand.
	 * @param personalInformationParams Properties instance of parameters used to create profile personal info.
	 * @param updateByShortName If true, an existing profile with given short name is tried to be updated. If not found, a new profile is created.
	 * @param addToGroupByName A group name that the profile should be added to.
	 * @return true for success
	 */
	function _getCreateOrUpdateProfileCommand(profileId, profileParams, contactParams, personalInformationParams, addToGroupByName, updateByShortName) {
	    //
	    //
	    var cmdData = "";
	    var cmdXML = "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.CreateOrUpdateProfile\"";
	    if(profileId) {
	        cmdXML += " PROFILE_ID=\"" + profileId + "\"";
	    }
	    if(addToGroupByName) {
	        cmdXML += " ADD_TO_GROUP=\"" + addToGroupByName + "\"";
	    }
	    if(updateByShortName == true) {
	        cmdXML += " UPDATE_BY_SHORT_NAME=\"true\"";
	    }
	    cmdXML += " >";
	    cmdXML += "<DATA>";
	    cmdData += "<PROFILE_DATA>";
	    if(profileParams) {
	        cmdData += profileParams.toXML();
	    }
	    if(contactParams) {
	        cmdData += contactParams.toXML();
	    }
	    if(personalInformationParams) {
	        personalInformationParams.toXML();
	    }
	    cmdData += "</PROFILE_DATA>";
	    cmdData = Base64.encode64(cmdData);
	    cmdXML += cmdData;
	    cmdXML += "</DATA>";
	    cmdXML += "</COMMAND>";
	    //
	    //
	    return cmdXML;
	}

    //
    //
    tenduke.serverinterface.CreateOrUpdateProfile = CreateOrUpdateProfile;

})();
tenduke.licensing={};
tenduke.licensing.subscription={};
/**
 * Data holder for subscription model lisensing transaction, event and request handling,
 */
(function() {

    //
    // Constructor
    var SubscriptionTransactionStatus = function() {
    };

    /** possible value for status member attribute */
    SubscriptionTransactionStatus.Accepted = "Accepted";
    /** possible value for status member attribute */
    SubscriptionTransactionStatus.Denied = "Denied";
    /** possible value for status member attribute */
    SubscriptionTransactionStatus.Cancelled = "Cancelled";

    /** */
    SubscriptionTransactionStatus.prototype._status = null;

    /** Getter for status */
    SubscriptionTransactionStatus.prototype.getStatus = function() {
        return this._status;
    }
    
    /** Setter for status */
    SubscriptionTransactionStatus.prototype.setStatus = function(rhs) {
        this._status = rhs;
    }

    /** */
    tenduke.licensing.subscription.SubscriptionTransactionStatus = SubscriptionTransactionStatus;

})();
//
// initialize package
var tenduke = tenduke || {};
tenduke.licensing = tenduke.licensing || {};
tenduke.licensing.subscription = tenduke.licensing.subscription || {};

/**
 * Data holder for subscription model lisensing information.
 * Information may include prices, durations, etc.
 * Intended use case is to access SubscriptionInfo via the getInstance method
 * that returns a singleton instance.
 *
 * Concrete applications / deployments shall implement a runtime configuration
 * of the singleton instance: definition of subscriptionIds and
 * associated price and duration info is expected.
 * SubscriptionInfo may be used in the implemntation
 * of Subscription providers. Subscription providers work with the assumption
 * that client code will be able to request subscriptions by subscriptionId only,
 * which makes it nessecary to access subscription information by a configuration
 * class like SubscriptionInfo.
 *
 * Usage:
 * var monthlySubscriptionId = "30";
 * var sixMonthSubscriptionId = "180";
 * tenduke.licensing.subscription.SubscriptionInfo.getInstance().setPrice(monthlySubscriptionId, 59.90);
 * tenduke.licensing.subscription.SubscriptionInfo.getInstance().setPrice(sixMonthSubscriptionId, 109.90);
 * tenduke.licensing.subscription.SubscriptionInfo.getInstance().setDescription(monthlySubscriptionId, "Subscribe to funny func app for the next 30 days for just 59.90");
 * tenduke.licensing.subscription.SubscriptionInfo.getInstance().setDescription(sixMonthSubscriptionId, "Subscribe to funny func app for half a year for just 109.90");
 * tenduke.licensing.subscription.SubscriptionInfo.getInstance().setDuration(monthlySubscriptionId, 30*24*3600*1000); // 30 days in milliseconds
 * tenduke.licensing.subscription.SubscriptionInfo.getInstance().setDuration(sixMonthSubscriptionId, 180*24*3600*1000); // 180 days in milliseconds
 * ...
 * tenduke.licensing.subscription.SubscriptionInfo.getInstance().getPrice(monthlySubscriptionId);
 *
 * @author Frej
 */
(function() {

    //
    // Constructor
    var SubscriptionInfo = function() {
    };

    /** */
    var _singletonInstance = null;

    /** */
    SubscriptionInfo.prototype._subscriptionIdPriceMap = new Hashtable();

    /** */
    SubscriptionInfo.prototype._subscriptionIdDurationMap = new Hashtable();

    /** */
    SubscriptionInfo.prototype._subscriptionIdCurrencyMap = new Hashtable();

    /** */
    SubscriptionInfo.prototype._subscriptionIdDescriptionMap = new Hashtable();

    /** */
    SubscriptionInfo.prototype._subscriptionIdSubscriptionStartedMap = new Hashtable();

    /** */
    SubscriptionInfo.prototype._subscriptionIdSubscriptionEndsMap = new Hashtable();

    /**
     * Main access to instance of SubscriptionInfo
     * @return singleton instance of SubscriptionInfo
     */
    SubscriptionInfo.getInstance = function() {
        if(_singletonInstance==null) {
            _singletonInstance = new SubscriptionInfo();
        }
        return _singletonInstance;
    }

    /** Get price for subscription */
    SubscriptionInfo.prototype.getPrice = function(subscriptionId) {
        return this._subscriptionIdPriceMap.getEntry(subscriptionId);
    }

    /** Set price for subscription */
    SubscriptionInfo.prototype.setPrice = function(subscriptionId, price) {
        this._subscriptionIdPriceMap.putEntry(subscriptionId, price);
    }
    
    /**
     * Get subscription duration
     * @return Subscription duration from start to end in milliseconds
     */
    SubscriptionInfo.prototype.getDuration = function(subscriptionId) {
        return this._subscriptionIdDurationMap.getEntry(subscriptionId);
    }

    /**
     * Set subscription duration
     * @param subscriptionId name if the subscription to store info for
     * @param duration Time in milliseconds from start to end
     */
    SubscriptionInfo.prototype.setDuration = function(subscriptionId, duration) {
        this._subscriptionIdDurationMap.putEntry(subscriptionId, duration);
    }

    /**
     * Get subscription currency
     */
    SubscriptionInfo.prototype.getCurrency = function(subscriptionId) {
        return this._subscriptionIdCurrencyMap.getEntry(subscriptionId);
    }

    /** Set subscription currency */
    SubscriptionInfo.prototype.setCurrency = function(subscriptionId, currency) {
        this._subscriptionIdCurrencyMap.putEntry(subscriptionId, currency);
    }

    /** Get subscription description */
    SubscriptionInfo.prototype.getDescription = function(subscriptionId) {
        return this._subscriptionIdDescriptionMap.getEntry(subscriptionId);
    }

    /** Set subscription description */
    SubscriptionInfo.prototype.setDescription = function(subscriptionId, description) {
        this._subscriptionIdDescriptionMap.putEntry(subscriptionId, description);
    }

    /**
     * Get subscription started
     * @return Instance of Date that defines the date and time when subscription started
     */
    SubscriptionInfo.prototype.getSubscriptionStarted = function(subscriptionId) {
        return this._subscriptionIdSubscriptionStartedMap.getEntry(subscriptionId);
    }

    /**
     * Set subscription started
     * @param subscriptionId name if the subscription to store info for
     * @param startedDate Date object that defines start date and time of subscription
     */
    SubscriptionInfo.prototype.setSubscriptionStarted = function(subscriptionId, startedDate) {
        this._subscriptionIdSubscriptionStartedMap.putEntry(subscriptionId, startedDate);
    }

    /**
     * Get subscription end
     * @return Instance of Date that defines the date and time when subscription ends
     */
    SubscriptionInfo.prototype.getSubscriptionEnds = function(subscriptionId) {
        return this._subscriptionIdSubscriptionEndsMap.getEntry(subscriptionId);
    }

    /**
     * Set subscription ends
     * @param subscriptionId name if the subscription to store info for
     * @param endsDate Date object that defines end date and time of subscription
     */
    SubscriptionInfo.prototype.setSubscriptionEnds = function(subscriptionId, endsDate) {
        this._subscriptionIdSubscriptionEndsMap.putEntry(subscriptionId, endsDate);
    }

    /** */
    tenduke.licensing.subscription.SubscriptionInfo = SubscriptionInfo;

})();
/**
 * Interface for working with subscription model licensing,
 */
(function() {

    var Subscription = {};

    /**
     * Method for application, module and other types of subscription based lisencing.
     * @param subscriptionId Name / identifier for what to subscribe
     * @param optParams A message to display to the end user to explain details about the transaction
     * @param callback Signature: function(resultObject), where the following members may or may not be defined:
     *                      result.error                    // Defined if and only if there has been at least one error
     *                      result.error.defaultMessage     // Default (not localizable) error message
     *                      result.error.messageId          // Error id that can be used to provide localized error messages
     *                      result.error.nestedErrors       // Errors produced by the underlying requests
     *
     *                      result.status                   // Instance of SubscriptionTransactionStatus with transaction status information
     *
     */
    Subscription.subscribe = function(subscriptionId, optParams, callback) {    
        //
        //
        showAlert("tenduke.licensing.subscription.Subscription is intended as an interface. Please declare and define implementation class and over-write this class with it.");
    }

    /**
     * 
     * @param subscriptionId Name / identifier for what to subscribe
     * @param optParams A message to display to the end user to explain details about the transaction
     * @param callback Signature: function(resultObject), where the following members may or may not be defined:
     *                      result.error                    // Defined if and only if there has been at least one error
     *                      result.error.defaultMessage     // Default (not localizable) error message
     *                      result.error.messageId          // Error id that can be used to provide localized error messages
     *                      result.error.nestedErrors       // Errors produced by the underlying requests
     *
     *                      result.status                   // Instance of SubscriptionTransactionStatus with transaction status information
     *
     */
    Subscription.subscribe = function(subscriptionId, optParams, callback) {
        //
        //
        showAlert("tenduke.licensing.subscription.Subscription is intended as an interface. Please declare and define implementation class and over-write this class with it.");
    }

    /**
     * Get subscription info for the user who owns the session (viewer).
     * @param subscriptionId Name / identifier for subscription to get info on (if set as null then all user subscription info is returned)
     * @param optParams Reserved to hold potentially range, offset etc info to control result set
     * @param callback Signature: function(resultObject), where the following members may or may not be defined:
     *                      result.error                    // Defined if and only if there has been at least one error
     *                      result.error.defaultMessage     // Default (not localizable) error message
     *                      result.error.messageId          // Error id that can be used to provide localized error messages
     *                      result.error.nestedErrors       // Errors produced by the underlying requests
     *
     *                      result.subscriptionInfoArray    // Array with instances of SubscriptionInfo objects
     *
     */
    Subscription.getSessionUserSubscriptionInfo = function(subscriptionId, callback) {
        //
        //
        showAlert("tenduke.licensing.subscription.getSessionUserSubscriptionInfo is intended as an interface. Please declare and define implementation class and over-write this class with it.");
    }

    //
    //
    tenduke.licensing.subscription.Subscription = Subscription;

})();
tenduke.opensocial={};/**
 * 
 */
 //package
var tenduke = tenduke || {};
tenduke.opensocial = tenduke.opensocial || {};
tenduke.opensocial.api = tenduke.opensocial.api || {};
(function() {

    var Netlog = {};
	Netlog.makeRequest=function(url,params,callback){
		osapi.makeRequest(url, params).execute(callback);
	}
    tenduke.opensocial.api.TendukeOSAPI = Netlog;

})();
/**
 * Utility methods for working with OpenSocial gadgets
 */
(function() {
    
    var GadgetUtils = {};

    /**
     * Private field: Object that represents OpenSocial gadget ModulePrefs, instance of gadgets.Prefs
     */
    var _modulePrefs;

    /**
     * Where the gadget backend actually lives
     */
    var _protoZoneAndPort; // Protocol, zone and port, e.g. "http://www.example.com"
    var _gadgetBasePath; // Base path to be appended after protoZoneAndPort, e.g. "/myGagdet"

    /**
     * Set protocol, zone and port where the gadget backend is, e.g. "http://www.example.com"
     */
    GadgetUtils.setProtoZoneAndPort = function(value) {
        _protoZoneAndPort = value;
    }

    /**
     * Get protocol, zone and port where the gadget backend is, e.g. "http://www.example.com"
     */
    GadgetUtils.getProtoZoneAndPort = function() {
        return _protoZoneAndPort;
    }

    /**
     * Set base path where the gadget backend is, e.g. "/myGadget"
     */
    GadgetUtils.setGadgetBasePath = function(value) {
        _gadgetBasePath = value;
    }

    /**
     * Get base path where the gadget backend is, e.g. "/myGadget"
     */
    GadgetUtils.getGadgetBasePath = function() {
        return _gadgetBasePath;
    }

    /**
     * Get base url where the gadget backend is, e.g. "http://www.example.com/myGadget".
     * Base url is getProtoZoneAndPort() + getGadgetBasePath()
     */
    GadgetUtils.getGadgetBaseUrl = function() {
        var retValue = "";
        if(GadgetUtils.getProtoZoneAndPort()) {
            retValue += GadgetUtils.getProtoZoneAndPort();
        }
        if(GadgetUtils.getGadgetBasePath()) {
            retValue += GadgetUtils.getGadgetBasePath();
        }
        return retValue;
    }

    /**
     * Get object that represents OpenSocial gadget ModulePrefs
     * @return instance of gadgets.Prefs
     */
    GadgetUtils.getModulePrefs = function() {
        //
        if(!_modulePrefs) {
            _modulePrefs = new gadgets.Prefs();
        }
        return _modulePrefs;
    }

    tenduke.opensocial.GadgetUtils = GadgetUtils;
    
})();
/**
 * Utility methods for working with OpenSocial internationalization and localization
 */
(function() {
    
    var Internationalization = {};

    /**
     * Get a localized message
     * @param scope This parameter is not used. Provided for compatibility with other internationalization schemes,
     *              i.e. for possibility to provide other implementations with the same signature.
     * @param messageId Identifier of the message to be fetched from a localized message bundle
     * @return Message string for the current locale
     */
    Internationalization.getMessage = function(scope, messageId) {
        var retValue;
        if(tenduke.opensocial.GadgetUtils.getModulePrefs()) {
            retValue = tenduke.opensocial.GadgetUtils.getModulePrefs().getMsg(messageId);
        }
        return retValue;
    }

    /**
     * Find and replace resource strings with localized messages
     * @param originalString The original string that contains __MSG_<messageKey>__ resource identifiers.
     * @return String where all resource identifiers have been replaced with localized messages. Returns null for null input.
     */
    Internationalization.findAndReplaceResourceStrings =  function(originalString) {
        //
        //
        var retValue = null;
        //
        //
        if(originalString!=null && originalString!=undefined) {
            //
            //
            var staticPartsRegExp = /__MSG_\w*__/;
            var staticParts = originalString.split(staticPartsRegExp);
            var messageParts = new Array();
            //
            //
            var i=0;
            var messageBlobStartId = "__MSG_";
            var messageBlobEndId = "__";
            var searchStartIndex = 0;
            var messageBlobStartIndex = 0;
            var messageBlobEndIndex = 0;
            var messageKeyStartIndex = 0;
            var messageKeyEndIndex = 0;
            //
            // initialize result serialization state vars:
            // two special cases: original string starts and ends with a message
            var originalStartsWithMessageBlob = false;
            var firstIndexOfMessageBlobStartId = originalString.indexOf(messageBlobStartId);
            if(firstIndexOfMessageBlobStartId==0) {
                originalStartsWithMessageBlob = true;
            }
            //
            // naive check for ends with case - assuming probability for two underscores at end of original is very small
            var originalEndsWithMessageBlob = false;
            var lastIndexOfMessageBlobEndId = originalString.lastIndexOf(messageBlobEndId);
            if(lastIndexOfMessageBlobEndId==originalString.length-2) {
                originalEndsWithMessageBlob = true;
            }
            //
            //
            while( searchStartIndex <= (originalString.length - messageBlobStartId.length - messageBlobEndId.length) ) {
                //
                // find next message blob start index
                messageBlobStartIndex = originalString.indexOf(messageBlobStartId, searchStartIndex);
                //
                // if found then sum blob start id length to messageBlobStartIndex to determine message key start
                if(messageBlobStartIndex!=-1) {
                    //
                    // search and compute rest of indices for current message in string
                    messageKeyStartIndex = messageBlobStartIndex + messageBlobStartId.length;
                    messageKeyEndIndex = originalString.indexOf(messageBlobEndId, messageKeyStartIndex);
                    messageBlobEndIndex = messageKeyEndIndex + messageBlobEndId.length;
                    //
                    // quick and naive sanity check of indices
                    if(messageBlobEndIndex<originalString.length && messageKeyEndIndex<messageBlobEndIndex && messageKeyStartIndex<messageKeyEndIndex && messageBlobStartIndex<messageKeyStartIndex) {
                        var messageId = originalString.substring(messageKeyStartIndex, messageKeyEndIndex);
                        var localizedMessage = tenduke.opensocial.GadgetUtils.getModulePrefs().getMsg(messageId);
                        if(localizedMessage==null || localizedMessage==undefined) {
                            localizedMessage = "Fix me: localized message not defined for messageId = " + messageId;
                        }
                        messageParts.push(localizedMessage);
                    }
                    //
                    // increment search start index to end of the current message blob
                    searchStartIndex = messageBlobEndIndex;
                }
                else {
                    break;
                }
            }
            //
            //
            var resultParts = new Array();
            var nextMessageIndex = 0;
            for(i=0; i<staticParts.length; i++) {
                if(originalStartsWithMessageBlob==false) {
                    resultParts.push(staticParts[i]);
                    resultParts.push(messageParts[nextMessageIndex]);
                }
                else {
                    resultParts.push(messageParts[nextMessageIndex]);
                    resultParts.push(staticParts[i]);
                }
                nextMessageIndex++;
            }
            if(originalEndsWithMessageBlob==true && nextMessageIndex<messageParts.length-1) {
                resultParts.push(messageParts[nextMessageIndex]);
            }
            //
            //
            retValue = resultParts.join("");
        }
        //
        //
        return retValue;
    }

    tenduke.opensocial.Internationalization = Internationalization;
    
})();
/**
 *
 */
(function() {
    
    /*
    * IMPORTS / external dependencies
    *
    */
    var SHA1			=	tenduke.util.SHA1;
    var GadgetUtils		=	tenduke.opensocial.GadgetUtils;
   	var TendukeOSAPI	=	tenduke.opensocial.api.TendukeOSAPI;
    /*
    * END IMPORTS
    */
    var RequestUtils = {};

    /**
     * Send a asynchronous XML command request. OpenSocial makeRequest implementation handles
     * post data badly (at least in Netlog / Apache Shindig 2009-06), this has to be worked
     * around by masking the command as it would be an url parameter, replacing equal signs
     * from the command, and url encoding the whole stuff.
     * @param xmlCommand A XML command set
     * @param callback a callback for handling request - response progress and status.
     *                       Signature: fnc(resultObject)
     *                       If you need the callback to be called in a scope of an object, use
     *                       tenduke.util.js.Function.createScopedFunction to wrap your callback function.
     */
    RequestUtils.asyncCommandRequest = function(xmlCommand, callback) {
        //
        var postDataHash = SHA1.doFinal(xmlCommand);
        //
        //
        var url = GadgetUtils.getProtoZoneAndPort() + "/signClientData.jsp?clientData=" + postDataHash;
        var getParams = {};
        getParams.format = "text";
        getParams[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
        TendukeOSAPI.makeRequest(url, getParams, function(signatureResult) {
            //
            //
            if(signatureResult && signatureResult.data) {
                //
                //
                var getRequestObject = eval('(' + signatureResult.data + ')');
                if(getRequestObject && getRequestObject.clientSignature && getRequestObject.clientTime && getRequestObject.clientViewer) {
                    var postUrl = GadgetUtils.getProtoZoneAndPort() + "/s/XMLCommandServlet?clientData=" + postDataHash + "&signature=" + getRequestObject.clientSignature + "&clientTime=" + getRequestObject.clientTime + "&clientViewer=" + getRequestObject.clientViewer;
                    var params = {};
                    var data = { "commands" : xmlCommand.split("=").join("&#61;") };
                    var postdata = gadgets.io.encodeValues(data);
                    params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
                    params[gadgets.io.RequestParameters.POST_DATA] = postdata;
                    params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.DOM;
                    params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
                    //
                    TendukeOSAPI.makeRequest(postUrl, params, function(result) {
                        if(callback) {
                            callback(result);
                        }
                    });
                }
            }
        });
    }

    tenduke.opensocial.RequestUtils = RequestUtils;
    
})();
/**
 * OpenSocial security related utility methods
 */
(function() {

    var Security = {};

    /**
     * Get security token. The default implementation assumes that the OpenSocial container is implemented
     * with Apache Shindig.
     * @return Security token
     */
    Security.getSecurityToken = function() {
        //
        return shindig.auth.getSecurityToken();
    }

    tenduke.opensocial.Security = Security;

})();
/**
 * Utility methods to help working with OpenSocial viewer and owner
 */
(function() {

    var ViewerAndOwner = {};

    var _viewer;
    var _owner;

    /**
     * Get cached viewer object. requestViewerAndOwner or requestViewer must have been called before using this method.
     * @return cached viewer object
     */
    ViewerAndOwner.getViewer = function() {
        return _viewer;
    }

    /**
     * Get cached owner object. requestViewerAndOwner or requestOwner must have been called before using this method.
     * @return cached owner object
     */
    ViewerAndOwner.getOwner = function() {
        return _owner;
    }

    /**
     * Get viewer id based on the cached viewer object. requestViewerAndOwner or requestViewer must have been called before using this method.
     * @return id of the cached viewer object
     */
    ViewerAndOwner.getViewerId = function() {
        var retValue;
        if(_viewer) {
            retValue = _viewer.getId();
        }
        return retValue;
    }

    /**
     * Get owner id based on the cached owner object. requestViewerAndOwner or requestOwner must have been called before using this method.
     * @return id of the cached viewer object
     */
    ViewerAndOwner.getOwnerId = function() {
        var retValue;
        if(_owner) {
            retValue = _owner.getId();
        }
        return retValue;
    }

    /**
     * Is current viewer anonumous. requestViewerAndOwner or requestViewer must have been called before using this method.
     * @return true if current viewer is anonymous or if viewer is not initialized
     */
    ViewerAndOwner.isViewerAnonymous = function() {
        var retValue = true;
        if(_viewer) {
            if(_viewer.getId() && _viewer.getId() != "-1") {
                retValue = false;
            }
        }
        return retValue;
    }

    /**
     * Is current owner anonumous. requestViewerAndOwner or requestOwner must have been called before using this method.
     * @return true if current owner is anonymous or if owner is not initialized
     */
    ViewerAndOwner.isOwnerAnonymous = function() {
        var retValue = true;
        if(_owner) {
            if(_owner.getId() && _owner.getId() != "-1") {
                retValue = false;
            }
        }
        return retValue;
    }

    /**
     * Initialize owner and viewer so that they can be later accessed by calling getViewer and getOwner.
     * This method is asynchronous and it doesn't use cached viewer and owner information. When this method
     * has been called at least once, getViewer and getOwner can be used to retrieve cached viewer and owner objects.
     * @param callback Signature: function(resultObject), where the following members may or may not be defined:
     *                      result.error                        // Defined if and only if there has been at least one error
     *                          result.error.defaultMessage     // Default (not localizable) error message
     *                          result.error.messageId          // Error id that can be used to provide localized error messages
     *                          result.error.nestedErrors       // Errors produced by the underlying requests
     *                      result.viewer                       // Viewer
     *                      result.owner                        // Owner
     */
    ViewerAndOwner.requestViewerAndOwner = function(callback,viewerDetailParams,ownerDetailParams) {
        //
        var resultObject = {};
        var viewerParams = {};
        var ownerParams = {};
        if(!viewerDetailParams){
        	viewerDetailParams=[opensocial.Person.Field.HAS_APP];
        }
        if(!ownerDetailParams){
        	ownerDetailParams=[];
        }
        viewerParams[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = viewerDetailParams;
        ownerParams[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = ownerDetailParams;
        var req = opensocial.newDataRequest();
        req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), 'viewer');
        req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.OWNER), 'owner');
        req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER, viewerParams), 'viewer2');
        req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.OWNER, ownerParams), 'owner2');
        req.send(function (result) {
            //
            if(result) {
                if(result.error) {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    if(!resultObject.error.nestedErrors) {
                        resultObject.error.nestedErrors = new Array();
                    }
                    resultObject.error.nestedErrors.push(result.error);
                }
                _viewer = result.get('viewer').getData();
                var hasErrors=false;
                if(!_viewer) {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    resultObject.error.defaultMessage = "Request to fetch viewer profile did not return viewer data";
                    resultObject.error.messageId = "ViewerAndOwner.error.noViewerFound";
                    hasErrors=true;
                }
                var viewer2=result.get('viewer2').getData();
                if(viewer2){
                	_viewer = viewer2;
                }
                _owner = result.get('owner').getData();
                if(!_owner) {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    if(!hasErrors){
	                    resultObject.error.defaultMessage = "Request to fetch owner profile did not return owner data";
    	                resultObject.error.messageId = "ViewerAndOwner.error.noOwnerFound";
    	            }
    	            else{
    	            	resultObject.error.defaultMessage = "Request to fetch owner and viewer profiles did not return owner or viewer data";
    	                resultObject.error.messageId = "ViewerAndOwner.error.noOwnerOrViewerFound";
    	            }
                }
                var owner2=result.get('owner2').getData();
                if(owner2){
                	_owner = owner2;
                }
            }
            else {
                if(!resultObject.error) {
                    resultObject.error = {};
                }
                resultObject.error.defaultMessage = "Request to fetch viewer profile failed";
                resultObject.error.messageId = "ViewerAndOwner.error.viewerRequestFailed";
            }
            //
            /*req = opensocial.newDataRequest();
        	params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = ownerDetailParams;
            req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.OWNER, params), 'owner');
            req.send(function (result) {
                //
                if(result) {
                    if(result.error) {
                        if(!resultObject.error) {
                            resultObject.error = {};
                        }
                        if(!resultObject.error.nestedErrors) {
                            resultObject.error.nestedErrors = new Array();
                        }
                        resultObject.error.nestedErrors.push(result.error);
                    }
                    _owner = result.get('owner').getData();
                    if(!_owner) {
                        if(!resultObject.error) {
                            resultObject.error = {};
                        }
                        resultObject.error.defaultMessage = "Request to fetch owner profile did not return owner data";
                        resultObject.error.messageId = "ViewerAndOwner.error.noOwnerFound";
                    }
                }
                else {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    resultObject.error.defaultMessage = "Request to fetch owner profile failed";
                    resultObject.error.messageId = "ViewerAndOwner.error.ownerRequestFailed";
                }
            });
            //
            */
            if(callback) {
                resultObject.viewer = _viewer;
                resultObject.owner = _owner;
                callback(resultObject);
            }
        });
    }

    /**
     * Initialize viewer so that it can be later accessed by calling getViewer.
     * This method is asynchronous and it doesn't use cached viewer information. When this method
     * has been called at least once, getViewer can be used to retrieve cached viewer object.
     * @param callback Signature: function(resultObject), where the following members may or may not be defined:
     *                      result.error                        // Defined if and only if there has been at least one error
     *                          result.error.defaultMessage     // Default (not localizable) error message
     *                          result.error.messageId          // Error id that can be used to provide localized error messages
     *                          result.error.nestedErrors       // Errors produced by the underlying requests
     *                      result.viewer                       // Viewer
     */
    ViewerAndOwner.requestViewer = function(callback) {
        //
        //
        var resultObject = {};
        var params = {};
        params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [opensocial.Person.Field.HAS_APP];
        var req = opensocial.newDataRequest();
        req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER, params), 'viewer');
        req.send(function (result) {
            //
            //
            if(result) {
                if(result.error) {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    if(!resultObject.error.nestedErrors) {
                        resultObject.error.nestedErrors = new Array();
                    }
                    resultObject.error.nestedErrors.push(result.error);
                }
                _viewer = result.get('viewer').getData();
                if(!_viewer) {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    resultObject.error.defaultMessage = "Request to fetch viewer profile did not return viewer data";
                    resultObject.error.messageId = "ViewerAndOwner.error.noViewerFound";
                }
            }
            else {
                if(!resultObject.error) {
                    resultObject.error = {};
                }
                resultObject.error.defaultMessage = "Request to fetch viewer profile failed";
                resultObject.error.messageId = "ViewerAndOwner.error.viewerRequestFailed";
            }
            //
            if(callback) {
                resultObject.viewer = _viewer;
                callback(resultObject);
            }
        });
    }

    /**
     * Initialize owner so that it can be later accessed by calling getOwner.
     * This method is asynchronous and it doesn't use cached owner information. When this method
     * has been called at least once, getOwner can be used to retrieve cached owner object.
     * @param callback Signature: function(resultObject), where the following members may or may not be defined:
     *                      result.error                        // Defined if and only if there has been at least one error
     *                          result.error.defaultMessage     // Default (not localizable) error message
     *                          result.error.messageId          // Error id that can be used to provide localized error messages
     *                          result.error.nestedErrors       // Errors produced by the underlying requests
     *                      result.owner                        // Owner
     */
    ViewerAndOwner.requestOwner = function(callback) {
        //
        var resultObject = {};
        var req = opensocial.newDataRequest();
        req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.OWNER), 'owner');
        req.send(function (result) {
            //
            if(result) {
                if(result.error) {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    if(!resultObject.error.nestedErrors) {
                        resultObject.error.nestedErrors = new Array();
                    }
                    resultObject.error.nestedErrors.push(result.error);
                }
                _owner = result.get('owner').getData();
                if(!_owner) {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    resultObject.error.defaultMessage = "Request to fetch owner profile did not return owner data";
                    resultObject.error.messageId = "ViewerAndOwner.error.noOwnerFound";
                }
            }
            else {
                if(!resultObject.error) {
                    resultObject.error = {};
                }
                resultObject.error.defaultMessage = "Request to fetch owner profile failed";
                resultObject.error.messageId = "ViewerAndOwner.error.ownerRequestFailed";
            }
            //
            if(callback) {
                resultObject.owner = _owner;
                callback(resultObject);
            }
        });
    }

    tenduke.opensocial.ViewerAndOwner = ViewerAndOwner;

})();
/**
 * Utilities for fitting together OpenSocial profiles and 10Duke accounts and profiles
 */
(function() {

    var TendukeAccountAndProfile = {};
	/*
	* IMPORTS / dependencies to external assets
	* Depends on an old style asset RegistrationApi.js
	* Depends on an old style asset Properties.js
	* Depends on an old style asset ProfileAPI.js
	* Depends on an old style asset Validator.js
	* Depends on an old style asset LoginUtils.js
	* Depends on an old style asset RequestUtils.js
	* Depends on an old style asset ContactProperties.js
	*/
	var Cookies			=	tenduke.util.html.Cookies;
	var RequestUtils	=	tenduke.opensocial.RequestUtils;
	var DOMUtils		=	tenduke.util.html.DOMUtils;
	var ViewerAndOwner	=	tenduke.opensocial.ViewerAndOwner;
	var GadgetUtils		=	tenduke.opensocial.GadgetUtils;
	var TendukeOSAPI	=	tenduke.opensocial.api.TendukeOSAPI;
	var DateAndTimeUtils=	tenduke.util.DateAndTimeUtils;
	
	/*
	* END IMPORTS
	*/
    //
    //
    TendukeAccountAndProfile.dumpResponse = function(node, level){
        //
        //
        if(node){
            //
            //
            alert("Node(" + level + "):\n node.localName = " + node.localName + ", node.nodeName = " + node.nodeName + ", node.nodeType = " + node.nodeType + "\nnode.nodeValue = " + node.nodeValue);
            //
            //
            var nodeChild = node.childNodes;
            if(nodeChild && nodeChild.length>0){
                var i = nodeChild.length;
                var localLevel = level + 1;
                while(i>0){
                    i--;
                    TendukeAccountAndProfile.dumpResponse(nodeChild[i], localLevel);
                }
            }
        }
    }

    /**
     * Initialize account and profile to 10Duke backend. The account will be created if account with given OpenSocial profile's id didn't exist,
     * otherwise the existing account is updated.
     * @param openSocialProfileObject Open social profile for which 10Duke account and profile should be created, for instance viewer profile
     * @param pw
     * @param callback Signature: function(resultObject), where the following members may or may not be defined:
     *                      result.error                        // Defined if and only if there has been at least one error
     *                          result.error.defaultMessage     // Default (not localizable) error message
     *                          result.error.messageId          // Error id that can be used to provide localized error messages
     *                          result.error.nestedErrors       // Errors produced by the underlying requests
     *                      result.accountId                    // 10Duke account id
     */
    TendukeAccountAndProfile.initAccountAndProfile = function(openSocialProfileObject, pw, callback) {
        //
        var resultObject = {};
        if(openSocialProfileObject) {
            //
            var params = new Array();
            var accountId = randomUUID();
            
        
            var userId = openSocialProfileObject.getId();
            if(userId){
            	userId=userId.replace(/\W/g,"_");
            }
            params.push(new Array("ACCOUNT_ID", accountId));
            params.push(new Array("primaryPrincipal", userId));
            params.push(new Array("PASSWORD", pw));
            params.push(new Array("PASSWORD_CONFIRMED", pw));
            
            var domain="opensocial";
            if(opensocial && opensocial.getEnvironment() && opensocial.getEnvironment().getDomain()){
            	domain=opensocial.getEnvironment().getDomain();
            }
            params.push(new Array("EMAIL", domain+"_"+ userId + "@dummy.email"));
            //
            var commandAttributes = new Array();
            commandAttributes.push(new Array("UPDATE_BY_PRIMARY_PRINCIPAL", "true"));
            //
            var createAccountCommand = getCreateAccountCommand(params, commandAttributes);
            
        	
            var commands = "<COMMANDS PROPAGATE=\"true\">" + createAccountCommand + "</COMMANDS>";
            RequestUtils.asyncCommandRequest(commands, function(result) {
        		
                //
                if(result && result.error) {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    if(!resultObject.error.nestedErrors) {
                        resultObject.error.nestedErrors = new Array();
                    }
                    resultObject.error.nestedErrors.push(result.error);
                }
                //
                //
                var resultXml = null;
                if(result!=null && result!=undefined) {
                    if(result.data!=null && result.data!=undefined) {
                        if(result.data.documentElement!=null && result.data.documentElement!=undefined) {
                            resultXml = result.data.documentElement;
                        }
                        else {
                            if(!resultObject.error) {
                                resultObject.error = {};
                            }
                            resultObject.error.defaultMessage = "Unkown result object received from OpenSocial container for create/initialize account command response";
                            resultObject.error.messageId = "TendukeAccountAndProfile.error.unkownOpenSocialResultObjectType";
                        }
                    }
                    else if(result.text!=null && result.text!=undefined) {
                        //
                        //
                        var aParser = new DOMParser();
                        //
                        //
                        try {
                            resultXml = aParser.parseFromString(result.text, "text/xml");
                        }
                        catch(xmlE) {
                            if(!resultObject.error) {
                                resultObject.error = {};
                            }
                            resultObject.error.defaultMessage = "XML parsing error for create/initialize account command response";
                            resultObject.error.messageId = "TendukeAccountAndProfile.error.xmlParserExceptionForAccountCreateOrInitialize";
                            if(!resultObject.error.nestedErrors) {
                                resultObject.error.nestedErrors = new Array();
                            }
                            resultObject.error.nestedErrors.push(xmlE);
                        }
                    }
                    else {}
                }
                else {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    resultObject.error.defaultMessage = "No result object received from OpenSocial container for profile query";
                    resultObject.error.messageId = "TendukeAccountAndProfile.error.missingOpenSocialResultObject";
                }
                //
                //
                if(resultXml!=null && resultXml!=undefined) {
                    //
                    //
                    var accountId = DOMUtils.getNodeValueByNodeName(resultXml, "ACCOUNT_ID");
                    //
                    //
                    if(accountId) {
                        //
                        //
                        resultObject.accountId = accountId;
                        TendukeAccountAndProfile.initProfile(openSocialProfileObject, accountId, callback, resultObject);
                    }
                    else {
                        if(callback) {
                            if(!resultObject.error) {
                                resultObject.error = {};
                            }
                            resultObject.error.defaultMessage = "Id of created account not found";
                            resultObject.error.messageId = "TendukeAccountAndProfile.error.createAccountResultMissingAccountId";
                            callback(resultObject);
                        }
                    }
                }
                else {
                    if(callback) {
                        if(!resultObject.error) {
                            resultObject.error = {};
                        }
                        resultObject.error.defaultMessage = "No OpenSocial profile object given to 10Duke account initialization";
                        resultObject.error.messageId = "TendukeAccountAndProfile.error.missingOpenSocialProfileParameter";
                        callback(resultObject);
                    }
                }
            });
        }
        else {
            if(callback) {
                if(!resultObject.error) {
                    resultObject.error = {};
                }
                resultObject.error.defaultMessage = "No OpenSocial profile object given to 10Duke account initialization";
                resultObject.error.messageId = "TendukeAccountAndProfile.error.createAccountMissingOpenSocialProfileParameter";
                callback(resultObject);
            }
        }
    }

    /**
     * Initialize profile to 10Duke backend. The profile will be created if profile with given OpenSocial profile's id didn't exist,
     * otherwise the existing profile is updated.
     * @param openSocialProfileObject Open social profile for which 10Duke account and profile should be created, for instance viewer profile
     * @param accountId Id of 10duke account whose profile the created profile should be
     * @param callback Signature: function(resultObject), where the following members may or may not be defined:
     *                      result.error                        // Defined if and only if there has been at least one error
     *                          result.error.defaultMessage     // Default (not localizable) error message
     *                          result.error.messageId          // Error id that can be used to provide localized error messages
     *                          result.error.nestedErrors       // Errors produced by the underlying requests
     *                      result.accountId                    // 10Duke account id
     * @param resultObject If defined, this is used as base object for the result object given to the callback
     */
    TendukeAccountAndProfile.initProfile = function(openSocialProfileObject, accountId, callback, resultObject) {
        //
        if(!resultObject) {
            resultObject = {};
        }

        //
        if(openSocialProfileObject) {
            //
            // get registered params
            var principalName = openSocialProfileObject.getId();
            var gender = openSocialProfileObject.getField('gender');
            var dob = openSocialProfileObject.getField('dateOfBirth');
            if(dob!=null && dob!=undefined && dob.constructor == (new Date()).constructor) {
                dob = DateAndTimeUtils.formatIso8601UtcDate(dob);
            }
            var emails = openSocialProfileObject.getField('emails');
            var email;
            if(emails && emails.length > 0) {
                email = emails[0].getField('address');
            }
            var name = openSocialProfileObject.getField('name');
            var firstName;
            var lastName;
            var formattedName;
            if(name) {
                firstName = name.getField('givenName');
                lastName = name.getField('familyName');
                formattedName = name.getField('formatted');
            }
        
            var addresses = openSocialProfileObject.getField('addresses');
            var address;
            if(addresses && addresses.length > 0) {
                address = addresses[0];
            }
            var country;
            if(address) {
                country = address.getField('country');
            }
            var displayName = openSocialProfileObject.getDisplayName();
            var thumbnailUrl = openSocialProfileObject.getField('thumbnailUrl');
            //
            // Write local profile basic data
            var primaryProfileData = new Properties();
            primaryProfileData.setParametersAreEncoded(true);
            primaryProfileData.setRootElementName("PROFILE");
            primaryProfileData.setValue("DISPLAY_NAME", displayName);
            primaryProfileData.setValue("SHORT_NAME", principalName);
            primaryProfileData.setValue("IS_PUBLIC", "true");
            if(gender) {
                primaryProfileData.setValue("GENDER", gender.getKey());
            }
            if(thumbnailUrl) {
                primaryProfileData.setValue("IMG_URL", thumbnailUrl);
            }
            if(dob) {
                primaryProfileData.setValue("BIRTHDAY", dob);
            }
            var domain="opensocial";
            if(opensocial && opensocial.getEnvironment() && opensocial.getEnvironment().getDomain()){
            	domain=opensocial.getEnvironment().getDomain();
            }
            primaryProfileData.setValue("DESCRIPTION", domain+" user");
            var profileId = randomUUID();
            primaryProfileData.setValue("PROFILE_ID", profileId);
            primaryProfileData.setValue("ACCOUNT_ID", accountId);
            
            //
            // contact details initialization
            // create the top level contact props
            var contactProperties = new ContactProperties();
            contactProperties.basic.setParametersAreEncoded(true);
            contactProperties.basic.setRootElementName("BASIC");
            if(formattedName) {
                contactProperties.basic.setValue("FORMATTED_NAME", formattedName);
            }
            if(lastName) {
                contactProperties.basic.setValue("FAMILY_NAME", lastName);
            }
            if(firstName) {
                contactProperties.basic.setValue("GIVEN_NAME", firstName);
            }
            contactProperties.basic.setValue("PROFILE_ID", profileId);
            var contactDetailsID=randomUUID();
            contactProperties.basic.setValue("CONTACT_DETAILS_ID", contactDetailsID);
            //
            // email fields initialied by the primary email registered by
            var emailEntryProps = null;
            if(email) {
                emailEntryProps = new Properties();
                emailEntryProps.setParametersAreEncoded(true);
                emailEntryProps.setRootElementName("EMAIL_ADDRESS");
                emailEntryProps.setValue("EMAIL", email);
                emailEntryProps.setValue("IS_PREFERED", "true");
                emailEntryProps.setValue("CONTACT_DETAILS_ID", contactDetailsID);
                var emailID=randomUUID();
                emailEntryProps.setValue("EMAIL_ADDRESS_ID", emailID);
                contactProperties.emails.putEntry(email, emailEntryProps);
            }
            //
            // postal props initialized with country asked in reg form
            contactProperties.postalAddress.setParametersAreEncoded(true);
            contactProperties.postalAddress.setRootElementName("POSTAL_ADDRESS");
            contactProperties.postalAddress.setValue("CONTACT_DETAILS_ID", contactDetailsID);
            var postalID=randomUUID();
            contactProperties.postalAddress.setValue("POSTAL_ADDRESS_ID", postalID);
            if(country) {
                contactProperties.postalAddress.setValue("COUNTRY", country);
            }
            //
            var createProfileCommand = getCreateOrUpdateProfileCommand(profileId, primaryProfileData, contactProperties, null, null, true);
            //
            if(createProfileCommand) {
                var commands = "<COMMANDS PROPAGATE=\"true\">" + createProfileCommand + "</COMMANDS>";
                RequestUtils.asyncCommandRequest(commands, function(result) {
                    //
                    if(result && result.error) {
                        if(!resultObject.error) {
                            resultObject.error = {};
                        }
                        if(!resultObject.error.nestedErrors) {
                            resultObject.error.nestedErrors = new Array();
                        }
                        resultObject.error.nestedErrors.push(result.error);
                    }
                    //
                    if(callback) {
                        callback(resultObject);
                    }
                });
            }
            else {
                if(callback) {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    resultObject.error.defaultMessage = "Failed to create command from profile creation";
                    resultObject.error.messageId = "TendukeAccountAndProfile.error.createProfileCommandCreationFailed";
                    callback(resultObject);
                }
            }
        }
        else {
            if(callback) {
                if(!resultObject.error) {
                    resultObject.error = {};
                }
                resultObject.error.defaultMessage = "No OpenSocial profile object given to 10Duke profile initialization";
                resultObject.error.messageId = "TendukeAccountAndProfile.error.createProfileMissingOpenSocialProfileParameter";
                callback(resultObject);
            }
        }
    }

    /**
     * Create an authenticated session (login)
     * @param viewerId OpenSocial viewer id that is used as login id (profile short name)
     * @param password Password
     * @param loginResultHandler function call back for handling login request results.
     *        loginResultHandler signature: fnc(aResultCode:int), where aResultCode can be LOGIN_SUCCESS | LOGIN_FAILED | ALREADY_LOGGED_IN.
     */
    TendukeAccountAndProfile.login = function(viewerId, password, loginResultHandler) {
        //
        //
        var loginState = (ViewerAndOwner.isViewerAnonymous() == false);
        //
        //
        if(loginState==false) {
            //
            //
            var principalName = viewerId;
            var atIndex = principalName.indexOf("@");
            var useEmailOpt = "";
            if(atIndex!=-1 && validateEmail(principalName)==true) {
                useEmailOpt = "&USE_EMAIL=true";
            }
            //
            //
            var returnParameterName = "ACCOUNT_STATE";
            var returnParameterValue = null;
            var temp_principalName = principalName;
            //
            //
            var url = GadgetUtils.getProtoZoneAndPort() + "/s/AuthenticateServlet?function=" + LOGIN_OPERATION_LOGIN + "&returnParameter=" + returnParameterName + "&" + LOGIN_PRINCIPAL_FIELD_NAME + "=" + temp_principalName + "&PASSWORD=" + password + useEmailOpt;
            var params = {};
            params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.DOM;
            //
            //
            TendukeOSAPI.makeRequest(url, params, function(result) {
                //
                //
                var response = ( result.data ? result.data : null);
                //
                //
                var returnParamsElements = (response ? response.getElementsByTagName('RETURN_PARAMETERS') : null);
                var returnParamsElement = (returnParamsElements && returnParamsElements.length>0 ? returnParamsElements[0] : null);
                if(returnParamsElement) {
                    var returnParameterValueElement = findFirstNodeByName(returnParamsElement, returnParameterName);
                    if(returnParameterValueElement && returnParameterValueElement.getAttribute("VALUE")) {
                        returnParameterValue = returnParameterValueElement.getAttribute("VALUE").toString();
                    }
                }
                //
                //
                var cmdLoginInfoElement = (response ? response.getElementsByTagName('LOGIN_INFORMATION') : null);
                if(cmdLoginInfoElement && cmdLoginInfoElement.length>0){
                    cmdLoginInfoElement=cmdLoginInfoElement[0];
                }
                var loginResult = LOGIN_FAILED;
                if(cmdLoginInfoElement){
                    var authResult=cmdLoginInfoElement.getAttribute("AUTHENTICATION_RESULT");
                    if(authResult){
                        if(authResult=="LOGIN_OK") {
                            //
                            //
                            hasDetailedLoginInformation = true;
                            loginResult = LOGIN_SUCCESS;
                            var accountState		=	cmdLoginInfoElement.getAttribute("ACCOUNT_STATE");
                            principalName			=	cmdLoginInfoElement.getAttribute("PRINCIPAL_NAME");
                            var accountDataComplete	=	cmdLoginInfoElement.getAttribute("ACCOUNT_DATA_IS_COMPLETE")
                            var accountValidated	=	cmdLoginInfoElement.getAttribute("ACCOUNT_VALIDATED")
                            var noEmail				=	cmdLoginInfoElement.getAttribute("ACCOUNT_HAS_NO_EMAIL");
                            //
                            //
                            principalName = principalName.replace(/\u0000/,"");
                            loggedInUserShortName = principalName;
                            //
                            //
                            if(trackUsage) {
                                trackUsage("/loggedIn");
                            }
                            //
                            //
                            if(accountState=="ACCOUNT_IS_DISABLED" || accountState=="LOCKED"){
                                loginResult=LOGIN_FAILED;
                            }
                            else if(emailValidationRequired==true && accountValidated!=null && accountValidated!=undefined){
                                emailValidated = accountValidated=="true";
                                Cookies.writeSessionCookie(ACCOUNT_VALIDATED_COOKIE_NAME, ""+accountValidated);
                            }
                            if(accountDataComplete=="ACCOUNT_REGISTRATION_IS_COMPLETE"){

                            }
                            if(noEmail==false){

                            }
                        }
                        else if(authResult=="LOGIN_FAILED") {
                            loginResult = AUTHENTICATION_FAILED;
                        }
                    }
                }
                if(loginResultHandler) {
                    var returnParameter = new Object();
                    returnParameter.name = returnParameterName;
                    returnParameter.value = returnParameterValue;
                    temp_principalName = principalName;
                    loginResultHandler.call(this, loginResult, temp_principalName, returnParameter);
                }
            });
        }
        else {
            if(loginResultHandler) loginResultHandler.call(this, ALREADY_LOGGED_IN);
        }

    }


    tenduke.opensocial.TendukeAccountAndProfile = TendukeAccountAndProfile;

})();
/**
 * Utilities for accessing people
 */
(function() {

    var People = {};

    /**
     * Get list of owner profiles friends
     * @param callback Signature: function(resultObject), where the following members may or may not be defined:
     *                      result.error                        // Defined if and only if there has been at least one error
     *                          result.error.defaultMessage     // Default (not localizable) error message
     *                          result.error.messageId          // Error id that can be used to provide localized error messages
     *                          result.error.nestedErrors       // Errors produced by the underlying requests
     *                          resultObject.friends            // Array of friends (field objects)
     *                          Structure of resultObject.friends array cell:
     *                          resultObject.friends[N].displayName
     *                          resultObject.friends[N].id
     *                          resultObject.friends[N].isOwner
     *                          resultObject.friends[N].isViewer
     *                          resultObject.friends[N].name
     *                              resultObject.friends[N].name.getField("familyName")
     *                              resultObject.friends[N].name.getField("formatted")
     *                              resultObject.friends[N].name.getField("givenName")
     *                              resultObject.friends[N].name.getField("unstructured")
     *                          resultObject.friends[N].nickname
     *                          resultObject.friends[N].profileUrl
     *                          resultObject.friends[N].thumbnailUrl
     *
     */
    People.getViewerFriends = function(callback) {
        //
        //
        var resultObject = {};
        //
        //
        var req = opensocial.newDataRequest();
        var viewerFriends = opensocial.newIdSpec({ "userId" : "VIEWER", "groupId" : "FRIENDS" });
        var opt_params = {};
        opt_params[opensocial.DataRequest.PeopleRequestFields.FILTER] = opensocial.DataRequest.FilterType.ALL;
        opt_params[opensocial.DataRequest.PeopleRequestFields.MAX] = 200;
        opt_params[opensocial.DataRequest.PeopleRequestFields.SORT_ORDER] = opensocial.DataRequest.SortOrder.NAME;
        req.add(req.newFetchPeopleRequest(viewerFriends, opt_params), 'viewerFriends');
        //
        //
        req.send(function (result) {
            //
            //
            var viewerFriends = result.get('viewerFriends').getData();
            if(!viewerFriends) {
                //
                //
                if(!resultObject.error) {
                    resultObject.error = {};
                }
                resultObject.error.defaultMessage = "Request to fetch viewer friends did not return data";
                resultObject.error.messageId = "People.error.noFriendsFound";
            }
            else {
                //
                //
                resultObject.friends = new Array();
                var friendsArray = viewerFriends.asArray();
                for(var i=0; i<friendsArray.length; i++) {
                    var aFriend = friendsArray[i];
                    resultObject.friends.push(aFriend.fields_);
                }
            }
            //
            if(callback) {
                callback(resultObject);
            }
        });
    }
    //
    //
    tenduke.opensocial.People = People;

})();
/**
 * Utility methods to help working with OpenSocial activity generation
 */
(function() {

    var Activity = {};

    /**
     * Create a new activity item for the viewer.
     * @param activityTitle A title for the new activity entry
     * @param activityBody Optional body for the activity
     * @param callback Signature: function(resultObject), where the following members may or may not be defined:
     *                      result.error                        // Defined if and only if there has been at least one error
     *                          result.error.defaultMessage     // Default (not localizable) error message, may not be defined
     *                          result.error.messageId          // Error id that can be used to provide localized error messages
     *                      
     */
    Activity.createActivity = function(activityTitle, activityBody, callback) {
        //
        //
        var resultObject = {};
        //
        //
        var newActivity = opensocial.newActivity();
        newActivity.setField(opensocial.Activity.Field.TITLE, activityTitle);
        if(activityBody) {
            newActivity.setField(opensocial.Activity.Field.BODY, activityBody);
        }
        opensocial.requestCreateActivity(newActivity, opensocial.CreateActivityPriority.LOW, function (result) {
            //
            //
            if(result) {
                if (result.error) {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    if(!resultObject.error.nestedErrors) {
                        resultObject.error.nestedErrors = new Array();
                    }
                    resultObject.error.messageId = "Activity.error.opensocial.requestCreateActivity.error";
                    resultObject.error.nestedErrors.push(result.error);
                    resultObject.success = false;
                } else {
                    resultObject.success = true;
                }
            }
            else {
                if(!resultObject.error) {
                    resultObject.error = {};
                }
                resultObject.error.defaultMessage = "Request to create activity entry failed";
                resultObject.error.messageId = "Activity.error.createFailed";
            }
            //
            if(callback) {
                callback(resultObject);
            }
        });
    }
    //
    //
    tenduke.opensocial.Activity = Activity;

})();
/**
 * Utility methods to help working with OpenSocial albums and media
 */
(function() {

    var NetlogAlbumsAndMedia = {};

    /**
     * Fetch all owners albums. At the time of writing the albums are limited to photo albums.
     * 
     * @param callback Signature: function(resultObject), where the following members may or may not be defined:
     *                      result.error                        // Defined if and only if there has been at least one error
     *                          result.error.defaultMessage     // Default (not localizable) error message
     *                          result.error.messageId          // Error id that can be used to provide localized error messages
     *                          result.error.nestedErrors       // Errors produced by the underlying requests
     *                      result.albums                       // Array of album objects
     *
     *                      result.albums is an Array of which each cell contains a data object with the following members:
     *                      result.albums[N].count, number: media item count in album
                            result.albums[N].description, string: album description
                            result.albums[N].id, string: identifier of album
                            result.albums[N].location, string: URL where album can be viewed in web page
                            result.albums[N].mediaItemCount, number: media item count in album
                            result.albums[N].mediaMimeType, string array: a mime type for each associated media item
                            result.albums[N].mediaType, string array: a media type for each associated media item
                            result.albums[N].ownerId, string: id of album owner profile
                            result.albums[N].thumbnailUrl, string: location / URL of album thumbnail image
                            result.albums[N].title, string: The title of the album
     */
    NetlogAlbumsAndMedia.requestOwnersAlbums = function(callback) {
        //
        //
        var resultObject = {};
        //
        //
        Netlog.Album.newFetchAlbumsRequest(opensocial.IdSpec.PersonId.OWNER, null, function (result) {
            //
            //
            if(result) {
                if(result.error) {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    if(!resultObject.error.nestedErrors) {
                        resultObject.error.nestedErrors = new Array();
                    }
                    resultObject.error.nestedErrors.push(result.error);
                }
                //
                //
                var albumsArray = result.getData();
                if(albumsArray!=null && albumsArray!=undefined && albumsArray.length>0) {
                    resultObject.albums = new Array();
                    for(var albumIndex=0; albumIndex<albumsArray.length; albumIndex++) {
                        var albumInstance = albumsArray[albumIndex].data;
                        resultObject.albums.push(albumInstance);
//                        showAlert(
//                        "Albums[" + albumIndex + "].count --> " + albumInstance.count + "\n" +
//                        "Albums[" + albumIndex + "].description --> " + albumInstance.description + "\n" +
//                        "Albums[" + albumIndex + "].id --> " + albumInstance.id + "\n" +
//                        "Albums[" + albumIndex + "].location --> " + albumInstance.location + "\n" +
//                        "Albums[" + albumIndex + "].mediaItemCount --> " + albumInstance.mediaItemCount + "\n" +
//                        "Albums[" + albumIndex + "].mediaMimeType[0] --> " + albumInstance.mediaMimeType[0] + "\n" +
//                        "Albums[" + albumIndex + "].mediaType[0] --> " + albumInstance.mediaType[0] + "\n" +
//                        "Albums[" + albumIndex + "].ownerId --> " + albumInstance.ownerId + "\n" +
//                        "Albums[" + albumIndex + "].thumbnailUrl --> " + albumInstance.thumbnailUrl + "\n" +
//                        "Albums[" + albumIndex + "].title --> " + albumInstance.title);
                    }
                }
                //
                //
                if(!resultObject.albums) {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    resultObject.error.defaultMessage = "Request to fetch owner albums did not return album ids";
                    resultObject.error.messageId = "NetlogAlbumsAndMedia.error.noAlbumsFound";
                }
            }
            else {
                if(!resultObject.error) {
                    resultObject.error = {};
                }
                resultObject.error.defaultMessage = "Request to fetch owner albums failed";
                resultObject.error.messageId = "NetlogAlbumsAndMedia.error.ownerAlbumsRequestFailed";
            }
            //
            if(callback) {
                callback(resultObject);
            }
        });
    }
    //
    //
    tenduke.opensocial.NetlogAlbumsAndMedia = NetlogAlbumsAndMedia;

})();
/**
 * Utility methods to help working with Netlog OpenSocial messaging
 * At the time of riting Netlog supports notifications and private messaging.
 */
(function() {

    var NetlogMessaging = {};

    /**
     * Request sending a private message.
     * @param recipients Recipients for message: array of user Id's
     * @param subject Subject / title of message
     * @param messageBody The message body text
     * @param optParams Optional parameter list. Content passed as such (key-value) pairs with Netlog.Message.Field.PARAMS to sendMessage request..
     *                  Example: { 'childView':'gallery','videoId' : 'video157' }
     * @param callback Signature: function(resultObject), where the following members may or may not be defined:
     *                      result.error                        // Defined if and only if there has been at least one error
     *                          result.error.defaultMessage     // Default (not localizable) error message
     *                          result.error.messageId          // Error id that can be used to provide localized error messages
     *                          result.error.nestedErrors       // Errors produced by the underlying requests
     *                      
     */
    NetlogMessaging.sendPrivateMessage = function(recipients, subject, messageBody, optParams, callback) {
        //
        //
        var resultObject = {};
        //
        //
        var params = {};
        params[opensocial.Message.Field.TYPE] = opensocial.Message.Type.PRIVATE_MESSAGE;
        params[opensocial.Message.Field.TITLE] = subject;
        params[Netlog.Message.Field.PARAMS] = optParams;
        var message = opensocial.newMessage(messageBody, params);
        //
        //
        opensocial.requestSendMessage(recipients, message, function (result) {
            //
            //
            
            if(result) {
                if (result.hadError()) {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    if(!resultObject.error.nestedErrors) {
                        resultObject.error.nestedErrors = new Array();
                    }
                    resultObject.error.nestedErrors.push(result.error);
                    resultObject.success = false;
                } else {
                    resultObject.success = true;
                }
            }
            else {
                if(!resultObject.error) {
                    resultObject.error = {};
                }
                resultObject.error.defaultMessage = "Request to send privat message failed";
                resultObject.error.messageId = "NetlogMessaging.error.privateMessageFailed";
            }
            //
            if(callback) {
                callback(resultObject);
            }
        });
    }
    NetlogMessaging.sendNotification = function(recipients, subject, messageBody, optParams, callback) {
    	NetlogMessaging.sendPrivateMessage(recipients, subject, messageBody, optParams, callback);
    }
    //
    //
    tenduke.opensocial.NetlogMessaging = NetlogMessaging;

})();
/**
 * Utility methods to help working with Netlog Payment class,
 * The class provides utility methods for subscribing
 * 
 *  Add <Require feature="payment"/> to gadget.xml
 */
(function() {

    var NetlogPayment = {};

    /**
     * Netlog credit system based implementation of application / module subscription.
     * @param subscriptionId Name / identifier for what to subscribe
     * @param optParams A message to display to the end user to explain details about the transaction
     * @param callback Signature: function(resultObject), where the following members may or may not be defined:
     *                      result.error                    // Defined if and only if there has been at least one error
     *                      result.error.defaultMessage     // Default (not localizable) error message
     *                      result.error.messageId          // Error id that can be used to provide localized error messages
     *                      result.error.nestedErrors       // Errors produced by the underlying requests
     *
     *                      result.status                   // Instance of subscriptionTransactionStatus with transaction status information
     *                      
     */
    NetlogPayment.subscribe = function(subscriptionId, optParams, callback) {
        //
        //
        var resultObject = {};
        //
        //
        var amountToRequest = tenduke.licensing.subscription.SubscriptionInfo.getInstance().getPrice(subscriptionId);
        var messageBody = tenduke.licensing.subscription.SubscriptionInfo.getInstance().getDescription(subscriptionId);
        //
        //
        function defaultSubscriptionResultHandler(result) {
            //
            //
            if(result) {
                if(result.error) {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    if(!resultObject.error.nestedErrors) {
                        resultObject.error.nestedErrors = new Array();
                    }
                    resultObject.error.nestedErrors.push(result.error);
                }
                else {
                    var resultDataObject = null;
                    if(result.getData && result.getData()) {
                        resultDataObject = result.getData();
                    }
                    if(resultDataObject) {
                        //
                        //
                        var state = resultDataObject.getField('state');
                        resultObject.status = new tenduke.licensing.subscription.SubscriptionTransactionStatus();
                        if (state == Payment.State.ACCEPTED)
                        {
                            resultObject.status.setStatus(tenduke.licensing.subscription.SubscriptionTransactionStatus.Accepted);
                        }
                        else if (state == Payment.State.DENIED)
                        {
                            resultObject.status.setStatus(tenduke.licensing.subscription.SubscriptionTransactionStatus.Denied);
                        }
                        else if (state == Payment.State.CANCELLED)
                        {
                            resultObject.status.setStatus(tenduke.licensing.subscription.SubscriptionTransactionStatus.Cancelled);
                        }
                    }
                    else {
                        if(!resultObject.error) {
                            resultObject.error = {};
                        }
                        resultObject.error.defaultMessage = "Subscription payment request failed, no result.data provided";
                        resultObject.error.messageId = "Subscription.error.noTransactionResultDataObject";
                    }
                }
            }
            else {
                if(!resultObject.error) {
                    resultObject.error = {};
                }
                resultObject.error.defaultMessage = "Subscription payment request failed, no result provided";
                resultObject.error.messageId = "Subscription.error.noTransactionResult";
            }
            //
            //
            if(callback) {
                callback.apply(this, new Array(resultObject));
            }
        }
        //
        //
        if(amountToRequest!=null) {
        	/*
 			*  Add <Require feature="payment"/> to gadget.xml
 			*/
            var payment = new Payment(amountToRequest, messageBody);
            var opt_params = {};
            Payment.requestPayment(payment, defaultSubscriptionResultHandler, opt_params);
        }
        else {
            //
            //
            if(!resultObject.error) {
                resultObject.error = {};
            }
            resultObject.error.defaultMessage = "Subscription can not be made unless subscriptionId is specified and price / amount for subscription is available in SubscriptionInfo";
            resultObject.error.messageId = "Subscription.error.couldNotResolveSubscriptionPrice";
            //
            //
            if(callback) {
                callback.apply(this, new Array(resultObject));
            }
        }
    }

    /**
     * Get subscription info for the user who owns the session (viewer).
     * @param subscriptionId Name / identifier for subscription to get info on (if set as null then all user subscription info is returned)
     * @param optParams Reserved to hold potentially range, offset etc info to control result set
     * @param callback Signature: function(resultObject), where the following members may or may not be defined:
     *                      result.error                    // Defined if and only if there has been at least one error
     *                      result.error.defaultMessage     // Default (not localizable) error message
     *                      result.error.messageId          // Error id that can be used to provide localized error messages
     *                      result.error.nestedErrors       // Errors produced by the underlying requests
     *
     *                      result.subscriptionInfo         // Array with instances of SubscriptionInfo objects
     *
     */
    NetlogPayment.getSessionUserSubscriptionInfo = function(subscriptionId, optParams, callback) {
        //
        //
        var resultObject = {};
        //
        //
        var commands = "<COMMANDS PROPAGATE=\"false\">";
        commands += "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.GetLicensedItemSubscription\"";
        commands += " ORDER_BY=\"created\" />";
        commands += "</COMMANDS>";
        tenduke.opensocial.RequestUtils.asyncCommandRequest(commands, function(result) {
            //
            //
            if(result && result.error) {
                if(!resultObject.error) {
                    resultObject.error = {};
                }
                if(!resultObject.error.nestedErrors) {
                    resultObject.error.nestedErrors = new Array();
                }
                resultObject.error.nestedErrors.push(result.error);
            }
            //
            //
            var resultXml = null;
            if(result!=null && result!=undefined) {
                if(result.data!=null && result.data!=undefined) {
                    if(result.data.documentElement!=null && result.data.documentElement!=undefined) {
                        resultXml = result.data.documentElement;
                    }
                    else {
                        if(!resultObject.error) {
                            resultObject.error = {};
                        }
                        resultObject.error.defaultMessage = "Unkown result object received from OpenSocial container for GetLicensedItemSubscription command response";
                        resultObject.error.messageId = "NetlogPayment.error.unkownOpenSocialResultObjectType";
                    }
                }
                else if(result.text!=null && result.text!=undefined) {
                    //
                    //
                    resultXml = tenduke.util.XmlUtils.createDomDocumentFromText(result.text);
                    if(resultXml==null) {
                        if(!resultObject.error) {
                            resultObject.error = {};
                        }
                        resultObject.error.defaultMessage = "XML parsing error for GetLicensedItemSubscription command response";
                        resultObject.error.messageId = "TendukeAccountAndProfile.error.xmlParserExceptionForGetLicensedItemSubscription";
                        if(!resultObject.error.nestedErrors) {
                            resultObject.error.nestedErrors = new Array();
                        }
                        resultObject.error.nestedErrors.push(xmlE);
                    }
                }
                else {}
            }
            else {
                if(!resultObject.error) {
                    resultObject.error = {};
                }
                resultObject.error.defaultMessage = "No result object received from OpenSocial container for profile query";
                resultObject.error.messageId = "TendukeAccountAndProfile.error.missingOpenSocialResultObject";
            }
            //
            //
            if(resultXml!=null && resultXml!=undefined) {
                var licensedItemSubscriptionNode = tenduke.util.XmlUtils.findFirstNodeByName(resultXml, "LicensedItemSubscription");
                if(licensedItemSubscriptionNode!=null) {
                    //
                    //
                    var startDateAsString = licensedItemSubscriptionNode.getAttribute("startDate");
                    var endDateAsString = licensedItemSubscriptionNode.getAttribute("endDate");
                    var startDate = tenduke.util.DateAndTimeUtils.parseIso8601UtcDate(startDateAsString);
                    var endDate = tenduke.util.DateAndTimeUtils.parseIso8601UtcDate(endDateAsString);
                    if(startDate!=null && endDate!=null) {
                        resultObject.subscriptionInfo = new Array();
                        resultObject.subscriptionInfo.push(new tenduke.licensing.subscription.SubscriptionInfo());
                        resultObject.subscriptionInfo[0].setSubscriptionStarted(subscriptionId, startDate);
                        resultObject.subscriptionInfo[0].setSubscriptionEnds(subscriptionId, endDate);
                        resultObject.subscriptionInfo[0].setDuration(subscriptionId, endDate.getTime() - startDate.getTime());
                    }
                    else {
                        resultObject.subscriptionInfo = null;
                    }
                }
                else {
                    resultObject.subscriptionInfo = null;
                }
            }
            else {
                resultObject.subscriptionInfo = null;
            }
            //
            //
            if(callback) {
                callback.apply(this, new Array(resultObject));
            }
        });
    }

    /**
     * Method for application to request payment from user
     * @param itemName Name / identifier for what to pay for
     * @param optParams A message to display to the end user to explain details about the transaction
     * @param callback Signature: function(resultObject), where the following members may or may not be defined:
     *                      result.error                    // Defined if and only if there has been at least one error
     *                      result.error.defaultMessage     // Default (not localizable) error message
     *                      result.error.messageId          // Error id that can be used to provide localized error messages
     *                      result.error.nestedErrors       // Errors produced by the underlying requests
     *
     *                      result.status                   // Instance of PaymentTransactionStatus with transaction status information
     *
     */
    NetlogPayment.requestPayment = function(itemName, optParams, callback) {
        //
        //
        var resultObject = {};
        //
        //
        var amountToRequest = tenduke.licensing.PaymentInfo.getInstance().getPrice(itemName);
        var messageBody = tenduke.licensing.PaymentInfo.getInstance().getDescription(itemName);
        //
        //
        function defaultPaymentResultHandler(result) {
            //
            //
            if(result) {
                if(result.error) {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    if(!resultObject.error.nestedErrors) {
                        resultObject.error.nestedErrors = new Array();
                    }
                    resultObject.error.nestedErrors.push(result.error);
                }
                else {
                    var resultDataObject = null;
                    if(result.getData && result.getData()) {
                        resultDataObject = result.getData();
                    }
                    if(resultDataObject) {
                        //
                        //
                        var state = resultDataObject.getField('state');
                        resultObject.status = new tenduke.licensing.PaymentTransactionStatus();
                        if (state == Payment.State.ACCEPTED)
                        {
                            resultObject.status.setStatus(tenduke.licensing.PaymentTransactionStatus.Accepted);
                        }
                        else if (state == Payment.State.DENIED)
                        {
                            resultObject.status.setStatus(tenduke.licensing.PaymentTransactionStatus.Denied);
                        }
                        else if (state == Payment.State.CANCELLED)
                        {
                            resultObject.status.setStatus(tenduke.licensing.PaymentTransactionStatus.Cancelled);
                        }
                    }
                    else {
                        if(!resultObject.error) {
                            resultObject.error = {};
                        }
                        resultObject.error.defaultMessage = "payment request failed, no result.data provided";
                        resultObject.error.messageId = "Payment.error.noTransactionResultDataObject";
                    }
                }
            }
            else {
                if(!resultObject.error) {
                    resultObject.error = {};
                }
                resultObject.error.defaultMessage = "Payment request failed, no result provided";
                resultObject.error.messageId = "Payment.error.noTransactionResult";
            }
            //
            //
            if(callback) {
                callback.apply(this, new Array(resultObject));
            }
        }
        //
        //
        if(amountToRequest!=null) {
        	/*
 			*  Add <Require feature="payment"/> to gadget.xml
 			*/
            var payment = new Payment(amountToRequest, messageBody);
            var opt_params = {};
            Payment.requestPayment(payment, defaultPaymentResultHandler, opt_params);
        }
        else {
            //
            //
            if(!resultObject.error) {
                resultObject.error = {};
            }
            resultObject.error.defaultMessage = "Payment can not be made unless itemName is specified and price / amount for payment is available in PaymentInfo";
            resultObject.error.messageId = "Payment.error.couldNotResolvePaymentPrice";
            //
            //
            if(callback) {
                callback.apply(this, new Array(resultObject));
            }
        }
    }

    /**
     * Get payment info for the user who owns the session (viewer).
     * @param itemName Name / identifier for payment to get info on.s
     * @param callback Signature: function(resultObject), where the following members may or may not be defined:
     *                      result.error                    // Defined if and only if there has been at least one error
     *                      result.error.defaultMessage     // Default (not localizable) error message
     *                      result.error.messageId          // Error id that can be used to provide localized error messages
     *                      result.error.nestedErrors       // Errors produced by the underlying requests
     *
     *                      result.paymentInfoArray         // Array with instances of PaymentInfo objects
     *
     */
    NetlogPayment.queryPaymentInfo = function(itemName, callback) {
        //
        //
        var resultObject = {};
        //
        //
        var commands = "<COMMANDS PROPAGATE=\"false\">";
        commands += "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.GetLicensedItemPayment\"";
        commands += " ORDER_BY=\"created\" />";
        commands += "</COMMANDS>";
        tenduke.opensocial.RequestUtils.asyncCommandRequest(commands, function(result) {
            //
            //
            if(result && result.error) {
                if(!resultObject.error) {
                    resultObject.error = {};
                }
                if(!resultObject.error.nestedErrors) {
                    resultObject.error.nestedErrors = new Array();
                }
                resultObject.error.nestedErrors.push(result.error);
            }
            //
            //
            var resultXml = null;
            if(result!=null && result!=undefined) {
                if(result.data!=null && result.data!=undefined) {
                    if(result.data.documentElement!=null && result.data.documentElement!=undefined) {
                        resultXml = result.data.documentElement;
                    }
                    else {
                        if(!resultObject.error) {
                            resultObject.error = {};
                        }
                        resultObject.error.defaultMessage = "Unkown result object received from OpenSocial container for GetLicensedItemPayment command response";
                        resultObject.error.messageId = "Payment.error.unkownOpenSocialResultObjectType";
                    }
                }
                else if(result.text!=null && result.text!=undefined) {
                    //
                    //
                    resultXml = tenduke.util.XmlUtils.createDomDocumentFromText(result.text);
                    if(resultXml==null) {
                        if(!resultObject.error) {
                            resultObject.error = {};
                        }
                        resultObject.error.defaultMessage = "XML parsing error for GetLicensedItemPayment command response";
                        resultObject.error.messageId = "Payment.error.xmlParserExceptionForGetLicensedItemPayment";
                        if(!resultObject.error.nestedErrors) {
                            resultObject.error.nestedErrors = new Array();
                        }
                        resultObject.error.nestedErrors.push(xmlE);
                    }
                }
                else {}
            }
            else {
                if(!resultObject.error) {
                    resultObject.error = {};
                }
                resultObject.error.defaultMessage = "No result object received from OpenSocial container for profile query";
                resultObject.error.messageId = "Payment.error.missingOpenSocialResultObject";
            }
            //
            //
            if(resultXml!=null && resultXml!=undefined) {
                var licensedItemPaymentNode = tenduke.util.XmlUtils.findFirstNodeByName(resultXml, "LicensedItemPayment");
                if(licensedItemPaymentNode!=null) {
                    //
                    //
                    var paymentTimeAsString = licensedItemPaymentNode.getAttribute("paymentTime");
                    var paymentTime = tenduke.util.DateAndTimeUtils.parseIso8601UtcDate(paymentTimeAsString);
                    var priceString = licensedItemPaymentNode.getAttribute("price");
                    var price = parseFloat(priceString);
                    if(startDate!=null) {
                        resultObject.paymentInfo = new Array();
                        resultObject.paymentInfo.push(new tenduke.licensing.PaymentInfo());
                        resultObject.paymentInfo[0].setPaymentMade(itemName, startDate);
                        resultObject.paymentInfo[0].setPrice(itemName, amount);
                    }
                    else {
                        resultObject.paymentInfo = null;
                    }
                }
                else {
                    resultObject.paymentInfo = null;
                }
            }
            else {
                resultObject.paymentInfo = null;
            }
            //
            //
            if(callback) {
                callback.apply(this, new Array(resultObject));
            }
        });
    }

    /**
     * Get payment info for the user who owns the session (viewer).
     * This method returns cached information based on previous call
     * to queryPaymentInfo.
     * 
     * @param itemName Name / identifier for payment to get info on
     * @return Array of PaymentInfo instances
     *
     */
    NetlogPayment.getPaymentInfo = function(itemName) {
        //
        //
        var retValue = new Array();
        retValue.push(new tenduke.licensing.PaymentInfo());
        retValue[0].setPaymentTime(itemName, new Date().getTime());
        retValue[0].setPrice(itemName, 20);
        //
        //
        return retValue;
    }

    //
    //
    tenduke.opensocial.NetlogPayment = NetlogPayment;

})();
var tenduke = tenduke || {};
tenduke.facebook = tenduke.facebook || {};

/**
 * 
 */
(function() {

	/*
	* IMPORTS / dependencies to external assets
	isLoggedIn()
	*/
	var ResourceImporter = tenduke.util.ResourceImporter;
	var Authentication = tenduke.facebook.Authentication;
	var TendukeAccountAndProfile = tenduke.facebook.TendukeAccountAndProfile;
	var Function_ = tenduke.util.js.Function;
	/*
	* END IMPORTS
	*/
	
	var FacebookConnect=function(){}
    
    FacebookConnect.prototype.libraryUrls=["http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/en_US"];
    FacebookConnect.prototype.apiKey=null;
    FacebookConnect.prototype.crossdomainReceiver="/xd_receiver.html";
    FacebookConnect.prototype.facebookApi=null;
    /**
   	
    */
    FacebookConnect.prototype.init=function(callback){
    	var c = Function_.createScopedFunction(this, function(){
    		if(this.apiKey!=null){
		    	FB.init(this.apiKey, this.crossdomainReceiver);//, {"ifUserConnected" : onFacebookConnectLogin});
	            this.facebookApi = null;
	            FB.Bootstrap.requireFeatures(["Api"], Function_.createScopedFunction(this, function() {
		        	//
		        	//
		        	//
		        	//
		        	FB.Bootstrap.requireFeatures(["Connect"], function() {
		        		callback();
		        	});
		        }));
	        }
	        else{
	        }
	    });
	    
	    var anFB = null;
	    if(typeof FB != "undefined"){
	    	anFB = FB;
	    }
        if(anFB!=null && anFB!=undefined){
        	c();
        }
        else{
		    ResourceImporter.importJSCollection(this.libraryUrls,c);
		}
    }
    FacebookConnect.prototype.requireSession=function(callback,cancelCallback,isUserAction){
    	FB.Connect.requireSession(Function_.createScopedFunction(this, function(){
    		if(this.apiKey!=null){
	    		this.facebookApi = new FB.ApiClient(this.apiKey, this.crossdomainReceiver, null);
    			callback();
    		}
    		else{
	        }
    	}),function(){if(cancelCallback!=null){cancelCallback();}},(isUserAction==true));
	}
    //
    //
    tenduke.facebook.FacebookConnect = new FacebookConnect();

})();
var tenduke = tenduke || {};
tenduke.facebook = tenduke.facebook || {};
/**
 * Utilities for fitting together Facebook profiles and 10Duke accounts and profiles
 */
(function() {

    var TendukeAccountAndProfile = {};
    /*
     * IMPORTS / dependencies to external assets
     */
    var Account = tenduke.objectmodel.Account;
    var Profile = tenduke.objectmodel.Profile;
    var ContactDetails = tenduke.objectmodel.ContactDetails;
    var EmailAddress = tenduke.objectmodel.EmailAddress;
    var PostalAddress = tenduke.objectmodel.PostalAddress;
    var Batch = tenduke.serverinterface.Batch;
    var CreateOrUpdateAccount = tenduke.serverinterface.CreateOrUpdateAccount;
    var CreateOrUpdateProfile = tenduke.serverinterface.CreateOrUpdateProfile;
    var FacebookConnect = tenduke.facebook.FacebookConnect;

    
    /**
     * Initialize account and profile to 10Duke backend. It is assumed that 
     * the account and profile exists and they will only be updated by this call.
     * @param callback Signature: function(resultObject), where the following members may or may not be defined:
     *                      result.error                        // Defined if and only if there has been at least one error
     *                          result.error.defaultMessage     // Default (not localizable) error message
     *                          result.error.messageId          // Error id that can be used to provide localized error messages
     *                          result.error.nestedErrors       // Errors produced by the underlying requests
     *                      result.profile                      // Profile object model representing the initialized profile.
     */
    TendukeAccountAndProfile.initAccountAndProfile = function(callback) {
        //
        var resultObject = {};
        //
        //
        var fbLoggedInUser = FB.Connect.get_loggedInUser();
        var fbLoggedInUserArray = new Array();
        if(fbLoggedInUser) {
            fbLoggedInUserArray.push(fbLoggedInUser);
        }
        //
        // assemble list of facebook profile details to query
        var infoArray = new Array();
        infoArray.push("name");
        infoArray.push("first_name");
        infoArray.push("last_name");
        infoArray.push("username");
        infoArray.push("proxied_email");
        infoArray.push("email");
        infoArray.push("birthday");
        infoArray.push("birthday_date");
        infoArray.push("pic");
        infoArray.push("pic_big");
        infoArray.push("pic_small");
        infoArray.push("sex");
        infoArray.push("current_location");
        infoArray.push("about_me");
        infoArray.push("locale");
        infoArray.push("verified");
        infoArray.push("is_blocked");
        //
        //
        if(fbLoggedInUserArray && fbLoggedInUserArray.length>0) {
            //
            //
            FacebookConnect.facebookApi.users_getInfo(fbLoggedInUser, infoArray, function(userInfoResult) {
                //
                //
                if(userInfoResult && userInfoResult.length && userInfoResult.length>0) {
                    //
                    // read values from query result object
                    var fb_uid = userInfoResult[0].uid;
                    var fb_name = userInfoResult[0].name;
                    var fb_first_name = userInfoResult[0].first_name;
                    var fb_last_name = userInfoResult[0].last_name;
                    var fb_email = userInfoResult[0].email;
                    var fb_proxied_email = userInfoResult[0].proxied_email;
                    var fb_birthday = userInfoResult[0].birthday;
                    var fb_birthday_date = userInfoResult[0].birthday_date;
                    if(fb_birthday_date!=null && fb_birthday_date!=undefined &&  typeof(fb_birthday_date)!="Date"){
                    	fb_birthday_date = new Date(fb_birthday_date);
                    }
                    else{
                    	fb_birthday_date=null;
                    }
                    var fb_pic = userInfoResult[0].pic;
                    var fb_pic_big = userInfoResult[0].pic_big;
                    var fb_pic_small = userInfoResult[0].pic_small;
                    var fb_sex = userInfoResult[0].sex;
                    var fb_current_location = userInfoResult[0].current_location;
                    var fb_about_me = userInfoResult[0].about_me;
                    var fb_locale = userInfoResult[0].locale;
                    var fb_verified = userInfoResult[0].verified;
                    var fb_is_blocked = userInfoResult[0].is_blocked;
                    //
                    //
                    var userId = "" + fb_uid;
                    if(userId){
                        userId = userId.replace(/\W/g,"_");
                    }
                    //
                    // create account update request
                    var account = new Account();
                    account.setPrimaryPrincipal(userId);
                    account.setPrimaryEmail(fb_proxied_email);
                    //
                    //
                    var createOrUpdateAccountParams = {};
                    createOrUpdateAccountParams.account = account;
                    createOrUpdateAccountParams.updateByPrimaryPrincipal = true;
                    createOrUpdateAccountParams.generatePassword = true;
                    var createOrUpdateAccount = CreateOrUpdateAccount.makeRequest(createOrUpdateAccountParams);
                    //
                    // create profile update request
                    var profile = new Profile();
                    profile.setShortName(userId);
                    profile.setDisplayName(fb_name);
                    profile.setDescription(fb_about_me);
                    profile.setProfileImageUrl(fb_pic);
                    profile.setGender(fb_sex);
                    profile.setBirthday(fb_birthday_date);
                    //
                    //
                    var contactDetails = new ContactDetails();
                    contactDetails.setGivenName(fb_first_name);
                    contactDetails.setFamilyName(fb_last_name);
                    contactDetails.setFormattedName(fb_name);
                    //
                    //
                    profile.setContactDetails(contactDetails);
                    //
                    //
                    var email = new EmailAddress();
                    if(fb_email!=null && fb_email!=undefined){
                    	email.setValue(fb_email);
                    }
                    else{
                    	email.setValue(fb_proxied_email);
                    }
                    //
                    //
                    var postalAddress = new PostalAddress();
                    postalAddress.setCountry(fb_current_location);
                    //
                    //
                    contactDetails.setEmail(email);
                    contactDetails.setPostalAddress(postalAddress);
                    //
                    //
                    var createOrUpdateProfileParams = {};
                    createOrUpdateProfileParams.profile = profile;
                    //
                    //
                    var createOrUpdateProfile = CreateOrUpdateProfile.makeRequest(createOrUpdateProfileParams);
                    //
                    //
                    var batch = Batch.newBatch();
                    batch.add("createOrUpdateAccount", createOrUpdateAccount);
                    batch.add("createOrUpdateProfile", createOrUpdateProfile);
                    //
                    //
                    batch.execute(function(result) {
                        //
                        //
                        if(result) {
                            //
                            // todo: update profile data
                            resultObject.profile = profile;
                            resultObject.request = batch;
                            resultObject.response = result;
                            callback.call(this, resultObject);
                        }
                    });
                }
            });
        }
        else {
            if(callback) {
                if(!resultObject.error) {
                    resultObject.error = {};
                }
                resultObject.error.defaultMessage = "No Facebook logged in user object resolved in 10Duke account initialization";
                resultObject.error.messageId = "TendukeAccountAndProfile.error.createAccountMissingFacebookLoggedInUser";
                callback(resultObject);
            }
        }
    }

    //
    //
    tenduke.facebook.TendukeAccountAndProfile = TendukeAccountAndProfile;

})();
var tenduke = tenduke || {};
tenduke.facebook = tenduke.facebook || {};

/**
 * Utilities for fitting together Facebook profiles and 10Duke accounts and profiles
 */
(function() {

    var Authentication = {};
	/*
	* IMPORTS / dependencies to external assets
	* Depends on an old style asset RegistrationApi.js
	* Depends on an old style asset Properties.js
	* Depends on an old style asset ProfileAPI.js
	* Depends on an old style asset Validator.js
	* Depends on an old style asset LoginUtils.js
	* Depends on an old style asset RequestUtils.js
	* Depends on an old style asset ContactProperties.js
	*/
        var LoginRequest = tenduke.serverinterface.LoginRequest;
        var FacebookConnect = tenduke.facebook.FacebookConnect;
	
	/*
	* END IMPORTS
	*/


    /**
     * Logout current logged in profile.
     * @param logoutResultHandler Signature: function(resultObject), where the following members may or may not be defined:
             *                      result.error                        // Defined if and only if there has been at least one error
             *                          result.error.defaultMessage     // Default (not localizable) error message
             *                          result.error.messageId          // Error id that can be used to provide localized error messages
             *                          result.error.nestedErrors       // Errors produced by the underlying requests
     */
    Authentication.logout = function(logoutResultHandler) {
        //
        //
        var resultObject = {};
        if(logoutResultHandler) {
            logoutResultHandler.call(this, resultObject);
        }
    }

    /**
     * Create an authenticated session with the connected application, not primarily with facebook. Calling this
     * method requires that the user is already logged in on facebook.
     * @param loginResultHandler function call back for handling login request results.
     *        loginResultHandler signature: fnc(aResultCode:int), where aResultCode can be LOGIN_SUCCESS | LOGIN_FAILED | ALREADY_LOGGED_IN.
     */
    Authentication.login = function(loginResultHandler) {
        //
        //
        var resultObject = {};
        //
        //
        var fbLoggedInUser = FB.Connect.get_loggedInUser();
        var fbLoggedInUserArray = new Array();
        if(fbLoggedInUser) {
            fbLoggedInUserArray.push(fbLoggedInUser);
        }
        //
        //
        var infoArray = new Array();
        infoArray.push("name");
        infoArray.push("locale");
        infoArray.push("verified");
        infoArray.push("is_blocked");
        //
        //
        if(fbLoggedInUserArray && fbLoggedInUserArray.length>0) {
            //
            //
            FacebookConnect.facebookApi.users_getInfo(fbLoggedInUser, infoArray, function(userInfoResult) {
                //
                //
                if(fbLoggedInUser) {
                    //
                    //
                    var loggedInUserInfo = ((userInfoResult && userInfoResult.length && userInfoResult.length>0)? userInfoResult[0]:null);
                    var fb_uid = fbLoggedInUser; //userInfoResult[0].uid;
                    // var principalName = fb_uid;
                    // var fb_name = userInfoResult[0].name;
					// var fb_locale = userInfoResult[0].locale;
                    // var fb_verified = userInfoResult[0].verified;
                    // var fb_is_blocked = userInfoResult[0].is_blocked;
                    //
                    //
                    var returnParameterName = "ACCOUNT_STATE";
                    //
                    //
                    var loginParameters = new Object();
                    loginParameters.loginOperation = LOGIN_OPERATION_LOGIN;
                    loginParameters.returnParameter = returnParameterName;
                    loginParameters.userName = "" + fb_uid;
//                    loginParameters.locale = fb_locale;
                    //
                    //
                    var loginRequest = new LoginRequest.makeRequest(loginParameters);
                    loginRequest.execute(function(resultObject) {
                        //
                        //
                        if(loginResultHandler && resultObject) {
                            //
                            //
                            loginResultHandler.call(this, resultObject);
                        }
                    });                    
                }
            });
        }
        else {
            //alert("Facebook API error: Facebook did not respond logged in user");
        }
    }
    //
    //
    tenduke.facebook.Authentication = Authentication;

})();

function Hashtable(){
    this.clear = hashtable_clear;
    this.containsKey = hashtable_containsKey;
	this.indexOfKey = hashtable_indexOfKey;
    this.containsValue = hashtable_containsValue;
    this.getEntry = hashtable_get;
    this.isEmpty = hashtable_isEmpty;
    this.keys = hashtable_keys;
    this.putEntry = hashtable_put;
    this.remove = hashtable_remove;
    this.size = hashtable_size;
    this.toString = hashtable_toString;
    this.values = hashtable_values;
    this.hashtable = new Array();
}

/*=======Private methods for internal use only========*/

function hashtable_clear(){
    this.hashtable = new Array();
}

function hashtable_containsKey(key){
    var exists = false;
    for (var i in this.hashtable) {
        if (i == key && this.hashtable[i] != null) {
            exists = true;
            break;
        }
    }
    return exists;
}
function hashtable_indexOfKey(key){
    var exists = -1;
    for (var i=0; i<this.keys().length; i++) {
        if (this.keys()[i] == key) {
            exists = i;
            break;
        }
    }
    return exists;
}

function hashtable_containsValue(value){
    var contains = false;
    if (value != null) {
        for (var i in this.hashtable) {
            if (this.hashtable[i] == value) {
                contains = true;
                break;
            }
        }
    }
    return contains;
}

function hashtable_get(key){
    return this.hashtable[key];
}

function hashtable_isEmpty(){
    return (parseInt(this.size()) == 0) ? true : false;
}

function hashtable_keys(){
    var keys = new Array();
    for (var i in this.hashtable) {
        if (this.hashtable[i] != null)
            keys.push(i);
    }
    return keys;
}

function hashtable_put(key, value){
    if (key == null || value == null) {
        throw "NullPointerException {" + key + "},{" + value + "}";
    }else{
        this.hashtable[key] = value;
    }
}

function hashtable_remove(key){
    var rtn = this.hashtable[key];
    this.hashtable[key] = null;
    return rtn;
}

function hashtable_size(){
    var size = 0;
    for (var i in this.hashtable) {
        if (this.hashtable[i] != null)
            size ++;
    }
    return size;
}

function hashtable_toString(){
    var result = "";
    for (var i in this.hashtable)
    {     
        if (this.hashtable[i] != null)
            result += "{" + i + "},{" + this.hashtable[i] + "}\n";  
    }
    return result;
}

function hashtable_values(){
    var values = new Array();
    for (var i in this.hashtable) {
        if (this.hashtable[i] != null)
            values.push(this.hashtable[i]);
    }
    return values;
}
/** 
*/
/* IMPORTS / external dependencies
* hashtable.js
* tenduke.util.Base64
*/
/*
* Backwards compatibility support
*/
	var tenduke = tenduke || {};
	if(encode64){
		tenduke.util = tenduke.util || {};
		if(!tenduke.util.Base64){
			tenduke.util.Base64 = {};
			tenduke.util.Base64.encode64=encode64;
			tenduke.util.Base64.decode64=decode64;
		}
	}
/*
* Backwards compatibility support END
*/
function Properties() {
		
    /** */
    this.rootElementName = "PARAMS";
    /** */
    this.getRootElementName = props_getRootElementName;
    /** */
    this.setRootElementName = props_setRootElementName;
    /** */
    this.rootElementAttributes = new Array();
    /** */
    this.setRootElementAttribute = props_setRootElementAttribute;  
    /** */
    this.propertyElementName = "PARAM";
    /** */
    this.getPropertyElementName = props_getPropertyElementName;
    /** */
    this.setPropertyElementName = props_setPropertyElementName;
    /** */
    this.propertyNameAttributeName = "NAME";
    /** */
    this.getPropertyNameAttributeName = props_getPropertyNameAttributeName;
    /** */
    this.setPropertyNameAttributeName = props_setPropertyNameAttributeName;
    /** */
    this.propertyValueAttributeName = "VALUE";
    /** */
    this.getPropertyValueAttributeName = props_getPropertyValueAttributeName;
    /** */
    this.setPropertyValueAttributeName = props_setPropertyValueAttributeName;
    /** */
    this.parametersAreEncoded = false;
    /** */
    this.getParametersAreEncoded = props_getParametersAreEncoded;
    /** */
    this.setParametersAreEncoded = props_setParametersAreEncoded;
	
    /** */
    this.params = new Hashtable();
    /** */
    this.dirtyParams = new Hashtable();
	
    /** */
    this.toString = props_toString;
    /** */
    this.toXML = props_toXML;
    /** */
    this.fromXML = props_fromXML;
	
    /** */
    this.parseNode = props_parseNode;
	
    /** */
    this.addValue = props_add;
    /** */
    this.setValue = props_set;
    /** */
    this.getValue = props_get;
    /** */
    this.removeValue = props_remove;
}

/** */
function props_toString() {
    return "Instance of Properties"
}
/** */
function props_getRootElementName() {
    return this.rootElementName;
}
/** */
function props_setRootElementName(rhs) {
    this.rootElementName = rhs;
}
/** */
function props_setRootElementAttribute(array) {
    this.rootElementAttributes = array;
}
/** */
function props_getPropertyElementName() {
    return this.propertyElementName;
}
/** */
function props_setPropertyElementName(rhs) {
    this.propertyElementName = rhs;
}
/** */
function props_getPropertyNameAttributeName() {
    return this.propertyNameAttributeName;
}
/** */
function props_setPropertyNameAttributeName(rhs) {
    this.propertyNameAttributeName = rhs;
}
/** */
function props_getPropertyValueAttributeName() {
    return this.propertyValueAttributeName;
}
/** */
function props_setPropertyValueAttributeName(rhs) {
    this.propertyValueAttributeName = rhs;
}
/** */
function props_getParametersAreEncoded() {
    return this.parametersAreEncoded;
}
/** */
function props_setParametersAreEncoded(value) {
    this.parametersAreEncoded = value;
}

/**
 *
 */
function props_parseNode(paramsNode) {
    //
    //
    var retValue = false;
    //
    // props
    var aNodeList = paramsNode.getElementsByTagName(this.propertyElementName);
    if(aNodeList!=null && aNodeList!=undefined) {
        //
        // set retValue to true if aNodeList contains > 0 parameters
        if(aNodeList.length>0) retValue = true;
        //
        //
        for(var i=0; i<aNodeList.length; i++) {
            var aNode = aNodeList[i];
            if(aNode!=null) {
                var aName = aNode.getAttribute( this.propertyNameAttributeName );
                if(aName!=null){
                	aName=aName.toString();
                }
                var aValue = aNode.getAttribute( this.propertyValueAttributeName );
                if(aValue!=null){
                	aValue=aValue.toString();
                }
                if(aValue!=null && this.getParametersAreEncoded()==true){
                    aValue = decode64(aValue);
                }
                if(aName!=null && aValue!=null){
                	this.addValue(aName, aValue);
                }
            }
        }
    }
    //
    //
    return retValue;
}

/**
 * @return XML doc as string for success (null for error)
 */
function props_toXML() {
    //
    //
    var retValue = null;
    //
    //
    retValue = "<" + this.rootElementName;
    if(this.rootElementAttributes && this.rootElementAttributes.length>0){
        for(var i=0; i<this.rootElementAttributes.length; i++){
            retValue += " "+this.rootElementAttributes[i].name+"=\""+this.rootElementAttributes[i].value+"\"";
        }
    }
    retValue += ">";
    //
    //
    var names = this.params.keys();
    var values = this.params.values();
    if(names!=null && values!=null && names.length>0 && names.length==values.length) {
        //
        //
        try {
            for (var i in names) {
                if (names[i] != null && values[i]!=null) {
                    retValue += "<" + this.propertyElementName + " " + this.propertyNameAttributeName + "=\"" + names[i] + "\" " + this.propertyValueAttributeName + "=\"" + (this.getParametersAreEncoded()==true ? tenduke.util.Base64.encode64(values[i]):values[i] ) + "\" />";
                }
            }
        }
        catch(serializeE) {
        }
    }
    //
    //
    retValue += "</" + this.rootElementName + ">";
    //
    //
    return retValue;
}

/**
 * @return XML doc as string for success (null for error)
 */
function props_fromXML(aXMLData) {
    //
    //
    var retValue = false;
    //
    //
    var xmlDoc = null;
    var aParser = new DOMParser();
    try {
        xmlDoc = aParser.parseFromString(aXMLData, "text/xml");
    }
    catch(xmlE) {
    }
    this.parseNode(xmlDoc);
    //
    //
    return retValue;
}

/**
 * @return XML doc as string for success (null for error)
 */
function props_toXMLByDirtyParams() {
    //
    //
    var retValue = null;
    //
    //
    var names = this.dirtyParams.keys();
    var values = this.dirtyParams.values();
    if(names!=null && values!=null && names.length>0 && names.length==values.length) {
        //
        //
        retValue = "<" + this.rootElementName + ">";
        //
        //
        try {
            for (var i in names) {
                if (names[i] != null && values[i]!=null) {
                    retValue += "<" + this.propertyElementName + " " + this.propertyNameAttributeName + "=\"" + names[i] + "\" " + this.propertyValueAttributeName + "=\"" + (this.getParametersAreEncoded()==true ? tenduke.util.Base64.encode64(values[i]):values[i] ) + "\" />";
                }
            }
        }
        catch(serializeE) {
        }
        //
        //
        retValue += "</" + this.rootElementName + ">";
    }
    //
    //
    return retValue;
}

/**
 * @return true for success
 */
function props_add(aName, aValue){
    //
    //
    if(this.params) {
        this.params.putEntry(aName, aValue);
        this.dirtyParams.putEntry(aName, "true");
        return true;
    }
    else
        return false;
}

/**
 * @return true for success
 */
function props_set(aName, aValue){
    //
    //
    return this.addValue(aName, aValue);
}

/**
 * @return param value for success (null for not found)
 */
function props_get(aName) {
    //
    //
    var retValue = null;
    //
    //
    if(this.params) {
        retValue = this.params.getEntry(aName);
    }
    //
    //
    return retValue;
}

/**
 * @return true for success
 */
function props_remove(aName) {
    //
    //
    if(this.params) {
        this.params.remove(aName);
        this.dirtyParams.remove(aName);
        return true;
    }
    else
        return false;
}/** 

Serialization model:
<CONTACT>
	<BASIC>...</BASIC>
    <EMAIL_ADDRESS>...</EMAIL_ADDRESS>
    <LINK>...</LINK>
    <POSTAL_ADDRESS>...</POSTAL_ADDRESS>
    <TELEPHONE_NUMBER>...</TELEPHONE_NUMBER>
</CONTACT>

*/

function ContactProperties() {	
	/** */
	this.basic = new Properties();
	/** */
	this.emails = new Hashtable();
	/** */
	this.websites = new Hashtable();
	/** */
	this.postalAddress = new Properties();
	/** */
	this.mobilePhone = new Properties();
	/** */
	this.landlinePhone = new Properties();
	/** */
	this.toXML = contacts_toXML;
}

/** */
function contacts_toXML() {
	//
	//
	var retValue = "<CONTACT>";
	//
	//
	if(this.basic) {
		this.basic.setRootElementName("BASIC");
		this.basic.setParametersAreEncoded(true);
		retValue += this.basic.toXML();
	}
	if(this.emails) {
		var htEntries = this.emails.values();
		if(htEntries) {
			for (var i in htEntries) {
				htEntries[i].setRootElementName("EMAIL_ADDRESS");
				htEntries[i].setParametersAreEncoded(true);
				if(htEntries[i]) retValue += htEntries[i].toXML();
			}
		}
	}
	if(this.websites) {
		var htEntries = this.websites.values();
		if(htEntries) {
			for (var i in htEntries) {
				htEntries[i].setRootElementName("LINK");
				htEntries[i].setParametersAreEncoded(true);
				if(htEntries[i]) retValue += htEntries[i].toXML();
			}
		}
	}
	if(this.postalAddress) {
		this.postalAddress.setRootElementName("POSTAL_ADDRESS");
		this.postalAddress.setParametersAreEncoded(true);
		retValue += this.postalAddress.toXML();
	}
	if(this.mobilePhone) {
		this.mobilePhone.setRootElementName("TELEPHONE_NUMBER");
		this.mobilePhone.setParametersAreEncoded(true);
		retValue += this.mobilePhone.toXML();
	}
	if(this.landlinePhone) {
		this.landlinePhone.setRootElementName("TELEPHONE_NUMBER");
		this.landlinePhone.setParametersAreEncoded(true);
		retValue += this.landlinePhone.toXML();
	}
	retValue += "</CONTACT>";
	//
	//
	return retValue;
}// JavaScript Document

/** */
var TEST_SESSION_COOKIE_NAME = "tsc";
/** */
var TEST_SESSION_COOKIE_VALUE = "enabled";
/** */
var TEST_PERSISTENT_COOKIE_NAME = "tpc";
/** */
var TEST_PERSISTENT_COOKIE_VALUE = "enabled";
/** */
var TEST_PERSISTENT_COOKIE_SCOPE = "minutes";
/** */
var ZONE_NAME = window.location.href.substring(0, window.location.href.indexOf("/", 10));
/** */
var alertDialogProvider = null;
/** */
var confirmDialogProvider = null;
/** */
var debugDialogProvider = null;
/** */
var allowDebugAlert = false;

/** */
function isIE(){
    if(_SARISSA_IS_IE){
        return true;	
    }
    else{
        return false;	
    }
}
function isOpera(){
    if(navigator.userAgent.toLowerCase().indexOf("opera") != -1){
        return true;	
    }
    else{
        return false;	
    }
}

/**
* JSON parser that validates the input String and does not eval if it's not  a valid JSON String.
*/
function parseJSON(text){
    if(isValidJSON(text)) {
        return eval('('+text+')');
    }
    else {
        alert("Invalid JSON: " + text);
    }
    return null;
	/*if (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(text)) {	
		return eval('('+text+')');	
	}
	else{
		//alert(text);
		return {};
	}
	*/
}

/** */
function leftTrim( value ) {
    var re = /\s*((\S+\s*)*)/;
    return value.replace(re, "$1");
}

/** */
function rightTrim( value ) {
    var re = /((\s*\S+)*)\s*/;
    return value.replace(re, "$1");
}
function getStyle(el,styleProp)
{
    var x = document.getElementById(el);
    var y = null;
    if (x.currentStyle) {
        y = x.currentStyle[styleProp];
    }
    else if (window.getComputedStyle) {
        y = document.defaultView.getComputedStyle(x,null).getPropertyValue(styleProp);
    }
    return y;
}
//
//
function showAlert(aMessage)
{
    if(alertDialogProvider){
       alertDialogProvider.showAlert(aMessage);
    }
    else {
        alert(aMessage);
    }
}
//
//
function showConfirm(aMessage)
{
    //
    //
    var retValue = null;
    if(confirmDialogProvider){
       retValue = confirmDialogProvider.showConfirm(aMessage);
    }
    else {
        retValue = confirm(aMessage);
    }
    //
    //
    return retValue;
}
//
//
function showDebug(aMessage)
{
    if(allowDebugAlert==true) {
        if(debugDialogProvider){
            debugDialogProvider.showAlert(aMessage);
        }
        else {
            alert(aMessage);
        }
    }
}
function hideElementById(el){
	var d=document.getElementById(el);
	if(d){
		hideElement(d);
	}
}
//
//
function hideElement(el)
{
    var retValue = null;
    if(el && el.style){
        retValue = el.style.cssText;
        el.style.cssText = "display:none; visibility:hidden;";
    }
    return retValue;
}
//
//
function showElementById(el, clientStyle){
	var d=document.getElementById(el);
	if(d){
		showElement(d, clientStyle);
	}
}
function showElement(el, clientStyle)
{
    if(el && el.style){
        if(!clientStyle) {
            el.style.cssText = "";
        }
        else {
            el.style.cssText = clientStyle;
        }
    }
}
//
//
function addClassNameToElement(element, className) {
    if(element) {
        var newClassNames = "";
        if(element && element.className && element.className.length > 0) {
            var classNamesToRemove = className.split(' ');
            var currentClasses = element.className.split(' ');
            if(currentClasses) {
              for(var i = 0; i < currentClasses.length; i++) {
                  var currentClassName = currentClasses[i];
                  if(currentClassName && currentClassName.length > 0 && currentClassName != " ") {
                      var currentClassNameShouldBeRemoved = false;
                      if(classNamesToRemove) {
                          for(var j = 0; j < classNamesToRemove.length; j++) {
                              if(classNamesToRemove[j] && classNamesToRemove[j] == currentClassName) {
                                  currentClassNameShouldBeRemoved = true;
                              }
                          }
                      }
                      if(currentClassNameShouldBeRemoved == false) {
                          if(newClassNames.length > 0) {
                              newClassNames = newClassNames.concat(" ");
                          }
                          newClassNames = newClassNames.concat(currentClassName);
                      }
                  }
              }
            }
        }
        if(newClassNames.length > 0) {
            newClassNames = newClassNames.concat(" ");
        }
        newClassNames = newClassNames.concat(className);
        element.className = newClassNames;
    }
}
//
//
function removeClassNameFromElement(element, className) {
    if(element && element.className && element.className.length > 0) {
        var newClassNames = "";
        var classNamesToRemove = className.split(' ');
        var currentClasses = element.className.split(' ');
        if(currentClasses) {
          for(var i = 0; i < currentClasses.length; i++) {
              var currentClassName = currentClasses[i];
              if(currentClassName && currentClassName.length > 0 && currentClassName != " ") {
                  var currentClassNameShouldBeRemoved = false;
                  if(classNamesToRemove) {
                      for(var j = 0; j < classNamesToRemove.length; j++) {
                          if(classNamesToRemove[j] && classNamesToRemove[j] == currentClassName) {
                              currentClassNameShouldBeRemoved = true;
                          }
                      }
                  }
                  if(currentClassNameShouldBeRemoved == false) {
                      if(newClassNames.length > 0) {
                          newClassNames = newClassNames.concat(" ");
                      }
                      newClassNames = newClassNames.concat(currentClassName);
                  }
              }
          }
        }
        element.className = newClassNames;
    }
}
//
//
function doesElementContainClassName(element, className) {
    var retVal = false;
    if(element && element.className && element.className.length > 0) {
        var currentClasses = element.className.split(' ');
        if(currentClasses) {
          for(var i = 0; i < currentClasses.length; i++) {
              var currentClassName = currentClasses[i];
              if(currentClassName) {
                  if(currentClassName == className) {
                      retVal = true;
                      break;
                  }
              }
          }
        }
    }
    return retVal;
}
//
//
function getChildById(node,childid){
    var retVal=null;
    /*var d=document.getElementById(childid);	
	if(d){
		var p=d.parentNode;
		while(p){
			if(p==node){
				
			}
		}
	}*/
    if(node && childid){
        var nodeChild=node.childNodes;
        if(nodeChild && nodeChild.length>0){
            var i=nodeChild.length;
            while(i>0){
                i--;
                if(nodeChild[i].nodeType==Node.ELEMENT_NODE){
                    if(nodeChild[i].id==childid){
                        retVal= nodeChild[i];
                        break;
                    }
                }
            }
            if(!retVal){
                i=nodeChild.length;
                while(i>0){
                    i--;
                    if(nodeChild[i].nodeType==Node.ELEMENT_NODE){
                        retVal=getChildById(nodeChild[i],childid);
                        if(retVal){
                            break;
                        }
                    }
                }
            }
            /*
			for(var i=0; i<nodeChild.length; i++){
				if(nodeChild[i].nodeType==Node.ELEMENT_NODE){
					if(nodeChild[i].getAttribute("id")==childid){
						retVal= nodeChild[i];
						break;
					}
				}
			}
			if(!retVal){
				for(var i=0; i<nodeChild.length; i++){
					if(nodeChild[i].nodeType==Node.ELEMENT_NODE){
						retVal=getChildById(nodeChild[i],childid);
						if(retVal){
							break;
						}
					}
				}
			}*/
        }
    }
    return retVal;
}
/** */
String.prototype.trim = function() { return leftTrim(rightTrim(this)); };

String.prototype.encodeXMLValue= function() {
    var retval=this;
    if(this.length>0) {
        retval=retval.replace(/&/g, "&amp;");
        retval=retval.replace(/</g, "&lt;");
        retval=retval.replace(/>/g, "&gt;");
        retval=retval.replace(/'/g, "&apos;");
        retval=retval.replace(/"/g, "&quot;");
    }
    return retval;
};
String.prototype.decodeXMLValue= function(){
    var retval=this;
    if(this.length>0) {
        retval=retval.replace(/&amp;/g, "&");
        retval=retval.replace(/&lt;/g, "<");
        retval=retval.replace(/&gt;/g, ">");
        retval=retval.replace(/&apos;/g, "'");
        retval=retval.replace(/&quot;/g, '"');
    }
    return retval;
};

String.prototype.format = function(valArray) {
    var retValue = this;
    var tokenCount = valArray.length;
    for(var i=0; i<tokenCount; i++ )
    {
        retValue = retValue.replace( new RegExp( "\\{" + i + "\\}", "gi" ), valArray[i] );
    }
    return retValue;
};

/** */
var arrayIndexOf = function(array,obj) { 
    for(var i=0; i<array.length; i++){
        if(array[i]==obj){
            return i;
        }
    }
    return -1;
};
function flagState(flags, flag) {
    //
    //
    return ( (flags & flag) == flag );
}
/** */
function trim( value ) {
    return leftTrim(rightTrim(value));	
}
/** */
function attachEventToDOMNode(node,eventname,eventHandler){
    if(node){
        if(node.addEventListener){
            node.addEventListener(eventname,eventHandler,false);
        }
        else if(node.attachEvent){
            node.attachEvent("on"+eventname,eventHandler);
        }
    }
}
function addEventToDOMNode( obj, type, fn ) {
    if ( obj.addEventListener ) {
        obj.addEventListener( type, fn, false );
        //alert("obj "+fn);
        //fn.apply(obj);
    }
    else if ( obj.attachEvent ) {
        var eProp = type + fn;
        obj["e"+eProp] = fn;
        obj[eProp] = function() { obj["e"+eProp]( window.event ); };
        obj.attachEvent( "on"+type, obj[eProp] );
    }
    else {
        obj['on'+type] = fn;
    }
}
function removeEventfromDOMNode( obj, type, fn ) {
    if ( obj.removeEventListener ) {
        obj.removeEventListener( type, fn, false );
    }
    else if ( obj.detachEvent ) {
        var eProp = type + fn;
        obj.detachEvent( "on"+type, obj[eProp] );
        obj['e'+eProp] = null;
        obj[eProp] = null;
    }
    else {
        obj['on'+type] = null;
    }
}

/**
 *
 */
function writeSessionCookie (cookieName, cookieValue) {
    if (testSessionCookie()) {
        document.cookie = escape(cookieName) + "=" + escape(cookieValue) + "; path=/";
        return true;
    }
    else 
        return false;
}

/**
 *
 */
function writePersistentCookie (CookieName, CookieValue, periodType, offset) {
    //
    //
    var expireDate = new Date ();
    offset = offset / 1;
    //
    //
    var myPeriodType = periodType;
    switch (myPeriodType.toLowerCase()) {
        case "years":
            expireDate.setYear(expireDate.getFullYear()+offset);
            break;
        case "months":
            expireDate.setMonth(expireDate.getMonth()+offset);
            break;
        case "days":
            expireDate.setDate(expireDate.getDate()+offset);
            break;
        case "hours":
            expireDate.setHours(expireDate.getHours()+offset);
            break;
        case "minutes":
            expireDate.setMinutes(expireDate.getMinutes()+offset);
            break;
        default:
            alert ("Invalid periodType parameter for writePersistentCookie()");
            break;
    } 

    document.cookie = escape(CookieName ) + "=" + escape(CookieValue) + "; expires=" + expireDate.toGMTString() + "; path=/";
}  

/**
 *
 */
function deleteCookie (cookieName) {
    //
    //
    if (getCookie(cookieName)) {
        writePersistentCookie (cookieName,"Pending delete","years", -1);  
    }
    return true;     
}

/**
 *
 */
function getCookie (cookieName) {
    var exp = new RegExp (escape(cookieName) + "=([^;]+)");
    if (exp.test (document.cookie + ";")) {
        exp.exec (document.cookie + ";");
        return unescape(RegExp.$1);
    }
    else return false;
}

/**
 *
 */
function testSessionCookie () {
    document.cookie = TEST_SESSION_COOKIE_NAME + "=" + TEST_SESSION_COOKIE_VALUE;
    if ( getCookie(TEST_SESSION_COOKIE_NAME)==TEST_SESSION_COOKIE_VALUE )
        return true 
    else{
        alert("Your brower doesn't support cookies.\n Some features of the "+SERVICE_BRAND_DISPLAY_NAME+" may not function correctly.\nWe recommend that you allow cookies for "+SERVICE_BRAND_DISPLAY_NAME);
        return false;
    }
}

/**
 *
 */
function testPersistentCookie () {
    writePersistentCookie (TEST_PERSISTENT_COOKIE_NAME, TEST_PERSISTENT_COOKIE_VALUE, TEST_PERSISTENT_COOKIE_SCOPE, 1);
    if (getCookie(TEST_PERSISTENT_COOKIE_NAME)==TEST_PERSISTENT_COOKIE_VALUE)
        return true  
    else 
        return false;
}
function xmlDecode(s){
    if(s){
        if(s.indexOf("&amp;")!=-1){
            s=s.split("&amp;").join("&");
        }
    }
    return s;
}
Date.prototype.getDayAsText=function(){	
    var d=new Array("sunday","monday","tuesday","wednesday","thursday","friday","saturday");
    return d[this.getDay()];
	
}
Date.prototype.getMonthAsText=function(){	
    var month=new Array(12)
    month[0]="January";
    month[1]="February";
    month[2]="March";
    month[3]="April";
    month[4]="May";
    month[5]="June";
    month[6]="July";
    month[7]="August";
    month[8]="September";
    month[9]="October";
    month[10]="November";
    month[11]="December";
    return month[this.getMonth()];
}

String.prototype.unescapeHTML=function() {
    if(this.indexOf("&")!=-1){
        var s=this;
        s=s.replace(/&amp;/g,"&");
        /*s=s.replace(/&quot;/g,"?");
		s=s.replace(/&lt;/g,"?");
		s=s.replace(/&gt;/g,"?");
		s=s.replace(/&euro;/g,"?");
		s=s.replace(/&nbsp;/g,"?");
		s=s.replace(/&Aacute;/g,"?");
		s=s.replace(/&aacute;/g,"?");
		s=s.replace(/&Acirc;/g,"?");
		s=s.replace(/&acirc;/g,"?");
		s=s.replace(/&acute;/g,"?");
		s=s.replace(/&AElig;/g,"?");
		s=s.replace(/&aelig;/g,"?");
		s=s.replace(/&Agrave;/g,"?");
		s=s.replace(/&agrave;/g,"?");
		s=s.replace(/&Aring;/g,"?");
		s=s.replace(/&aring;/g,"?");
		s=s.replace(/&Atilde;/g,"?");
		s=s.replace(/&atilde;/g,"?");
		s=s.replace(/&Auml;/g,"?");
		s=s.replace(/&auml;/g,"?");
		s=s.replace(/&brvbar;/g,"?");
		s=s.replace(/&Ccedil;/g,"?");
		s=s.replace(/&ccedil;/g,"?");
		s=s.replace(/&cedil;/g,"?");
		s=s.replace(/&cent;/g,"?");
		s=s.replace(/&circ;/g,"?");
		s=s.replace(/&copy;/g,"?");
		s=s.replace(/&curren;/g,"?");
		s=s.replace(/&deg;/g,"?");
		s=s.replace(/&divide;/g,"?");
		s=s.replace(/&Eacute;/g,"?");
		s=s.replace(/&eacute;/g,"?");
		s=s.replace(/&Ecirc;/g,"?");
		s=s.replace(/&ecirc;/g,"?");
		s=s.replace(/&Egrave;/g,"?");
		s=s.replace(/&egrave;/g,"?");
		s=s.replace(/&ETH;/g,"?");
		s=s.replace(/&eth;/g,"?");
		s=s.replace(/&Euml;/g,"?");
		s=s.replace(/&euml;/g,"?");
		s=s.replace(/&fnof;/g,"?");
		s=s.replace(/&frac12;/g,"?");
		s=s.replace(/&frac14;/g,"?");
		s=s.replace(/&frac34;/g,"?");
		s=s.replace(/&Iacute;/g,"?");
		s=s.replace(/&iacute;/g,"?");
		s=s.replace(/&Icirc;/g,"?");
		s=s.replace(/&icirc;/g,"?");
		s=s.replace(/&iexcl;/g,"?");
		s=s.replace(/&Igrave;/g,"?");
		s=s.replace(/&igrave;/g,"?");
		s=s.replace(/&iquest;/g,"?");
		s=s.replace(/&Iuml;/g,"?");
		s=s.replace(/&iuml;/g,"?");
		s=s.replace(/&laquo;/g,"?");
		s=s.replace(/&macr;/g,"?");
		s=s.replace(/&micro;/g,"?");
		s=s.replace(/&middot;/g,"?");
		s=s.replace(/&not;/g,"?");
		s=s.replace(/&Ntilde;/g,"?");
		s=s.replace(/&ntilde;/g,"?");
		s=s.replace(/&Oacute;/g,"?");
		s=s.replace(/&oacute;/g,"?");
		s=s.replace(/&Ocirc;/g,"?");
		s=s.replace(/&ocirc;/g,"?");
		s=s.replace(/&OElig;/g,"?");
		s=s.replace(/&oelig;/g,"?");
		s=s.replace(/&Ograve;/g,"?");
		s=s.replace(/&ograve;/g,"?");
		s=s.replace(/&ordf;/g,"?");
		s=s.replace(/&ordm;/g,"?");
		s=s.replace(/&Oslash;/g,"?");
		s=s.replace(/&oslash;/g,"?");
		s=s.replace(/&Otilde;/g,"?");
		s=s.replace(/&otilde;/g,"?");
		s=s.replace(/&Ouml;/g,"?");
		s=s.replace(/&ouml;/g,"?");
		s=s.replace(/&para;/g,"?");
		s=s.replace(/&plusmn;/g,"?");
		s=s.replace(/&pound;/g,"?");
		s=s.replace(/&raquo;/g,"?");
		s=s.replace(/&reg;/g,"?");
		s=s.replace(/&Scaron;/g,"?");
		s=s.replace(/&scaron;/g,"?");
		s=s.replace(/&sect;/g,"?");
		s=s.replace(/&shy;/g,"?");
		s=s.replace(/&sup1;/g,"?");
		s=s.replace(/&sup2;/g,"?");
		s=s.replace(/&sup3;/g,"?");
		s=s.replace(/&szlig;/g,"?");
		s=s.replace(/&THORN;/g,"?");
		s=s.replace(/&thorn;/g,"?");
		s=s.replace(/&tilde;/g,"?");
		s=s.replace(/&times;/g,"?");
		s=s.replace(/&Uacute;/g,"?");
		s=s.replace(/&uacute;/g,"?");
		s=s.replace(/&Ucirc;/g,"?");
		s=s.replace(/&ucirc;/g,"?");
		s=s.replace(/&Ugrave;/g,"?");
		s=s.replace(/&ugrave;/g,"?");
		s=s.replace(/&uml;/g,"?");
		s=s.replace(/&Uuml;/g,"?");
		s=s.replace(/&uuml;/g,"?");
		s=s.replace(/&Yacute;/g,"?");
		s=s.replace(/&yacute;/g,"?");
		s=s.replace(/&yen;/g,"?");
		s=s.replace(/&Yuml;/g,"?");
		s=s.replace(/&yuml;/g,"?");
		s=s.replace(/&ensp;/g,"?");
		s=s.replace(/&emsp;/g,"?");
		s=s.replace(/&thinsp;/g,"?");
		s=s.replace(/&zwnj;/g,"?");
		s=s.replace(/&zwj;/g,"?");
		s=s.replace(/&lrm;/g,"?");
		s=s.replace(/&rlm;/g,"?");
		s=s.replace(/&ndash;/g,"?");
		s=s.replace(/&mdash;/g,"?");
		s=s.replace(/&lsquo;/g,"?");
		s=s.replace(/&rsquo;/g,"?");
		s=s.replace(/&sbquo;/g,"?");
		s=s.replace(/&ldquo;/g,"?");
		s=s.replace(/&rdquo;/g,"?");
		s=s.replace(/&bdquo;/g,"?");
		s=s.replace(/&lsaquo;/g,"?");
		s=s.replace(/&rsaquo;/g,"?");
		s=s.replace(/&dagger;/g,"?");
		s=s.replace(/&Dagger;/g,"?");
		s=s.replace(/&permil;/g,"?");
		s=s.replace(/&bull;/g,"?");
		s=s.replace(/&hellip;/g,"?");
		s=s.replace(/&Prime;/g,"?");
		s=s.replace(/&prime;/g,"?");
		s=s.replace(/&oline;/g,"?");
		s=s.replace(/&frasl;/g,"?");
		s=s.replace(/&weierp;/g,"?");
		s=s.replace(/&image;/g,"?");
		s=s.replace(/&real;/g,"?");
		s=s.replace(/&trade;/g,"?");
		s=s.replace(/&alefsym;/g,"?");
		s=s.replace(/&larr;/g,"?");
		s=s.replace(/&uarr;/g,"?");
		s=s.replace(/&rarr;/g,"?");
		s=s.replace(/&darr;/g,"?");
		s=s.replace(/&harr;/g,"?");
		s=s.replace(/&crarr;/g,"?");
		s=s.replace(/&lArr;/g,"?");
		s=s.replace(/&uArr;/g,"?");
		s=s.replace(/&rArr;/g,"?");
		s=s.replace(/&dArr;/g,"?");
		s=s.replace(/&hArr;/g,"?");
		s=s.replace(/&forall;/g,"?");
		s=s.replace(/&part;/g,"?");
		s=s.replace(/&exist;/g,"?");
		s=s.replace(/&empty;/g,"?");
		s=s.replace(/&nabla;/g,"?");
		s=s.replace(/&isin;/g,"?");
		s=s.replace(/&notin;/g,"?");
		s=s.replace(/&ni;/g,"?");
		s=s.replace(/&prod;/g,"?");
		s=s.replace(/&sum;/g,"?");
		s=s.replace(/&minus;/g,"?");
		s=s.replace(/&lowast;/g,"?");
		s=s.replace(/&radic;/g,"?");
		s=s.replace(/&prop;/g,"?");
		s=s.replace(/&infin;/g,"?");
		s=s.replace(/&ang;/g,"?");
		s=s.replace(/&and;/g,"?");
		s=s.replace(/&or;/g,"?");
		s=s.replace(/&cap;/g,"?");
		s=s.replace(/&cup;/g,"?");
		s=s.replace(/&int;/g,"?");
		s=s.replace(/&there4;/g,"?");
		s=s.replace(/&sim;/g,"?");
		s=s.replace(/&cong;/g,"?");
		s=s.replace(/&asymp;/g,"?");
		s=s.replace(/&ne;/g,"?");
		s=s.replace(/&equiv;/g,"?");
		s=s.replace(/&le;/g,"?");
		s=s.replace(/&ge;/g,"?");
		s=s.replace(/&sub;/g,"?");
		s=s.replace(/&sup;/g,"?");
		s=s.replace(/&nsub;/g,"?");
		s=s.replace(/&sube;/g,"?");
		s=s.replace(/&supe;/g,"?");
		s=s.replace(/&oplus;/g,"?");
		s=s.replace(/&otimes;/g,"?");
		s=s.replace(/&perp;/g,"?");
		s=s.replace(/&hArr;/g,"?");
		s=s.replace(/&sdot;/g,"?");
		s=s.replace(/&lceil;/g,"?");
		s=s.replace(/&rceil;/g,"?");
		s=s.replace(/&lfloor;/g,"?");
		s=s.replace(/&rfloor;/g,"?");
		s=s.replace(/&lang;/g,"?");
		s=s.replace(/&rang;/g,"?");
		s=s.replace(/&loz;/g,"?");
		s=s.replace(/&spades;/g,"?");
		s=s.replace(/&clubs;/g,"?");
		s=s.replace(/&hearts;/g,"?");
		s=s.replace(/&diams;/g,"?");
		s=s.replace(/&Alpha;/g,"?");
		s=s.replace(/&alpha;/g,"?");
		s=s.replace(/&Beta;/g,"?");
		s=s.replace(/&beta;/g,"?");
		s=s.replace(/&Gamma;/g,"?");
		s=s.replace(/&gamma;/g,"?");
		s=s.replace(/&Delta;/g,"?");
		s=s.replace(/&delta;/g,"?");
		s=s.replace(/&Epsilon;/g,"?");
		s=s.replace(/&epsilon;/g,"?");
		s=s.replace(/&Zeta;/g,"?");
		s=s.replace(/&zeta;/g,"?");
		s=s.replace(/&Eta;/g,"?");
		s=s.replace(/&eta;/g,"?");
		s=s.replace(/&Theta;/g,"?");
		s=s.replace(/&theta;/g,"?");
		s=s.replace(/&thetasym;/g,"?");
		s=s.replace(/&Iota;/g,"?");
		s=s.replace(/&iota;/g,"?");
		s=s.replace(/&Kappa;/g,"?");
		s=s.replace(/&kappa;/g,"?");
		s=s.replace(/&Lambda;/g,"?");
		s=s.replace(/&lambda;/g,"?");
		s=s.replace(/&Mu;/g,"?");
		s=s.replace(/&mu;/g,"?");
		s=s.replace(/&Nu;/g,"?");
		s=s.replace(/&nu;/g,"?");
		s=s.replace(/&Xi;/g,"?");
		s=s.replace(/&xi;/g,"?");
		s=s.replace(/&Omicron;/g,"?");
		s=s.replace(/&omicron;/g,"?");
		s=s.replace(/&Pi;/g,"?");
		s=s.replace(/&pi;/g,"?");
		s=s.replace(/&piv;/g,"?");
		s=s.replace(/&Rho;/g,"?");
		s=s.replace(/&rho;/g,"?");
		s=s.replace(/&Sigma;/g,"?");
		s=s.replace(/&sigma;/g,"?");
		s=s.replace(/&sigmaf;/g,"?");
		s=s.replace(/&Tau;/g,"?");
		s=s.replace(/&tau;/g,"?");
		s=s.replace(/&Upsilon;/g,"?");
		s=s.replace(/&upsilon;/g,"?");
		s=s.replace(/&upsih;/g,"?");
		s=s.replace(/&Phi;/g,"?");
		s=s.replace(/&phi;/g,"?");
		s=s.replace(/&Chi;/g,"?");
		s=s.replace(/&chi;/g,"?");
		s=s.replace(/&Psi;/g,"?");
		s=s.replace(/&psi;/g,"?");
		s=s.replace(/&Omega;/g,"?");
		s=s.replace(/&omega;/g,"?");*/
        return s;
    }
    else{
        return this;	
    }
};
function copyPrototype(descendant, parent) { 
    var sConstructor = parent.toString(); 
    var aMatch = sConstructor.match( /\s*function (.*)\(/ ); 
    if ( aMatch != null ) {
        descendant.prototype[aMatch[1]] = parent;
    } 
    for (var m in parent.prototype) { 
        descendant.prototype[m] = parent.prototype[m]; 
    }
    //
}; 

/**
 * The following JSON validation code is based on YAHOO.lang.JSON (http://developer.yahoo.com/yui/docs/JSON.js.html)
 */

/**
 * Replace certain Unicode characters that JavaScript may handle incorrectly
 * during eval--either by deleting them or treating them as line
 * endings--with escape sequences.
 * IMPORTANT NOTE: This regex will be used to modify the input if a match is
 * found.
 */
var _JSON_UNICODE_EXCEPTIONS = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;


/**
 * First step in the validation.  Regex used to replace all escape
 * sequences (i.e. "\\", etc) with '@' characters (a non-JSON character).
 */
var _JSON_ESCAPES = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;

/**
 * Second step in the validation.  Regex used to replace all simple
 * values with ']' characters.
 */
var _JSON_VALUES  = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;

/**
 * Third step in the validation.  Regex used to remove all open square
 * brackets following a colon, comma, or at the beginning of the string.
 */
var _JSON_BRACKETS = /(?:^|:|,)(?:\s*\[)+/g;

/**
 * Final step in the validation.  Regex used to test the string left after
 * all previous replacements for invalid characters.
 */
var _JSON_INVALID  = /^[\],:{}\s]*$/;

/**
 * Character substitution map for common escapes and special characters.
 */
var _JSON_CHARS = {
    '\b': '\\b',
    '\t': '\\t',
    '\n': '\\n',
    '\f': '\\f',
    '\r': '\\r',
    '"' : '\\"',
    '\\': '\\\\'
};

/**
 * JSON validation, based on YAHOO.lang.JSON (http://developer.yahoo.com/yui/docs/JSON.js.html)
 */
function isValidJSON(jsonStr) {
    return _JSON_INVALID.test(_prepareJSON(jsonStr.
           replace(_JSON_ESCAPES,'@').
           replace(_JSON_VALUES,']').
           replace(_JSON_BRACKETS,'')));
}

/**
 * Escapes a special character to a safe Unicode representation
 * @param c {String} single character to escape
 * @return {String} safe Unicode escape
 */
function _prepareJSON_char(c) {
    if (!_JSON_CHARS[c]) {
        _JSON_CHARS[c] =  '\\u'+('0000'+(+(c.charCodeAt(0))).toString(16)).slice(-4);
    }
    return _JSON_CHARS[c];
}

/**
 * Replace certain Unicode characters that may be handled incorrectly by
 * some browser implementations.
 * @param s {String} parse input
 * @return {String} sanitized JSON string ready to be validated/parsed
 * @private
 */
function _prepareJSON(s) {
    return s.replace(_JSON_UNICODE_EXCEPTIONS, _prepareJSON_char);
}

/**
 * Regular expressions and other validation methods for validating emails, telephone numbers, names, ISO 8859-1 (Latin-1) characters, dates, and passwords.
 * 
 * EMAIL_REG_EX, Validates email addresses.
 * TEL_REG_EX, Validates telephone numbers.
 * NAME_REG_EX, Validates names, accepts multiple names in one filed.
 * STRING_REG_EX, Validates ISO 8859-1 (Latin-1) characters
 *
 */

var UUID_REG_EX = /^([A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}|\{[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}\})$/;

//(Add >0 chars, then optional (-._+&))>=0 times, then >0 chars, add required @, then (add >0 chars, add required .)>0, finally adds chars of length 2-6
var EMAIL_REG_EX=/^([0-9a-zA-Z]+[-._+&amp;])*[0-9a-zA-Z]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$/;

// Add optional +, then add (0-9, space, (, or)) >0 times, then add (0-9, space, (, ), or -) >=0 times, finally add (0-9 or space)
var TEL_REG_EX=/^\+?[0-9\s\(\)]+[0-9\s\(\)\-]*[0-9\s]$/;

// (Add char >0 times, add optional (',.- and a char), add optional space, add char >=0 times) all this >= times
var NAME_REG_EX=/^[a-zA-Z]+(([\'\,\.\-\_][a-zA-Z])?\s?[a-zA-Z]*)*$/;

// Test for ISO 8859-1 (Latin-1)
var STRING_REG_EX=/^[\x00-\x7e\xa0-\xff]*$/;

// Test that the password is in ISO 8859-1 (Latin-1) and >=6 chars in length
var PASSWORD_REG_EX=/^[\x21-\x7e\x80-\xfe]{6,}$/;

/**
 * @param input, Input string to be validated
 * @param type, Validation method
 */
function validate(input, type) {
    var expr = type;
    if (!input || !expr) {
        return false;
    }
    if (expr.test(input)) {
        return true;
    } else {
        return false;
    }
}
function filter(input) {
    return input;
}
function convertToEntity(input) {
    return input;
}

/**
 * Validates an email address syntax.
 * @param anUuid An Uuid to validate. 
 * @return true if anUuid is valid by syntax.
 */
function validateUuid(anUuid) {
    //
    //
    var retValue = false;
    //
    //
    if(anUuid) {
        retValue=validate(anUuid, UUID_REG_EX);
    }
    //
    //
    return retValue;
}

/**
 * Validates an email address syntax.
 * @param anEmail An email address to validate. 
 * @return true if email address is valid by syntax.
 */
function validateEmail(anEmail) {
    //
    //
    var retValue = false;
    //
    //
    if(anEmail) {
        anEmail=anEmail.replace(/\x00-\x32/, "");
        retValue=validate(anEmail, EMAIL_REG_EX);
    }
    //
    //
    return retValue;
}
/** 
 * Validates a date of birth value against iso8601: yyyy-mm-dd
 * @return null for valid date format (string message for errors)
 */
function validateDateOfBirth(aDob) {
	//
	//
	var retValue = null;
	//
	//
    var errMsg = "";
    var objectForResourceAccess = new Object();
    if(typeof(SERVICE_NAMES_GENERAL_REGISTRATION_BUNDLE_ID) !== 'undefined') {
        objectForResourceAccess.className = SERVICE_NAMES_GENERAL_REGISTRATION_BUNDLE_ID;
    }
    //
    //
    errMsg = getResourceString(objectForResourceAccess, "signupDataValidateDateOfBirthMissingErrorMessage");
    if(!errMsg) {
        errMsg = "- The date of birth must be given\n";
    }
    //
    //
	if(!aDob || aDob.length!=10) {
        return errMsg;
    }
    var dobDataArray = null;
	if(aDob) {
		dobDataArray = aDob.split("-"); 
		if(!dobDataArray) {
            return errMsg;
        }
		if(dobDataArray && dobDataArray.length!=3) {
            return errMsg;
        }
	}
	if(aDob) {
		//
		// split str into array by date delim
		dobDataArray = aDob.split("-"); 
		var yyyy=dobDataArray[0];
		var mm=dobDataArray[1];
		var dd=dobDataArray[2];
		if(mm.indexOf("0")==0) mm = mm.substring(1);
		if(dd.indexOf("0")==0) dd = dd.substring(1);
		//
		// parse dob data
		var yyyyInt = parseInt(yyyy);
		var mmInt = parseInt(mm);
		var ddInt = parseInt(dd);
		//
		// check that data is numbers
		if(isNaN(yyyyInt)) {
            errMsg = getResourceString(objectForResourceAccess, "signupDataValidateDateOfBirthYearIsNanErrorMessage");
            if(!errMsg) {
                errMsg = "- The date of birth year must be a number\n";
            }
            return errMsg;
        }
		if(isNaN(mmInt)) {
            errMsg = getResourceString(objectForResourceAccess, "signupDataValidateDateOfBirthMonthIsNanErrorMessage");
            if(!errMsg) {
                errMsg = "- The date of birth month must be a number\n";
            }
            return errMsg;
        }
		if(isNaN(ddInt)) {
            errMsg = getResourceString(objectForResourceAccess, "signupDataValidateDateOfBirthDayIsNanErrorMessage");
            if(!errMsg) {
                errMsg = "- The date of birth day must be a number\n";
            }
            return errMsg;
        }
		//
		// check basic ranges of data
		if(yyyyInt<1900 || yyyyInt>2008) {
            errMsg = getResourceString(objectForResourceAccess, "signupDataValidateDateOfBirthYearRangeErrorMessage");
            if(!errMsg) {
                errMsg = "- The date of birth year must be a number greater than 1900 and smaller than 2009\n";
            }
            return errMsg;
        }
		if(mmInt<1 || mmInt>12) {
            errMsg = getResourceString(objectForResourceAccess, "signupDataValidateDateOfBirthMonthRangeErrorMessage");
            if(!errMsg) {
                errMsg = "- The date of birth month must be a number ranging from 1 to 12\n";
            }
            return errMsg;
        }
		if(ddInt<1 || ddInt>31) {
            errMsg = getResourceString(objectForResourceAccess, "signupDataValidateDateOfBirthDayRangeErrorMessage");
            if(!errMsg) {
                errMsg = "- The date of birth day must be a number number ranging from 1 to 31\n";
            }
            return errMsg;
        }
		//
		// check for month / day missmatch
		if(mmInt==1 || mmInt==3 || mmInt==5 || mmInt==7 || mmInt==8 || mmInt==10 || mmInt==12) {
            if(ddInt>31 || ddInt<1) {
                errMsg = getResourceString(objectForResourceAccess, "signupDataValidateDateOfBirthDayRangeErrorMessage");
                if(!errMsg) {
                    errMsg = "- The date of birth day must be a number number ranging from 1 to 31\n";
                }
                return errMsg;
            }
		}
		else if(mmInt==2) {
            if(ddInt>29 || ddInt<1) {
                errMsg = getResourceString(objectForResourceAccess, "signupDataValidateDateOfBirthDayRangeFebruaryErrorMessage");
                if(!errMsg) {
                    errMsg = "- The date of birth day must be a number number ranging from 1 to 29\n";
                }
                return errMsg;
            }
		}
		else if(mmInt==4 || mmInt==6 || mmInt==9 || mmInt==11) {
            if(ddInt>30 || ddInt<1) {
                errMsg = getResourceString(objectForResourceAccess, "signupDataValidateDateOfBirthDayRange30ErrorMessage");
                if(!errMsg) {
                    errMsg = "- The date of birth day must be a number number ranging from 1 to 30\n";
                }
                return errMsg;
            }
		}
	}
	//
	//
	return retValue;
}

/**
 * var FOUL_REG_EX=/(co+c+k)|(fu+c+k)/i;
 * var ENTITY_REG_EX=/^[&"<>]$/;
 *//**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info/
*
**/

var Base64 = {

    // private property
    _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

    // public method for encoding
    encode64 : function (input) {
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var i = 0;

        input = Base64._utf8_encode(input);

        while (i < input.length) {

            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);

            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;

            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }

            output = output +
            this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
            this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

        }

        return output;
    },

    // public method for decoding
    decode64 : function (input) {
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;

        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

        while (i < input.length) {

            enc1 = this._keyStr.indexOf(input.charAt(i++));
            enc2 = this._keyStr.indexOf(input.charAt(i++));
            enc3 = this._keyStr.indexOf(input.charAt(i++));
            enc4 = this._keyStr.indexOf(input.charAt(i++));

            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;

            output = output + String.fromCharCode(chr1);

            if (enc3 != 64) {
                output = output + String.fromCharCode(chr2);
            }
            if (enc4 != 64) {
                output = output + String.fromCharCode(chr3);
            }

        }

        output = Base64._utf8_decode(output);

        return output;

    },

    // private method for UTF-8 encoding
    _utf8_encode : function (string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";

        for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }

        }

        return utftext;
    },

    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;

        while ( i < utftext.length ) {

            c = utftext.charCodeAt(i);

            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }

        }

        return string;
    }

}

/**
 *
 */
function encode64(inp)
{
    if(inp == null || inp == undefined)
        return null;
    if(inp == "")
        return "";
    return Base64.encode64(inp);
}

/**
 *
 */
function decode64(inp)
{
    if(inp == null || inp == undefined)
        return null;
    if(inp == "")
        return "";
    return Base64.decode64(inp);
}
// JavaScript Document

/** object type id string for images */
var OBJECT_TYPE_IMAGE_FILE = "OBJECT_TYPE_IMAGE_FILE";
/** object type id string for videos */
var OBJECT_TYPE_VIDEO_FILE = "OBJECT_TYPE_VIDEO_FILE";
/** object type id string for audio */
var OBJECT_TYPE_AUDIO_FILE = "OBJECT_TYPE_AUDIO_FILE";
/** object type id string for documents */
var OBJECT_TYPE_DOCUMENT_FILE = "OBJECT_TYPE_DOCUMENT_FILE";


/** object type id string for unkown formats */
var OBJECT_TYPE_UNKOWN = "OBJECT_TYPE_UNKOWN";

/** */
var MIME_TYPES = new Array(
"aac","audio/aac",
"3gp","video/3gpp",
"3gpp","video/3gpp",
"ai","application/postscript",
"aif","audio/x-aiff",
"aifc","audio/x-aiff",
"aiff","audio/x-aiff",
"asc","text/plain",
"asf","video/x.ms.asf",
"asx","video/x.ms.asx",
"au","audio/basic",
"avi","video/x-msvideo",
"bcpio","application/x-bcpio",
"bin","application/octet-stream",
"cab","application/x-cabinet",
"cdf","application/x-netcdf",
"class","application/java-vm",
"cpio","application/x-cpio",
"cpt","application/mac-compactpro",
"crt","application/x-x509-ca-cert",
"csh","application/x-csh",
"css","text/css",
"csv","text/comma-separated-values",
"dcr","application/x-director",
"dir","application/x-director",
"dll","application/x-msdownload",
"dms","application/octet-stream",
"doc","application/msword",
"docm","application/vnd.ms-word.document.macroEnabled.12",
"docx","application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"dotm","application/vnd.ms-word.template.macroEnabled.12",
"dotx","application/vnd.openxmlformats-officedocument.wordprocessingml.template",
"dtd","application/xml-dtd",
"dvi","application/x-dvi",
"dxr","application/x-director",
"eps","application/postscript",
"etx","text/x-setext",
"exe","application/octet-stream",
"flv","video/x-flv",
"ez","application/andrew-inset",
"gif","image/gif",
"gtar","application/x-gtar",
"gz","application/gzip",
"gzip","application/gzip",
"hdf","application/x-hdf",
"hqx","application/mac-binhex40",
"html","text/html",
"htm","text/html",
"ice","x-conference/x-cooltalk",
"ico","image/x-icon",
"ief","image/ief",
"iges","model/iges",
"igs","model/iges",
"jar","application/java-archive",
"java","text/plain",
"jfif","image/jpeg",
"jfif-tbnl","image/jpeg",
"jnlp","application/x-java-jnlp-file",
"jpeg","image/jpeg",
"jpe","image/jpeg",
"jpg","image/jpeg",
"js","application/x-javascript",
"jsp","text/plain",
"kar","audio/midi",
"latex","application/x-latex",
"lha","application/octet-stream",
"lzh","application/octet-stream",
"m4v","video/x-m4v",
"man","application/x-troff-man",
"mathml","application/mathml+xml",
"me","application/x-troff-me",
"mesh","model/mesh",
"mid","audio/midi",
"midi","audio/midi",
"mif","application/vnd.mif",
"mol","chemical/x-mdl-molfile",
"movie","video/x-sgi-movie",
"mov","video/quicktime",
"mp2","audio/mpeg",
"mp3","audio/mpeg",
"mpeg","video/mpeg",
"mpe","video/mpeg",
"mpga","audio/mpeg",
"mpg","video/mpeg",
"ms","application/x-troff-ms",
"msh","model/mesh",
"msi","application/octet-stream",
"nc","application/x-netcdf",
"oda","application/oda",
"odb","application/vnd.oasis.opendocument.database",
"odc","application/vnd.oasis.opendocument.chart",
"odf","application/vnd.oasis.opendocument.formula",
"odg","application/vnd.oasis.opendocument.graphics",
"odi","application/vnd.oasis.opendocument.image", 
"odm","application/vnd.oasis.opendocument.text-master",
"odp","application/vnd.oasis.opendocument.presentation",
"ods","application/vnd.oasis.opendocument.spreadsheet",
"odt","application/vnd.oasis.opendocument.text", 
"otg","application/vnd.oasis.opendocument.graphics-template",
"oth","application/vnd.oasis.opendocument.text-web",
"otp","application/vnd.oasis.opendocument.presentation-template",
"ots","application/vnd.oasis.opendocument.spreadsheet-template",
"ott","application/vnd.oasis.opendocument.text-template",
"ogg","application/ogg",
"pbm","image/x-portable-bitmap",
"pdb","chemical/x-pdb",
"pdf","application/pdf",
"pgm","image/x-portable-graymap",
"pgn","application/x-chess-pgn",
"png","image/png",
"pnm","image/x-portable-anymap",
"potm","application/vnd.ms-powerpoint.template.macroEnabled.12",
"potx","application/vnd.openxmlformats-officedocument.presentationml.template",
"ppam","application/vnd.ms-powerpoint.addin.macroEnabled.12",
"ppm","image/x-portable-pixmap",
"ppsm","application/vnd.ms-powerpoint.slideshow.macroEnabled.12",
"ppsx","application/vnd.openxmlformats-officedocument.presentationml.slideshow",
"ppt","application/vnd.ms-powerpoint",
"pptm","application/vnd.ms-powerpoint.presentation.macroEnabled.12",
"pptx","application/vnd.openxmlformats-officedocument.presentationml.presentation",
"ps","application/postscript",
"qt","video/quicktime",
"ra","audio/x-pn-realaudio",
"ra","audio/x-realaudio",
"ram","audio/x-pn-realaudio",
"ras","image/x-cmu-raster",
"rdf","application/rdf+xml",
"rgb","image/x-rgb",
"rm","audio/x-pn-realaudio",
"roff","application/x-troff",
"rpm","application/x-rpm",
"rpm","audio/x-pn-realaudio",
"rtf","application/rtf",
"rtx","text/richtext",
"ser","application/java-serialized-object",
"sgml","text/sgml",
"sgm","text/sgml",
"sh","application/x-sh",
"shar","application/x-shar",
"silo","model/mesh",
"sit","application/x-stuffit",
"skd","application/x-koan",
"skm","application/x-koan",
"skp","application/x-koan",
"skt","application/x-koan",
"smi","application/smil",
"smil","application/smil",
"snd","audio/basic",
"spl","application/x-futuresplash",
"src","application/x-wais-source",
"sv4cpio","application/x-sv4cpio",
"sv4crc","application/x-sv4crc",
"svg","image/svg+xml",
"swf","application/x-shockwave-flash",
"t","application/x-troff",
"tar","application/x-tar",
"tar.gz","application/x-gtar",
"tcl","application/x-tcl",
"tex","application/x-tex",
"texi","application/x-texinfo",
"texinfo","application/x-texinfo",
"tgz","application/x-gtar",
"tiff","image/tiff",
"tif","image/tiff",
"tr","application/x-troff",
"tsv","text/tab-separated-values",
"txt","text/plain",
"ustar","application/x-ustar",
"vcd","application/x-cdlink",
"vrml","model/vrml",
"vxml","application/voicexml+xml",
"wav","audio/x-wav",
"wbmp","image/vnd.wap.wbmp",
"wmlc","application/vnd.wap.wmlc",
"wmlsc","application/vnd.wap.wmlscriptc",
"wmls","text/vnd.wap.wmlscript",
"wml","text/vnd.wap.wml",
"wrl","model/vrml",
"wtls-ca-certificate","application/vnd.wap.wtls-ca-certificate",
"xbm","image/x-xbitmap",
"xht","application/xhtml+xml",
"xhtml","application/xhtml+xml",
"xlam","application/vnd.ms-excel.addin.macroEnabled.12",
"xlsb","application/vnd.ms-excel.sheet.binary.macroEnabled.12",
"xlsm","application/vnd.ms-excel.sheet.macroEnabled.12",
"xlsx","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"xltm","application/vnd.ms-excel.template.macroEnabled.12",
"xltx","application/vnd.openxmlformats-officedocument.spreadsheetml.template",
"xls","application/vnd.ms-excel",
"xml","application/xml",
"xpm","image/x-xpixmap",
"xpm","image/x-xpixmap",
"xsl","application/xml",
"xslt","application/xslt+xml",
"xul","application/vnd.mozilla.xul+xml",
"xwd","image/x-xwindowdump",
"xyz","chemical/x-xyz",
"z","application/compress",
"zip","application/zip");





/**
 * Resolve the mime type for a file name.
 * @param aName a string that contains a file type name.
 * @return mime type string for input.
 */
function resolveMimeType(aName) {
	//
	//
	var retValue = null;
	//
	//
	if(aName==null) {
		return "application/octet-stream";
	}
	//
	//
	var lName = aName.toLowerCase();
	lName = lName.substring(lName.lastIndexOf(".")+1);
	//
	//
	if(lName.lastIndexOf("jpg")>0 || lName.lastIndexOf("jpeg")>0 || lName.lastIndexOf("jfif")>0 || lName.lastIndexOf("jfif-tbnl")>0 || lName.lastIndexOf("jpe")>0) {
		retValue =  "image/jpeg";
	}
	else if(lName.lastIndexOf("gif")>0) {
		retValue =  "image/gif";
	}
	else if(lName.lastIndexOf("png")>0 || lName.lastIndexOf("x-png")>0) {
		retValue =  "image/png";
	}
	else if(lName.lastIndexOf("bmp")>0 || lName.lastIndexOf("bm")>0) {
		retValue =  "image/bmp";
	}
	else if(lName.lastIndexOf("tiff")>0 || lName.lastIndexOf("tif")>0) {
		retValue =  "image/tiff";
	}	
	else if(lName.lastIndexOf("3gp")>0 || lName.lastIndexOf("3gpp")>0) {
		retValue =  "video/3gpp";
	}
	else if(lName.lastIndexOf("mpeg")>0 || lName.lastIndexOf("mpg")>0 || lName.lastIndexOf("mpeg2")>0 || lName.lastIndexOf("mpe")>0 || lName.lastIndexOf("mpa")>0 || lName.lastIndexOf("mpv2")>0) {
		retValue =  "video/mpeg";
	}
	else if(lName.lastIndexOf("mp4")>0 || lName.lastIndexOf("mpeg4")>0) {
		retValue =  "video/mp4";
	}
	else if(lName.lastIndexOf("asf")>0 || lName.lastIndexOf("asr")>0 || lName.lastIndexOf("asx")>0) {
		retValue =  "video/x-ms-asf";
	}
	else if(lName.lastIndexOf("wmv")>0 || lName.lastIndexOf("avi")>0) {
		retValue =  "video/x-msvideo";
	}
	else if(lName.lastIndexOf("flv")>0) {
		retValue =  "video/x-flv";
	}
	else if(lName.lastIndexOf("swf")>0) {
		retValue =  "application/x-shockwave-flash";
	}
	else if(lName.lastIndexOf("m4v")>0) {
		retValue =  "video/x-m4v";
	}
	else if(lName.lastIndexOf("mov")>0 || lName.lastIndexOf("qt")>0 ) {
		retValue =  "video/quicktime";
	}
	//
	//
	if(retValue==null) {
		var  ffIndex = arrayIndexOf(MIME_TYPES, lName);
		if(ffIndex>=0 && ffIndex%2==0) {
			retValue = MIME_TYPES[ffIndex+1];
		}
		if(retValue==null) retValue = "application/octet-stream";
	}	
	//
	//
	return retValue;
}

/**
 * Resolve the mime type for a file name.
 * @param aName a string that contains a file type name.
 * @return mime type string for input.
 */
function resolveFileFormatNameByMimeType(aMimeType) {
	//
	//
	var retValue = null;
	if(!aMimeType || aMimeType.length<1) return "";
	//
	//
	var lName = aMimeType.toLowerCase();
	//
	//
	var mtIndex = arrayIndexOf(MIME_TYPES, lName);
	if(mtIndex>=0 && mtIndex%2!=0) {
		retValue = MIME_TYPES[mtIndex-1];
	}
	if(retValue==null) retValue = "";
	//
	//
	return retValue;
}

/**
 * Resolve the object type for a file name.
 * @param aName a string that contains a file type name.
 * @return object type string ID for input (OBJECT_TYPE_IMAGE_FILE | OBJECT_TYPE_VIDEO_FILE | OBJECT_TYPE_UNKOWN | OBJECT_TYPE_DOCUMENT_FILE).
 */
function resolveObjectType(aName) {
	//
	//
	var retValue = OBJECT_TYPE_UNKOWN;
	var lName = aName.toLowerCase();	
	//
	//
	if(lName.lastIndexOf(".jpg")>0 || lName.lastIndexOf(".jpeg")>0 || lName.lastIndexOf(".jfif")>0 ||
	   lName.lastIndexOf(".jfif-tbnl")>0 || lName.lastIndexOf(".jpe")>0 || lName.lastIndexOf(".gif")>0 ||
	   lName.lastIndexOf(".png")>0 || lName.lastIndexOf(".x-png")>0 || lName.lastIndexOf(".bmp")>0 || 
	   lName.lastIndexOf(".bm")>0 || lName.lastIndexOf(".tiff")>0 || lName.lastIndexOf(".tif")>0) {
		retValue = OBJECT_TYPE_IMAGE_FILE;
	}
	else if(lName.lastIndexOf(".mpeg")>0 || lName.lastIndexOf(".mpg")>0 || lName.lastIndexOf(".mpeg2")>0 ||
			lName.lastIndexOf(".wmv")>0 || lName.lastIndexOf(".avi")>0 || lName.lastIndexOf(".mpeg4")>0 ||
			lName.lastIndexOf(".mp4")>0 ||	lName.lastIndexOf(".flv")>0 || lName.lastIndexOf(".swf")>0 || 
			lName.lastIndexOf(".asf")>0 || lName.lastIndexOf(".m4v")>0 || lName.lastIndexOf(".mov")>0 ||
			lName.lastIndexOf(".qt")>0 || lName.lastIndexOf(".mpa")>0 || lName.lastIndexOf(".mpe")>0 ||
			lName.lastIndexOf(".3gp")>0 || lName.lastIndexOf(".3gpp")>0 || lName.lastIndexOf(".mpv2")>0) {
		retValue = OBJECT_TYPE_VIDEO_FILE;
	}
	else if(lName.lastIndexOf(".aac")>0 || lName.lastIndexOf(".aif")>0 || lName.lastIndexOf(".aifc")>0 ||
			lName.lastIndexOf(".aiff")>0 || lName.lastIndexOf(".au")>0 || lName.lastIndexOf(".kar")>0 ||
			lName.lastIndexOf(".mid")>0 || lName.lastIndexOf(".midi")>0 || lName.lastIndexOf(".mp2")>0 ||
			lName.lastIndexOf(".mp3")>0 || lName.lastIndexOf(".mpga")>0 || lName.lastIndexOf(".ra")>0 ||
			lName.lastIndexOf(".ram")>0 || lName.lastIndexOf(".rm")>0 || lName.lastIndexOf(".rpm")>0 ||
			lName.lastIndexOf(".snd")>0 || lName.lastIndexOf(".wav")>0){
		retValue = OBJECT_TYPE_AUDIO_FILE;
	}
	else if(lName.lastIndexOf(".pdf")>0 || lName.lastIndexOf(".doc")>0 || lName.lastIndexOf(".docx")>0 ||
			lName.lastIndexOf(".docm")>0 || lName.lastIndexOf(".dotx")>0 || lName.lastIndexOf(".dotm")>0 ||
			lName.lastIndexOf(".xls")>0 || lName.lastIndexOf(".xlsx")>0 || lName.lastIndexOf(".xlam")>0 || 
			lName.lastIndexOf(".xlsb")>0 || lName.lastIndexOf(".xlsm")>0 || lName.lastIndexOf(".xltm")>0 || 
			lName.lastIndexOf(".xltx")>0 || lName.lastIndexOf(".ppt")>0 || lName.lastIndexOf(".pptx")>0 ||
			lName.lastIndexOf(".pptm")>0 || lName.lastIndexOf(".ppsx")>0 || lName.lastIndexOf(".ppsm")>0 || 
			lName.lastIndexOf(".ppam")>0 || lName.lastIndexOf(".potx")>0 || lName.lastIndexOf(".potm")>0 || 
			lName.lastIndexOf(".txt" )>0 || lName.lastIndexOf(".odt")>0 || lName.lastIndexOf(".ott")>0  || 
			lName.lastIndexOf(".oth")>0 || lName.lastIndexOf(".odm")>0 || lName.lastIndexOf(".odg")>0 || 
			lName.lastIndexOf(".otg")>0 || lName.lastIndexOf(".odp")>0 || lName.lastIndexOf(".otp")>0 || 
			lName.lastIndexOf(".ods")>0 || lName.lastIndexOf(".ots")>0 || lName.lastIndexOf(".odc")>0 || 
			lName.lastIndexOf(".odf")>0 || lName.lastIndexOf(".odb")>0 || lName.lastIndexOf(".odi")>0 ){
		retValue = OBJECT_TYPE_DOCUMENT_FILE;
	}
	//
	//
	return retValue;	
}//
//
var htmlFileCache=null;
//
//
var debugLevel=1;
var trackingProvider = null;
var loggingProvider = null;
/** 
 *
 */
function dsInit(){
    //
    //
    htmlFileCache = new Hashtable();
}
/**
 * @param uri The resource to request
 * @param method The method to use in the request (get or post)
 */
function initRequest(uri, method) {
    //
    //
    var useMethod = method;
    var aGenericReq = new XMLHttpRequest();
    zoneName = ZONE_NAME;
    if(useMethod==undefined) useMethod = "GET";
    var fullUri;
    if(uri.indexOf("http")==0){
        fullUri=uri;
    }
    else if(uri.indexOf("/")==0 || ZONE_NAME.lastIndexOf("/")==ZONE_NAME.length-1){
    	fullUri=zoneName + uri;    	
    }
    else{
        fullUri=zoneName +"/"+ uri;
    }
    aGenericReq.open(useMethod, fullUri, false);
    return aGenericReq;
}

/**
 * @param uri The resource to request
 * @param method The method to use in the request (get or post)
 */
function initAsyncRequest(uri, method) {
    //
    //
    var useMethod = method;
    var aGenericAsyncReq = new XMLHttpRequest();
    zoneName = ZONE_NAME;
    if(useMethod==undefined) useMethod = "GET";
    var fullUri;
    if(uri.indexOf("http")==0){
        fullUri=uri;
    }
    else if(uri.indexOf("/")==0 || ZONE_NAME.lastIndexOf("/")==ZONE_NAME.length-1){
    	fullUri=zoneName + uri;    	
    }
    else{
        fullUri=zoneName +"/"+ uri;
    }
    aGenericAsyncReq.open(useMethod, fullUri, true);
    return aGenericAsyncReq;
}
function callUrl(uri, method, isAsync){
	
    var retValue=null;
    //
    //
    var aGenericCmdReq;
    if(!isAsync){
        aGenericCmdReq = initRequest(uri, method);	
    }
    else{
        aGenericCmdReq = initAsyncRequest(uri, method);
    }
    aGenericCmdReq.setRequestHeader("Content-Type", "text/html; charset=\"UTF-8\"");
    aGenericCmdReq.setRequestHeader("CacheControl", "no-cache");
    //
    //
    try {
        aGenericCmdReq.send("");
        retValue = aGenericCmdReq;
    }
    catch(cmdSendE) {
        retValue = null;
    }
	
    return retValue;
}

/**
 * Send a synchronous XML command request.
 * @param xmlCommand A XML command set (structure and composition specified by the "kentish" server app context).
 * @param onReadyStateCB a callback for handling request - response progress and status.
 *                       Signature: fnc(aGenericCmdReq:XMLHttpRequest), where aGenericCmdReq may be null to indicate exception.
 * @return the request instance or null for errors.
 */
function commandRequest(xmlCommand, onReadyStateCB) {
    //
    //
    var retValue = null;
    //
    //
    var aGenericCmdReq = initRequest("/servlets/XMLCommandServlet", "POST");
    aGenericCmdReq.setRequestHeader("Content-Type", "text/xml; charset=\"UTF-8\"");
    if(xmlCommand) {
      aGenericCmdReq.setRequestHeader("Content-Length", xmlCommand.length);
    }
    //
    //
    try {
        aGenericCmdReq.send(xmlCommand);
        retValue = aGenericCmdReq;
    }
    catch(cmdSendE) {
        retValue = null;
    }
    //
    //
    if(onReadyStateCB) {
        onReadyStateCB(aGenericCmdReq);
    }
    //
    //
    return retValue;
}

/**
 * Send a asynchronous XML command request.
 * @param xmlCommand A XML command set (structure and composition specified by the "kentish" server app context).
 * @param onReadyStateCB a callback for handling request - response progress and status.
 *                       Signature: fnc(aGenericCmdReq:XMLHttpRequest, eventObject), where aGenericCmdReq may be null to indicate exception.
 * @param eventListenerInstance instance in whos scope the callback is executed
 * @return the request instance or null for errors.
 */
function asyncCommandRequest(xmlCommand, onReadyStateCB, eventListenerInstance) {
    //
    //
    var retValue = null;
    //
    //
    var aGenericCmdReq = initAsyncRequest("/servlets/XMLCommandServlet", "POST");
    aGenericCmdReq.setRequestHeader("Content-Type", "text/xml; charset=\"UTF-8\"");
    if(xmlCommand) {
      aGenericCmdReq.setRequestHeader("Content-Length", xmlCommand.length);
    }
    //
    //    
    aGenericCmdReq.onreadystatechange = function (aRespEvt) {
        if (aGenericCmdReq.readyState == 4) {
            if(onReadyStateCB) {
                onReadyStateCB.call(eventListenerInstance, aGenericCmdReq, aRespEvt);
            }            
        }
    };

    //
    //
    try {
        aGenericCmdReq.send(xmlCommand);
        retValue = aGenericCmdReq;
    }
    catch(cmdSendE) {
        retValue = null;
    }    
    //
    //
    return retValue;
}

/**
 * Send a synchronous XML command request. Assumes the xmlCommand data contains one
 * single command.
 * @param xmlCommand A XML command set (structure and composition specified by the "kentish" server app context). 
 * @return true if command execution was successful.
 */
function singleCommandRequest(xmlCommand) {
    //
    //
    var retValue = false;
    //
    //
    var aGenericCmdReq = initRequest("/servlets/XMLCommandServlet", "POST");
    aGenericCmdReq.setRequestHeader("Content-Type", "text/xml; charset=\"UTF-8\"");
    //
    //
    try {
        aGenericCmdReq.send(xmlCommand);
        retValue = aGenericCmdReq;
    }
    catch(cmdSendE) {
    }
    //
    //
    var numOKs = getNumCommandOKs(aGenericCmdReq);
    if(numOKs==1) {
        retValue = true;
    }
    //
    //
    return retValue;
}

/**
 * Send a synchronous XML command request. Assumes the xmlCommand data contains one single command.
 * @param xmlCommand A XML command (structure and composition specified by the "kentish" server app context). 
 * @return Command result as a string, or an error message.
 */
function sendCommandReturnResultAsString(xmlCommand) {
    //
    //
    var commandResult = null;
    var commandRequest = initRequest("/servlets/XMLCommandServlet", "POST");
    commandRequest.setRequestHeader("Content-Type", "text/xml; charset=\"UTF-8\"");
    try {
        //
        //
        commandRequest.send(xmlCommand);
        //
        //
        if (commandRequest.readyState == 4) {
            //
            //
            if (commandRequest.status != 200) {
                commandResult = "Error: Server returned status code " + commandRequest.status;
            }
            else if (commandRequest.responseXML == null) {
                commandResult = "Error: Server returned no xml response";
            }
            else {
                var resultXml  = commandRequest.responseXML;
                var serializer = new XMLSerializer();
                commandResult = serializer.serializeToString(resultXml);
            }
        }
        else {
            //
            //
            commandResult = "Error: Command execution ready state " + commandRequest.readyState;
        }
    }
    catch(sendE) {
        commandRequest = null;
        commandResult = "Error: " + sendE.description;
    }
    //
    //
    return commandResult;
}

/**
 * Send a synchronous XML command request with multiple commands. Assumes the xmlCommand data contains numCommands.
 * @param xmlCommand A XML command set (structure and composition specified by the "kentish" server app context). 
 * @param numCommands The number of commands in the xmlCommand XML
 * @return true if command execution was successfull.
 */
function multipleCommandRequest(xmlCommand, numCommands) {
    //
    //
    var retValue = false;
    //
    //
    var aGenericCmdReq = initRequest("/servlets/XMLCommandServlet", "POST");
    aGenericCmdReq.setRequestHeader("Content-Type", "text/xml; charset=\"UTF-8\"");
    //
    //
    try {
        aGenericCmdReq.send(xmlCommand);
        retValue = aGenericCmdReq;
    }
    catch(cmdSendE) {
    }
    //
    //
    var numOKs = getNumCommandOKs(aGenericCmdReq);
    if(numOKs==numCommands) {
        retValue = true;
    }
    else {
        //
        //
        var response  = aGenericCmdReq.responseXML.documentElement;
        var cmdElements = (response ? response.getElementsByTagName('COMMAND'):null);
        var cmdElement = null;
        if(cmdElements && cmdElements.length>0) {
            //
            //
            retValue = new Array();
            //
            //
            for(var cmdIndex=0; cmdIndex<cmdElements.length; cmdIndex++) {
                //
                //
                var aResultObject = new Object();
                retValue.push(aResultObject);
                //
                //
                cmdElement = cmdElements[cmdIndex];
                var cmdMessageElements = (cmdElement ? cmdElement.getElementsByTagName('MESSAGE'):null);
                var cmdMessageElement = null;
                if(cmdMessageElements && cmdMessageElements.length>0) {
                    cmdMessageElement = cmdMessageElements[0];
                }
                var result = ( (cmdElement && cmdElement.getAttribute('RESULT')) ? cmdElement.getAttribute('RESULT').toString():"FAILED");
                var errCode = parseInt( ( (cmdElement && cmdElement.getAttribute('CODE')) ? cmdElement.getAttribute('CODE').toString():"-1") );
                aResultObject.result = result;
                aResultObject.errorCode = errCode;
                if(cmdMessageElement && cmdMessageElement.firstChild) {
                    aResultObject.message = cmdMessageElement.firstChild.data;
                }
            }
        }
    }
    //
    //
    return retValue;
}

/**
 * @param uri Recourse id to load file from.
 * @param forceCacheDisable
 * @return XMLHttpRequest instance or null for errors.
 */
function loadFile(uri, forceCacheDisable) {
    //
    //
    var retValue=null;
    //
    //
    var addon="";
    if(forceCacheDisable) {
        if(uri.indexOf("?")==-1) {
            addon += "?";
        }
        else {
            addon += "&";
        }
        addon += "foo=" + new Date().getTime();
    }
    retValue=callUrl(uri + addon, "GET", false);
    //
    //
    return retValue;
}

/**
 * @return XML DOM model
 */
function loadFileCreateDOM(uri,forceCacheDisable) {
    //
    //
    var retValue = null;	
    //
    //
    var resultXML = loadFile(uri,forceCacheDisable);
    if(resultXML && resultXML.responseXML && resultXML.responseXML.documentElement) {
        retValue = resultXML.responseXML.documentElement;
    }
    else if(resultXML && resultXML.responseText) {
        var aParser = new DOMParser();
        try { retValue = aParser.parseFromString(resultXML.responseText, "text/xml"); } catch(xmlE) {}
    }
    //
    //
    return retValue;
}

/**
 * @param emailArray Array of recipient email addresses
 * @param aSubject Subject for email message
 * @param aMessage Body text for email message
 * @param aContentType Content type for email message (mime type)
 * @param skipEmailValidation true or false
 * @param sender Sender email address
 * @param forceSender Boolean value, if set true, forces using sender parameter as email sender
 */
function sendEmail(emailArray, aSubject, aMessage, aContentType, skipEmailValidation, sender, forceSender) {
    //
    //
    var retValue=false;
    //
    //
    if(!aContentType){
        aContentType="text/plain";
    }
    var decodedCmdSet = "";
    decodedCmdSet = "<COMMANDS>";
    decodedCmdSet += "<COMMAND CLASS_NAME=\"com.tenduke.services.messaging.SendEmail\" CONTENT_TYPE=\"" + aContentType + "\"  IS_ASYNCHRONOUS=\"true\"";
    if(sender) {
        decodedCmdSet += " SENDER=\"" + encode64(sender) + "\"";
    }
    if(forceSender == true) {
        decodedCmdSet += " ALWAYS_USE_SENDER_ADDRESS=\"true\"";
    }
    decodedCmdSet += " >";
    //
    // the email command contains the email spec that defines the message
    var emailSpec = "<EMAIL_SPECIFICATION>";
    emailSpec += "<RECIPIENTS>";
    for(i=0; i<emailArray.length; i++) {
        if(skipEmailValidation){
            emailSpec += "<RECIPIENT>" + encode64(emailArray[i]) + "</RECIPIENT>";
        }
        else{
            if(validateEmail(emailArray[i])) {
                emailSpec += "<RECIPIENT>" + encode64(emailArray[i]) + "</RECIPIENT>";
            }
        }
    }
    emailSpec += "</RECIPIENTS>";
    emailSpec += "<SUBJECT>" + encode64(aSubject) + "</SUBJECT>";
    emailSpec += "<BODY>" + encode64(aMessage) + "</BODY>";
    emailSpec += "</EMAIL_SPECIFICATION>";
    //
    // the email spec must be base64 encoded
    decodedCmdSet += encode64(emailSpec);
    decodedCmdSet += "</COMMAND>";
    decodedCmdSet += "</COMMANDS>";
    //
    // send async request
    var emailReq = initRequest("/servlets/XMLCommandServlet", "POST");
    emailReq.setRequestHeader("Content-Type", "text/xml; charset=\"UTF-8\"");
    try {
        emailReq.send(decodedCmdSet);
        retValue = true;
    }
    catch(cmdSendE) {
        emailReq = null;
    }
    //
    //
    return retValue;
}

/**
 * Install (set) a logging provider to use for logging application events.
 * @param aLogger Instance of an object that declares and defines a method
 *        with signature: addEntry(LogEntry:logEntry)
 */
function installLogger(aLogger) {
    loggingProvider = aLogger;
}

/**
 * Add a log entry to be logged.
 * @param logEntry
 */
function addLogEntry(logEntry) {
    //
    //
    if(loggingProvider && debugLevel>0) {
        loggingProvider.addLogEntry(logEntry);
    }
}
//
//
LogEntry.Audience = {
    Human:0,
    Machine:1
};
LogEntry.Priority = {
    Critical:1,
    Critical_AlertSystemAdministrator:1,
    Highlevel:2,
    Highlevel_TopLevelApplicationEvents:2,
    ApplicationInternal:3,
    Verbose:4,
    VeryVerbose:5
};
LogEntry.EventType = {
    Error:0,
    Warning:1,
    Info:2
};
LogEntry.prototype.audience = null;
LogEntry.prototype.priority = null;
LogEntry.prototype.eventType = null;
LogEntry.prototype.message = null;
function LogEntry(anAudience, aPriority, anEventType, aMessage) {
    this.audience = anAudience;
    this.priority = aPriority;
    this.eventType = anEventType;
    this.message = aMessage;
}
//
//
LogEntry.prototype.toString = function(){
    //
    //
    return this.message;
}
//
//
function AlertDialogLoggingProvider() {
}
AlertDialogLoggingProvider.prototype.addLogEntry = function(logEntry){
    //
    //
    try {
        if(logEntry.priority<=debugLevel) {
            showAlert(logEntry);
        }
    }
    catch(gatException) {
    }
}
//
//
MemCacheLoggingProvider.prototype.logCache = new Array();
MemCacheLoggingProvider.prototype.maxCacheSize = 100;
function MemCacheLoggingProvider(maxSize) {
    if(maxSize) {
        this.maxCacheSize = maxSize;
    }
}
MemCacheLoggingProvider.prototype.addLogEntry = function(logEntry){
    //
    //
    if(logEntry.priority<=debugLevel) {
        if(this.logCache.length>=this.maxCacheSize) {
            this.logCache.splice(this.logCache.length/2);
        }
        this.logCache.push(logEntry);
    }
}

/**
 * Install (set) a tracking provider to use for tracking consumption and user
 * interaction with the application and assets.
 * @param aTrackingProvider Instance of an object that declares and defines a method
 *        with signature: trackUsage(string:assetName)
 */
function installTrackingProvider(aTrackingProvider) {
    trackingProvider = aTrackingProvider;
}

/**
 * Track usage of a named asset.
 * @param pageOrAssetName
 */
function trackUsage(pageOrAssetName) {
    //
    //
    if(trackingProvider) {
        setTimeout('internalTrackUsage("' + pageOrAssetName + '")', 1);
    }
}

/** private */
function internalTrackUsage(pageOrAssetName) {
    //
    //
    if(trackingProvider) {
        try {
            trackingProvider.trackUsage(pageOrAssetName);
        }
        catch(trackingException) {
        }
    }
}
//
//
GoogleAnalyticsTrackingProvider.prototype.googleAnalyticsProvider = null;
function GoogleAnalyticsTrackingProvider(aGoogleAnalyticsProvider) {
    this.googleAnalyticsProvider = aGoogleAnalyticsProvider;
}
GoogleAnalyticsTrackingProvider.prototype.trackUsage = function(pageOrAssetName){
    //
    // google analytics
    try {
        if(this.googleAnalyticsProvider) {
            this.googleAnalyticsProvider._trackPageview(pageOrAssetName);
            addLogEntry(new LogEntry(LogEntry.Audience.Human, LogEntry.Priority.VeryVerbose, LogEntry.EventType.Info, "Google Analytics tracking usage: " + pageOrAssetName));
        }
    }
    catch(gatException) {
        addLogEntry(new LogEntry(LogEntry.Audience.Human, LogEntry.Priority.Highlevel, LogEntry.EventType.Error, "Google Analytics tracking exception: " + gatException));
    }
}

/** */
function getNumCommandOKs(aCommandResponse) {
    var retValue = -1;
    if (aCommandResponse && aCommandResponse.readyState == 4 && aCommandResponse.status == 200 && aCommandResponse.responseXML!=null) {
        var response=aCommandResponse.responseXML.documentElement;
        if(response) {
            var numOKs = 0; 
            var cmdElements = response.getElementsByTagName('COMMAND');
            if(cmdElements && cmdElements.length>0) {
                var cmdElement = null;
                for(var i=0; i<cmdElements.length; i++) {
                    cmdElement = cmdElements[i];
                    if(cmdElement && cmdElement.getAttribute('RESULT')) {
                        var result = cmdElement.getAttribute('RESULT').toString(); if(result=="OK") numOKs++;
                    }
                }
            }
            if(cmdElements && cmdElements.length>0) retValue = numOKs;
        }
    }
    return retValue;
}

/** */
function getNumNamedCommandResults(aCommandDOM, aResultValue) {
    var retValue = -1;
    if(aCommandDOM) {
        var numOKs = 0; 
        var cmdElements = aCommandDOM.getElementsByTagName('COMMAND');
        if(cmdElements && cmdElements.length>0) {
            var cmdElement = null;
            for(var i=0; i<cmdElements.length; i++) {
                cmdElement = cmdElements[i];
                if(cmdElement && cmdElement.getAttribute('RESULT')) {
                    var result = cmdElement.getAttribute('RESULT').toString(); 
                    if(result==aResultValue) numOKs++;
                }
            }
        }
        if(cmdElements && cmdElements.length>0) retValue = numOKs;
    }
    return retValue;
}

/** */
function findFirstNodeByName(startNode, aName) {
    var retValue = null;
    if(startNode && aName && startNode.nodeName==aName) retValue = startNode;
    else if(startNode && startNode.childNodes) {
        for(var i=0; i<startNode.childNodes.length; i++) {
            retValue = findFirstNodeByName(startNode.childNodes[i], aName);
            if(retValue) break;
        }
    }
    return retValue;
}
// JavaScript Document
function Delegate(){
	this.listeners=new Array();
	this.addListener=Delegate_addListener;
	this.removeListener=Delegate_removeListener;
	this.fireEvent=Delegate_fireEvent;
	this.findListener=Delegate_findListener;
}
function Delegate_addListener(object,functio){
	var index=this.findListener(object,functio);
	if(index<0){
		this.listeners.push(new Array(object,functio));
	}
}
function Delegate_removeListener(object,functio){
	var index=this.findListener(object,functio);
	if(index>=0 && index<this.listeners.length){
		this.listeners.splice(index,1);
	}
}
function Delegate_findListener(object,functio){
	var index=-1;
	for(var i=0; i<this.listeners.length; i++){
		if(this.listeners[i][0]==object){
			if(this.listeners[i][1]==functio){
				index=i;
				break;
			}
		}
	}
	return index;
}
function Delegate_fireEvent(object,eventData,bubble){
	if(bubble==true && object.bubbleEvent){
		object.bubbleEvent.call(object,object,eventData);
	}
	if(this.listeners.length>0){
		for(var i=0; i<this.listeners.length; i++){
			if(this.listeners[i] && this.listeners[i][1]){
				if(this.listeners[i][0]){
					this.listeners[i][1].apply(this.listeners[i][0],new Array(object,eventData));	
				}
				else{
					this.listeners[i][1](object,eventData);
				}
			}
		}
	}
}
// JavaScript Document
function openHTMLFileInto(url,id,isAppend,uniqueIdPrefix){
	document.body.style.cursor="wait";
	var htmlText=htmlFileCache.getEntry(url);
	if(!htmlText){
		var regHTML=loadFile(url);
		if(regHTML){
			var respText=regHTML.responseText;
			if(respText){
				var respSplit=respText.split('<!--content_html_split_point-->');
				if(respSplit && respSplit[1]){
					htmlText=respSplit[1];
					htmlFileCache.putEntry(url,htmlText);
				}
			}
			else{
				//alert("no text");	
			}
		}
		else{
			//alert("no File");	
		}
	}
	
	var target=document.getElementById(id);
	if(target){
		if(htmlText){
			var tempElem=document.createElement("div");
			if(uniqueIdPrefix){
				tempElem.innerHTML=htmlText.replace(/REPLACE_WITH_ID_PREFIX/g,uniqueIdPrefix);//htmlText.split("REPLACE_WITH_ID_PREFIX").join(uniqueIdPrefix);
			}
			else{
				tempElem.innerHTML=	htmlText;	
			}
			var xmlDoc = tempElem;
			if(xmlDoc){
				var cont=xmlDoc.getElementsByTagName("div");
				if(cont){
					var initMethod;
					var content=false;
					for(var i=0; i<cont.length; i++){
						if(!content && cont[i].id.indexOf(".content")!=-1){
							var div=document.createElement("div");
							div.id=cont[i].id;
							div.innerHTML=cont[i].innerHTML
							if(isAppend){
								target.appendChild(div);//innerHTML+='<div id="'+cont[i].id+'">'+cont[i].innerHTML+'</div>';
							}
							else{
								target.innerHTML="";//'<div id="'+cont[i].id+'">'+cont[i].innerHTML+'</div>';
								target.appendChild(div);
							}
							content=true;
						}
						else if(cont[i].id=="initMethod"){
							initMethod=""+cont[i].innerHTML;
						}
					}
					if(initMethod){
						eval(initMethod);
					}
				}
				else{
					//alert("xmlDoc: "+xmlDoc);
				}
			}
			else{
				//alert("no xml");	
			}
		}
		else{
			//alert("no html text");	
		}
	}
	else{
		//alert("no target");	
	}
	document.body.style.cursor="auto";
}
// JavaScript Document
var oldHash="";
var refreshCurrentContentArgs;
var IEhistoryWriter;
var IEhistorySrc;

function initDeepLinking() {
    if(isIE()==true) {
        IEhistoryWriter=document.createElement("iframe");
        IEhistoryWriter.name="historyWriter";
        IEhistoryWriter.id="historyWriter";
        IEhistoryWriter.width="1";
        IEhistoryWriter.height="1";
        IEhistoryWriter.frameBorder="0";
        IEhistoryWriter.src=SERVICE_WWW_ROOT+"empty.html";
        addEventToDOMNode(IEhistoryWriter,"load",iFrameLoaded);
        document.body.appendChild(IEhistoryWriter);
    }
    //alert(""+(oldHash!=window.location.hash+window.location.search));
    setInterval(checkHash, 500);
}
function checkHash() {
    //alert("checkHash");
    //alert("window.location.hash = " + window.location.hash);
    //alert("window.location.search = " + window.location.search);
    var windowLocationHash = new String(window.location.hash);
    var windowLocationSearch = new String(window.location.search);
    var indexOfOpenInSearchString = windowLocationSearch.indexOf("?open");
    if(indexOfOpenInSearchString > -1) {
        if(indexOfOpenInSearchString == 0) {
            var indexOfNextQuestionMark = windowLocationSearch.indexOf("?", 1);
            if(indexOfNextQuestionMark > 0) {
                windowLocationHash = windowLocationSearch.substr(0, indexOfNextQuestionMark);
                windowLocationSearch = windowLocationSearch.substr(indexOfNextQuestionMark);
            }
            else {
                windowLocationHash = windowLocationSearch;
                windowLocationSearch = "";
            }
        }
        else {
            var indexOfPreviousQuestionMark = windowLocationSearch.indexOf("?");
            if(indexOfPreviousQuestionMark < indexOfOpenInSearchString) {
                windowLocationHash = windowLocationSearch.substr(indexOfOpenInSearchString);
                windowLocationSearch = windowLocationSearch.substr(0, indexOfOpenInSearchString);
            }
            else {
                windowLocationHash = windowLocationSearch;
                windowLocationSearch = "";
            }
        }
        windowLocationHash = windowLocationHash.split("?open").join("#open");
    }
    var currentHash = windowLocationHash + windowLocationSearch;
    //
    //    
    if(windowLocationSearch && windowLocationSearch.length==1 && windowLocationSearch.indexOf("?")==0) {
        //currentHash = windowLocationHash
    }
    //
    //    
    if(currentHash && currentHash.indexOf("?") == currentHash.length-1) {   
        //currentHash = currentHash.substring(0, currentHash.length-2);
    }
    //
    //
    if(currentHash.indexOf("?!") > -1) {
        var currentHashSplit = currentHash.split("?!");
        if(currentHashSplit.length == 2) {
            currentHashSplit[1] = encode64(currentHashSplit[1]);
            currentHash = currentHashSplit.join("?");
        }
    }
    //
    //
    if(oldHash != currentHash) {
        //
        //alert("oldHash: " + oldHash + " hash: "+windowLocationHash+" search "+windowLocationSearch);
        oldHash = currentHash;
        var isProfile=false;
        var args;
        if(oldHash.indexOf("?")!=-1) {
            //alert("?");
            args=oldHash.split("?");
        }else{
            //alert("no ?");
            args=oldHash.split("-");
        }
        //alert(args[0]+" " +args[1]);
        if(oldHash.indexOf("open")!=1) {
            isProfile=true;
        }
        else{
        	var tempS=args[0].substring(1);
        	var re = new RegExp("^(\\d|\\w)*$");
			if(tempS.match(re)){
				if(args && eval("typeof("+tempS+")")=="function") {	
	                isProfile=false;
	            }
	            else{
	                isProfile=true;
	            }
			}
			else {
				//alert('tempS: ['+tempS+']');
				alert('The page you tried to access does not exist');
				return;
			}
        }
        if(isProfile==true) {//oldHash.indexOf("-")==-1 && oldHash.indexOf("open")!=1) {
            refreshCurrentContentArgs=new Array((""+oldHash.substring(1)).toLowerCase());	
            openProfile(refreshCurrentContentArgs);
        }
        else{
            if(args && args.length>0) {
                if(!args[1]) {
                    args[1]="AA==";
                }
                if(args[1].length%4!=0) {
                    if(args[1].length%4==2) {
                        args[1]=args[1]+"==";
                    }
                    else if(args[1].length%4==3) {
                        args[1]=args[1]+"=";
                    }
                    else{
                        alert("Invalid address! \n If you have copied or typed the address please check that you have'nt missed any characters.");
                    }
                }
                var argsDecoded=decode64(""+args[1]);
                if(argsDecoded.indexOf("&")!=-1) {
                    refreshCurrentContentArgs=argsDecoded.split("&");
                }
                else{
                    if(argsDecoded && argsDecoded.length>0) {
                        refreshCurrentContentArgs=new Array(""+argsDecoded);
                    }
                    else{
                        refreshCurrentContentArgs=null;
                    }
                }
                if(refreshCurrentContentArgs) {
                    //		alert("with args");
                    eval(""+args[0].substring(1)).apply(this,refreshCurrentContentArgs);
                }
                else{
                    //	alert("no args");
                    eval(""+args[0].substring(1)).call(this);
                }
                //alert("sbstr "+args[0].substring(1)+" arg: "+refreshCurrentContentArgs);
            }
            /*else if(oldHash && oldHash.length<1) {
				refreshCurrentContentArgs=null;
				eval(""+oldHash.substring(1))(refreshCurrentContentArgs);
			}*/
        }
    }
    else if(oldHash=="" && windowLocationHash=="") {
        openSiteIndex();
    }
}
function refreshCurrentContent() {
	
}
function setRefreshCurrentContent(func, arg) {
    var args = "";
    if(arg) {
        refreshCurrentContentArgs = arg;
        args = arg.join("&");
    }
    else{
        refreshCurrentContentArgs = null;
    }
    var funcToString = func.toString();
    //
    //
    var funcName = funcToString.substring(funcToString.indexOf("function")+9,funcToString.indexOf("("));
    var h="#"+funcName;
    var p = "?" + encode64(args);
    //alert(oldHash + "!=" + h+p);
    if(refreshCurrentContent!=func){
    	refreshCurrentContent=func;
    }
    var hashAndParamString = h + p;
    if(oldHash != hashAndParamString) {
        oldHash=hashAndParamString;
        //window.location.hash=h
        //window.location.search=p;
        if(window.location.href.indexOf("?open") > -1) {
            window.location.href=hashAndParamString.split("#open").join("?open");
        }
        else {
            window.location.href=hashAndParamString;
        }
        //refreshCurrentContent=func;
        writeIEHistory();
    }
}
function writeIEHistory() {
    if(isIE()==true) {
        if(IEhistorySrc) {
            if(oldHash.indexOf("?")!=-1) {
                var split=oldHash.split("?");
                var h=split[0];
                var p=split[1];
                var s="h="+h+"&p="+p;
                if(IEhistorySrc.indexOf(s)==-1) {
                    //alert(IEhistoryWriter.src+" = "+SERVICE_WWW_ROOT+"empty.html?r="+Math.random()+"&"+s);
                    IEhistoryWriter.src=SERVICE_WWW_ROOT+"empty.html?r="+Math.random()+"&"+s;
                }
            }
            else{
                if(IEhistorySrc.indexOf("h="+oldHash)==-1) {
                    IEhistoryWriter.src=SERVICE_WWW_ROOT+"empty.html?r="+Math.random()+"&h="+oldHash;
                }
            }
        }
        else{
            if(oldHash.indexOf("?")!=-1) {
                var split=oldHash.split("?");
                var h=split[0];
                var p=split[1];
                var s="h="+h+"&p="+p;
                //alert("no src "+ IEhistoryWriter.src+" = "+SERVICE_WWW_ROOT+"empty.html?r="+Math.random()+"&"+s);
                IEhistoryWriter.src=SERVICE_WWW_ROOT+"empty.html?r="+Math.random()+"&"+s;
            }
            else{
                IEhistoryWriter.src=SERVICE_WWW_ROOT+"empty.html?r="+Math.random()+"&h="+oldHash;
            }
        }
    }
}
function iFrameLoaded(iFrameSrc) {
    if(isIE()==true) {
		
        var targ;
        if (!iFrameSrc) var iFrameSrc = window.event;
        if (iFrameSrc.target) targ = iFrameSrc.target;
        else if (iFrameSrc.srcElement) targ = iFrameSrc.srcElement;
		
        var oDoc = targ.contentWindow || targ.contentDocument;
    	if (oDoc.document) {
            oDoc = oDoc.document;
    	}
        var index=null;
        var index2=null;
        IEhistorySrc=oDoc.location.href;
        if(IEhistorySrc && IEhistorySrc.length>0) {
            index=IEhistorySrc.indexOf("h=");
            index2=IEhistorySrc.indexOf("&p=");
        }
        //alert("iframe loaded "+IEhistorySrc+" " +index+" "+index2);
        var s=null;
        var h=null;
        var p=null;
        if(index && index!=-1 && index<IEhistorySrc.length) {
            if(index2 && index2!=-1 && index2<IEhistorySrc.length) {
                h=IEhistorySrc.substr(index+2,index2-(index+2));
                p="?"+IEhistorySrc.substr(index2+3);
                s=h+p;
            }
            else{
                s=IEhistorySrc.substr(index+1);
            }
        }
		
        if(s && s.length>1 && s!=IEhistorySrc) {
		
            if(s!=oldHash && (h!=window.location.hash || p!=window.location.search)) {
                //alert("nav: "+h+" "+p);
                //window.location.hash=h;
                //window.location.search=p;
                window.location.href=h+p;
                //alert("res: "+window.location.href);
            }
        }
    }
}//
// login operations
/*
* This file requires old style asset DElegate.js to function
*/
/** Indicates that the login request was successfull */
var LOGIN_OPERATION_LOGIN = "LOGIN";
var LOGIN_OPERATION_LOGOUT = "LOGOUT";
//
// login result values
/** Indicates that the login request was successfull */
var LOGIN_SUCCESS = 0;
/** Indicates that the login request failed */
var LOGIN_FAILED = 1;
/** Indicates that the clients login state is "logged in" */
var ALREADY_LOGGED_IN = 2;

/** Indicates that the logout request was successfull */
var LOGOUT_SUCCESS = 3;
/** Indicates that the logout request failed */
var LOGOUT_FAILED = 4;

var AUTHENTICATION_FAILED = 5;

/**  */
var LOGIN_STATE_COOKIE_NAME = "LOGIN_STATE";
/**  */
var SESSION_SHORT_NAME_COOKIE = "shortName";
/** */
var SESSION_DISPLAY_NAME_COOKIE = "displayName";
/**  */
var LOGIN_PRINCIPAL_FIELD_NAME = "shortName";
/**  */
var ACCOUNT_VALIDATED_COOKIE_NAME = "accountValidated";
/**  */
var hasDetailedLoginInformation=false;
var emailValidated=false;
var emailValidationRequired=false;
var caseSensitivePrincipalName=false;
/** */
var loginStateChanged = new Delegate();
var loginFailedMessage;
/** */
var loginStateCheckTime=null;
/**
 * Create an authenticated session (login).
 * @param principalName (user name)
 * @param password Password for the account
 * @param loginResultHandler function call back for handling login request results.
 *        loginResultHandler signature: fnc(aResultCode:int), where aResultCode can be LOGIN_SUCCESS | LOGIN_FAILED | ALREADY_LOGGED_IN.
 */
function login(principalName, password, loginResultHandler) {
    //
    //
    var loginState = isLoggedIn();
    //
    //
    if(loginState==false) {
        //
        //
        var atIndex = principalName.indexOf("@");
        var useEmailOpt = "";
        if(atIndex!=-1 && validateEmail(principalName)==true) {
            useEmailOpt = "&USE_EMAIL=true";
        }
        //
        //
        var isANum = false;
        var phoneNumAsAlias = ( (principalName && principalName.indexOf("+")==0) ? principalName.substring(1):principalName );
        try {
            var phoneNum = new Number(phoneNumAsAlias);
            isANum = isFinite(phoneNum);
        }
        catch(numException) {
        }
        var useAliasOpt = "";
        if(isANum==true) {
            useAliasOpt = "&USE_ALIAS=true";
        }
        //
        //
        var returnParameterName = "ACCOUNT_STATE";
        var returnParameterValue = null;
        var temp_principalName = principalName;
        if(caseSensitivePrincipalName==false){
        	temp_principalName = principalName.toLowerCase();
        }
        var anAuthReq = initRequest("/servlets/AuthenticateServlet?function=" + LOGIN_OPERATION_LOGIN + "&returnParameter=" + returnParameterName + "&" + LOGIN_PRINCIPAL_FIELD_NAME + "=" + temp_principalName + "&PASSWORD=" + password + useEmailOpt + useAliasOpt, "GET");
        anAuthReq.setRequestHeader("Content-Type", "text/plain; charset=\"UTF-8\"");
        anAuthReq.send("");
        var response = ( anAuthReq.responseXML ? anAuthReq.responseXML.documentElement : null);
        //
        //
        /*
            var serializer = new XMLSerializer();
            var str = serializer.serializeToString(response);
            alert("response "+str);
         */
        //
        //
        var returnParamsElements = (response ? response.getElementsByTagName('RETURN_PARAMETERS') : null);
        var returnParamsElement = (returnParamsElements && returnParamsElements.length>0 ? returnParamsElements[0] : null);
        if(returnParamsElement) {
            var returnParameterValueElement = findFirstNodeByName(returnParamsElement, returnParameterName);
            if(returnParameterValueElement && returnParameterValueElement.getAttribute("VALUE")) {
                returnParameterValue = returnParameterValueElement.getAttribute("VALUE").toString();
            }
        }
        //
        //
        var cmdLoginInfoElement = (response ? response.getElementsByTagName('LOGIN_INFORMATION') : null);
        if(cmdLoginInfoElement && cmdLoginInfoElement.length>0){
            cmdLoginInfoElement=cmdLoginInfoElement[0];
        }
        var loginResult = LOGIN_FAILED;
        if(cmdLoginInfoElement){
            var authResult=cmdLoginInfoElement.getAttribute("AUTHENTICATION_RESULT");
            if(authResult){
                if(authResult=="LOGIN_OK") {
                    //
                    //
                    hasDetailedLoginInformation = true;
                    loginResult = LOGIN_SUCCESS;
                    var accountState		=	cmdLoginInfoElement.getAttribute("ACCOUNT_STATE");
                    principalName			=	cmdLoginInfoElement.getAttribute("PRINCIPAL_NAME");
                    var accountDataComplete	=	cmdLoginInfoElement.getAttribute("ACCOUNT_DATA_IS_COMPLETE")
                    var accountValidated	=	cmdLoginInfoElement.getAttribute("ACCOUNT_VALIDATED")
                    var noEmail				=	cmdLoginInfoElement.getAttribute("ACCOUNT_HAS_NO_EMAIL");
                    //
                    //
                    principalName = principalName.replace(/\u0000/,"");
                    //
                    //
                    if(trackUsage) {
                        trackUsage("/loggedIn");
                    }
                    //
                    //
                    if(accountState=="ACCOUNT_IS_DISABLED" || accountState=="LOCKED"){
                        loginResult=LOGIN_FAILED;
                    }
                    else if(emailValidationRequired==true && accountValidated!=null && accountValidated!=undefined){
                        emailValidated = accountValidated=="true";
                        writeSessionCookie(ACCOUNT_VALIDATED_COOKIE_NAME, ""+accountValidated);
                    }
                    if(accountDataComplete=="true" || accountDataComplete=="ACCOUNT_REGISTRATION_IS_COMPLETE"){
                        emailValidated = accountValidated=="true";
                    }
                    if(noEmail==false){
        				
                    }
                }
                else if(authResult=="LOGIN_FAILED") {
                    loginResult = AUTHENTICATION_FAILED;
                }
            }
        }
       	if(loginResultHandler) {
            var returnParameter = new Object();
            returnParameter.name = returnParameterName;
            returnParameter.value = returnParameterValue;
            temp_principalName = principalName;
            if(caseSensitivePrincipalName==false){
            	temp_principalName = principalName.toLowerCase();
            }
            loginResultHandler.call(this, loginResult, temp_principalName, returnParameter);
        }
    }
    else {
        if(loginResultHandler) loginResultHandler.call(this, ALREADY_LOGGED_IN);
    }
}
function defaultLoginResultHandler(arg, aPrincipalName, aReturnParameter) {
    //
    //
    var evtobj=new Object();
    evtobj.type	= "loginStateChanged";
    evtobj.operation = LOGIN_OPERATION_LOGIN;
    evtobj.loginResult = arg;
    //
    //
    if(aPrincipalName) {
        evtobj.principalName = aPrincipalName;
    }
    if(aReturnParameter) {
        evtobj.returnParameter = aReturnParameter;
    }
    //
    //
    if(arg==ALREADY_LOGGED_IN || arg==LOGIN_SUCCESS){
        evtobj.code	=	0;	
    }
    else{
        if(!loginFailedMessage){
            alert("Login failed!\nPlease check that your email and password are correctly typed");
        }
        else{
            alert(loginFailedMessage);
        }
        evtobj.code	=	-1;
    }
    //
    //
    loginStateChanged.fireEvent(loginStateChanged, evtobj);
}
function defaultLogoutResultHandler(arg){
    var evtobj=new Object();
    evtobj.type	= "loginStateChanged";
    evtobj.operation = LOGIN_OPERATION_LOGOUT;
    if(arg==LOGOUT_SUCCESS){
        evtobj.code	=	0;	
    }
    else{
        evtobj.code	=	-1;	
    }
    loginStateChanged.fireEvent(loginStateChanged,evtobj);
}

/**
 * Terminate the current session and clear all session cookies associated with the login state.
 * Cookies are cleared even if the logout fails.
 *
 * @param logoutResultHandler function call back for handling logout request results.
 *        logoutResultHandler signature: fnc(aResultCode:int), where aResultCode can be LOGOUT_SUCCESS | LOGOUT_FAILED.
 *
 * @return void.
 */
function logout(logoutResultHandler) {
    //
    //
    var logoutReq = initRequest("/servlets/AuthenticateServlet?function=" + LOGIN_OPERATION_LOGOUT, "GET");
    logoutReq.setRequestHeader("Content-Type", "text/plain; charset=\"UTF-8\"");
    var logoutCode;
    try {
        logoutReq.send("");
    }
    catch(connectionE) {
        logoutReq = null;
        writeSessionCookie(ACCOUNT_VALIDATED_COOKIE_NAME, "false");
    }
    if(logoutReq) {
        //
        //
        var response  = (logoutReq.responseXML ? logoutReq.responseXML.documentElement:null);
        //
        //
        var cmdMsgElements = (response ? response.getElementsByTagName('MESSAGE') : null);
        var cmdMessageElement = null;
        if(cmdMsgElements && cmdMsgElements.length>0) cmdMessageElement = cmdMsgElements[0];
        //
        //
        if(cmdMessageElement && cmdMessageElement.firstChild) {
            //
            //
            var cmdMessageElementData = cmdMessageElement.firstChild.data;
            if(cmdMessageElementData!=null && cmdMessageElementData=="LOGOUT_OK") {
                if(logoutResultHandler){
                    logoutCode=LOGOUT_SUCCESS;
                }
            }
            else {
                if(logoutResultHandler){
                    logoutCode=LOGOUT_FAILED;
                }
            }
        }
        else {
            if(logoutResultHandler){
                logoutCode=LOGOUT_FAILED;
            }
        }
    }
    else {
        if(logoutResultHandler){
            logoutCode=LOGOUT_FAILED;
        }
    }
    //
    //
    writeSessionCookie(ACCOUNT_VALIDATED_COOKIE_NAME, "false");
    writeSessionCookie(LOGIN_STATE_COOKIE_NAME, "false");
    deleteCookie(SESSION_SHORT_NAME_COOKIE);
    if(logoutResultHandler) {
        logoutResultHandler(logoutCode);
    }
    //
    //
    if(trackUsage) {
        trackUsage("/loggedOut");
    }
}

/**
 * Resolves the login state of the client. Implementation based on cookie (LOGIN_STATE_COOKIE_NAME) 
 * value (session inactivity expiration is undetected).
 * @return true if client is logged in (an authenticated session exists).
 */
function isLoggedIn() {
    //
    //
    var retValue = false;
    if(emailValidationRequired ==true && !emailValidated){
        var emailCookie=getCookie(ACCOUNT_VALIDATED_COOKIE_NAME);
        if(emailCookie=="true"){
            emailValidated=true;	
        }
        else{
            emailValidated=false;
            return retValue;
        }
    }
    var sessionCookie = getCookie(LOGIN_STATE_COOKIE_NAME);
    if(sessionCookie=="true"){
        if(!loginStateCheckTime || loginStateCheckTime+1800000 <= (new Date()).getTime()){
            loginStateCheckTime=(new Date()).getTime();
            var sessionReq = initRequest("/servlets/AuthenticateServlet?function=HAS_SESSION", "GET");
            sessionReq.setRequestHeader("Content-Type", "text/plain; charset=\"UTF-8\"");
            var sessionCode;
            try {
                sessionReq.send("");
            }
            catch(connectionE) {
                sessionReq = null;
            }
            if(sessionReq) {
                //
                //
                var response  = (sessionReq.responseXML ? sessionReq.responseXML.documentElement:null);
                //
                //
	
                /*var serializer = new XMLSerializer();
	              str = serializer.serializeToString(response);
	              alert(str);*/
	
                var cmdMsgElements = (response ? response.getElementsByTagName('MESSAGE') : null);
                var cmdMessageElement = null;
                if(cmdMsgElements && cmdMsgElements.length>0) cmdMessageElement = cmdMsgElements[0];
                //
                //
                if(cmdMessageElement && cmdMessageElement.firstChild) {
                    //
                    //
                    var cmdMessageElementData = cmdMessageElement.firstChild.data;
                    if(cmdMessageElementData!=null && cmdMessageElementData=="true") {
                        retValue = true;
                    }
                    else {
                        retValue = false;
                    }
                }
                else {
                    retValue = false;
                }
            }
            else {
                retValue = false;
            }
		
		
            if(retValue == false){
                logout(defaultLogoutResultHandler);
            }
        }
        else{
            retValue = true;
        }
    }
    return retValue;
}

/**
 * @deprecated
 */
function getAccountID() {
    return getSessionShortName();
}

/**
 * Gets the short name (user name) of the current session.
 * Session short name is resolved by reading a cookie with name [SESSION_SHORT_NAME_COOKIE] defined in this file.
 * @return Short name (user name) or null if short name is not found (client is not logged in)
 */
function getSessionShortName() {
    //
    //
    var retValue = null;
    var accountIDCookie = getCookie(SESSION_SHORT_NAME_COOKIE);
    if(accountIDCookie && accountIDCookie.length>0) {
        retValue = accountIDCookie;
        retValue=retValue.replace(/\u0000/,"");
    }
    return retValue;
}

/*
 *
 */
function requestForgottenPassword(login){
    var retValue=false;
    if(login){
        var cmdXML = "<COMMANDS><COMMAND CLASS_NAME=\"com.tenduke.services.platform.command.RequestPassword\"";
        cmdXML += " LOGIN=\""+encode64(login)+"\""+
            " PRIMARY_CONTACT=\"EMAIL\""+
            " SECONDARY_CONTACT=\"SMS\""+
            " SECONDARY_GATEWAY=\"\""+
            " SERVICE_BRAND=\""+SERVICE_BRAND+"\" /> ";
        cmdXML += "</COMMANDS>";
        //
        // send request
        var aReq = initRequest("/servlets/XMLCommandServlet", "POST");
        aReq.setRequestHeader("Content-Type", "text/xml; charset=\"UTF-8\"");
        try {
            aReq.send(cmdXML);
        }
        catch(connectionException) {
            aReq = null;
        }
        //
        //
        if (aReq!=null && aReq.readyState == 4) {
            if (aReq.status == 200 && aReq.responseXML!=null) {
                //
                //
                var response  = aReq.responseXML;
                var cmdElements = response.getElementsByTagName('COMMAND');
                var cmdElement = null;
                if(cmdElements && cmdElements.length>0) cmdElement = cmdElements[0];
                //
                //
                if(cmdElement) {
                    //
                    //
                    var result = (cmdElement.getAttribute( 'RESULT' ) ? cmdElement.getAttribute( 'RESULT' ).toString():null);
                    if(result && result=="OK") {
                        //
                        //
                        if(trackUsage) {
                            trackUsage("/requestForgottenPassword");
                        }
                        //
                        //
                        retValue=true;
                    }
                }
            }
        }
    }
    return retValue;
}var imported_js_files=new Object();

function importJS(url,callback){
	if(imported_js_files && imported_js_files[url]){
		if(callback){
			return callback();
		}
	}
	else{
		var headID = document.getElementsByTagName("head")[0];         
		var newScript = document.createElement('script');
		newScript.setAttribute("type","text/javascript");
		newScript.setAttribute("language","javascript");
		headID.appendChild(newScript);
		if(callback){
			if(isIE()==true){
				//var count=0;
				var f=function(e){
					//alert("count "+window.event.srcElement+", "+window.event.readyState +", "+window.event.srcElement.readyState );


					if(window.event.srcElement.readyState=="loaded"){
						return callback();
					}
				}			
				newScript.onreadystatechange=f;
			}
			else{
				attachEventToDOMNode(newScript,"load",callback);
			}
		}
		newScript.setAttribute("src",url);
		imported_js_files[url]=true;
	}
}

function importJSCollection(urlArray,callback){
	if(urlArray && urlArray.length>0){
		var len=urlArray.length;
		var ind=0;
		//alert("import collection");
		var c=function(){
			ind++;
			//alert("import collection internal callback: "+ind);
			if(ind>=len){
				//alert("import collection all imported "+ ind+" == "+len);
				return callback();
			}
			
		}
		for(var i=0; i<urlArray.length; i++){
			//alert("import collection importing index "+i);
			importJS(urlArray[i],c);
		}
	}
}
var imported_css_files=new Object();

function importCSS(url,callback){
	if(imported_css_files && imported_css_files[url]){
		if(callback){
			return callback();
		}
	}
	else{
		var headID = document.getElementsByTagName("head")[0];   
		var newStyle = document.createElement('link');
		newStyle.setAttribute("rel","stylesheet");
		newStyle.setAttribute("type","text/css");
		headID.appendChild(newStyle);
		if(callback){
			if(isIE()==true){
				//var count=0;
				var f=function(e){
					//alert("count "+window.event.srcElement+", "+window.event.readyState +", "+window.event.srcElement.readyState );


					if(window.event.srcElement.readyState=="loaded"){
						return callback();
					}
				}			
				newStyle.onreadystatechange=f;
			}
			else{
				attachEventToDOMNode(newStyle,"load",callback);
			}
		}
		newStyle.setAttribute("href",url);
		imported_css_files[url]=true;
	}
}

function importCSSCollection(urlArray,callback){
	if(urlArray && urlArray.length>0){
		var len=urlArray.length;
		var ind=0;
		//alert("import collection");
		var c=function(){
			ind++;
			//alert("import collection internal callback: "+ind);
			if(ind>=len){
				//alert("import collection all imported "+ ind+" == "+len);
				return callback();
			}
			
		}
		for(var i=0; i<urlArray.length; i++){
			//alert("import collection importing index "+i);
			importCSS(urlArray[i],c);
		}
	}
}function OneToManyMap(){
	this.keys				=	new Object();
	this.replaceAllFromKey	=	OneToManyMap_replaceAllFromKey;
	this.addToKey			=	OneToManyMap_addToKey;
	this.removeFromKey		=	OneToManyMap_removeFromKey;
	this.containsValue		=	OneToManyMap_containsValue;
	this.readFromKey		=	OneToManyMap_readFromKey;
}
function OneToManyMap_replaceAllFromKey(key,array){
	this.keys[key]=array;
}
function OneToManyMap_addToKey(key,value){
	if(!this.keys[key]){
		this.replaceAllFromKey(key,new Array());
	}
	if(this.containsValue(key,value)==-1){
		this.keys[key].push(value);
	}
}
function OneToManyMap_removeFromKey(key,value){
	var ind=this.containsValue(key,value);
	if(ind>=0){
		this.keys[key].splice(ind);
	}
}
function OneToManyMap_containsValue(key,value){
	var retVal=-1;
	if(this.keys[key]){
		for(var i=0; i<this.keys[key].length; i++){
			if(this.keys[key][i]==value){
				retVal=i;
				break;
			}
		}
	}
	return retVal;

}
function OneToManyMap_readFromKey(key){
	return this.keys[key];
}

/** 
 * Enforced by the account model specified by the kentish server app project 
 * The following account parameters have been commonly used, 
 * params with (required) comment shall be specified when createing an account.
 *   ACCOUNT_TYPE
 *   ACCOUNT_ID (required)
 *   PRINCIPAL_NAME (required)
 *   PASSWORD (required)
 *   PASSWORD_CONFIRMED (required)
 *   FIRST_NAME
 *   LAST_NAME
 *   EMAIL (required)
 *   GENDER
 *   AGE
 *   COUNTRY
 *   REGION
 *   MOBILE_NUMBER
 */
var REQUIRED_ACCOUNT_PARAMS = ["ACCOUNT_ID", "PRINCIPAL_NAME", "PASSWORD", "PASSWORD_CONFIRMED", "EMAIL"];

/** */
var SIGN_UP_OK = 0;
/** */
var SIGN_UP_FAILED = -1;

/** */
var SIGN_UP_FAILURE_REASON_USER_NAME_NOT_VALID_ERROR = -3;
/** */
var SIGN_UP_FAILURE_REASON_ACCOUNT_ALREADY_EXISTS_ERROR = -4;
/** */
var SIGN_UP_FAILURE_REASON_PASSWORD_TOO_SHORT_ERROR = -5;
/** */
var SIGN_UP_FAILURE_REASON_PASSWORD_MISSMATCH_ERROR = -6;
/** */
var SIGN_UP_FAILURE_REASON_EMAIL_NOT_VALID_ERROR = -7;
/** */
var SIGN_UP_FAILURE_REASON_REQUEST_ERROR = -8;


/** */
var UPDATE_ACCOUNT_OK = 0;
/** */
var UPDATE_ACCOUNT_FAILED = -1;

/**
 * @return true if REQUIRED_ACCOUNT_PARAMS contains the specified param name
 */
function containsRequiredAccountParam(aParamName) {
    //
    //
    var retValue = false;
    if(REQUIRED_ACCOUNT_PARAMS.indexOf(aParamName)>-1) retValue = true;
    return retValue;
}

/**
 * Get XML command to create a new account in the client app context.
 * Required input params: "ACCOUNT_ID", "PASSWORD", "PASSWORD_CONFIRMED", "EMAIL" as minimum set of parameters.
 * @param accountParams Array of parameters used to create an account in the system.
 * @param commandAttrs Array of attributes to set for the account create command
 */
function getCreateAccountCommand(accountParams, commandAttrs) {
    //
    //
    var i=0;
    var retValue = "<COMMAND CLASS_NAME=\"com.tenduke.services.platform.command.CreateAccount\"";
    if(commandAttrs) {
        for(j = 0; j < commandAttrs.length; j++) {
            retValue += " " + commandAttrs[j][0] + "=\"" + commandAttrs[j][1] + "\"";
        }
    }
    retValue += ">";
    retValue += "<![CDATA[<ACCOUNT_CREATE_DATA><ACCOUNT_PARAMETERS>";
    for(i=0; i<accountParams.length; i++) {
        retValue += "<ACCOUNT_PARAMETER NAME=\"" + accountParams[i][0] + "\" VALUE=\"" + accountParams[i][1] + "\"/>";
    }		
    retValue += "</ACCOUNT_PARAMETERS></ACCOUNT_CREATE_DATA>]]></COMMAND>";
    //
    //
    return retValue;
}

/**
 * Create a new account in the client app context.
 * Required input params: "ACCOUNT_ID", "PASSWORD", "PASSWORD_CONFIRMED", "EMAIL" as minimum set of parameters.
 * @accountParams Array of parameters used to create an account in the system.
 * @signupHandler a function call back to handle GUI aspects and user communication with the signup process.
 */
function createAccount(accountParams, signupHandler) {
    //
    //
    var i=0;
    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
    cmdXML += getCreateAccountCommand(accountParams);
    cmdXML += "</COMMANDS>";
    //
    //
    var caReq = initRequest("/servlets/XMLCommandServlet", "POST");
    caReq.setRequestHeader("Content-Type", "text/xml; charset=\"UTF-8\"");
    //
    //
    try {
        caReq.send(cmdXML);
    }
    catch(cmdSendE) {
        caReq = null;
        cmdXML = null;
    }
    //
    //
    if (caReq && caReq.readyState == 4) {
        if (caReq.status == 200 && caReq.responseXML!=null) {
            //
            //
            var response  = caReq.responseXML.documentElement;
            var cmdElements = (response ? response.getElementsByTagName('COMMAND'):null);
            var cmdElement = null;
            if(cmdElements && cmdElements.length>0) cmdElement = cmdElements[0];
            var cmdMessageElements = (response ? response.getElementsByTagName('MESSAGE'):null);
            var cmdMessageElement = null;
            if(cmdMessageElements && cmdMessageElements.length>0) cmdMessageElement = cmdMessageElements[0];
            var result = ( (cmdElement && cmdElement.getAttribute('RESULT')) ? cmdElement.getAttribute('RESULT').toString():"FAILED");
            var errCode = parseInt( ( (cmdElement && cmdElement.getAttribute('CODE')) ? cmdElement.getAttribute('CODE').toString():"-1") );
			
            if(result=="OK") {
                if(signupHandler) signupHandler.call(this, SIGN_UP_OK, 0);
            }
            else if(cmdMessageElement && cmdMessageElement.firstChild) {
                if(signupHandler) signupHandler.call(this, SIGN_UP_FAILED, cmdMessageElement.firstChild.data, errCode);
            }
        } 
        else {
            if(signupHandler) signupHandler.call(this, SIGN_UP_FAILED, "", SIGN_UP_FAILURE_REASON_REQUEST_ERROR);
        }
    }
    //
    //
    cmdXML = null;
}

/**
 * Assembly of an array that contains all
 * elements to submit as account parameters when
 * registering an account.
 */
function getAccountParamsToSubmit(aDomObject, removePrefixFromElementIds) {
    var retValue = new Object();
    var returnArray = null;
    var returnHashtable = null;
    if(aDomObject){
        var inputs = aDomObject.getElementsByTagName("input");
        var selects = aDomObject.getElementsByTagName("select");
        var i=0;
        if(inputs && selects) {
            returnArray = new Array();
            returnHashtable = new Hashtable()
        }
        if(inputs) {
            for(i=0; i<inputs.length; i++){
                var idAttr = inputs[i].getAttribute("id");
                var typeAttr = inputs[i].getAttribute("type");
                if(idAttr && idAttr.indexOf("DONT_SEND")==-1 && typeAttr!="button"){
                    var paramName=null;
                    if(removePrefixFromElementIds) paramName = inputs[i].getAttribute("id").split(removePrefixFromElementIds)[1];
                    else paramName = inputs[i].getAttribute("id");
                    if(!paramName) continue;
                    var ar=new Array();
                    ar[0]=paramName;
                    ar[1] = "";
                    if(typeAttr!="checkbox") ar[1] = (inputs[i].value?inputs[i].value.replace(/\x00/, ""):"");
                    else ar[1] = "" + inputs[i].checked;
                    returnArray[returnArray.length]=ar;
                    returnHashtable.putEntry(ar[0], ar[1]);
                }
            }
        }
        if(selects) {
            for(i=0; i<selects.length; i++){
                var idAttr = selects[i].getAttribute("id");
                if(idAttr.indexOf("DONT_SEND")==-1){
                    var paramName=null;
                    if(removePrefixFromElementIds) paramName = selects[i].getAttribute("id").split(removePrefixFromElementIds)[1];
                    else paramName = selects[i].getAttribute("id");
                    if(!paramName) continue;
                    var ar = new Array();
                    ar[0] = paramName;
                    ar[1] = (selects[i].value?selects[i].value.replace(/\x00/, ""):"");
                    returnArray[returnArray.length]=ar;
                    returnHashtable.putEntry(ar[0], ar[1]);
                }
            }
        }
    }
    retValue.accountParamsArray = returnArray;
    retValue.accountParamsHashtable = returnHashtable;
    return retValue;
}

/**
 * Change the account information.
 * @param password Value of the new password
 * @param passwordConfirmed Value of the new password confirmed
 * @param updateResultHandler function callback to handle events and results.
                              Signature: fnc(statusCode:int, description:String), where statusCode
                                         can take values: UPDATE_ACCOUNT_OK | UPDATE_ACCOUNT_FAILED
                                         and description is for development purposes.
 */
function changeAccountInformation(accountParams, updateResultHandler) {
    //
    //
    var retValue = UPDATE_ACCOUNT_FAILED;
    //
    //
    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
    cmdXML += "<COMMAND CLASS_NAME=\"com.tenduke.services.platform.command.UpdateAccount\">";
    cmdXML += "<![CDATA[<ACCOUNT_CREATE_DATA><ACCOUNT_PARAMETERS>";
    for(var i=0; i<accountParams.length; i++){	
        cmdXML += "<ACCOUNT_PARAMETER NAME=\""+accountParams[i][0]+"\" VALUE=\"" + accountParams[i][1] + "\"/>";
    }
    cmdXML += "</ACCOUNT_PARAMETERS></ACCOUNT_CREATE_DATA>]]></COMMAND>";
    cmdXML += "</COMMANDS>";
    //
    //
    var caReq = initRequest("/servlets/XMLCommandServlet", "POST");
    caReq.setRequestHeader("Content-Type", "text/xml; charset=\"UTF-8\"");
    //
    //
    try {
        caReq.send(cmdXML);
    }
    catch(cmdSendE) {
        caReq = null;
        cmdXML = null;
    }
    //
    //
    if (caReq!=null && caReq.readyState == 4) {
        if (caReq.status == 200 && caReq.responseXML!=null) {
            //
            //
            var response  = caReq.responseXML.documentElement;
            var cmdElements = (response ? response.getElementsByTagName('COMMAND'):null);
            var cmdElement = null;
            if(cmdElements && cmdElements.length>0) cmdElement = cmdElements[0];
            var cmdMessageElements = (response ? response.getElementsByTagName('MESSAGE'):null);
            //
            //
            var result = null;
            if(cmdElement)
                result = cmdElement.getAttribute('RESULT').toString();
            if(result!=null && result=="OK") {
                retValue = UPDATE_ACCOUNT_OK;
                if(updateResultHandler){
                    updateResultHandler.call(this, UPDATE_ACCOUNT_OK);
                }
            }
            else {
                retValue = UPDATE_ACCOUNT_FAILED;
                var errorMessage = "";
                if(cmdMessageElements)
                    for(var i=0; i<cmdMessageElements.length; i++){
                        errorMessage += cmdMessageElements[i].firstChild.data;
                    }
                if(updateResultHandler){
                    updateResultHandler.call(this, UPDATE_ACCOUNT_FAILED, errorMessage);	
                }
            }
        } 
        else if(updateResultHandler){
            retValue = UPDATE_ACCOUNT_FAILED;
            updateResultHandler.call(this, UPDATE_ACCOUNT_FAILED, "Bad response ready state!");
        }
    }
    //
    //
    return retValue;
}

/**
 *
 */
function initAccountParamsInPage(accountParamNames, dependecyListProcessor, elementNamePrefix) {
    //
    //
    var retValue = INIT_ACCOUNT_PARAMS_FAILED;
    //
    //
    if(!elementNamePrefix){
        elementNamePrefix="";	
    }
    //
    // do the command XML
    var i=0;
    var cmdXML = "<COMMANDS><COMMAND CLASS_NAME=\"com.tenduke.services.platform.command.GetAccountParameters\">";
    cmdXML += "<![CDATA[<ACCOUNT_PARAMETERS>";
    for(i=0; i<accountParamNames.length; i++) {
        cmdXML += "<ACCOUNT_PARAMETER NAME=\"" + accountParamNames[i]+ "\" />";
    }
    cmdXML += "</ACCOUNT_PARAMETERS>]]></COMMAND></COMMANDS>";
    //
    // send request
    var aReq = initRequest("/servlets/XMLCommandServlet", "POST");
    aReq.setRequestHeader("Content-Type", "text/xml; charset=\"UTF-8\"");
    try {
        aReq.send(cmdXML);
    }
    catch(connectionException) {
        aReq = null;
    }
    //
    //
    if (aReq!=null && aReq.readyState == 4) {
        if (aReq.status == 200 && aReq.responseXML!=null) {
            //
            //
            var response  = aReq.responseXML;
            var cmdElements = response.getElementsByTagName('COMMAND');
            var cmdElement = null;
            if(cmdElements && cmdElements.length>0) cmdElement = cmdElements[0];
            //
            //
            if(cmdElement) {
                //
                //
                var result = (cmdElement.getAttribute( 'RESULT' ) ? cmdElement.getAttribute( 'RESULT' ).toString():null);
                if(result && result=="OK") {
                    //
                    //
                    var dataElements = response.getElementsByTagName('ACCOUNT_PARAMETERS');
                    var dataElement = null;
                    if(dataElements && dataElements.length>0) dataElement = dataElements[0];
                    if(dataElement) {
                        //
                        //
                        var isEncodedFlag = dataElement.getAttribute("VALUES_ARE_ENCODED");
                        var aParamList = dataElement.getElementsByTagName('ACCOUNT_PARAMETER');
                        if(aParamList) {
                            //
                            //
                            for(i=0; i<aParamList.length; i++) {
                                var aParam = aParamList[i];
                                if(aParam && aParam.getAttribute( 'NAME' ) && aParam.getAttribute( 'VALUE' )) {
                                    //
                                    //
                                    var aName = aParam.getAttribute( 'NAME' ).toString();
                                    var aValue = aParam.getAttribute( 'VALUE' ).toString();
                                    if(isEncodedFlag && isEncodedFlag=="true") {
                                        aValue = decode64(aValue);
                                    }
                                    var namedElement = document.getElementById(elementNamePrefix+aName);
                                    if(namedElement) {
                                        namedElement.value = aValue;
                                        retValue = INIT_ACCOUNT_PARAMS_OK;
                                    }
                                    else if(aName!=null && aName!=undefined) {
                                        //
                                        // todo: define app logics
                                    }
                                }
                            }
                        }
                        else {
                            //
                            // todo: define app logics						
                        }
                    }
                    else {
                        //
                        // todo: define app logics						
                    }
                }
                else {
                    //
                    // todo: define app logics
                }
            }
            else {
                //
                // todo: define app logics
            }
        } 
        else {
            //
            // todo: define app logics
        }
    }
    //
    // if specified call the result handler
    if(dependecyListProcessor) dependecyListProcessor.call(this, retValue);
    //
    // return the error status
    return retValue;
}

/**
 * Send account activation email (may be used ad a general welcome email as well.)
 */
function sendActivationEmail(invalidateAccount, aSender, aSubject, aMessage, aMimeType) {
    //
    //
    return sendActivationEmailToNamedRecipient(invalidateAccount, null, aSender, aSubject, aMessage, aMimeType);
}

/**
 * Send account activation email (may be used ad a general welcome email as well.)
 */
function getSendActivationEmailToNamedRecipientXml(aRecipient, aSender, aSubject, aMessage, aMimeType) {
    //
    //
    var cmdXML = "<COMMANDS>" +
        "<COMMAND CLASS_NAME=\"com.tenduke.services.platform.command.SendAccountActivationEmail\""+
        (aRecipient ? " PRINCIPAL_NAME=\""+encode64(aRecipient)+"\"":"")+
        " SENDER=\""+encode64(aSender)+"\""+
        " SUBJECT=\""+encode64(aSubject)+"\""+
        " MESSAGE=\""+encode64(aMessage)+"\""+
        " CONTENT_TYPE=\""+encode64(aMimeType)+"\"/>"+
        "</COMMANDS>";
    //
    //
    return cmdXML;
}

/**
 * Send account activation email (may be used ad a general welcome email as well.)
 */
function sendActivationEmailToNamedRecipient(invalidateAccount, aRecipient, aSender, aSubject, aMessage, aMimeType) {	
    //
    //
    var retValue = false;
    //
    //
    if(invalidateAccount) {
        //
        //
        var changedAccountParams = new Array();
        var newParam = new Array();
        newParam.push("ACCOUNT_VALIDATED");
        newParam.push("false");
        changedAccountParams.push(newParam);
        changeAccountInformation(changedAccountParams, null);
    }
    //
    //
    var cmdXML = getSendActivationEmailToNamedRecipientXml(aRecipient, aSender, aSubject, aMessage, aMimeType);
    //
    // send request
    var aReq = initAsyncRequest("/servlets/XMLCommandServlet", "POST");
    aReq.setRequestHeader("Content-Type", "text/xml; charset=\"UTF-8\"");
    try {
        aReq.send(cmdXML);
        retValue = true;
    }
    catch(connectionException) {
        aReq = null;
    }
    //
    //
    return retValue;
}function SelectedItem(widget){
	this.contentUID=widget.contentUID;
	this.widgetID=widget.id;
	this.type=widget.type;
	this.className=widget.className;
	//
	//
	this.equals=SI_equals;
}
function SI_equals(sItem){
	var retVal=false;
	if(this.contentUID){
		if(sItem.contentUID){
			if(this.contentUID == sItem.contentUID){
				retVal=true;
			}
			else{
				retVal=false;			
			}
		}
		else{
			retVal=false;			
		}
	}
	else{
		retVal=false;	
	}
	return retVal;
}var HIDDEN_WIDGETS_STATE_HOLDER=new Object();
function hideExsistingWidgets(cid){
	var cont=document.getElementById(cid);	
	if(cont && document.widgets){
		var divs=cont.getElementsByTagName("div");
		if(divs){
			var wids=new Array();
			for(var i=0; i< divs.length; i++){
				var id=divs[i].getAttribute("id");
				if(id){
					if(document.widgets[id]){
						wids.push(document.widgets[id]);
					}
				}
			}
			hideWidgets(wids);
		}
	}
}
function hideWidgets(wids){
	if(wids && wids.length>0){
		for(var i=0; i<wids.length; i++){
			wids[i].hide();
		}
	}
}
function setWidgetVisibility(cid,uid,flag){
	if(flag==true){
		if(HIDDEN_WIDGETS_STATE_HOLDER && HIDDEN_WIDGETS_STATE_HOLDER[cid+uid]){
			for(var i=0; i<HIDDEN_WIDGETS_STATE_HOLDER[cid+uid].length; i++){
				document.widgets[HIDDEN_WIDGETS_STATE_HOLDER[cid+uid][i]].setVisible(true);
			}
			HIDDEN_WIDGETS_STATE_HOLDER[cid+uid]=null;
		}
	}
	else{
			var cont=document.getElementById(cid);	
		if(cont && document.widgets){
			var divs=cont.getElementsByTagName("div");
			if(divs){
				for(var i=0; i< divs.length; i++){
					var id=divs[i].getAttribute("id");
					if(id){
						if(document.widgets[id]){
							if(!HIDDEN_WIDGETS_STATE_HOLDER[cid+uid]){
								HIDDEN_WIDGETS_STATE_HOLDER[cid+uid]=new Array();
							}
							HIDDEN_WIDGETS_STATE_HOLDER[cid+uid][HIDDEN_WIDGETS_STATE_HOLDER[cid+uid].length]=id;
							document.widgets[id].setVisible(false);
						}
					}
				}
			}
		}
	}
}//
//
/**
 * @param entryId The id of the entry for which data is wanted
 * @param entryType type of entry as string (AudioEntry, AudioEntrySet, ImageEntry, ...)
 * @return Instance of Properties class that holds the entry data as parameters
 */
function getEntryById(entryId, entryType) {
    //
    //
    var retValue = null;
    //
    //
    if(!entryType) {
        entryType = "VideoEntry";
    }
    var cmdXML = "<COMMANDS>";
    cmdXML += "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.GetEntry\" ENTRY_ID=\"" + encode64(entryId) + "\" ENTRY_TYPE=\"" + entryType + "\">";
    cmdXML +="</COMMAND></COMMANDS>";
    //
    //
    var aCommandResponse = commandRequest(cmdXML, null);
    if (aCommandResponse && aCommandResponse.readyState == 4 && aCommandResponse.status == 200 && aCommandResponse.responseXML!=null) {
        var respXml = aCommandResponse.responseXML.documentElement;
        if(respXml) {
            var entryElements = respXml.getElementsByTagName('ENTRY');
            if(entryElements && entryElements.length>0) {
                var entryElement = entryElements[0];
                if(entryElement) {
                    var entryProps = new Properties();
                    entryProps.setRootElementName("ENTRY");
                    entryProps.setParametersAreEncoded(true);
                    entryProps.parseNode(entryElement);
                    retValue = entryProps;
                }
            }
        }
    }
    //
    //
    return retValue;
}

/**
 * @param profileId The profile that owns the entry (may be null incase session profile is to be used)
 * @param displayName Displat name of entry to look up
 * @param entryType type of entry as string (AudioEntry, AudioEntrySet, ImageEntry, ...)
 * @return Instance of Properties class that holds the entry data as parameters
 */
function getEntryByProfileIdAndDisplayName(profileId, displayName, entryType) {
    //
    //
    var retValue = null;
    //
    //
    if(!entryType) {
        entryType = "VideoEntry";
    }
    var cmdXML = "<COMMANDS>";
    cmdXML += "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.GetEntry\""; 
    if(profileId) {
        cmdXML += " PROFILE_ID=\"" + profileId + "\"";
    }
    cmdXML += " DISPLAY_NAME=\"" + encode64(displayName) + "\"";
    cmdXML += " ENTRY_TYPE=\"" + entryType + "\">";
    cmdXML +="</COMMAND></COMMANDS>";
    //
    //
    var aCommandResponse = commandRequest(cmdXML, null);
    if (aCommandResponse && aCommandResponse.readyState == 4 && aCommandResponse.status == 200 && aCommandResponse.responseXML!=null) {
        var respXml = aCommandResponse.responseXML.documentElement;
        if(respXml) {
            var entryElements = respXml.getElementsByTagName('ENTRY');
            if(entryElements && entryElements.length>0) {
                var entryElement = entryElements[0];
                if(entryElement) {
                    var entryProps = new Properties();
                    entryProps.setRootElementName("ENTRY");
                    entryProps.setParametersAreEncoded(true);
                    entryProps.parseNode(entryElement);
                    retValue = entryProps;
                }
            }
        }
    }
    //
    //
    return retValue;
}

/**
 * Create a new entry or update an existing one.
 * @param entryParams Properties instance of parameters used to create an entry in the system.
 * @param entryType "AudioEntry", "ImageEntry" or "VideoEntry" supported.
 * @param entryId Id for new or existing entry.
 * @param relatedProfiles array of profile ids.
 * @return true for success false for failure.
 */
function createOrUpdateEntry(entryParams, entryType, entryId, relatedProfiles) {
    //
    //
    var retValue = false;
    if(!entryParams) return retValue;
    if(!entryType) entryType="VideoEntry";
    //
    //
    var cmdData = "";
    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
    cmdXML += "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.CreateOrUpdateEntry\" ENTRY_TYPE=\"" + entryType + "\" ENTRY_ID=\"" + entryId + "\"";
   	if(relatedProfiles && relatedProfiles.length>0){
     	cmdXML += " RELATED_PROFILE_IDS=\""+relatedProfiles.join(",")+"\"";
     }
    cmdXML += "><DATA>";
    cmdData = encode64("<ENTRY_DATA>" + entryParams.toXML() + "</ENTRY_DATA>");
    cmdXML += cmdData;
    cmdXML += "</DATA></COMMAND></COMMANDS>";
    //
    //
    retValue = singleCommandRequest(cmdXML);
    //
    //
    return retValue;
}

/**
 * Delete an entry.
 * @param entryId Id for existing entry to delete. 
 * @param entryType "AudioEntry", "ImageEntry" or "VideoEntry" supported.
 * @param deleteFiles Boolean flag to control if files associated with entry should also be deleted, optional
 * @param fileExtensions Array of file extension names that indicate derived media assets for delete operation, optional
 * @return true for success false for failure.
 */
function deleteEntry(entryId, entryType, deleteFiles, fileExtensions) {
    //
    //
    var retValue = false;
    if(!entryId || !entryType) {
        return retValue;
    }
    //
    //
    var cmd = new Array();
    cmd[cmd.length] = '<COMMANDS PROPAGATE="true">';
    cmd[cmd.length] = '<COMMAND CLASS_NAME="com.tenduke.tendukecommunity.command.DeleteEntry" ';
    cmd[cmd.length] = ' ENTRY_ID="' + entryId + '" ';
    cmd[cmd.length] = ' ENTRY_TYPE="' + entryType + '" ';	
    if(true==deleteFiles) {
        cmd[cmd.length]= ' DELETE_STORED_OBJECTS="' + true + '"';
    }
    if(fileExtensions && fileExtensions.length>0) {
        cmd[cmd.length]= ' STORED_OBJECT_FORMAT_EXTENSIONS="' + fileExtensions.join(",") + '"';
    }
    cmd[cmd.length] = ' /></COMMANDS>';
    //
    //
    retValue = singleCommandRequest(cmd.join(""));
    //
    //
    return retValue;
}

/**
 * Add entries to an entry set
 * @param entryIds Array of entry id:s to add to entry set
 * @param entryTypes Array of entry types
 * @param entrySetId Id of entry set where this entry will be added
 * @param commandName Optional, name of command to call. If not given, uses
 *                    AddEntryToEntrySet. If given, it must be full name of a command
 *                    that implements same interface as AddEntryToEntrySet.
 */
function addEntriesToEntrySet(entryIds, entryTypes, entrySetId, commandName){
    //
    //
    var retValue = false;
    if(!commandName) {
        commandName = "com.tenduke.tendukecommunity.command.AddEntryToEntrySet";
    }
    //
    //
    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
    for(var i=0; i<entryIds.length; i++){
        cmdXML += '<COMMAND CLASS_NAME="' + commandName + '"';
        cmdXML += ' ENTRY_ID="'+entryIds[i]+'"';
        cmdXML += ' ENTRY_SET_ID="'+entrySetId+'"';
        //cmdXML += ' ENTRY_INDEX="[index for entry in entry set, defaults to last]"';
        cmdXML += ' ENTRY_TYPE="'+entryTypes[i]+'"';
        cmdXML += ' INSERT_POLICY="APPEND">';
        cmdXML += '</COMMAND>';
    }
    cmdXML += '</COMMANDS>';
    //
    //
    retValue = singleCommandRequest(cmdXML);
    //
    //
    cmdXML = null;
    return retValue;
}
/**
 * Remove entries from an entry set
 * @param entryIds Array of entry id:s to remove from entry set
 * @param entryTypes Array of entry types
 * @param entrySetId Id of entry set from which this entry will be removed
 * @param commandName Optional, name of command to call. If not given, uses
 *                    RemoveEntryFromEntrySet. If given, it must be full name of a command
 *                    that implements same interface as RemoveEntryFromEntrySet.
 */
function removeEntriesFromEntrySet(entryIds, entryTypes, entrySetId, commandName){
    //
    //
    var retValue = false;
    if(!commandName) {
        commandName = "com.tenduke.tendukecommunity.command.RemoveEntryFromEntrySet";
    }
    //
    //
    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
    for(var i=0; i<entryIds.length; i++){
        cmdXML += '<COMMAND CLASS_NAME="' + commandName + '"';
        cmdXML += ' ENTRY_ID="'+entryIds[i]+'"';
        cmdXML += ' ENTRY_SET_ID="'+entrySetId+'"';
        cmdXML += ' ENTRY_TYPE="'+entryTypes[i]+'"';
        cmdXML += '>';
        cmdXML += '</COMMAND>';
    }
    cmdXML += '</COMMANDS>';
    //
    //
    retValue = singleCommandRequest(cmdXML);
    //
    //
    cmdXML = null;
    return retValue;
}

/**
 * Add one ore more entries to a channel.
 * @param entryIds Array of entry Id's for each entry to add to specified channel
 * @param entryTypes Array of entry types for each entry to add to specified channel
 * @param channelId Id of the channel to add entries to.
 */
function addEntriesToChannel(entryIds, entryTypes, channelId){
    //
    //
    var retValue = false;

    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
    for(var i=0; i<entryIds.length; i++){
        cmdXML += '<COMMAND CLASS_NAME="com.tenduke.tendukecommunity.command.AddEntryToChannel"';
        cmdXML += ' ENTRY_ID="'+entryIds[i]+'"';
        cmdXML += ' CHANNEL_ID="'+ channelId +'"';
        //cmdXML += ' ENTRY_INDEX="[index for entry in entry set, defaults to last]"';
        cmdXML += ' ENTRY_TYPE="'+entryTypes[i]+'"';
        cmdXML += ' INSERT_POLICY="APPEND">';
        cmdXML += '</COMMAND>';
    }
    cmdXML += '</COMMANDS>';
    //
    //
    retValue = singleCommandRequest(cmdXML);
    //
    //
    cmdXML = null;
    return retValue;
}

/**
 * Remove one ore more entries from a channel.
 * @param entryIds Array of entry Id's for each entry to remove from specified channel
 * @param entryTypes Array of entry types for each entry to remove specified channel
 * @param channelId Id of the channel to remove entries from.
 */
function removeEntriesFromChannel(entryIds, entryTypes, channelId){
    //
    //
    var retValue = false;

    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
    for(var i=0; i<entryIds.length; i++){
        cmdXML += '<COMMAND CLASS_NAME="com.tenduke.tendukecommunity.command.RemoveEntryFromChannel"';
        cmdXML += ' ENTRY_ID="'+entryIds[i]+'"';
        cmdXML += ' CHANNEL_ID="'+channelId+'"';
        cmdXML += ' ENTRY_TYPE="'+entryTypes[i]+'"';
        cmdXML += '>';
        cmdXML += '</COMMAND>';
    }
    cmdXML += '</COMMANDS>';
    //
    //
    retValue = singleCommandRequest(cmdXML);
    //
    //
    cmdXML = null;
    return retValue;
}

/**
 * Create a relation for entry and profile. Both the specified entry and profile
 * must exist for the relation creation to work.
 * @param entryType "AudioEntry", "DocumentEntry", "ImageEntry" or "VideoEntry" supported.
 * @param entryId Id for existing entry to relate with profile.
 * @param relatedProfileId Id for existing profile to relate with entry.
 * @return true for success false for failure.
 */
function createOrUpdateEntryProfileRelation(entryType, entryId, relatedProfileId) {
    //
    //
    var retValue = false;
    //
    //
    if(!entryId || !relatedProfileId) {
        return retValue;
    }
    if(!entryType) {
        entryType="VideoEntry";
    }
    //
    //
    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
    cmdXML += "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.CreateOrUpdateEntryProfileRelation\" ENTRY_TYPE=\"" + entryType + "\" ENTRY_ID=\"" + entryId + "\" RELATED_PROFILE_ID=\"" + relatedProfileId + "\">";
    cmdXML += "</COMMAND></COMMANDS>";
    //
    //
    retValue = singleCommandRequest(cmdXML);
    //
    //
    return retValue;
}

/**
 * Create a new entryset or update an existing one.
 * @param entrySetId Id for new or existing entrySet.
 * @param entrySetParams Properties instance of parameters used to create an entry in the system.
 * @param entryParamsArray Properties array with params instances used to create child entries for set in the system.
 * @param entryType "AudioEntrySet", "ImageEntrySet", "VideoEntrySet" supported.
 * @return true for success false for failure.
 */
function createOrUpdateEntrySet(entrySetId, entrySetParams, entryParamsArray, entryType) {
    //
    //
    var retValue = false;
    if(!entrySetParams) return retValue;
    if(!entryType) entryType="VideoEntrySet";
    //
    //
    var cmdData = "";
    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
    cmdXML += "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.CreateOrUpdateEntrySet\" ENTRY_ID=\"" + entrySetId + "\" ENTRY_TYPE=\"" + entryType + "\"><DATA>";
    var data=new Array();
    data[data.length]="<ENTRY_SET>";
    data[data.length]=entrySetParams.toXML();
    if(entryParamsArray){
        data[data.length]="<CHILD_ENTRIES>";
        for(var i=0; i<entryParamsArray.length; i++){
            data[data.length]=entryParamsArray[i].toXML();
        }
        data[data.length]="</CHILD_ENTRIES>";
    }
    data[data.length]="</ENTRY_SET>";
    cmdData = encode64(data.join(""));
    cmdXML += cmdData;
    cmdXML += "</DATA></COMMAND></COMMANDS>";
    //
    //
    retValue = singleCommandRequest(cmdXML);
    //
    //
    return retValue;
}

/**
 * Delete an entry set.
 * @param entryId Id for existing entry set to delete. 
 * @param entryType "AudioEntrySet", "ImageEntrySet" or "VideoEntrySet" supported.
 * @param deleteEntries Boolean flag to control if child entries should also be deleted, optional, default to false
 * @param deleteFiles Boolean flag to control if files associated with entry should also be deleted, optional, default to false
 * @param fileExtensions Array of file extension names that indicate derived media assets for delete operation, optional, default to false
 * @return true for success false for failure.
 */
function deleteEntrySet(entryId, entryType, deleteEntries, deleteFiles, fileExtensions) {
    //
    //
    var retValue = false;
    if(!entryId || !entryType) {
        return retValue;
    }
    //
    //
    var cmd = new Array();
    cmd[cmd.length] = '<COMMANDS PROPAGATE="true">';
    cmd[cmd.length] = '<COMMAND CLASS_NAME="com.tenduke.tendukecommunity.command.DeleteEntry" ';
    cmd[cmd.length] = ' ENTRY_ID="' + entryId + '" ';
    cmd[cmd.length] = ' ENTRY_TYPE="' + entryType + '" ';	
    if(true==deleteEntries) {
        cmd[cmd.length]= ' DELETE_ENTRIES="' + true + '"';
    }
    if(true==deleteFiles) {
        cmd[cmd.length]= ' DELETE_STORED_OBJECTS="' + true + '"';
    }
    if(fileExtensions && fileExtensions.length()>0) {
        cmd[cmd.length]= ' STORED_OBJECT_FORMAT_EXTENSIONS="' + fileExtensions.join(",") + '"';
    }
    cmd[cmd.length] = ' /></COMMANDS>';
    //
    //
    retValue = singleCommandRequest(cmd.join(""));
    //
    //
    return retValue;
}

/** */
function rateEntry(entryId,newRate,entryType){
    var retValue = false;
    //
    //
    if(!entryType) {
        entryType = "VideoEntry";
    }
    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
    cmdXML += "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.RateEntry\" ENTRY_ID=\"" + encode64(entryId) + "\" ENTRY_TYPE=\"" + entryType + "\" RATING=\""+ newRate +"\">";
    cmdXML +="</COMMAND></COMMANDS>";
    //
    //
    retValue = singleCommandRequest(cmdXML);
    //
    //
    if(trackUsage) {
        trackUsage("/rateEntry_" + entryType);
    }
    //
    //
    return retValue;
}
/** */
function rateProfile(entryId,newRate){
    var retValue = false;
    //
    //
    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
    cmdXML += "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.RateProfile\" RATEABLE_PROFILE_ID=\"" + encode64(entryId) + "\"  RATING=\""+ newRate +"\">";
    cmdXML +="</COMMAND></COMMANDS>";
    //
    //
    retValue = singleCommandRequest(cmdXML);
    //
    //
    if(trackUsage) {
        trackUsage("/rateProfile");
    }
    //
    //
    return retValue;
}

/** */
function voteEntry(entryId, entryType) {
    var retValue = false;
    //
    //
    if(!entryType) {
        entryType = "VideoEntry";
    }
    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
    cmdXML += "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.VoteEntry\" ENTRY_ID=\"" + entryId + "\" ENTRY_TYPE=\"" + entryType + "\">";
    cmdXML +="</COMMAND></COMMANDS>";
    //
    //
    retValue = singleCommandRequest(cmdXML);
    //
    //
    if(trackUsage) {
        trackUsage("/voteEntry_" + entryType);
    }
    //
    //
    return retValue;
}

/*
 * Set tag values for a specified tenduke object. <br />
 * @param targetId Id for the target object to set properties for <br />
 * @param targetType (AudioEntry, AudioEntrySet, Comment, ContactDetails, EmailAddress, Entry,  <br />
 *                    EntryEntrySet, EntrySet, Event, EventType, ImageEntry, ImageEntrySet, Link, Message,  <br />
 *                    MessageBody, MessageFolder, MessageSendData, MessageThread, PostalAddress, Profile, <br />
 *                    ProfileProfile, SummaryEvent, Tag, TelephoneNumber, VideoEntry, VideoEntrySet <br />
 * @param tagsArray The tags to tag target object with <br />
 */
function setTags(targetId, targetType, tagsArray){
    //
    //
    var retValue=false;
    //
    //
    var delimiter = ",";	
    var cmd=new Array();
    cmd[cmd.length]='<COMMANDS PROPAGATE="true">';
    cmd[cmd.length]='<COMMAND CLASS_NAME="com.tenduke.tendukecommunity.command.SetTags" ';
    cmd[cmd.length]=	'TARGET_ID="'+targetId+'" ';
    cmd[cmd.length]=	'TARGET_TYPE="'+targetType+'" ';
    cmd[cmd.length]=	'DELIMITER="'+delimiter+'" ';
    cmd[cmd.length]=	'TAGS="';
    for(var i=0; i<tagsArray.length; i++){
    	cmd[cmd.length]=	encode64(tagsArray[i])+delimiter;
    }
    cmd[cmd.length]=	'" /></COMMANDS>';
    //
    //
    retValue = singleCommandRequest(cmd.join(""));
    //
    //
    return retValue;    
}

/*
 * Delete tags in general or for a specified tenduke object. <br />
 * @param targetId Id for the target object to delete tags for, optional if the named tags should be fully deleted <br />
 * @param targetType (AudioEntry, AudioEntrySet, Comment, ContactDetails, EmailAddress, Entry,  <br />
 *                    EntryEntrySet, EntrySet, Event, EventType, ImageEntry, ImageEntrySet, Link, Message,  <br />
 *                    MessageBody, MessageFolder, MessageSendData, MessageThread, PostalAddress, Profile, <br />
 *                    ProfileProfile, SummaryEvent, Tag, TelephoneNumber, VideoEntry, VideoEntrySet <br />
 * @param tagsArray The tags to tag target object with <br />
 */
function deleteTags(targetId, targetType, tagsArray){
    //
    //
    var retValue=false;
    //
    //
    var delimiter = ",";	
    var cmd=new Array();
    cmd[cmd.length]='<COMMANDS PROPAGATE="true">';
    cmd[cmd.length]='<COMMAND CLASS_NAME="com.tenduke.tendukecommunity.command.DeleteTags" ';
    if(targetId) {
      cmd[cmd.length]=	'TARGET_ID="' + targetId + '" ';
    }
    cmd[cmd.length]=	'TARGET_TYPE="'+targetType+'" ';
    cmd[cmd.length]=	'DELIMITER="'+delimiter+'" ';
    cmd[cmd.length]=	'TAGS="';
    for(var i=0; i<tagsArray.length; i++){
    	cmd[cmd.length]=	encode64(tagsArray[i])+delimiter;
    }
    cmd[cmd.length]=	'" /></COMMANDS>';
    //
    //
    retValue = singleCommandRequest(cmd.join(""));
    //
    //
    return retValue;    
}

/*
 * Set meta text for a specified tenduke object. <br />
 * @param targetId Id for the target object to set properties for <br />
 * @param targetType (AudioEntry, AudioEntrySet, Comment, ContactDetails, EmailAddress, Entry,  <br />
 *                    EntryEntrySet, EntrySet, Event, EventType, ImageEntry, ImageEntrySet, Link, Message,  <br />
 *                    MessageBody, MessageFolder, MessageSendData, MessageThread, PostalAddress, Profile, <br />
 *                    ProfileProfile, SummaryEvent, Tag, TelephoneNumber, VideoEntry, VideoEntrySet <br />
 * @param id Id for the new metatext entry <br />
 * @param type <br />
 * @param value <br />
 * @param profileId Modifying profile Id, optional if session exists <br />
 * @param dataSetNamePrefix Name prefix for dataset
 */
function setMetaText(targetId, targetType, id, type, value, profileId, dataSetNamePrefix) {
    //
    //
    var retValue=false;
    //
    //
    var cmd=new Array();
    cmd[cmd.length]='<COMMANDS PROPAGATE="true">';	
    cmd[cmd.length]='<COMMAND CLASS_NAME="com.tenduke.tendukecommunity.command.SetObjectMetaText" ';
    if(profileId) {
        cmd[cmd.length]= ' PROFILE_ID="' + profileId + '"';
    }
    cmd[cmd.length]=	' META_TEXT_TYPE="'+type+'"';
    cmd[cmd.length]=	' OBJECT_ID="'+id+'"';
    cmd[cmd.length]=	' TARGET_ID="'+targetId+'"';
    cmd[cmd.length]=	' TARGET_TYPE="'+targetType+'"';
    if(dataSetNamePrefix){
	    cmd[cmd.length]=	' DATASET_NAME_PREFIX="'+dataSetNamePrefix+'"';
    }
    cmd[cmd.length]=	' VALUE="';
    cmd[cmd.length]=	encode64(value);
    cmd[cmd.length]=	'" /></COMMANDS>';
    //
    //
    retValue = singleCommandRequest(cmd.join(""));
    //
    //
    if(trackUsage) {
        trackUsage("/set" + type + "_" + targetType);
    }
    //
    //
    return retValue;
    
}

/*
 * Set genre relations for a specified tenduke entry object. <br />
 * Both the entry and the genres must exist for setEntryGenres to be successfull <br />
 * @param entryId Id for the target object to set genres for <br />
 * @param entryType (AudioEntry, AudioEntrySet, ImageEntry, ImageEntrySet, VideoEntry, VideoEntrySet <br />
 * @param genreIds Genres identified by genre Ids, optional if genreNames is given <br />
 * @param genreNames Genres identified by genre names, optional if genreIds is given <br />
 */
function setEntryGenres(entryId, entryType, genreIds, genreNames){
    //
    //
    var retValue=false;
    var delimiter = ",";
    //
    //
    var cmd=new Array();
    cmd[cmd.length] = '<COMMANDS PROPAGATE="true">';
    cmd[cmd.length] = '<COMMAND CLASS_NAME="com.tenduke.tendukecommunity.command.SetEntryGenres"';
    cmd[cmd.length] = ' ENTRY_ID="' + entryId + '"';
    cmd[cmd.length] = ' ENTRY_TYPE="' + entryType + '"';
    cmd[cmd.length] = ' DELIMITER="' + delimiter + '"';
    if(genreIds && genreIds.length>0) {
        cmd[cmd.length] = ' GENRE_IDS="';
        cmd[cmd.length] = genreIds.join(delimiter);
        cmd[cmd.length] = '"';
    }
    if(genreNames && genreNames.length>0) {
        cmd[cmd.length] = ' GENRE_NAMES="';
        for(var i=0; i<genreNames.length; i++){
            cmd[cmd.length] = encode64(genreNames[i]) + delimiter;
        }
        cmd[cmd.length] = '"';
    }
    cmd[cmd.length] = ' /></COMMANDS>';
    //
    //
    retValue = singleCommandRequest(cmd.join(""));
    //
    //
    return retValue;    
}

/*
 * Set properties for a specified tenduke object. <br />
 * @param targetId Id for the target object to set properties for <br />
 * @param targetType (AudioEntry, AudioEntrySet, Comment, ContactDetails, EmailAddress, Entry,  <br />
 *                    EntryEntrySet, EntrySet, Event, EventType, ImageEntry, ImageEntrySet, Link, Message,  <br />
 *                    MessageBody, MessageFolder, MessageSendData, MessageThread, PostalAddress, Profile, <br />
 *                    ProfileProfile, SummaryEvent, Tag, TelephoneNumber, VideoEntry, VideoEntrySet <br />
 * @param properties Array of parameters objects with root element name set to PROPERTY <br />
 * @param profileId Modifying profile Id, optional if session exists <br />
 */
function setProperties(targetId, targetType, properties, profileId){
    //
    //
    var retValue=false;
    //
    //
    var cmd=new Array();
    cmd[cmd.length]='<COMMANDS PROPAGATE="true">';
    cmd[cmd.length]='<COMMAND CLASS_NAME="com.tenduke.tendukecommunity.command.SetProperties"';
    if(profileId) {
        cmd[cmd.length]= ' PROFILE_ID="' + profileId + '"';
    }
    cmd[cmd.length]= ' TARGET_ID="'+targetId+'"';
    cmd[cmd.length]= ' TARGET_TYPE="' + targetType + '" ><DATA>';
    //
    //
    var cmdData = encode64("<PROPERTIES>" + properties.toXML() + "</PROPERTIES>");
    cmd[cmd.length]= cmdData;
    //
    // 
    cmd[cmd.length]= '</DATA></COMMAND>';
    cmd[cmd.length]= '</COMMANDS>';
    //
    //
    retValue = singleCommandRequest(cmd.join(""));
    //
    //
    return retValue;    
}

/**
 * Execute face recognition for an image entry. Attaches properties to the image entry
 * according to the result.
 * @param objectPath Properties instance of parameters used to create an entry in the system.
 * @param entryId Id for new or existing entry.
 * @return true for success false for failure.
 */
function findClosestMatch(objectPath, entryId) {
    //
    //
    var retValue = false;
    //
    //
    var cmdData = "";
    var cmdXML = "<COMMANDS PROPAGATE=\"false\">";
    cmdXML += "<COMMAND CLASS_NAME=\"com.tenduke.services.computervision.FindClosestMatches\"";
    cmdXML += " OBJECT_PATH=\"" + encode64(objectPath) + "\" >";
    cmdXML += "<ON_SUCCESS>";    
    cmdData += "<COMMANDS PROPAGATE=\"true\">";
        cmdData += "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.HandleFindClosestMatchResult\"";
            cmdData += " ENTRY_ID=\"" + encode64(entryId) + "\">";
        cmdData += "</COMMAND>";
    cmdData += "</COMMANDS> ";
    cmdXML += cmdData;
    cmdXML += "</ON_SUCCESS>";
    cmdXML += "</COMMAND></COMMANDS>";
    //
    //
    retValue = singleCommandRequest(cmdXML);
    //
    //
    return retValue;
}
/**
 * @param aCommentId
 * @param aTargetType
 */
function deleteComment(aCommentId,aTargetType) {
    //
    //
    var retValue = false;
    //
    //
    if(aCommentId && aTargetType){
	    var decodedCmdSet = "";
	    decodedCmdSet =  "<COMMANDS PROPAGATE=\"true\">";
	    decodedCmdSet += "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.DeleteComment\" COMMENT_ID=\"" + aCommentId + "\" TARGET_TYPE=\"" + aTargetType + "\">";
	    decodedCmdSet += "</COMMAND>";
	    decodedCmdSet += "</COMMANDS>";
	    //
	    //
	    retValue = singleCommandRequest(decodedCmdSet);
    }
    //
    //
    return retValue;
}
//
//
function UserFormat(){
	//
	//
}
//
//
//
//
UserFormat.prototype.toHTML=function(key,s){
	
	return s;
}
//
//
BBCodeFormat.prototype.configurations=null;
BBCodeFormat.prototype.bbCodes=null;
BBCodeFormat.prototype.htmlSets=null;

function BBCodeFormat(){
	BBCodeFormat.prototype.superClass.constructor.call(this);
	//
	//
	this.configurations=new Hashtable();
	var defaultConf=new Hashtable();
	defaultConf.putEntry("image",true);
	defaultConf.putEntry("link1",true);
	defaultConf.putEntry("link2",true);
	defaultConf.putEntry("link3",true);
	defaultConf.putEntry("link4",true);
	defaultConf.putEntry("bold",true);
	defaultConf.putEntry("italic",true);
	defaultConf.putEntry("underline",true);
	defaultConf.putEntry("mailto",true);
	defaultConf.putEntry("size",true);
	defaultConf.putEntry("color",true);
	this.configurations.putEntry("default",defaultConf);
	
	this.bbCodes=new Hashtable();
	this.bbCodes.putEntry("image",/\[img\](.*?)=\1\[\/img\]/g);
	this.bbCodes.putEntry("link1",/\[url=([\w]+?:\/\/[^ \\"\n\r\t<]*?)\](.*?)\[\/url\]/g);
	this.bbCodes.putEntry("link2",/\[url\]((www|ftp|)\.[^ \\"\n\r\t<]*?)\[\/url\]/g);
	this.bbCodes.putEntry("link3", /\[url=((www|ftp|)\.[^ \\"\n\r\t<]*?)\](.*?)\[\/url\]/g);
	this.bbCodes.putEntry("link4",/\[url\](http:\/\/[^ \\"\n\r\t<]*?)\[\/url\]/g);
	this.bbCodes.putEntry("bold",/\[b\](.*?)\[\/b\]/g);
	this.bbCodes.putEntry("italic",/\[i\](.*?)\[\/i\]/g);
	this.bbCodes.putEntry("underline",/\[u\](.*?)\[\/u\]/g);
	this.bbCodes.putEntry("size",/\[size=(.*?)\](.*?)\[\/size\]/g);
	this.bbCodes.putEntry("color",/\[color=(.*?)\](.*?)\[\/color\]/g);
	this.bbCodes.putEntry("mailto",/\[email\](([a-z0-9&\-_.]+?)@([\w\-]+\.([\w\-\.]+\.)?[\w]+))\[\/email\]/g);
	
	this.htmlSets=new Hashtable();
	var defaultSet=new Hashtable();
	defaultSet.putEntry("image","<img src=\"$1\" alt=\"An image\"/>");
	defaultSet.putEntry("link1","<a href=\"$1\" target=\"blank\">$2</a>");
	defaultSet.putEntry("link2","<a href=\"http://$1\" target=\"blank\">$1</a>");
	defaultSet.putEntry("link3","<a href=\"$1\" target=\"blank\">$1</a>");
	defaultSet.putEntry("link4","<a href=\"$1\" target=\"blank\">$1</a>");
	defaultSet.putEntry("bold","<strong>$1</strong>");
	defaultSet.putEntry("italic","<em>$1</em>");
	defaultSet.putEntry("underline","<span style=\"text-decoration:underline;\">$1</span>");
	defaultSet.putEntry("size","<span style=\"font-size:$1px;\">$2</span>");
	defaultSet.putEntry("color","<span style=\"color:$1;\">$2</span>");
	defaultSet.putEntry("mailto","<a href=\"mailto:$1\">$1</a>");
	this.htmlSets.putEntry("default",defaultSet);
}
//
//
copyPrototype(BBCodeFormat,UserFormat);
//
//
BBCodeFormat.prototype.superClass=UserFormat.prototype;
//
//
BBCodeFormat.prototype.toHTML=function(key,s){
	var conf=this.configurations.getEntry(key);
	if(!conf){
		conf=this.configurations.getEntry("default");
	}
	var htmlSet=this.htmlSets.getEntry(key);
	if(!htmlSet){
		htmlSet=this.htmlSets.getEntry("default");
	}
	var keys=conf.keys();
	s=s.split("\n").join("<br />");
	for(var i=0; i< keys.length; i++){
		if(conf.getEntry(keys[i])==true){
			s = s.replace(this.bbCodes.getEntry(keys[i]),htmlSet.getEntry(keys[i]));
		}
	}
	return s;
}
/** ERROR CODE FOR FILE UPLOAD */
var FORM_SUBMIT_OK = 0;
/** ERROR CODE FOR FILE UPLOAD */
var FORM_SUBMIT_CANCEL = -1;
/** ERROR CODE FOR FILE UPLOAD */
var FORM_SUBMIT_GENERAL_ERROR = -2;
/** ERROR CODE FOR FILE UPLOAD */
var FORM_SUBMIT_PREVIOUS_IS_STILL_IN_PROGRESS = -3;
/** ERROR CODE FOR FILE UPLOAD */
var FORM_SUBMIT_REQUIRES_AUTHENTICATION = -4;
/** ERROR CODE FOR FILE UPLOAD */
var FORM_SUBMIT_FILE_NOT_SUPPORTED = -5;
/** ERROR CODE FOR FILE UPLOAD */
var FORM_SUBMIT_BAD_FILE_NAME = -6;
/** ERROR CODE FOR FILE UPLOAD */
var FORM_SUBMIT_BAD_ACCOUNT_ID_FOR_SESSION = -7;
/** ERROR CODE FOR FILE UPLOAD */
var FORM_SUBMIT_RESET = -8;
/** ERROR CODE FOR FILE UPLOAD */
var FORM_SUBMIT_DB_TRANSACTIONS_FAILED = -9;
/** ERROR CODE FOR FILE UPLOAD */
var FORM_SUBMIT_BAD_FILE_TYPE = -10;
/** ERROR CODE FOR FILE UPLOAD */
var FORM_SUBMIT_NOT_ALLOWED = -11;
/** ERROR CODE FOR FILE UPLOAD */
var FORM_SUBMIT_STARTED = 1;



/** Private */
var currentUploadForms=new Hashtable();
/** Private */
var currentElementId=null;
/** Private */
var currentHandlerCommandsProvider=null;
/** Private */
var currentResponseHandler=null;
/** Private */
var uploadInProgress=false;
/** Private */
var currentAssetPath=null;
/** Private */
var currentAssetName=null;
/** Private */
var currentAssetID=null;
/** Private */
var currentAssetDisplayName=null;
/** Private */
var currentAcceptedObjectType=null;

/**
 * Inserts a file upload form into the current document within the element specified by elementID.
 * Once this method is called and it is successfull the calling context can start waiting for callbacks
 * into aResponseHandler (after the end user has started using the form and submitted it).
 *
 * Define style for:
 *          <input type="file"...
 *          <input type="submit" class="fileFormSubmit"...
 *          <input type="reset" class="fileFormSubmit"...
 * to change the appearance of the upload function.
 *
 * @param aContainerElement element in current document to generate the file upload form into.
 * @param aHandlerCommandsProvider provider for XML command to include in the form submit
 * @param aResponseHandler a function callback that will receive notifications on the upload process state and errors.
 * @param acceptedObjectType
 * @param allowUploadFieldId
 * 
 * Signature for aResponseHandler: fnc(boolean success, Object objectData, int errorCode), where:
    - success defines if the upload form submit has been interupted 
    - objectData (objectPath, objectName, objectDisplayName), for errors objectData is an informal error string
    - errorCode is a specific error status defined in this file's error values:
    FORM_SUBMIT_OK = 0
    FORM_SUBMIT_CANCEL = -1
    FORM_SUBMIT_GENERAL_ERROR = -2
    FORM_SUBMIT_PREVIOUS_IS_STILL_IN_PROGRESS = -3
    FORM_SUBMIT_REQUIRES_AUTHENTICATION = -4
    FORM_SUBMIT_FILE_NOT_SUPPORTED = -5
    FORM_SUBMIT_BAD_FILE_NAME = -6
    FORM_SUBMIT_BAD_ACCOUNT_ID_FOR_SESSION = -7
    FORM_SUBMIT_RESET = -8
    FORM_SUBMIT_DB_TRANSACTIONS_FAILED = -9
 *
 * @return void.
 */
function generateFileUploadFunction(aContainerElement, aHandlerCommandsProvider, aResponseHandler, acceptedObjectType, allowUploadFieldId, aFormTarget) {
    //
    //
    var formTarget=aFormTarget;
    if(aFormTarget==null || aFormTarget==undefined){
    	formTarget="_new";
    }
    var key=aContainerElement.getAttribute("id");
    if(currentUploadForms.getEntry(key)){
        currentUploadForms.remove(key);
    }
    var currentUploadForm=new Object();
    currentUploadForm.elementId; //==currentElementId
    currentUploadForm.handlerCommandsProvider; //==currentHandlerCommandsProvider
    currentUploadForm.responceHandler; //==currentResponseHandler
    currentUploadForm.assetPath; //==currentAssetPath
    currentUploadForm.assetName; //==currentAssetName
    currentUploadForm.assetID; //==currentAssetID
    currentUploadForm.assetDisplayName; //==currentAssetDisplayName
    currentUploadForm.acceptedObjectType; //==currentAcceptedObjectType
    currentUploadForm.allowUploadFieldId=allowUploadFieldId;
	
    currentUploadForms.putEntry(key,currentUploadForm);
	
    if(acceptedObjectType){
        currentUploadForm.acceptedObjectType=acceptedObjectType;
    }
    else{
        currentUploadForm.acceptedObjectType=null;
    }
    currentUploadForm.handlerCommandsProvider = aHandlerCommandsProvider;
    currentUploadForm.responceHandler=aResponseHandler;
    currentUploadForm.elementId = aContainerElement.id;
    //
    //
    var theContent = "<form id=\"ContentFormNewAsset_"+key+"\" action=\"/servlets/MultipartParserServlet\" method=\"post\" enctype=\"multipart/form-data\" target=\""+formTarget+"\" onsubmit=\"return formSubmitEvent('"+key+"');\" onreset=\"formResetEvent('"+key+"');\">";
    theContent += "<input name=\"MPP_CONTENT_TYPE_"+key+"\" value=\"application/octet-stream\" type=\"hidden\" ID=\"MPP_CONTENT_TYPE_"+key+"\"/>";
    theContent += "<input name=\"MPP_OBJECT_PATH_"+key+"\" value=\"\" type=\"hidden\" ID=\"MPP_OBJECT_PATH_"+key+"\"/>";
    theContent += "<input name=\"MPP_OBJECT_NAME_"+key+"\" value=\"\" type=\"hidden\" ID=\"MPP_OBJECT_NAME_"+key+"\"/>";
    theContent += "<input name=\"MPP_HANDLER_DEF_"+key+"\" value=\"\" type=\"hidden\" ID=\"MPP_HANDLER_DEF_"+key+"\"/>";
    theContent += "<input name=\"FILE_NEW_ASSET_"+key+"\" type=\"file\" />";
    theContent += "<input type=\"submit\" class=\"fileUploadFormSubmit\" onmouseover=\"this.className='fileUploadFormSubmit fileUploadFormSubmitMouseOver';\" onmouseout=\"this.className='fileUploadFormSubmit';\" id=\"Submit_"+key+"\" name=\"Submit_"+key+"\" value=\"OK\"/>";
    theContent += "<input type=\"reset\" class=\"fileUploadFormReset\" onmouseover=\"this.className='fileUploadFormReset fileUploadFormResetMouseOver';\" onmouseout=\"this.className='fileUploadFormReset';\" id=\"cancel_"+key+"\" name=\"cancel_"+key+"\" value=\"Cancel\"/>";
    theContent += "</form>";
    //
    //
    aContainerElement.innerHTML = theContent;
}

/**
 * Private: Eventhandler for a file upload form submit (defined in generateFileUploadFunction)
 */
function formSubmitEvent(key) {
    //
    //
    var currentUploadForm=currentUploadForms.getEntry(key);
    if(!currentUploadForm){
        return false;
    }
    if(currentUploadForm.allowUploadFieldId){
        var d=document.getElementById(currentUploadForm.allowUploadFieldId);
        if(d){
            if(d.value=="true" || d.value==true || d.checked=="true" || d.checked==true || d.checked=="checked"){
				
            }
            else{
                if(currentUploadForm.responceHandler){
                    currentUploadForm.responceHandler.uploadResponseHandler.call(currentUploadForm.responceHandler, false, "Sorry, we can't allow you to upload. Please check that you have correctly filled all required fields.", FORM_SUBMIT_NOT_ALLOWED);
                }
                return false;
            }
        }
    }
    if(uploadInProgress) {
        if(currentUploadForm.responceHandler){
            currentUploadForm.responceHandler.uploadResponseHandler.call(currentUploadForm.responceHandler, false, "Sorry, your previous upload has not finished", FORM_SUBMIT_PREVIOUS_IS_STILL_IN_PROGRESS);
        }
        return false;
    }
    //
    // set up emulator client and response handler
    var theForm=document.getElementById("ContentFormNewAsset_"+key);
    var fth=document.getElementById("FormTargetHandler");
    if(fth){
    	addEventToDOMNode(fth,"load",formSubmitResponse);
    	theForm.target = fth.name;
    }
    //
    //
    var loginState = isLoggedIn();
    if(loginState == false) {
        currentUploadForm.responceHandler.uploadResponseHandler.call(currentUploadForm.responceHandler, false, "Sorry, you need to be logged in to upload a file", FORM_SUBMIT_REQUIRES_AUTHENTICATION);
        uploadInProgress = false;
        return false;
    }	
    //
    // get the selected files full path on client machine
    var strVal = theForm.elements["FILE_NEW_ASSET_"+key].value;
    if(strVal==null || strVal==undefined || strVal.length<4) {
        currentUploadForm.responceHandler.uploadResponseHandler.call(currentUploadForm.responceHandler, false, "Sorry, the file name does not qualify", FORM_SUBMIT_BAD_FILE_NAME);
        uploadInProgress = false;
        return false;
    }
    //
    // create path ID for asset
    currentUploadForm.assetPath = strVal.replace(/[^A-Za-z0-9\/\\\/.]/g, "_");
    //
    //
    if(currentUploadForm.acceptedObjectType && resolveObjectType(currentUploadForm.assetPath)!=currentUploadForm.acceptedObjectType){

        var acceptedFileType = "image";
        if(currentUploadForm.acceptedObjectType==OBJECT_TYPE_VIDEO_FILE){
            acceptedFileType="video";
        }
        else if(currentUploadForm.acceptedObjectType==OBJECT_TYPE_AUDIO_FILE){
            acceptedFileType="audio";
        }
        currentUploadForm.responceHandler.uploadResponseHandler.call(currentUploadForm.responceHandler, false, "Sorry, only " + acceptedFileType + " files are accepted", FORM_SUBMIT_BAD_FILE_TYPE);
        //alert("testi");
        uploadInProgress = false;
        currentUploadForm.assetPath=null;
        currentUploadForm.acceptedObjectType=null;
        return false;
    }	
    //
    // parse display name
    var lastDelimIndex = currentUploadForm.assetPath.lastIndexOf(filePathDelimChar)+1;
    if(lastDelimIndex>0 && lastDelimIndex<currentUploadForm.assetPath.length) {
        currentUploadForm.assetDisplayName=currentUploadForm.assetPath.substring(lastDelimIndex);
    }
    else {
        currentUploadForm.assetDisplayName=strVal;
    }
    //
    // make path and name ID data sufficiently unique in account context
    var timeNow = new Date();
    var timeNowTech = timeNow.getTime();
    var lastDotIndex = currentUploadForm.assetPath.lastIndexOf(".");
    if(lastDotIndex>0) {
        var firstPart = currentUploadForm.assetPath.substring(0, currentUploadForm.assetPath.lastIndexOf("."));
        firstPart += "" + timeNowTech;
        var lastPart = currentUploadForm.assetPath.substring(currentUploadForm.assetPath.lastIndexOf("."));
        currentUploadForm.assetPath = firstPart + lastPart;
    }
    else {
        currentUploadForm.assetPath += "" + timeNowTech;
    }
    //
    // create technical name for asset
    currentUploadForm.assetName = currentUploadForm.assetPath.substring(currentUploadForm.assetPath.lastIndexOf(filePathDelimChar)+1);
    //
    // generate ID for asset (for this service we rely on accountID beeing unique, 
    // new upload automatically replaces previous)
    var accountID = getAccountID();
    currentUploadForm.assetID = "";
    if(accountID!=null && accountID!=undefined)
        currentUploadForm.assetID = accountID;
    else{
        currentUploadForm.responceHandler.uploadResponseHandler.call(currentUploadForm.responceHandler, false, "Sorry, your session is not valid", FORM_SUBMIT_BAD_ACCOUNT_ID_FOR_SESSION); 
        uploadInProgress = false;
        return false;
    }
    currentUploadForm.assetID += "." + timeNowTech;
    currentUploadForm.assetPath="/"+SERVICE_BRAND+"/ugc/"+currentUploadForm.assetName;
    //
    // Required: create base 64 encoded set of commands that define the handler tool chain to execute for uploaded asset
    var aMimeType = resolveObjectType(currentUploadForm.assetName);
    var decodedCmdSet = "";
    if(currentUploadForm.handlerCommandsProvider) {
        decodedCmdSet = currentUploadForm.handlerCommandsProvider.getHandlerCommandsXML(currentUploadForm.assetPath, currentUploadForm.assetName, aMimeType);
        //currentUploadForm.handlerCommandsProvider = null;
    }
    //
    //
    document.body.style.cursor = "wait";
    uploadInProgress = key;
    //
    // Required: set MPP_OBJECT_PATH and MPP_OBJECT_NAME values
    theForm.elements["MPP_OBJECT_PATH_"+key].value = encode64(currentUploadForm.assetPath);
    theForm.elements["MPP_OBJECT_NAME_"+key].value = encode64(currentUploadForm.assetName);
    //
    // Required: set MPP_HANDLER_DEF value (base64 encode above command set)
    theForm.elements["MPP_HANDLER_DEF_"+key].value = encode64(decodedCmdSet);
    //
    //
    currentUploadForm.responceHandler.uploadResponseHandler.call(currentUploadForm.responceHandler, true, "", FORM_SUBMIT_STARTED);
    return true;
}

/**
 * Private: Eventhandler for a file upload form reset (defined in generateFileUploadFunction)
 */
function formResetEvent(key) {
    //
    //
    document.body.style.cursor = "default";
    uploadInProgress = false;
    //
    //	
    var currentUploadForm=currentUploadForms.getEntry(key);
    if(!currentUploadForm){
        return;
    }
    if(currentUploadForm.responceHandler){
        currentUploadForm.responceHandler.uploadResponseHandler.call(currentUploadForm.responceHandler, false, "RESET", FORM_SUBMIT_RESET);
    }
    //
    //
    currentUploadForm.assetDisplayName=null;
    currentUploadForm.assetPath=null;
    currentUploadForm.assetName=null;
    currentUploadForm.assetID=null;
}

/**
 * Private: Eventhandler for a file upload form submit done
 */
function formSubmitResponse() {
    //
    //
    document.body.style.cursor = "default";
    //
    //		
    var currentUploadForm=currentUploadForms.getEntry(uploadInProgress);
    if(!currentUploadForm){
        uploadInProgress=false;
        return;
    }					   
    if(currentUploadForm.assetDisplayName!=null) {
        //
        //
        var objectData=new Object();
        objectData.objectDisplayName=currentUploadForm.assetDisplayName;
        objectData.objectPath=currentUploadForm.assetPath;
        objectData.objectName=currentUploadForm.assetName;
        //
        //		
        uploadInProgress = false;
        currentUploadForm.assetDisplayName=null;
        //
        //
        //
        currentUploadForm.responceHandler.uploadResponseHandler.call(currentUploadForm.responceHandler, true, objectData, FORM_SUBMIT_OK);		
    }
    else{
        uploadInProgress = false;
        if(currentUploadForm.responceHandler){
            currentUploadForm.responceHandler.uploadResponseHandler.call(currentUploadForm.responceHandler, false, "Sorry, internal error occured", FORM_SUBMIT_GENERAL_ERROR);		
        }
    }
    currentUploadForm.assetDisplayName=null;
    currentUploadForm.assetPath=null;
    currentUploadForm.assetName=null;
    currentUploadForm.assetID=null;
}
//
//
function requestPermanentFileDelete(anAssetPathArray, anAssetNameArray) {
    var retValue=null;
    //
    //
    var cmdXML="";
    if(anAssetPathArray && anAssetNameArray && anAssetPathArray.length==anAssetNameArray.length && anAssetPathArray.length>0) {
        cmdXML = "<COMMANDS PROPAGATE=\"true\">";
        for(var i=0; i<anAssetPathArray.length; i++) {
            cmdXML += " <COMMAND CLASS_NAME=\"com.tenduke.services.objectstorage.command.DeleteFile\"";
            cmdXML += " OBJECT_ID=\"" + encode64(anAssetPathArray[i]) + "\" OBJECT_NAME=\"" + encode64(anAssetNameArray[i]) + "\"/>";
        }
        cmdXML += "</COMMANDS>";
    }

    //
    //
    // send request
    var fileReq = initRequest("/servlets/XMLCommandServlet", "POST");
    fileReq.setRequestHeader("Content-Type", "text/xml; charset=\"UTF-8\"");
    try {
        fileReq.send(cmdXML);
    }
    catch(cmdSendE) {
        fileReq = null;
    }
    //
    //
    if (fileReq && fileReq.readyState == 4 && fileReq.status == 200 && fileReq.responseXML!=null) {
        //
        //
        var response  = fileReq.responseXML.documentElement;
        if(response) {
            //
            //
            var numOKs = 0;
            var cmdElements = response.getElementsByTagName('COMMAND');
            if(cmdElements && cmdElements.length>0) {
                var cmdElement = null;
                retValue=new Array();
                for(var i=0; i<cmdElements.length; i++) {
                    cmdElement = cmdElements[i];
                    if(cmdElement && cmdElement.getAttribute('RESULT')) {
                        var result = cmdElement.getAttribute('RESULT').toString();
                        if(result=="OK") {
                            retValue.push(true);
                            numOKs++;
                        }
                        else retValue.push(false);
                    }
                }
            }
        }
    }
    //
    //
    return retValue;
}

/*
* IMPORTS/ external dependencies
* tenduke.util.Base64
*/
/*
* Backwards compatibility support
*/
	var tenduke = tenduke || {};
	if(encode64){
		tenduke.util = tenduke.util || {};
		if(!tenduke.util.Base64){
			tenduke.util.Base64 = {};
			tenduke.util.Base64.encode64=encode64;
			tenduke.util.Base64.decode64=decode64;
		}
	}
/*
* Backwards compatibility support END
*/
/**
 * Create a new profile or update an existing one.
 * @param profileId profile to update (may be null if scenario is create).
 * @param profileParams Properties instance of parameters used to create an profile in the system (see PROFILE_REQUIRED_PROFILE_PARAMS for create scenarios).
 * @param contactParams Instance that implements signature toXML(), used to serialize payload for CreateOrUpdateProfileCommand.
 * @param personalInformationParams Properties instance of parameters used to create profile personal info.
 * @param createOrUpdateHandler a function call back to handle GUI aspects and user communication with the request and response.
 * @return true for success
 */
function createOrUpdateProfileOld(profileId, profileParams, contactParams, personalInformationParams, createOrUpdateHandler) {
    //
    //
    return createOrUpdateProfileEx(profileId, profileParams, contactParams, personalInformationParams, null, createOrUpdateHandler)
}

/**
 * Create a new profile or update an existing one and adds it optionally to a named group (group shall exist).
 * @param profileId profile to update (may be null if scenario is create).
 * @param profileParams Properties instance of parameters used to create an profile in the system (see PROFILE_REQUIRED_PROFILE_PARAMS for create scenarios).
 * @param contactParams Instance that implements signature toXML(), used to serialize payload for CreateOrUpdateProfileCommand.
 * @param personalInformationParams Properties instance of parameters used to create profile personal info.
 * @param updateByShortName If true, an existing profile with given short name is tried to be updated. If not found, a new profile is created.
 * @param addToGroupByName A group name that the profile should be added to.
 * @return true for success
 */
function getCreateOrUpdateProfileCommand(profileId, profileParams, contactParams, personalInformationParams, addToGroupByName, updateByShortName) {
    //
    //
    var cmdData = "";
    var cmdXML = "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.CreateOrUpdateProfile\"";
    if(profileId) {
        cmdXML += " PROFILE_ID=\"" + profileId + "\"";
    }
    if(addToGroupByName) {
        cmdXML += " ADD_TO_GROUP=\"" + addToGroupByName + "\"";
    }
    if(updateByShortName == true) {
        cmdXML += " UPDATE_BY_SHORT_NAME=\"true\"";
    }
    cmdXML += " >";
    cmdXML += "<DATA>";
    cmdData += "<PROFILE_DATA>";
    if(profileParams) {
        cmdData += profileParams.toXML();
    }
    if(contactParams) {
        cmdData += contactParams.toXML();
    }
    if(personalInformationParams) {
        personalInformationParams.toXML();
    }
    cmdData += "</PROFILE_DATA>";
    cmdData = tenduke.util.Base64.encode64(cmdData);
    cmdXML += cmdData;
    cmdXML += "</DATA>";
    cmdXML += "</COMMAND>";
    //
    //
    return cmdXML;
}

/**
 * Create a new profile or update an existing one and adds it optionally to a named group (group shall exist).
 * @param profileId profile to update (may be null if scenario is create).
 * @param profileParams Properties instance of parameters used to create an profile in the system (see PROFILE_REQUIRED_PROFILE_PARAMS for create scenarios).
 * @param contactParams Instance that implements signature toXML(), used to serialize payload for CreateOrUpdateProfileCommand.
 * @param personalInformationParams Properties instance of parameters used to create profile personal info.
 * @param addToGroupByName A group name that the profile should be added to.
 * @return true for success
 */
function createOrUpdateProfile(profileId, profileParams, contactParams, personalInformationParams, addToGroupByName) {
    //
    //
    var retValue = false;
    //
    //
    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
    cmdXML += getCreateOrUpdateProfileCommand(profileId, profileParams, contactParams, personalInformationParams, addToGroupByName);
    cmdXML += "</COMMANDS>";
    retValue = singleCommandRequest(cmdXML);
    cmdXML = null;
    //
    //
    return retValue;
}

/**
 * Update / set profiles status text.
 * @param profileId
 * @param aStatusText
 * @return true for success
 */
function setProfileStatusText(profileId, aStatusText) {
    //
    //
    var retValue = false;
    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
    cmdXML += "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.SetProfileStatus\"";
    if(profileId) {
        cmdXML += " PROFILE_ID\"" + profileId + "\"";
    }
    cmdXML += " STATUS_TEXT=\"" + tenduke.util.Base64.encode64(aStatusText) + "\" />";
    cmdXML += "</COMMANDS>";
    //
    //
    retValue = singleCommandRequest(cmdXML);
    //
    //
    if(trackUsage) {
        trackUsage("/setProfileStatusText");
    }
    //
    //
    cmdXML = null;
    return retValue;
}

/**
 * Makes a connect as friends request.
 * 
 */
function requestConnectAsFriends(profileSrcId, profileSrcShortName, profileSrcDisplayName, profileDstId, profileDstShortName, profileDstDisplayName, aSubject, aMessage, allowSendEmail) {
    //
    //
    var retValue = false;
    //
    //
    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
    cmdXML += "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.RequestConnectAsFriends\"";
    if(profileSrcId!=null){
    	cmdXML += " PROFILE_ID=\"" + profileSrcId + "\"";
    }
    if(profileDstId!=null){
    	cmdXML += " DST_PROFILE_ID=\"" + profileDstId + "\"";
	}    
    if(profileDstShortName!=null){
    	cmdXML += " DST_PROFILE_SHORT_NAME=\"" + profileDstShortName + "\"";
    }
  
	cmdXML += " >";
    //
    // the command contains the message spec that defines the subject and message
    if(aSubject!=null || aMessage!=null){
	    var messageId = randomUUID();
	    var messageSpec = "<MESSAGE_SPECIFICATION MESSAGE_ID=\"" + messageId + "\">";
	    if(aSubject!=null){
	    	messageSpec += "<SUBJECT>" + tenduke.util.Base64.encode64(aSubject) + "</SUBJECT>";
	   	}
	   	if(aMessage!=null){
	    	messageSpec += "<BODY>" + tenduke.util.Base64.encode64(aMessage) + "</BODY>";
	    }
	    messageSpec += "</MESSAGE_SPECIFICATION>";
	    //
	    // the email spec must be base64 encoded
	    cmdXML += tenduke.util.Base64.encode64(messageSpec);
    }
    cmdXML += "</COMMAND>";
    cmdXML += "</COMMANDS>";
    //
    //
    retValue = singleCommandRequest(cmdXML);
    if(retValue==true && allowSendEmail==true) {
        var resourceBundleIdObject = new Object();
        resourceBundleIdObject.className = SERVICE_NAMES_GENERAL_FRIENDS_BUNDLE_ID;
        var anEmailSender = getResourceString(resourceBundleIdObject, "REQUEST_CONNECT_AS_FRIENDS_SENDER");
        var anEmailSubject = getResourceString(resourceBundleIdObject, "REQUEST_CONNECT_AS_FRIENDS_SUBJECT");
        var anEmailMessage = getResourceString(resourceBundleIdObject, "REQUEST_CONNECT_AS_FRIENDS_MESSAGE");
        anEmailMessage = anEmailMessage.split("SRC_DISPLAY_NAME_INSERT").join(profileSrcDisplayName);
        anEmailMessage = anEmailMessage.split("DST_DISPLAY_NAME_INSERT").join(profileDstDisplayName);
        var anEmailMimeType = getResourceString(resourceBundleIdObject, "REQUEST_CONNECT_AS_FRIENDS__MESSAGE_TYPE");
        if(!anEmailMimeType) {
            anEmailMimeType = "text/plain";
        }
        sendEmail(new Array(profileDstShortName), anEmailSubject, anEmailMessage, anEmailMimeType, true, anEmailSender);
    }
    //
    //
    if(trackUsage) {
        trackUsage("/requestConnectAsFriends");
    }
    //
    //
    cmdXML = null;
    return retValue;    
}

/**
 * Posts a response to a connect as friends request.
 * @param requestingProfileId The original friends connect request profile id to send request to.
 * @param acceptState true | false to indicate if the request receiver aceepts becoming friends with the requester.
 * @param aSubject A subject text for the friends response message.
 * @param aMessage A message to display to the of the acknowledgement.
 */
function respondToConnectAsFriendsRequest(requestingProfileId, acceptState, aSubject, aMessage) {
    //
    //
    var retValue = false;
    //
    //
    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
    cmdXML += "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.ResponseConnectAsFriends";
    cmdXML += "\" REQUESTING_PROFILE_ID=\"" + tenduke.util.Base64.encode64(requestingProfileId);
    cmdXML += "\" ACCEPT=\"" + acceptState + "\" >";
    //
    // the command contains the message spec that defines the subject and message
    var messageId = randomUUID();
    var messageSpec = "<MESSAGE_SPECIFICATION MESSAGE_ID=\"" + messageId + "\">";
    messageSpec += "<SUBJECT>" + tenduke.util.Base64.encode64(aSubject) + "</SUBJECT>";
    messageSpec += "<BODY>" + tenduke.util.Base64.encode64(aMessage) + "</BODY>";
    messageSpec += "</MESSAGE_SPECIFICATION>";
    //
    // the email spec must be base64 encoded
    cmdXML += tenduke.util.Base64.encode64(messageSpec);
    cmdXML += "</COMMAND>";
    cmdXML += "</COMMANDS>";
    //
    //
    retValue = singleCommandRequest(cmdXML);
    //
    //
    if(trackUsage) {
        trackUsage("/respondToConnectAsFriendsRequest");
    }
    //
    //
    return retValue;
}

/**
 * Send a request to delete a friends connection.
 * @param profileId The friend to delete request profile id to send request to.
 * @param aSubject A subject text for the friends response message.
 * @param aMessage A message to display to the of the acknowledgement.
 */
function deleteFriendsConnections(profileId, aSubject, aMessage) {
    //
    //
    var retValue = false;
    //
    //
    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
    cmdXML += "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.DeleteFriendConnection";
    cmdXML += "\" FRIEND_PROFILE_ID=\"" + tenduke.util.Base64.encode64(profileId) + "\" >";
    //
    // the command contains the message spec that defines the subject and message
    var messageId = randomUUID();
    var messageSpec = "<MESSAGE_SPECIFICATION MESSAGE_ID=\"" + messageId + "\">";
    messageSpec += "<SUBJECT>" + tenduke.util.Base64.encode64(aSubject) + "</SUBJECT>";
    messageSpec += "<BODY>" + tenduke.util.Base64.encode64(aMessage) + "</BODY>";
    messageSpec += "</MESSAGE_SPECIFICATION>";
    //
    // the email spec must be base64 encoded
    cmdXML += tenduke.util.Base64.encode64(messageSpec);
    cmdXML += "</COMMAND>";
    cmdXML += "</COMMANDS>";
    //
    //
    retValue = singleCommandRequest(cmdXML);
    //
    //
    if(trackUsage) {
        trackUsage("/deleteFriendsConnections");
    }
    //
    //
    return retValue;
}

/*
 * Get XML command for setting genre relations for a specified tenduke profile object. <br />
 * Both the target profile and the genres must exist for setProfileGenres to be successfull. <br />
 * @param targetProfileId Id for the target object to set genres for <br />
 * @param genreIds Genres identified by genre Ids, optional if genreNames is given <br />
 * @param genreNames Genres identified by genre name, optional if genreIds is given <br />
 */
function getSetProfileGenresCommand(targetProfileId, genreIds, genreNames) {
    //
    //
    var delimiter = ",";
    //
    //
    var cmd=new Array();    
    cmd[cmd.length] = '<COMMAND CLASS_NAME="com.tenduke.tendukecommunity.command.SetProfileGenres"';
    cmd[cmd.length] = ' TARGET_PROFILE_ID="' + targetProfileId + '"';
    cmd[cmd.length] = ' DELIMITER="' + delimiter + '"';
    if(genreIds && genreIds.length>0) {
        cmd[cmd.length] = ' GENRE_IDS="';
        cmd[cmd.length] = genreIds.join(delimiter);
        cmd[cmd.length] = '"';
    }
    if(genreNames && genreNames.length>0) {
        cmd[cmd.length] = ' GENRE_NAMES="';
        for(var i=0; i<genreNames.length; i++){
            cmd[cmd.length] = tenduke.util.Base64.encode64(genreNames[i]) + delimiter;
        }
        cmd[cmd.length] = '"';
    }
    cmd[cmd.length] = ' />';
    //
    //
    return cmd.join("");
}
    
/*
 * Set genre relations for a specified tenduke profile object. <br />
 * Both the target profile and the genres must exist for setProfileGenres to be successfull. <br />
 * @param targetProfileId Id for the target object to set genres for <br />
 * @param genreIds Genres identified by genre Ids, optional if genreNames is given <br />
 * @param genreNames Genres identified by genre name, optional if genreIds is given <br />
 */
function setProfileGenres(targetProfileId, genreIds, genreNames) {
    //
    //
    var retValue=false;
    //
    //
    var cmd=new Array();
    cmd[cmd.length] = '<COMMANDS PROPAGATE="true">';
    cmd[cmd.length] = getSetProfileGenresCommand(targetProfileId, genreIds, genreNames);
    cmd[cmd.length] = '</COMMANDS>';
    //
    //
    retValue = singleCommandRequest(cmd.join(""));
    //
    //
    return retValue;    
}

/**
 *
 */
function getProfileNotifications(profileId, onResponseCallbackHandler, eventHandlerInstance) {
    //
    //
    var retValue=false;
    //
    //
    var cmd = new Array();
    cmd[cmd.length] = '<COMMANDS PROPAGATE="false">';
    cmd[cmd.length] = '<COMMAND CLASS_NAME="com.tenduke.tendukecommunity.command.GetProfileNotifications"';
    cmd[cmd.length] = ' PROFILE_ID="' + profileId + '"';
    cmd[cmd.length] = ' /></COMMANDS>';
    //
    //
    asyncCommandRequest(cmd.join(""), onResponseCallbackHandler, eventHandlerInstance);
    //alert(commandRequest(cmd.join(""), onResponseCallbackHandler, eventHandlerInstance));
    //
    //
    return retValue;    
}

/**
 *
 */
function getProfileDisplayNameByShortName(shortName) {
    //
    //
    commandResultXml = getProfileDataByShortName(shortName);
    //
    //
    retValue = new Properties();
    retValue.parseNode(commandResultXml);
    //
    //
    return retValue.getValue("DISPLAY_NAME");
}


/**
 * @return command ret value as string
 */
function checkShortNameAvailability(shortName) {
    //
    //
    var retValue=false;
    //
    //
    if(shortName){
	    var cmd = new Array();
	    
	    
	    cmd[cmd.length] = '<COMMANDS PROPAGATE="false">';
	    cmd[cmd.length] = '<COMMAND CLASS_NAME="com.tenduke.tendukecommunity.command.CheckAvailabilityForProfileShortName"';
	    cmd[cmd.length] = ' PROFILE_SHORT_NAME="' + tenduke.util.Base64.encode64(shortName) + '"';
	    cmd[cmd.length] = ' ENCODE_RESULT="false" /></COMMANDS>';
	    //
	    //
	    var aCommandResponse = commandRequest(cmd.join(""));
	    
	    
	    
	    if (aCommandResponse && aCommandResponse.readyState == 4 && aCommandResponse.status == 200 && aCommandResponse.responseXML!=null) {
	        var response = aCommandResponse.responseXML.documentElement;
	        if(response) {
	            var shortNameElements = response.getElementsByTagName('PROFILE_SHORT_NAME');
	            if(shortNameElements && shortNameElements.length>0) {
	                var shortNameElement = null;
	                for(var i=0; i<shortNameElements.length; i++) {
	                    shortNameElement = shortNameElements[i];
	                    if(shortNameElement && shortNameElement.getAttribute('IS_AVAILABLE')) {
	                        retValue = (shortNameElement.getAttribute('IS_AVAILABLE').toString()=="true");
	                    }
	                }
	            }
	        }
	    }
    }
    //
    //
    return retValue;    
}
/**
 * @return command ret value as string
 */
function getProfileDataByShortName(shortName) {
    //
    //
    var retValue="";
    //
    //
    if(shortName){
	    var cmd = new Array();
	    cmd[cmd.length] = '<COMMANDS PROPAGATE="false">';
	    cmd[cmd.length] = '<COMMAND CLASS_NAME="com.tenduke.tendukecommunity.command.GetProfileData"';
	    cmd[cmd.length] = ' PROFILE_SHORT_NAME="' + tenduke.util.Base64.encode64(shortName) + '"';
	    cmd[cmd.length] = ' ENCODE_RESULT="false" /></COMMANDS>';
	    //
	    //
	    retValue = commandRequest(cmd.join(""));
	    retValue=retValue.responseXML.documentElement;
    }
    //
    //
    return retValue;    
}

/**
 *
 */
function getProfileDisplayNameByProfileId(pId) {
    //
    //
    commandResultXml = getProfileDataByProfileId(pId);
    //
    //
    retValue = new Properties();
    retValue.parseNode(commandResultXml);
    //
    //
    return retValue.getValue("DISPLAY_NAME");
}

/**
 * @return command ret value as string
 */
function getProfileDataByProfileId(pId) {
    //
    //
    var retValue="";
    //
    //
    if(pId){
	    var cmd = new Array();
	    cmd[cmd.length] = '<COMMANDS PROPAGATE="false">';
	    cmd[cmd.length] = '<COMMAND CLASS_NAME="com.tenduke.tendukecommunity.command.GetProfileData"';
	    cmd[cmd.length] = ' PROFILE_ID="' + pId + '"';
	    cmd[cmd.length] = ' ENCODE_RESULT="false" /></COMMANDS>';
	    //
	    //
	    retValue = commandRequest(cmd.join(""));
	    retValue=retValue.responseXML.documentElement;
   	}
    //
    //
    return retValue;    
}// JavaScript Document
Widget.prototype.id		=	null;
Widget.prototype.parentWidget	=	null;
Widget.prototype.domContainer	=	null;
Widget.prototype.domContainerID	=	null;
Widget.prototype.visible	=	true;
Widget.prototype.isOpen		=	false;
Widget.prototype.model		=	null;
Widget.prototype.domModel	=	null;
Widget.prototype.domObject	=	null;
Widget.prototype.displayIndex	=	-1;
Widget.prototype.queryParams	=	null;
Widget.prototype.loginRequired	=	false;
Widget.prototype.stackedWidget	=	null;
Widget.prototype.contentUID	=	null;
Widget.prototype.selected	=	false;
Widget.prototype.selectionStyle	=	false;
Widget.prototype.className = null;
Widget.prototype.forceRedraw = false;


//
//
function Widget(id,domContainer,parentWidget){
	//
	//
	this.id	= id;
        if(document.widgets==null || document.widgets==undefined){
            document.widgets=new Object();	
        }
	document.widgets[this.id]	=	this;
	this.parentWidget			=	parentWidget;
	if(domContainer && (domContainer.nodeType==null || domContainer.nodeType==undefined)) {
		this.domContainerID		=	domContainer;
		this.domContainer		=	document.getElementById(domContainer);
	}
	else{
		this.domContainer		=	domContainer;	
	}
	var d=document.getElementById(this.id);
	if(d){
		this.domObject=d;
		this.isOpen=true;
	}
	var tempS=this.constructor.toString();
	this.className=tempS.substring(9,tempS.indexOf("("));
	
	//
	//
	this.events			=	new Object();
	this.events.onFocusLost		=	new Delegate();
	this.events.onFocus		=	new Delegate();
	this.events.onKeyDown		=	new Delegate();
	this.events.onKeyPress		=	new Delegate();
	this.events.onKeyUp		=	new Delegate();
	this.events.onMouseDown		=	new Delegate();
	this.events.onMouseMove		=	new Delegate();
	this.events.onMouseOut		=	new Delegate();
	this.events.onMouseOver		=	new Delegate();
	this.events.onMouseUp		=	new Delegate();
	this.events.onSelect		=	new Delegate();	
	this.events.onClick		=	new Delegate();
	this.events.onDoubleClick	=	new Delegate();
		
	this.events.onSetVisible                =	new Delegate();
	this.events.onHide                      =	new Delegate();
	this.events.onShow                      =	new Delegate();
	this.events.onOpen                      =	new Delegate();
	this.events.onClose                     =	new Delegate();
	this.events.onModelSetComplete		=	new Delegate();
	this.events.onDomModelSetComplete	=	new Delegate();
	this.events.onQueryParamsSetComplete	=	new Delegate();
	this.events.onSelectionChanged		=	new Delegate();
	
	this.events.onLoginRequired		=	new Delegate();
	this.events.onBubbleEvent		=	new Delegate();
}
Widget.prototype.generateHTML=function(){
	//alert(this.domModel==null+" "+this.domModel.innerHTML==null);
	if(!this.domModel && this.queryParams && this.queryParams.loadDomModel==true){
		if(this.queryParams.contentURL!=null){
			this.loadDomModel(this.queryParams.contentURL);
		}
	}
	if(!this.domModel){
		this.domModel=this.createDefaultDomModel();
	}
	//alert(this.id+" model "+this.domModel+" model content "+this.domModel.childNodes.length);
	var domModelStyle=this.domModel.getAttribute("style");
	if(domModelStyle && typeof domModelStyle == 'object') {
		if(domModelStyle.cssText && domModelStyle.cssText.length>3){
			domModelStyle=domModelStyle.cssText;
		}
		else{
			domModelStyle=null;
		}
	}
	if (domModelStyle){
		domModelStyle=domModelStyle.toLowerCase();
	}
	if(this.visible==false){
		if(this.originalStyleAttribute && this.originalStyleAttribute==domModelStyle){
			this.domModel.style.cssText = "display:none;visibility:hidden;";
		}
		else if(domModelStyle && (domModelStyle.indexOf("display:none")==-1 && domModelStyle.indexOf("visibility:hidden")==-1 && domModelStyle.indexOf("display: none")==-1 && domModelStyle.indexOf("visibility: hidden")==-1)){
			//alert(domModelStyle.indexOf("display:none")+" && "+domModelStyle.indexOf("visibility:hidden")+" && "+ domModelStyle.indexOf("display: none")+" && "+ domModelStyle.indexOf("visibility: hidden"));
			this.originalStyleAttribute=domModelStyle;
			this.domModel.style.cssText = "display:none;visibility:hidden;";
		}
		else{
			this.domModel.style.cssText = "display:none;visibility:hidden;";
		}
	}
	else if(domModelStyle && (domModelStyle.indexOf("display:none")!=-1 || domModelStyle.indexOf("visibility:hidden")!=-1 || domModelStyle.indexOf("display: none")!=-1 || domModelStyle.indexOf("visibility: hidden")!=-1)){
		if(this.originalStyleAttribute){
			this.domModel.style.cssText = this.originalStyleAttribute;
		}
		else{
			this.domModel.removeAttribute("style");
		}
	}
	if(this.selectionStyle!=false){
		var myClass=this.domModel.className;
		if(this.selected==true){
			myClass=this.selectionStyle+" "+myClass;
		}
		else{
			myClass=myClass.split(this.selectionStyle+" ").join("");
		}
		this.domModel.className=myClass;
	}
	return this.domModel;
}
Widget.prototype.setStackedWidget=function(widget){
	if(widget.domContainerID!=this.domContainerID){
		widget.domContainer=null;
		widget.domContainerID=this.domContainerID;
	}
	widget.events.onHide.addListener(this,this.stackedWidgetHidden);
	this.stackedWidget=widget;
	this.stackedWidget.isOpen=this.isOpen;
	this.redraw();		
}
Widget.prototype.stackedWidgetHidden=function(obj,evtObj){
	if(this.stackedWidget){
		var v=this.stackedWidget.visible;
		this.stackedWidget.close();
		this.stackedWidget=null;
		this.visible=v;
		this.redraw();
	}
}
/**
 * @param nocache
 * @param callback Called when reloadDomModel is completed. Signature: function(resultObject).
 */
Widget.prototype.reloadDomModel=function(nocache,callback){
	if(this.queryParams && this.queryParams.loadDomModel==true){
		if(this.queryParams.contentURL!=null){
            this.loadDomModel(this.queryParams.contentURL,nocache,callback);
		}
        else {
            if(callback) {
                callback({result:{widget:this,error:{message:"Content url not defined"}}});
            }
        }
	}
    else {
        if(callback) {
            callback({result:{widget:this,error:{message:"Query parameters not set, or loadDomModel not set"}}});
        }
    }
}
Widget.prototype.createDefaultDomModel=function(){
	var frag = document.createDocumentFragment();
	var theDiv=document.createElement('div');
	theDiv.setAttribute("id",this.id);
	theDiv.innerHTML='Widget: '+this.id;
	frag.appendChild(theDiv);
	return theDiv;
}
Widget.prototype.setDOMObject=function(obj){
	this.domObject=obj;
	if(obj){
		this.addSupportedDOMEventsToNode(obj);
	}
}
Widget.prototype.setLoginRequired=function(flag){
	this.loginRequired = flag;
	if(flag==true){
		//loginStateChanged.addListener(this,this.loginStateChangedEventHandler);
	}
	else{
	//	loginStateChanged.removeListener(this,this.loginStateChangedEventHandler);
	}
}

Widget.prototype.addSupportedDOMEventsToNode=function(obj){
	//this.addDOMClickEventsToNode(obj);
	//this.addDOMMouseEventsToNode(obj);
	//this.addDOMKeyEventsToNode(obj);
	//this.addDOMFocusEventsToNode(obj);
	
	//addEventToDOMNode( obj, "select", this.domNode_onSelect);
}

Widget.prototype.addDOMFocusEventsToNode=function(obj){
	addEventToDOMNode( obj, "blur", this.domNode_onFocusLost);
	addEventToDOMNode( obj, "focus", this.domNode_onFocus);
}
Widget.prototype.addDOMKeyEventsToNode=function(obj){
	addEventToDOMNode( obj, "keydown", this.domNode_onKeyDown);
	addEventToDOMNode( obj, "keypress", this.domNode_onKeyPress);
	addEventToDOMNode( obj, "keyup", this.domNode_onKeyUp);
}
Widget.prototype.addDOMMouseEventsToNode=function(obj){
	addEventToDOMNode( obj, "mousemove", this.domNode_onMouseMove);
	addEventToDOMNode( obj, "mouseout", this.domNode_onMouseOut);
	addEventToDOMNode( obj, "mouseover", this.domNode_onMouseOver);
}
Widget.prototype.addDOMClickEventsToNode=function(obj){
	addEventToDOMNode( obj, "click", this.domNode_onClick);
	addEventToDOMNode( obj, "dblclick", this.domNode_onDoubleClick);
	addEventToDOMNode( obj, "mousedown", this.domNode_onMouseDown);
	addEventToDOMNode( obj, "mouseup", this.domNode_onMouseUp);
}
//On all of the DOM event handlers the "this" keyword refers to the htmlDOM element.
Widget_getWidgetIdFromWidgetDOMNode=function(node){
	var origId=node.id;
	var id;
	var origIdSplitted;
	if(origId){
		origIdSplitted=origId.split("_");
		id=origIdSplitted[0];
	}
	else{
		//node.getAttribute("id").split("_")[0];
		while(!id){
			node=node.parentNode;
			origId=node.getAttribute("id");
			if(origId){
				origIdSplitted=origId.split("_")
				id=origIdSplitted[0];
			}
			if(node==document.body){
				return -1;
			}
		}	
	}
	
	var w=document.widgets[origId];
	while(!w && origIdSplitted.length>1){
		origIdSplitted.pop();
		w=document.widgets[origIdSplitted.join("_")];
	}
	if(w){
		return w.id;
	}
	else{
		return -1;
	}
	/*
	var w=document.widgets[id];
	if(w && w.childWidgets){
		var id2=origId.split("_")[1];
		if(w.childWidgets[id+"_"+id2]){
			id=id+"_"+id2;
		}
	}*/
	//return id;
}
Widget.prototype.toggleSelectState=function(){
	var evtobj=new Object();
		evtobj.type	=	"onSelectionChanged";
		evtobj.code	=	0;
	if(!this.id){
		var id=Widget_getWidgetIdFromWidgetDOMNode(this);
		var widget=document.widgets[id];
		if(widget.selected==true){
			evtobj.state=false;
			widget.selected=false;
		}
		else{
			evtobj.state=true;
			widget.selected=true;
		}
		if(this.selectionStyle!=false){
			widget.redraw();
		}
		widget.events.onSelectionChanged.fireEvent(widget,evtobj);
	}
	else{
		if(this.selected==true){
			evtobj.state=false;
			this.selected=false;
		}
		else{
			evtobj.state=true;
			this.selected=true;
		}
		if(this.selectionStyle!=false){
			this.redraw();
		}
		this.events.onSelectionChanged.fireEvent(this,evtobj);
		
	}
	
}
Widget.prototype.domNode_onClick=function(evt){
	var id=Widget_getWidgetIdFromWidgetDOMNode(this);
	var widget=document.widgets[id];
	var evtobj=new Object();
	evtobj.type	=	"onClick";
	evtobj.code	=	0;
	widget.events.onClick.fireEvent(widget,evtobj);
}
Widget.prototype.domNode_onDoubleClick=function(evt){
	var id=Widget_getWidgetIdFromWidgetDOMNode(this);
	var widget=document.widgets[id];
	var evtobj=new Object();
	evtobj.type	=	"onDoubleClick";
	evtobj.code	=	0;
	widget.events.onDoubleClick.fireEvent(widget,evtobj);
}
Widget.prototype.domNode_onMouseMove=function(evt){
	var id=Widget_getWidgetIdFromWidgetDOMNode(this);
	var widget=document.widgets[id];
	var evtobj=new Object();
	evtobj.type	=	"onMouseMove";
	evtobj.code	=	0;
	widget.events.onMouseMove.fireEvent(widget,evtobj);
}
Widget.prototype.domNode_onFocusLost=function(evt){
	var id=Widget_getWidgetIdFromWidgetDOMNode(this);
	var widget=document.widgets[id];
	var evtobj=new Object();
	evtobj.type	=	"onFocusLost";
	evtobj.code	=	0;
	widget.events.onFocusLost.fireEvent(widget, evtobj);
}
Widget.prototype.domNode_onFocus=function(evt){
	var id=Widget_getWidgetIdFromWidgetDOMNode(this);
	var widget=document.widgets[id];
	var evtobj=new Object();
	evtobj.type	=	"onFocus";
	evtobj.code	=	0;
	widget.events.onFocus.fireEvent(widget,evtobj);
}
Widget.prototype.domNode_onKeyDown=function(evt){
	var id=Widget_getWidgetIdFromWidgetDOMNode(this);
	var widget=document.widgets[id];
	var evtobj=new Object();
	evtobj.type	=	"onKeyDown";
	evtobj.code	=	0;
	widget.events.onKeyDown.fireEvent(widget,evtobj);
}
Widget.prototype.domNode_onKeyPress=function(evt){
	var id=Widget_getWidgetIdFromWidgetDOMNode(this);
	var widget=document.widgets[id];
	var evtobj=new Object();
	evtobj.type	=	"onKeyPress";
	evtobj.code	=	0;
	widget.events.onKeyPress.fireEvent(widget,evtobj);
}
Widget.prototype.domNode_onKeyUp=function(evt){
	var id=Widget_getWidgetIdFromWidgetDOMNode(this);
	var widget=document.widgets[id];
	var evtobj=new Object();
	evtobj.type	=	"onKeyUp";
	evtobj.code	=	0;
	widget.events.onKeyUp.fireEvent(widget,evtobj);
}
Widget.prototype.domNode_onMouseDown=function(evt){
	var id=Widget_getWidgetIdFromWidgetDOMNode(this);
	var widget=document.widgets[id];
	var evtobj=new Object();
	evtobj.type	=	"onMouseDown";
	evtobj.code	=	0;
	widget.events.onMouseDown.fireEvent(widget,evtobj);
}
Widget.prototype.domNode_onMouseOut=function(evt){
	var id=Widget_getWidgetIdFromWidgetDOMNode(this);
	var widget=document.widgets[id];
	var evtobj=new Object();
	evtobj.type	=	"onMouseOut";
	evtobj.code	=	0;
	widget.events.onMouseOut.fireEvent(widget, evtobj);
}
Widget.prototype.domNode_onMouseOver=function(evt){
	var id=Widget_getWidgetIdFromWidgetDOMNode(this);
	var widget=document.widgets[id];
	var evtobj=new Object();
	evtobj.type	=	"onMouseOver";
	evtobj.code	=	0;
	widget.events.onMouseOver.fireEvent(widget,evtobj);
}
Widget.prototype.domNode_onMouseUp=function(evt){
	var id=Widget_getWidgetIdFromWidgetDOMNode(this);
	var widget=document.widgets[id];
	var evtobj=new Object();
	evtobj.type	=	"onMouseUp";
	evtobj.code	=	0;
	widget.events.onMouseUp.fireEvent(widget,evtobj);
}
Widget.prototype.domNode_onSelect=function(evt){
	var id=Widget_getWidgetIdFromWidgetDOMNode(this);
	var widget=document.widgets[id];
	var evtobj=new Object();
	evtobj.type	=	"onSelect";
	evtobj.code	=	0;
	widget.events.onSelect.fireEvent(widget,evtobj);
}
Widget.prototype.setQueryParams=function(object){
	this.queryParams=object;	
	var eventObj=new Object();
	eventObj.type	=	"onQueryParamsSetComplete";
	eventObj.code	=	0;
	this.events.onQueryParamsSetComplete.fireEvent(this,eventObj);
}
Widget.prototype.setModel=function(model){
	this.model=model
	var eventObj=new Object();
	eventObj.type	=	"onModelSetComplete";
	eventObj.code	=	0;
	this.events.onModelSetComplete.fireEvent(this,eventObj);
}
Widget.prototype.setDomModel=function(domModel){
	this.domModel=domModel;
	var myQueryParams=null;
	if(this.domModel && this.domModel.childNodes){
		var spans=this.domModel.getElementsByTagName("span");
		var child=null;
		for(var i=0; i<spans.length; i++){
			if(spans[i].id && spans[i].id==this.id+"_JSON"){
				child=spans[i];
			}
		}
		//var child=getChildById(this.domModel,this.id+"_JSON");
		
		if(child){
			this.parseJSONAttributes(child.innerHTML);
			//child.parentNode.removeChild(child);
		}
	}
	var eventObj=new Object();
	eventObj.type	=	"onDomModelSetComplete";
	eventObj.code	=	0;
	this.events.onDomModelSetComplete.fireEvent(this,eventObj);
	if(myQueryParams){
		this.setQueryParams(myQueryParams);
	}
}
Widget.prototype.parseJSONAttributes=function(s){
	if(s){
		//var object=eval("("+s+")");
		var object=parseJSON(s);
		if(object.queryParams){
			myQueryParams=object.queryParams;
		}
		if(object.widgetAttributes){
			for(var i in object.widgetAttributes){
				this[i]=object.widgetAttributes[i];
			}
		}
		if(object.eventHandling){
			for(var i=0; i<object.eventHandling.length; i++){
				var w=document.widgets[object.eventHandling[i].handlerWidgetId];
				if(w){
					if(this.events && this.events[object.eventHandling[i].eventName]){
						if(w[object.eventHandling[i].handlerName] && this.events[object.eventHandling[i].eventName].findListener(w,w[object.eventHandling[i].handlerName])==-1){
							this.events[object.eventHandling[i].eventName].addListener(w,w[object.eventHandling[i].handlerName]);
						}
					}
				}
			}
			
		}
		return object;
	}
	return null;
}
/**
 * @param param
 * @param nocache
 * @param callback Called when reloadDomModel is completed. Signature: function(resultObject).
 */
Widget.prototype.loadDomModel=function(param,nocache,callback){
	document.body.style.cursor="wait";
    var success=false;
	var htmlText;
	if(nocache && htmlFileCache){
		htmlText=htmlFileCache.getEntry(param);
	}
	if(!htmlText){
		var regHTML;
		if(nocache){
			if(param.indexOf("?")!=-1){
				regHTML=loadFile(param+"&ts="+new Date().getTime());
			}
			else{
				regHTML=loadFile(param+"?ts="+new Date().getTime());
			}
		}
		else{
			regHTML=loadFile(param);
		}
		if(regHTML){
			var respText=regHTML.responseText;
			if(respText){
				var respSplit=respText.split('<!--content_html_split_point-->');
				if(respSplit && respSplit[1]){
					htmlText=respSplit[1];
					if(htmlFileCache){
						htmlFileCache.putEntry(param,htmlText);
					}
				}
			}
			else{
				//alert("no text");	
			}
		}
		else{
			//alert("no File");	
		}
	}
	if(htmlText){
		var d=document.createElement('div');
		var s=htmlText.split("REPLACE_WITH_ID_PREFIX").join(this.id);
		d.innerHTML=s;
		this.setDomModel(d.getElementsByTagName("div")[0]);
        success=true;
	}
	else{
		this.setDomModel(null);
	}
    //
	document.body.style.cursor="auto";
    //
    if(callback) {
        if(success==true) {
            callback({result:{widget:this,error:{message:"Dom loading failed"}}});
        }
        else {
            callback({result:{widget:this}});
        }
    }
}
Widget.prototype.getModel=function(){
	return this.model;	
}
Widget.prototype.open=function(){
	if(this.stackedWidget!=null){
		if(this.visible==true){
			this.visible=false;
		}
		this.stackedWidget.open();
	}
	var eventObj=new Object();
	eventObj.type	=	"onOpen";
	this.isOpen=true;
	eventObj.code	=	0;
	this.events.onOpen.fireEvent(this,eventObj);
	this.show();
}
Widget.prototype.show=function(){
	if(this.loginRequired==true && isLoggedIn()==false){
		var evtObj=new Object();
		evtObj.type="onLoginRequired";
		evtObj.code=0;
		this.events.onLoginRequired.fireEvent(this,evtObj,true);
	}
	if(this.stackedWidget!=null){
		if(this.visible==true){
			this.visible=false;
		}
		this.stackedWidget.show();
	}
	var eventObj=new Object();
	eventObj.type	=	"onShow";
	if(!this.domContainer && this.domContainerID){
		this.domContainer=document.getElementById(this.domContainerID);
	}
	if(this.domContainer){
		if(this.isOpen==true && this.domObject){
			try{
				this.domContainer.removeChild(this.domObject);
			}
			catch (e){
			}
			this.domObject=null;
		}
		if(this.displayIndex>-1){
			if(this.domContainer.childNodes){
				var elementNodes=new Array();
				for(var i=0; i<this.domContainer.childNodes.length; i++){
					if(this.domContainer.childNodes[i].nodeType==Node.ELEMENT_NODE){
						elementNodes.push(this.domContainer.childNodes[i]);
					}
				}
				if(elementNodes.length>this.displayIndex){
					if(elementNodes[0].id && elementNodes[0].id.indexOf("_JSON")!=-1){
						this.domContainer.insertBefore(this.generateHTML(),elementNodes[this.displayIndex+1]);
					}
					else{
						this.domContainer.insertBefore(this.generateHTML(),elementNodes[this.displayIndex]);
					}
				}
				else{
					this.domContainer.appendChild(this.generateHTML());
				}
			}
			else{
				this.domContainer.appendChild(this.generateHTML());
			}
		}
		else{
			this.domContainer.appendChild(this.generateHTML());
		}
		this.setDOMObject(document.getElementById(this.id));
		eventObj.code	=	0;
		this.events.onShow.fireEvent(this,eventObj);
		return;
	}
	eventObj.code	=	-1;
	this.events.onShow.fireEvent(this,eventObj);
}
Widget.prototype.hide=function(){
	this.isOpen=false;
	if(this.stackedWidget!=null){
		if(this.visible==true){
			this.visible=false;
		}
		this.stackedWidget.hide();
	}
	var eventObj=new Object();
	eventObj.type	=	"onHide";
	if(!this.domContainer && this.domContainerID){
		this.domContainer = document.getElementById(this.domContainerID);
	}
	if(this.domContainer && this.domObject){
		eventObj.code	=	0;
		try{
			this.domContainer.removeChild(this.domObject);
		}
		catch (e){
			eventObj.code	=	1;		
		}
		this.domObject=null;
		this.events.onHide.fireEvent(this,eventObj);
		return;
	}
	eventObj.code	=	2;
	this.events.onHide.fireEvent(this,eventObj);
}
Widget.prototype.setVisible=function(flag){
	if(this.stackedWidget!=null){
		if(this.visible==true){
			this.visible=false;
		}
		this.stackedWidget.setVisible(flag);
		return;
	}
	var eventObj=new Object();
	eventObj.type	=	"onSetVisible";
	eventObj.state	=	flag;
	if(flag==true){
		if(this.visible==false && this.isOpen==true){
			this.visible=true;
			this.redraw();
			eventObj.code	=	0;
		}
		else{
			this.visible=true;
			eventObj.code	=	1;
		} 	
	}
	else{
		if(this.isOpen==true && this.visible==true){
			this.visible=false;
			this.redraw();
			eventObj.code	=	0;
		}
		else{
			this.visible=false;
			eventObj.code	=	1;
		}
	}
	
	this.events.onSetVisible.fireEvent(this,eventObj);
	return;
}
Widget.prototype.redraw=function(){
	if(this.isOpen==true){
		this.show();
	}
}
Widget.prototype.close=function(){
	if(this.isOpen==true){
		this.hide();
	}
	if(this.stackedWidget!=null){
		this.stackedWidget.close();
	}
	var eventObj=new Object();
	eventObj.type	=	"onClose";
	eventObj.code	=	0;
	//var index=arrayIndexOf(document.widgets,this);
	document.widgets[this.id]=null;
	this.events.onClose.fireEvent(this,eventObj);        
}
Widget.prototype.getID=function(){
	return this.id;
}
Widget.prototype.getEvents=function(){
	return this.events;	
}
Widget.prototype.hasEvent=function(eventName){
	if(this.events && this.events[eventName]){
		return true;	
	}
	return false;
}
Widget.prototype.bubbleEvent=function(obj,evtObj){
	if(this.parentWidget && this.parentWidget.bubbleEvent){
		this.parentWidget.bubbleEvent.call(this.parentWidget,obj,evtObj);
	}
	var eventObj=new Object();
	eventObj.type	=	"onBubbleEvent";
	eventObj.code	=	0;
	eventObj.originalObject=obj;
	eventObj.originalEvtObject=evtObj;
	this.events.onBubbleEvent.fireEvent(this,eventObj);
}
Widget.prototype.addClassName=function(className){
    var element = document.getElementById(this.id);
    addClassNameToElement(element, className);
}
Widget.prototype.removeClassName=function(className){
    var element = document.getElementById(this.id);
    removeClassNameFromElement(element, className);
}
//
//
//
//
function ContainerWidget(id,domContainer,parentWidget){
		ContainerWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
		this.childWidgets=new Object();
}
//
//
copyPrototype(ContainerWidget,Widget);
//
//
ContainerWidget.prototype.superClass=Widget.prototype;
//
//
ContainerWidget.prototype.generateHTML=function(){
	var s=ContainerWidget.prototype.superClass.generateHTML.apply(this);
	/*if(this.childWidgets){
		for(var i in this.childWidgets){
			var child=getChildById(s,i);
			if(child){
				if(this.childWidgets[i].stackedWidget){
					child.parentNode.replaceChild(this.childWidgets[i].generateHTML(),child);
					child.parentNode.appendChild(this.childWidgets[i].stackedWidget.generateHTML());
				}
				else{
					child.parentNode.replaceChild(this.childWidgets[i].generateHTML(),child);
				}
			}
		}
	}*/
	return s;	
}
ContainerWidget.prototype.createDefaultDomModel=function(){
	var frag = document.createDocumentFragment();
	var theDiv=document.createElement('div');
	theDiv.setAttribute("id",this.id);
	frag.appendChild(theDiv);
	return theDiv;
}
ContainerWidget.prototype.setDomModel=function(domModel){
	ContainerWidget.prototype.superClass.setDomModel.call(this,domModel);
	if(this.childWidgets){
		//var divs=this.domModel.getElementsByTagName("div");
		//var d=null;
		for(var i in this.childWidgets){
			//d=null;
			/*for(var j=0; j<divs.length; j++){
				if(divs[j].id && divs[j].id==i){
					d=divs[j];
					break;
				}
			}*/
			var d=getChildById(this.domModel,i);
			if(d){
				this.childWidgets[i].setDomModel(d);
			}
		}
	}	
}
ContainerWidget.prototype.parseJSONAttributes=function(s){
	var object=ContainerWidget.prototype.superClass.parseJSONAttributes.apply(this,new Array(s));
	if(object){
		if(object.childWidgetData){
			for(var i=0; i<object.childWidgetData.length; i++){
				if(object.childWidgetData[i] && object.childWidgetData[i].id){
					var c;
					if(object.childWidgetData[i].containerId){
						c=object.childWidgetData[i].containerId;
					}
					else{
						//c=getChildById(this.domModel,object.childWidgetData[i].id);
						var divs=this.domModel.getElementsByTagName("div");
						for(var j=0; j<divs.length; j++){
							if(divs[j].id && divs[j].id==object.childWidgetData[i].id){
								c=divs[j];
								break;
							}
						}
						if(c && c.parentNode && c.parentNode.id){
							c=c.parentNode.id;
						}
					}
					if(!c){
						alert("JSON container failed at "+this.id);
					}
					else{
						var cf=eval(object.childWidgetData[i].type);
						this.childWidgets[object.childWidgetData[i].id]=new cf(object.childWidgetData[i].id,c,this);
					}
				}
			}
		}
		/*if(object.eventHandling){
			for(var i=0; i<object.eventHandling.length; i++){
				var w=document.widgets[object.eventHandling[i].handlerWidgetId];
				if(w){
					if(this.events && this.events[object.eventHandling[i].eventName]){
						if(w[object.eventHandling[i].handlerName] && this.events[object.eventHandling[i].eventName].findListener(w,w[object.eventHandling[i].handlerName])==-1){
							this.events[object.eventHandling[i].eventName].addListener(w,w[object.eventHandling[i].handlerName]);
						}
					}
				}
			}
			
		}
		*/
		return object;
	}
	return null;
}
ContainerWidget.prototype.show=function(){
	if(this.loginRequired==true && isLoggedIn()==false){
		var evtObj=new Object();
		evtObj.type="onLoginRequired";
		evtObj.code=0;
		this.events.onLoginRequired.fireEvent(this,evtObj,true);
	}
	if(this.stackedWidget!=null){
		if(this.visible==true){
			this.visible=false;
		}
		this.stackedWidget.show();
	}
	var eventObj=new Object();
	eventObj.type	=	"onShow";
	if(!this.domContainer && this.domContainerID){
		this.domContainer=document.getElementById(this.domContainerID);
	}
	if(this.domContainer){
		if(this.isOpen==true && this.domObject){
			try{
				this.domContainer.removeChild(this.domObject);
			}
			catch (e){
			}
			this.domObject=null;
		}
		if(this.displayIndex>-1){
			if(this.domContainer.childNodes){
				var elementNodes=new Array();
				for(var i=0; i<this.domContainer.childNodes.length; i++){
					if(this.domContainer.childNodes[i].nodeType==Node.ELEMENT_NODE){
						elementNodes.push(this.domContainer.childNodes[i]);
					}
				}
				if(elementNodes.length>this.displayIndex){
                                        var actualIndex=this.displayIndex;
					if(elementNodes[0].id && elementNodes[0].id.indexOf("_JSON")!=-1){
                                             actualIndex++;
					}
                                        if(actualIndex>=elementNodes.length){
                                            this.domContainer.appendChild(this.generateHTML());
                                        }
                                        else{
                                            this.domContainer.insertBefore(this.generateHTML(),elementNodes[actualIndex]);
                                        }
				}
				else{
					this.domContainer.appendChild(this.generateHTML());
				}
			}
			else{
				this.domContainer.appendChild(this.generateHTML());
			}
		}
		else{
			this.domContainer.appendChild(this.generateHTML());
		}
		this.setDOMObject(document.getElementById(this.id));
		this.showChild();
		//this.visible=true;
		eventObj.code	=	0;
		this.events.onShow.fireEvent(this,eventObj);
		return;
	}
	eventObj.code	=	-1;
	this.events.onShow.fireEvent(this,eventObj);
}
ContainerWidget.prototype.showChild=function(){
	if(this.childWidgets){
			for(var i in this.childWidgets){
				if(this.childWidgets[i]){
					var d=document.getElementById(i);//getChildById(this.domObject,i);
					var c=this.domObject;
					if(this.childWidgets[i].domContainerID){
						c=document.getElementById(this.childWidgets[i].domContainerID);//getChildById(this.domObject,this.childWidgets[i].domContainerID);
					}
					this.childWidgets[i].domContainer=c;
					if(this.childWidgets[i].stackedWidget){
						this.childWidgets[i].stackedWidget.domContainer=c;
					}
					if(d){
						this.childWidgets[i].setDOMObject(d);
						this.childWidgets[i].isOpen=true;
						if(this.childWidgets[i].showChild){
							this.childWidgets[i].showChild();
						}
						if(this.childWidgets[i].forceRedraw==true || (this.childWidgets[i].swfUrl!==null && this.childWidgets[i].swfUrl!==undefined)){// Detects all widgets that are or extend the class FlashWidget
							this.childWidgets[i].redraw();
						}
					}
					else if(this.childWidgets[i].isOpen==true){
						this.childWidgets[i].show();
					}
				}
			}
		}
}
ContainerWidget.prototype.close=function(){
	if(this.stackedWidget!=null){
		this.stackedWidget.close();
	}
	if(this.isOpen==true){
		this.hide();
	}
	if(this.childWidgets){
		for(var i in this.childWidgets){
			if(this.childWidgets[i]!=null && this.childWidgets[i]!=undefined){
				this.childWidgets[i].close();
			}
		}
	}	
	var eventObj=new Object();
	eventObj.type	=	"onClose";
	eventObj.code	=	0;
	
	document.widgets[this.id]=null;
	this.events.onClose.fireEvent(this,eventObj);
}
ContainerWidget.prototype.closeChild=function(child){
	for(var i in this.childWidgets){
		if(this.childWidgets[i]==child){
			this.childWidgets[i].close();
			this.childWidgets[i]=null;
			break;
		}
	}
}
ContainerWidget.prototype.hideAllChild=function(){
	if(this.childWidgets) {
		for(var i in this.childWidgets){
			if(this.childWidgets[i].isOpen==true){
				this.childWidgets[i].hide();
			}
		}
	}
}//
//
TabbedWidget.prototype.tabs = null;
TabbedWidget.prototype.selectedTab = null;
TabbedWidget.prototype.tabClass = "navItem";
TabbedWidget.prototype.selectedTabClass = "selectedNavItem";
//
//
function TabbedWidget(id,domContainer,parentWidget){
    TabbedWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    this.tabs=new Object();
    this.events.onTabChanged=new Delegate();
}
//
//
copyPrototype(TabbedWidget,ContainerWidget);
//
//
TabbedWidget.prototype.superClass=ContainerWidget.prototype;
/*
TabbedWidget.prototype.parseJSONAttributes=function(s){
	var obj=TabbedWidget.prototype.superClass.parseJSONAttributes.call(this,s);
	alert("TabbedWidget parseJSONAttributes");
	if(this.childWidgets && this.tabs && this.selectedTab && this.childWidgets[this.tabs[this.selectedTab]]){
	
		alert("child and tabs found");
		for(var i in this.tabs){
			var t=this.childWidgets[this.tabs[i]];
			alert(i+" "+t.isOpen+" s:"+this.selectedTab);
			if(t.isOpen==true && i!=this.selectedTab){
				t.hide();
				alert("hiding stuff");
			}
		}
		if(this.childWidgets[this.tabs[this.selectedTab]].isOpen==false){
			this.childWidgets[this.tabs[this.selectedTab]].open();
				alert("opening stuff");
		}
		
	}
	return obj;
}

TabbedWidget.prototype.show=function(){
	TabbedWidget.prototype.superClass.show.call(this);

}
*/
TabbedWidget.prototype.tabClicked=function(tab){
	var evtObj=new Object();
    evtObj.type	= "onTabChanged";
	evtObj.code	= -1;
    evtObj.selectedTab=null;
    if(this.tabs) {
        var domTab = null;
        if(this.selectedTab && this.childWidgets[this.tabs[this.selectedTab]]){
            this.childWidgets[this.tabs[this.selectedTab]].hide();
            domTab = document.getElementById(this.selectedTab);
            if(domTab){
            	var cssClass=domTab.className;
                cssClass=cssClass.split(this.selectedTabClass).join(this.tabClass);
                domTab.className=cssClass;
                if(cssClass.indexOf(this.tabClass)==-1){
                	domTab.className=cssClass+" "+this.tabClass;
                }
            }
        }
        if(this.tabs[tab] && this.childWidgets[this.tabs[tab]]){
            this.selectedTab=tab;
			evtObj.code	= 0;
    		evtObj.selectedTab=this.selectedTab;
            domTab = document.getElementById(this.selectedTab);
            if(domTab){
            	var cssClass=domTab.className;
                cssClass=cssClass.split(this.tabClass).join(this.selectedTabClass);
                domTab.className=cssClass;
                if(cssClass.indexOf(this.selectedTabClass)==-1){
                	domTab.className=cssClass+" "+this.selectedTabClass;
                }
            }
            this.childWidgets[this.tabs[tab]].open();
        }
    }
    this.events.onTabChanged.fireEvent(this,evtObj);
}
TabbedWidget.prototype.showChild=function(){
	TabbedWidget.prototype.superClass.showChild.call(this);
    /*if(this.childWidgets){
        for(var i in this.childWidgets){
            if(this.childWidgets[i]){
                if(this.childWidgets[i].isOpen==true){
                    var d=getChildById(this.domObject,i);
                    var c=this.domObject;
                    if(this.childWidgets[i].domContainerID){
                        c=getChildById(this.domObject,this.childWidgets[i].domContainerID);
                    }
                    this.childWidgets[i].domContainer=c;
                    if(this.childWidgets[i].stackedWidget){
                        this.childWidgets[i].stackedWidget.domContainer=c;
                    }
                    if(d){
                        this.childWidgets[i].setDOMObject(d);
                        this.childWidgets[i].isOpen=true;
                        if(this.childWidgets[i].showChild){
                            this.childWidgets[i].showChild();
                        }
                    }
                    else if(this.childWidgets[i].isOpen==true){
                        this.childWidgets[i].show();
                    }
                }
            }
        }*/
      	if(this.childWidgets && this.tabs && this.selectedTab && this.childWidgets[this.tabs[this.selectedTab]]){
		for(var i in this.tabs){
				var t=this.childWidgets[this.tabs[i]];
				if(i!=this.selectedTab){
					t.hide();
					//t.redraw();
				}
			}
			if(this.childWidgets[this.tabs[this.selectedTab]].isOpen==false){
				this.childWidgets[this.tabs[this.selectedTab]].open();
			}
			
		}
    //}
}//
//
FlashWidget.prototype.swfUrl=null;
FlashWidget.prototype.flashVars=null;
FlashWidget.prototype.defaultFlashParams=null;
FlashWidget.prototype.flashContainerID=null;
FlashWidget.prototype.movie=null;
FlashWidget.prototype.flashVersion="8.0.0";
FlashWidget.prototype.useExpressInstall=true;
FlashWidget.prototype.expressInstallSwf="flash/expressinstall.swf";

//
//
function FlashWidget(id,domContainer,parentWidget){
    //
    //
    FlashWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //
    this.flashContainerID = this.id+"_swf";
    this.defaultFlashParams = new Object();
    this.defaultFlashParams["allowfullscreen"] = "false";
    this.defaultFlashParams["allowScriptAccess"] = "always";
    this.defaultFlashParams["allowNetworking"] = "all";
    this.defaultFlashParams["wmode"] = "transparent";
    this.defaultFlashParams["redirectUrl"] = "http://www.macromedia.com/go/getflashplayer";
    //
    //
    this.flashVars=new Object();
	
}
//
//
copyPrototype(FlashWidget,Widget);
//
//
FlashWidget.prototype.superClass=Widget.prototype;
//
//
FlashWidget.prototype.setFlashVars=function(obj){
    this.flashVars=obj;
}
FlashWidget.prototype.setFlashVar=function(name,value){
    if(!this.flashVars){
        this.flashVars=new Object();
    }
    this.flashVars[name]=value;
}
FlashWidget.prototype.setFlashParam=function(name,value){
    if(!this.defaultFlashParams){
        this.defaultFlashParams=new Object();
    }
    this.defaultFlashParams[name]=value;
}
FlashWidget.prototype.setSwfUrl=function(url){
    this.swfUrl=url;
}
FlashWidget.prototype.show=function(){
    FlashWidget.prototype.superClass.show.apply(this);
    this.embedFlashPlayer();
}
FlashWidget.prototype.hide=function(){
    FlashWidget.prototype.superClass.hide.apply(this);
}
FlashWidget.prototype.removeFlashPlayer=function(){
    /**
	* swfObject 2.1 implements this
	* swfobject.removeSWF(this.flashContainerID);
	* implementing the same functionality here. The following code can be replace with the above line once swfObject isupdated.
	*/
    try{
        var obj = document.getElementById(this.flashContainerID);
        if(!obj){
            obj=this.movie;
        }
        if (obj && (obj.nodeName == "OBJECT" || obj.nodeName == "EMBED")) {
            if(navigator.appName.indexOf("Microsoft") != -1) {
                for (var i in obj) {
                    if (typeof obj[i] == "function") {
                        obj[i] = null;
                    }
                }
                obj.parentNode.removeChild(obj);
            }
            obj.parentNode.removeChild(obj);
        }
    }
    catch(e){}
}
FlashWidget.prototype.embedFlashPlayer=function(){
    //alert("embed flash");
    /*var myDOM = document.getElementById(this.id);
	if(myDOM){
		myDOM.parentNode.replaceChild(this.createDefaultDomModel(),myDOM);
		alert("replaced");
	}*/
    var container=document.getElementById(this.flashContainerID);
	
    var d = this.createDefaultDomModel();
    if(container){
        try {
            container.parentNode.replaceChild(d.firstChild,container);
        }
        catch(e) {
        }
    }
    else{
        container=document.getElementById(this.id);
        if(container){
            container.appendChild(d);
        }
        else{
            return;
        }
    }
	
	
    //alert(this.id+", "+document.getElementById(this.id));
    /*
	var so = new SWFObject(this.swfUrl,this.id+"_swf",this.flashVars["width"],this.flashVars["height"],this.flashVersion);
	for(var i in this.defaultFlashParams){
		so.addParam(i,this.defaultFlashParams[i]);	
	}
	for(var i in this.flashVars){
		//alert(i+": "+this.defaultFLVVars[i]);
		if(this.flashVars[i]!=null){
			so.addVariable(i,this.flashVars[i]);	
		}
	}*/
    var expressInstallSwfurl=null;
    if(this.useExpressInstall && this.expressInstallSwf){
        //so.useExpressInstall(this.expressInstallSwf);
        expressInstallSwfurl=this.expressInstallSwf;
    }
	
    if(!this.flashVars["id"]){
        //so.addVariable("id",this.id+"_swf");
        this.flashVars["id"]=this.id+"_swf";
    }
    /*
		so.write(this.flashContainerID);
	*/
    //var obj={id:this.id+"_swf"};

    /*
	var frame=document.createElement("iframe");
	frame.setAttribute("src","javascript:false"); 
	frame.setAttribute("style","position: absolute; top: 110px; left: 220px; display: none; width: 102px; height: 32px; z-index: 5;");	
	frame.setAttribute("id",this.flashContainerID+"iframeHack");
	frame.setAttribute("frameborder","0");
	frame.setAttribue("scrolling","no");
	document.body.appendChild(frame);
	*/
    if(this.defaultFlashParams){
        this.defaultFlashParams.flashvars=undefined;
    }
    swfobject.embedSWF(this.swfUrl, this.flashContainerID, this.flashVars["width"], this.flashVars["height"], this.flashVersion, expressInstallSwfurl, this.flashVars, this.defaultFlashParams);
    if(navigator.appName.indexOf("Microsoft") != -1) {
        //alert("IE");
        this.movie = window[this.id+"_swf"];
    //alert("this.movie: "+this.movie);
    } else {
        this.movie = document[this.id+"_swf"];
    }
	
//alert("flash embedded");
}
FlashWidget.prototype.createDefaultDomModel=function(){
    var frag = document.createDocumentFragment();
    var theDiv=document.createElement('div');
    theDiv.setAttribute("id",this.id);
    theDiv.innerHTML="<div id=\""+this.id+"_swf\"><strong>You need a flash player to view content</strong><a href=\"http://www.adobe.com/go/getflashplayer\">Get Flash!</a></div>";
    //theDiv.setAttribute("onmouseover","var d=document["+this.id+"_swf];if(d){d.focus();}");
    frag.appendChild(theDiv);
    return theDiv;
}//
//
SelectableListWidget.prototype.SELECTION_TYPE_ADD=0;
SelectableListWidget.prototype.SELECTION_TYPE_REMOVE=1;
//
//
SelectableListWidget.prototype.selectedItems=null;
SelectableListWidget.prototype.isMultiSelect=true;

function SelectableListWidget(id,domContainer,parentWidget){
    //
    //
    SelectableListWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
	//
	//
	this.events.onSelectionListChanged=new Delegate();
   	
}

/** ImageWidget initialize prototype */
copyPrototype(SelectableListWidget,ContainerWidget);
/** ImageWidget class hierarchy */
SelectableListWidget.prototype.superClass=ContainerWidget.prototype;
//
//
SelectableListWidget.prototype.loadDomModel=function(param,nocache){
	this.clearSelection();
	SelectableListWidget.prototype.superClass.loadDomModel.call(this,param,nocache);
	
}
SelectableListWidget.prototype.show=function(){
	SelectableListWidget.prototype.superClass.show.call(this);
	if(this.selectedItems && this.selectedItems.length>0){
		for(var i=0; i<this.selectedItems.length; i++){
			var w=this.childWidgets[this.selectedItems[i].widgetId];
			if(w){
				if(w.selected==false){
					w.toggleSelectState();
				}
			}
		}
	}
}
SelectableListWidget.prototype.parseJSONAttributes=function(s){
	var object=SelectableListWidget.prototype.superClass.parseJSONAttributes.apply(this,new Array(s));
	if(object){
		if(object.childWidgetData){
			for(var i=0; i<this.childWidgets.length; i++){
				this.childWidgets[i].events.onSelectionChanged.addListener(this,this.childSelectionChanged);
			}
		}
	}
	return object;
}
SelectableListWidget.prototype.childSelectionChanged=function(obj, evtObj){
	if(evtObj.code==0){
		if(evtObj.state==true){
			if(this.isSelected(obj)==false){
				if(this.isMultiSelect==false){
					this.clearSelection();
				}
				this.selectItem(obj);
			}
		}
		else{
			if(this.isSelected(obj)==true){
				this.deSelectItem(obj);
			}
		}
	}
}
SelectableListWidget.prototype.clearSelection=function(){
	if(this.selectedItems){
		this.deSelectItems(this.selectedItems);
	}
}
SelectableListWidget.prototype.getSelectedItems=function(){
	return this.selectedItems;
}
SelectableListWidget.prototype.getSelectedWidgets=function(){
	var w=new Array();
	if(this.selectedItems && this.selectedItems.length>0){
		for(var i=0; i<this.selectedItems.length; i++){
			if(this.selectedItems[i].widgetId){
				w[w.length]=this.childWidgets[this.selectedItems[i].widgetId];
			}
		}
	}
	return w;
}
SelectableListWidget.prototype.getSelectedItem=function(){
	if(!this.selectedItems){
		return null;
	}
	return this.selectedItems[0];
}
SelectableListWidget.prototype.selectItems=function(array){
	for(var i=0; i<array.length; i++){
		this.selectItem(array[i]);
	}
}
SelectableListWidget_delayedToggleSelection=function(params){
	setTimeout("SelectableListWidget_toggleSelection('"+params+"')",1);
}
SelectableListWidget_toggleSelection=function(params){
	var s=params.split(",");
	if(s && s.length>1){
		var f=document.widgets[s[0]];
		var i=document.widgets[s[1]];
		if(f && i){
			f.toggleSelection(i);
		}
	}
}
SelectableListWidget.prototype.toggleSelection=function(item){
	if(!item.className){
		item=this.childWidgets[item];
	}
	if(item){
		if(this.isSelected(item)>=0){
			this.deSelectItem(item);
		}
		else{
			this.selectItem(item);
		}
	}
}
SelectableListWidget.prototype.selectItem=function(item){
	
	var sItem=new Object();
	sItem.contentUID=item.contentUID;
	sItem.widgetId=item.id;
	var eventObj		= 	new Object();
	if(this.isMultiSelect==false){
		this.clearSelection();
	}
	if(!this.selectedItems){
		this.selectedItems=new Array();
	}
	if(this.selectedItems.length>0){
		var ind=this.isSelected(item);
		if(ind>=0){
			eventObj.code	=	1;
		}
		else{
			eventObj.code	=	0;
			this.selectedItems.push(sItem);
		}
	}
	else{
		this.selectedItems.push(sItem);
	}
	if(item.selected==false){
		item.toggleSelectState();
	}
	eventObj.type	=	"onSelectionListChanged";
	
	eventObj.selectionItem	=	item;
	eventObj.selectionType	= this.SELECTION_TYPE_ADD;
	//var index=arrayIndexOf(document.widgets,this);
	this.events.onSelectionListChanged.fireEvent(this,eventObj);	
}
SelectableListWidget.prototype.deSelectItems=function(array){
	var items=new Array();
	for(var i in array){
		var obj=array[i];
		items[i]=obj;
	}
	for(var i in items){
		this.deSelectItem(items[i]);
	}
}
SelectableListWidget.prototype.deSelectItem=function(item){
	var eventObj		= 	new Object();
	if(this.selectedItems && this.selectedItems.length>0){
		var ind=this.isSelected(item);
		if(ind>=0){
			var w;
			if(item.id){
				w=item;
			}
			else{
				w=document.widgets[item.widgetId];
			}
			if(w && w.selected==true){
				w.toggleSelectState();
			}
			this.selectedItems.splice(ind,1);
			eventObj.code	=	0;
		}
		else{
			eventObj.code	=	1;
		}
	}
	
	eventObj.type			=	"onSelectionListChanged";
	eventObj.selectionItem	=	item;
	eventObj.selectionType	= this.SELECTION_TYPE_REMOVE;
	//var index=arrayIndexOf(document.widgets,this);
	this.events.onSelectionListChanged.fireEvent(this,eventObj);	
}
SelectableListWidget.prototype.isSelected=function(item){
	var retVal=-1;
	if(this.selectedItems){
		for(var i=0; i<this.selectedItems.length; i++){
			if(this.selectedItems[i] && this.selectedItems[i].contentUID==item.contentUID){
				retVal=i;
				break;
			}
		}
	}
	return retVal;
}

//
//
function LoginWidget(id,domContainer,parentWidget){
    LoginWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    loginStateChanged.addListener(this,this.loginStateChangedEventHandler);
}
//
//
copyPrototype(LoginWidget,Widget);
//
//
LoginWidget.prototype.superClass=Widget.prototype;
//
//
LoginWidget.prototype.generateHTML=function(){
    this.domModel=LoginWidget.prototype.superClass.generateHTML.apply(this);
    var d=this.domModel.getElementsByTagName("div");
    var d1;
    var d0;
    for(var i=0; i<d.length; i++){
        if(d[i].getAttribute("id")==this.id+"_state_1"){
            d1=d[i];
        }
        else if(d[i].getAttribute("id")==this.id+"_state_0"){
            d0=d[i];
        }
        if(d1 && d0){
            break;
        }
    }
    if(d1 && d0){
        if(isLoggedIn()==true){
            d1.className=this.state1class;
            d0.className="hidden";
            hideElement(d0);
            showElement(d1);
        }
        else{
            d1.className="hidden";
            hideElement(d1);
            d0.className=this.state0class;
            showElement(d0);
        }
    }
    return this.domModel;
}
LoginWidget.prototype.setDomModel=function(d){
    LoginWidget.prototype.superClass.setDomModel.call(this,d);
    this.state1class="";
    this.state0class="";
    var d1=getChildById(d,this.id+"_state_1");
    var d0=getChildById(d,this.id+"_state_0");
    if(d1){
        this.state1class=d1.className.split("hidden").join("");
    }
    if(d0){
        this.state0class=d0.className.split("hidden").join("");
    }
}
LoginWidget.prototype.createDefaultDomModel=function(){
    var frag = document.createDocumentFragment();
    var theDiv=document.createElement('div');
    theDiv.setAttribute("id",this.id);
		
    var t=new Array();
    t[t.length]='<label for="';
    t[t.length]=	this.id;
    t[t.length]=	'_userNameInput">email:</label><input type="text" id="';
    t[t.length]=	this.id;
    t[t.length]=	'_userNameInput" name="';
    t[t.length]=	this.id;
    t[t.length]=	'_userNameInput" /><label for="'
    t[t.length]=	this.id;
    t[t.length]=	'_pwdInput">password:</label><input type="password" id="';
    t[t.length]=	this.id;
    t[t.length]=	'_pwdInput" name="';
    t[t.length]=	this.id;	
    t[t.length]=	'_pwdInput" onkeydown="var key=(event.which) ? event.which : event.keyCode;if(key && key==13){document.widgets[\''+this.id+'\'].loginButtonClicked();return false;}return true;"/><input id="';
    t[t.length]=	this.id;
    t[t.length]=	'_loginButton" name="';
    t[t.length]=	this.id;
    t[t.length]=	'_loginButton" type="button" value="Login" onclick="var w=document.widgets[\''+this.id+'\']; w.loginButtonClicked();"/>';
    theDiv.innerHTML=t.join("");
    frag.appendChild(theDiv);
    return theDiv;
}
LoginWidget.prototype.loginButtonClicked = function(userNameValue, passwordValue){
    //
    //
    var userName = userNameValue;
    var password = passwordValue;
    //
    //
    if( userName==null || userName==undefined || password==null || password==undefined ) {
        //
        //
        var userNameInput=document.getElementById(this.id+'_userNameInput');
        var pwdInput=document.getElementById(this.id+'_pwdInput');
        //
        //
        if(userNameInput && pwdInput){
            userName = userNameInput.value;
            password = pwdInput.value;
            pwdInput.value="";
        }
    }
    //
    //
    if( userName!=null && userName!=undefined && password!=null && password!=undefined ) {
        login(userName, password,defaultLoginResultHandler);
    }
}
LoginWidget.prototype.logoutButtonClicked=function(){
    logout(defaultLogoutResultHandler);
}
LoginWidget.prototype.loginStateChangedEventHandler=function(object,evtObject){
    /*if((""+window.location.href).indexOf("openSiteIndex")!=-1){
		openNewsFeedPage();
	}*/
    this.redraw();
}
//
//
function NaviBarWidget(id,domContainer,parentWidget){
	NaviBarWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
}
//
//
copyPrototype(NaviBarWidget,Widget);
//
//
NaviBarWidget.prototype.superClass=Widget.prototype;
//
//
UploadWidget.prototype.toolIsActive=true;
UploadWidget.prototype.handlerCommandsProvider=null;
UploadWidget.prototype.autoPublish=true;
UploadWidget.prototype.acceptedObjectType="";
UploadWidget.prototype.displayNameInputFieldIdPostfix = "DisplayNameField";
UploadWidget.prototype.descriptionInputFieldIdPostfix = "DescriptionField";
UploadWidget.prototype.tagInputFieldIdPostfix = "TagField";
UploadWidget.prototype.formTarget=null;
UploadWidget.prototype.relatedProfiles=null;


/** */
function UploadWidget(id,domContainer,parentWidget){
    //
    //
    UploadWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //
    this.events.onUploadStarted = new Delegate();
    this.events.onUploadDone    = new Delegate();
    this.events.onUploadFailed  = new Delegate();
}

/** */
copyPrototype(UploadWidget, Widget);
/** */
UploadWidget.prototype.superClass = Widget.prototype;

/** */
UploadWidget.prototype.generateHTML=function(){
    //
    //
    var s = UploadWidget.prototype.superClass.generateHTML.apply(this);
    //
    //
    var fileUploadControl = getChildById(s, this.id + "_fileInput");
	
    //
    //
//    if(this.toolIsActive) {
//        if(fileUploadControl) fileUploadControl.removeAttribute("class");
//	
//    }
//    else {
//        if(fileUploadControl) fileUploadControl.className = "hidden";
//    }
    //
    //
    this.toolIsActive = true;
    //
    //
    return s;	
}


/** */
UploadWidget.prototype.createDefaultDomModel=function(){
    //
    var frag = document.createDocumentFragment();
    //
    //
    var thisWidgetDiv=document.createElement('div');
    thisWidgetDiv.setAttribute("id", this.id);
    //
    //
    var uploadControlDiv=document.createElement('div');
    uploadControlDiv.setAttribute("id",this.id+"_fileInput");
    thisWidgetDiv.appendChild(uploadControlDiv);
    //
    //
    var statusMessageDiv=document.createElement('div');
    statusMessageDiv.setAttribute("id",this.id+"_uploadResult");
    thisWidgetDiv.appendChild(statusMessageDiv);
    //
    //
    generateFileUploadFunction(uploadControlDiv, this, this, this.acceptedObjectType, this.id+"_allowUploadFieldId", this.formTarget);
    frag.appendChild(thisWidgetDiv);
    return thisWidgetDiv;
}


/**
 * Sets handle to an instance that can provide for handling command associated 
 * with the upload receiver on the back end.
 */
UploadWidget.prototype.setHandlerCommandsProvider=function(aProvider) {
    this.handlerCommandsProvider = aProvider;
}

/**
 * Get the current provider for file manipulation commands.
 */
UploadWidget.prototype.getHandlerCommandsProvider=function() {
    var retVal=this.handlerCommandsProvider;
    if(!retVal){
        retVal=null;
    }
    return retVal;
}

/**
 * Default implementation does nothing.
 */
UploadWidget.prototype.getHandlerCommandsXML=function(anAssetPath, anAssetName, aMimeType) {
    //
    //
    var retValue=null;
    if(this.getHandlerCommandsProvider()==null){
        retValue=this.getDefaultHandlerCommandsXML(anAssetPath, anAssetName, aMimeType);
    }
    else{
        retValue= this.getHandlerCommandsProvider().getHandlerCommandsXML(anAssetPath, anAssetName, aMimeType);
    }
    if(retValue && retValue.indexOf("<COMMANDS>")!=0){
        retValue="<COMMANDS>"+retValue+"</COMMANDS>";
    }
    //
    //
    return retValue;
}
//
//
UploadWidget.prototype.addEntryToEntrySet = function(entryId, entrySetId) {
    alert("Fix widget configuration: UploadWidget.addEntryToEntryEntrySet used from base class implementation.");
}//
//
var IMAGE_FILE_POSTFIX=".default.jpeg";
ImageUploadWidget.prototype.imageWidth = 640;
ImageUploadWidget.prototype.imageHeight = 480;
ImageUploadWidget.prototype.imageThumbnailWidth = 120;
ImageUploadWidget.prototype.imageThumbnailHeight = 80;
ImageUploadWidget.prototype.hideOnComplete = false;
ImageUploadWidget.prototype.displayName = null;
ImageUploadWidget.prototype.description = null;



/** */
function ImageUploadWidget(id,domContainer,parentWidget){
    //
    //
    ImageUploadWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //
    this.acceptedObjectType=OBJECT_TYPE_IMAGE_FILE;
}

/** */
copyPrototype(ImageUploadWidget, UploadWidget);
/** */
ImageUploadWidget.prototype.superClass = UploadWidget.prototype;

/**
 * Set the behavior of this widget for managing display state once the
 * upload has completed (or form has been reset). If specified as true 
 * then the widget will hide itself on transaction complete.
 * @param hideEnabled
 */
ImageUploadWidget.prototype.setHideOnComplete = function(hideEnabled) {
    this.hideOnComplete = hideEnabled;
}

/** 
 * Provides serialization of two commands by given objetc path, object name (and mime type): 
 * 1. scale to large size by instance attribures imageWidth and imageHeight values.
 * 2. scale to thumbnail size by instance attribures imageThumbnailWidth and imageThumbnailHeight values.
 * 
 * @param anAssetPath The object path of the uploaded image.
 * @param anAssetName The object name of the uploaded image.
 * @param aMimeType The mime type of the uploaded image.
 * @return command xml without enclosing <COMMANDS> element.
 */
ImageUploadWidget.prototype.getDefaultHandlerCommandsXML=function(anAssetPath, anAssetName, aMimeType) {
    var decodedCmdSet = new Array();
    decodedCmdSet[decodedCmdSet.length] = "<COMMAND CLASS_NAME=\"com.tenduke.services.multimediatranscoder.ScaleImage\"";
    decodedCmdSet[decodedCmdSet.length] = " OBJECT_PATH=\"" + encode64(anAssetPath) + "\"";
    decodedCmdSet[decodedCmdSet.length] = " OBJECT_NAME=\"" + encode64(anAssetName) + "\"";
    decodedCmdSet[decodedCmdSet.length] = " OUTPUT_PATH=\"" + encode64(anAssetPath+IMAGE_FILE_POSTFIX) + "\"";
    decodedCmdSet[decodedCmdSet.length] = " OUTPUT_NAME=\"" + encode64(anAssetName+IMAGE_FILE_POSTFIX) + "\"";
    decodedCmdSet[decodedCmdSet.length] = " WIDTH=\"" + this.imageWidth + "\"";
    decodedCmdSet[decodedCmdSet.length] = " HEIGHT=\"" + this.imageHeight + "\"";
    decodedCmdSet[decodedCmdSet.length] = " PRESERVE_ASPECT=\"true\"";
    decodedCmdSet[decodedCmdSet.length] = " IS_ENCODED=\"true\"";
    decodedCmdSet[decodedCmdSet.length] = "/>";
    decodedCmdSet[decodedCmdSet.length] = "<COMMAND CLASS_NAME=\"com.tenduke.services.multimediatranscoder.ScaleImage\"";
    decodedCmdSet[decodedCmdSet.length] = " SUCCESS_DEPENDENCY_CHAIN=\"1\"";
    decodedCmdSet[decodedCmdSet.length] = " OBJECT_PATH=\"" + encode64(anAssetPath) + "\"";
    decodedCmdSet[decodedCmdSet.length] = " OBJECT_NAME=\"" + encode64(anAssetName) + "\"";
    decodedCmdSet[decodedCmdSet.length] = " OUTPUT_PATH=\"" + encode64(anAssetPath + THUMB_FILE_POSTFIX) + "\"";
    decodedCmdSet[decodedCmdSet.length] = " OUTPUT_NAME=\"" + encode64(anAssetName + THUMB_FILE_POSTFIX) + "\"";
    decodedCmdSet[decodedCmdSet.length] = " WIDTH=\"" + this.imageThumbnailWidth + "\"";
    decodedCmdSet[decodedCmdSet.length] = " HEIGHT=\"" + this.imageThumbnailHeight + "\"";
    decodedCmdSet[decodedCmdSet.length] = " PRESERVE_ASPECT=\"true\"";
    decodedCmdSet[decodedCmdSet.length] = " IS_ENCODED=\"true\"";
    decodedCmdSet[decodedCmdSet.length] = "/>";
    return decodedCmdSet.join("");
}

/** */
ImageUploadWidget.prototype.uploadResponseHandler = function(successState, objectData, resultCode) {
    //
    //
    var evtobj = new Object();
    evtobj.code	= resultCode;
    evtobj.storedObjectData = objectData;
    if(successState==true){
        //
        //	
        if(resultCode==FORM_SUBMIT_STARTED){	
            //
            //
            this.toolIsActive = false;
            //
            //
            var displayNameInput = document.getElementById(this.id + this.displayNameInputFieldIdPostfix);
            if(displayNameInput && displayNameInput.value) {
                this.displayName = displayNameInput.value;                
            }
            var descriptionInput = document.getElementById(this.id + this.descriptionInputFieldIdPostfix);
            if(descriptionInput && descriptionInput.value) {
                this.description = descriptionInput.value;                
            }
            
            var tagInput = document.getElementById(this.id + this.tagInputFieldIdPostfix);
            if(tagInput && tagInput.value) {
                var tagString = tagInput.value;                
                this.tags=TagWidget.prototype.parseTagsFromString(tagString);
            }
            //
            //
            evtobj.type	= "onUploadStarted";
            this.events.onUploadStarted.fireEvent(this, evtobj);
        }
        else{
            //
            //
            this.toolIsActive = true;
            //
            // 1. build notification (image uploaded OK)
            var principalName = getAccountID();
            var imageUrl = SERVICE_WWW_ROOT + "servlets/View/" + principalName + "/" + encode64(objectData.objectPath);
            var defaultImageUrl = SERVICE_WWW_ROOT + "servlets/View/" + principalName + "/" + encode64(objectData.objectPath + IMAGE_FILE_POSTFIX);
            var thumbUrl = SERVICE_WWW_ROOT + "servlets/View/" + principalName + "/" + encode64(objectData.objectPath+THUMB_FILE_POSTFIX);
            evtobj.type	=	"onUploadDone";			
            evtobj.fileAssetURL	= imageUrl;
            evtobj.defaultImageUrl	= defaultImageUrl;
            evtobj.thumbAssetURL	= thumbUrl;			
            //
            // 2. prepare adding the db entry
            var entryParams = new Properties();
            entryParams.setParametersAreEncoded(true);
            entryParams.setRootElementName("ENTRY");
            var entryId = randomUUID();
            evtobj.entryId = entryId;
            entryParams.setValue("ENTRY_ID", entryId);
            entryParams.setValue("OBJECT_PATH", objectData.objectPath);
            entryParams.setValue("OBJECT_NAME", objectData.objectName);
            if(!this.displayName)
              this.displayName = objectData.objectDisplayName;
            entryParams.setValue("DISPLAY_NAME", this.displayName);
            //
            //
            if(!this.description)
                this.description = "";
            entryParams.setValue("DESCRIPTION", this.description);
            entryParams.setValue("IS_PUBLIC", "" + this.autoPublish);
            //
            // 3. request write entry to db
            createOrUpdateEntry(entryParams, "ImageEntry", entryId, this.relatedProfiles);
            if(this.tags){
            	setTags(entryId, "ImageEntry", this.tags);
            }
            //
            // 4. notify listeners
            this.events.onUploadDone.fireEvent(this, evtobj);
            //
            // 5. update gui state
            if(true == this.hideOnComplete) {
                //
                //
                this.toolIsActive = false;
            }
        }
    }
    else{
        //
        //
        evtobj.type = "onUploadFailed";			
        this.events.onUploadFailed.fireEvent(this,evtobj);
        //
        //
        this.toolIsActive = true;	
        //
        // update gui state
        if(true == this.hideOnComplete) {
            //
            //
            this.toolIsActive = false;
        }
    }
    //
    //
    this.redraw();
}
//
//
ImageUploadWidget.prototype.addImageToImageEntrySet = function(entryId, entrySetId) {
    //
    //
    if(entryId && entrySetId) {
        var entriesToAdd = new Array();
        var entryTypesToAdd = new Array();
        entriesToAdd[0] = entryId;
        entryTypesToAdd[0] = "ImageEntry";
        addEntriesToEntrySet(entriesToAdd, entryTypesToAdd, entrySetId);
    }
}
ImageUploadWidget.prototype.addEntryToEntrySet = function(entryId, entrySetId) {
    //
    //
    this.addImageToImageEntrySet(entryId, entrySetId);
}
//
//
ProfileImageUploadWidget.prototype.profileId=null;
//
//
function ProfileImageUploadWidget(id,domContainer,parentWidget){
    ProfileImageUploadWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
}
//
//
copyPrototype(ProfileImageUploadWidget,ImageUploadWidget);
//
//
ProfileImageUploadWidget.prototype.superClass=ImageUploadWidget.prototype;
//
//
ProfileImageUploadWidget.prototype.getDefaultHandlerCommandsXML = function(anAssetPath, anAssetName, aMimeType) {
    //
    //
    var decodedCmdSet = "" + 
        "<COMMANDS>" +
        "<COMMAND CLASS_NAME=\"com.tenduke.services.multimediatranscoder.ScaleImage\"" +
        " OBJECT_PATH=\"" + encode64(anAssetPath) + "\"" +
        " OBJECT_NAME=\"" + encode64(anAssetName) + "\"" +
        " OUTPUT_PATH=\"" + encode64(anAssetPath) + "\"" +
        " OUTPUT_NAME=\"" + encode64(anAssetName) + "\"" +
        " WIDTH=\"" + this.imageWidth + "\"" +
        " HEIGHT=\"" + this.imageHeight + "\""+
        " PRESERVE_ASPECT=\"true\"" +
        " IS_ENCODED=\"true\"" +
        "/>" +
        "<COMMAND CLASS_NAME=\"com.tenduke.services.multimediatranscoder.ScaleImage\"" +
        " OBJECT_PATH=\"" + encode64(anAssetPath) + "\"" +
        " OBJECT_NAME=\"" + encode64(anAssetName) + "\"" +
        " OUTPUT_PATH=\"" + encode64(anAssetPath + IMAGE_FILE_POSTFIX) + "\"" +
        " OUTPUT_NAME=\"" + encode64(anAssetName + IMAGE_FILE_POSTFIX) + "\"" +
        " WIDTH=\"" + this.imageWidth + "\"" +
        " HEIGHT=\"" + this.imageHeight + "\""+
        " PRESERVE_ASPECT=\"true\"" +
        " IS_ENCODED=\"true\"" +
        "/>" +
        "<COMMAND CLASS_NAME=\"com.tenduke.services.multimediatranscoder.ScaleImage\"" +
        " SUCCESS_DEPENDENCY_CHAIN=\"1\"" +
        " OBJECT_PATH=\"" + encode64(anAssetPath) + "\"" +
        " OBJECT_NAME=\"" + encode64(anAssetName) + "\"" +
        " OUTPUT_PATH=\"" + encode64(anAssetPath + THUMB_FILE_POSTFIX) + "\"" +
        " OUTPUT_NAME=\"" + encode64(anAssetName + THUMB_FILE_POSTFIX) + "\"" +
        " WIDTH=\"" + this.imageThumbnailWidth + "\"" +
        " HEIGHT=\"" + this.imageThumbnailHeight + "\""+
        " PRESERVE_ASPECT=\"true\"" +
        " IS_ENCODED=\"true\"" +
        "/>" +
        "</COMMANDS>";
    return decodedCmdSet;
}
//
//
ProfileImageUploadWidget.prototype.uploadResponseHandler=function(successState, objectData, resultCode) {
    //
    //
    var evtobj = new Object();
    evtobj.code	= resultCode;
    evtobj.storedObjectData = objectData;
    if(successState==true){
        //
        //	
        if(resultCode==FORM_SUBMIT_STARTED){	
            this.toolIsActive=false;
            var uploadForm=document.getElementById(this.id+"_fileInput");
            if(uploadForm){
                uploadForm.className="hidden";	
            }
            //
            //
            evtobj.type	= "onUploadStarted";			
            this.events.onUploadStarted.fireEvent(this, evtobj);
        }
        else{
            //
            //
            this.toolIsActive=true;
            //
            //
            var shortName = getSessionShortName();
            var profileImageUrl = SERVICE_WWW_ROOT + "/servlets/View/" + shortName + "/" + encode64(objectData.objectPath + IMAGE_FILE_POSTFIX);
            var profileParams = new Properties();
            profileParams.setRootElementName("PROFILE");
            profileParams.setParametersAreEncoded(true);
            if(this.profileId){
                profileParams.setValue("PROFILE_ID", this.profileId);
            }
            profileParams.setValue("IMG_URL", ZONE_NAME + profileImageUrl);
            createOrUpdateProfile(this.profileId, profileParams, null, null, null);
            //
            // 1. notify image uploaded OK
            var thumbUrl = SERVICE_WWW_ROOT + "servlets/View/" + shortName + "/" + encode64(objectData.objectPath + THUMB_FILE_POSTFIX);
            evtobj.type	=	"onUploadDone";			
            evtobj.fileAssetURL	= ZONE_NAME + profileImageUrl;	
            evtobj.thumbAssetURL = thumbUrl;			
            this.events.onUploadDone.fireEvent(this, evtobj);
            //
            // update gui state
            if(true == this.hideOnComplete) {
                //
                //
                this.toolIsActive = false;
            }
        }
    }
    else{
        //
        //
        evtobj.type	= "onUploadFailed";			
        this.events.onUploadFailed.fireEvent(this,evtobj);
        this.toolIsActive=true;
        //
        // update gui state
        if(true == this.hideOnComplete) {
            //
            //
            this.toolIsActive = false;
        }
    }
    //
    //
    this.redraw();
}


/** */
VideoUploadWidget.prototype.imageWidth=640;
/** */
VideoUploadWidget.prototype.imageHeight=480;
/** */
VideoUploadWidget.prototype.imageThumbnailWidth=120;
/** */
VideoUploadWidget.prototype.imageThumbnailHeight=80;

/** */
function VideoUploadWidget(id,domContainer,parentWidget){
	VideoUploadWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
	//
	//
	this.acceptedObjectType=OBJECT_TYPE_VIDEO_FILE;
}

/** */
copyPrototype(VideoUploadWidget,UploadWidget);
/** */
VideoUploadWidget.prototype.superClass=UploadWidget.prototype;


/** 
 * Provides serialization of two commands by given objetc path, object name (and mime type): 
 * 1. scale to large size by instance attribures imageWidth and imageHeight values.
 * 2. scale to thumbnail size by instance attribures imageThumbnailWidth and imageThumbnailHeight values.
 * 
 * @param anAssetPath The object path of the uploaded image.
 * @param anAssetName The object name of the uploaded image.
 * @param aMimeType The mime type of the uploaded image.
 * @return command xml without enclosing <COMMANDS> element.
 */
VideoUploadWidget.prototype.getDefaultHandlerCommandsXML=function(anAssetPath, anAssetName, aMimeType) {
    var decodedCmdSet = new Array();
    decodedCmdSet[decodedCmdSet.length] = "<COMMAND CLASS_NAME=\"com.tenduke.services.multimediatranscoder.TranscodeVideo\"";
	decodedCmdSet[decodedCmdSet.length] = 	" OBJECT_PATH=\"" + encode64(anAssetPath) + "\"";
	decodedCmdSet[decodedCmdSet.length] = 	" OBJECT_NAME=\"" + encode64(anAssetName) + "\"";
	decodedCmdSet[decodedCmdSet.length] = 	" TARGET_FORMAT=\"" + VIDEO_FILE_POSTFIX + "\"";
	decodedCmdSet[decodedCmdSet.length] = 	" TARGET_TYPE=\"video\"";
	decodedCmdSet[decodedCmdSet.length] = 	"/>";
	decodedCmdSet[decodedCmdSet.length] = "<COMMAND CLASS_NAME=\"com.tenduke.services.multimediatranscoder.TranscodeVideo\"";
	decodedCmdSet[decodedCmdSet.length] = 	" OBJECT_PATH=\"" + encode64(anAssetPath) + "\"";
	decodedCmdSet[decodedCmdSet.length] = 	" OBJECT_NAME=\"" + encode64(anAssetName) + "\"";
	decodedCmdSet[decodedCmdSet.length] = 	" TARGET_FORMAT=\"" + SCRSHOT_FILE_POSTFIX + "\"";
	decodedCmdSet[decodedCmdSet.length] = 	" TARGET_TYPE=\"thumbnail\"";
	decodedCmdSet[decodedCmdSet.length] = 	" START_TIME=\"00:00:02\"";
	decodedCmdSet[decodedCmdSet.length] = 	"/>";
	decodedCmdSet[decodedCmdSet.length] = "<COMMAND CLASS_NAME=\"com.tenduke.services.multimediatranscoder.TranscodeVideo\"";
	decodedCmdSet[decodedCmdSet.length] = 	" OBJECT_PATH=\"" + encode64(anAssetPath) + "\"";
	decodedCmdSet[decodedCmdSet.length] = 	" OBJECT_NAME=\"" + encode64(anAssetName) + "\"";
	decodedCmdSet[decodedCmdSet.length] = 	" TARGET_FORMAT=\"" + THUMB_FILE_POSTFIX + "\"";
	decodedCmdSet[decodedCmdSet.length] = 	" TARGET_TYPE=\"thumbnail\"";
	decodedCmdSet[decodedCmdSet.length] = 	" START_TIME=\"00:00:02\"";
	decodedCmdSet[decodedCmdSet.length] = 	"/>";
    return decodedCmdSet.join("");
}

/** */
VideoUploadWidget.prototype.uploadResponseHandler=function(successState, objectData, resultCode) {
	//
	//
	var evtobj = new Object();
	evtobj.code	= resultCode;
	evtobj.storedObjectData = objectData;
	if(successState==true){
		//
		//	
		if(resultCode==FORM_SUBMIT_STARTED){	
			this.toolIsActive=false;
			var uploadForm=document.getElementById(this.id+"_fileInput");
			//if(uploadForm){
			//	uploadForm.className="hidden";	
			//}
			var displayNameInput = document.getElementById(this.id + this.displayNameInputFieldIdPostfix);
            if(displayNameInput && displayNameInput.value) {
                this.displayName = displayNameInput.value;                
            }
            var descriptionInput = document.getElementById(this.id + this.descriptionInputFieldIdPostfix);
            if(descriptionInput && descriptionInput.value) {
                this.description = descriptionInput.value;                
            }
            var tagInput = document.getElementById(this.id + this.tagInputFieldIdPostfix);
            if(tagInput && tagInput.value) {
                var tagString = tagInput.value;                
                this.tags=TagWidget.prototype.parseTagsFromString(tagString);
            }
			//
			//
			evtobj.type	= "onUploadStarted";			
			this.events.onUploadStarted.fireEvent(this, evtobj);
		}
		else{
			//
			//
			this.toolIsActive=true;
			//
			// 1. notify video uploaded OK
			var principalName = getAccountID();
			var imageUrl = SERVICE_WWW_ROOT + "servlets/View/" + principalName + "/" + encode64(objectData.objectPath);
			var thumbUrl = SERVICE_WWW_ROOT + "servlets/View/" + principalName + "/" + encode64(objectData.objectPath+THUMB_FILE_POSTFIX);
			evtobj.type	=	"onUploadDone";			
			evtobj.fileAssetURL	= imageUrl;	
			evtobj.thumbAssetURL	= thumbUrl;			
            //
            // 2. prepare adding the db entry
            var entryParams = new Properties();
            entryParams.setParametersAreEncoded(true);
            entryParams.setRootElementName("ENTRY");
            var entryId = randomUUID();
            evtobj.entryId = entryId;
            entryParams.setValue("ENTRY_ID", entryId);
            entryParams.setValue("OBJECT_PATH", objectData.objectPath);
            entryParams.setValue("OBJECT_NAME", objectData.objectName);
            if(!this.displayName)
              this.displayName = objectData.objectDisplayName;
            entryParams.setValue("DISPLAY_NAME", this.displayName);
            //
            //
            if(!this.description)
                this.description = "";
            entryParams.setValue("DESCRIPTION", this.description);
            entryParams.setValue("IS_PUBLIC", "" + this.autoPublish);
			
			//
            // 3. request write entry to db
            createOrUpdateEntry(entryParams, "VideoEntry", entryId, this.relatedProfiles);
            if(this.tags){
            	setTags(entryId, "VideoEntry", this.tags);
            }
            //
            // 4. notify listeners
            this.events.onUploadDone.fireEvent(this, evtobj);
            //
            // 5. update gui state
            if(true == this.hideOnComplete) {
                //
                //
                this.toolIsActive = false;
            }
		}
	}
	else{
		//
		//
		evtobj.type	= "onUploadFailed";			
		this.events.onUploadFailed.fireEvent(this,evtobj);
		//
		//
		this.toolIsActive=true;		
	}
	//
	//
	this.redraw();
}
//
//
VideoUploadWidget.prototype.addVideoToVideoEntrySet = function(entryId, entrySetId) {
    //
    //
    if(entryId && entrySetId) {
        var entriesToAdd = new Array();
        var entryTypesToAdd = new Array();
        entriesToAdd[0] = entryId;
        entryTypesToAdd[0] = "VideoEntry";
        addEntriesToEntrySet(entriesToAdd, entryTypesToAdd, entrySetId);
    }
}
//
//
VideoUploadWidget.prototype.addEntryToEntrySet = function(entryId, entrySetId) {
    //
    //
    this.addVideoToVideoEntrySet(entryId, entrySetId);
}
//
//
EntryWidget.prototype.entryDisplayName = null;
EntryWidget.prototype.entryId = null;
EntryWidget.prototype.entryType = null;
EntryWidget.prototype.deleteFiles = true;
EntryWidget.prototype.entryFileExtensionNames = null;
//
//
function EntryWidget(id, domContainer, parentWidget) {
    //
    //
    EntryWidget.prototype.superClass.constructor.call(this, id, domContainer, parentWidget);
    this.entryFileExtensionNames = new Array();
    this.events.onEntryDeleted = new Delegate();
    this.events.onEntryPublicityChanged = new Delegate();
    this.events.onEntryAddedToEntrySet = new Delegate();
    this.events.onEntryRemovedFromEntrySet = new Delegate();
}
//
//EntryWidget initialize prototype
copyPrototype(EntryWidget,ContainerWidget);
//
// EntryWidget class hierarchy
EntryWidget.prototype.superClass=ContainerWidget.prototype;
//
//
EntryWidget.prototype.deleteEntry=function() {
    //
    // request entry delete
    var confirmResult = this.confirmDeleteEntry();
    if(confirmResult) {
      //
      //
      var deleteResult = deleteEntry(this.entryId, this.entryType, this.deleteFiles, this.entryFileExtensionNames);
      //
      // fire deleted event
      var evtobj = new Object();
      evtobj.code = 0;
      evtobj.deleteResult = deleteResult;
      evtobj.type	= "onEntryDeleted";
      this.events.onEntryDeleted.fireEvent(this, evtobj);
  }
}
//
//
EntryWidget.prototype.confirmDeleteEntry=function() {
    //
    //
    var retValue = true;
    retValue = confirm("Do you really want to delete " + this.entryDisplayName + "?");
    return retValue;
}
//
//
EntryWidget.prototype.setPublicity=function(isPublic) {
      //
      //
      var evtobj = new Object();
     var entryParams = new Properties();
     entryParams.setParametersAreEncoded(true);
     entryParams.setRootElementName("ENTRY");
     evtobj.entryId = this.entryId;
     entryParams.setValue("ENTRY_ID", this.entryId);
     //
     //
     entryParams.setValue("IS_PUBLIC", "" + isPublic);
      var result=createOrUpdateEntry(entryParams, this.entryType,this.entryId);
      //
      // fire deleted event
      if(!result){
      	evtobj.code = -1;
      }
      else{
      	evtobj.code = 0;
      }
      evtobj.isPublic = isPublic;
      evtobj.type	= "onEntryPublicityChanged";
      this.events.onEntryPublicityChanged.fireEvent(this, evtobj);
}
/**
 * Add entry to an entry set
 * @param entrySetId Id of entry set where this entry will be added
 * @param commandName Optional, name of command to call. If not given, uses
 *                    AddEntryToEntrySet. If given, it must be full name of a command
 *                    that implements same interface as AddEntryToEntrySet.
 */
EntryWidget.prototype.addToEntrySet=function(entrySetId, commandName) {
      //
      //
      var evtobj = new Object();
      evtobj.entryId = this.entryId;
      evtobj.entrySetId = entrySetId;
      evtobj.entryType = this.entryType;
      //
      //
      var result=addEntriesToEntrySet([this.entryId], [this.entryType], entrySetId, commandName);
      //
      // fire deleted event
      if(!result){
      	evtobj.code = -1;
      }
      else{
      	evtobj.code = 0;
      }
      evtobj.type	= "onEntryAddedToEntrySet";
      this.events.onEntryAddedToEntrySet.fireEvent(this, evtobj);
}
/**
 * Remove entry from an entry set
 * @param entrySetId Id of entry set from which this entry will be removed
 * @param commandName Optional, name of command to call. If not given, uses
 *                    RemoveEntryFromEntrySet. If given, it must be full name of a command
 *                    that implements same interface as RemoveEntryFromEntrySet.
 */
EntryWidget.prototype.removeFromEntrySet=function(entrySetId, commandName) {
      //
      //
      var evtobj = new Object();
      evtobj.entryId = this.entryId;
      evtobj.entrySetId = entrySetId;
      evtobj.entryType = this.entryType;
      //
      //
      var result=removeEntriesFromEntrySet([this.entryId], [this.entryType], entrySetId, commandName);
      //
      // fire deleted event
      if(!result){
      	evtobj.code = -1;
      }
      else{
      	evtobj.code = 0;
      }
      evtobj.type	= "onEntryRemovedFromEntrySet";
      this.events.onEntryRemovedFromEntrySet.fireEvent(this, evtobj);
}//
//
ImageWidget.prototype.imageURL = null;
ImageWidget.prototype.imageWidth = 120;
ImageWidget.prototype.imageHeight = 90;
ImageWidget.prototype.imageLoaded = false;
ImageWidget.prototype.usePadding = false;

/** */
function ImageWidget(id,domContainer,parentWidget){
    //
    //
    ImageWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //
    this.entryFileExtensionNames.push(THUMB_FILE_POSTFIX);
}

/** ImageWidget initialize prototype */
copyPrototype(ImageWidget,EntryWidget);

/** ImageWidget class hierarchy */
ImageWidget.prototype.superClass=EntryWidget.prototype;

/** */
ImageWidget.prototype.generateHTML = function(){
    var s=ImageWidget.prototype.superClass.generateHTML.call(this);
    var imgArray=s.getElementsByTagName("img");
    var img=null;
    for(var i=0; i<imgArray.length; i++){
    	if(imgArray[i].id==this.id+"_image"){
    		img=imgArray[i];
    		break;
    	}
   	}
    if(img && this.imageURL){
        if(img.getAttribute("src")!=this.imageURL){
            var anId=this.id+"_image";
            
            var aWidth=this.imageWidth;
            var aHeight=this.imageHeight;
            var c=function(event){alert(event);imageSizeInspector(document.getElementById(anId),aWidth,aHeight);};
			
			img.setAttribute("width","");
			img.setAttribute("height","");
			
			addEventToDOMNode(img,"load",this.onImgLoaded);
			
            img.setAttribute("src",this.imageURL);
            //img.setAttribute("onload", "imageSizeInspector(document.getElementById('" + this.id+"_image" + "'), " + this.imageWidth + ", " + this.imageHeight + ");");
        }
    }
    return s;	
}

/**
 * 
 */
ImageWidget.prototype.setImageURL = function(newImageSrc){
    this.imageURL = newImageSrc;
}

/**
 * 
 */
ImageWidget.prototype.createDefaultDomModel = function(){
    var frag = document.createDocumentFragment();
    var theDiv=document.createElement('div');
    theDiv.setAttribute("id", this.id);
    var img=document.createElement('img');
    img.setAttribute("id", this.id + "_image");
    img.setAttribute("src", "" + this.imageURL);
    img.setAttribute("alt", "" + this.entryDisplayName);
    img.setAttribute("onload", "imageSizeInspector(document.getElementById('" + this.id+"_image" + "'), " + this.imageWidth + ", " + this.imageHeight + ", "+this.usePadding+");");
    theDiv.appendChild(img);
    frag.appendChild(theDiv);
    return theDiv;
}
ImageWidget.prototype.show=function(){
	ImageWidget.prototype.superClass.show.call(this);
	var img = document.getElementById(this.id + "_image");
	if(img){ // in some cases at least on IE the image onload executes before the widget is initialized causing the image resize to fail. This check should fix it.
		if(this.imageLoaded && (Number(this.imageWidth)!=Number(img.getAttribute("width")) && Number(this.imageHeight)!=Number(img.getAttribute("height"))) || (Number(this.imageWidth)<Number(img.getAttribute("width")) || Number(this.imageHeight)<Number(img.getAttribute("height")))){
			//alert("resize on show "+this.id+": w:"+img.getAttribute("width")+" h:"+img.getAttribute("height")+" mw:"+this.imageWidth+" mh:"+this.imageHeight);
    		
			imageSizeInspector(img, this.imageWidth, this.imageHeight,this.usePadding);
    	}
    }
}
ImageWidget.prototype.onImgLoaded = function(e){
	var id=Widget_getWidgetIdFromWidgetDOMNode(this);
	var widget=document.widgets[id];
    if(widget){
    	//alert("onload "+this.id+" "+this.width+" "+this.height+" "+this.getAttribute("width")+" "+this.getAttribute("heigth"));
    	imageSizeInspector(this, widget.imageWidth, widget.imageHeight, widget.usePadding);
    	widget.imageLoaded=true;
    }
}
/**
 * @param anImage Reference to the image object whos size should be checked and fixed (input and output).
 * @param maxWidth The maximum width to allow for the input image.
 * @param maxHeight The maximum height to allow for the input image.
 */
function imageSizeInspector(anImage, maxWidth, maxHeight,usePadding) {
    //
    //
    //alert(" anImage.width/anImage.height;"+  anImage.width+"/"+anImage.height+" = "+( anImage.width/anImage.height));
    if(anImage && anImage.height>0 && maxWidth && maxHeight) {
        var aspectRatio = anImage.width/anImage.height;
        if(aspectRatio>1) {
            if(maxWidth/aspectRatio>maxHeight){
            	anImage.height = maxHeight;
            	anImage.width = maxHeight*aspectRatio;
            }
            else{
	            anImage.height = maxWidth/aspectRatio;
	            anImage.width = maxWidth;
	        }
        }
        else {
        	if(maxHeight*aspectRatio>maxWidth){
        		anImage.height = maxWidth/aspectRatio;
	            anImage.width = maxWidth;
        	}
        	else{
	            anImage.height = maxHeight;
    	        anImage.width = maxHeight*aspectRatio;
    	    }
        }
        if(usePadding==true){
        	var h=anImage.height;
        	var w=anImage.width;
        	var pt, pb, pl,pr;
        	pt=pb=pl=pr=0;
        	if(h<maxHeight){
        		pt=Math.floor((maxHeight-h)/2);
        		pb=pt;
        		while((pb+pt)<(maxHeight-h)){
        			pb++;
        		}
        	}
        	if(w<maxWidth){
        		pl=Math.floor((maxWidth-w)/2);
        		pr=pl;
        		while((pr+pl)<(maxWidth-w)){
        			pr++;
        		}
        	}
        	anImage.style.padding=pt+"px "+pr+"px "+pb+"px "+pl+"px"; 
        }
    }
    //alert(" anImage.width/anImage.height;"+  anImage.width+"/"+anImage.height+" = "+( anImage.width/anImage.height));
}
/**
 * Usage:
 * - 
 * Required fields in the page:
 * element with id = this.id + registrationFields that contains input and select elements in it's child hierarchy.
				   Each input and select value will be added as an account parameter incase the id does not start with "DONT_SEND"
				   The input and select element id's will be used as such to name the corresponding account parameter.
 * element with id = this.id + inviteFriendsEmails. A comma separated list of recipients for invitation mail
 * element with id = this.id + inviteFriendsName. Element's value is used as the sender name
 */

/** */
RegistrationWidget.prototype.signupCommands = null;
/** */
RegistrationWidget.prototype.createAccountCommand = null;
/** */
RegistrationWidget.prototype.createProfileCommand = null;
/** */
RegistrationWidget.prototype.activationEmailCommand = null;
/** */
RegistrationWidget.prototype.accountId = null;
/** */
RegistrationWidget.prototype.login = null;
/** */
RegistrationWidget.prototype.email = null;
/** */
RegistrationWidget.prototype.password = null;


/** */
function RegistrationWidget(id,domContainer,parentWidget){
    //
    //
    RegistrationWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //
    this.accountParameters	=	null;
    this.events.registrationComplete=new Delegate();
}
//
//
copyPrototype(RegistrationWidget,Widget);
//
//
RegistrationWidget.prototype.superClass=Widget.prototype;

/** 
 * Handler for register button clicked
 */
RegistrationWidget.prototype.registerButtonClicked = function(){
    //
    //
    var accountDataOK = this.initializeAccountData();
    var profileDataOK = this.initializeProfileData();
    if(true==accountDataOK && true==profileDataOK) {
        var registerOK = this.completeRegistration();
        if(true == registerOK) {
            this.sendActivationEmail();
        }
    }
}

/** 
 * @return true for success
 */
RegistrationWidget.prototype.initializeAccountData = function() {
    //
    //
    var retValue = false;
    //
    //
    var preCondition = false;
   
    //
    //
    this.accountParameters = getAccountParamsToSubmit( document.getElementById(this.id+"_registrationFields") ,this.id+"_");
    //
    //
    var tcsAccepted = this.accountParameters.accountParamsHashtable.getEntry("ACCEPT_TCS");
    this.accountId = randomUUID();
    this.accountParameters.accountParamsHashtable.putEntry("ACCOUNT_ID", this.accountId);
    var accountIdParameterAsArray = new Array();
    accountIdParameterAsArray[0] = "ACCOUNT_ID";
    accountIdParameterAsArray[1] = this.accountId;
    this.accountParameters.accountParamsArray[this.accountParameters.accountParamsArray.length] = accountIdParameterAsArray;
    //
    //
    var principalName = this.accountParameters.accountParamsHashtable.getEntry("primaryPrincipal"); 
    if(principalName) {
        if(caseSensitivePrincipalName==false){
        	principalName=principalName.toLowerCase();
        	this.accountParameters.accountParamsHashtable.putEntry("primaryPrincipal",principalName);
        	for (var i=0; i<this.accountParameters.accountParamsArray.length; i++){
		    	if(this.accountParameters.accountParamsArray[i][0] && this.accountParameters.accountParamsArray[i][0]=="primaryPrincipal"){
		    		this.accountParameters.accountParamsArray[i][1]=principalName;
		    		break;
		    	}
		    }
        }
        this.login = principalName;
    }
    var password = this.accountParameters.accountParamsHashtable.getEntry("PASSWORD");
    this.password = password;
    var passwordConfirmed = this.accountParameters.accountParamsHashtable.getEntry("PASSWORD_CONFIRMED");
    var email = this.accountParameters.accountParamsHashtable.getEntry("EMAIL");
    this.email = email;
    var dob = this.accountParameters.accountParamsHashtable.getEntry("DOB");
    var country = this.accountParameters.accountParamsHashtable.getEntry("COUNTRY");
    //
    //
    var errMsg;
    if(tcsAccepted && tcsAccepted=="true") {
        preCondition = true;
        errMsg = getResourceString(this, "signupDataValidateErrorMessageHead");
        if(!errMsg) {
            errMsg = "Sorry, you cannot sign up because:\r\n";
        }
        var d=document.getElementById(this.id+"_ACCEPT_TCS");
    	if(d){
    		var s=d.className;
    		s=s.replace(/error/g,"");
    		d.className=s;
    	}
    }
    else{
        errMsg = getResourceString(this, "signupDataValidateAcceptTermsAndConditionsErrorMessage");
        if(!errMsg) {
            errMsg = "Sorry, you cannot sign up because:\r\n- You must accept terms and conditions!\r\n";
        }
    	var d=document.getElementById(this.id+"_ACCEPT_TCS");
    	if(d){
    		d.className+=" error";
    	}
    	
    }
    var reservedIdUsed=false;
    var principalNameInLowerCase=principalName.toLowerCase();
    for(var i=0; i<RESERVED_ACCOUNT_IDS.length; i++){
        var indexOfReservedAccountId = principalNameInLowerCase.indexOf(RESERVED_ACCOUNT_IDS[i]);
        if(indexOfReservedAccountId==0 || (indexOfReservedAccountId > 0 && indexOfReservedAccountId==principalNameInLowerCase.length-RESERVED_ACCOUNT_IDS[i].length)){
            preCondition = false;
            errMsg = getResourceString(this, "signupDataValidateUserNameNotAllowedErrorMessage");
            if(!errMsg) {
                errMsg = "- The selected user name is not allowed!\r\n";
            }
            break;
        }
    }
    if(reservedIdUsed==false){
    	var d=document.getElementById(this.id+"_primaryPrincipal");
    	if(d){
    		var s=d.className;
    		s=s.replace(/error/g,"");
    		d.className=s;
    	}
    }
    else{
    	var d=document.getElementById(this.id+"_primaryPrincipal");
    	if(d){
    		var s=d.className;
    		s=s.replace(/error/g,"");
    		d.className=s;
    	}
    }
    /*
     * Validation for password, email, firstName and lastName.
     * firstName and lastName validated with STRING_REG_EX, for now.
     */
    if(password!=passwordConfirmed) {
        preCondition = false;
        errMsg = getResourceString(this, "signupDataValidatePasswordMissmatchErrorMessage");
        if(!errMsg) {
            errMsg = "- Passwords do not match!\r\n";
        }
        var d=document.getElementById(this.id+"_PASSWORD");
        var d2=document.getElementById(this.id+"_PASSWORD_CONFIRMED");
    	if(d){
    		d.className+=" error";
    	}
    	if(d2){
    		d2.className+=" error";
    	}
    }
    else{
    	var d=document.getElementById(this.id+"_PASSWORD");
        var d2=document.getElementById(this.id+"_PASSWORD_CONFIRMED");
    	if(d){
    		var s=d.className;
    		s=s.replace(/error/g,"");
    		d.className=s;
    	}
    	if(d2){
    		var s=d.className;
    		s=s.replace(/error/g,"");
    		d.className=s;
    	}
    }
    if(validateEmail(email)==false) {
        preCondition = false;
        errMsg = getResourceString(this, "signupDataValidateEmailNotValidErrorMessage");
        if(!errMsg) {
            errMsg = "- The email address does not qualify!\r\n";
        }
        var d=document.getElementById(this.id+"_EMAIL");
    	if(d){
    		d.className+=" error";
    	}
    }
    else{
    	var d=document.getElementById(this.id+"_EMAIL");
    	if(d){
    		var s=d.className;
    		s=s.replace(/error/g,"");
    		d.className=s;
    	}
    }
    var dobErrMessage = validateDateOfBirth(dob);
    if(dobErrMessage){
        preCondition = false;
        errMsg += dobErrMessage;
    	var d_m=document.getElementById(this.id+"_DONT_SEND_DOB_MONTH");
    	var d_y=document.getElementById(this.id+"_DONT_SEND_DOB_YEAR");
    	var d_d=document.getElementById(this.id+"_DONT_SEND_DOB_DAY");
    	if(d_m){
    		d_m.className+=" error";
    	}
    	if(d_y){
    		d_y.className+=" error";
    	}
    	if(d_d){
    		d_d.className+=" error";
    	}
    }
    else{
    	var d_m=document.getElementById(this.id+"_DONT_SEND_DOB_MONTH");
    	var d_y=document.getElementById(this.id+"_DONT_SEND_DOB_YEAR");
    	var d_d=document.getElementById(this.id+"_DONT_SEND_DOB_DAY");
    	if(d_m){
    		var s=d_m.className;
    		s=s.replace(/error/g,"");
    		d_m.className=s;
    	}
    	if(d_y){
    		var s=d_y.className;
    		s=s.replace(/error/g,"");
    		d_y.className=s;
    	}
    	if(d_d){
    		var s=d_d.className;
    		s=s.replace(/error/g,"");
    		d_d.className=s;
    	}
    }
    if(country==-1){
        preCondition = false;
        errMsg = getResourceString(this, "signupDataValidateCountryMissingErrorMessage");
        if(!errMsg) {
            errMsg = "- You must enter your country!\r\n";
        }
    	var d=document.getElementById(this.id+"_COUNTRY");
    	if(d){    		
    		d.className+=" error";
    	}
    }
    else{
    	var d=document.getElementById(this.id+"_COUNTRY");
    	if(d){
    		var s=d.className;
    		s=s.replace(/error/g,"");
    		d.className=s;
    	}
    }
    if(preCondition==true) {
    	var d=document.getElementById(this.id+"_DONT_SEND_ERROR_INFO");
    	if(d){
    		d.className+=" hidden";
    		d.innerHTML="";
    	}
        //
        //
        var argsArray = new Array();
        argsArray[argsArray.length] = this.accountParameters.accountParamsArray;
        //
        // old code:
        //argsArray[argsArray.length] = this.signupHandler;
        //createAccount.apply(this, argsArray);
        //
        // new code:
        this.createAccountCommand = getCreateAccountCommand(this.accountParameters.accountParamsArray);        
        retValue = true;
    }
    else {
    	var d=document.getElementById(this.id+"_DONT_SEND_ERROR_INFO");
    	if(d){
    		var s=d.className;
    		s=s.replace(/hidden/g,"");
    		d.className=s;
    		d.innerHTML=errMsg;
    	}
    	else{
	        alert(errMsg);
	    }
    }
    //
    //
    return retValue;
}

/** 
 * @return true for success
 */
RegistrationWidget.prototype.initializeProfileData = function(){
    //
    //
    var retValue = false;
    //
    // get registered params
    var principalName = this.accountParameters.accountParamsHashtable.getEntry("primaryPrincipal"); 
    if(principalName) {
    	if(caseSensitivePrincipalName==false){
	        principalName=principalName.toLowerCase();
	        this.accountParameters.accountParamsHashtable.putEntry("primaryPrincipal",principalName);
	    }
    }
    var gender = this.accountParameters.accountParamsHashtable.getEntry("GENDER"); 
    if(!gender) {
        gender="undefined";
    }
    var dob = this.accountParameters.accountParamsHashtable.getEntry("DOB");
    var email = this.accountParameters.accountParamsHashtable.getEntry("EMAIL");
    var mobilePhone = this.accountParameters.accountParamsHashtable.getEntry("MOBILE_PHONE");
    var firstName = this.accountParameters.accountParamsHashtable.getEntry("FIRST_NAME");
    var lastName = this.accountParameters.accountParamsHashtable.getEntry("LAST_NAME");
    var country = this.accountParameters.accountParamsHashtable.getEntry("COUNTRY");
    var city = this.accountParameters.accountParamsHashtable.getEntry("CITY");
    var postalCode = this.accountParameters.accountParamsHashtable.getEntry("POSTAL_CODE");
    var state = this.accountParameters.accountParamsHashtable.getEntry("STATE");
    var displayName = this.accountParameters.accountParamsHashtable.getEntry("DISPLAY_NAME");
    if(!displayName){
        displayName = firstName + " " + lastName;
    }
    //
    // profile basic data
    var primaryProfileData = new Properties();
    primaryProfileData.setParametersAreEncoded(true);
    primaryProfileData.setRootElementName("PROFILE");
    primaryProfileData.setValue("DISPLAY_NAME", displayName);
    primaryProfileData.setValue("SHORT_NAME", principalName);
    primaryProfileData.setValue("IS_PUBLIC", "true");
    primaryProfileData.setValue("GENDER", gender);
    primaryProfileData.setValue("IMG_URL", "undefined");
    primaryProfileData.setValue("BIRTHDAY", dob);
    var profileId = randomUUID();
    primaryProfileData.setValue("PROFILE_ID", profileId);
    primaryProfileData.setValue("ACCOUNT_ID", this.accountId);
    //
    // contacts entry initialization		
    // 1. create the top level contact props
    var contactProperties = new ContactProperties();
    contactProperties.basic.setParametersAreEncoded(true);
    contactProperties.basic.setRootElementName("BASIC");
    contactProperties.basic.setValue("FORMATTED_NAME", firstName + " " + lastName);
	if(lastName) {
		contactProperties.basic.setValue("FAMILY_NAME", lastName);
	}
	if(firstName) {
		contactProperties.basic.setValue("GIVEN_NAME", firstName);
	}
    contactProperties.basic.setValue("PROFILE_ID", profileId);
    var contactDetailsID=randomUUID();
    contactProperties.basic.setValue("CONTACT_DETAILS_ID", contactDetailsID);
    //
    // 2. email fields initialied by the primary email registered by
    var emailEntryProps = new Properties();
    emailEntryProps.setParametersAreEncoded(true);
    emailEntryProps.setRootElementName("EMAIL_ADDRESS");
    emailEntryProps.setValue("EMAIL", email);
    emailEntryProps.setValue("IS_PREFERED", "true");
    emailEntryProps.setValue("CONTACT_DETAILS_ID", contactDetailsID);
    var emailID=randomUUID();
    emailEntryProps.setValue("EMAIL_ADDRESS_ID", emailID);
    contactProperties.emails.putEntry(email, emailEntryProps);
    //
    //
    if(mobilePhone) {
        contactProperties.mobilePhone.setRootElementName("TELEPHONE_NUMBER");
        contactProperties.mobilePhone.setValue("VALUE", mobilePhone);
        contactProperties.mobilePhone.setValue("IS_PREFERED", "true");
        contactProperties.mobilePhone.setValue("CONTACT_DETAILS_ID", contactDetailsID);
        var mobileID=randomUUID();
        contactProperties.mobilePhone.setValue("TELEPHONE_NUMBER_ID", mobileID);
        contactProperties.mobilePhone.setValue("TELEPHONE_NUMBER_TYPE", "4");
    }
    //
    // 3. postal props initialized with country asked in reg form
    contactProperties.postalAddress.setParametersAreEncoded(true);
    contactProperties.postalAddress.setRootElementName("POSTAL_ADDRESS");
    contactProperties.postalAddress.setValue("CONTACT_DETAILS_ID", contactDetailsID);
    var postalID=randomUUID();
    contactProperties.postalAddress.setValue("POSTAL_ADDRESS_ID", postalID);
    if(country){
        contactProperties.postalAddress.setValue("COUNTRY", country);
    }
    if(city){
        contactProperties.postalAddress.setValue("CITY", city);
    }
    if(state){
        contactProperties.postalAddress.setValue("STATE", state);
    }
    if(postalCode){
        contactProperties.postalAddress.setValue("POSTAL_CODE", postalCode);
    }
    //
    //		
    var profileGroup = this.accountParameters.accountParamsHashtable.getEntry("GROUP");
    //
    // old code:
    //createOrUpdateProfile.call(this, profileId, primaryProfileData, contactProperties, null,profileGroup, this.createOrUpdateHandler);
    //
    // new code:
    this.createProfileCommand = getCreateOrUpdateProfileCommand.call(this, profileId, primaryProfileData, contactProperties, null, profileGroup);
    retValue = true;
    //
    //
    return retValue;
}

/** 
 * @return true for success
 */
RegistrationWidget.prototype.completeRegistration = function(){
    //
    //
    var retValue = false;
    var cmdXML = this.compileSignupCommands();
    var createResult = multipleCommandRequest(cmdXML, 2);
    var evtobj=new Object();
    var i=0;
    if(createResult==true) {
        //
        //
        retValue = true;
        //
        //
        evtobj.type	=	"registrationComplete";
        evtobj.code	=	0;
        evtobj.login	=	this.login;
        evtobj.password	=	this.password;
        this.events.registrationComplete.fireEvent(this, evtobj);
    }
    else {
        evtobj.type	=	"registrationComplete";
        evtobj.code	=	-1;
        if(createResult!=null && createResult instanceof Array && createResult.length>0 && createResult[0] && createResult[0].message) {
            var errMsg = getResourceString(this, "signupFailedErrorMessageHead");
            if(!errMsg) {
                errMsg = "Sign Up failed due to following error(s): \r\n";
            }
            for(i=0; i<createResult.length; i++) {
                if(createResult[i] && 
                   createResult[i].message &&
                   createResult[i].message.toLowerCase().indexOf("success")<0 &&
                   createResult[i].message.toLowerCase().indexOf("exception")<0)
               {
                    errMsg += createResult[i].message + "\r\n";
               }
            }
            evtobj.message = errMsg;
        }
        this.events.registrationComplete.fireEvent(this,evtobj);
    }
    //
    //
    return retValue;
}

/** */
RegistrationWidget.prototype.sendActivationEmail = function(){
    //
    //
    var invalidateAccount=false;
    var aSender = getResourceString(this,"ACCOUNT_ACTIVATION_MESSAGE_SENDER");
    var aSubject = getResourceString(this,"ACCOUNT_ACTIVATION_SUBJECT");
    var aMessage = getResourceString(this, "ACCOUNT_ACTIVATION_MESSAGE");
    var aMimeType = getResourceString(this,"ACCOUNT_ACTIVATION_MESSAGE_TYPE");
    sendActivationEmailToNamedRecipient(invalidateAccount, this.login, aSender, aSubject, aMessage, aMimeType);
}

/** */
RegistrationWidget.prototype.compileSignupCommands = function(){
    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
    cmdXML += this.createAccountCommand;
    cmdXML += this.createProfileCommand;
    cmdXML += "</COMMANDS>";
    return cmdXML;
}

/** */
RegistrationWidget.prototype.registration_login_resultHandler=function(arg) {
    //if(arg==LOGIN_FAILED) {
        //alert("Debug message: Authentication registering process failed...");
    //}
}

/** */
RegistrationWidget.prototype.createOrUpdateHandler=function(statusCode, dbgMessage, failureCode){
	
}
function GalleryViewWidget(id,domContainer,parentWidget){
    //
    //
    GalleryViewWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //
    this.events.onItemSelectionChanged=new Delegate();
}

copyPrototype(GalleryViewWidget,SelectableListWidget);

GalleryViewWidget.prototype.superClass=SelectableListWidget.prototype;

GalleryViewWidget.prototype.loadDomModel=function(param,nocache){
    for(var i in this.childWidgets){
        if(this.childWidgets[i]) {
            this.childWidgets[i].close();
            this.childWidgets[i] = null;
        }
    }
    this.childWidgets=new Object();
    GalleryViewWidget.prototype.superClass.loadDomModel.call(this,param,nocache);
}
GalleryViewWidget.prototype.setDomModel=function(model){
	for(var i in this.childWidgets){
        if(this.childWidgets[i]) {
            this.childWidgets[i].close();
            this.childWidgets[i] = null;
        }
    }
    this.childWidgets=new Object();
    GalleryViewWidget.prototype.superClass.setDomModel.call(this,model);
}

/**
 * Handle child remove events
 */
GalleryViewWidget.prototype.onRemoveChild=function(widgetInstance, eventObjectInstance){
    //
    // close child
    if(widgetInstance && widgetInstance.id) {
        //
        // if direct child
        if(this.childWidgets[widgetInstance.id]) {
            this.childWidgets[widgetInstance.id].close();
            this.childWidgets[widgetInstance.id] = null;
        }
        else {
            //
            //
            var sourceParent = widgetInstance.parentWidget;
            while(sourceParent) {
                if(sourceParent==this) {
                    break;
                }
                if(this.childWidgets[sourceParent.id]) {
                    this.childWidgets[sourceParent.id].close();
                    this.childWidgets[sourceParent.id] = null;
                    break;
                }
                sourceParent = sourceParent.parentWidget;
            }
        }      
    }
    this.redraw();
    //
    // notify parent (gallery)
    
}
//
//
ProfileWidget.prototype.displayName = null;
ProfileWidget.prototype.profileId = null;
//
//
function ProfileWidget(id, domContainer, parentWidget) {
    //
    //
    ProfileWidget.prototype.superClass.constructor.call(this, id, domContainer, parentWidget);
    //
    //
    this.childWidgets[this.id+"_ProfileImage"] = new FlashImageWidget(this.id+"_ProfileImage", this.id+"_ProfileImage_Holder", this);
    this.childWidgets[this.id+"_ProfileImage"].isOpen=true;
    //
    //
    this.events.onFriendAccepted = new Delegate();
    this.events.onFriendRejected = new Delegate();
    this.events.onFriendDeleted = new Delegate();
}
//
//
copyPrototype(ProfileWidget,ContainerWidget);
//
//
ProfileWidget.prototype.superClass=ContainerWidget.prototype;
//
//

ProfileWidget.prototype.acceptAsFriendClicked = function() {
    //
    //
    var acceptResult = respondToConnectAsFriendsRequest(this.profileId, true, "A friendly subject", "A friendly message");
    if(acceptResult==true) {
        var objectForResourceAccess = new Object();
        objectForResourceAccess.className = SERVICE_NAMES_GENERAL_FRIENDS_BUNDLE_ID;
        var alertMessage = getResourceString(objectForResourceAccess, "acceptedFriendRequestMessage");
        if(alertMessage==null || alertMessage==undefined || alertMessage.length<0) {
            alertMessage = "You and " + this.displayName + " are now listed as friends.";
        }
        else {
            alertMessage = alertMessage.replace(/INVITER_NAME/, this.displayName);
        }
        showAlert(alertMessage);
        var eventObj=new Object();
        eventObj.type = "onFriendAccepted";
        eventObj.code = 0;
        eventObj.profileId = this.profileId;
        this.events.onFriendAccepted.fireEvent(this, eventObj);
    }
}
//
//
ProfileWidget.prototype.rejectAsFriendClicked = function() {
    // 
    //
    var acceptResult = respondToConnectAsFriendsRequest(this.profileId, false, "A friendly subject", "A friendly message");
    if(acceptResult==true) {
        var objectForResourceAccess = new Object();
        objectForResourceAccess.className = SERVICE_NAMES_GENERAL_FRIENDS_BUNDLE_ID;
        var alertMessage = getResourceString(objectForResourceAccess, "rejectedFriendRequestMessage");
        if(alertMessage==null || alertMessage==undefined || alertMessage.length<0) {
            alertMessage = "Rejected " + this.displayName + "'s friend request.";
        }
        else {
            alertMessage = alertMessage.replace(/INVITER_NAME/, this.displayName);
        }
        showAlert(alertMessage);
        var eventObj=new Object();
        eventObj.type = "onFriendRejected";
        eventObj.code = 0;
        eventObj.profileId = this.profileId;
        this.events.onFriendRejected.fireEvent(this, eventObj);
    }
}
//
//
ProfileWidget.prototype.deleteFriendClicked = function() {
    //
    //
    var objectForResourceAccess = new Object();
    objectForResourceAccess.className = SERVICE_NAMES_GENERAL_FRIENDS_BUNDLE_ID;
    var confirmMessage = getResourceString(objectForResourceAccess, "confirmDeleteFriendQuestion");
    if(confirmMessage==null || confirmMessage==undefined || confirmMessage.length<0) {
        confirmMessage = "Are you sure you want to remove: ";
    }
    var confirmResult = showConfirm(confirmMessage + this.displayName);
    if(confirmResult==true) {
        var acceptResult = deleteFriendsConnections(this.profileId, "A friendly subject", "A friendly message");
        if(acceptResult==true) {
            alert("Deleted " + this.displayName + " from friends.");
            var eventObj=new Object();
            eventObj.type = "onFriendDeleted";
            eventObj.code = 0;
            eventObj.profileId = this.profileId;
            this.events.onFriendDeleted.fireEvent(this, eventObj);
        }
    }
}//
//
FlashImageWidget.prototype.flashImageAttr=null;
FlashImageWidget.prototype.bgcolor=null;
FlashImageWidget.prototype.swfUrl='/flash/ImageTransformer.swf';
/** */
function FlashImageWidget(id,domContainer,parentWidget){
    //
    //
    FlashImageWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //
    var flashImage=new FlashWidget(this.id+"_flashImage",this.id+"_flashImageHolder",this);
    flashImage.setSwfUrl(this.swfUrl);
    this.flashImageAttr=new Array();
    this.flashImageAttr["width"]=490;
    this.flashImageAttr["height"]=368;
    this.flashImageAttr["widgetID"]=this.id;
    //this.flashImageAttr["widgetID"]=this.id;
    //this.flashImageAttr["clickHandler"]="FlashRatingWidget_flash_rater_clicked";
    flashImage.setFlashVars(this.flashImageAttr);
    flashImage.isOpen=true;
    flashImage.setFlashParam("wmode","opaque");
    this.childWidgets[this.id+"_flashImage"]=flashImage;
}

/** ImageWidget initialize prototype */
copyPrototype(FlashImageWidget,ImageWidget);
/** ImageWidget class hierarchy */
FlashImageWidget.prototype.superClass=ImageWidget.prototype;
/** */
FlashImageWidget.prototype.generateHTML=function(){
	var s=FlashImageWidget.prototype.superClass.generateHTML.call(this);
	/*var img=getChildById(s,this.id+"_flashImage");
	if(img && this.imageURL){
		if(img.getAttribute("src")!=imageURL){
			img.setAttribute("src",this.imageURL);
		}
	}/*/
	return s;
	
}
FlashImageWidget.prototype.setImageURL=function(newImageSrc){
	this.imageURL=newImageSrc;
}
FlashImageWidget.prototype.show=function(){
	this.flashImageAttr["imgWidth"]=encodeURIComponent("100%");//this.imageWidth;
	this.flashImageAttr["imgHeight"]=encodeURIComponent("100%");//this.imageHeight;
	this.flashImageAttr["width"]=this.imageWidth;
	this.flashImageAttr["height"]=this.imageHeight;
	this.flashImageAttr["imgX"]=encodeURIComponent("50%");
	this.flashImageAttr["imgY"]=encodeURIComponent("50%");
	this.flashImageAttr["imgURL"]=encodeURIComponent(this.imageURL);
	this.flashImageAttr["imgId"]=this.entryId;
	this.flashImageAttr["clickHandler"]=this.clickHandler;
	this.flashImageAttr["useTween"]=this.tweenType;
	if(this.bgcolor){
		this.childWidgets[this.id+"_flashImage"].setFlashParam("bgcolor",this.bgcolor);
	}
	this.childWidgets[this.id+"_flashImage"].setFlashVars(this.flashImageAttr);
	
	FlashImageWidget.prototype.superClass.show.call(this);
//	this.childWidgets[this.id+"_flashImage"].embedFlashPlayer();
}
FlashImageWidget.prototype.showChild=function(){
	this.flashImageAttr["imgWidth"]=encodeURIComponent("100%");//this.imageWidth;
	this.flashImageAttr["imgHeight"]=encodeURIComponent("100%");//this.imageHeight;
	this.flashImageAttr["width"]=this.imageWidth;
	this.flashImageAttr["height"]=this.imageHeight;
	this.flashImageAttr["imgX"]=encodeURIComponent("50%");
	this.flashImageAttr["imgY"]=encodeURIComponent("50%");
	this.flashImageAttr["imgURL"]=encodeURIComponent(this.imageURL);
	this.flashImageAttr["imgId"]=this.entryId;
	this.flashImageAttr["clickHandler"]=this.clickHandler;
	this.flashImageAttr["useTween"]=this.tweenType;
	if(this.bgcolor){
		this.childWidgets[this.id+"_flashImage"].setFlashParam("bgcolor",this.bgcolor);
	}
	FlashImageWidget.prototype.superClass.showChild.call(this);
	this.childWidgets[this.id+"_flashImage"].setFlashVars(this.flashImageAttr);
	this.childWidgets[this.id+"_flashImage"].embedFlashPlayer();
}
/** */
InviteFriendsWidget.prototype.thirdPartyAddressBookProvider = null;
InviteFriendsWidget.prototype.hideOnInvitationsSent = true;
InviteFriendsWidget.prototype.hideOnSkip = true;
InviteFriendsWidget.prototype.alwaysUseServiceInfoEmailAsSender = false;
//
//
function InviteFriendsWidget(id,domContainer,parentWidget){
    //
    //
	InviteFriendsWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //
    this.events.invitationSent = new Delegate();
    this.events.invitationSkipped = new Delegate();
    this.events.contactsImported = new Delegate();
}


//
//
copyPrototype(InviteFriendsWidget,Widget);
//
//
InviteFriendsWidget.prototype.superClass=Widget.prototype;

/** */
InviteFriendsWidget.prototype.inviteFriendsButtonClicked=function(){

	//
	//
    var emailField=document.getElementById(this.id+"_inviteFriendsEmails");	
    var inviterNameField = document.getElementById(this.id+"_inviteFriendsName");
    //
    //
    var success=false;
    if(emailField  && inviterNameField){
        var emails = this.getEmails();
        if(emails) {
            //
            //
            var subject = getResourceString(this,"INVITATION_EMAIL_SUBJECT");
            var message = getResourceString(this,"INVITATION_EMAIL_MESSAGE");
            var aMimeType = getResourceString(this, "INVITATION_EMAIL_MESSAGE_MESSAGE_TYPE");
            //
            //
            if(message) {
                message = message.replace(/INVITER_NAME/, inviterNameField.value);
            }
            //
            //
            var aSender = null;
            if(isLoggedIn()==false || this.alwaysUseServiceInfoEmailAsSender) {
                aSender = SERVICE_INFO_EMAIL;
            }
            //
            //
            success = sendEmail(emails, subject, message, aMimeType, false, aSender);
        }
        //
        //
        var evtobj = new Object();
        //
        //
        if(success){
            //
            //
            if(this.hideOnInvitationsSent) {
                this.hide();
            }
            //
            // Notifying of invitation sent by triggering an event            
            evtobj.type	= "invitationSent";
            evtobj.code	= 0;
            this.events.invitationSent.fireEvent(this, evtobj);
        }
        else {
            //
            // Notifying of invitation sent by triggering an event
            evtobj.type	= "invitationSendFailed";
            evtobj.code	= -1;
            this.events.invitationSent.fireEvent(this, evtobj);
        }
    }
}

/** */
InviteFriendsWidget.prototype.skipButtonClicked=function() {
    //
    //
    if(this.hideOnSkip) {
        this.hide();
    }
    //
    // Notifying of invitation skipped by triggering an event
    var evtobj = new Object();
    evtobj.type	= "invitationSkipped";
    evtobj.code	= 0;
    this.events.invitationSkipped.fireEvent(this, evtobj);
}

/** */
InviteFriendsWidget.prototype.getEmails = function() {
	//
	//
    var retValue = null;
    //
    //
    var emailField=document.getElementById(this.id+"_inviteFriendsEmails");
    if(emailField) {
        var emailString=emailField.value;
        if(emailString) {
            emailString.trim();
            retValue = emailString.split(",");
            if(retValue) {
                for(var i = 0; i < retValue.length; i++){
                    var tempAddr = retValue[i].trim();
                    tempAddr = tempAddr.replace(/\x00/, "");
                    retValue[i] = tempAddr;
                    /*if (validate(tempAddr, EMAIL_REG_EX)) {
                        retValue[i]=tempAddr;
                    } else {
                        retValue[i]=null;
                        alert("The email address: "+tempAddr+" is not valid!");
                        continue;
                    }*/
                }
            }
        }
    }
    //
    //
    return retValue;
}

/** */
InviteFriendsWidget.prototype.setEmails = function(emailArray) {
    //
    //
    var emailField=document.getElementById(this.id+"_inviteFriendsEmails");
    if(emailField) {
        var emailString = "";
        if(emailArray) {
            emailString = emailArray.join(",");
        }
        emailField.value = emailString;
    }
}

/**
 *
 */
InviteFriendsWidget.prototype.addInvitee = function(email) {
    //
    //
    if(email) {
        email = email.trim();
        var emailIsAlreadyOnTheList = false;
        var currentEmails = this.getEmails();
        if(currentEmails) {
            for(var i = 0; i < currentEmails.length; i++) {
                if(email == currentEmails[i]) {
                    emailIsAlreadyOnTheList = true;
                    break;
                }
            }
        }
        //
        //
        if(emailIsAlreadyOnTheList == false) {
            if(!currentEmails) {
                currentEmails = new Array();
            }
            currentEmails.push(email);
            this.setEmails(currentEmails);
        }
    }
}

/**
 *
 */
InviteFriendsWidget.prototype.removeInvitee = function(email) {
    //
    //
    if(email) {
        email = email.trim();
        var currentIndex = -1;
        var currentEmails = this.getEmails();
        if(currentEmails) {
            for(var i = 0; i < currentEmails.length; i++) {
                if(email == currentEmails[i]) {
                    currentIndex = i;
                    break;
                }
            }
        }
        //
        //
        if(currentIndex >= 0) {
            currentEmails.splice(currentIndex, 1);
            this.setEmails(currentEmails);
        }
    }
}

/** Set name of a third party provider for address book used to import addresses. */
InviteFriendsWidget.prototype.setThirdPartyAddressBookProviderName = function(providerName) {
    this.thirdPartyAddressBookProvider = providerName;
}

/** */
InviteFriendsWidget.prototype.importContacts = function(serviceProviderName, eventHandlerWidgetId) {
    importContactsFrom3rdPartyService(serviceProviderName, eventHandlerWidgetId);
}

/**
 * Event handler that gets called when importing contacts from a 3rd party address book is finished
 * @param sourceObjectInstance object that triggered the event, may be null
 * @param eventObjectInstance event data, eventObjectInstance.contactsArray is array of imported contacts
 */
InviteFriendsWidget.prototype.contactsImportedEventHandler = function(sourceObjectInstance, eventObjectInstance) {
    //
    // Passing the imported contacts to subscribers of the contactsImported event
    this.events.contactsImported.fireEvent(this, eventObjectInstance);
}

//
//
MetaTextWidget.prototype.READ_MODE=0;
MetaTextWidget.prototype.WRITE_MODE=1;
MetaTextWidget.prototype.PREVIEW_MODE=2;
MetaTextWidget.prototype.currentMode=1;
MetaTextWidget.prototype.targetId=null;
MetaTextWidget.prototype.targetType=null;
MetaTextWidget.prototype.metaTextId=null;
MetaTextWidget.prototype.metaTextDisplayText="";
MetaTextWidget.prototype.metaText="";
MetaTextWidget.prototype.metaTextType="";
MetaTextWidget.prototype.userFormatter=null;
MetaTextWidget.prototype.returnToReadMode=true;
MetaTextWidget.prototype.allowGuestEdit=false;
MetaTextWidget.prototype.dataSetNamePrefix=null;
MetaTextWidget.prototype.inputOnly=false;
//
//
function MetaTextWidget(id,domContainer,parentWidget){
    MetaTextWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //
    this.childWidgets[this.id+"_editor"]=new UserFormatEditorWidget(this.id+"_editor",this.id+"_editorHolder",this);
    this.childWidgets[this.id+"_editor"].isOpen=true;
    this.childWidgets[this.id+"_editor"].textAreaId=this.id+"_editArea";
    this.userFormatter=userFormatter;
	
    this.events.onMetaTextSaved=new Delegate();
}
//
//
copyPrototype(MetaTextWidget,ContainerWidget);
//
//
MetaTextWidget.prototype.superClass=ContainerWidget.prototype;
//
//
MetaTextWidget.prototype.generateHTML=function(){
    var s=MetaTextWidget.prototype.superClass.generateHTML.call(this);
    var readDiv=getChildById(s,this.id+"_readMode");
    var writeDiv=getChildById(s,this.id+"_writeMode");
    if(this.currentMode==this.READ_MODE || this.currentMode==this.PREVIEW_MODE){
        if(readDiv){
            readDiv.removeAttribute("style");	
            var save2Button=getChildById(readDiv, this.id+"_save2Button");
            if(save2Button){
                if(this.currentMode==this.PREVIEW_MODE){
                    save2Button.removeAttribute("style");
                }
                else{
                    save2Button.style.cssText="display:none; visibility:hidden";
                }
            }
        }
        if(writeDiv){
            writeDiv.style.cssText="display:none; visibility:hidden";
        }
		
    }
    else{
        if(!writeDiv){
            var d=this.createDefaultWriteModeDOM();
            s.appendChild(d);
            writeDiv=d;
        }
        if(writeDiv){
            writeDiv.removeAttribute("style");	
        }
        if(readDiv){
            readDiv.style.cssText="display:none; visibility:hidden";
        }	
    }
    return s;
}
MetaTextWidget.prototype.createDefaultWriteModeDOM=function(){
    var frag=document.createDocumentFragment();
    var d=document.createElement("div");
    d.setAttribute("id",this.id+"_writeMode");
    d.className="left";
    frag.appendChild(d);
    var t=new Array();
    var text=this.metaText;
    if(!text){
        text="";
    }
    t[t.length]='<textarea id="'+this.id+'_editArea" name="'+this.id+'_editArea" class="clearThis left">'+text+'</textarea>';
    t[t.length]='<div class="left clearThis">';
    t[t.length]=	'<input id="'+this.id+'_previewButton" name="'+this.id+'_previewButton" type="button" onclick="document.widgets[\''+this.id+'\'].previewButtonClicked();" class="right small_button" onmouseOver="this.className=\'right small_button_over\';" onmouseout="this.className=\'right small_button\';" value="Preview" />';
    t[t.length]=	'<input id="'+this.id+'_saveButton" name="'+this.id+'_saveButton" type="button" onclick="document.widgets[\''+this.id+'\'].saveButtonClicked();" class="right small_button" onmouseOver="this.className=\'right small_button_over\';" onmouseout="this.className=\'right small_button\';" value="Post" />';
    t[t.length]='</div>';
    d.innerHTML=t.join("");
    if(this.childWidgets[this.id+"_editor"]){
        d.insertBefore(this.childWidgets[this.id+"_editor"].createDefaultDomModel(),d.firstChild);
    }
    return d;
	
}
MetaTextWidget.prototype.setUserFormatter=function(formatter){
    this.userFormatter=formatter;
    if(!formatter){
        this.childWidgets[this.id+"_editor"].close();
    }
	
}
MetaTextWidget.prototype.setDOMObject=function(obj){
    MetaTextWidget.prototype.superClass.setDOMObject.call(this,obj);
    if(this.metaText && this.metaText.length>0){
        this.preview(this.metaText);
    }	
	
}
MetaTextWidget.prototype.preview=function(s){
    var d=document.getElementById(this.id + "_metaText");
    if(d){
        if(this.userFormatter){
            d.innerHTML=this.userFormatter.toHTML("default",s);
        }
        else{
            d.innerHTML=s;
        }
    }
}
MetaTextWidget.prototype.setMetaText=function(s){
    this.metaText=s;
    if(this.currentMode==0 || this.currentMode==2){
        this.preview(s);
    }

    var d=document.getElementById(this.id+'_editArea');
    if(d){
        d.value=s;
    }


}
//
//
MetaTextWidget.prototype.editButtonClicked=function(){
    this.setMode(this.WRITE_MODE);
    this.redraw();
}
MetaTextWidget.prototype.cancelButtonClicked=function(){
    this.setMode(this.READ_MODE);
    var editArea=document.getElementById(this.id+"_editArea");
    if(editArea){
        editArea.value=this.metaText;
    }
    this.redraw();
    this.preview(this.metaText);
}
MetaTextWidget.prototype.doSave=function(){
    if(this.allowGuestEdit==false && isLoggedIn()==false){
        alert("This feature is only for registered users.\n Please login.");
        return;
    }
    var evtObj=new Object();
    evtObj.type="onMetaTextSaved";
    evtObj.code=-1;
    var editArea=document.getElementById(this.id+"_editArea");
    if(editArea){
        var textString=editArea.value;
        if(textString && textString.length>0){
            var cid=this.metaTextId;
            if(!cid){
                cid=randomUUID();
            }
            this.updateRemote(this.targetId,this.targetType,cid,this.metaTextType,textString,this.updateRemoteHandler);
            evtObj.code=0;
            /*	if(this.returnToReadMode==true){
				this.setMode(this.READ_MODE);
				this.redraw();
				this.setMetaText(textString);
			}*/
			
        }
        else if(this.inputOnly==false){
            this.setMode(this.READ_MODE);
            this.redraw();
            if(this.metaText){
                this.preview(this.metaText);
            }			
            evtObj.code=-2;
        }
        else{
        	evtObj.code=-2;
        }
    }
    else if(this.inputOnly==false){
        this.setMode(this.READ_MODE);
        this.redraw();
        if(this.metaText){
            this.preview(this.metaText);
        }
        evtObj.code=-3;
    }
    else{
        evtObj.code=-3;
    }
    //var index=arrayIndexOf(document.widgets,this);
    this.events.onMetaTextSaved.fireEvent(this,evtObj);	
}
MetaTextWidget.prototype.updateRemote=function(target_Id,target_type,cid,metaText_type,textString,handler){
	var f;
	if(this.dataSetNamePrefix!=null){
    	f= setMetaText(target_Id, target_type, cid, metaText_type, textString,null,this.dataSetNamePrefix);
    }
    else{
    	f= setMetaText(target_Id, target_type, cid, metaText_type, textString);
    }
    this.updateRemoteHandler(f, null, null);
}
MetaTextWidget.prototype.updateRemoteHandler=function(statusCode, dbgMessage, failureCode){
    if(statusCode==true){
        var editArea=document.getElementById(this.id+"_editArea");
        if(editArea){
            var textString=editArea.value;
            //editArea.value="";
            this.metaText=textString;
        }
    }
    if(this.inputOnly==true){
	    this.setMode(this.WRITE_MODE);
	    this.metaText="";
	    var editArea=document.getElementById(this.id+"_editArea");
        if(editArea){
	        editArea.value= this.metaText;
	    }
	    this.redraw();
    }
    else{
	    this.setMode(this.READ_MODE);
	    this.redraw();
	    if(this.metaText){
	        this.preview(this.metaText);
	    }
    }
}
MetaTextWidget.prototype.previewButtonClicked=function(){
    var editArea=document.getElementById(this.id+"_editArea");
    var textString=null;
    if(editArea){
        textString=editArea.value;
    }
    this.setMode(this.PREVIEW_MODE);
    this.redraw();
    if(textString){
        this.preview(textString);
    }
	
}
MetaTextWidget.prototype.saveButtonClicked=function(){
    this.doSave();
}
MetaTextWidget.prototype.save2ButtonClicked=function(){
    this.doSave();
}
MetaTextWidget.prototype.setMode=function(mode){
    this.currentMode=mode;	
}
//
//
function TextFieldWidget(id,domContainer,parentWidget){
    TextFieldWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
}
//
//
copyPrototype(TextFieldWidget,MetaTextWidget);
//
//
TextFieldWidget.prototype.superClass=MetaTextWidget.prototype;
//
//
TextFieldWidget.prototype.updateRemote=function(target_Id,target_type,cid,metaText_type,textString){
    if(target_type=="Profile"){
        var principalName = getAccountID();
        var profileParams = new Properties();
        profileParams.setRootElementName("PROFILE");
        profileParams.setParametersAreEncoded(true);
        //
        //
        var contactProperties = null;
		
        if(target_Id){
            profileParams.setValue("PROFILE_ID", target_Id);
        }
        if(metaText_type=="displayName"){	
            profileParams.setValue("DISPLAY_NAME", textString);    
        }
        else if(metaText_type=="profileImageURL"){
            profileParams.setValue("IMG_URL", textString);    
        }
        else if(metaText_type=="profileLink"){
            contactProperties = new ContactProperties();
            contactProperties.basic.setParametersAreEncoded(true);
            contactProperties.basic.setRootElementName("BASIC");
            contactProperties.basic.setValue("PROFILE_ID", target_Id);
            //
            // 2. email fields initialied by the primary email registered by
            var linkEntryProps = new Properties();
            linkEntryProps.setParametersAreEncoded(true);
            linkEntryProps.setRootElementName("LINK");
            linkEntryProps.setValue("VALUE", textString);
            linkEntryProps.setValue("IS_PREFERED", "true");
            linkEntryProps.setValue("LINK_ID", cid);
            contactProperties.websites.putEntry(textString, linkEntryProps);  
        }
        else if(metaText_type=="userStatusMessage"){
        	profileParams.setValue("USER_STATUS_MESSAGE", textString);    
        }
        var cmdData = "";
        cmdData += "<PROFILE_DATA>";
        cmdData += profileParams.toXML();
        cmdData += "</PROFILE_DATA>";
        cmdData = encode64(cmdData);
        //
        //
        createOrUpdateProfile.call(this, target_Id, profileParams, contactProperties, null,null);
		this.updateRemoteHandler();
    }
    else if(target_type=="AudioEntrySet" || target_type=="ImageEntrySet" || target_type=="VideoEntrySet"){
        var entrySetParams = new Properties();
        entrySetParams.setParametersAreEncoded(true);
        entrySetParams.setRootElementName("ENTRY");
        entrySetParams.setValue("ENTRY_ID", target_Id);
        //entrySetParams.setValue("PROFILE_ID", this.profileId);
        if(metaText_type=="displayName"){	
            entrySetParams.setValue("DISPLAY_NAME", textString);
        }
        if(metaText_type=="description"){	
            entryParams.setValue("DESCRIPTION", textString);
        }
        //entrySetParams.setValue("IS_PUBLIC", "true");
        createOrUpdateEntrySet(target_Id, entrySetParams, null, target_type);
        this.updateRemoteHandler();
    }
    else if(target_type=="AudioEntry" || target_type=="ImageEntry" || target_type=="VideoEntry"){
        var entryParams = new Properties();
        entryParams.setParametersAreEncoded(true);
        entryParams.setRootElementName("ENTRY");
        entryParams.setValue("ENTRY_ID", target_Id);
        //entrySetParams.setValue("PROFILE_ID", this.profileId);
        if(metaText_type=="displayName"){	
            entryParams.setValue("DISPLAY_NAME", textString);
        }
        if(metaText_type=="description"){	
            entryParams.setValue("DESCRIPTION", textString);
        }
        //entrySetParams.setValue("IS_PUBLIC", "true");
        createOrUpdateEntry(entryParams, target_type,target_Id);
        this.updateRemoteHandler();
    }

    //setMetaText(target_Id,target_type,cid,metaText_type,textString);
}
TextFieldWidget.prototype.updateRemoteHandler=function(){

        var editArea=document.getElementById(this.id+"_editArea");
        if(editArea){
            var textString=editArea.value;
            //editArea.value="";
            this.metaText=textString;
        }

    this.setMode(this.READ_MODE);
    this.redraw();
    if(this.metaText){
        this.preview(this.metaText);
    }
}//
//
EntryToolsWidget.prototype.targetId="";
EntryToolsWidget.prototype.targetType="";
//
//
function EntryToolsWidget(id,domContainer,parentWidget) {
    //
    //
    EntryToolsWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //	
    this.childWidgets[this.id+"_commentWidget"] = new MetaTextWidget(this.id+"_commentWidget", this.id+"_commentWidgetHolder", this);
    this.childWidgets[this.id+"_commentWidget"].isOpen=false;
    //
    this.childWidgets[this.id+"_embedWidget"] = new Widget(this.id+"_embedWidget",this.id+"_embedWidgetHolder",this);
    this.childWidgets[this.id+"_embedWidget"].isOpen = false;
    //	
    this.childWidgets[this.id+"_shareWidget"] = new ComposeEmailWidget(this.id+"_shareWidget",this.id+"_shareWidgetHolder",this);
    this.childWidgets[this.id+"_shareWidget"].isOpen = false;

    this.tabs[this.id+"_commentTab"] = this.id+"_commentWidget";
    this.tabs[this.id+"_embedTab"] = this.id+"_embedWidget";
    this.tabs[this.id+"_shareTab"] = this.id+"_shareWidget";
	
}
//
//
copyPrototype(EntryToolsWidget,TabbedWidget);
//
//
EntryToolsWidget.prototype.superClass=TabbedWidget.prototype;
//
//
EntryToolsWidget.prototype.setDomModel=function(domModel){
    EntryToolsWidget.prototype.superClass.setDomModel.call(this,domModel);
    alert(" _ "+this.targetId);
    if(this.targetId){
        if(this.childWidgets[this.id+"_shareWidget"]){
            this.childWidgets[this.id+"_shareWidget"].messageAppend=" id: "+this.targetId;	
        }
    }
}
//
//
EntryViewWidget.prototype.entryType=null;
EntryViewWidget.prototype.entryId=null;
EntryViewWidget.prototype.file=null;
EntryViewWidget.prototype.title=null;
EntryViewWidget.prototype.openingTime=null;
EntryViewWidget.prototype.customViewCountingParameter=null;
EntryViewWidget.prototype.enableViewCounting=true;
/** */
function EntryViewWidget(id,domContainer,parentWidget){
    //
    //
    EntryViewWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
}

/** ImageWidget initialize prototype */
copyPrototype(EntryViewWidget,ContainerWidget);
/** ImageWidget class hierarchy */
EntryViewWidget.prototype.superClass=ContainerWidget.prototype;

EntryViewWidget.prototype.open=function(){
	EntryViewWidget.prototype.superClass.open.call(this);
	this.openingTime=new Date().getTime();
	if(this.enableViewCounting==true){
		var rs=new Array();
		rs[rs.length]="/jsp/viewcounter.jsp?id=";
		rs[rs.length]=this.entryId;
		rs[rs.length]="&state=";
		rs[rs.length]="start";
		rs[rs.length]="&file=";
		rs[rs.length]=this.file;
		rs[rs.length]="&entryType=";
		rs[rs.length]=this.entryType;
		rs[rs.length]="&title=";
		rs[rs.length]=this.title;
		rs[rs.length]="&duration=";
		rs[rs.length]="0";
        if(this.customViewCountingParameter) {
            rs[rs.length] = "&userData=";
            rs[rs.length] = this.customViewCountingParameter;
        }
		callUrl(rs.join(""),"GET",true);
	}	
}

EntryViewWidget.prototype.hide=function(){
	EntryViewWidget.prototype.superClass.hide.call(this);
	if(this.enableViewCounting==true){
		var rs=new Array();
		rs[rs.length]="/jsp/viewcounter.jsp?id=";
		rs[rs.length]=this.entryId;
		rs[rs.length]="&state=";
		rs[rs.length]="stop";
		rs[rs.length]="&file=";
		rs[rs.length]=this.file;
		rs[rs.length]="&entryType=";
		rs[rs.length]=this.entryType;
		rs[rs.length]="&title=";
		rs[rs.length]=this.title;
		rs[rs.length]="&duration=";
		rs[rs.length]=""+Math.round((new Date().getTime()-this.openingTime)/1000);
		callUrl(rs.join(""),"GET",true);
	}
	this.openingTime=null;
}


UserFormatEditorWidget.prototype.textAreaId="";
//
//

//
//
function UserFormatEditorWidget(id,domContainer,parentWidget){
	UserFormatEditorWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
	//
	//
}
//
//
copyPrototype(UserFormatEditorWidget,Widget);
//
//
UserFormatEditorWidget.prototype.superClass=Widget.prototype;
//
//
UserFormatEditorWidget.prototype.getTextArea=function(){
	var d=document.getElementById(this.textAreaId);
	return d;
}

UserFormatEditorWidget.prototype.applyFormatting=function(formatId){
	var area=this.getTextArea();
	if(area){
		var beginTag="";
		var endTag="";
		if(formatId=="bold"){
			beginTag="[b]";
			endTag="[/b]";
		}
		if(formatId=="image"){
			var url=prompt("Please enter the url of your image:" , "http://");
			if(!url){
				return;
			}
			beginTag="[img]"+url;
			endTag="[/img]";
		}
		if(formatId=="link"){
			var url=prompt("Please enter the url of your link:" , "http://");
			if(!url){
				return;
			}
			beginTag="[url="+url+"]";
			endTag="[/url]";
		}
		if(formatId=="italic"){
			beginTag="[i]";
			endTag="[/i]";
		}
		if(formatId=="underline"){
			beginTag="[u]";
			endTag="[/u]";
		}
		if(formatId=="mailto"){
			beginTag="[email]";
			endTag="[/email]";
		}
		if(formatId=="size"){
			var size=prompt("Please enter the font size [6,24]:" , "");
			if(!size){
				return;
			}
			beginTag="[size="+size+"]";
			endTag="[/size]";
		}
		if(formatId=="color"){
			var color=prompt("Please enter the color name or hex value" , "");
			if(!color){
				return;
			}
			beginTag="[color="+color+"]";
			endTag="[/color]";
		}
		if(typeof area.selectionStart == 'number'){// Mozilla, Opera, and other browsers
			var start=area.value.length-1;
			var end=start;
			start = area.selectionStart;
			end   = area.selectionEnd;
			area.value=area.value.substring(0, start) + beginTag + area.value.substring(start, end) + endTag + area.value.substring(end, area.value.length);			
		}
		else if(document.selection){
			area.focus();
			var range = document.selection.createRange();
			if(range.parentElement() != area){
				return;
			}
		    if(typeof range.text == 'string'){
	        	document.selection.createRange().text = beginTag + range.text + endTag;
	        }
	        	
		}
	
	}	
}
UserFormatEditorWidget.prototype.createDefaultDomModel=function(){
	var frag = document.createDocumentFragment();
	var theDiv=document.createElement('div');
	theDiv.setAttribute("id",this.id);
	theDiv.className="left";
	frag.appendChild(theDiv);
	var t=new Array();
	t[t.length]='<a class="left" href="javascript:document.widgets[\''+this.id+'\'].applyFormatting(\'bold\');"><img src="../../images/userFormatButtons/bold.gif" alt="B" title="Makes the selected text bold" /></a>';
	t[t.length]='<a class="left" href="javascript:document.widgets[\''+this.id+'\'].applyFormatting(\'italic\');"><img src="../../images/userFormatButtons/italic.gif" alt="I" title="Makes the selected text italic" /></a>';
	t[t.length]='<a class="left" href="javascript:document.widgets[\''+this.id+'\'].applyFormatting(\'underline\');"><img src="../../images/userFormatButtons/underline.gif" alt="U" title="Underlines the selected text" /></a>';
	t[t.length]='<a class="left" href="javascript:document.widgets[\''+this.id+'\'].applyFormatting(\'color\');"><img src="../../images/userFormatButtons/color.gif" alt="Color" title="change the color of the selection" /></a>';
	t[t.length]='<a class="left" href="javascript:document.widgets[\''+this.id+'\'].applyFormatting(\'size\');"><img src="../../images/userFormatButtons/size.gif" alt="Size" title="change the size of the selection" /></a>';
	t[t.length]='<a class="left" href="javascript:document.widgets[\''+this.id+'\'].applyFormatting(\'link\');"><img src="../../images/userFormatButtons/link.gif" alt="Link" title="Insert a link" /></a>';
	t[t.length]='<a class="left" href="javascript:document.widgets[\''+this.id+'\'].applyFormatting(\'mailto\');"><img src="../../images/userFormatButtons/email.gif" alt="Email" title="Insert an email address" /></a>';
	t[t.length]='<a class="left" href="javascript:document.widgets[\''+this.id+'\'].applyFormatting(\'image\');"><img src="../../images/userFormatButtons/image.gif" alt="Image" title="Embed an image" /></a>';
	theDiv.innerHTML=t.join("");
	return theDiv;
}

//
//
function PageWidget(id,domContainer,parentWidget){
	PageWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
}
//
//
copyPrototype(PageWidget,ContainerWidget);
//
//
PageWidget.prototype.superClass=ContainerWidget.prototype;
//
//
PageWidget.prototype.generateHTML=function(){
	var s=PageWidget.prototype.superClass.generateHTML.apply(this);
	s.innerHTML+=" PageWidget";
	/*alert("page");
	var d=document.createElement("div");
	d.innerHTML="page"*/
	return s;	
}//
//
AccountWidget.prototype.profileId = null;
//
//
function AccountWidget(id,domContainer,parentWidget) {
    //
    //
    AccountWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //
    this.events.onDataSaved = new Delegate();
}

//
copyPrototype(AccountWidget, Widget);
AccountWidget.prototype.superClass = Widget.prototype;

//
AccountWidget.prototype.generateHTML=function(){
    var s = AccountWidget.prototype.superClass.generateHTML.apply(this);
    this.applyFieldValues(s);
    return s;
}

//
AccountWidget.prototype.applyFieldValues=function(s) {

}

//
AccountWidget.prototype.doSave=function() {
    //
    //
   var fetchResult=this.fetchDataForSave();
   if(fetchResult.success==true){
        //
        //
        var updateResult = this.updateRemote();      
        if(updateResult==UPDATE_ACCOUNT_OK) {
            var alertMessage = getResourceString(this, "accountUpdatedMessage");
            if(!alertMessage) {
                alertMessage = "Your account has been updated.";
            }
            showAlert(alertMessage);
        }
    }
    else {
        alert(fetchResult.errMsg);
    }
}
AccountWidget.prototype.fetchDataForSave = function(){
	var retVal={};
	retVal.success=true;
	retVal.errMsg="";
	
	var preCondition = true;
    //
    //
    var email = null;
    var passwd = null;
    var passwdConfirmed = null;
    //
    // email
    d=document.getElementById(this.id+"_EMAIL");
    if(d && d.value) {
    	email = d.value;
    }
    //
    // passwd
    d=document.getElementById(this.id+"_PASSWORD");
    if(d && d.value) {
    	passwd = d.value;
    }
    d=document.getElementById(this.id+"_PASSWORD_CONFIRMED");
    if(d && d.value) {
    	passwdConfirmed = d.value;
    }	
    //
    //
    if(email && email.length>1) {
        if(validateEmail(email)==false){
            preCondition = false;
            retVal.errMsg += "- The email address does not qualify!\r\n";
        }
    }
    //
    // 
    if(passwd && passwd.length>0) {   
        if(passwd!=passwdConfirmed) {
            preCondition = false;
            retVal.errMsg += "- Passwords do not match!\r\n";
        }
        if(passwd.length<6) {
            preCondition = false;
            retVal.errMsg += "- Password must be at least 6 (six) characters long!\r\n";
        }
    }
    if(preCondition==true) {
        //
        //
        this.changedAccountParams = new Array();
        var newParam = null;
        if(email) {
            newParam = new Array();
            newParam.push("EMAIL");
            newParam.push(email);
            this.changedAccountParams.push(newParam);
        }
        if(passwd) {
            newParam = new Array();
            newParam.push("PASSWORD");
            newParam.push(passwd);
            this.changedAccountParams.push(newParam);
            newParam = new Array();
            newParam.push("PASSWORD_CONFIRMED");
            newParam.push(passwd);
            this.changedAccountParams.push(newParam);
        }
        return retVal;
    }
    else{
    	this.changedAccountParams=null;
    	retVal.success=false;
    	return retVal;
    }
}
//	
//
AccountWidget.prototype.updateRemote = function(){
	var retVal = false;
	if(this.changedAccountParams!=null){
		retVal = changeAccountInformation(this.changedAccountParams, null);
	}
    //
    //
    var eventObject = new Object();
    eventObject.profileId = this.profileId;
    eventObject.changedAccountParameters = this.changedAccountParams;
    eventObject.updateResult = retVal;
    this.events.onDataSaved.fireEvent(this, eventObject);
    
    return retVal;
}
//
//
AccountWidget.prototype.saveButtonClicked = function(){
    this.doSave();
}
AccountWidget.prototype.cancelButtonClicked = function(){
    this.reloadDomModel();
    this.redraw();	
}
//
//
BasicProfileEditWidget.prototype.profileId = null;
BasicProfileEditWidget.prototype.contactDetailsId = null;
BasicProfileEditWidget.prototype.postalAddressId = null;
BasicProfileEditWidget.prototype.officialWebsiteId = null;
BasicProfileEditWidget.prototype.dataChangedExternally = false;
BasicProfileEditWidget.prototype.additionalProperties=null;
BasicProfileEditWidget.prototype.requireDateOfBirth=true;
BasicProfileEditWidget.prototype.requireCountry=true;
BasicProfileEditWidget.prototype.profileActivatedTimestamp=null;
//
//
function BasicProfileEditWidget(id,domContainer,parentWidget){
    //
    //
    BasicProfileEditWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //
    this.events.onDataSaved = new Delegate();
    this.events.onCancel = new Delegate();
    
}
//
//
copyPrototype(BasicProfileEditWidget,Widget);
//
//
BasicProfileEditWidget.prototype.superClass=Widget.prototype;
//
//
BasicProfileEditWidget.prototype.generateHTML=function(){
    var s=BasicProfileEditWidget.prototype.superClass.generateHTML.apply(this);
    this.applyFieldValues();
    return s;	
}
//
//
BasicProfileEditWidget.prototype.show = function() {
    //
    //
    BasicProfileEditWidget.prototype.superClass.show.call(this);
    this.applyFieldValues();
}
/**
 * Almost all select elems require manual state set.
 */
BasicProfileEditWidget.prototype.applyFieldValues = function() {
    //
    // 1. birthday 
    var hiddenDobElement = document.getElementById(this.id + "_BIRTHDAY");
    if(!hiddenDobElement) {
        hiddenDobElement = document.getElementById(this.id + "_DOB");
    }
    var hiddenDob = (hiddenDobElement?hiddenDobElement.value:null);	
    if(hiddenDob) hiddenDob = hiddenDob.trim();
    if(hiddenDob && hiddenDob.length==10 && hiddenDob.indexOf("-")==4 && hiddenDob.lastIndexOf("-")==7) {
        var yyyySelect = document.getElementById(this.id + "_DONT_SEND_DOB_YEAR");
        var mmSelect = document.getElementById(this.id + "_DONT_SEND_DOB_MONTH");
        var ddSelect = document.getElementById(this.id + "_DONT_SEND_DOB_DAY");
        if(yyyySelect && mmSelect && ddSelect){
            if(yyyySelect.value=="-1" || mmSelect.value=="-1"  || ddSelect.value=="-1" ){
                // yyyy-mm-dd
                var yyyy = hiddenDob.substring(0, 4);
                var mm = parseInt(hiddenDob.substring(5, 7));
                var dd = parseInt(hiddenDob.substring(8));
                if( isNaN(mm)==false && isNaN(dd)==false && dd>0 && mm>0) {
                    for(var i=0; i<yyyySelect.options.length; i++) {
                        if(yyyySelect.options[i].value==yyyy) {
                            yyyySelect.options[i].selected = true;
                            break;
                        }
                    }
                    mmSelect.options[mm].selected = true;
                    ddSelect.options[dd].selected = true;
                }
            }
        }
    }
    else {
    //alert("DEBUG MESSAGE: Birthday date format is incorrect: VALUE = " + hiddenDob);
    }
    //
    // 2. Country
    var hiddenCountryElement = document.getElementById(this.id + "_DONT_SEND_COUNTRY");
    var hiddenCountry = (hiddenCountryElement?hiddenCountryElement.value:null);
    if(hiddenCountry) {
        var countrySelect = document.getElementById(this.id + "_COUNTRY");
        if(countrySelect) {
            for(var i=0; i<countrySelect.options.length; i++) {
                if(countrySelect.options[i].value==hiddenCountry || countrySelect.options[i].getAttribute("label2")==hiddenCountry) {
                    countrySelect.options[i].selected = true;
                    break;
                }
            }
        }
    }	
}
/** */
BasicProfileEditWidget.prototype.doSave=function() {
    //
    //
    var fetchResult=this.fetchDataForSave();
    if(fetchResult.success==true){
        //
        //
        var updateResult=this.updateRemote();
        if(updateResult==true) {
            var alertMessage = getResourceString(this, "profileUpdatedMessage");
            if(!alertMessage) {
                alertMessage = "Your profile has been updated.";
            }
            showAlert(alertMessage);
        }
    }
    else {
        alert(fetchResult.errMsg);
    }
}
//
//
BasicProfileEditWidget.prototype.fetchDataForSave = function(){
    var retVal={};
    retVal.success=true;
    retVal.errMsg="";
    var preCondition = true;
    //
    //
    var firstName = null;
    var lastName = null;
    var companyName = null;
    var title = null;
    this.profileData = new Properties();
    this.profileData.setRootElementName("PROFILE");
    if(this.profileId) {
        this.profileData.setValue("PROFILE_ID",this.profileId);
    }
    //
    // Shortname
    var shortname = null;
    var d=document.getElementById(this.id+"_SHORT_NAME");
    if(!d) {
        d=document.getElementById(this.id+"_SHORT_NAME");
    }
    if(d && d.value && d.value.length>0){
        shortname=d.value;
        preCondition = this.checkShortNameAvailability(shortname);
        if(preCondition==false){
            /*var labels = document.getElementsByTagName('label');
        	var fieldName="Username"
		    for (var i = 0; i < labels.length; i++){
		    	if (labels[i].htmlFor != '' && labels[i].htmlFor==this.id+"_SHORT_NAME"){
					fieldName=labels[i].htmlFor.innerHTML.replace(":","");
				}*/
            retVal.errMsg += "- "+shortname+" is already reserved\r\n";
        }
        else{
            this.profileData.setValue("SHORT_NAME",shortname);
        }
    }
    //
    // activated
    if(this.profileActivatedTimestamp) {
        this.profileData.setValue("ACTIVATED", ""+this.profileActivatedTimestamp);
    }
    //
    // Birthday
    d = document.getElementById(this.id+"_BIRTHDAY");
    if(!d) {
        d=document.getElementById(this.id+"_DOB");
    }
    if(d && d.value){
        this.profileData.setValue("BIRTHDAY",d.value);
    }
    //
    // gender
    d=document.getElementById(this.id+"_GENDER");
    if(d && d.value){
        this.profileData.setValue("GENDER",d.value);
    }
    //
    // description
    d=document.getElementById(this.id+"_DISPLAY_NAME");
    if(d && d.value){
        this.profileData.setValue("DISPLAY_NAME",d.value);
    }
    //
    // description
    d=document.getElementById(this.id+"_DESCRIPTION");
    if(d && d.value){
        this.profileData.setValue("DESCRIPTION",d.value);
    }
    //
    // official website
    d=document.getElementById(this.id+"_OFFICIAL_WEBSITE");
    if(d && d.value){
        this.profileData.setValue("OFFICIAL_WEBSITE",d.value);
    }
    //
    // Country
    d=document.getElementById(this.id+"_COUNTRY");
    if(d && d.value){
        this.profileData.setValue("COUNTRY",d.value);
    }
    //
    // Region
    d=document.getElementById(this.id+"_REGION");
    if(d && d.value){
        this.profileData.setValue("REGION",d.value);
    }
    //
    // Sub region
    d=document.getElementById(this.id+"_SUB_REGION");
    if(d && d.value){
        this.profileData.setValue("SUB_REGION",d.value);
    }
    //
    // Home town
    d = document.getElementById(this.id+"_HOME_TOWN");
    if(d && d.value){
        this.profileData.setValue("HOME_TOWN",d.value);
        this.profileData.setValue("CITY",d.value);
        this.profileData.setValue("TOWN",d.value);
    }
    else {
        d = document.getElementById(this.id+"_CITY");
        if(d && d.value){
            this.profileData.setValue("HOME_TOWN",d.value);
            this.profileData.setValue("CITY",d.value);
            this.profileData.setValue("TOWN",d.value);
        }
        else {
            d = document.getElementById(this.id+"_TOWN");
            if(d && d.value){
                this.profileData.setValue("HOME_TOWN",d.value);
                this.profileData.setValue("CITY",d.value);
                this.profileData.setValue("TOWN",d.value);
            }
            else {
                this.profileData.setValue("HOME_TOWN", "");
                this.profileData.setValue("CITY", "");
                this.profileData.setValue("TOWN","");
            }
        }
    }
    //
    // Postal code
    d=document.getElementById(this.id+"_POSTAL_CODE");
    if(d && d.value){
        this.profileData.setValue("POSTAL_CODE",d.value);
    }
    //
    // Street address
    d=document.getElementById(this.id+"_STREET_ADDRESS");
    if(d && d.value){
        this.profileData.setValue("STREET_ADDRESS",d.value);
    }
    //
    // first name and last name
    d=document.getElementById(this.id+"_FIRST_NAME");
    if(d && d.value){
        firstName = d.value;
    }
    d=document.getElementById(this.id+"_LAST_NAME");
    if(d && d.value){
        lastName = d.value;
    }
    d=document.getElementById(this.id+"_TITLE");
    if(d && d.value){
        title = d.value;
    }
    d=document.getElementById(this.id+"_COMPANY_NAME");
    if(d==null || d==undefined){
        d=document.getElementById(this.id+"_ORGANIZATION_NAME");
    }
    if(d && d.value){
        companyName = d.value;
    }
    //
    // Basic
    var gender = this.profileData.getValue("GENDER");
    var displayName = this.profileData.getValue("DISPLAY_NAME");
    var description = this.profileData.getValue("DESCRIPTION");
    var officialWebsite = this.profileData.getValue("OFFICIAL_WEBSITE");
    var dob = this.profileData.getValue("BIRTHDAY"); //
    var hometown = this.profileData.getValue("HOME_TOWN");
    if(!hometown) {
        hometown = this.profileData.getValue("CITY");
    }
    var country = this.profileData.getValue("COUNTRY");
    //
    //
    if(this.requireDateOfBirth==true){
        var dobErrMessage = validateDateOfBirth(dob);
        if(dobErrMessage){
            preCondition = false;
            retVal.errMsg += dobErrMessage;
        }
    }
    if(this.requireCountry==true){
        if(country==-1){
            preCondition = false;
            retVal.errMsg += "- You must enter your country!\r\n";
        }
    }
    
    if(this.additionalPropertyInfo && this.additionalPropertyInfo.length>0){
        this.additionalProperties=[];
        for(var i=0; i<this.additionalPropertyInfo.length; i++){
	    	
            this.additionalProperties[i]= new Properties();
            this.additionalProperties[i].setRootElementName("PROPERTY");
            this.additionalProperties[i].setParametersAreEncoded(true);
            this.additionalProperties[i].setValue("PROFILE_ID", this.profileId);
            var propertyId=this.additionalPropertyInfo[i].id;
            if(propertyId==null || propertyId==undefined){
                propertyId=randomUUID();
            }
            this.additionalProperties[i].setValue("PROPERTY_ID", propertyId);
            this.additionalProperties[i].setValue("PROPERTY_OWNER_ID", this.profileId);
            this.additionalProperties[i].setValue("KEY", this.additionalPropertyInfo[i].key);
            var d=document.getElementById(this.additionalPropertyInfo[i].domId);
            if(d && d.value!=null){
                this.additionalProperties[i].setValue("VALUE", d.value);
            }
		       
        }
    }
    
    
    if(preCondition==true) {
        //
        // 1. profileId - if known, profile basic data, contact data = null, personal information data = null, handler callback
        this.profileData.setParametersAreEncoded(true);
        this.contactProperties = new ContactProperties();
        if(this.contactDetailsId){
            this.contactProperties.basic.setValue("CONTACT_DETAILS_ID", this.contactDetailsId);
        }
        else {
            this.contactDetailsId = randomUUID();
            this.contactProperties.basic.setValue("CONTACT_DETAILS_ID", this.contactDetailsId);
        }
        if(this.profileId) {
            this.contactProperties.basic.setValue("PROFILE_ID", this.profileId);
        }
        if(firstName && firstName.length>0) {
            this.contactProperties.basic.setValue("GIVEN_NAME", firstName);
        }
        if(lastName && lastName.length>0) {
            this.contactProperties.basic.setValue("FAMILY_NAME", lastName);
        }
        if(title && title.length>0) {
            this.contactProperties.basic.setValue("TITLE", title);
        }
        if(companyName && companyName.length>0) {
            this.contactProperties.basic.setValue("COMPANY_NAME", companyName);
            this.contactProperties.basic.setValue("ORGANIZATION_NAME", companyName);
        }
        // 3. postal props initialized with country asked in reg form
        this.contactProperties.postalAddress.setParametersAreEncoded(true);
        this.contactProperties.postalAddress.setRootElementName("POSTAL_ADDRESS");
        if(this.postalAddressId) {
            this.contactProperties.postalAddress.setValue("POSTAL_ADDRESS_ID", this.postalAddressId);
        }
        else {
            this.postalAddressId = randomUUID();
            this.contactProperties.postalAddress.setValue("POSTAL_ADDRESS_ID", this.postalAddressId);
        }
        if(this.contactDetailsId) {
            this.contactProperties.postalAddress.setValue("CONTACT_DETAILS_ID", this.contactDetailsId);
        }
        if(country) {
            this.contactProperties.postalAddress.setValue("COUNTRY", country);
        }
        if(hometown) {
            this.contactProperties.postalAddress.setValue("CITY", hometown);
        }
        //
        //
        if(officialWebsite && officialWebsite.length>5) {
            //
            //
            if(!this.officialWebsiteId) {
                this.officialWebsiteId = randomUUID();
            }
            //
            // allocate properties and set root elem name
            var anEntryProps = new Properties();
            anEntryProps.setRootElementName("LINK");
            anEntryProps.setValue("LINK", officialWebsite.trim());
            anEntryProps.setValue("LINK_ID", this.officialWebsiteId);
            anEntryProps.setValue("CONTACT_DETAILS_ID", this.contactDetailsId);
            anEntryProps.setValue("IS_PREFERED", "true");
            //
            // add email to collection
            this.contactProperties.websites.putEntry(anEntryProps.getValue("LINK"), anEntryProps);
        }
        return retVal;
    }
    else{
        this.profileData=null;
        this.contactProperties=null;
        retVal.success=false;
        return retVal;
    }
}
BasicProfileEditWidget.prototype.updateRemote=function(){
	
    var retVal = false;
    if(this.profileData!=null && this.contactProperties!=null){
        retVal = createOrUpdateProfile.call(this, this.profileId, this.profileData, this.contactProperties, null, this.updateHandler);
    }
    var eventObject = new Object();
    eventObject.profileId = this.profileId;
    eventObject.profileData = this.profileData;
    eventObject.contactDetailsData = this.contactProperties;
    //
    //
    if(this.additionalProperties && this.additionalProperties.length){
        eventObject.additionalProperties=this.additionalProperties;
        for(var i=0; i<this.additionalProperties.length; i++){
            retVal = retVal && setProperties.call(this, this.profileId, "Profile", this.additionalProperties[i], this.profileId);
        }
    }
    //
    //
    
    eventObject.updateResult = retVal;
    this.events.onDataSaved.fireEvent(this, eventObject);
    return retVal;
}


//
//
BasicProfileEditWidget.prototype.saveButtonClicked = function(){
    this.doSave();
}
BasicProfileEditWidget.prototype.cancelButtonClicked = function(){
    var eventObject = new Object();
    eventObject.type="onCancel";
    eventObject.code=0;
    this.events.onCancel.fireEvent(this, eventObject);
}
//
//
BasicProfileEditWidget.prototype.dataChanged = function(sourceInstance, eventObjectInstance) {
    //
    //
    this.dataChangedExternally = true;
}
BasicProfileEditWidget.prototype.checkShortNameAvailability=function(s){
    var retVal=checkShortNameAvailability(s);
    return retVal;
}//
//
ContactEditWidget.prototype.profileId=null;
ContactEditWidget.prototype.contactDetailsId=null;
ContactEditWidget.prototype.postalAddressId;
//
//
function ContactEditWidget(id,domContainer,parentWidget) {
    //
    //
    ContactEditWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //
    this.events.onDataSaved = new Delegate();
}
//
//
copyPrototype(ContactEditWidget,Widget);
//
//
ContactEditWidget.prototype.superClass=Widget.prototype;


ContactEditWidget.prototype.generateHTML=function(){
    var s=ContactEditWidget.prototype.superClass.generateHTML.apply(this);
    this.applyFieldValues(s);
    return s;	
}
/**
 * Almost all select elems require manual state set.
 */
ContactEditWidget.prototype.applyFieldValues=function(s) {
    //
    // 1. Country
    var hiddenCountryElement = getChildById(s,this.id + "_HIDDEN_COUNTRY");
    var hiddenCountry = (hiddenCountryElement?hiddenCountryElement.value:null);
    if(hiddenCountry) {
        var countrySelect = getChildById(s,this.id + "_COUNTRY");
        if(countrySelect) {
            for(var i=0; i<countrySelect.options.length; i++) {
                if(countrySelect.options[i].value==hiddenCountry) {
                    countrySelect.options[i].selected = true;
                    break;
                }
            }
        }
    }
}
/** */
ContactEditWidget.prototype.doSave=function() {
    //
    //
    var fetchResult=this.fetchDataForSave();
   if(fetchResult.success==true){
        //
        //
        var updateResult=this.updateRemote();
        if(updateResult==true) {
            var alertMessage = getResourceString(this, "profileUpdatedMessage");
            if(!alertMessage) {
                alertMessage = "Your profile has been updated.";
            }
            showAlert(alertMessage);
        }
        //
        //
    }
    else {
        alert(fetchResult.errMsg);
    }
}
//
//
ContactEditWidget.prototype.fetchDataForSave = function(){
	var retVal={};
	retVal.success=true;
	retVal.errMsg="";
	
	var preCondition = true;
    if(this.contactDetailsId && this.profileId){
        //
        // 1. create the top level contact props
        this.contactDetailsData = new ContactProperties();    
        this.contactDetailsData.basic.setValue("CONTACT_DETAILS_ID",this.contactDetailsId);
        this.contactDetailsData.basic.setValue("PROFILE_ID", this.profileId);        
        //
        // query basic contact props
        this.contactDetailsData.basic.setRootElementName("BASIC");	
        //
        // query email fields from the doc
        var i=0;
        var d = null;
        //
        // EMAIL_LIST
        d=document.getElementById(this.id+"_LIST_OF_EMAILS_CONTAINER");
        var emailList = (d?d.getElementsByTagName("div"):null);
        if(emailList) {
            for(i=0; i<emailList.length; i++) {
                //
                //
                var anEmailInputPair = emailList[i];
                if(anEmailInputPair && anEmailInputPair.id.indexOf("EMAIL_INPUT_PAIR")!=-1 && anEmailInputPair.getElementsByTagName("label")) {
                    var anEmailLabel = anEmailInputPair.getElementsByTagName("label")[0];
                    if(anEmailLabel) {
                        //
                        // allocate properties and set root elem name
                        var anEmailEntryProps = new Properties();
                        anEmailEntryProps.setRootElementName("EMAIL_ADDRESS");	
                        anEmailEntryProps.setValue("EMAIL", anEmailLabel.innerHTML.trim());
                        anEmailEntryProps.setValue("EMAIL_ADDRESS_ID", randomUUID());
                        anEmailEntryProps.setValue("CONTACT_DETAILS_ID", this.contactDetailsId);
                        if(i==0) {
                            anEmailEntryProps.setValue("IS_PREFERED", "true");
                        }
                        //
                        // add email to collection
                        this.contactDetailsData.emails.putEntry(anEmailEntryProps.getValue("EMAIL"), anEmailEntryProps);
                    }
                }
            }
        }
        //
        // query telephone props
        d=document.getElementById(this.id+"_MOBILE_PHONE");
        if(d && d.value){
            this.contactDetailsData.mobilePhone.setRootElementName("TELEPHONE_NUMBER");
            this.contactDetailsData.mobilePhone.setValue("VALUE", d.value);
            this.contactDetailsData.mobilePhone.setValue("IS_PREFERED", "true");
            this.contactDetailsData.mobilePhone.setValue("TELEPHONE_NUMBER_TYPE", "4");
            this.contactDetailsData.mobilePhone.setValue("TELEPHONE_NUMBER_ID", randomUUID());
            this.contactDetailsData.mobilePhone.setValue("CONTACT_DETAILS_ID", this.contactDetailsId);
        }
        d=document.getElementById(this.id+"_LAND_PHONE");
        if(d && d.value){
            this.contactDetailsData.landlinePhone.setRootElementName("TELEPHONE_NUMBER");
            this.contactDetailsData.landlinePhone.setValue("VALUE", d.value);
            this.contactDetailsData.landlinePhone.setValue("IS_PREFERED", "false");
            this.contactDetailsData.landlinePhone.setValue("TELEPHONE_NUMBER_TYPE", "9");
            this.contactDetailsData.landlinePhone.setValue("TELEPHONE_NUMBER_ID", randomUUID());
            this.contactDetailsData.landlinePhone.setValue("CONTACT_DETAILS_ID", this.contactDetailsId);
        }
        //
        //
        var streetAddress = null;
        var city = null;
        var postalCode = null;
        var state = null;    
        var country = null;    
        // 
        d=document.getElementById(this.id+"_ADDRESS");
        if(d && d.value) streetAddress = d.value;
        d=document.getElementById(this.id+"_CITY");
        if(d && d.value) city = d.value;
        else d=document.getElementById(this.id+"_HOME_TOWN");
        if(d && d.value) city = d.value;
        d=document.getElementById(this.id+"_ZIP");
        if(d && d.value) postalCode = d.value;
        else d=document.getElementById(this.id+"_POSTAL_CODE");
        if(d && d.value) postalCode = d.value;
        d=document.getElementById(this.id+"_STATE");
        if(d && d.value) state = d.value;
        d=document.getElementById(this.id+"_COUNTRY");
        if(d && d.value) country = d.value;
        //
        if(streetAddress || city || postalCode || country) {
            this.contactDetailsData.postalAddress.setRootElementName("POSTAL_ADDRESS");
            this.contactDetailsData.postalAddress.setValue("POSTAL_ADDRESS_ID", this.postalAddressId);
            this.contactDetailsData.postalAddress.setValue("CONTACT_DETAILS_ID", this.contactDetailsId);
            if(streetAddress) {
                this.contactDetailsData.postalAddress.setValue("STREET_ADDRESS", streetAddress);		
            }
            if(city) {
                this.contactDetailsData.postalAddress.setValue("CITY", city);
            }
            if(postalCode) {
                this.contactDetailsData.postalAddress.setValue("POSTAL_CODE", postalCode);
            }
            if(state) {
                this.contactDetailsData.postalAddress.setValue("STATE", state);
            }
            if(country) {
                this.contactDetailsData.postalAddress.setValue("COUNTRY", country);
            }
        }
        //
        // LINK_LIST
        d=document.getElementById(this.id+"_WEBSITES_CONTAINER");
        var linkList = (d?d.getElementsByTagName("div"):null);
        if(linkList) {
            for(i=0; i<linkList.length; i++) {
                //
                //
                var anInputPair = linkList[i];
                if(anInputPair && anInputPair.id.indexOf("WEBSITE_INPUT_PAIR")!=-1 && anInputPair.getElementsByTagName("label")) {
                    var aLabel = anInputPair.getElementsByTagName("label")[0];
                    if(aLabel) {
                        //
                        // allocate properties and set root elem name
                        var anEntryProps = new Properties();
                        anEntryProps.setRootElementName("LINK");
                        anEntryProps.setValue("LINK", aLabel.innerHTML.trim());
                        anEntryProps.setValue("LINK_ID", randomUUID());
                        anEntryProps.setValue("CONTACT_DETAILS_ID", this.contactDetailsId);
                        if(i==0) {
                            anEntryProps.setValue("IS_PREFERED", "true");
                        }
                        //
                        // add email to collection
                        this.contactDetailsData.websites.putEntry(anEntryProps.getValue("LINK"), anEntryProps);
                    }
                }
            }
        }
        return retVal;
    }
    else{
    	this.contactDetailsData=null;
        retVal.success=false;
        retVal.errMsg+="\n- We are very sorry but we could not fullfill your request.\nPlease logout and try again later.\n";
        return retVal;
    }
    //
    //
    
	
}
ContactEditWidget.prototype.updateRemote=function(){
	//
    // 1. profileId - if known, profile basic data, contact data = null, personal information data = null, handler callback
	var retVal=false;
    if(this.contactDetailsData!=null){
	    retVal = createOrUpdateProfile.call(this, this.profileId, null, this.contactDetailsData, null, this.updateHandler);
	}
	var eventObject = new Object();
    eventObject.profileId = this.profileId;
    eventObject.contactDetailsId = this.contactDetailsId;
    eventObject.postalAddressId = this.postalAddressId;
    eventObject.contactDetailsData = this.contactDetailsData;
    eventObject.updateResult = retVal;
    this.events.onDataSaved.fireEvent(this, eventObject);
    
	return retVal;
}
ContactEditWidget.prototype.saveButtonClicked = function(){
    this.doSave();
    //alert("save clicked"+this+" "+id);
}

/** */
ContactEditWidget.prototype.addEmail=function(anEmailAddress){
    //
    //
    var id = Widget_getWidgetIdFromWidgetDOMNode(this);
    var widget=document.widgets[id];
    if(widget && anEmailAddress) {
        //
        //
        var currentTimeMs = new Date().getTime();
        var emailContainer = document.getElementById(widget.id + "_LIST_OF_EMAILS_CONTAINER");
        //
        //
        var inputContainer = document.createElement("div");
        inputContainer.setAttribute("id", widget.id + "_EMAIL_INPUT_PAIR_" + currentTimeMs);
        //
        //
        var selectCheckBoxInput = document.createElement("input");
        selectCheckBoxInput.setAttribute("id", widget.id + "_CHECKBOX_EMAIL_" + currentTimeMs);
        selectCheckBoxInput.setAttribute("name", selectCheckBoxInput.id);
        selectCheckBoxInput.setAttribute("type", "checkbox");
        selectCheckBoxInput.className="checkBox";
        //
        //
        var emailValueLabel = document.createElement("label");
        emailValueLabel.setAttribute("for", widget.id + "_CHECKBOX_EMAIL_" + currentTimeMs);
        emailValueLabel.innerHTML = anEmailAddress.value;
        //
        //
        inputContainer.appendChild(selectCheckBoxInput);
        inputContainer.appendChild(emailValueLabel);
        if(emailContainer.childNodes && emailContainer.childNodes.length>0){
            emailContainer.insertBefore(inputContainer,emailContainer.firstChild);
        }
        else{
            emailContainer.appendChild(inputContainer);
        }
    }
}

/** */
ContactEditWidget.prototype.deleteEmailAddressSelection=function(){
    //
    //
    var id=Widget_getWidgetIdFromWidgetDOMNode(this);
    var widget=document.widgets[id];
    if(widget) {
        //
        //
        var emailContainer = document.getElementById(widget.id + "_LIST_OF_EMAILS_CONTAINER");
        //
        //
        var emailList = (emailContainer?emailContainer.getElementsByTagName("div"):null);
        if(emailList) {
            var removableElements = new Array();
            for(var i=0; i<emailList.length; i++) {
                var anEmailInputPair = emailList[i];
                if(anEmailInputPair && anEmailInputPair.id.indexOf("EMAIL_INPUT_PAIR")!=-1 && anEmailInputPair.getElementsByTagName("input")) {
                    var anEmailSelectBox = anEmailInputPair.getElementsByTagName("input")[0];
                    if(anEmailSelectBox && anEmailSelectBox.type=="checkbox" && anEmailSelectBox.checked==true) {
                        removableElements.push(anEmailInputPair);						
                    }
                }
            }
            for(var i=0; i<removableElements.length; i++) {
                emailContainer.removeChild(removableElements[i]);
            }
        }
    }
}

/** */
ContactEditWidget.prototype.addWebsite=function(aWebSiteAddress){
    //
    //
    var id=Widget_getWidgetIdFromWidgetDOMNode(this);
    var widget=document.widgets[id];
    if(widget && aWebSiteAddress) {
        //
        //
        var currentTimeMs = new Date().getTime();
        var aContainer = document.getElementById(widget.id + "_WEBSITES_CONTAINER");
        //
        //
        var inputContainer = document.createElement("div");
        inputContainer.setAttribute("id", widget.id + "_WEBSITE_INPUT_PAIR_" + currentTimeMs);
        inputContainer.setAttribute("name", inputContainer.id);
        //
        //
        var selectCheckBoxInput = document.createElement("input");
        selectCheckBoxInput.setAttribute("id", widget.id + "_CHECKBOX_WEBSITE_" + currentTimeMs);
        selectCheckBoxInput.setAttribute("name", selectCheckBoxInput.id);
        selectCheckBoxInput.setAttribute("type", "checkbox");
        selectCheckBoxInput.className="checkBox";
        //
        //
        var aValueLabel = document.createElement("label");
        aValueLabel.setAttribute("for", widget.id + "_CHECKBOX_WEBSITE_" + currentTimeMs);
        aValueLabel.innerHTML = aWebSiteAddress.value;
        //
        //
        inputContainer.appendChild(selectCheckBoxInput);
        inputContainer.appendChild(aValueLabel);
        if(aContainer.childNodes && aContainer.childNodes.length>0){
            aContainer.insertBefore(inputContainer,aContainer.firstChild);
        }
        else{
            aContainer.appendChild(inputContainer);
        }
    }
}

/** */
ContactEditWidget.prototype.deleteWebsiteAddressSelection=function(){
    //
    //
    var id=Widget_getWidgetIdFromWidgetDOMNode(this);
    var widget=document.widgets[id];
    if(widget) {
        //
        //
        var aContainer = document.getElementById(widget.id + "_WEBSITES_CONTAINER");
        //
        //
        var aList = (aContainer?aContainer.getElementsByTagName("div"):null);
        if(aList) {
            var removableElements = new Array();
            for(var i=0; i<aList.length; i++) {
                var anInputPair = aList[i];
                if(anInputPair && anInputPair.id.indexOf("WEBSITE_INPUT_PAIR")!=-1 && anInputPair.getElementsByTagName("input")) {
                    var aSelectBox = anInputPair.getElementsByTagName("input")[0];
                    if(aSelectBox && aSelectBox.type=="checkbox" && aSelectBox.checked==true) {
                        removableElements.push(anInputPair);						
                    }
                }
            }
            for(var i=0; i<removableElements.length; i++) {
                aContainer.removeChild(removableElements[i]);
            }
        }
    }
}
//
//
ProfilePreferenceEditWidget.prototype.profileId = null;
ProfilePreferenceEditWidget.prototype.enableGenres = true;
ProfilePreferenceEditWidget.prototype.enableCategories = false;
ProfilePreferenceEditWidget.prototype.genres = false;
//
//
function ProfilePreferenceEditWidget(id,domContainer,parentWidget){
    //
    //
    ProfilePreferenceEditWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //
    this.events.onDataSaved = new Delegate();
}
//
//
copyPrototype(ProfilePreferenceEditWidget, Widget);
ProfilePreferenceEditWidget.prototype.superClass = Widget.prototype;
//
//
ProfilePreferenceEditWidget.prototype.generateHTML=function(){
    var s = ProfilePreferenceEditWidget.prototype.superClass.generateHTML.apply(this);
    return s;
}
//
//
ProfilePreferenceEditWidget.prototype.show = function() {
    //
    //
    ProfilePreferenceEditWidget.prototype.superClass.show.call(this);
    this.applyFieldValues();
}
//
//
ProfilePreferenceEditWidget.prototype.applyFieldValues=function() {
    //
    // 1. Genre preference selection
    if(this.genres && this.genres.length>0) {
        var genreSelect = document.getElementById(this.id + "_DONT_SEND_GENRE");
        if(genreSelect) {
            for(var i=0; i<genreSelect.options.length; i++) {
                var genreOption = genreSelect.options[i].value;
                if(genreOption) {
                    genreOption = genreOption.replace(/&amp;/, "&");
                    for(var j=0; j<this.genres.length; j++) {
                        var profileGenre = this.genres[j].genreName;
                        if(profileGenre) {
                            profileGenre = profileGenre.replace(/&amp;/, "&");
                            if(genreOption == profileGenre) {
                                genreSelect.options[i].selected = true;
                            }
                        }
                    }
                }
            }
        }
    }	
}

//
ProfilePreferenceEditWidget.prototype.doSave=function() {
    //
    //
    var genreListInput = document.getElementById(this.id + "_DONT_SEND_GENRE");
    var genreArray = null;
    if(genreListInput) {
        for(var optIndex=0; optIndex<genreListInput.options.length; optIndex++) {
            if(genreListInput.options[optIndex].selected) {
                if(genreArray==null) {
                    genreArray = new Array();
                }
                genreArray.push(genreListInput.options[optIndex].value);
            }
        }
    }
    //
    // if favorite genres were specified... store them for user 
    if(genreArray && genreArray.length>0) {
        var updateResult = setProfileGenres(this.profileId, null, genreArray);
        if(updateResult==true) {
            var alertMessage = getResourceString(this, "profileUpdatedMessage");
            if(!alertMessage) {
                alertMessage = "Your profile has been updated.";
            }
            showAlert(alertMessage);
        }
        //
        //
        var eventObject = new Object();
        eventObject.profileId = this.profileId;
        eventObject.genreArray = this.genreArray;
        eventObject.updateResult = updateResult;
        this.events.onDataSaved.fireEvent(this, eventObject);
    }
}

//
ProfilePreferenceEditWidget.prototype.saveButtonClicked = function(){
    this.doSave();
}
ProfilePreferenceEditWidget.prototype.cancelButtonClicked = function(){
    this.reloadDomModel();
    this.redraw();	
}

/** */
ProfilePageWidget.prototype.friendInviteSubject = null;
/** */
ProfilePageWidget.prototype.friendInviteMessage = null;

/** */
function ProfilePageWidget(id,domContainer,parentWidget){
    ProfilePageWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
}

/** */
copyPrototype(ProfilePageWidget,ContainerWidget);

/** */
ProfilePageWidget.prototype.superClass=ContainerWidget.prototype;

/** */
ProfilePageWidget.prototype.onToFriendsClicked = function(profileSrcDisplayName, profileSrcShortName, profileSrcId, profileDstDisplayName, profileDstShortName, profileDstId) {
    var friendRequestResult = requestConnectAsFriends(profileSrcId, profileSrcShortName, profileSrcDisplayName, profileDstId, profileDstShortName, profileDstDisplayName, this.friendInviteSubject, this.friendInviteMessage);
}//
//
MyFriendsPageWidget.prototype.totalNumFriends = 0;
MyFriendsPageWidget.prototype.infoFields = null;
MyFriendsPageWidget.prototype.viewTrackingNames = null;
MyFriendsPageWidget.prototype.baseTrackingName = null;
//
//
function MyFriendsPageWidget(id,domContainer,parentWidget){
    //
    //
    MyFriendsPageWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //
    this.baseTrackingName = this.id;
    if(this.baseTrackingName && this.baseTrackingName.indexOf("/")!=0) {
        this.baseTrackingName = "/" + this.baseTrackingName;
    }
    //
    //
    this.childWidgets[this.id+"_FriendsByAccepted"] = new GalleryWidget(this.id+"_FriendsByAccepted", this.id+"_FriendsByAccepted_Holder", this);
    this.childWidgets[this.id+"_FriendsByAccepted"].isOpen=true;
    //
    //
    this.childWidgets[this.id+"_FriendsByRequestsForMe"] = new GalleryWidget(this.id+"_FriendsByRequestsForMe", this.id+"_FriendsByRequestsForMe_Holder", this);
    this.childWidgets[this.id+"_FriendsByRequestsForMe"].isOpen=false;
    //
    //
    this.childWidgets[this.id+"_FriendsByRequestedByMe"] = new GalleryWidget(this.id+"_FriendsByRequestedByMe", this.id+"_FriendsByRequestedByMe_Holder", this);
    this.childWidgets[this.id+"_FriendsByRequestedByMe"].isOpen=false;
    //
    //
    this.tabs[this.id + "_FriendsByAcceptedTab"] = this.id + "_FriendsByAccepted";
    this.tabs[this.id + "_FriendsByRequestsForMeTab"] = this.id + "_FriendsByRequestsForMe";
    this.tabs[this.id + "_FriendsByRequestedByMeTab"] = this.id + "_FriendsByRequestedByMe";
    this.selectedTab = this.id+"_FriendsByAcceptedTab";
    //
    //
    this.viewTrackingNames = new Array();
    this.viewTrackingNames[this.id + "_FriendsByAcceptedTab"] = "friendsByAccepted";
    this.viewTrackingNames[this.id + "_FriendsByRequestsForMeTab"] = "friendsByRequestsForMe";
    this.viewTrackingNames[this.id + "_FriendsByRequestedByMeTab"] = "friendsByRequestedByMe";
    //
    //
    this.infoFields = new Array();
    this.infoFields[0] = this.id+"_FriendsByAccepted_Info";
    this.infoFields[1] = this.id+"_FriendsByRequestsForMe_Info";
    this.infoFields[2] = this.id + "_FriendsByRequestedByMe_Info";
}
//
//
copyPrototype(MyFriendsPageWidget, TabbedWidget);
//
//
MyFriendsPageWidget.prototype.superClass = TabbedWidget.prototype;
//
//
MyFriendsPageWidget.prototype.tabClicked=function(tab){
    MyFriendsPageWidget.prototype.superClass.tabClicked.call(this, tab);
    if(tab){
        //
        // analytics
        if(trackUsage && this.baseTrackingName) {
            var viewTrackingName = this.viewTrackingNames[tab];
            if(!viewTrackingName) {
                viewTrackingName = "";
            }
            trackUsage(this.baseTrackingName + "_" + viewTrackingName);
        }
        //
        //
        var infoId = this.tabs[tab]+"_Info";
        var d = null;
        for(var i=0; i<this.infoFields.length; i++){
            d = document.getElementById(this.infoFields[i]);
            if(d){
                d.style.cssText="display:none; visibility:hidden;";
            }
        }
        d = document.getElementById(infoId);
        if(d){
            d.style.cssText="";
        }        
    }
}

ViewNavigationWidget.prototype.viewNumberNavigationItemIdPrefix = null;
ViewNavigationWidget.prototype.viewNumberNavigationItemPrevId = null;
ViewNavigationWidget.prototype.viewNumberNavigationItemFirstId = null;
ViewNavigationWidget.prototype.viewNumberNavigationItemNextId = null;
ViewNavigationWidget.prototype.viewNumberNavigationItemLastId = null;
ViewNavigationWidget.prototype.currentView=0;
ViewNavigationWidget.prototype.viewCount=0;
ViewNavigationWidget.prototype.viewNumberNavigationElements=null;
ViewNavigationWidget.prototype.viewNumberCurrentClass="number active";
ViewNavigationWidget.prototype.viewNumberOtherClass="number";
ViewNavigationWidget.prototype.viewFirstEnabledClass=null;
ViewNavigationWidget.prototype.viewFirstDisabledClass=null;
ViewNavigationWidget.prototype.viewPreviousEnabledClass="prevButton";
ViewNavigationWidget.prototype.viewPreviousDisabledClass="prevButtonDisabled";
ViewNavigationWidget.prototype.viewNextEnabledClass="nextButton";
ViewNavigationWidget.prototype.viewNextDisabledClass="nextButtonDisabled";
ViewNavigationWidget.prototype.viewLastEnabledClass=null;
ViewNavigationWidget.prototype.viewLastDisabledClass=null;
//
//
function ViewNavigationWidget(id,domContainer,parentWidget){
    //
    //
    ViewNavigationWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //
    this.events.onNavigate=new Delegate();
}
//
//
copyPrototype(ViewNavigationWidget,Widget);
//
//
ViewNavigationWidget.prototype.superClass=Widget.prototype;
//
//
ViewNavigationWidget.prototype.show=function(){
	ViewNavigationWidget.prototype.superClass.show.apply(this);
}
ViewNavigationWidget.prototype.showFirstView=function(){
    this.showView(0);
}
ViewNavigationWidget.prototype.showPrevView=function(){
    if(this.currentView>0){
        this.showView(this.currentView-1);
    }
}
ViewNavigationWidget.prototype.showLastView=function(){
    this.showView(this.viewCount-1);
}
ViewNavigationWidget.prototype.showNextView=function(){
    if(this.currentView<this.viewCount-1){
        this.showView(this.currentView+1);
    }
}
ViewNavigationWidget.prototype.showView=function(i){
    if(this.currentView != i) {
        this.viewChanged(i);
        this.publishNavigateEvents();
    }
}
ViewNavigationWidget.prototype.viewChanged=function(i){
    if(this.currentView != i) {
        this.currentView=i;
        this.updateNavigationItems();
    }
}
ViewNavigationWidget.prototype.publishNavigateEvents=function(){
    var evtObj=new Object();
    evtObj.viewIndex=this.currentView;
    evtObj.sourceWidget=this;
    //
    //
    this.events.onNavigate.fireEvent(this,evtObj);	
}
ViewNavigationWidget.prototype.initializeViewNumberNavigationElements=function(){
    //
    //
    if(this.viewNumberNavigationItemIdPrefix) {      
        this.viewNumberNavigationElements = new Array();
        var i = 0;        
        var currentViewNumberNavigationElement=document.getElementById(this.viewNumberNavigationItemIdPrefix + i);
        while(i < this.viewCount && currentViewNumberNavigationElement) {
            this.viewNumberNavigationElements[i] = currentViewNumberNavigationElement;
            i++;
            currentViewNumberNavigationElement=document.getElementById(this.viewNumberNavigationItemIdPrefix + i);
        }
    }
}
ViewNavigationWidget.prototype.updateNavigationItems=function(){
    //
    // update state of the view number links
    this.initializeViewNumberNavigationElements();
    if(this.viewNumberNavigationElements && this.viewNumberNavigationElements.length > 0) {
        //
        //
        var currentElement = null;
        var firstViewIndex = 0;
        if(this.viewCount > this.viewNumberNavigationElements.length && this.currentView >= this.viewNumberNavigationElements.length / 2) {
            firstViewIndex = Math.ceil(this.currentView - (this.viewNumberNavigationElements.length / 2));
            if(firstViewIndex + this.viewNumberNavigationElements.length > this.viewCount) {
                firstViewIndex = this.viewCount - this.viewNumberNavigationElements.length;
            }
        }        
        for(var i = 0; i < this.viewNumberNavigationElements.length; i++) {
            currentElement = this.viewNumberNavigationElements[i];
            if(currentElement) {
                var viewIndexForNavigationElement = firstViewIndex + i;
                var navigationNumberContainerElement = currentElement;
                /*while(navigationNumberContainerElement.firstChild)
                    navigationNumberContainerElement = navigationNumberContainerElement.firstChild;*/
                navigationNumberContainerElement=navigationNumberContainerElement.firstChild;
                navigationNumberContainerElement.innerHTML = viewIndexForNavigationElement + 1;
                var href=navigationNumberContainerElement.getAttribute("href");
                if(href && href.indexOf("showView")!=-1){
                	navigationNumberContainerElement.setAttribute("href","javascript:document.widgets['"+this.id+"'].showView("+viewIndexForNavigationElement+")");
                }
                if(viewIndexForNavigationElement == this.currentView) {
                    removeClassNameFromElement(currentElement, this.viewNumberOtherClass);
                    if(doesElementContainClassName(currentElement, this.viewNumberCurrentClass) == false) {
                      addClassNameToElement(currentElement, this.viewNumberCurrentClass);
                    }
                }
                else {
                    removeClassNameFromElement(currentElement, this.viewNumberCurrentClass);
                    if(doesElementContainClassName(currentElement, this.viewNumberOtherClass) == false) {
                      addClassNameToElement(currentElement, this.viewNumberOtherClass);
                    }
                }
            }
        }
    }
    //
    // update state of prev/next/first/last buttons
    var navigateToFirstElement = null;
    if(this.viewNumberNavigationItemFirstId) { navigateToFirstElement = document.getElementById(this.viewNumberNavigationItemFirstId); }    
    var navigateToPrevElement = null;
    if(this.viewNumberNavigationItemPrevId) { navigateToPrevElement = document.getElementById(this.viewNumberNavigationItemPrevId); }
    var navigateToLastElement = null;
    if(this.viewNumberNavigationItemLastId) {  navigateToLastElement = document.getElementById(this.viewNumberNavigationItemLastId); }
    var navigateToNextElement = null;
    if(this.viewNumberNavigationItemNextId) { navigateToNextElement = document.getElementById(this.viewNumberNavigationItemNextId); }
    if(this.currentView == 0) {
        if(navigateToFirstElement) {
            navigateToFirstElement.className = navigateToFirstElement.className.split(this.viewFirstEnabledClass).join(this.viewFirstDisabledClass);
        }
        if(navigateToPrevElement) {
            navigateToPrevElement.className = navigateToPrevElement.className.split(this.viewPreviousEnabledClass).join(this.viewPreviousDisabledClass);
        }
    }
    else {
        if(navigateToFirstElement) {
            navigateToFirstElement.className = navigateToFirstElement.className.split(this.viewFirstDisabledClass).join(this.viewFirstEnabledClass);
        }
        if(navigateToPrevElement) {
            navigateToPrevElement.className = navigateToPrevElement.className.split(this.viewPreviousDisabledClass).join(this.viewPreviousEnabledClass);
        }
    }
    if(this.currentView >= this.viewCount - 1) {
        if(navigateToLastElement) {
            navigateToLastElement.className = navigateToLastElement.className.split(this.viewLastEnabledClass).join(this.viewLastDisabledClass);
        }
        if(navigateToNextElement) {
            navigateToNextElement.className = navigateToNextElement.className.split(this.viewNextEnabledClass).join(this.viewNextDisabledClass);
        }
    }
    else {
        if(navigateToLastElement) {
            navigateToLastElement.className = navigateToLastElement.className.split(this.viewLastDisabledClass).join(this.viewLastEnabledClass);
        }
        if(navigateToNextElement) {
            navigateToNextElement.className = navigateToNextElement.className.split(this.viewNextDisabledClass).join(this.viewNextEnabledClass);
        }
    }
}
//
//
GalleryWidget.prototype.imageURL=null;
GalleryWidget.prototype.rangeSize=10;
GalleryWidget.prototype.currentPage=0;
GalleryWidget.prototype.sortMethod='DATE';
GalleryWidget.prototype.searchKeyValuePair='';
GalleryWidget.prototype.searchString='';
GalleryWidget.prototype.totalItemCount=2;
GalleryWidget.prototype.groupId=null;
GalleryWidget.prototype.baseTrackingName=null;
GalleryWidget.prototype.galleryViewDOMModelBaseURL="jsp/galleryPage.jsp?all=true";
//
//
function GalleryWidget(id,domContainer,parentWidget){
    //
    //
    GalleryWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //
    this.childWidgets[this.id+"_pageNavigation"] = new ViewNavigationWidget(this.id+"_pageNavigation",this.id+"_pageNavigationContainer",this);
    this.childWidgets[this.id+"_pageNavigation"].isOpen=true;
    this.childWidgets[this.id+"_pageNavigation"].events.onNavigate.addListener(this, this.navigateViewChanged);
    //
    //  
    this.galleryPages=new Array();
    //
    //
    this.events.onSelectionListChanged = new Delegate();
	this.events.onGalleryViewChanged = new Delegate();
}
//
//
copyPrototype(GalleryWidget,ContainerWidget);
//
//
GalleryWidget.prototype.superClass=ContainerWidget.prototype;
//
//
GalleryWidget.prototype.showPrevPage=function(){
    if(this.currentPage>0){
        this.showPage(Number(this.currentPage)-1);
    }
}
//
//
GalleryWidget.prototype.showNextPage=function(){
    this.showPage(Number(this.currentPage)+1);
}
//
//
GalleryWidget.prototype.showPage=function(i){
    //
    //
    if(this.baseTrackingName && trackUsage) {
        var sortTrackingName = this.sortMethod;
        if(!sortTrackingName || sortTrackingName.length<2) {
            sortTrackingName = "";
        }
        if(sortTrackingName && sortTrackingName.length>0) {
            sortTrackingName = "_by_" + sortTrackingName.toLowerCase();
        }
        trackUsage(this.baseTrackingName + sortTrackingName + "_page_" + (i+1));
    }
    //
    //
    if(!this.galleryPages){
        this.galleryPages=new Array();
    }
    if(!this.galleryPages[i]){
        this.galleryPages[i]=new GalleryViewWidget(this.id+"_page_"+i,this.id+"_pageContent",this);
        this.childWidgets[this.id+"_page_"+i]=this.galleryPages[i];
        var obj= new Object();
        obj.contentURL=SERVICE_WWW_ROOT+this.getGalleryViewDOMModelURL(i)+"&wid="+this.id+"_page_"+i;
        obj.loadDomModel=true;
        this.galleryPages[i].setQueryParams(obj);
    }
    var ind=0;
    var pages=Math.ceil(this.totalItemCount/this.rangeSize);
    var cur=Number(i);
    if(pages>0){
	    for(ind=0; ind<pages; ind++){// in this.galleryPages){
	    	if(ind!=cur){
	    		if(this.galleryPages[ind]) {
	    			this.galleryPages[ind].hide();
	    		}
	    	}
	    }
    }
    if(this.currentPage!=null &&  this.galleryPages[this.currentPage] && this.galleryPages[this.currentPage].isOpen){
    	this.galleryPages[this.currentPage].hide();
    }
    /*if(this.galleryPages[this.currentPage]){
        this.galleryPages[this.currentPage].hide();
    }*/
    this.galleryPages[i].open();
    this.currentPage = i;
    this.applySelectionListeners();
    // setRefreshCurrentContent(openVideoGallery, new Array(this.currentPage*this.rangeSize,this.rangeSize,this.sortMethod,this.searchKeyValuePair));
    var eventObject = new Object();
    eventObject.currentPage = this.currentPage;
    eventObject.startIndex = this.currentPage*this.rangeSize;
    eventObject.rangeSize = this.rangeSize;
    eventObject.sortMethod = this.sortMethod;
    eventObject.searchKeyValuePair = this.searchKeyValuePair;
    eventObject.searchString = this.searchString;
    this.events.onGalleryViewChanged.fireEvent(this, eventObject);
}
//
//
GalleryWidget.prototype.setDomModel=function(domModel){
    GalleryWidget.prototype.superClass.setDomModel.call(this,domModel);
    this.applySelectionListeners();
}
//
//
GalleryWidget.prototype.applySelectionListeners=function(){
    if(this.galleryPages){
        for(var i=0; i<this.galleryPages.length; i++){
            if(this.galleryPages[i] && this.galleryPages[i].events.onSelectionListChanged && this.galleryPages[i].events.onSelectionListChanged.findListener(this,this.galleryPageSelectionGhanged)==-1){
                this.galleryPages[i].events.onSelectionListChanged.addListener(this,this.galleryPageSelectionChanged);
            }
        }
    }
}
//
//
GalleryWidget.prototype.galleryPageSelectionChanged=function(obj,eventObj){
    var evtObj=new Object();
    evtObj.type=eventObj.type;
    evtObj.selectionItem=eventObj.selectionItem;
    evtObj.selectionType=eventObj.selectionType;
    evtObj.sourceWidget=obj;
    //var index=arrayIndexOf(document.widgets,this);
    this.events.onSelectionListChanged.fireEvent(this,evtObj);	
}
//
//
GalleryWidget.prototype.navigateViewChanged=function(obj,eventObj){
    //
    //
    this.showPage(eventObj.viewIndex);
    //
    // let navigation widgets update their state
    this.childWidgets[this.id+"_pageNavigation"].viewChanged(eventObj.viewIndex);
}
/*GalleryWidget.prototype.open=function(){
	GalleryWidget.prototype.superClass.open.call(this);
	if(this.childWidgets[this.id+"_page_"+this.currentPage]){
		this.galleryPages[this.currentPage]=this.childWidgets[this.id+"_page_"+this.currentPage];
	}
}*/
//
//
GalleryWidget.prototype.setDOMObject=function(obj){
    GalleryWidget.prototype.superClass.setDOMObject.call(this,obj);
    if(this.childWidgets[this.id+"_page_"+this.currentPage]){
        this.galleryPages[this.currentPage]=this.childWidgets[this.id+"_page_"+this.currentPage];
        var ind=0;
	    for(var j in this.galleryPages){
	    	if(ind!=this.currentPage){
	    		if(this.galleryPages[j]) {
	    			this.galleryPages[j].hide();
	    		}
	    	}
	    	ind++;
	    }
    }
    this.applySelectionListeners();
}
//
//
GalleryWidget.prototype.getGalleryViewDOMModelURL=function(page){
    var ind=page*this.rangeSize;
	
    var s=this.galleryViewDOMModelBaseURL;
    if(s.indexOf("&amp;")!=-1){
    	s=s.split("&amp;").join("&");
    }
    if(s.indexOf("?")!=-1){
        s=s+"&i=";
    }
    else{
        s=s+"?i=";
    }

    s=s+ind;

    if(this.groupId)
    {
       s=s+"&groupId="+this.groupId;
    }
    
    s=s+"&r="+this.rangeSize+"&sort="+this.sortMethod+this.searchKeyValuePair;
    return s;
}
//
//
GalleryWidget.prototype.clearAllPages=function(){
    for(var i=0; i<this.galleryPages.length; i++){
        if(this.galleryPages[i]){
            var cid=this.galleryPages[i].id;
            this.childWidgets[cid].close();
            this.childWidgets[cid]=null;
        }
    }
    this.galleryPages=new Array();
	
}
//
//
GalleryWidget.prototype.setRangeSize=function(r){
    if(r!=this.rangeSize){
        this.rangeSize=r;
        this.showPage(this.currentPage);
    }
}
//
//
GalleryWidget.prototype.setSortMethod=function(s){
    if(s!=this.sortMethod){
        this.sortMethod=s;
        this.clearAllPages();
        this.currentPage=0;
        var eventObj = new Object();
        eventObj.viewIndex = this.currentPage;
        this.navigateViewChanged(this, eventObj);
    }
}
//
//
GalleryWidget.prototype.setTotalItemCount=function(c){
    this.totalItemCount=c;
}
GalleryWidget.prototype.itemDeletedHandler=function(obj,evtObj){
	if(evtObj && evtObj.code==0){
		this.clearAllPages();
		this.showPage(this.currentPage);
	}
}
/*GalleryWidget.prototype.selectIndex=function(index){
	if(!this.selectedIndices){
		this.selectedIndices=new Array();
	}
	for(var i=0; i< this.selectedIndices.length; i++){
		if(this.selectedIndices[i]==index){
			return;
		}
	}
	this.selectedIndices.push(i)
}*///
//
function DoubleNavigationGalleryWidget(id,domContainer,parentWidget){
    //
    //
    DoubleNavigationGalleryWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //
    this.childWidgets[this.id+"_pageNavigation2"] = new ViewNavigationWidget(this.id+"_pageNavigation2",this.id+"_pageNavigationContainer2",this);
    this.childWidgets[this.id+"_pageNavigation2"].isOpen=true;
    this.childWidgets[this.id+"_pageNavigation2"].events.onNavigate.addListener(this, this.navigateViewChanged);
}
//
//
copyPrototype(DoubleNavigationGalleryWidget, GalleryWidget);
//
//
DoubleNavigationGalleryWidget.prototype.superClass = GalleryWidget.prototype;
//
//
DoubleNavigationGalleryWidget.prototype.navigateViewChanged = function(obj, eventObj){
    //
    //
    DoubleNavigationGalleryWidget.prototype.superClass.navigateViewChanged.call(this, obj, eventObj);
    this.childWidgets[this.id+"_pageNavigation2"].viewChanged(eventObj.viewIndex);
}//
//
EditMyProfileWidget.prototype.profileId = 0;
//
//
function EditMyProfileWidget(id,domContainer,parentWidget){
    //
    //
    EditMyProfileWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    //
    //
    this.childWidgets[this.id+"_BasicInformation"] = new BasicProfileEditWidget(this.id+"_BasicInformation", this.id+"_BasicInformationHolder", this);
    this.childWidgets[this.id+"_BasicInformation"].isOpen = true;
    //
    //
    this.childWidgets[this.id+"_ContactInformation"] = new ContactEditWidget(this.id+"_ContactInformation", this.id+"_ContactInformationHolder", this);
    this.childWidgets[this.id+"_ContactInformation"].isOpen=false;
    //
    //
    this.childWidgets[this.id+"_PrefereneInformation"] = new ProfilePreferenceEditWidget(this.id+"_PrefereneInformation", this.id+"_PrefereneInformationHolder", this);
    this.childWidgets[this.id+"_PrefereneInformation"].isOpen=false;
    //
    //
    this.childWidgets[this.id+"_AccountSettings"] = new AccountWidget(this.id+"_AccountSettings", this.id+"_AccountSettingsHolder", this);
    this.childWidgets[this.id+"_AccountSettings"].isOpen=false;
    //
    //
    this.tabs[this.id + "_BasicInformationTab"] = this.id + "_BasicInformation";
    this.tabs[this.id + "_ContactInformationTab"] = this.id + "_ContactInformation";
    this.tabs[this.id + "_PrefereneInformationTab"] = this.id + "_PrefereneInformation";
    this.tabs[this.id + "_AccountSettingsTab"] = this.id + "_AccountSettings";
    this.selectedTab = this.id+"_BasicInformationTab";
}
//
//
copyPrototype(EditMyProfileWidget, TabbedWidget);
//
//
EditMyProfileWidget.prototype.superClass = TabbedWidget.prototype;
//
//
EditMyProfileWidget.prototype.tabClicked=function(tab) {
    //
    //
    EditMyProfileWidget.prototype.superClass.tabClicked.call(this, tab);
}
//
//
EditMyProfileWidget.prototype.show = function() {
    //
    //
    EditMyProfileWidget.prototype.superClass.show.call(this);
    this.childWidgets[this.id+"_BasicInformation"].applyFieldValues();
}
//
//
EditMyProfileWidget.prototype.loginStateChangedEventHandler = function() {
    if(this.queryParams && this.queryParams.loadDomModel==true){
        if(this.queryParams.contentURL!=null){ 
            this.reloadDomModel(true);	
            this.redraw();
        }
    }
}//
//
AccountActivationWidget.prototype.keyParam=null;
AccountActivationWidget.prototype.accountParam=null;
AccountActivationWidget.prototype.originalEmailAddress=null;
//
//
function AccountActivationWidget(id,domContainer,parentWidget){
    AccountActivationWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);
    this.events.onAccountActivated = new Delegate();
}
//
//
copyPrototype(AccountActivationWidget,ContainerWidget);
//
//
AccountActivationWidget.prototype.superClass=ContainerWidget.prototype;
//
//
AccountActivationWidget.prototype.open=function() {
    //
    //
    AccountActivationWidget.prototype.superClass.open.call(this);
    if(this.keyParam && this.accountParam){
        this.activateAccount();
    }
    else{
        //
        //
        var msg = getResourceString(this, "ACCOUNT_ACTIVATION_PAGE_INTRO_MESSAGE");
        this.showResendForm(msg);
    }		
}
AccountActivationWidget.prototype.showResendForm=function(msg){
    var activateAccountMessage=document.getElementById(this.id+"_Message");
    if(activateAccountMessage){
		
        var contentHTML=msg+
            '<input type="text" value="'+this.originalEmailAddress+'" id="S_EMAIL" name="S_EMAIL" />'+
            '<input type="button" value="Resend" onclick="document.widgets[\''+this.id+'\'].resendValidationEmail();" />'+
            '<div id="emailSentNotifier">&nbsp;</div>';
        activateAccountMessage.innerHTML=contentHTML;
		
    }
}
AccountActivationWidget.prototype.activateAccount=function(){

    var sessionReq = initRequest("/servlets/AuthenticateServlet?function=ACTIVATE_ACCOUNT&ACCOUNT_ACTIVATION_ID="+this.keyParam+"&LOGIN="+this.accountParam, "GET");
    sessionReq.setRequestHeader("Content-Type", "text/plain; charset=\"UTF-8\"");
    try {
        sessionReq.send("");
    }
    catch(connectionE) {
        sessionReq = null;
    }
    //
    //
    var accountValidated = false;
    var response = ( sessionReq.responseXML ? sessionReq.responseXML.documentElement : null);
    //
    var returnParamsElements = (response ? response.getElementsByTagName('RETURN_PARAMETERS') : null);
    var returnParamsElement = (returnParamsElements && returnParamsElements.length>0 ? returnParamsElements[0] : null);
    var returnParameterValue;
    if(returnParamsElement) {
        var returnParameterValueElement = findFirstNodeByName(returnParamsElement, returnParameterName);
        if(returnParameterValueElement && returnParameterValueElement.getAttribute("VALUE")) {
            returnParameterValue = returnParameterValueElement.getAttribute("VALUE").toString();
        }
    }
    //
    //
    var cmdLoginInfoElement = null;
    var cmdLoginInfoElements = (response ? response.getElementsByTagName('LOGIN_INFORMATION') : null);
    if(cmdLoginInfoElements && cmdLoginInfoElements.length>0){
    	cmdLoginInfoElement = cmdLoginInfoElements[0];
    }
    var loginResult = LOGIN_FAILED;
    if(cmdLoginInfoElement){
        var authResult = cmdLoginInfoElement.getAttribute("AUTHENTICATION_RESULT");
        if(authResult){
            if(authResult=="LOGIN_OK"){
                loginResult = LOGIN_SUCCESS;
                var accountState = cmdLoginInfoElement.getAttribute("ACCOUNT_STATE");
                principalName =	cmdLoginInfoElement.getAttribute("PRINCIPAL_NAME");
                var accountDataComplete = cmdLoginInfoElement.getAttribute("ACCOUNT_DATA_IS_COMPLETE")
                accountValidated = cmdLoginInfoElement.getAttribute("ACCOUNT_VALIDATED")
                var noEmail = cmdLoginInfoElement.getAttribute("ACCOUNT_HAS_NO_EMAIL");
                //
                //
                principalName = principalName.replace(/\u0000/,"");
                writeSessionCookie(LOGIN_STATE_COOKIE_NAME, "true");
                writeSessionCookie(SESSION_SHORT_NAME_COOKIE, principalName);
                //
                //
                if(accountState=="ACCOUNT_IS_DISABLED" || accountState=="LOCKED"){
                    loginResult=LOGIN_FAILED;
                    writeSessionCookie(LOGIN_STATE_COOKIE_NAME, "false");
                }
                else if(emailValidationRequired==true && accountValidated!=null && accountValidated!=undefined){
                    emailValidated = accountValidated=="true";
                    writeSessionCookie(ACCOUNT_VALIDATED_COOKIE_NAME, ""+accountValidated);
                }
                if(accountDataComplete=="ACCOUNT_REGISTRATION_IS_COMPLETE"){
					
                }
                if(noEmail==false){
					
                }
            }
        }
    }
    //
    //
    var evtobj = new Object();
    evtobj.loginResult = loginResult;
    evtobj.returnParameterValue = returnParameterValue;
    var activateAccountMessage = document.getElementById(this.id+"_Message");
    if(loginResult==LOGIN_SUCCESS && (accountValidated == true || accountValidated == "true")) {
	//	
        //
        if(activateAccountMessage){
            var contentHTML = getResourceString(this, "ACCOUNT_ACTIVATION_PAGE_RESULT_MESSAGE");
            activateAccountMessage.innerHTML=contentHTML;
        }
        //
        //
        evtobj.code = 0;
        evtobj.activationResult = true;
        evtobj.type = "onAccountActivated";
        this.events.onAccountActivated.fireEvent(this, evtobj);
        //defaultLoginResultHandler(loginResult, principalName, returnParameterValue);
    }
    else {
        //
        //
        var msg='<p>Your account activation has failed</p>'+
            '<p>Please check that your email adress is correct and click resend and we will send you a new activation email.</p>'+
            '<p id="emailSentNotifier">&nbsp;</p>';
        //
        //
        this.showResendForm(msg);		
        //
        //
        evtobj.code = -1;
        evtobj.activationResult = false;
        evtobj.type = "onAccountActivated";
        this.events.onAccountActivated.fireEvent(this, evtobj);
    }
}

AccountActivationWidget.prototype.resendValidationEmail=function(){
    var emailField=document.getElementById("S_EMAIL");
    if(this.originalEmailAddress){
        var resendTo=this.originalEmailAddress;
        if(emailField){
            if(emailField.value.trim()!=this.originalEmailAddress){
                var params=new Array();
                resendTo=emailField.value.trim();
                params.push(new Array("EMAIL", resendTo));
                changeAccountInformation(params,changeEmailResultHandler);
					
            }
        }
        var invalidateAccount=false;
        var aSender = getResourceString(this,"ACCOUNT_ACTIVATION_MESSAGE_SENDER");
        var aSubject = getResourceString(this,"ACCOUNT_ACTIVATION_SUBJECT");
        var aMessage = getResourceString(this,"ACCOUNT_ACTIVATION_MESSAGE");
        var aMimeType = "text/plain";
        sendActivationEmail(invalidateAccount, aSender, aSubject, aMessage, aMimeType);
        //
        //
        var notifier=document.getElementById("emailSentNotifier");
        if(notifier){
            notifier.innerHTML="Email has been sent to "+resendTo;
        }
    }
}
function changeEmailResultHandler(code, message){
    if(code==0){
		
    }
    else{
        alert(code+", "+message);
    }
		
}


//
//
ClearspringSharingWidget.prototype.clearspringLibraryURL="http://widgets.clearspring.com/launchpad/include.js";

/**
	String that identifies the clearspring widget (and apparently your clearspring account as well)
*/
ClearspringSharingWidget.prototype.clearspringWidgetId=null;
/**
	String that passes all required configuration into your clearspring widget
	example:
	"{"mashid": "0"}"
*/
ClearspringSharingWidget.prototype.clearspringConfig=null;
/**
	css to use with your clearspring widget
*/
ClearspringSharingWidget.prototype.clearspringCSS="http://cdn.clearspring.com/launchpad/skins/white.css";
ClearspringSharingWidget.prototype.clearspringParams=null;


function ClearspringSharingWidget(id,domContainer,parentWidget){
    //
    //
    ClearspringSharingWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);

}
//
//
copyPrototype(ClearspringSharingWidget,Widget);
//
//
ClearspringSharingWidget.prototype.superClass=Widget.prototype;
ClearspringSharingWidget.prototype.forceRedraw = true;
//
//	
ClearspringSharingWidget.prototype.show=function(){
	//importJS(ClearspringSharingWidget.prototype.clearspringLibraryURL,function(){});
	ClearspringSharingWidget.prototype.superClass.show.call(this);
	var obj={};
	obj.targetElement=this.id+"_content";
	obj.wid = this.clearspringWidgetId;
	obj.config= this.clearspringConfig;
	obj.customCSS=this.clearspringCSS;
	if(this.clearspringParams){
		for(var i in this.clearspringParams){
			obj[i]=this.clearspringParams[i];
		}
	}
	
	if(typeof $Launchpad!="undefined"){
		$Launchpad.ShowMenu(obj);		
	}
	else{
		var timeoutObj={};
		timeoutObj.obj=obj;
		timeoutObj.widget=this;
		setTimeout(ClearspringSharingWidget_showClearspring,100,timeoutObj);
	}
}
ClearspringSharingWidget_showClearspring=function(timeoutObj){
	//
	//
	if(timeoutObj.widget.isOpen && timeoutObj.widget.visible){
		if(typeof $Launchpad!="undefined"){
				$Launchpad.ShowMenu(timeoutObj.obj);		
		}
		else{
			setTimeout(ClearspringSharingWidget_showClearspring,200,timeoutObj);
		}
	}
}
ClearspringSharingWidget.prototype.createDefaultDomModel=function(){
	var frag = document.createDocumentFragment();
	var theDiv=document.createElement('div');
	theDiv.setAttribute("id",this.id);
	theDiv.innerHTML='<div id="'+this.id+'_content"></div>';
	frag.appendChild(theDiv);
	return theDiv;
}


/*
	<!--Include this JavaScript library once in the BODY of your HTML page-->
<script type="text/javascript" src="http://widgets.clearspring.com/launchpad/include.js">
</script>

<!--This script invokes the Button or Menu-->
<script type="text/javascript">
$Launchpad.ShowMenu({wid: "47a180de045b700e", config: {"mashid": "0"}, customCSS: "http://cdn.clearspring.com/launchpad/skins/white.css"});
</script>
	
	
	targetElement=this.id+"_content";
*///
//
ContactUsWidget.prototype.datafieldPrefix="_DATA_";
ContactUsWidget.prototype.senderEmail = null; // if this.senderEmail is set, it overrides other mechanisms to set the sender email
//
//
function ContactUsWidget(id,domContainer,parentWidget){
    ContactUsWidget.prototype.superClass.constructor.call(this,id,domContainer,parentWidget);

    this.events.onMessageSent=new Delegate();
}
//
//
copyPrototype(ContactUsWidget,ContainerWidget);
//
//
ContactUsWidget.prototype.superClass=ContainerWidget.prototype;


ContactUsWidget.prototype.sendMessageButtonClicked=function(){
	this.sendContactUsMessage();
}
ContactUsWidget.prototype.sendContactUsMessage=function(){
	var data=this.getDataFromPage();
	var messageString="";
	for(var i in data){
		messageString+=i+" : \t"+data[i]+"\n\n";
	}
	var recipient=getResourceString(this,"CONTACT_US_MESSAGE_RECIPIENT");
	var subject=getResourceString(this,"CONTACT_US_MESSAGE_SUBJECT");
	if(recipient && messageString.length>0){
		var sender=getResourceString(this,"CONTACT_US_MESSAGE_DEFAULT_SENDER");;
		if(data && data.email && data.email.length>4){
			sender=data.email;
		}
        if(this.senderEmail) {
            sender = this.senderEmail;
        }
		sendEmail([recipient], subject, messageString, "text/plain", true, sender);
                this.events.onMessageSent.fireEvent(this);
	}
}

ContactUsWidget.prototype.getDataFromPage=function(){
	var d=document.getElementById(this.id);
	if(d){
		var inputFields = d.getElementsByTagName("input");
		var selectFields = d.getElementsByTagName("select");
		var textAreas = d.getElementsByTagName("textarea");
		var data=new Object();
		for(var i=0; i<inputFields.length; i++){
			var ids=inputFields[i].getAttribute("id");
			if(ids && ids.indexOf(this.id+this.datafieldPrefix)==0){
				data[ids.split(this.id+this.datafieldPrefix)[1]]=inputFields[i].value;
			}
		}
		for(var i=0; i<selectFields.length; i++){
			var ids=selectFields[i].getAttribute("id");
			if(ids && ids.indexOf(this.id+this.datafieldPrefix)==0){
				data[ids.split(this.id+this.datafieldPrefix)[1]]=selectFields[i].value;
			}
		}
		for(var i=0; i<textAreas.length; i++){
			var ids=textAreas[i].getAttribute("id");
			if(ids && ids.indexOf(this.id+this.datafieldPrefix)==0){
				data[ids.split(this.id+this.datafieldPrefix)[1]]=textAreas[i].value;
			}
		}
		return data;
	}
}/**
 * Import contacts from supported providers. Supported providers currently include
 * Yahoo mail, Gmail and Hotmail.
 */

/**
 * Import contacts from a 3rd party address book. Opens a new popup window
 * @param serviceProviderName Gmail | Hotmail | Yahoo
 * @param eventHandlerWidgetId Widget id that handles contact import events.
 *           The widget must be found at document.widgets[eventHandlerWidgetId] and the widget must implement function 
 *           contactsImportedEventHandler = function(sourceObjectInstance, eventObjectInstance).
 */
function importContactsFrom3rdPartyService(serviceProviderName, eventHandlerWidgetId) {
    //
    //
    var importContactsWindow = window.open('/jsp/importContacts.jsp?serviceProvider=' + serviceProviderName + '&eventHandlerWidgetId=' + eventHandlerWidgetId, '_blank', 'height=680,width=780,top=100,left=100');
    if(importContactsWindow) {
        importContactsWindow.focus();
    }
    else {
        alert("A pop-up blocker may be disabling the contact import");
    }
}

/**
 * Function that should be called on the page that receives imported contacts and passes them
 * to the handler widget that was originally passed to importContactsFrom3rdPartyService
 */
function handleContactsImportedFrom3rdPartyServiceResult(jsonElementName, eventHandlerWidgetId) {
    //
    //
    var jsonElement = document.getElementById(jsonElementName);
    if(jsonElement) {
        var jsonStr = jsonElement.innerHTML;
        var jsonObject = parseJSON(jsonStr);
        if(jsonObject && eventHandlerWidgetId) {
            var widgetMap = document.widgets;
            if(!widgetMap) {
                if(window.opener) {
                    widgetMap = window.opener.document.widgets;
                }
            }
            if(widgetMap) {
                var eventHandlerWidget = widgetMap[eventHandlerWidgetId];
                if(eventHandlerWidget && eventHandlerWidget.contactsImportedEventHandler) {
                    var importedContactsArray = jsonObject.contacts;
                    var eventObj = new Object();
                    eventObj.contactsArray = importedContactsArray;
                    eventHandlerWidget.contactsImportedEventHandler(null, eventObj);
                }
            }
        }
    }
}

