﻿
/**
 * ====================================================================
 * 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}}}}}();
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;
}
var tenduke={};
var tenduke = tenduke || {};
tenduke.util = tenduke.util || {};
/*!
Math.uuid.js (v1.4)
http://www.broofa.com
mailto:robert@broofa.com

Copyright (c) 2010 Robert Kieffer
Dual licensed under the MIT and GPL licenses.
*/

/*
 * Generate a random uuid.
 *
 * USAGE: Math.uuid(length, radix)
 *   length - the desired number of characters
 *   radix  - the number of allowable values for each character.
 *
 * EXAMPLES:
 *   // No arguments  - returns RFC4122, version 4 ID
 *   >>> Math.uuid()
 *   "92329D39-6F5C-4520-ABFC-AAB64544E172"
 * 
 *   // One argument - returns ID of the specified length
 *   >>> Math.uuid(15)     // 15 character ID (default base=62)
 *   "VcydxgltxrVZSTV"
 *
 *   // Two arguments - returns ID of the specified length, and radix. (Radix must be <= 62)
 *   >>> Math.uuid(8, 2)  // 8 character ID (base=2)
 *   "01001010"
 *   >>> Math.uuid(8, 10) // 8 character ID (base=10)
 *   "47473046"
 *   >>> Math.uuid(8, 16) // 8 character ID (base=16)
 *   "098F4D35"
 */
 var tenduke = tenduke || {};
tenduke.util = tenduke.util || {};
(function() {
  // Private array of chars to use
  var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); 
  var UUID={};
  UUID.uuid = function (len, radix) {
    var chars = CHARS, uuid = [];
    radix = radix || chars.length;

    if (len) {
      // Compact form
      for (var i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix];
    } else {
      // rfc4122, version 4 form
      var r;

      // rfc4122 requires these characters
      uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
      uuid[14] = '4';

      // Fill in random data.  At i==19 set the high bits of clock sequence as
      // per rfc4122, sec. 4.1.5
      for (var i = 0; i < 36; i++) {
        if (!uuid[i]) {
          r = 0 | Math.random()*16;
          uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
        }
      }
    }

    return uuid.join('');
  };

  // A more performant, but slightly bulkier, RFC4122v4 solution.  We boost performance
  // by minimizing calls to random()
  UUID.uuidFast = function() {
    var chars = CHARS, uuid = new Array(36), rnd=0, r;
    for (var i = 0; i < 36; i++) {
      if (i==8 || i==13 ||  i==18 || i==23) {
        uuid[i] = '-';
      } else {
        if (rnd <= 0x02) rnd = (0x2000000 + Math.random()*0x1000000)|0;
        r = rnd & 0xf;
        rnd = rnd >> 4;
        uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
      }
    }
    return uuid.join('');
  };

  // A more compact, but less performant, RFC4122v4 solution:
  UUID.uuidCompact = function() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
      var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
      return v.toString(16);
    }).toUpperCase();
  };
  tenduke.util.UUID=UUID;
})();
var tenduke = tenduke || {};
tenduke.util = tenduke.util || {};
(function() {

	var BrowserInfo= function(){}
	//
	//
	
   
    /*
	* appCodeName - The name of the browser's code such as "Mozilla".
	*/
    BrowserInfo.prototype.getAppCodeName=function(){
    	return navigator.appCodeName;
    }
    /*
     * appMinorVersion - The minor version number of the browser.
     */
    BrowserInfo.prototype.getAppMinorVersion=function(){
    	return navigator.appMinorVersion;
    }
    /*
    * appName - The name of the browser such as "Microsoft Internet Explorer" or "Netscape Navigator".
    */
    BrowserInfo.prototype.getAppName=function(){
    	return navigator.appName;
    }
    /*
    * appVersion - The version of the browser which may include a compatability value and operating system name.
    */
    BrowserInfo.prototype.getAppVersion=function(){
    	return navigator.appVersion;
    }
    /*
    * cookieEnabled - A boolean value of true or false depending on whether cookies are enabled in the browser.
    */
    BrowserInfo.prototype.isCookieEnabled=function(){
    	return navigator.cookieEnabled;
    }
    /*
    * cpuClass - The type of CPU which may be "x86"
    */
    BrowserInfo.prototype.getCpuClass=function(){
    	return navigator.cpuClass;
    }
    /*
    * mimeTypes - An array of MIME type descriptive strings that are supported by the browser.
    */
    BrowserInfo.prototype.getMimeTypes=function(){
    	return navigator.mimeTypes;
    }
    /*
    * onLine - A boolean value of true or false.
    */
    BrowserInfo.prototype.isOnLine=function(){
    	return navigator.onLine;
    }
    /*
    * opsProfile
    */
    BrowserInfo.prototype.getOpsProfile=function(){
    	return navigator.opsProfile;
    }
    /*
    * platform - A description of the operating system platform. In my case it is "Win32" for Windows 95.
    */
    BrowserInfo.prototype.getPlatform=function(){
    	return navigator.platform;
    }
    /*
    * plugins - An array of plug-ins supported by the browser and installed on the browser.
    */
    BrowserInfo.prototype.getPlugins=function(){
    	return navigator.plugins;
    }
    /*
    * systemLanguage - The language being used such as "en-us".
    */
    BrowserInfo.prototype.getSystemLanguage=function(){
    	return navigator.systemLanguage;
    }
    /*
    * userAgent - In my case it is "Mozilla/4.0 (compatible; MSIE 4.01; Windows 95)" which describes the browser associated user agent header.
    */
    BrowserInfo.prototype.getUserAgent=function(){
    	return navigator.userAgent;
    }
    /*
    * userLanguage - The languge the user is using such as "en-us".
    */
    BrowserInfo.prototype.getUserLanguage=function(){
    	return navigator.userLanguage;
    }
    /*
    * userProfile 
    */
    BrowserInfo.prototype.getUserProfile=function(){
    	return navigator.userProfile;
    }
    /*
    *window.screen.colorDepth;
    */
     BrowserInfo.prototype.getColorDepth=function(){
    	return window.screen.colorDepth;
    }
    /*
    *window.screen.width
    */
     BrowserInfo.prototype.getScreenWidth=function(){
    	return window.screen.width;
    }
    /*
    *window.screen.height
    */
     BrowserInfo.prototype.getScreenHeight=function(){
    	return window.screen.height;
    }
    /*
    *window.screen.availWidth
    */
     BrowserInfo.prototype.getScreenMaxWidth=function(){
    	return window.screen.availWidth;
    }
    /*
    *window.screen.availHeight
    */
     BrowserInfo.prototype.getScreenMaxHeight=function(){
    	return window.screen.availHeight;
    }
    /*
    *
    */
    BrowserInfo.prototype.isIE=function(){
      if (this.getAppVersion().indexOf("MSIE") != -1){
      	return true;
      }
      else{
      	return false;
      }
    }
	//
	//
	tenduke.util.BrowserInfo=new BrowserInfo();
})();// 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;
})();/** 
*/
/* IMPORTS / external dependencies
* hashtable.js
* tenduke.util.Base64
*/
/*
* Backwards compatibility support
*/
	var tenduke = tenduke || {};
	try{
		if(encode64){
			tenduke.util = tenduke.util || {};
			if(!tenduke.util.Base64){
				tenduke.util.Base64 = {};
				tenduke.util.Base64.encode64=encode64;
				tenduke.util.Base64.decode64=decode64;
			}
		}
	}catch(e){};
/*
* 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;
}var tenduke = tenduke || {};
tenduke.util = tenduke.util || {};

/**
 *
 */
(function() {

    /*
     * IMPORTS / dependencies to external assets
     */
    
    /*
     * END IMPORTS
     */

    /**
     * Creates new instance of DataValidation
     */
    var DataValidation = function(){}

    /**
     * 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
     *
     */
    
    /** Test for valid UUID syntax */
    DataValidation.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 */
    DataValidation.USERNAME_REG_EX=/^[0-9a-zA-Z]*$/;

    /** (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 */
    DataValidation.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) */
    DataValidation.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 */
    DataValidation.NAME_REG_EX=/^[a-zA-Z]+(([\'\,\.\-\_][a-zA-Z])?\s?[a-zA-Z]*)*$/;

    /** Test for ISO 8859-1 (Latin-1) */
    DataValidation.STRING_REG_EX=/^[\x00-\x7e\xa0-\xff]*$/;

    /** Test that the password is in ISO 8859-1 (Latin-1) and >=6 chars in length */
    DataValidation.PASSWORD_REG_EX=/^[\x21-\x7e\x80-\xfe]{6,}$/;

    /**
     * @param input, Input string to be validated
     * @param validationExpression, Validation regexp to use
     * @return true or false depending if input was validated using validationExpression.
     *         Method will return false if null or undefined arguments are passed.
     */
    DataValidation.validate = function(input, validationExpression) {
        //
        // sanity check args
        if (!input || !validationExpression || !validationExpression.test) {
            return false;
        }
        //
        // process validation
        if (validationExpression.test(input)) {
            return true;
        }
        else {
            return false;
        }
    }

    /**
     * Validates an username.
     * @param anUsername An username to validate.
     * @return true if anUsername is valid to use.
     */
    DataValidation.validateUsername = function(anUsername) {
        //
        //
        var retValue = false;
        //
        //
        if(anUsername) {
            retValue = DataValidation.validate(anUsername, DataValidation.USERNAME_REG_EX);
        }
        //
        //
        return retValue;
    }

    /**
     * Validates an UUID syntax.
     * @param anUuid An Uuid to validate.
     * @return true if anUuid is valid by syntax.
     */
    DataValidation.validateUuid = function(anUuid) {
        //
        //
        var retValue = false;
        //
        //
        if(anUuid) {
            retValue = DataValidation.validate(anUuid, DataValidation.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.
     */
    DataValidation.validateEmail = function(anEmail) {
        //
        //
        var retValue = false;
        //
        //
        if(anEmail) {
            anEmail = anEmail.replace(/\x00-\x32/, "");
            retValue = DataValidation.validate(anEmail, DataValidation.EMAIL_REG_EX);
        }
        //
        //
        return retValue;
    }

    
    //
    //
    tenduke.util.DataValidation = DataValidation;

})();
/**
 * 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;

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

/**
 * Serializer that support serializing object model objects to / from DukeXml format
 */
(function() {

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

    /**
     * Get array of field names that have the specified annotation set
     * @param type Class whose fields are queried
     * @param annotationType Required annotation class
     * @return Array of field names that have the specified annotation set
     */
    ReflectionUtils.getAnnotatedFieldNames = function(type, annotationType) {
        //
        var retValue = [];
        //
        
        if(type){
            if(type.prototype.superClass && type.prototype.superClass.constructor){
                var temp=ReflectionUtils.getAnnotatedFieldNames(type.prototype.superClass.constructor,annotationType);
                if(temp!=null){
                    retValue=temp;
                }
            }
            if(type.annotations) {
                //
                for(var annotatedFieldName in type.annotations) {
                    //
                    var fieldAnnotations = type.annotations[annotatedFieldName];
                    if(fieldAnnotations) {
                        //
                        for(var i = 0; i < fieldAnnotations.length; i++) {
                            var currentAnnotation = fieldAnnotations[i];
                            if(currentAnnotation && currentAnnotation.constructor == annotationType) {
                                retValue.push(annotatedFieldName);
                                break;
                            }
                        }
                    }
                }
            }
        }
        return retValue;
    }

    /**
     * Get array of annotation objects defined for a field of a class
     * @param type Class that owns field whose annotations are queried
     * @param fieldName Name of the field in the class
     * @param annotationType Required annotation class
     * @return Array of annotation objects (objects of class defined by annotationType)
     */
    ReflectionUtils.getFieldAnnotations = function(type, fieldName, annotationType) {
        //
        var retValue = [];
        //
        if(type) {
            //
            //
            if(type.prototype.superClass && type.prototype.superClass.constructor){
                retValue = ReflectionUtils.getFieldAnnotations(type.prototype.superClass.constructor,fieldName,annotationType);
                if(retValue==null){
                    retValue=[];
                }
            }
            //
            //
            if(type.annotations) {
                //
                var fieldAnnotations = type.annotations[fieldName];
                if(fieldAnnotations) {
                    //
                    for(var i = 0; i < fieldAnnotations.length; i++) {
                        var currentAnnotation = fieldAnnotations[i];
                        if(currentAnnotation && currentAnnotation.constructor == annotationType) {
                            retValue.push(currentAnnotation);
                        }
                    }
                }
            }
        }
        //
        return retValue;
    }

    /**
     * Get array of class annotations of type defined by annotationType
     * @param type Class whose annotations are queried
     * @param annotationType Required annotation class
     * @return Array of annotation objects (objects of class defined by annotationType)
     */
    ReflectionUtils.getClassAnnotations = function(type, annotationType) {
        //
        //
        var retValue = [];
        //
        //
        if(type.prototype.superClass && type.prototype.superClass.constructor) {
            retValue = ReflectionUtils.getClassAnnotations(type.prototype.superClass.constructor, annotationType);
            if(retValue==null) {
                retValue=[];
            }
        }
        //
        //
        if(type && type.annotations) {
            //
            for(var annotatedFieldName in type.annotations) {
                //
                var fieldAnnotations = type.annotations[annotatedFieldName];
                for(var i = 0; i < fieldAnnotations.length; i++) {
                    var currentAnnotation = fieldAnnotations[i];
                    if(currentAnnotation && currentAnnotation.constructor == annotationType) {
                        retValue.push(currentAnnotation);
                    }
                }
            }
        }
        //
        return retValue;
    }

    /**
     * Get name of field that has the given annotation object associated with it
     * @param type Class whose fields are checked for the given annotation object instance
     * @param annotation Annotation object
     * @return Name of field that has the given annotation object associated with it
     */
    ReflectionUtils.getFieldNameByAnnotation = function(type, annotation) {
        //
        //
        var retValue = null;
        //
        //
        if(type.prototype.superClass && type.prototype.superClass.constructor) {
            retValue = ReflectionUtils.getFieldNameByAnnotation(type.prototype.superClass.constructor, annotation);
        }
        //
        //
        if(retValue==null && type && type.annotations) {
            //
            for(var annotatedFieldName in type.annotations) {
                //
                var fieldAnnotations = type.annotations[annotatedFieldName];
                for(var i = 0; i < fieldAnnotations.length; i++) {
                    var currentAnnotation = fieldAnnotations[i];
                    if(currentAnnotation == annotation) {
                        retValue = annotatedFieldName;
                        break;
                    }
                }
                //
                if(retValue != null) {
                    break;
                }
            }
        }
        //
        //
        return retValue;
    }

    /**
     * Returns true if obj is instance of type or class inherited from type
     * @param obj Object to test
     * @param type Class against which tested
     * @return true if obj is instance of type or class inherited from type
     */
    ReflectionUtils.isInstanceOf = function(obj, type) {
        //
        return ReflectionUtils.isInheritedFrom(obj.constructor, type);
    }

    /**
     * Returns true if type is baseType or if type is inherited from baseType
     * @param type Class to test
     * @param baseType Class against which tested
     * @return true if type is baseType or if type is inherited from baseType
     */
    ReflectionUtils.isInheritedFrom = function(type, baseType) {
        //
        var retValue = false;
        //
        if(type == baseType) {
            retValue = true;
        }
        else if(type.prototype.superClass) {
            type = type.prototype.superClass.constructor;
            retValue = ReflectionUtils.isInheritedFrom(type, baseType);
        }
        //
        return retValue;
    }
    
    /**
     * Utility to copy js object prototype from object to another to mimic class inheritance
     * @param descendant Class to receive the prototypecopy
     * @param parent Class to copy from
     */
    ReflectionUtils.copyPrototype = function(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];
        }
    //
    };
    tenduke.util.ReflectionUtils = ReflectionUtils;

})();
/*
* declare global copyPrototype. The use of the global function should be refactored from all classes.
*/
var copyPrototype;
copyPrototype = tenduke.util.ReflectionUtils.copyPrototype;

/**
 * Utility class for working with XML and text that represents XML documents.
 */
(function() {
	//
	//Requires DOMParser from eg. sarissa 
    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 = this.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.js={};//
(function() {
    var Function_ = {};
    
    /**
     * 
     */
    Function_.createScopedFunction = function(scope, func) {
        return function() {
            if(func) {
                func.apply(scope, arguments);
            }
        };
    }
    
    tenduke.util.js.Function = Function_;
})();
tenduke.util.html={};//
//
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();
})();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() {
	//
	// Imports
	//
	// Constructor
	/*
	* 
	*/
	var BusyManager=function(){}
	//
	//
	BusyManager.prototype._tasks;
	BusyManager.prototype._defaultView;
	/*
	* get the View to use to indicate busy
	* Override to achieve app specific look
	*/
	BusyManager.prototype.getView=function(id){
		return this.getDefaultView();
	}
	BusyManager.prototype.getDefaultView=function(){
		if(!this._defaultView){
			var d=document.createElement("div");
			d.className="busyIndicator";
			var l=document.createElement("span");
			l.className="label";
			l.innerHTML="Loading";
			d.appendChild(l);
			this._defaultView=d;
		}
		return this._defaultView;
	}
	
	/** 
	* @param id a string id that identifies the caller
	* @param obj holds all additional paramteres. Extended when necessary
	*	obj.domNode triggering dom node if any
	*/
	BusyManager.prototype.startTask=function(id,obj){
		if(this._tasks==null ||this. _tasks==undefined){
			this._tasks=[];
		}
		var aTask={};
		aTask.id=id;
		aTask.params=obj;
		aTask.view=this.getView(id);
		this._tasks[this._tasks.length] = aTask;
		if(this._tasks.length==1 || aTask.view != this._defaultView){
			this._showBusyView(aTask.view);
		}
	}
	BusyManager.prototype.completeTask=function(id){
		if(this._tasks && this._tasks.length>0){
			for(var i=0; i<this._tasks.length; i++){
				if(this._tasks[i].id==id){
					var aTask=this._tasks[i];			
					this._tasks.splice(i,1);
					if(this._tasks.length==0 || aTask.view != this._defaultView){
						this._hideBusyView(aTask.view);
					}
					break;
				}
			}
		}
	}
	BusyManager.prototype._showBusyView=function(d){
		document.body.appendChild(d);
	}
	BusyManager.prototype._hideBusyView=function(d){
		try{
			document.body.removeChild(d);
		}
		catch(e){};
	}
	
	//
	//
	tenduke.util.html.BusyManager=BusyManager;
})();
var tenduke = tenduke || {};
tenduke.util = tenduke.util || {};
tenduke.util.html = tenduke.util.html || {};
(function() {
	//
	// Imports
	var BusyManager = tenduke.util.html.BusyManager;
	//
	// Constructor
	/*
	* static wrapping for simple access to busy state indication
	*/
	var BusyIndicator=function(){}
	//
	//
	/**
	* a temp holder for the BusyManager instance.
	* should be removed once the factory is in use
	*/
	var _busyManager;
	/** 
	* @param id a string id that identifies the caller
	* @param obj holds all additional paramteres. Extended when necessary
	*	obj.domNode triggering dom node if any
	* The idea is to use a BusyManagerFactory to create the manager. Factory should be implemented when necessary
	*/
	BusyIndicator.prototype.startTask=function(id,obj){
		if(_busyManager==null || _busyManager==undefined){
			_busyManager=new BusyManager();
		}
		_busyManager.startTask(id,obj);
	}
	BusyIndicator.prototype.completeTask=function(id){
		if(_busyManager!=null && _busyManager!=undefined){
			_busyManager.completeTask(id);
		}
	}
	
	//
	//
	tenduke.util.html.BusyIndicator=new BusyIndicator();
})();
// JavaScript Document
(function() {
	//
	// Package
	var _package=tenduke.util;
	//
	//
	var DOMUtils=tenduke.util.html.DOMUtils;
	var BrowserInfo=tenduke.util.BrowserInfo;
	//
	// 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(BrowserInfo.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();
})();// JavaScript Document
var tenduke = tenduke || {};
tenduke.reporting= tenduke.reporting || {};
(function() {
	/**
	 * Class that works as a hub, taking in reporting entries and publishing them to subscribers.
	 * @author jarno
	 */
	 /**
	 * Constructor - usually don't instantiate objects directly but use the singleton instance via Reporter.instance() static method
	 */
	Reporter=function(){
		_reportEntrySubscribers = [];
	}
	
	var _instance = null;
	/**
	 * List of subsribers to whom received reporting entries are relayed. Subscribers must implement
	 * ReportEntrySubscriber interface.
	 */
	var _reportEntrySubscribers = null;
	/**
	 * Returning handle to Logger singleton instance
	 * @return The singleton Logger instance
	 */
	Reporter.instance=function(){
		if (!_instance){
			_instance = new Reporter();
		}
		return _instance;
	}	
				
	/**
	 * Giving the reporter a new report entry that needs to distributed to subscribers of this reporter
	 * @param reportEntry The report entry to be distributed to the subscribers
	 */
	Reporter.prototype.addEntry = function (reportEntry){
		if (reportEntry){
			var currentTime = new Date();
			for (var i = 0; i < _reportEntrySubscribers.length; i++){
				var currentSubscriber = _reportEntrySubscribers[i];
				if (currentSubscriber){
					currentSubscriber.reportEntryReceived(reportEntry, currentTime);
				}
			}
		}
	}
	
	/**
	 * Subscribe to report entries distributed by this reporter
	 * @param subscriber The subscriber
	 */		
	Reporter.prototype.subscribe = function (subscriber){
		if (_arrayContainsValue(_reportEntrySubscribers, subscriber) == false){
			_reportEntrySubscribers[_reportEntrySubscribers.length]=subscriber;
		}
	}

	/**
	 * Unsubscribe from report entries distributed by this reporter
	 * @param subscriber The subscriber
	 */
	Reporter.prototype.unsubscribe = function (subscriber){
		_removeValueFromArray(_reportEntrySubscribers, subscriber);
	}
		
	function _arrayContainsValue(arr, value){
		var retVal=false;
		var len = arr.length;
		for(var i = len; i > -1; i--){
			if(arr[i] === value){
				retVal=true;
				break;
			}
		}
		return retVal;
	}
	
	function _removeValueFromArray(arr, value){
		var len = arr.length;
		for(var i = len; i > -1; i--){
			if(arr[i] === value){
				arr.splice(i, 1);
			}
		}
	}
	
	tenduke.reporting.Reporter=Reporter;
})(); // JavaScript Document
var tenduke = tenduke || {};
tenduke.reporting= tenduke.reporting || {};
(function() {
	
	var ReportEntrySubscriber = function (){};
	/**
	 * Method that is called for each ReportEntrySubscriber by Reporter when a new report entry is received.
	 * @param entry the report entry
	 */
	ReportEntrySubscriber.prototype.reportEntryReceived=function(entry, entryTime){}
	
	tenduke.reporting.ReportEntrySubscriber=ReportEntrySubscriber;
})(); // JavaScript Document
var tenduke = tenduke || {};
tenduke.reporting= tenduke.reporting || {};
(function() {
	/**
	 * Base class that represents an application event that needs to be reported.
	 * @author jarno
	 */
	 /**
	 * Creates a new ReportEntry
	 */
	var ReportEntry = function (){};
	/**
	 * Method that is called for each ReportEntrySubscriber by Reporter when a new report entry is received.
	 * @param entry the report entry
	 */
	ReportEntry.prototype.toString=function(){
		var retValue = null;
		return retValue;
	}
	tenduke.reporting.ReportEntry=ReportEntry;
})(); // JavaScript Document
var tenduke = tenduke || {};
tenduke.reporting= tenduke.reporting || {};
(function() {
	var ReportEntry=tenduke.reporting.ReportEntry;
	/**
	 * Usage report entry
	 * @author jarno
	 */
	var UsageReportEntry = function(resourceName){
		this._resourceName = resourceName;
	}
	
	copyPrototype(UsageReportEntry, ReportEntry);
    UsageReportEntry.prototype.superClass = ReportEntry.prototype;
    
	UsageReportEntry.prototype._resourceName=null;
	 
		
	UsageReportEntry.prototype.toString=function(){
		var retValue = this._resourceName;
		return retValue;
	}
	tenduke.reporting.UsageReportEntry=UsageReportEntry;
})(); // JavaScript Document
var tenduke = tenduke || {};
tenduke.reporting= tenduke.reporting || {};
(function() {
	/**
	 * Interface to be implemented by classes that filter ReportEntries
	 * @author jarkko
	 */
	 /**
	 * Creates a new ReportEntryFilter
	 */
	var ReportEntryFilter = function (){};
	/**
	 * Should this report entry be accepted or denied
	 * @param	reportEntry ReportEntry to be filtered
	 * @return	True if report entry is accepted
	 */
	ReportEntryFilter.prototype.accept=function(reportEntry){};
		
	tenduke.reporting.ReportEntryFilter=ReportEntryFilter;
})(); // JavaScript Document
var tenduke = tenduke || {};
tenduke.reporting= tenduke.reporting || {};
(function() {
	var ReportEntryFilter = tenduke.reporting.ReportEntryFilter;
	var UsageReportEntry = tenduke.reporting.UsageReportEntry;
	/**
	 * Filter for filtering UsageReportEntries
	 * @author jarkko
	 */
	 /**
	 * Creates a new UsageReportEntryFilter
	 */
	var UsageReportEntryFilter = function (){};


	copyPrototype(UsageReportEntryFilter, ReportEntryFilter);
    UsageReportEntryFilter.prototype.superClass = ReportEntryFilter.prototype;
	
	/**
	 * Should this report entry be accepted or denied
	 * @param	reportEntry ReportEntry to be filtered
	 * @return	True if report entry is accepted
	 */
	UsageReportEntryFilter.prototype.accept=function(reportEntry){
		return (reportEntry.constructor == UsageReportEntry);
	}
		
	tenduke.reporting.UsageReportEntryFilter=UsageReportEntryFilter;
})(); // JavaScript Document
var tenduke = tenduke || {};
tenduke.reporting= tenduke.reporting || {};
(function() {
	var ReportEntrySubscriber=tenduke.reporting.ReportEntrySubscriber;	
	/**
	 * Track usage with Google Analytics
	 * @author jarno
	 */
 	/**
	 * 
	 * @param	filter
	 * @param	account
	 */
	var GoogleAnalyticsTrackerReportEntrySubscriber = function(filter, account){
		this._account = account;
		this._filter = filter;
		this._trackerInitialized = false;
	}
	copyPrototype(GoogleAnalyticsTrackerReportEntrySubscriber, ReportEntrySubscriber);
    GoogleAnalyticsTrackerReportEntrySubscriber.prototype.superClass = ReportEntrySubscriber.prototype;	
	
	GoogleAnalyticsTrackerReportEntrySubscriber.prototype._filter=null;
	GoogleAnalyticsTrackerReportEntrySubscriber.prototype._trackerInitialized=null;
	GoogleAnalyticsTrackerReportEntrySubscriber.prototype._account=null;
	GoogleAnalyticsTrackerReportEntrySubscriber.prototype._tracker=null;
		
		
	GoogleAnalyticsTrackerReportEntrySubscriber.prototype.reportEntryReceived=function(entry, entryTime){
		if (this._trackerInitialized == false){
			this._initializeTracker();
		}
		if (this._tracker != null){
			var accept = true;
			if (this._filter != null){
				accept = this._filter.accept(entry);
			}
			if (accept == true){
				try{
					var reportUsageMessage = entry.toString();
					this._tracker._trackPageview(reportUsageMessage);
				}
				catch (error){}
			}
		}
	}
		
	GoogleAnalyticsTrackerReportEntrySubscriber.prototype._initializeTracker=function(){
		if (this._account == null || this._account.length == 0)
		{
			alert("GoogleAnalyticsTrackerReportEntrySubscriber._initializeTracker: account Missing");
		}
		if (this._account != null && this._account.length > 0){
			try{
				if(_gat && _gat._getTracker){
					this._tracker = _gat._getTracker(this._account);
				}
			}
			catch (error){}
		}
		this._trackerInitialized = true;
	}
		
	tenduke.reporting.GoogleAnalyticsTrackerReportEntrySubscriber=GoogleAnalyticsTrackerReportEntrySubscriber;
})();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
   	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
    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
	* 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;
})();//
// 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.prototype.classSimpleName = "TendukeObject";

    //
    // Introduce using annotations
    TendukeObject.annotations = {};
    
    /** */
    TendukeObject.annotations._id = [ new SerializableField("id") ];
    TendukeObject.prototype._id = null;

    /** */
    TendukeObject.annotations._created = [ new SerializableField("created") ];
    TendukeObject.prototype._created = null;

    /** */
    TendukeObject.annotations._modified = [ new SerializableField("modified") ];
    TendukeObject.prototype._modified = null;
    
    /** */
    TendukeObject.prototype.getId = function() {
        return this._id;
    }
    
    /** */
    TendukeObject.prototype.setId = function(rhs) {
        this._id = rhs;
    }

    /** */
    TendukeObject.prototype.getCreated = function() {
        return this._created;
    }

    /** */
    TendukeObject.prototype.setCreated = function(rhs) {
        this._created = rhs;
    }

    /** */
    TendukeObject.prototype.getModified = function() {
        return this._modified;
    }

    /** */
    TendukeObject.prototype.setModified = function(rhs) {
        this._modified = rhs;
    }

    tenduke.objectmodel.TendukeObject = TendukeObject;

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

/**
 * Serializer that support serializing object model objects (TendukeObjects) to / from DukeXml format
 */
(function() {
    //
    // Imports
    var ReflectionUtils = tenduke.util.ReflectionUtils;
    var SerializableField = tenduke.objectmodel.SerializableField;
    var TendukeObject = tenduke.objectmodel.TendukeObject;

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

    /**
     * Serialize TendukeObject to DukeXml
     * @param obj Object model object to serialize
     * @return DukeXml representation of the object
     */
    DukeXmlSerializer.prototype.serialize = function(obj) {
        //
        return serializeRecursively(obj);
    }

    /**
     * Deserialized serialized TendukeObject
     * @param serialized DukeXml serialized representation of the object to deserialize
     * @return Deserialized TendukeObject
     */
    DukeXmlSerializer.prototype.deserialize = function(serialized) {
        //
        return deserializeRecursively(serialized);
    }

    function serializeRecursively(obj) {
        //
        var serialized = "";
        //
        var fieldsToSerializeNames = ReflectionUtils.getAnnotatedFieldNames(obj.constructor, SerializableField);
        if(fieldsToSerializeNames) {
            //
            var fieldsToSerializeAsAttributesNames = [];
            var fieldsToSerializeAsChildrenNames = [];
            sortFields(obj, fieldsToSerializeNames, fieldsToSerializeAsAttributesNames, fieldsToSerializeAsChildrenNames);
            //
            var objectElementName = obj.classSimpleName;
            //
            serialized += "<";
            serialized += objectElementName;
            //
            serialized += serializeAttributes(obj, fieldsToSerializeAsAttributesNames);
            serialized += ">";
            //
            serialized += serializeChildElements(obj, fieldsToSerializeAsChildrenNames);
            //
            serialized += "</";
            serialized += objectElementName;
            serialized += ">";
        }
        //
        return serialized;
    }

    function serializeChildElements(obj, fieldsToSerializeAsChildrenNames) {
        //
        var retValue = "";
        //
        for(var i = 0; i < fieldsToSerializeAsChildrenNames.length; i++) {
            var currentFieldToSerializeAsChildName = fieldsToSerializeAsChildrenNames[i];
            retValue += serializeChildElement(obj, currentFieldToSerializeAsChildName);
        }
        //
        return retValue;
    }

    function serializeChildElement(obj, fieldToSerializeAsChildName) {
        //
        var retValue = "";
        //
        var fieldToSerialize = obj[fieldToSerializeAsChildName];
        var nodeName = getSerializeNodeNameForField(obj, fieldToSerializeAsChildName);
        if(null != fieldToSerialize && undefined != fieldToSerialize) {
            //
            retValue = "<" + nodeName + ">";
            if(typeof(fieldToSerialize) == "string") {
                //
                retValue += fieldToSerialize;
            }
            //
            else if(fieldToSerialize instanceof Array && fieldToSerialize.length > 0) {
                //
                var relationMultiplicity = getFieldRelationMultiplicity(obj.constructor, fieldToSerializeAsChildName);
                if(relationMultiplicity == SerializableField.RELATION_ONE_TO_ONE || relationMultiplicity == SerializableField.RELATION_MANY_TO_ONE) {
                    retValue += serializeRecursively(fieldToSerialize[0]);
                }
                else if(relationMultiplicity == SerializableField.RELATION_ONE_TO_MANY || relationMultiplicity == SerializableField.RELATION_MANY_TO_MANY) {
                    retValue += serializePlural(fieldToSerialize);
                }
            }
            else if(ReflectionUtils.isInstanceOf(fieldToSerialize, TendukeObject) == true) {
                //
                retValue += serializeRecursively(fieldToSerialize);
            }
            retValue += "</" + nodeName + ">";
        }
        //
        return retValue;
    }

    function serializePlural(fieldToSerialize) {
        //
        var retValue = "";
        //
        if(fieldToSerialize instanceof Array && fieldToSerialize.length > 0) {
            //
            var firstObjectToSerialize = fieldToSerialize[0];
            if(null != firstObjectToSerialize && undefined != firstObjectToSerialize &&
                    firstObjectToSerialize.constructor && firstObjectToSerialize.classSimpleName) {
                //
                var pluralTagName = firstObjectToSerialize.classSimpleName + "List";
                retValue += "<" + pluralTagName + ">";
                //
                for(var i = 0; i < fieldToSerialize.length; i++) {
                    //
                    retValue += serializeRecursively(fieldToSerialize[i]);
                }
                //
                retValue += "</" + pluralTagName + ">";
            }
        }
        //
        return retValue;
    }

    function serializeAttributes(obj, fieldsToSerializeAsAttributesNames) {
        //
        var retValue = "";
        //
        for(var i = 0; i < fieldsToSerializeAsAttributesNames.length; i++) {
            var currentFieldToSerializeAsAttributeName = fieldsToSerializeAsAttributesNames[i];
            retValue += serializeAttribute(obj, currentFieldToSerializeAsAttributeName);
        }
        //
        return retValue;
    }

    function serializeAttribute(obj, fieldToSerializeAsAttributeName) {
        //
        var retValue = "";
        //
        var fieldToSerialize = obj[fieldToSerializeAsAttributeName];
        var nodeName = getSerializeNodeNameForField(obj, fieldToSerializeAsAttributeName);
        if(null != fieldToSerialize && undefined != fieldToSerialize) {
            retValue = " " + nodeName + "=\"" + fieldToSerialize + "\"";
        }
        //
        return retValue;
    }

    function getFieldSerializableFieldAnnotations(obj, fieldName) {
        //
        var serializableFieldAnnotationObjects = ReflectionUtils.getFieldAnnotations(obj.constructor, fieldName, SerializableField);
        return serializableFieldAnnotationObjects;
    }

    function getSerializeNodeNameForField(obj, fieldName) {
        //
        var serializableFieldAnnotations = getFieldSerializableFieldAnnotations(obj, fieldName);
        var nodeName = "";
        if(serializableFieldAnnotations && serializableFieldAnnotations.length > 0) {
            nodeName = serializableFieldAnnotations[0].getName();
        }
        //
        return nodeName;
    }

    function sortFields(obj, fieldsToSerializeNames, fieldsToSerializeAsAttributesNames, fieldsToSerializeAsChildrenNames) {
        //
        for(var i = 0; i < fieldsToSerializeNames.length; i++) {
            //
            var fieldToSerializeName = fieldsToSerializeNames[i];
            var fieldToSerialize = obj[fieldToSerializeName];
            //
            if(null != fieldToSerialize && undefined != fieldToSerialize) {
                //
                if(isFieldSerializableAsAttribute(fieldToSerialize, fieldToSerializeName) == true) {
                    //
                    fieldsToSerializeAsAttributesNames.push(fieldToSerializeName);
                }
                else {
                    //
                    fieldsToSerializeAsChildrenNames.push(fieldToSerializeName);
                }
            }
        }
    }

    function isFieldSerializableAsAttribute(field, fieldName) {
        //
        var retValue = false;
        //
        var fieldType = typeof(field);
        if(fieldType == "number" ||
            fieldType == "boolean" ||
            fieldName == "_id" ||
            fieldName == "id" ||
            fieldName.lastIndexOf("Id")==fieldName.length-2 ||
            (fieldType == "object" && field.constructor == Date)) {
            //
            retValue = true;
        }
        //
        return retValue;
    }

    function deserializeRecursively(serialized) {
        //
        var retValue = null;
        //
        var parser = null;
        var serializedXml=null;
        if(typeof serialized =="string"){
        	parser = new DOMParser();
        	serializedXml = parser.parseFromString(serialized, "text/xml");
        }
        else{
        	serializedXml = serialized;
        }
        if(serializedXml) {
            if(serializedXml.nodeName == "#document") {
                serializedXml = serializedXml.firstChild;
            }
            retValue = deserializeXmlNodeRecursively(serializedXml);
        }
        //
        return retValue;
    }

    function deserializeXmlNodeRecursively(node) {
        //
        var objectClassName = node.nodeName;
        var objectClass = tenduke.objectmodel[objectClassName];
        var deserializedObject = new objectClass();
        deserializeObject(node, deserializedObject);
        //
        return deserializedObject;
    }

    function deserializeObject(node, deserializedObject) {
        //
        var fieldsToDeserializeNames = ReflectionUtils.getAnnotatedFieldNames(deserializedObject.constructor, SerializableField);
        if(fieldsToDeserializeNames) {
            //
            deserializeAttributes(node, deserializedObject);
            deserializeChildElements(node, deserializedObject);
        }
    }

    function deserializeAttributes(node, deserializedObject) {
        //
        for(var i = 0; i < node.attributes.length; i++) {
            //
            var fieldToDeserializeName = node.attributes[i].nodeName;
            deserializeAttribute(node, deserializedObject, fieldToDeserializeName);
        }
    }

    function deserializeAttribute(node, deserializedObject, fieldToDeserializeName) {
        //
        var fieldName = findFieldNameBySerializableFieldAnnotationName(deserializedObject, fieldToDeserializeName);
        if(fieldName != null) {
            //
            var value = node.getAttribute(fieldToDeserializeName);
            deserializedObject[fieldName] = value;
        }
    }

    function deserializeChildElements(node, deserializedObject) {
        //
        for(var i = 0; i < node.childNodes.length; i++) {
            //
            var fieldToDeserializeName = node.childNodes[i].nodeName;
            deserializeChildElement(node, deserializedObject, fieldToDeserializeName);
        }
    }

    function deserializeChildElement(node, deserializedObject, fieldToDeserializeName) {
        //
        var fieldName = findFieldNameBySerializableFieldAnnotationName(deserializedObject, fieldToDeserializeName);
        if(fieldName != null) {
            //
            for(var i = 0; i < node.childNodes.length; i++) {
                //
                var currentChild = node.childNodes[i];
                if(currentChild.nodeName == fieldToDeserializeName) {
                    //
                    //
                    var value=null;
                    if(currentChild.childNodes && currentChild.childNodes.length>0){
                    	value='';
                    	for(var j=0; j<currentChild.childNodes.length; j++){
                    		value+=currentChild.childNodes[j].data;
                    	}
                    }
                    else{
	                    value = currentChild.innerText || currentChild.textContent;
	                }
                    deserializedObject[fieldName] = value;
                    //
                    //
                    var relationMultiplicity = getFieldRelationMultiplicity(deserializedObject.constructor, fieldName);
                    if(relationMultiplicity == SerializableField.RELATION_ONE_TO_ONE || relationMultiplicity == SerializableField.RELATION_MANY_TO_ONE) {
                        //
                        if(currentChild.firstChild) {
                            //
                            deserializedObject[fieldName] = [];
                            deserializedObject[fieldName].push(deserializeXmlNodeRecursively(currentChild.firstChild));
                        }
                    }
                    else if(relationMultiplicity == SerializableField.RELATION_ONE_TO_MANY || relationMultiplicity == SerializableField.RELATION_MANY_TO_MANY) {
                        //
                        if(currentChild.firstChild && currentChild.firstChild.childNodes && currentChild.firstChild.childNodes.length > 0) {
                            //
                            deserializedObject[fieldName] = [];
                            for(var j = 0; j < currentChild.firstChild.childNodes.length; j++) {
                                deserializedObject[fieldName].push(deserializeXmlNodeRecursively(currentChild.firstChild.childNodes[j]));
                            }
                        }
                    }
                    break;
                }
            }
        }
    }

    function findFieldNameBySerializableFieldAnnotationName(deserializedObject, fieldToDeserializeName) {
        //
        var retValue = null;
        //
        var classSerializableFieldAnnotations = ReflectionUtils.getClassAnnotations(deserializedObject.constructor, SerializableField);
       
        for(var i = 0; i < classSerializableFieldAnnotations.length; i++) {
            //
            var currentSerializableFieldAnnotation = classSerializableFieldAnnotations[i];
            if(currentSerializableFieldAnnotation.getName() == fieldToDeserializeName) {
                //
                retValue = ReflectionUtils.getFieldNameByAnnotation(deserializedObject.constructor, currentSerializableFieldAnnotation);
                break;
            }
        }
        //
        return retValue;
    }

    function getFieldRelationMultiplicity(type, fieldName) {
        //
        var retValue = null;
        //
        var serializableFieldAnnotations = ReflectionUtils.getFieldAnnotations(type, fieldName, SerializableField);
        if(serializableFieldAnnotations && serializableFieldAnnotations.length > 0) {
            retValue = serializableFieldAnnotations[0].getRelation();
        }
        //
        return retValue;
    }

    tenduke.objectmodel.serialization.DukeXmlSerializer = DukeXmlSerializer;

})();
//
// initialize package
var tenduke = tenduke || {};
tenduke.objectmodel = tenduke.objectmodel || {};

/**
 * Object model class for TendukeSetObject
 */
(function() {
    //
    // Imports
    var SerializableField = tenduke.objectmodel.SerializableField;
    var TendukeObject = tenduke.objectmodel.TendukeObject;
    
    //
    // Constructor
    var TendukeSetObject = function() {
        TendukeSetObject.prototype.superClass.constructor.call();
    };
    copyPrototype(TendukeSetObject,TendukeObject);
    TendukeSetObject.prototype.superClass=TendukeObject.prototype;
    TendukeSetObject.prototype.classSimpleName = "TendukeSetObject";
    
    
    //
    // Introduce using annotations
    TendukeSetObject.annotations = {};
    
    /** */
    TendukeSetObject.annotations._index = [ new SerializableField("index") ];
    TendukeSetObject.prototype._index = null;
    
    /** */
    TendukeSetObject.prototype.getIndex = function() {
        return this._index;
    }
    
    /** */
    TendukeSetObject.prototype.setIndex = function(rhs) {
        this._index = ind;
    }  
	
    tenduke.objectmodel.TendukeSetObject = TendukeSetObject;

})();//
// 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();
    };

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

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

    /** */
    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._id;
    }
    
    /** */
    Account.prototype.setAccountId = function(rhs) {
        this._id = 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();
    };
    copyPrototype(Profile,TendukeObject);
    Profile.prototype.superClass=TendukeObject.prototype;
    Profile.prototype.classSimpleName = "Profile";

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


    /** */
    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._id;
    }
    
    /** */
    Profile.prototype.setProfileId = function(rhs) {
        this._id = 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 Entry
 */
(function() {
    //
    // Imports
    var SerializableField = tenduke.objectmodel.SerializableField;
    var TendukeSetObject = tenduke.objectmodel.TendukeSetObject;
    

    /**
     * Entry represents an asset in the system with associated metadata. This is base class, derived concrete Entry
     * classes include VideoEntry, ImageEntry, AudioEntry, DocumentEntry etc.
     * @author jarno
     */
    //
    // Constructor
    var Entry = function() {
        Entry.prototype.superClass.constructor.call();
    };

    //
    //
    copyPrototype(Entry,TendukeSetObject);
    //
    //
    Entry.prototype.superClass = TendukeSetObject.prototype;
    //
    //
    Entry.prototype.classSimpleName = "Entry";    
    //
    // Introduce using annotations
    Entry.annotations = {};
    
    /** */
    Entry.annotations._objectPath = [ new SerializableField("objectPath") ];
    Entry.prototype._objectPath = null;
    /** */
    Entry.annotations._objectName = [ new SerializableField("objectName") ];
    Entry.prototype._objectName = null;
    /** */
    Entry.annotations._cdnId = [ new SerializableField("cdnId") ];
    Entry.prototype._cdnId = null;
    /** */
    Entry.annotations._displayName = [ new SerializableField("displayName") ];
    Entry.prototype._displayName = null;
    /** */
    Entry.annotations._description = [ new SerializableField("description") ];
    Entry.prototype._description = null;
    /** */
    Entry.annotations._isPublic = [ new SerializableField("isPublic") ];
    Entry.prototype._isPublic = false;
    /** */
    Entry.annotations._isDeleted = [ new SerializableField("isDeleted") ];
    Entry.prototype._isDeleted = false;
    /** */
    Entry.annotations._consumptionCount = [ new SerializableField("consumptionCount") ];
    Entry.prototype._consumptionCount = null;
    /** */
    Entry.annotations._rating = [ new SerializableField("rating") ];
    Entry.prototype._rating = null;
    /** */
    Entry.annotations._ratingCount = [ new SerializableField("ratingCount") ];
    Entry.prototype._ratingCount = null;
    /** */
    Entry.annotations._voteCount = [ new SerializableField("voteCount") ];
    Entry.prototype._voteCount = null;
    /** */
    Entry.annotations._entryDate = [ new SerializableField("entryDate") ];
    Entry.prototype._entryDate = null;
    /** */
    Entry.annotations._profileId = [ new SerializableField("profileId") ];
    Entry.prototype._profileId = null;
    /** */
    Entry.annotations._profile = [ new SerializableField("profile") ];
    Entry.prototype._profile = [] // List of Profile
    /** */
    Entry.annotations._entryIndex = [ new SerializableField("entryIndex") ];
    Entry.prototype._entryIndex = null;
    /** */
    Entry.annotations._comments = [ new SerializableField("comments", SerializableField.RELATION_ONE_TO_MANY)];
    Entry.prototype._comments = [];
    /** */
    Entry.annotations._tags = [ new SerializableField("tags", SerializableField.RELATION_MANY_TO_MANY)];
    Entry.prototype._tags = [];
    /** */
    Entry.annotations._groups = [ new SerializableField("groups", SerializableField.RELATION_MANY_TO_MANY)];
    Entry.prototype._groups = [];
    /** */
    Entry.annotations._media = [ new SerializableField("media", SerializableField.RELATION_ONE_TO_MANY)];
    Entry.prototype._media = [];
    /** */
    Entry.annotations._placemarks = [ new SerializableField("placemarks", SerializableField.RELATION_MANY_TO_MANY)];
    Entry.prototype._placemarks = [];
    /** */
    Entry.annotations._channels = [ new SerializableField("channels", SerializableField.RELATION_MANY_TO_MANY)];
    Entry.prototype._channels = [];
    
    /** */
    Entry.prototype.getObjectPath=function()
    {
        return this._objectPath;
    }
    /** */
    Entry.prototype.setObjectPath=function(value)
    {
        this._objectPath = value;
    }
		
    /** */
    Entry.prototype.getObjectName=function()
    {
        return this._objectName;
    }
    Entry.prototype.setObjectName=function(value)
    {
        this._objectName = value;
    }
	

    Entry.prototype.getCdnId=function() // Integer
    {
        return this._cdnId;
    }
    Entry.prototype.setCdnId=function(value /* Integer */)
    {
        this._cdnId = value;
    }
	
    Entry.prototype.getDisplayName=function()
    {
        return this._displayName;
    }
    Entry.prototype.setDisplayName=function(value)
    {
        this._displayName = value;
    }
	

    Entry.prototype.getDescription=function()
    {
        return this._description;
    }
    Entry.prototype.setDescription=function(value)
    {
        this._description = value;
    }
	
    Entry.prototype.getIsPublic=function()
    {
        return this._isPublic;
    }
    Entry.prototype.setIsPublic=function(value)
    {
        this._isPublic = value;
    }
	
    Entry.prototype.getIsDeleted=function()
    {
        return this._isDeleted;
    }
    Entry.prototype.setIsDeleted=function(value)
    {
        this._isDeleted = value;
    }
	
    Entry.prototype.getConsumptionCount=function()// Long
    {
        return this._consumptionCount;
    }
    Entry.prototype.setConsumptionCount=function(value /* Long */)
    {
        this._consumptionCount = value;
    }
	
    Entry.prototype.getRating=function() // Double
    {
        return this._rating;
    }
    Entry.prototype.setRating=function(value /* Double */)
    {
        this._rating = value;
    }
	
    Entry.prototype.getRatingCount=function() // Long
    {
        return this._ratingCount;
    }
    Entry.prototype.setRatingCount=function(value /* Long */)
    {
        this._ratingCount = value;
    }
	
    Entry.prototype.getVoteCount=function() // Long
    {
        return this._voteCount;
    }
    Entry.prototype.setVoteCount=function(value /* Long */)
    {
        this._voteCount = value;
    }
	
    Entry.prototype.getEntryDate=function()
    {
        return this._entryDate;
    }
    Entry.prototype.setEntryDate=function(value)
    {
        this._entryDate = value;
    }
	
    Entry.prototype.getProfileId=function() // UUID
    {
        return this._profileId;
    }
    Entry.prototype.setProfileId=function(value /* UUID */)
    {
        this._profileId = value;
    }
	
    Entry.prototype.getProfiles=function() // List of Profile
    {
        return this._profile;
    }
	
    Entry.prototype.setProfiles=function(value/* List of Profile */)
    {
        this._profile = value;
    }
	
    Entry.prototype.getEntryIndex=function() // Integer
    {
        return this._entryIndex;
    }
	
    Entry.prototype.setEntryIndex=function(value /* Integer */)
    {
        this._entryIndex = value;
    }
	
    Entry.prototype.getComments=function()
    {
        return this._comments;
    }
    Entry.prototype.setComments=function(value)
    {
        this._comments = value;
    }
	
    Entry.prototype.getTags=function()
    {
        return this._tags;
    }
    Entry.prototype.setTags=function(value)
    {
        this._tags = value;
    }
	
    Entry.prototype.getGroups=function()
    {
        return this._groups;
    }
    Entry.prototype.setGroups=function(value)
    {
        this._groups = value;
    }
	
    Entry.prototype.getMedia=function()
    {
        return this._media;
    }
    Entry.prototype.setMedia=function(value)
    {
        this._media = value;
    }
	
    Entry.prototype.getPlacemarks=function()
    {
        return this._placemarks;
    }
    Entry.prototype.setPlacemarks=function(value)
    {
        this._placemarks = value;
    }
	
    Entry.prototype.getChannels=function()
    {
        return this._channels;
    }
    Entry.prototype.setChannels=function(value)
    {
        this._channels = value;
    }
	
    //} endregion
	
    //{ region methods
	
	
    /**
     * Get profile associated with this entry
     * @return
     */
    Entry.prototype.getProfile=function()
    {
        var retValue = null;
        if (this._profile != null && this._profile.length > 0)
        {
            retValue = profile[0];
        }
        return retValue;
    }
	
    //} endregion

	
    tenduke.objectmodel.Entry = Entry;

})();//
// initialize package
var tenduke = tenduke || {};
tenduke.objectmodel = tenduke.objectmodel || {};

/**
 * Object model class for VideoEntry
 */
(function() {
    //
    // Imports
	var Entry = tenduke.objectmodel.Entry;    

    /**
	 * Entry represents an asset in the system with associated metadata. This is base class, derived concrete Entry
	 * classes include VideoEntry, ImageEntry, AudioEntry, DocumentEntry etc.
	 * @author jarno
	 */
	//
    // Constructor
    var VideoEntry = function() {
        VideoEntry.prototype.superClass.constructor.call();
    };
    copyPrototype(VideoEntry,Entry);
    VideoEntry.prototype.superClass=Entry.prototype;
    
    VideoEntry.prototype.classSimpleName = "VideoEntry";
    
    
    tenduke.objectmodel.VideoEntry = VideoEntry;
})();
//
// 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();
    };

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

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

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

    /** */
    ContactDetails.annotations._contactId = [ new SerializableField("contactId") ];
    ContactDetails.prototype._contactId = 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", SerializableField.RELATION_ONE_TO_MANY)];
    ContactDetails.prototype._emails = new Array();

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

    /** */
    ContactDetails.prototype.getContactDetailsId = function() {
        return this._id;
    }
    
    /** */
    ContactDetails.prototype.setContactDetailsId = function(rhs) {
        this._id = rhs;
    }
    /** */
    ContactDetails.prototype.getContactId = function() {
        return this._contactId;
    }
    
    /** */
    ContactDetails.prototype.setContactId = function(rhs) {
        this._contactId = 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();
    };

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

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

    /** */
    EmailAddress.annotations._contactDetailsId = [ new SerializableField("contactDetailsId") ];
    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._id;
    }
    
    /** */
    EmailAddress.prototype.setEmailAddressId = function(rhs) {
        this._id = 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();
    };

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

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

    /** */
    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._id;
    }
    
    /** */
    PostalAddress.prototype.setPostalAddressId = function(rhs) {
        this._id = 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;

})();
//
// 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 Contact = function() {
        Contact.prototype.superClass.constructor.call();
    };
    copyPrototype(Contact,TendukeObject);
    Contact.prototype.superClass=TendukeObject.prototype;
    Contact.prototype.classSimpleName = "Contact";

    //
    // Introduce using annotations
    Contact.annotations = {};


    /** */
    Contact.annotations._ownerId = [ new SerializableField("ownerId") ];
    Contact.prototype._ownerId = null;

    /** */
    Contact.annotations._contactDetails = [ new SerializableField("contactDetails", SerializableField.RELATION_ONE_TO_MANY)];
    Contact.prototype._contactDetails = null;


    /** */
    Contact.prototype.getContactId = function() {
        return this._id;
    }
    
    /** */
    Contact.prototype.setContactId = function(rhs) {
        this._id = rhs;
    }
    
    /** */
    Contact.prototype.getOwnerId = function() {
        return this._ownerId;
    }
    
    /** */
    Contact.prototype.setOwnerId = function(rhs) {
        this._ownerId = rhs;
    }  
    
    /** */
    Contact.prototype.setContactDetails = function(rhs) {
        this._contactDetails = new Array();
        this._contactDetails.push(rhs);
    }

    /** */
    Contact.prototype.getContactDetails = function() {
        var retValue = null;
        if(this._contactDetails  && this._contactDetails.length>0) {
            retValue = this._contactDetails[0];
        }
        return retValue;
    }

    tenduke.objectmodel.Contact = Contact;

})();
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;
    }
    Request.prototype.getNumCommandOKs=function(response) {
	    var retValue = -1;
        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;
	}
    //
    //
    tenduke.serverinterface.Request = Request;
})();var tenduke = tenduke || {};
tenduke.serverinterface = tenduke.serverinterface || {};
(function() {
    //
    //IMPORTS
    var Request = tenduke.serverinterface.Request;
    var RequestParameters = tenduke.networking.RequestParameters;
    /*
    * this import can not be used. tenduke.networking.Request should be overridden in application specific files
    * using the imported resource will point to an empty baseclass implementation that does not execute
    */
    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 _Function = tenduke.util.js.Function;
    var Cookies = tenduke.util.html.Cookies;
   	var XmlUtils = tenduke.util.XmlUtils;

    /**
     * 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);
    }
	LoginRequest.prototype.loginPrincipalFieldName = "shortName";
	LoginRequest.prototype.LOGIN_SUCCESS= 0;
	LoginRequest.prototype.LOGIN_FAILED = 1;
	LoginRequest.prototype.ALREADY_LOGGED_IN = 2;
	LoginRequest.prototype.AUTHENTICATION_FAILED = 5;
	LoginRequest.prototype.LOGIN_OPERATION_LOGIN =  "LOGIN";
	LoginRequest.prototype.LOGIN_OPERATION_LOGOUT =  "LOGOUT";
	LoginRequest.prototype.ACCOUNT_VALIDATED_COOKIE_NAME = "accountValidated";
	LoginRequest.prototype.LOGIN_STATE_COOKIE_NAME = "LOGIN_STATE";
	LoginRequest.prototype.emailValidationRequired = false;
    /**
     * @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:"") + "&" + this.loginPrincipalFieldName + "=" + userName + (password ? "&PASSWORD=" + password:"");
            var anAuthRequest = new tenduke.networking.Request(url, null);
            //
            //
            anAuthRequest.execute(_Function.createScopedFunction(this,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 = XmlUtils.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 = this.LOGIN_FAILED;
                if(cmdLoginInfoElement){
                    var authResult=cmdLoginInfoElement.getAttribute("AUTHENTICATION_RESULT");
                    if(authResult){
                        if(authResult=="LOGIN_OK") {
                            //
                            //
                            resultObject.hasDetailedLoginInformation = true;
                            loginResult = this.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=this.LOGIN_FAILED;
                            }
                            else if(this.emailValidationRequired==true && accountValidated!=null && accountValidated!=undefined){
                                emailValidated = accountValidated=="true";
                                Cookies.writeSessionCookie(this.ACCOUNT_VALIDATED_COOKIE_NAME, ""+accountValidated);
                            }
                            if(accountDataComplete=="ACCOUNT_REGISTRATION_IS_COMPLETE"){

                            }
                            if(noEmail==false){

                            }
                        }
                        else if(authResult=="LOGIN_FAILED") {
                            loginResult = this.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 _NetworkRequest = tenduke.networking.Request;
    var _Function = tenduke.util.js.Function;
    var Cookies = tenduke.util.html.Cookies;
   	var XmlUtils = tenduke.util.XmlUtils;

    /**
     * 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 HasSessionRequest = function(params){
    	HasSessionRequest.prototype.superClass.constructor.call(this, params);
    };
    //
    //
    copyPrototype(HasSessionRequest, Request);
    HasSessionRequest.prototype.superClass = Request.prototype;
    //
    //
    HasSessionRequest.makeRequest = function(params) {
    	return new HasSessionRequest(params);
    }
    /**
     * @return false
     */
    HasSessionRequest.prototype.propagateIsRequired = function() {
    	return false;
    }

    /**
     * @return null
     */
    HasSessionRequest.prototype.getCommandXml=function() {
        return null;
    }

    /**
     *
     */
    HasSessionRequest.prototype.execute=function(callback) {
        //
        //
        var resultObject = {};
        resultObject.request = this;
        //
        //
        //
        //
        var returnParameter = "data"
        var returnParameterValue = null;
        var url = "/s/AuthenticateServlet?function=HAS_SESSION";
        var anAuthRequest = new tenduke.networking.Request(url, null);
        //
        //
        anAuthRequest.execute(_Function.createScopedFunction(this,function(result) {
            //
            //
            var response = ( result.data ? result.data : null);
            //
            //
			var _validSession=false;

            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") {
                    _validSession = true;
                }
                else {
                    _validSession = false;
                }
            }
            else {
                _validSession = false;
            }
            
            resultObject.hasSession = _validSession;
            //
            //
            if(callback) {
                //
                //
                callback.call(this, resultObject);
            }
        }));
    }
    HasSessionRequest.prototype.setUrl=function(url) {
    	this._networkingRequest.setUrl(url);
    }
    HasSessionRequest.prototype.getUrl=function() {
    	return this._networkingRequest.getUrl();
    }
    HasSessionRequest.prototype.setParams=function(params) {
    	this._networkingRequest.setParams(params);
    }
    HasSessionRequest.prototype.getParams=function() {
    	return this._networkingRequest.getParams();
    }
    tenduke.serverinterface.HasSessionRequest = HasSessionRequest;
})();//
//
var tenduke = tenduke || {};
tenduke.serverinterface = tenduke.serverinterface || {};
//
//
(function() {
    //
    //IMPORTS
    /*
     *
     */
    var Request = tenduke.serverinterface.Request;

    /*
    * this import can not be used. tenduke.networking.Request should be overridden in application specific files
    * using the imported resource will point to an empty baseclass implementation that does not execute
    * 
    */
    var _NetworkRequest = tenduke.networking.Request;
    var _NetworkRequestParameters = tenduke.networking.RequestParameters;
    var Base64 = tenduke.util.Base64;

    /**
     * Constructor takes a single argument params, which is an instance of Object
     * that can contain following attributes:
     * 1. email: The email to check availability for (email for registering an user account)
     */
    var CheckEmailAvailability = function(params) {
    	CheckEmailAvailability.prototype.superClass.constructor.call(this, params);
    };

    //
    //
    copyPrototype(CheckEmailAvailability, Request);
    CheckEmailAvailability.prototype.superClass = Request.prototype;

    /**
     * Construct new request object
     */
    CheckEmailAvailability.makeRequest = function(params) {
    	return new CheckEmailAvailability(params);
    }

    /**
     * @return true
     */
    CheckEmailAvailability.prototype.propagateIsRequired = function() {
    	return false;
    }


    /**
     * The command xml for checking if an email is available in user registration.
     * @return Command xml for making query
     */
    CheckEmailAvailability.prototype.getCommandXml=function() {
        //
        //
        var retValue = null;
        //
        //
        var cmd = new Array();
	//
        //
        cmd[cmd.length] = '<COMMANDS PROPAGATE="false">';
        cmd[cmd.length] = '<COMMAND CLASS_NAME="com.tenduke.tendukecommunity.command.CheckAvailabilityForEmail"';
        cmd[cmd.length] = ' EMAIL="' + tenduke.util.Base64.encode64(this._params.email) + '"';
        cmd[cmd.length] = ' ENCODE_RESULT="false" /></COMMANDS>';
        //
        //
        retValue = cmd.join("");
        //
        //
        return retValue;
    }

    /**
     * Execute request
     * @param callback, Signature: function(resultObject) {...,
     *       where resultObject will contain:
     *       resultObject.email, The original email specified by caller
     *       resultObject.isAvailable, value is true or false to indicate availability
     *       resultObject.resultXml Handle to server response XML
     *       resultObject.error Handle to error object if errors occure
     *       resultObject.error.defaultMessage Default technical error message;
     *       resultObject.error.messageId Error id
     */
    CheckEmailAvailability.prototype.execute=function(callback) {
        //
        //
        var resultObject = {};
        //
        //
        resultObject.request = this;
        resultObject.email = this._params.email;
        resultObject.isAvailable = false;
        //
        //
        var checkAvailabilityCommand = this.getCommandXml();
        //
        //
        var commands = this.getCommandsHeadXml() + checkAvailabilityCommand + this.getCommandsTailXml();
        //
        //
        var requestParams = {};
        requestParams[_NetworkRequestParameters.POST_DATA] = commands;
        requestParams[RequestParameters.CONTENT_TYPE] = "text/xml";
        //
        //
        var networkRequest = new tenduke.networking.Request(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 CheckEmailAvailability command response";
                        resultObject.error.messageId = "CheckEmailAvailability.error.unkownServerResultObjectType";
                    }
                }
            }
            else {
                if(!resultObject.error) {
                    resultObject.error = {};
                }
                resultObject.error.defaultMessage = "No result object received from server for CheckEmailAvailability request";
                resultObject.error.messageId = "CheckEmailAvailability.error.missingServerResultObject";
            }
            //
            //
            if(resultXml!=null && resultXml!=undefined) {
                //
                //
                resultObject.resultXml = resultXml;
                //
                //
                var emailElements = resultXml.getElementsByTagName('EMAIL');
                if(emailElements && emailElements.length>0) {
                    var emailElement = null;
                    for(var i=0; i<emailElements.length; i++) {
                        emailElement = emailElements[i];
                        if(emailElement && emailElement.getAttribute('IS_AVAILABLE')) {
                            retValue = (emailElement.getAttribute('IS_AVAILABLE').toString()=="true");
                            resultObject.isAvailable = retValue;
                            break;
                        }
                    }
                }
                //
                //
                if(callback) {
                    callback(resultObject);
                }
            }
            else {
                if(callback) {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    resultObject.error.defaultMessage = "No response data received in CheckEmailAvailability response";
                    resultObject.error.messageId = "CheckEmailAvailability.error.noResponseDataInCheckEmailAvailability";
                    callback(resultObject);
                }
            }
        });
        
    }    
    //
    //
    tenduke.serverinterface.CheckEmailAvailability = CheckEmailAvailability;

})();
var tenduke = tenduke || {};
tenduke.serverinterface = tenduke.serverinterface || {};
(function() {
    //
    //IMPORTS
    var Request = tenduke.serverinterface.Request;
    /*
    * this import can not be used. tenduke.networking.Request should be overridden in application specific files
    * using the imported resource will point to an empty baseclass implementation that does not execute
    */
    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;
    }
	/**
	 * 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;
	}
    /**
     * 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 tenduke.networking.Request(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
    /*
    * depencies to old code
    * properties.js
    * contactProperties.js
    */
    var DateAndTimeUtils = tenduke.util.DateAndTimeUtils;
    var Request = tenduke.serverinterface.Request;
    /*
    * this import can not be used. tenduke.networking.Request should be overridden in application specific files
    * using the imported resource will point to an empty baseclass implementation that does not execute
    * 
    */
    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 tenduke.networking.Request(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;

})();
var tenduke = tenduke || {};
tenduke.serverinterface = tenduke.serverinterface || {};
(function() {
    //
    //IMPORTS
    var DateAndTimeUtils = tenduke.util.DateAndTimeUtils;
    var Request = tenduke.serverinterface.Request;
    var _Function = tenduke.util.js.Function;
    /*
    * this import can not be used. tenduke.networking.Request should be overridden in application specific files
    * using the imported resource will point to an empty baseclass implementation that does not execute
    */
    var _NetworkRequest = tenduke.networking.Request;
    var _NetworkRequestParameters = tenduke.networking.RequestParameters;
    var Entry = tenduke.objectmodel.Entry;
    var Base64 = tenduke.util.Base64;
    var DukeXmlSerializer = tenduke.objectmodel.serialization.DukeXmlSerializer;

    /**
     * Constructor takes a single argument params, which is an instance of Object
     * that must contain following attributes:
     * 1. entry: instance of tenduke.objectmodel.Entry with relevant member attributes set
     */
    var CreateOrUpdateEntry = function(params){
    	CreateOrUpdateEntry.prototype.superClass.constructor.call(this, params);
    };

    //
    //
    copyPrototype(CreateOrUpdateEntry, Request);
    CreateOrUpdateEntry.prototype.superClass = Request.prototype;

    /**
     * Construct new request object
     */
    CreateOrUpdateEntry.makeRequest = function(params) {
    	return new CreateOrUpdateEntry(params);
    }

    /**
     * @return true
     */
    CreateOrUpdateEntry.prototype.propagateIsRequired = function() {
    	return true;
    }


    /**
     * The command xml for creating or updating a profile.
     * @return Command xml for creating or updating an account
     */
    CreateOrUpdateEntry.prototype.getCommandXml=function() {
        //
        //
        var retValue = null;
        //
        //
        if(this._params!=null && this._params.entry) {
            //
            //
            var entry = this._params.entry;
            //
            // get registered params
            //
            // Write local entry basic data
            //
            //
            //retValue = _getCreateOrUpdateEntryCommand(profile.getProfileId(), primaryProfileData, contactProperties, null, null, true);
            retValue = _getCreateOrUpdateEntryCommand(entry);
        }
        //
        //
        return retValue;
    }

    /**
     * Execute request
     * @param callback, Signature: function(resultObject) {... where resultObject:
     */
    CreateOrUpdateEntry.prototype.execute=function(callback) {
        //
        //
        var resultObject = {};
        resultObject.error={};
        
        //
        //
        resultObject.request = this;
        //
        //
        if(this._params!=null) {
            //
            //
            resultObject.entry = this._params.entry;
            //
            //
            var createEntryCommand = this.getCommandXml();
            //
            //
            var commands = this.getCommandsHeadXml() + createEntryCommand + this.getCommandsTailXml();
            //
            //
            var requestParams = {};
            requestParams[_NetworkRequestParameters.POST_DATA] = commands;
            requestParams[RequestParameters.CONTENT_TYPE] = "text/xml";
            //
            //
            var networkRequest = new tenduke.networking.Request(this.getUrl(), requestParams);
            networkRequest.execute(_Function.createScopedFunction(this,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 = "CreateOrUpdateEntry.error.unkownServerResultObjectType";
                        }
                    }
                }
                else {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    resultObject.error.defaultMessage = "No result object received from server for CreateOrUpdateEntry request";
                    resultObject.error.messageId = "CreateOrUpdateEntry.error.missingServerResultObject";
                }
                //
                //
                if(resultXml!=null && resultXml!=undefined) {
                    //
                    //
                    resultObject.resultXml = resultXml;
                    if(this.getNumCommandOKs(resultXml)==1){
                    	resultObject.error=null;
                    }
                    if(callback) {
                        callback(resultObject);
                    }
                }
                else {
                    if(callback) {
                        if(!resultObject.error) {
                            resultObject.error = {};
                        }
                        resultObject.error.defaultMessage = "No response data received in CreateOrUpdateEntry response";
                        resultObject.error.messageId = "TendukeAccountAndProfile.error.noResponseDataInCreateOrUpdateEntry";
                        callback(resultObject);
                    }
                }
            }));
        }
    }
    /**
	 * Create a commandXML for creating a new entry or updating an existing one.
	 * @param entryParams Properties instance of parameters used to create an entry in the system.
	 * @param simpleClassName "Audio", "Image" or "Video" supported.
	 * @param entryId Id for new or existing entry.
	 * @param relatedProfiles array of profile ids.
	 * @return commandXML.
	 */
	function _getCreateOrUpdateEntryCommand(entry) {
	    //
	    //
	    var cmdData = "";
	    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
	    cmdXML += "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.CreateOrUpdateEntry\" ENTRY_TYPE=\"" + entry.classSimpleName + "\" ENTRY_ID=\"" + entry.getId() + "\"><DATA>";
	    var serializeEntry=new DukeXmlSerializer().serialize(entry);
	    cmdData =  Base64.encode64(serializeEntry);
	    cmdXML += cmdData;
	    cmdXML += "</DATA></COMMAND></COMMANDS>";
	    //
	    //
	    //
	    //
	    return cmdXML;
	}

    //
    //
    tenduke.serverinterface.CreateOrUpdateEntry = CreateOrUpdateEntry;

})();
//
//
var tenduke = tenduke || {};
tenduke.serverinterface = tenduke.serverinterface || {};
//
//
(function() {
    //
    //IMPORTS
    /*
     *
     */
    var DateAndTimeUtils = tenduke.util.DateAndTimeUtils;
    var Request = tenduke.serverinterface.Request;

    /*
    * this import can not be used. tenduke.networking.Request should be overridden in application specific files
    * using the imported resource will point to an empty baseclass implementation that does not execute
    * 
    */
    var _NetworkRequest = tenduke.networking.Request;
    var _NetworkRequestParameters = tenduke.networking.RequestParameters;
    var Profile = tenduke.objectmodel.Profile;
    var Contact = tenduke.objectmodel.Contact;
    var ContactDetails = tenduke.objectmodel.ContactDetails;
    var Base64 = tenduke.util.Base64;
    var DukeXmlSerializer = tenduke.objectmodel.serialization.DukeXmlSerializer;

    /**
     * Constructor takes a single argument params, which is an instance of Object
     * that must contain following attributes:
     * 1. contact: instance of tenduke.objectmodel.Contact with relevant member attributes set
     *    and optionally ContactDetails nested objects to create or update.
     * 2. profileId: modifying profileId for transaction, optional
     */
    var CreateOrUpdateContact = function(params){
    	CreateOrUpdateContact.prototype.superClass.constructor.call(this, params);
    };

    //
    //
    copyPrototype(CreateOrUpdateContact, Request);
    CreateOrUpdateContact.prototype.superClass = Request.prototype;

    /**
     * Construct new request object
     */
    CreateOrUpdateContact.makeRequest = function(params) {
    	return new CreateOrUpdateContact(params);
    }

    /**
     * @return true
     */
    CreateOrUpdateContact.prototype.propagateIsRequired = function() {
    	return true;
    }


    /**
     * The command xml for creating or updating a profile.
     * @return Command xml for creating or updating an account
     */
    CreateOrUpdateContact.prototype.getCommandXml=function() {
        //
        //
        var retValue = null;
        //
        //
        if(this._params && this._params.contact) {
            //
            //
            var modifyingProfileId = null;
            if(this._params.profileId){
            	modifyingProfileId = this._params.profileId;
            }
            var contactObject = this._params.contact;
            //
            //
            retValue = _getCreateOrUpdateContactCommand(modifyingProfileId, contactObject);
        }
        //
        //
        return retValue;
    }

    /**
     * Execute request
     * @param callback, Signature: function(resultObject) {...,
     *       where resultObject will contain:
     *       resultObject.contact Handle to the original contact model passed in as parameter
     *       resultObject.resultXml Handle to server response XML
     *       resultObject.error Handle to error object if errors occure
     *       resultObject.error.defaultMessage Default technical error message;
     *       resultObject.error.messageId Error id
     */
    CreateOrUpdateContact.prototype.execute=function(callback) {
        //
        //
        var resultObject = {};
        //
        //
        resultObject.request = this;
        //
        //
        if(this._params!=null && this._params.contact) {
            //
            //
            resultObject.contact = this._params.contact;
            //
            //
            var createOrUpdateContactCommand = this.getCommandXml();
            //
            //
            var commands = this.getCommandsHeadXml() + createOrUpdateContactCommand + this.getCommandsTailXml();
            //
            //
            var requestParams = {};
            requestParams[_NetworkRequestParameters.POST_DATA] = commands;
            requestParams[RequestParameters.CONTENT_TYPE] = "text/xml";
            //
            //
            var networkRequest = new tenduke.networking.Request(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 CreateOrUpdateContact command response";
                            resultObject.error.messageId = "CreateOrUpdateContact.error.unkownServerResultObjectType";
                        }
                    }
                }
                else {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    resultObject.error.defaultMessage = "No result object received from server for CreateOrUpdateContact request";
                    resultObject.error.messageId = "CreateOrUpdateContact.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 CreateOrUpdateContact response";
                        resultObject.error.messageId = "CreateOrUpdateContact.error.noResponseDataInCreateOrUpdateContact";
                        callback(resultObject);
                    }
                }
            });
        }
    }
    
    /**
     * Create a new contact or update an existing one.
     * @param profileId Modifying profileId for transaction.
     * @param contactObject Properties instance of parameters used to create an profile in the system (see PROFILE_REQUIRED_PROFILE_PARAMS for create scenarios).
     * @return Command XML for success
     */
    function _getCreateOrUpdateContactCommand(profileId, contactObject) {
        //
        //
        var cmdXML = "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.CreateOrUpdateContact\"";
        //
        //
        if(profileId) {
            cmdXML += " PROFILE_ID=\"" + profileId + "\"";
        }
        if(contactObject && contactObject.getId()) {
            cmdXML += " CONTACT_ID=\"" + contactObject.getId() + "\"";
        }
        cmdXML += " >";
        //
        //
        cmdXML += "<DATA>";
        //
        //
        if(contactObject) {
            //
            //
            var serializedContact = new DukeXmlSerializer().serialize(contactObject);
            var cmdData = Base64.encode64(serializedContact);
            cmdXML += cmdData;
        }
        //
        //
        cmdXML += "</DATA>";
        cmdXML += "</COMMAND>";
        //
        //
        return cmdXML;
    }
    //
    //
    tenduke.serverinterface.CreateOrUpdateContact = CreateOrUpdateContact;

})();
//
//
var tenduke = tenduke || {};
tenduke.serverinterface = tenduke.serverinterface || {};
//
//
(function() {
    //
    //IMPORTS
    /*
     *
     */
    var DateAndTimeUtils = tenduke.util.DateAndTimeUtils;
    var Request = tenduke.serverinterface.Request;

    /*
    * this import can not be used. tenduke.networking.Request should be overridden in application specific files
    * using the imported resource will point to an empty baseclass implementation that does not execute
    * 
    */
    var _NetworkRequest = tenduke.networking.Request;
    var _NetworkRequestParameters = tenduke.networking.RequestParameters;
    var Profile = tenduke.objectmodel.Profile;
    var Contact = tenduke.objectmodel.Contact;
    var ContactDetails = tenduke.objectmodel.ContactDetails;
    var Base64 = tenduke.util.Base64;
    var DukeXmlSerializer = tenduke.objectmodel.serialization.DukeXmlSerializer;

    /**
     * Constructor takes a single argument params, which is an instance of Object
     * that must contain following attributes:
     * 1. contact: instance of tenduke.objectmodel.Contact with relevant member attributes set
     *    and optionally ContactDetails nested objects to create or update.
     * 2. profileId: modifying profileId for transaction, optional
     */
    var DeleteContact = function(params){
    	DeleteContact.prototype.superClass.constructor.call(this, params);
    };

    //
    //
    copyPrototype(DeleteContact, Request);
    DeleteContact.prototype.superClass = Request.prototype;

    /**
     * Construct new request object
     */
    DeleteContact.makeRequest = function(params) {
    	return new DeleteContact(params);
    }

    /**
     * @return true
     */
    DeleteContact.prototype.propagateIsRequired = function() {
    	return true;
    }


    /**
     * The command xml for creating or updating a profile.
     * @return Command xml for creating or updating an account
     */
    DeleteContact.prototype.getCommandXml=function() {
        //
        //
        var retValue = null;
        //
        //
        if(this._params && this._params.contact) {
            //
            //
            var modifyingProfileId = null;
            if(this._params.profileId){
            	modifyingProfileId = this._params.profileId;
            }
            var contactObject = this._params.contact;
            //
            //
            retValue = _getDeleteContactCommand(modifyingProfileId, contactObject);
        }
        //
        //
        return retValue;
    }

    /**
     * Execute request
     * @param callback, Signature: function(resultObject) {...,
     *       where resultObject will contain:
     *       resultObject.contact Handle to the original contact model passed in as parameter
     *       resultObject.resultXml Handle to server response XML
     *       resultObject.error Handle to error object if errors occure
     *       resultObject.error.defaultMessage Default technical error message;
     *       resultObject.error.messageId Error id
     */
    DeleteContact.prototype.execute=function(callback) {
        //
        //
        var resultObject = {};
        //
        //
        resultObject.request = this;
        //
        //
        if(this._params!=null && this._params.contact) {
            //
            //
            resultObject.contact = this._params.contact;
            //
            //
            var deleteContactCommand = this.getCommandXml();
            //
            //
            var commands = this.getCommandsHeadXml() + deleteContactCommand + this.getCommandsTailXml();
            //
            //
            var requestParams = {};
            requestParams[_NetworkRequestParameters.POST_DATA] = commands;
            requestParams[RequestParameters.CONTENT_TYPE] = "text/xml";
            //
            //
            var networkRequest = new tenduke.networking.Request(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 DeleteContact command response";
                            resultObject.error.messageId = "DeleteContact.error.unkownServerResultObjectType";
                        }
                    }
                }
                else {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    resultObject.error.defaultMessage = "No result object received from server for DeleteContact request";
                    resultObject.error.messageId = "DeleteContact.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 DeleteContact response";
                        resultObject.error.messageId = "DeleteContact.error.noResponseDataInDeleteContact";
                        callback(resultObject);
                    }
                }
            });
        }
    }
    
    /**
     * Create a new contact or update an existing one.
     * @param profileId Modifying profileId for transaction.
     * @param contactObject Properties instance of parameters used to create an profile in the system (see PROFILE_REQUIRED_PROFILE_PARAMS for create scenarios).
     * @return Command XML for success
     */
    function _getDeleteContactCommand(profileId, contactObject) {
        //
        //
        var cmdXML = "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.DeleteContact\"";

        //
        if(profileId) {
            cmdXML += " PROFILE_ID=\"" + profileId + "\"";
        }
        if(contactObject && contactObject.getId()) {
            cmdXML += " CONTACT_ID=\"" + contactObject.getId() + "\"";
        }
        cmdXML += " >";
        cmdXML += "</COMMAND>";
        //
        //
        return cmdXML;
    }
    //
    //
    tenduke.serverinterface.DeleteContact = DeleteContact;

})();
//
//
var tenduke = tenduke || {};
tenduke.serverinterface = tenduke.serverinterface || {};
//
//
(function() {
    //
    //IMPORTS
    /*
     *
     */
    var DateAndTimeUtils = tenduke.util.DateAndTimeUtils;
    var Request = tenduke.serverinterface.Request;

    /*
    * this import can not be used. tenduke.networking.Request should be overridden in application specific files
    * using the imported resource will point to an empty baseclass implementation that does not execute
    * 
    */
    var _NetworkRequest = tenduke.networking.Request;
    var _NetworkRequestParameters = tenduke.networking.RequestParameters;
    var Profile = tenduke.objectmodel.Profile;
    var Contact = tenduke.objectmodel.Contact;
    var ContactDetails = tenduke.objectmodel.ContactDetails;
    var Base64 = tenduke.util.Base64;
    var DukeXmlSerializer = tenduke.objectmodel.serialization.DukeXmlSerializer;

    /**
     * Constructor takes a single argument params, which is an instance of Object
     * that can contain following attributes:
     * 1. profileId: modifying profileId for transaction, optional
     */
    var GetContacts = function(params){
    	GetContacts.prototype.superClass.constructor.call(this, params);
    };

    //
    //
    copyPrototype(GetContacts, Request);
    GetContacts.prototype.superClass = Request.prototype;

    /**
     * Construct new request object
     */
    GetContacts.makeRequest = function(params) {
    	return new GetContacts(params);
    }

    /**
     * @return true
     */
    GetContacts.prototype.propagateIsRequired = function() {
    	return false;
    }


    /**
     * The command xml for creating or updating a profile.
     * @return Command xml for creating or updating an account
     */
    GetContacts.prototype.getCommandXml=function() {
        //
        //
        var retValue = null;
        //
        //
        //
        //
        var modifyingProfileId = null;
        if(this._params && this._params.profileId){
        	modifyingProfileId = this._params.profileId;
        }
        //
        //
        retValue = _getGetContactsCommand(modifyingProfileId);

        //
        //
        return retValue;
    }

    /**
     * Execute request
     * @param callback, Signature: function(resultObject) {...,
     *       where resultObject will contain:
     *       resultObject.contact Handle to the original contact model passed in as parameter
     *       resultObject.resultXml Handle to server response XML
     *       resultObject.error Handle to error object if errors occure
     *       resultObject.error.defaultMessage Default technical error message;
     *       resultObject.error.messageId Error id
     */
    GetContacts.prototype.execute=function(callback) {
        //
        //
        var resultObject = {};
        //
        //
        resultObject.request = this;
        //
        //
            //
            //
            var getContactsCommand = this.getCommandXml();
            //
            //
            var commands = this.getCommandsHeadXml() + getContactsCommand + this.getCommandsTailXml();
            //
            //
            var requestParams = {};
            requestParams[_NetworkRequestParameters.POST_DATA] = commands;
            requestParams[RequestParameters.CONTENT_TYPE] = "text/xml";
            //
            //
            var networkRequest = new tenduke.networking.Request(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 GetContacts command response";
                            resultObject.error.messageId = "GetContacts.error.unkownServerResultObjectType";
                        }
                    }
                }
                else {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    resultObject.error.defaultMessage = "No result object received from server for GetContacts request";
                    resultObject.error.messageId = "GetContacts.error.missingServerResultObject";
                }
                //
                //
                if(resultXml!=null && resultXml!=undefined) {
                    //
                    //
                    resultObject.resultXml = resultXml;
                    var contactNodes=resultXml.getElementsByTagName(Contact.prototype.classSimpleName);
                    var contacts=[]
                    for(var i=0; i<contactNodes.length; i++){
                    	contacts[contacts.length]=(new DukeXmlSerializer()).deserialize(contactNodes[i]);
                    }	 
                    resultObject.contacts=contacts;
                    if(callback) {
                        callback(resultObject);
                    }
                }
                else {
                    if(callback) {
                        if(!resultObject.error) {
                            resultObject.error = {};
                        }
                        resultObject.error.defaultMessage = "No response data received in GetContacts response";
                        resultObject.error.messageId = "GetContacts.error.noResponseDataInGetContacts";
                        callback(resultObject);
                    }
                }
            });
        
    }
    
    /**
     * Create a new contact or update an existing one.
     * @param profileId Modifying profileId for transaction.
     * @param contactObject Properties instance of parameters used to create an profile in the system (see PROFILE_REQUIRED_PROFILE_PARAMS for create scenarios).
     * @return Command XML for success
     */
    function _getGetContactsCommand(profileId) {
        //
        //
        var cmdXML = "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.GetContacts\"";
        //
        //
        if(profileId) {
            cmdXML += " PROFILE_ID=\"" + profileId + "\"";
        }
        cmdXML += " >";
        //
        //
        cmdXML += "</COMMAND>";
        //
        //
        return cmdXML;
    }
    //
    //
    tenduke.serverinterface.GetContacts = GetContacts;

})();
var tenduke = tenduke || {};
tenduke.serverinterface = tenduke.serverinterface || {};
(function() {
    //
    //IMPORTS
    var Request = tenduke.serverinterface.Request;
    /*
    * this import can not be used. tenduke.networking.Request should be overridden in application specific files
    * using the imported resource will point to an empty baseclass implementation that does not execute
    */
    var _NetworkRequest = tenduke.networking.Request;
    var _NetworkRequestParameters = tenduke.networking.RequestParameters;
    var Base64 = tenduke.util.Base64;
    var Account = tenduke.objectmodel.Account;
    var _Function = tenduke.util.js.Function;

    /**
     * Constructor takes a single argument params, which is an instance of Object
     * that must contain following attributes:
     * 1. currentPassword
     * 2. newPassword
     * 3. newPasswordConfirmed
     * 4. principalName
     */
    var SetPassword = function(params){
    	SetPassword.prototype.superClass.constructor.call(this, params);
    };

    //
    //
    copyPrototype(SetPassword, Request);
    SetPassword.prototype.superClass = Request.prototype;

    /**
     * Construct new request object
     */
    SetPassword.makeRequest = function(params) {
    	return new SetPassword(params);
    }
    
    /**
     * @return true
     */
    SetPassword.prototype.propagateIsRequired = function() {
    	return true;
    }


    /**
     * The command xml for creating or updating an account.
     * @return Command xml for creating or updating an account
     */
    SetPassword.prototype.getCommandXml=function() {
        //
        //
        var retValue = null;
        //
        //
        if(this._params!=null && this._params.principalName && this._params.currentPassword && this._params.newPassword && this._params.newPasswordConfirmed== this._params.newPassword) {
            //
            //

            //
            //
            retValue = _getSetPasswordCommand(this._params);
        }
        //
        //
        return retValue;
    }
    function _getSetPasswordCommand(params) {
	    //
	    //
	    
	    var cmdXML = "<COMMANDS>";
	    cmdXML += "<COMMAND CLASS_NAME=\"com.tenduke.services.platform.command.SetPassword\"";
	    if(params.principalName!=null){
	    	cmdXML += " PRINCIPAL_NAME=\""+ Base64.encode64(params.principalName) +"\"";
	   	}
	    if(params.currentPassword!=null){
        	cmdXML += " CURRENT_PASSWORD=\""+ Base64.encode64(params.currentPassword) +"\"";
        }
        if(params.newPassword!=null){
	        cmdXML += " PASSWORD=\""+ Base64.encode64(params.newPassword) +"\"";
	    }
	    if(params.newPasswordConfirmed!=null){
        	cmdXML += " PASSWORD_CONFIRMED=\""+ Base64.encode64(params.newPasswordConfirmed) +"\"";
        }
	    cmdXML += " /></COMMANDS>";
	    //
	    //
	    //
	    //
	    return cmdXML;
	}

    /**
     * Execute request
     * @param callback, Signature: function(resultObject) {... where resultObject:
     */
    SetPassword.prototype.execute=function(callback) {
        //
        //
        var resultObject = {};
        resultObject.error = {};
        //
        //
        resultObject.request = this;
        //
        //
        if(this._params!=null) {
            //
            //
            //
            //
            var setPasswordCommand = this.getCommandXml();
            //
            //
            var commands = this.getCommandsHeadXml() + setPasswordCommand + this.getCommandsTailXml();
            //
            //
            var requestParams = {};
            requestParams[_NetworkRequestParameters.POST_DATA] = commands;
            requestParams[RequestParameters.CONTENT_TYPE] = "text/xml";
            //
            //
            var networkRequest = new tenduke.networking.Request(this.getUrl(), requestParams);
            networkRequest.execute(_Function.createScopedFunction(this,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 = "SetPassword.error.unkownServerResultObjectType";
                            
		                    if(callback) {
		                        callback(resultObject);
		                    }
                        }
                    }
                }
                else {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    resultObject.error.defaultMessage = "No result object received from server for SetPassword request";
                    resultObject.error.messageId = "SetPassword.error.missingServerResultObject";
                    
                    if(callback) {
                        callback(resultObject);
                    }
                }
                //
                //
                if(resultXml!=null && resultXml!=undefined) {
                    //
                    //
                    //
                    //
                    resultObject.resultXml = resultXml;
                    if(this.getNumCommandOKs(resultXml)==1){
                    	resultObject.error=null;
                    }
                    if(callback) {
                        callback(resultObject);
                    }
                }
                else {
                    if(callback) {
                        if(!resultObject.error) {
                            resultObject.error = {};
                        }
                        resultObject.error.defaultMessage = "No response data received in SetPassword response";
                        resultObject.error.messageId = "TendukeAccountAndProfile.error.noResponseDataInSetPassword";
                        callback(resultObject);
                    }
                }
            }));
        }
    }

    //
    //
    tenduke.serverinterface.SetPassword = SetPassword;
    
})();
var tenduke = tenduke || {};
tenduke.serverinterface = tenduke.serverinterface || {};
(function() {
    //
    //IMPORTS
    var DateAndTimeUtils = tenduke.util.DateAndTimeUtils;
    var Request = tenduke.serverinterface.Request;
    var _Function = tenduke.util.js.Function;
    /*
    * this import can not be used. tenduke.networking.Request should be overridden in application specific files
    * using the imported resource will point to an empty baseclass implementation that does not execute
    */
    var _NetworkRequest = tenduke.networking.Request;
    var _NetworkRequestParameters = tenduke.networking.RequestParameters;
    var Entry = tenduke.objectmodel.Entry;
    var Base64 = tenduke.util.Base64;
    var DukeXmlSerializer = tenduke.objectmodel.serialization.DukeXmlSerializer;

    /**
     * Constructor takes a single argument params, which is an instance of Object
     * that must contain following attributes:
     * 1. entry: instance of tenduke.objectmodel.Entry with relevant member attributes set
     * in addition it can contain the following
     * deleteFiles: true if originals should be deleted
     * fileExtensions: [] string array of extensions used for file assets
     * ignoreStoredObjectDeleteErrors: true/false
     */
    var DeleteEntry = function(params){
    	DeleteEntry.prototype.superClass.constructor.call(this, params);
    };

    //
    //
    copyPrototype(DeleteEntry, Request);
    DeleteEntry.prototype.superClass = Request.prototype;

    /**
     * Construct new request object
     */
    DeleteEntry.makeRequest = function(params) {
    	return new DeleteEntry(params);
    }

    /**
     * @return true
     */
    DeleteEntry.prototype.propagateIsRequired = function() {
    	return true;
    }


    /**
     * The command xml for creating or updating a profile.
     * @return Command xml for creating or updating an account
     */
    DeleteEntry.prototype.getCommandXml=function() {
        //
        //
        var retValue = null;
        //
        //
        if(this._params!=null && this._params.entry) {
            //
            //
            var entry = this._params.entry;
            //
            // get registered params
            //
            // Write local entry basic data
            //
            //
            //retValue = _getDeleteEntryCommand(profile.getProfileId(), primaryProfileData, contactProperties, null, null, true);
            retValue = this._getDeleteEntryCommand(entry);
        }
        //
        //
        return retValue;
    }

    /**
     * Execute request
     * @param callback, Signature: function(resultObject) {... where resultObject:
     */
    DeleteEntry.prototype.execute=function(callback) {
        //
        //
        var resultObject = {};
        resultObject.error={};
        
        //
        //
        resultObject.request = this;
        //
        //
        if(this._params!=null) {
            //
            //
            resultObject.entry = this._params.entry;
            //
            //
            var deleteEntryCommand = this.getCommandXml();
            //
            //
            var commands = this.getCommandsHeadXml() + deleteEntryCommand + this.getCommandsTailXml();
            //
            //
            var requestParams = {};
            requestParams[_NetworkRequestParameters.POST_DATA] = commands;
            requestParams[RequestParameters.CONTENT_TYPE] = "text/xml";
            //
            //
            var networkRequest = new tenduke.networking.Request(this.getUrl(), requestParams);
            networkRequest.execute(_Function.createScopedFunction(this,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 = "DeleteEntry.error.unkownServerResultObjectType";
                        }
                    }
                }
                else {
                    if(!resultObject.error) {
                        resultObject.error = {};
                    }
                    resultObject.error.defaultMessage = "No result object received from server for DeleteEntry request";
                    resultObject.error.messageId = "DeleteEntry.error.missingServerResultObject";
                }
                //
                //
                if(resultXml!=null && resultXml!=undefined) {
                    //
                    //
                    resultObject.resultXml = resultXml;
                    if(this.getNumCommandOKs(resultXml)==1){
                    	resultObject.error=null;
                    }
                    if(callback) {
                        callback(resultObject);
                    }
                }
                else {
                    if(callback) {
                        if(!resultObject.error) {
                            resultObject.error = {};
                        }
                        resultObject.error.defaultMessage = "No response data received in DeleteEntry response";
                        resultObject.error.messageId = "TendukeAccountAndProfile.error.noResponseDataInDeleteEntry";
                        callback(resultObject);
                    }
                }
            }));
        }
    }
    /**
	 */
	DeleteEntry.prototype._getDeleteEntryCommand=function(entry) {
	    //
	    //
	    var cmdData = "";
	    var cmdXML = "<COMMANDS PROPAGATE=\"true\">";
	    cmdXML += "<COMMAND CLASS_NAME=\"com.tenduke.tendukecommunity.command.DeleteEntry\" ENTRY_TYPE=\"" + entry.classSimpleName + "\" ENTRY_ID=\"" + entry.getId() + "\"";
	    if(this._params && this._params.deleteFiles==true) {
	        cmdXML += ' DELETE_STORED_OBJECTS="' + true + '"';
	    }
	    if(this._params && this._params.fileExtensions && this._params.fileExtensions.length>0) {
	        cmdXML += ' STORED_OBJECT_FORMAT_EXTENSIONS="' + this._params.fileExtensions.join(",") + '"';
	    }
	    if(this._params && this._params.ignoreStoredObjectDeleteErrors==true){
	     	cmdXML += ' IGNORE_STORED_OBJECT_DELETE_ERRORS="true"';
	    }
    	cmdXML +="></COMMAND></COMMANDS>";
	    //
	    //
	    //
	    //
	    return cmdXML;
	}

    //
    //
    tenduke.serverinterface.DeleteEntry = DeleteEntry;

})();
//
// initialize package
var tenduke = tenduke || {};
tenduke.application = tenduke.application || {};

/**
 * Base class for all object model objects
 */
(function() {
	//
	// Imports
	var LoginRequest = tenduke.serverinterface.LoginRequest;
	var HasSessionRequest = tenduke.serverinterface.HasSessionRequest;
	var Cookies = tenduke.util.html.Cookies;
    //
    // Constructor
    var Application = function() {
    };

    /** */
    var _singletonInstance = null;
	var _loginStateCheckTime = null;
    /** */
    Application.prototype._loggedInProfile = null;

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

    /** Get logged in profile, may return null */
    Application.prototype.getLoggedInProfile = function() {
        return this._loggedInProfile;
    }

    /** Set logged in profile */
    Application.prototype.setLoggedInProfile = function(loggedInProfile) {
        this._loggedInProfile = loggedInProfile;
    }
    /**
	 * 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).
	 */
	Application.prototype.isLoggedIn=function(callback) {
	    //
	    //
	    if(LoginRequest.prototype.emailValidationRequired ==true && !emailValidated){
	        var emailCookie=Cookies.getCookie(LoginRequest.prototype.ACCOUNT_VALIDATED_COOKIE_NAME);
	        if(emailCookie!="true"){
	        	callback(false);
	        	return;
	        }
	    }
	    var sessionCookie = Cookies.getCookie(LoginRequest.prototype.LOGIN_STATE_COOKIE_NAME);
	    if(sessionCookie=="true"){
	        if(!_loginStateCheckTime || _loginStateCheckTime+1800000 <= (new Date()).getTime()){
	            _loginStateCheckTime=(new Date()).getTime();
	            
	            var r=HasSessionRequest.makeRequest(null);
				r.execute(function(resultObject){
					if(resultObject!=null){
						if(resultObject.hasSession===true){
							callback(true);
	        				return;
						}
						else{
							callback(false);
	        				return;
						}
					}
					else{
						callback(false);
        				return;
					}
				});
				return;
	        }
	        else{
	            callback(true);
	        	return;
	        }
	    }
		callback(false);
    	return;
	    
	}
	
    //
    //
    tenduke.application.Application = Application;

})();
var tenduke = tenduke || {};
tenduke.facebook = tenduke.facebook || {};

/**
 * FacebookConnect represents the main "entry point" for initializing
 * a Facebook connect JavaScript client. This class will by default initialize
 * features "Connect" and "Api" from in the Facebook JavaScript environment. <br/>
 * <br/>
 * Facebook connect reference: http://wiki.developers.facebook.com/index.php/Facebook_Connect. <br/>
 * <br/>
 * This class provides a "static" initialization method: tenduke.facebook.FacebookConnect.init
 * to call before using Facebook JavaScript library from client code.
 * <br/>
 * <br/>
 * Usage example: <br/>
 * //
 * // First call to static initialization of Facebook environment <br/>
 * // including a chain of callback handlers that will require the user <br/>
 * // to sign in with facebook user credentials. Finally the execution <br/>
 * // controll is passed to method onFacebookConnectLogin, which outlines <br/>
 * // an example that authenticates the facebook logged in user to the <br/>
 * // 10Duke back-end where the client application is hosted <br/>
 * tenduke.facebook.FacebookConnect.init(function() { <br/>
       tenduke.facebook.FacebookConnect.requireSession(onFacebookConnectLogin,function(){}, true); <br/>
   }); <br/>

 * <br/>
 * //
 * // Example callback handler that authenticates the <br/>
 * // facebook logged in user to the 10Duke back-end where the <br/>
 * // client application is hosted <br/>
 * function onFacebookConnectLogin() { <br/>
 *      //
        // request connect status from the facebook environment <br/>
        FB.Connect.get_status().waitUntilReady(function(fbConnectStatus) { <br/>
            // <br/>
            // switch status reported by the facebook Connect.get_status() call <br/>
            switch(fbConnectStatus) { <br/>
                // <br/>
                // <br/>
                case FB.ConnectState.connected: <br/>
                    // <br/>
                    // This example checks if the user has already been granted a session: <br/>
                    // if not, then call login to the 10Duke back-end <br/>
                    if(isLoggedIn()==false) { <br/>
                            // <br/>
                            // Optionally initialize a 10Duke account and profile (creates both if they do not exist) <br/>
                            // tenduke.facebook.TendukeAccountAndProfile.initializeAccountAndProfile(function(accountAndProfileInitResult) { <br/>
                                    // <br/>
                                    // Login / authenticate user to 10Duke back-end <br/>
                                    tenduke.facebook.Authentication.login(function(resultObject) { <br/>
                                        // <br/>
                                        // Handling of login response. Simple case where success and already logged in <br/>
                                        // response defines first branch and all other cases are treated as failure to authenticate user <br/>
                                        // Example shows 10Duke JS library style of dynamic GUI status update <br/>
                                        var returnParameter = null; <br/>
                                        if(resultObject.returnParameters && resultObject.returnParameters.length && resultObject.returnParameters.length>0) { <br/>
                                            returnParameter = resultObject.returnParameters[0]; <br/>
                                        } <br/>
                                        if(resultObject.loginResult==ALREADY_LOGGED_IN || resultObject.loginResult==LOGIN_SUCCESS) { <br/>
                                            // <br/>
                                            // <br/>
                                            tenduke.facebook.TendukeAccountAndProfile.initAccountAndProfile(function(initResult) { <br/>
                                                // <br/>
                                                // <br/>
                                                tenduke.util.html.DOMUtils.setAttribute("headerFacebookButton", "src", "static/images/facebookButton.png"); <br/>
                                                tenduke.util.html.DOMUtils.setAttribute("facebookConnectButton", "src", "static/images/facebookConnectButton.gif"); <br/>
                                                defaultLoginResultHandler(resultObject.loginResult, resultObject.principalName, returnParameter); <br/>
                                            }); <br/>
                                        } <br/>
                                        else { <br/>
                                            // <br/>
                                            // <br/>
                                            tenduke.util.html.DOMUtils.setAttribute("headerFacebookButton", "src", "static/images/facebookButton.png"); <br/>
                                            tenduke.util.html.DOMUtils.setAttribute("facebookConnectButton", "src", "static/images/facebookConnectButton.gif"); <br/>
                                            defaultLoginResultHandler(resultObject.loginResult, resultObject.principalName, returnParameter); <br/>
                                        } <br/>
                                    }); <br/>
                            // <br/>
                            // }); <br/>
                    } <br/>
                    else { // already logged in, example restores GUI progress status display <br/>
                        // <br/>
                        // <br/>
                        tenduke.util.html.DOMUtils.setAttribute("headerFacebookButton", "src", "static/images/facebookButton.png"); <br/>
                        tenduke.util.html.DOMUtils.setAttribute("facebookConnectButton", "src", "static/images/facebookConnectButton.gif"); <br/>
                    } <br/>
                    break; <br/>
                case FB.ConnectState.appNotAuthorized: <br/>
                    //showAlert("Facebook connect: application not authorized error"); <br/>
                    tenduke.util.html.DOMUtils.setAttribute("headerFacebookButton", "src", "static/images/facebookButton.png"); <br/>
                    tenduke.util.html.DOMUtils.setAttribute("facebookConnectButton", "src", "static/images/facebookConnectButton.gif"); <br/>
                    break;
                case FB.ConnectState.userNotLoggedIn: <br/>
                    //showAlert("Facebook connect: you are not logged in"); <br/>
                    tenduke.util.html.DOMUtils.setAttribute("headerFacebookButton", "src", "static/images/facebookButton.png"); <br/>
                    tenduke.util.html.DOMUtils.setAttribute("facebookConnectButton", "src", "static/images/facebookConnectButton.gif"); <br/>
                    break; <br/>
            } <br/>
        }); <br/>
    } <br/>
 *
 *
 */
(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
    */

    /**
     * Creates new instance of FacebookConnect
     */
    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;
    
    /**
     * Initialize Facebook JS environment by requiring
     * features Connect and Api.
     * @param callback Caller defined method that executes when both FB features Api
     *        and Connect have been loaded.
     */
    FacebookConnect.prototype.init=function(callback) {
        //
        //
        var d=document.getElementById("FB_HiddenContainer");
        if(!d) {
            var fbHiddenDiv = document.createElement("div");
            fbHiddenDiv.id = "FB_HiddenContainer";
            fbHiddenDiv.style.position = "absolute";
            fbHiddenDiv.style.left = "-10000px";
            fbHiddenDiv.style.top = "-10000px";
            fbHiddenDiv.style.width = "0px";
            fbHiddenDiv.style.height = "0px";
            window.document.body.insertBefore(fbHiddenDiv, window.document.body.firstChild);
        }
        //
        //
        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;
        try{
            anFB=FB;
        }
        catch(e){
        }
        if(anFB!=null && anFB!=undefined){
            c();
        }
        else{
            ResourceImporter.importJSCollection(this.libraryUrls,c);
        }
    }

    //
    // variable to hold number of retry attempts to initialize FB API
    var _facebookRequireSessionRetries=0;

    /**
     * Require that user sign in on Facebook
     * @param callback Caller defined method that executes when session has been granted
     * @param cancelCallback Caller defined method that executes when session was not granted (canceled by user)
     * @param isUserAction Flag to indicate if the request is directly from user interaction or generated by application implicitly in relation to some other user action
     */
    FacebookConnect.prototype.requireSession=function(callback, cancelCallback, isUserAction) {
        try{
            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));
        }
        catch(e) {
            //
            //
            _facebookRequireSessionRetries++;
            //alert("retries"+_facebookRequireSessionRetries);
            //
            if(_facebookRequireSessionRetries>=3) {
                //
                //
                _facebookRequireSessionRetries=0;
                if(cancelCallback!=null){
                    cancelCallback();
                }
            }
            else {
                //
                //
                var retry=Function_.createScopedFunction(this, function(){
                    this.requireSession(callback,cancelCallback,isUserAction);
                });
                setTimeout(retry,100);
            }
        }
    }

    //
    //
    tenduke.facebook.FacebookConnect = new FacebookConnect();
/*
	requireSession:function(b,d,c){
		if(arguments.length===1){
			if(typeof(b)!=='function'){
				c=(b);
				b=null;
			}
		}
		else if(arguments.length===2)
			if(typeof(d)!=='function'){
				c=(d);
				d=null;
			}
		var a=FB.SessionDialog.getActive();
		if(!a){
			a=FB.SessionDialog.make();
			a.setIsUserActionHint(c).request();
		}
		else 
			a.focus();
		if(b)
			FB.Connect.get_status().waitForValue(FB.ConnectState.connected,b);
		if(d)
			a.add_cancelled(d);
	}
	getActive:function(){
		if(FB.SessionDialog._singleton&&FB.SessionDialog._singleton.isActive())
			return FB.SessionDialog._singleton;
		return null;
	}
	make:function(){
		FB.SessionDialog.closeAll();
		FB.SessionDialog._singleton=new FB.SessionDialog();
		return FB.SessionDialog._singleton;
	}
	
	*/
})();
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 = LoginRequest.prototype.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;

})();
var tenduke = tenduke || {};
tenduke.contacts = tenduke.contacts || {};
(function() {
	/**
	 * Import contacts from supported providers. Supported providers currently include
	 * Yahoo mail, Gmail and Hotmail.
	 */
	var ImportContacts = function(){};
	//
	//
	ImportContacts.prototype.importContacts=function(params,callback){};
	
	
    tenduke.contacts.ImportContacts = ImportContacts;
})();
var tenduke = tenduke || {};
tenduke.contacts = tenduke.contacts || {};
tenduke.contacts.gmail = tenduke.contacts.gmail || {};
(function() {
	/*
	* requires 
	* randomUUID()
	*/
	var ImportContacts=tenduke.contacts.ImportContacts;
	var Contact=tenduke.objectmodel.Contact;
	var ContactDetails=tenduke.objectmodel.ContactDetails;
	var EmailAddress=tenduke.objectmodel.EmailAddress;
	var UUID=tenduke.util.UUID;
	/**
	 * Import contacts from supported providers. Supported providers currently include
	 * Yahoo mail, Gmail and Hotmail.
	 */
	var ImportGMailContacts = function(){
		ImportGMailContacts.prototype.superClass.constructor.call(this);
    };
    //
    //
    copyPrototype(ImportGMailContacts, ImportContacts);
    ImportGMailContacts.prototype.superClass = ImportContacts.prototype;
    _callbacks = []; 
    _requestId = 0;
	//
	//
	ImportGMailContacts.resultHandler=function(requestId, contacts){
		if(_callbacks[requestId]){
			if(contacts && contacts.length>0){
				for(var i=0; i<contacts.length; i++){
					var c= new Contact();
					c.setContactId(UUID.uuid());
					var cd=new ContactDetails();
					cd.setContactDetailsId(UUID.uuid());
					cd.setContactId(c.getContactId());
					if(contacts[i].name){
						cd.setFormattedName(contacts[i].name);
					}
					if(contacts[i].email){
						var e=new EmailAddress();
						e.setEmailAddressId(UUID.uuid());
						e.setContactDetailsId(cd.getContactDetailsId());
						e.setValue(contacts[i].email);
						cd.setEmail(e);
					}
					c.setContactDetails(cd);
					contacts[i]=c;
				}	
			}
			_callbacks[requestId](contacts);
			_callbacks[requestId]=null;
		}
	}
	ImportGMailContacts.prototype.importContacts=function(params,callback){
		_callbacks[_requestId]=callback;
		var importContactsWindow = window.open('/importContacts.jsp?serviceProvider=gmail&requestId=' +_requestId , '_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");
	    }
		_requestId++;
	};
	
	
    tenduke.contacts.gmail.ImportGMailContacts = ImportGMailContacts;
})();var tenduke = tenduke || {};
tenduke.contacts = tenduke.contacts || {};
tenduke.contacts.yahoo = tenduke.contacts.yahoo || {};
(function() {
	/*
	* requires 
	*/
	var ImportContacts=tenduke.contacts.ImportContacts;
	var Contact=tenduke.objectmodel.Contact;
	var ContactDetails=tenduke.objectmodel.ContactDetails;
	var EmailAddress=tenduke.objectmodel.EmailAddress;
	var UUID=tenduke.util.UUID;
	/**
	 * Import contacts from supported providers. Supported providers currently include
	 * Yahoo mail, Gmail and Hotmail.
	 */
	var ImportYahooContacts = function(){
		ImportYahooContacts.prototype.superClass.constructor.call(this);
    };
    //
    //
    copyPrototype(ImportYahooContacts, ImportContacts);
    ImportYahooContacts.prototype.superClass = ImportContacts.prototype;
    _callbacks = []; 
    _requestId = 0;
	//
	//
	ImportYahooContacts.resultHandler=function(requestId, contacts){
		if(_callbacks[requestId]){
			if(contacts && contacts.length>0){
				for(var i=0; i<contacts.length; i++){
					var c= new Contact();
					c.setContactId(UUID.uuid());
					var cd=new ContactDetails();
					cd.setContactDetailsId(UUID.uuid());
					cd.setContactId(c.getContactId());
					if(contacts[i].name){
						cd.setFormattedName(contacts[i].name);
					}
					if(contacts[i].email){
						var e=new EmailAddress();
						e.setEmailAddressId(UUID.uuid());
						e.setContactDetailsId(cd.getContactDetailsId());
						e.setValue(contacts[i].email);
						cd.setEmail(e);
					}
					c.setContactDetails(cd);
					contacts[i]=c;
				}	
			}
			_callbacks[requestId](contacts);
			_callbacks[requestId]=null;
		}
	}
	ImportYahooContacts.prototype.importContacts=function(params,callback){
		_callbacks[_requestId]=callback;
		var importContactsWindow = window.open('/importContacts.jsp?serviceProvider=yahoo&requestId=' +_requestId , '_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");
	    }
		_requestId++;
	};
	
	
    tenduke.contacts.yahoo.ImportYahooContacts = ImportYahooContacts;
})();var tenduke = tenduke || {};
tenduke.contacts = tenduke.contacts || {};
tenduke.contacts.hotmail = tenduke.contacts.hotmail || {};
(function() {
	/*
	* requires 
	*/
	var ImportContacts=tenduke.contacts.ImportContacts;
	var Contact=tenduke.objectmodel.Contact;
	var ContactDetails=tenduke.objectmodel.ContactDetails;
	var EmailAddress=tenduke.objectmodel.EmailAddress;
	var UUID=tenduke.util.UUID;
	/**
	 * Import contacts from supported providers. Supported providers currently include
	 * Yahoo mail, Gmail and Hotmail.
	 */
	var ImportHotmailContacts = function(){
		ImportHotmailContacts.prototype.superClass.constructor.call(this);
    };
    //
    //
    copyPrototype(ImportHotmailContacts, ImportContacts);
    ImportHotmailContacts.prototype.superClass = ImportContacts.prototype;
    _callbacks = []; 
    _requestId = 0;
	//
	//
	ImportHotmailContacts.resultHandler=function(requestId, contacts){
		if(_callbacks[requestId]){
			if(contacts && contacts.length>0){
				for(var i=0; i<contacts.length; i++){
					var c= new Contact();
					c.setContactId(UUID.uuid());
					var cd=new ContactDetails();
					cd.setContactDetailsId(UUID.uuid());
					cd.setContactId(c.getContactId());
					if(contacts[i].name){
						cd.setFormattedName(contacts[i].name);
					}
					if(contacts[i].email){
						var e=new EmailAddress();
						e.setEmailAddressId(UUID.uuid());
						e.setContactDetailsId(cd.getContactDetailsId());
						e.setValue(contacts[i].email);
						cd.setEmail(e);
					}
					c.setContactDetails(cd);
					contacts[i]=c;
				}	
			}
			_callbacks[requestId](contacts);
			_callbacks[requestId]=null;
		}
	}
	ImportHotmailContacts.prototype.importContacts=function(params,callback){
		_callbacks[_requestId]=callback;
		var importContactsWindow = window.open('/importContacts.jsp?serviceProvider=hotmail&requestId=' +_requestId , '_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");
	    }
		_requestId++;
	};
	
	
    tenduke.contacts.hotmail.ImportHotmailContacts = ImportHotmailContacts;
})();//
//
tenduke.networking.Request = tenduke.networking.XmlHttpRequest;
tenduke.networking.RequestImpl = tenduke.networking.XmlHttpRequest;
tenduke.util.html.BusyManager.prototype.getDefaultView=function(){
		if(!this._defaultView){
			var d=document.createElement("div");
			d.className="busyIndicator";
			var i=document.createElement("img");
			i.src="/images/BusyIndicatorAnim.gif";
			i.setAttribute("title","");
			i.setAttribute("alt",".....");
			d.appendChild(i);
			var l=document.createElement("span");
			l.className="label";
			l.innerHTML="Loading";
			d.appendChild(l);
			this._defaultView=d;
		}
		return this._defaultView;
	}