/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * XXX This is a modified copy of MyFaces 3.0.0-SNAPSHOT (git 05d7a3c3 of 2019-08-28) jsf-uncompressed-full.js
 * XXX Modifications are marked with TOBAGO-JSF-JS
 */

/**
 * @namespace
 * @name window
 * @description Eval routines, depending on the browser.
 * <p/>
 * The problem solved in this class is the problem on how to perform
 * a global eval on multiple browsers. Some browsers auto eval themselves
 * they do not need to be called
 * <li>Some work with a window.eval.call(window,... </li>
 * <li>Others use simply execScript <li>
 * <li>Some others work only with the head appendix method
 * head.appendChild(&lt;script...., head.removeChild(&lt;script </li>
 * <p/>
 * Note: The code here already is precompressed because the compressor
 * fails on it, the deficits in readability will be covered by more comments
 *
 */


if (!window.myfaces) {
    /**
     * @namespace
     * @name myfaces
     */
    var myfaces = new function() {
    };
    window.myfaces = myfaces;
}

/**
 * @memberOf myfaces
 * @namespace
 * @name _impl
 */
myfaces._impl = (myfaces._impl) ? myfaces._impl : {};
/**
 * @memberOf myfaces._impl
 * @namespace
 * @name core
 */
myfaces._impl.core = (myfaces._impl.core) ? myfaces._impl.core :{};

if (!myfaces._impl.core._EvalHandlers) {
    /**
     * @memberOf myfaces._impl.core
     * @namespace
     * @name _EvalHandlers
     */
    myfaces._impl.core._EvalHandlers = new function() {
        //the rest of the namespaces can be handled by our namespace feature
        //helper to avoid unneeded hitches
        /**
         * @borrows myfaces._impl.core._Runtime as _T
         */
        var _T = this;


        /**
         * an implementation of eval which drops legacy support
         * and allows nonce
         * @param code
         * @param cspMeta optional csp metadata, only allowed key atm nonce
         */
        _T.globalEval = function(code, cspMeta) {
            //check for jsf nonce
            var nonce = cspMeta ? cspMeta.nonce : this._currentScriptNonce();

            var element = document.createElement("script");
            element.setAttribute("type", "text/javascript");
            element.innerHTML = code;
            if(nonce) {
                element.setAttribute("nonce", nonce);
            }
            //head appendix method, modern browsers use this method savely to eval scripts
            //we did not use it up until now because there were really old legacy browsers where
            //it did not work
            var htmlScriptElement = document.head.appendChild(element);
            document.head.removeChild(htmlScriptElement);
        };

        /*
        * determines the jsfjs nonce and adds them to the namespace
        * this is done once and only lazily
        */
        _T._currentScriptNonce = function() {
            //already processed
            if(myfaces.config && myfaces.config.cspMeta) {
                return myfaces.config.cspMeta.nonce;
            }

            //since our baseline atm is ie11 we cannot use document.currentScript globally
            if(document.currentScript && document.currentScript.getAttribute("nonce")) {
                //fastpath for modern browsers
                return document.currentScript.getAttribute("nonce") || null;
            }

            var scripts = document.querySelectorAll("script[src], link[src]");
            var jsf_js = null;

            //we search all scripts
            for(var cnt = 0; scripts && cnt < scripts.length; cnt++) {
                var scriptNode = scripts[cnt];
                if(!scriptNode.getAttribute("nonce")) {
                    continue;
                }
                var src = scriptNode.getAttribute("src") || "";
                if(src && !src.match(/jsf\.js\?ln\=javax\.faces/gi)) {
                    jsf_js = scriptNode;
                    //the first one is the one we have our code in
                    //subsequent ones do not overwrite our code
                    break;
                }
            }
            //found
            myfaces.config = myfaces.config || {};
            myfaces.config.cspMeta = myfaces.config.cspMeta || {
                nonce: null
            };
            if(jsf_js) {
                myfaces.config.cspMeta.nonce = jsf_js.getAttribute("nonce") || null;
            }
            return myfaces.config.cspMeta.nonce;
        };

    };
}
/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


/**
 * Runtime/Startup class
 * this is the central class which initializes all base mechanisms
 * used by the rest of the system such as
 * a) namespacing system
 * b) browser detection
 * c) loose configuration coupling
 * d) utils methods to fetch the implementation
 * e) ajaxed script loading
 * f) global eval (because it is used internally)
 * g) Structural base patterns as singleton, delegate and inheritance
 *
 * Note this class is self contained and must!!! be loaded
 * as absolute first class before going into anything else
 *
 *
 */
/** @namespace myfaces._impl.core._Runtime*/

myfaces._impl.core = (myfaces._impl.core) ? myfaces._impl.core : {};
//now this is the only time we have to do this cascaded and manually
//for the rest of the classes our reserveNamespace function will do the trick
//Note, this class uses the classical closure approach (to save code)
//it cannot be inherited by our inheritance mechanism, but must be delegated
//if you want to derive from it
//closures and prototype inheritance do not mix, closures and delegation however do
/**
 * @ignore
 */
if (!myfaces._impl.core._Runtime) {
    /**
     * @memberOf myfaces._impl.core
     * @namespace
     * @name _Runtime
     */
    myfaces._impl.core._Runtime = new function() {
        //the rest of the namespaces can be handled by our namespace feature
        //helper to avoid unneeded hitches
        /**
         * @borrows myfaces._impl.core._Runtime as _T
         */
        var _T = this;

        //namespace idx to speed things up by hitting eval way less
        this._reservedNMS = {};
        this._registeredSingletons = {};
        this._registeredClasses = [];
        /**
         * replacement counter for plugin classes
         */
        this._classReplacementCnt = 0;

        /**
         * global eval on scripts
         * @param {String} code
         * @name myfaces._impl.core._Runtime.globalEval
         * @function
         */
        _T.globalEval = function(code, cspMeta) {
            return myfaces._impl.core._EvalHandlers.globalEval(code, cspMeta);
        };

        /**
         * applies an object to a namespace
         * basically does what bla.my.name.space = obj does
         * note we cannot use var myNameSpace = fetchNamespace("my.name.space")
         * myNameSpace = obj because the result of fetch is already the object
         * which the namespace points to, hence this function
         *
         * @param {String} nms the namespace to be assigned to
         * @param {Object} obj the  object to be assigned
         * @name myfaces._impl.core._Runtime.applyToGlobalNamespace
         * @function
         */
        _T.applyToGlobalNamespace = function(nms, obj) {
            var splitted = nms.split(/\./);
            if (splitted.length == 1) {
                window[nms] = obj;
                return;
            }
            var parent = splitted.slice(0, splitted.length - 1);
            var child = splitted[splitted.length - 1];
            var parentNamespace = _T.fetchNamespace(parent.join("."));
            parentNamespace[child] = obj;
        };

        /**
         * fetches the object the namespace points to
         * @param {String} nms the namespace which has to be fetched
         * @return the object the namespace points to or null if nothing is found
         */
        this.fetchNamespace = function(nms) {
            if ('undefined' == typeof nms || null == nms || !_T._reservedNMS[nms]) {
                return null;
            }

            var ret = null;
            try {
                //blackberries have problems as well in older non webkit versions
                if (!_T.browser.isIE) {
                    //in ie 6 and 7 we get an error entry despite the suppression
                    ret = _T.globalEval("window." + nms);
                }
                //namespace could point to numeric or boolean hence full
                //save check

            } catch (e) {/*wanted*/
            }
            //ie fallback for some ie versions path because it cannot eval namespaces
            //ie in any version does not like that particularily
            //we do it the hard way now
            if ('undefined' != typeof ret && null != ret) {
                return ret;
            }
            return _T._manuallyResolveNMS(nms);

        };

        _T._manuallyResolveNMS = function(nms) {
            //ie fallback for some ie versions path because it cannot eval namespaces
            //ie in any version does not like that particularily
            //we do it the hard way now

            nms = nms.split(/\./);
            var ret = window;
            var len = nms.length;

            for (var cnt = 0; cnt < len; cnt++) {
                ret = ret[nms[cnt]];
                if ('undefined' == typeof ret || null == ret) {
                    return null;
                }
            }
            return ret;
        };

        /**
         * Backported from dojo
         * a failsafe string determination method
         * (since in javascript String != "" typeof alone fails!)
         * @param {Object} it  the object to be checked for being a string
         * @return {boolean} true in case of being a string false otherwise
         */
        this.isString = function(/*anything*/ it) {
            //	summary:
            //		Return true if it is a String
            return !!arguments.length && it != null && (typeof it == "string" || it instanceof String); // Boolean
        };

        /**
         * reserves a namespace in the specific scope
         *
         * usage:
         * if(_T.reserve("org.apache.myfaces.MyUtils")) {
         *      org.apache.myfaces.MyUtils = function() {
         *      }
         * }
         *
         * reserves a namespace and if the namespace is new the function itself is reserved
         *
         *
         *
         * or:
         * _T.reserve("org.apache.myfaces.MyUtils", function() { .. });
         *
         * reserves a namespace and if not already registered directly applies the function the namespace
         *
         * note for now the reserved namespaces reside as global maps justl like jsf.js but
         * we also use a speedup index which is kept internally to reduce the number of evals or loops to walk through those
         * namespaces (eval is a heavy operation and loops even only for namespace resolution introduce (O)2 runtime
         * complexity while a simple map lookup is (O)log n with additional speedup from the engine.
         *
         *
         * @param {String} nms
         * @returns {boolean} true if it was not provided
         * false otherwise for further action
         */
        this.reserveNamespace = function(nms, obj) {

            if (!_T.isString(nms)) {
                throw Error("Namespace must be a string with . as delimiter");
            }
            if (_T._reservedNMS[nms] || null != _T.fetchNamespace(nms)) {
                return false;
            }

            var entries = nms.split(/\./);
            var currNms = window;

            var tmpNmsName = [];
            var  UDEF = "undefined";
            for (var cnt = 0; cnt < entries.length; cnt++) {
                var subNamespace = entries[cnt];
                tmpNmsName.push(subNamespace);
                if (UDEF == typeof currNms[subNamespace]) {
                    currNms[subNamespace] = {};
                }
                if (cnt == entries.length - 1 && UDEF != typeof obj) {
                    currNms[subNamespace] = obj;
                } else {
                    currNms = currNms[subNamespace];
                }
                _T._reservedNMS[tmpNmsName.join(".")] = true;
            }
            return true;
        };

        /**
         * iterates over all registered singletons in the namespace
         * @param operator a closure which applies a certain function
         * on the namespace singleton
         */
        this.iterateSingletons = function(operator) {
            var singletons = _T._registeredSingletons;
            for(var key in singletons) {
                var nms = _T.fetchNamespace(key);
                operator(nms);
            }
        };
        /**
         * iterates over all registered singletons in the namespace
         * @param operator a closure which applies a certain function
         * on the namespace singleton
         */
        this.iterateClasses = function(operator) {
            var classes = _T._registeredClasses;
            for(var cnt  = 0; cnt < classes.length; cnt++) {
                operator(classes[cnt], cnt);
            }
        };

        /**
         * check if an element exists in the root
         * also allows to check for subelements
         * usage
         * _T.exists(rootElem,"my.name.space")
         * @param {Object} root the root element
         * @param {String} subNms the namespace
         */
        this.exists = function(root, subNms) {
            if (!root) {
                return false;
            }
            //special case locally reserved namespace
            if (root == window && _T._reservedNMS[subNms]) {
                return true;
            }

            //initial condition root set element not set or null
            //equals to element exists
            if (!subNms) {
                return true;
            }
            var UDEF = "undefined";
            try {
                //special condition subnamespace exists as full blown key with . instead of function map
                if (UDEF != typeof root[subNms]) {
                    return true;
                }

                //crossported from the dojo toolkit
                // summary: determine if an object supports a given method
                // description: useful for longer api chains where you have to test each object in the chain
                var p = subNms.split(".");
                var len = p.length;
                for (var i = 0; i < len; i++) {
                    //the original dojo code here was false because
                    //they were testing against ! which bombs out on exists
                    //which has a value set to false
                    // (TODO send in a bugreport to the Dojo people)

                    if (UDEF == typeof root[p[i]]) {
                        return false;
                    } // Boolean
                    root = root[p[i]];
                }
                return true; // Boolean

            } catch (e) {
                //ie (again) has a special handling for some object attributes here which automatically throw an unspecified error if not existent
                return false;
            }
        };



        /**
         * fetches a global config entry
         * @param {String} configName the name of the configuration entry
         * @param {Object} defaultValue
         *
         * @return either the config entry or if none is given the default value
         */
        this.getGlobalConfig = function(configName, defaultValue) {
            /**
             * note we could use exists but this is an heavy operation, since the config name usually
             * given this function here is called very often
             * is a single entry without . in between we can do the lighter shortcut
             */
            return (myfaces["config"] && 'undefined' != typeof myfaces.config[configName] ) ?
                myfaces.config[configName]
                :
                defaultValue;
        };

        /**
         * gets the local or global options with local ones having higher priority
         * if no local or global one was found then the default value is given back
         *
         * @param {String} configName the name of the configuration entry
         * @param {String} localOptions the local options root for the configuration myfaces as default marker is added implicitely
         *
         * @param {Object} defaultValue
         *
         * @return either the config entry or if none is given the default value
         */
        this.getLocalOrGlobalConfig = function(localOptions, configName, defaultValue) {
            /*use(myfaces._impl._util)*/
            var _local = !!localOptions;
            var _localResult;
            var MYFACES = "myfaces";

            if (_local) {
                //note we also do not use exist here due to performance improvement reasons
                //not for now we loose the subnamespace capabilities but we do not use them anyway
                //this code will give us a performance improvement of 2-3%
                _localResult = (localOptions[MYFACES]) ? localOptions[MYFACES][configName] : undefined;
                _local = "undefined" != typeof _localResult;
            }

            return (!_local) ? _T.getGlobalConfig(configName, defaultValue) : _localResult;
        };

        /**
         * determines the xhr level which either can be
         * 1 for classical level1
         * 1.5 for mozillas send as binary implementation
         * 2 for xhr level 2
         */
        this.getXHRLvl = function() {
            if (!_T.XHR_LEVEL) {
                _T.getXHRObject();
            }
            return _T.XHR_LEVEL;
        };

        /**
         * encapsulated xhr object which tracks down various implementations
         * of the xhr object in a browser independent fashion
         * (ie pre 7 used to have non standard implementations because
         * the xhr object standard came after IE had implemented it first
         * newer ie versions adhere to the standard and all other new browsers do anyway)
         *
         * @return the xhr object according to the browser type
         */
        this.getXHRObject = function() {
            var _ret = new XMLHttpRequest();
            //we now check the xhr level
            //sendAsBinary = 1.5 which means mozilla only
            //upload attribute present == level2
            var XHR_LEVEL = "XHR_LEVEL";
            if (!_T[XHR_LEVEL]) {
                var _e = _T.exists;
                _T[XHR_LEVEL] = (_e(_ret, "sendAsBinary")) ? 1.5 : 1;
                _T[XHR_LEVEL] = (_e(_ret, "upload") && 'undefined' != typeof FormData) ? 2 : _T.XHR_LEVEL;
            }
            return _ret;
        };

        /**
         * loads a script and executes it under a global scope
         * @param {String} src  the source of the script
         * @param {String} type the type of the script
         * @param {Boolean} defer  defer true or false, same as the javascript tag defer param
         * @param {String} charSet the charset under which the script has to be loaded
         * @param {Boolean} async tells whether the script can be asynchronously loaded or not, currently
         * @param cspMetas csp meta data to be processed by globalEval
         * not used
         */
        this.loadScriptEval = function(src, type, defer, charSet, async, cspMeta) {
            var xhr = _T.getXHRObject();
            xhr.open("GET", src, false);

            if (charSet) {
                xhr.setRequestHeader("Content-Type", "text/javascript; charset:" + charSet);
            }

            xhr.send(null);

            //since we are synchronous we do it after not with onReadyStateChange

            if (xhr.readyState == 4) {
                if (xhr.status == 200) {
                    //defer also means we have to process after the ajax response
                    //has been processed
                    //we can achieve that with a small timeout, the timeout
                    //triggers after the processing is done!
                    if (!defer) {
                        //we moved the sourceurl notation to # instead of @ because ie does not cover it correctly
                        //newer browsers understand # including ie since windows 8.1
                        //see http://updates.html5rocks.com/2013/06/sourceMappingURL-and-sourceURL-syntax-changed
                        _T.globalEval(xhr.responseText.replace("\n", "\r\n") + "\r\n//# sourceURL=" + src, cspMeta);
                    } else {
                        //TODO not ideal we maybe ought to move to something else here
                        //but since it is not in use yet, it is ok
                        setTimeout(function() {
                            _T.globalEval(xhr.responseText.replace("\n", "\r\n") + "\r\n//# sourceURL=" + src, cspMeta);
                        }, 1);
                    }
                } else {
                    throw Error(xhr.responseText);
                }
            } else {
                throw Error("Loading of script " + src + " failed ");
            }

        };

        /**
         * load script functionality which utilizes the browser internal
         * script loading capabilities
         *
         * @param {String} src  the source of the script
         * @param {String} type the type of the script
         * @param {Boolean} defer  defer true or false, same as the javascript tag defer param
         * @param {String} charSet the charset under which the script has to be loaded
         */
        this.loadScriptByBrowser = function(src, type, defer, charSet, async, cspMeta) {
            //if a head is already present then it is safer to simply
            //use the body, some browsers prevent head alterations
            //after the first initial rendering

            //ok this is nasty we have to do a head modification for ie pre 8
            //the rest can be finely served with body
            var position = "head";
            var UDEF = "undefined";
            try {
                var holder = document.getElementsByTagName(position)[0];
                if (UDEF == typeof holder || null == holder) {
                    holder = document.createElement(position);
                    var html = document.getElementsByTagName("html");
                    html.appendChild(holder);
                }
                var script = document.createElement("script");

                script.type = type || "text/javascript";
                script.src = src;
                if(cspMeta && cspMeta.nonce) {
                    script.setAttribute("nonce", cspMeta.nonce);
                }
                if (charSet) {
                    script.charset = charSet;
                }
                if (defer) {
                    script.defer = defer;
                }
                /*html5 capable browsers can deal with script.async for
                 * proper head loading*/
                if (UDEF != typeof script.async) {
                    script.async = async;
                }
                holder.appendChild(script);

            } catch (e) {
                //in case of a loading error we retry via eval
                return false;
            }

            return true;
        };

        this.loadScript = function(src, type, defer, charSet, async) {
            //the chrome engine has a nasty javascript bug which prevents
            //a correct order of scripts being loaded
            //if you use script source on the head, we  have to revert
            //to xhr+ globalEval for those
            var b = _T.browser;
            if (!b.isFF && !b.isWebkit && !b.isOpera >= 10) {
                _T.loadScriptEval(src, type, defer, charSet);
            } else {
                //only firefox keeps the order, sorry ie...
                _T.loadScriptByBrowser(src, type, defer, charSet, async);
            }
        };

        //Base Patterns, Inheritance, Delegation and Singleton



        /*
         * prototype based delegation inheritance
         *
         * implements prototype delegaton inheritance dest <- a
         *
         * usage
         * <pre>
         *  var newClass = _T.extends( function (var1, var2) {
         *                                          _T._callSuper("constructor", var1,var2);
         *                                     };
         *                                  ,origClass);
         *
         *       newClass.prototype.myMethod = function(arg1) {
         *              _T._callSuper("myMethod", arg1,"hello world");
         *       ....
         *
         * other option
         *
         * myfaces._impl._core._Runtime.extends("myNamespace.newClass", parent, {
         *                              init: function() {constructor...},
         *                              method1: function(f1, f2) {},
         *                              method2: function(f1, f2,f3) {
         *                                  _T._callSuper("method2", F1,"hello world");
         *                              }
         *              });
         * </p>
         * @param {function|String} newCls either a unnamed function which can be assigned later or a namespace
         * @param {function} extendCls the function class to be extended
         * @param {Object} protoFuncs (Map) an optional map of prototype functions which in case of overwriting a base function get an inherited method
         *
         * To explain further
         * prototype functions:
         * <pre>
         *  newClass.prototype.<prototypeFunction>
         * namspace function
         *  newCls.<namespaceFunction> = function() {...}
         *  </pre>
         */

        this.extendClass = function(newCls, extendCls, protoFuncs, nmsFuncs) {

            if (!_T.isString(newCls)) {
                throw Error("new class namespace must be of type String");
            }
            var className = newCls;

            if (_T._reservedNMS[newCls]) {
                return _T.fetchNamespace(newCls);
            }
            var constr = "constructor_";
            var parClassRef = "_mfClazz";
            if(!protoFuncs[constr]) {
                protoFuncs[constr] =  (extendCls[parClassRef]  || (extendCls.prototype && extendCls.prototype[parClassRef])) ?
                    function() {this._callSuper("constructor_");}: function() {};
                var assigned = true;
            }

            if ('function' != typeof newCls) {
                newCls = _reserveClsNms(newCls, protoFuncs);
                if (!newCls) return null;
            }
            //if the type information is known we use that one
            //with this info we can inherit from objects also
            //instead of only from classes
            //sort of like   this.extendClass(newCls, extendObj._mfClazz...

            if (extendCls[parClassRef]) {
                extendCls = extendCls[parClassRef];
            }

            if ('undefined' != typeof extendCls && null != extendCls) {
                //first we have to get rid of the constructor calling problem
                //problem
                var tmpFunc = function() {
                };
                tmpFunc.prototype = extendCls.prototype;

                var newClazz = newCls;
                newClazz.prototype = new tmpFunc();
                tmpFunc = null;
                var clzProto = newClazz.prototype;
                clzProto.constructor = newCls;
                clzProto._parentCls = extendCls.prototype;
                //in case of overrides the namespace is altered with mfclazz
                //we want the final namespace
                clzProto._nameSpace = className.replace(/(\._mfClazz)+$/,"");
                /**
                 * @ignore
                 */
                clzProto._callSuper = function(methodName) {
                    var passThrough = (arguments.length == 1) ? [] : Array.prototype.slice.call(arguments, 1);
                    var accDescLevel = "_mfClsDescLvl";
                    //we store the descension level of each method under a mapped
                    //name to avoid name clashes
                    //to avoid name clashes with internal methods of array
                    //if we don't do this we trap the callSuper in an endless
                    //loop after descending one level
                    var _mappedName = ["_",methodName,"_mf_r"].join("");
                    this[accDescLevel] = this[accDescLevel] || new Array();
                    var descLevel = this[accDescLevel];
                    //we have to detect the descension level
                    //we now check if we are in a super descension for the current method already
                    //if not we are on this level
                    var _oldDescLevel = this[accDescLevel][_mappedName] || this;
                    //we now step one level down
                    var _parentCls = _oldDescLevel._parentCls;
                    var ret = null;
                    try {
                        //we now store the level position as new descension level for callSuper
                        descLevel[_mappedName] = _parentCls;
                        //and call the code on this
                        if(!_parentCls[methodName]) {
                            throw Error("Method _callSuper('"+ methodName+"')  called from "+className+" Method does not exist ");
                        }
                        ret = _parentCls[methodName].apply(this, passThrough);
                    } finally {
                        descLevel[_mappedName] = _oldDescLevel;
                    }
                    if('undefined' != typeof ret) {
                        return ret;
                    }
                };
                //reference to its own type
                clzProto[parClassRef] = newCls;
                _T._registeredClasses.push(clzProto);
            }

            //we now map the function map in
            _T._applyFuncs(newCls, protoFuncs, true);
            //we could add inherited but that would make debugging harder
            //see http://www.ruzee.com/blog/2008/12/javascript-inheritance-via-prototypes-and-closures on how to do it

            _T._applyFuncs(newCls, nmsFuncs, false);

            return newCls;
        };



        /**
         * Extends a class and puts a singleton instance at the reserved namespace instead
         * of its original class
         *
         * @param {function|String} newCls either a unnamed function which can be assigned later or a namespace
         * @param {function} extendsCls the function class to be extended
         * @param {Object} protoFuncs (Map) an optional map of prototype functions which in case of overwriting a base function get an inherited method
         */
        this.singletonExtendClass = function(newCls, extendsCls, protoFuncs, nmsFuncs) {
            _T._registeredSingletons[newCls] = true;
            return _T._makeSingleton(_T.extendClass, newCls, extendsCls, protoFuncs, nmsFuncs);
        };



        //since the object is self contained and only
        //can be delegated we can work with real private
        //functions here, the other parts of the
        //system have to emulate them via _ prefixes
        this._makeSingleton = function(ooFunc, newCls, delegateObj, protoFuncs, nmsFuncs) {
            if (_T._reservedNMS[newCls]) {
                return _T._reservedNMS[newCls];
            }

            var clazz = ooFunc(newCls + "._mfClazz", delegateObj, protoFuncs, nmsFuncs);
            if (clazz != null) {
                _T.applyToGlobalNamespace(newCls, new clazz());
            }
            return _T.fetchNamespace(newCls)["_mfClazz"] = clazz;
        };

        //internal class namespace reservation depending on the type (string or function)
        var _reserveClsNms = function(newCls, protoFuncs) {
            var constr = null;
            var UDEF = "undefined";
            if (UDEF != typeof protoFuncs && null != protoFuncs) {
                constr = (UDEF != typeof null != protoFuncs['constructor_'] && null != protoFuncs['constructor_']) ? protoFuncs['constructor_'] : function() {
                };
            } else {
                constr = function() {
                };
            }

            if (!_T.reserveNamespace(newCls, constr)) {
                return null;
            }
            newCls = _T.fetchNamespace(newCls);
            return newCls;
        };

        this._applyFuncs = function (newCls, funcs, proto) {
            if (funcs) {
                for (var key in funcs) {
                    //constructor already passed, callSuper already assigned
                    if ('undefined' == typeof key || null == key || key == "_callSuper") {
                        continue;
                    }
                    if (!proto)
                        newCls[key] = funcs[key];
                    else
                        newCls.prototype[key] = funcs[key];
                }
            }
        };

        /**
         * general type assertion routine
         *
         * @param probe the probe to be checked for the correct type
         * @param theType the type to be checked for
         */
        this.assertType = function(probe, theType) {
            return _T.isString(theType) ? probe == typeof theType : probe instanceof theType;
        };

        /**
         * onload wrapper for chaining the onload cleanly
         * @param func the function which should be added to the load
         * chain (note we cannot rely on return values here, hence jsf.util.chain will fail)
         */
        this.addOnLoad = function(target, func) {
            var oldonload = (target) ? target.onload : null;
            target.onload = (!oldonload) ? func : function() {
                try {
                    oldonload();
                } catch (e) {
                    throw e;
                } finally {
                    func();
                }
            };
        };

        /**
         * returns the internationalisation setting
         * for the given browser so that
         * we can i18n our messages
         *
         * @returns a map with following entires:
         * <ul>
         *      <li>language: the lowercase language iso code</li>
         *      <li>variant: the uppercase variant iso code</li>
         * </ul>
         * null is returned if the browser fails to determine the language settings
         */
        this.getLanguage = function(lOverride) {
            var deflt = {language: "en", variant: "UK"}; //default language and variant
            try {
                var lang = lOverride || navigator.language || navigator.browserLanguage;
                if (!lang || lang.length < 2) return deflt;
                return {
                    language: lang.substr(0, 2),
                    variant: (lang.length >= 5) ? lang.substr(3, 5) : null
                };
            } catch(e) {
                return deflt;
            }
        };

        //implemented in extruntime
        this.singletonDelegateObj = function()  {};

        /**
         * browser detection code
         * cross ported from dojo 1.2
         *
         * dojos browser detection code is very sophisticated
         * hence we port it over it allows a very fine grained detection of
         * browsers including the version number
         * this however only can work out if the user
         * does not alter the user agent, which they normally dont!
         *
         * the exception is the ie detection which relies on specific quirks in ie
         *
         * TODO check if the browser detection still is needed
         * for 2.3 since our baseline will be IE11 most likely not
         */
        var n = navigator;
        var dua = n.userAgent,
            dav = n.appVersion,
            tv = parseFloat(dav);
        var _T = this;
        _T.browser = {};
        myfaces._impl.core._EvalHandlers.browser = _T.browser;
        var d = _T.browser;

        if (dua.indexOf("Opera") >= 0) {
            _T.isOpera = tv;
        }
        if (dua.indexOf("AdobeAIR") >= 0) {
            d.isAIR = 1;
        }
        if (dua.indexOf("BlackBerry") >= 0) {
            d.isBlackBerry = tv;
        }
        d.isKhtml = (dav.indexOf("Konqueror") >= 0) ? tv : 0;
        d.isWebKit = parseFloat(dua.split("WebKit/")[1]) || undefined;
        d.isChrome = parseFloat(dua.split("Chrome/")[1]) || undefined;

        // safari detection derived from:
        //		http://developer.apple.com/internet/safari/faq.html#anchor2
        //		http://developer.apple.com/internet/safari/uamatrix.html
        var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);
        if (index && !d.isChrome) {
            // try to grab the explicit Safari version first. If we don't get
            // one, look for less than 419.3 as the indication that we're on something
            // "Safari 2-ish".
            d.isSafari = parseFloat(dav.split("Version/")[1]);
            if (!d.isSafari || parseFloat(dav.substr(index + 7)) <= 419.3) {
                d.isSafari = 2;
            }
        }

        //>>excludeStart("webkitMobile", kwArgs.webkitMobile);

        if (dua.indexOf("Gecko") >= 0 && !d.isKhtml && !d.isWebKit) {
            d.isMozilla = d.isMoz = tv;
        }
        if (d.isMoz) {
            //We really need to get away from _T. Consider a sane isGecko approach for the future.
            d.isFF = parseFloat(dua.split("Firefox/")[1] || dua.split("Minefield/")[1] || dua.split("Shiretoko/")[1]) || undefined;
        }

        if (document.all && !d.isOpera && !d.isBlackBerry) {
            d.isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
            d.isIEMobile = parseFloat(dua.split("IEMobile")[1]);
            //In cases where the page has an HTTP header or META tag with
            //X-UA-Compatible, then it is in emulation mode, for a previous
            //version. Make sure isIE reflects the desired version.
            //document.documentMode of 5 means quirks mode.

            /** @namespace document.documentMode */
            if (d.isIE >= 8 && document.documentMode != 5) {
                d.isIE = document.documentMode;
            }
        }
    };
}


/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*we cannot privatize with a global function hence we store the values away for the init part*/
(function() {
    var target = window || document.body;
    var impl = "myfaces._impl.";
    var params = {_PFX_UTIL: impl + "_util.",
        _PFX_CORE:impl + "core.",
        _PFX_XHR: impl + "xhrCore.",
        _PFX_I18N: impl + "i18n."};
    if ('undefined' != typeof target.myfaces) {
        //some mobile browsers do not have a window object
        var _RT = myfaces._impl.core._Runtime;
        params._MF_CLS = _RT.extendClass;
        params._MF_SINGLTN = _RT.singletonExtendClass;
    } else {
        params._MF_CLS = false;
        params._MF_SINGLTN = false;
        target.myfaces = {};
    }
    target.myfaces._implTemp = {};
    for (var key in params) {
        target.myfaces._implTemp[key] = target[key];
        target[key] = params[key];
    }
})();

/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @memberOf myfaces._impl
 * @namespace
 * @name i18n
 */

/**
 * System messages base version    <p />
 * (note the base version is basically the en_US) version
 * of all messages
 *
 * @class
 * @name Messages
 * @memberOf myfaces._impl.i18n
 */
_MF_CLS && _MF_CLS(_PFX_I18N+"Messages", Object,
    /**
     * @lends myfaces._impl.i18n.Messages.prototype
     */
    {

        MSG_TEST:               "Testmessage",

        /*Messages*/
        /** @constant */
        MSG_DEV_MODE:           "Note, this message is only sent, because project stage is development and no " +
            "other error listeners are registered.",
        /** @constant */
        MSG_AFFECTED_CLASS:     "Affected Class:",
        /** @constant */
        MSG_AFFECTED_METHOD:    "Affected Method:",
        /** @constant */
        MSG_ERROR_NAME:         "Error Name:",
        /** @constant */
        MSG_ERROR_MESSAGE:      "Error Message:",
        /** @constant */
        MSG_SERVER_ERROR_NAME:  "Server Error Name:",

        /** @constant */
        MSG_ERROR_DESC:         "Error Description:",
        /** @constant */
        MSG_ERROR_NO:           "Error Number:",
        /** @constant */
        MSG_ERROR_LINENO:       "Error Line Number:",

        /*Errors and messages*/
        /** @constant */
        ERR_FORM:               "Sourceform could not be determined, either because element is not attached to a form or we have multiple forms with named elements of the same identifier or name, stopping the ajax processing",
        /** @constant */
        ERR_VIEWSTATE:          "jsf.viewState: param value not of type form!",
        /** @constant */
        ERR_TRANSPORT:          "Transport type {0} does not exist",
        /** @constant */
        ERR_EVT_PASS:           "an event must be passed down (either a an event object null or undefined) ",
        /** @constant */
        ERR_CONSTRUCT:          "Parts of the response couldn't be retrieved when constructing the event data: {0} ",
        /** @constant */
        ERR_MALFORMEDXML:       "The server response could not be parsed, the server has returned with a response which is not xml !",
        /** @constant */
        ERR_SOURCE_FUNC:        "source cannot be a function (probably source and event were not defined or set to null",
        /** @constant */
        ERR_EV_OR_UNKNOWN:      "An event object or unknown must be passed as second parameter",
        /** @constant */
        ERR_SOURCE_NOSTR:       "source cannot be a string",
        /** @constant */
        ERR_SOURCE_DEF_NULL:    "source must be defined or null",

        //_Lang.js
        /** @constant */
        ERR_MUST_STRING:        "{0}: {1} namespace must be of type String",
        /** @constant */
        ERR_REF_OR_ID:          "{0}: {1} a reference node or identifier must be provided",
        /** @constant */
        ERR_PARAM_GENERIC:      "{0}: parameter {1} must be of type {2}",
        /** @constant */
        ERR_PARAM_STR:          "{0}: {1} param must be of type string",
        /** @constant */
        ERR_PARAM_STR_RE:       "{0}: {1} param must be of type string or a regular expression",
        /** @constant */
        ERR_PARAM_MIXMAPS:      "{0}: both a source as well as a destination map must be provided",
        /** @constant */
        ERR_MUST_BE_PROVIDED:   "{0}: an {1} and a {2} must be provided",
        /** @constant */
        ERR_MUST_BE_PROVIDED1:  "{0}: {1} must be set",

        /** @constant */
        ERR_REPLACE_EL:         "replaceElements called while evalNodes is not an array",

        /** @constant */
        ERR_EMPTY_RESPONSE:     "{0}: The response cannot be null or empty!",
        /** @constant */
        ERR_ITEM_ID_NOTFOUND:   "{0}: item with identifier {1} could not be found",
        /** @constant */
        ERR_PPR_IDREQ:          "{0}: Error in PPR Insert, id must be present",
        /** @constant */
        ERR_PPR_INSERTBEFID:    "{0}: Error in PPR Insert, before id or after id must be present",
        /** @constant */
        ERR_PPR_INSERTBEFID_1:  "{0}: Error in PPR Insert, before  node of id {1} does not exist in document",
        /** @constant */
        ERR_PPR_INSERTBEFID_2:  "{0}: Error in PPR Insert, after  node of id {1} does not exist in document",

        /** @constant */
        ERR_PPR_DELID:          "{0}: Error in delete, id not in xml markup",
        /** @constant */
        ERR_PPR_UNKNOWNCID:     "{0}:  Unknown Html-Component-ID: {1}",

        /** @constant */
        ERR_NO_VIEWROOTATTR:    "{0}: Changing of ViewRoot attributes is not supported",
        /** @constant */
        ERR_NO_HEADATTR:        "{0}: Changing of Head attributes is not supported",
        /** @constant */
        ERR_RED_URL:            "{0}: Redirect without url",

        /** @constant */
        ERR_REQ_FAILED_UNKNOWN: "Request failed with unknown status",

        /** @constant */
        ERR_REQU_FAILED: "Request failed with status {0} and reason {1}",

        /** @constant */
        UNKNOWN: "UNKNOWN",

        ERR_NO_MULTIPART_FORM: "The form with the id {0} has an input file element, but is not a multipart form"
    });


/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


/**
 * System messages german version
 * (note the base version is basically the en_US) version
 * of all messages
 * <p />
 * We use inheritance to overide the default messages with our
 * german one, variants can derive from the german one (like
 * suisse which do not have the emphasized s)
 * <p />
 * By using inheritance we can be sure that we fall back to the default one
 * automatically and that our variants only have to override the parts
 * which have changed from the baseline
 *
 * @class
 * @name Messages_de
 * @extends myfaces._impl.i18n.Messages
 * @memberOf myfaces._impl.i18n
 */

_MF_CLS && _MF_CLS(_PFX_I18N + "Messages_de", myfaces._impl.i18n.Messages,
    /** @lends myfaces._impl.i18n.Messages_de.prototype */
    {

        MSG_TEST:               "Testnachricht",

        /*Messages*/
        MSG_DEV_MODE:           "Sie sehen diese Nachricht, da sie sich gerade im Entwicklungsmodus befinden " +
            "und sie keine Fehlerbehandlungsfunktionen registriert haben.",

        MSG_AFFECTED_CLASS:     "Klasse:",
        MSG_AFFECTED_METHOD:    "Methode:",

        MSG_ERROR_NAME:         "Fehler Name:",
        MSG_ERROR_MESSAGE:      "Nachricht:",
        MSG_SERVER_ERROR_NAME:  "Server Fehler Name:",

        MSG_ERROR_DESC:         "Fehlerbeschreibung:",
        MSG_ERROR_NO:           "Fehlernummer:",
        MSG_ERROR_LINENO:       "Zeilennummer:",

        /*Errors and messages*/
        ERR_FORM:                "Das Quellformular konnte nicht gefunden werden. " +
            "Mögliche Gründe: Sie haben entweder kein formular definiert, oder es kommen mehrere Formulare vor, " +
            "die alle das auslösende Element mit demselben Namen besitzen. " +
            "Die Weitere Ajax Ausführung wird gestoppt.",

        ERR_VIEWSTATE:          "jsf.viewState: der Parameter ist not vom Typ form!",

        ERR_TRANSPORT:          "Transport typ {0} existiert nicht",
        ERR_EVT_PASS:           "Ein Event Objekt muss übergeben werden (entweder ein event Objekt oder null oder undefined)",
        ERR_CONSTRUCT:          "Teile des response konnten nicht ermittelt werden während die Event Daten bearbeitet wurden: {0} ",
        ERR_MALFORMEDXML:       "Es gab zwar eine Antwort des Servers, jedoch war diese nicht im erwarteten XML Format. Der Server hat kein valides XML gesendet! Bearbeitung abgebrochen.",
        ERR_SOURCE_FUNC:        "source darf keine Funktion sein",
        ERR_EV_OR_UNKNOWN:      "Ein Ereignis Objekt oder UNKNOWN muss als 2. Parameter übergeben werden",
        ERR_SOURCE_NOSTR:       "source darf kein String sein",
        ERR_SOURCE_DEF_NULL:    "source muss entweder definiert oder null sein",

        //_Lang.js
        ERR_MUST_STRING:        "{0}: {1} namespace muss vom Typ String sein",
        ERR_REF_OR_ID:          "{0}: {1} Ein Referenzknoten oder id muss übergeben werden",
        ERR_PARAM_GENERIC:      "{0}: Paramter {1} muss vom Typ {2} sein",
        ERR_PARAM_STR:          "{0}: Parameter {1} muss vom Typ String sein",
        ERR_PARAM_STR_RE:       "{0}: Parameter {1} muss entweder ein String oder ein Regulärer Ausdruck sein",
        ERR_PARAM_MIXMAPS:      "{0}: both a source as well as a destination map must be provided",
        ERR_MUST_BE_PROVIDED:   "{0}: ein {1} und ein {2} müssen übergeben werden",
        ERR_MUST_BE_PROVIDED1:  "{0}: {1} muss gesetzt sein",

        ERR_REPLACE_EL:         "replaceElements aufgerufen während evalNodes nicht ein Array ist",
        ERR_EMPTY_RESPONSE:     "{0}: Die Antwort darf nicht null oder leer sein!",
        ERR_ITEM_ID_NOTFOUND:   "{0}: Element mit ID {1} konnte nicht gefunden werden",
        ERR_PPR_IDREQ:          "{0}: Fehler im PPR Insert, ID muss gesetzt sein",
        ERR_PPR_INSERTBEFID:    "{0}: Fehler im PPR Insert, before ID oder after ID muss gesetzt sein",
        ERR_PPR_INSERTBEFID_1:  "{0}: Fehler im PPR Insert, before  Knoten mit ID {1} Existiert nicht",
        ERR_PPR_INSERTBEFID_2:  "{0}: Fehler im PPR Insert, after  Knoten mit ID {1} Existiert nicht",

        ERR_PPR_DELID:          "{0}: Fehler im PPR delete, id ist nicht im xml Markup vorhanden",
        ERR_PPR_UNKNOWNCID:     "{0}: Unbekannte Html-Komponenten-ID: {1}",
        ERR_NO_VIEWROOTATTR:    "{0}: Änderung von ViewRoot Attributen ist nicht erlaubt",
        ERR_NO_HEADATTR:        "{0}: Änderung von Head Attributen ist nicht erlaubt",
        ERR_RED_URL:            "{0}: Redirect ohne URL",

        ERR_REQ_FAILED_UNKNOWN: "Anfrage mit unbekanntem Status fehlgeschlagen",
        ERR_REQU_FAILED: "Anfrage mit Status {0} and Ursache {1} fehlgeschlagen",
        UNKNOWN: "Unbekannt",
        ERR_NO_MULTIPART_FORM: "Das Form Element mit der ID {0} hat ein Fileupload Feld aber ist kein Multipart Form"

    });


/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * System messages dutch version
 *
 * @class
 * @name Messages_nl
 * @extends myfaces._impl.i18n.Messages
 * @memberOf myfaces._impl.i18n
 */
_MF_CLS && _MF_CLS(_PFX_I18N + "Messages_nl", myfaces._impl.i18n.Messages,
    /** @lends myfaces._impl.i18n.Messages_nl.prototype */
    {

        MSG_TEST:               "Testbericht",

        /*Messages*/
        MSG_DEV_MODE:           "Opmerking, dit bericht is enkel gestuurd omdat het project stadium develoment is en er geen " +
            "andere listeners zijn geconfigureerd.",
        MSG_AFFECTED_CLASS:     "Betrokken Klasse:",
        MSG_AFFECTED_METHOD:    "Betrokken Methode:",

        MSG_ERROR_NAME:         "Naam foutbericht:",
        MSG_ERROR_MESSAGE:      "Naam foutbericht:",

        MSG_ERROR_DESC:         "Omschrijving fout:",
        MSG_ERROR_NO:           "Fout nummer:",
        MSG_ERROR_LINENO:       "Fout lijn nummer:",

        /*Errors and messages*/
        ERR_FORM:               "De doel form kon niet bepaald worden, ofwel omdat het element niet tot een form behoort, ofwel omdat er verschillende forms zijn met 'named element' met dezelfde identifier of naam, ajax verwerking is gestopt.",
        ERR_VIEWSTATE:          "jsf.viewState: param waarde is niet van het type form!",
        ERR_TRANSPORT:          "Transport type {0} bestaat niet",
        ERR_EVT_PASS:           "een event moet opgegegevn worden (ofwel een event object null of undefined) ",
        ERR_CONSTRUCT:          "Delen van het antwoord konden niet opgehaald worden bij het aanmaken van de event data: {0} ",
        ERR_MALFORMEDXML:       "Het antwoordt van de server kon niet ontleed worden, de server heeft een antwoord gegeven welke geen xml bevat!",
        ERR_SOURCE_FUNC:        "source kan geen functie zijn (waarschijnlijk zijn source en event niet gedefinieerd of kregen de waarde null)",
        ERR_EV_OR_UNKNOWN:      "Een event object of 'unknown' moet gespecifieerd worden als tweede parameter",
        ERR_SOURCE_NOSTR:       "source kan geen string zijn",
        ERR_SOURCE_DEF_NULL:    "source moet gedefinieerd zijn of null bevatten",

        //_Lang.js
        ERR_MUST_STRING:        "{0}: {1} namespace moet van het type String zijn",
        ERR_REF_OR_ID:          "{0}: {1} een referentie node of identifier moet opgegeven worden",
        ERR_PARAM_GENERIC:      "{0}: parameter {1} moet van het type {2} zijn",
        ERR_PARAM_STR:          "{0}: {1} parameter moet van het type string zijn",
        ERR_PARAM_STR_RE:       "{0}: {1} parameter moet van het type string zijn of een reguliere expressie",
        ERR_PARAM_MIXMAPS:      "{0}: zowel source als destination map moeten opgegeven zijn",
        ERR_MUST_BE_PROVIDED:   "{0}: een {1} en een {2} moeten opgegeven worden",
        ERR_MUST_BE_PROVIDED1:  "{0}: {1} moet gezet zijn",

        ERR_REPLACE_EL:         "replaceElements opgeroepen maar evalNodes is geen array",
        ERR_EMPTY_RESPONSE:     "{0}: Het antwoord kan geen null of leeg zijn!",
        ERR_ITEM_ID_NOTFOUND:   "{0}: item met identifier {1} kan niet gevonden worden",
        ERR_PPR_IDREQ:          "{0}: Fout in PPR Insert, id moet bestaan",
        ERR_PPR_INSERTBEFID:    "{0}: Fout in PPR Insert, before id of after id moet bestaan",
        ERR_PPR_INSERTBEFID_1:  "{0}: Fout in PPR Insert, before node van id {1} bestaat niet in het document",
        ERR_PPR_INSERTBEFID_2:  "{0}: Fout in PPR Insert, after node van id {1} bestaat niet in het document",

        ERR_PPR_DELID:          "{0}: Fout in delete, id is niet in de xml markup",
        ERR_PPR_UNKNOWNCID:     "{0}: Onbekende Html-Component-ID: {1}",
        ERR_NO_VIEWROOTATTR:    "{0}: Wijzigen van ViewRoot attributen is niet ondersteund",
        ERR_NO_HEADATTR:        "{0}: Wijzigen van Head attributen is niet ondersteund",
        ERR_RED_URL:            "{0}: Redirect zonder url",

        ERR_REQ_FAILED_UNKNOWN: "Request mislukt met onbekende status",
        ERR_REQU_FAILED:        "Request mislukt met status {0} en reden {1}",
        UNKNOWN:                "ONBEKEND"

    });

/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


/**
 * System messages french version version
 * (note the base version is basically the en) version
 * of all messages
 *
 * @class
 * @name Messages_fr
 * @extends myfaces._impl.i18n.Messages
 * @memberOf myfaces._impl.i18n
 */
_MF_CLS && _MF_CLS(_PFX_I18N + "Messages_fr", myfaces._impl.i18n.Messages,
    /** @lends myfaces._impl.i18n.Messages_fr.prototype */
    {
        MSG_TEST:               "MessageTest FR",

        /*Messages*/
        MSG_DEV_MODE:           "Note : ce message n'est envoyé que parce que le projet est au stade de développement et " +
            "qu'aucun autre listener d'erreurs n'est enregistré.",
        MSG_AFFECTED_CLASS:     "Classe affectée : ",
        MSG_AFFECTED_METHOD:    "Méthode affectée : ",

        MSG_ERROR_NAME:         "Nom de l'erreur : ",
        MSG_ERROR_MESSAGE:      "Nom de l'erreur : ",

        MSG_ERROR_DESC:         "Description de l'erreur : ",
        MSG_ERROR_NO:           "Numéro de l'erreur : ",
        MSG_ERROR_LINENO:       "Erreur à la ligne : ",

        /*Errors and messages*/
        ERR_FORM:               "Le formulaire source n'a pas pu être déterminé, soit parce que l'élément n'est rattaché à aucun formulaire, soit parce qu'ils y a plusieurs formulaires contenant des éléments avec le même nom ou identifiant. Arrêt du traitement AJAX",
        ERR_VIEWSTATE:          "jsf.viewState: La valeur de 'param' n'est pas de type 'form' !",
        ERR_TRANSPORT:          "Le type de tansport {0} n'existe pas",
        ERR_EVT_PASS:           "Un évènement doit être transmis (soit un objet évènement, soit null ou undefined) ",
        ERR_CONSTRUCT:          "Des éléments de la réponse n'ont pu être récupérés lors de la construction des données de l'évènement : {0} ",
        ERR_MALFORMEDXML:       "La réponse du serveur n'a pas pu être analysée : le serveur n'a pas renvoyé une réponse en xml !",
        ERR_SOURCE_FUNC:        "La source ne peut pas être une fonction (Il est probable que 'source' et 'event' n'ont pas été définis ou mis à null",
        ERR_EV_OR_UNKNOWN:      "Le second paramètre doit être un objet évènement ou 'unknown' ",
        ERR_SOURCE_NOSTR:       "La source ne peut pas être de type String",
        ERR_SOURCE_DEF_NULL:    "La source doit être définie ou égale à null",

        //_Lang.js
        ERR_MUST_STRING:        "{0}: Le namespace {1} doit être de type String",
        ERR_REF_OR_ID:          "{0}: {1} un noeud de référence ou un identifiant doit être passé",
        ERR_PARAM_GENERIC:      "{0}: Le paramètre {1} doit être de type {2}",
        ERR_PARAM_STR:          "{0}: Le paramètre {1} doit être de type String",
        ERR_PARAM_STR_RE:       "{0}: Le paramètre {1} doit être de type String ou être une expression régulière",
        ERR_PARAM_MIXMAPS:      "{0}: Un Map de source et un Map de destination doivent être passés",
        ERR_MUST_BE_PROVIDED:   "{0}: un(e) {1} et un(e) {2} doivent être passés",
        ERR_MUST_BE_PROVIDED1:  "{0}: {1} doit être défini",

        ERR_REPLACE_EL:         "replaceElements a été appelé alors que evalNodes n'est pas un tableau",
        ERR_EMPTY_RESPONSE:     "{0}: La réponse ne peut pas être nulle ou vide !",
        ERR_ITEM_ID_NOTFOUND:   "{0}: l'élément portant l'identifiant {1} n'a pas pu être trouvé",
        ERR_PPR_IDREQ:          "{0}: Erreur lors de l'insertion PPR, l'id doit être présent",
        ERR_PPR_INSERTBEFID:    "{0}: Erreur lors de l'insertion PPR, 'before id' ou 'after id' doivent être présents",
        ERR_PPR_INSERTBEFID_1:  "{0}: Erreur lors de l'insertion PPR, le noeud before de l'id {1} n'existe pas dans le document",
        ERR_PPR_INSERTBEFID_2:  "{0}: Erreur lors de l'insertion PPR, le noeud after  de l'id {1} n'existe pas dans le document",

        ERR_PPR_DELID:          "{0}: Erreur lors de la suppression, l'id n'est pas présent dans le xml",
        ERR_PPR_UNKNOWNCID:     "{0}:  Html-Component-ID inconnu : {1}",
        ERR_NO_VIEWROOTATTR:    "{0}: Le changement d'attributs dans ViewRoot n'est pas supporté",
        ERR_NO_HEADATTR:        "{0}: Le changement d'attributs dans Head n'est pas supporté",
        ERR_RED_URL:            "{0}: Redirection sans url"
    });

/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * System messages italian version version
 * (note the base version is basically the en_US) version
 * of all messages
 *
 * @class
 * @name Messages_it
 * @extends myfaces._impl.i18n.Messages
 * @memberOf myfaces._impl.i18n
 */
_MF_CLS && _MF_CLS(_PFX_I18N + "Messages_it", myfaces._impl.i18n.Messages,
    /** @lends myfaces._impl.i18n.Messages_it.prototype */
    {
        /*Messages*/
        MSG_DEV_MODE:           "Questo messaggio � stato inviato esclusivamente perch� il progetto � in development stage e nessun altro listener � stato registrato.",
        MSG_AFFECTED_CLASS:     "Classi coinvolte:",
        MSG_AFFECTED_METHOD:    "Metodi coinvolti:",

        MSG_ERROR_NAME:         "Nome dell'errore:",
        MSG_ERROR_MESSAGE:      "Nome dell'errore:",

        MSG_ERROR_DESC:         "Descrizione dell'errore:",
        MSG_ERROR_NO:           "Numero errore:",
        MSG_ERROR_LINENO:       "Numero di riga dell'errore:",

        /*Errors and messages*/
        ERR_FORM:               "Il Sourceform non puo' essere determinato a causa di una delle seguenti ragioni: l'elemento non e' agganciato ad un form oppure sono presenti pi� form con elementi con lo stesso nome, il che blocca l'elaborazione ajax",
        ERR_VIEWSTATE:          "jsf.viewState: il valore del parametro non � di tipo form!",
        ERR_TRANSPORT:          "Il transport type {0} non esiste",
        ERR_EVT_PASS:           "� necessario passare un evento (sono accettati anche gli event object null oppure undefined) ",
        ERR_CONSTRUCT:          "Durante la costruzione dell' event data: {0} non � stato possibile acquisire alcune parti della response ",
        ERR_MALFORMEDXML:       "Il formato della risposta del server non era xml, non � stato quindi possibile effettuarne il parsing!",
        ERR_SOURCE_FUNC:        "source non puo' essere una funzione (probabilmente source and event non erano stati definiti o sono null",
        ERR_EV_OR_UNKNOWN:      "Come secondo parametro bisogna passare un event object oppure unknown",
        ERR_SOURCE_NOSTR:       "source non pu� essere una stringa di testo",
        ERR_SOURCE_DEF_NULL:    "source deve essere definito oppure  null",

        //_Lang.js
        ERR_MUST_STRING:        "{0}: {1} namespace deve essere di tipo String",
        ERR_REF_OR_ID:          "{0}: {1} un reference node oppure un identificatore deve essere fornito",
        ERR_PARAM_GENERIC:      "{0}: il parametro {1} deve essere di tipo {2}",
        ERR_PARAM_STR:          "{0}: {1} parametro deve essere di tipo String",
        ERR_PARAM_STR_RE:       "{0}: {1} parametro deve essere di tipo String oppure una regular expression",
        ERR_PARAM_MIXMAPS:      "{0}: � necessario specificare sia  source che destination map",
        ERR_MUST_BE_PROVIDED:   "{0}: � necessario specificare sia {1} che {2} ",
        ERR_MUST_BE_PROVIDED1:  "{0}: {1} deve essere settato",

        ERR_REPLACE_EL:         "replaceElements chiamato metre evalNodes non � un array",
        ERR_EMPTY_RESPONSE:     "{0}: La response non puo' essere nulla o vuota!",
        ERR_ITEM_ID_NOTFOUND:   "{0}: non � stato trovato alcun item con identificativo {1}",
        ERR_PPR_IDREQ:          "{0}: Errore durante la PPR Insert, l' id deve essere specificato",
        ERR_PPR_INSERTBEFID:    "{0}: Errore durante la PPR Insert, before id o after id deve essere specificato",
        ERR_PPR_INSERTBEFID_1:  "{0}: Errore durante la PPR Insert, before node of id {1} non esiste nel document",
        ERR_PPR_INSERTBEFID_2:  "{0}: Errore durante la PPR Insert, after  node of id {1} non esiste nel in document",

        ERR_PPR_DELID:          "{0}: Errore durante la delete, l'id non e' nella forma di un markup xml",
        ERR_PPR_UNKNOWNCID:     "{0}:   Html-Component-ID: {1} sconosciuto",
        ERR_NO_VIEWROOTATTR:    "{0}: La modifica degli attributi del ViewRoot non � supportata",
        ERR_NO_HEADATTR:        "{0}: La modifica degli attributi di Head non � supportata",
        ERR_RED_URL:            "{0}: Redirect senza url"
    });


/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


/**
 * System messages spanish version version
 * (note the base version is basically the en_US) version
 * of all messages
 *
 * @class
 * @name Messages_es
 * @extends myfaces._impl.i18n.Messages
 * @memberOf myfaces._impl.i18n
 */

_MF_CLS && _MF_CLS(_PFX_I18N + "Messages_es", myfaces._impl.i18n.Messages,
    /** @lends myfaces._impl.i18n.Messages_es.prototype */
    {


        MSG_TEST:               "Mensajeprueba",

        /*Messages*/
        MSG_DEV_MODE:           "Aviso. Este mensaje solo se envia porque el 'Project Stage' es 'Development' y no hay otros 'listeners' de errores registrados.",
        MSG_AFFECTED_CLASS:     "Clase Afectada:",
        MSG_AFFECTED_METHOD:    "M�todo Afectado:",

        MSG_ERROR_NAME:         "Nombre del Error:",
        MSG_ERROR_MESSAGE:      "Mensaje del Error:",
        MSG_SERVER_ERROR_NAME:  "Mensaje de error de servidor:",

        MSG_ERROR_DESC:         "Descripci�n del Error:",
        MSG_ERROR_NO:           "N�mero de Error:",
        MSG_ERROR_LINENO:       "N�mero de L�nea del Error:",

        /*Errors and messages*/
        ERR_FORM:               "El formulario de origen no ha podido ser determinado, debido a que el elemento no forma parte de un formulario o hay diversos formularios con elementos usando el mismo nombre o identificador. Parando el procesamiento de Ajax.",
        ERR_VIEWSTATE:          "jsf.viewState: el valor del par�metro no es de tipo 'form'!",
        ERR_TRANSPORT:          "El tipo de transporte {0} no existe",
        ERR_EVT_PASS:           "un evento debe ser transmitido (sea null o no definido)",
        ERR_CONSTRUCT:          "Partes de la respuesta no pudieron ser recuperadas cuando construyendo los datos del evento: {0} ",
        ERR_MALFORMEDXML:       "La respuesta del servidor no ha podido ser interpretada. El servidor ha devuelto una respuesta que no es xml !",
        ERR_SOURCE_FUNC:        "el origen no puede ser una funci�n (probablemente 'source' y evento no han sido definidos o son 'null'",
        ERR_EV_OR_UNKNOWN:      "Un objeto de tipo evento o desconocido debe ser pasado como segundo par�metro",
        ERR_SOURCE_NOSTR:       "el origen no puede ser 'string'",
        ERR_SOURCE_DEF_NULL:    "el origen debe haber sido definido o ser 'null'",

        //_Lang.js
        ERR_MUST_STRING:        "{0}: {1} namespace debe ser de tipo String",
        ERR_REF_OR_ID:          "{0}: {1} una referencia a un nodo o identificador tiene que ser pasada",
        ERR_PARAM_GENERIC:      "{0}: el par�metro {1} tiene que ser de tipo {2}",
        ERR_PARAM_STR:          "{0}: el par�metro {1} tiene que ser de tipo string",
        ERR_PARAM_STR_RE:       "{0}: el par�metro {1} tiene que ser de tipo string o una expresi�n regular",
        ERR_PARAM_MIXMAPS:      "{0}: han de ser pasados tanto un origen como un destino",
        ERR_MUST_BE_PROVIDED:   "{0}: {1} y {2} deben ser pasados",
        ERR_MUST_BE_PROVIDED1:  "{0}: {1} debe estar definido",

        ERR_REPLACE_EL:         "replaceElements invocado mientras que evalNodes no es un an array",
        ERR_EMPTY_RESPONSE:     "{0}: �La respuesta no puede ser de tipo 'null' o vac�a!",
        ERR_ITEM_ID_NOTFOUND:   "{0}: el elemento con identificador {1} no ha sido encontrado",
        ERR_PPR_IDREQ:          "{0}: Error en PPR Insert, 'id' debe estar presente",
        ERR_PPR_INSERTBEFID:    "{0}: Error in PPR Insert, antes de 'id' o despu�s de 'id' deben estar presentes",
        ERR_PPR_INSERTBEFID_1:  "{0}: Error in PPR Insert, antes de nodo con id {1} no existe en el documento",
        ERR_PPR_INSERTBEFID_2:  "{0}: Error in PPR Insert, despu�s de nodo con id {1} no existe en el documento",

        ERR_PPR_DELID:          "{0}: Error durante borrado, id no presente en xml",
        ERR_PPR_UNKNOWNCID:     "{0}:  Desconocido Html-Component-ID: {1}",
        ERR_NO_VIEWROOTATTR:    "{0}: El cambio de atributos de ViewRoot attributes no es posible",
        ERR_NO_HEADATTR:        "{0}: El cambio de los atributos de Head attributes no es posible",
        ERR_RED_URL:            "{0}: Redirecci�n sin url",

        ERR_REQ_FAILED_UNKNOWN: "La petici�n ha fallado con estado desconocido",
        ERR_REQU_FAILED:        "La petici�n ha fallado con estado {0} y raz�n {1}",
        UNKNOWN:                "DESCONOCIDO"

    });



/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
if (_MF_CLS) {
    /**
     * System messages kyrillic/russian version
     *
     * @class
     * @name Messages_nl
     * @extends myfaces._impl.i18n.Messages
     * @memberOf myfaces._impl.i18n
     */
    _MF_CLS && _MF_CLS(_PFX_I18N + "Messages_ru", myfaces._impl.i18n.Messages,
        /** myfaces._impl.i18n.Messages_ru.prototype */
        {

            MSG_TEST:               "ТестовоеСообщение",

            /*Messages*/
            MSG_DEV_MODE:           "Это сообщение выдано, потому что 'project stage' было присоено значение 'development', и никаких" +
                "других error listeners зарегистрировано не было.",
            MSG_AFFECTED_CLASS:     "Задействованный класс:",
            MSG_AFFECTED_METHOD:    "Задействованный метод:",

            MSG_ERROR_NAME:         "Имя ошибки:",
            MSG_ERROR_MESSAGE:      "Имя ошибки:",

            MSG_ERROR_DESC:         "Описание ошибки:",
            MSG_ERROR_NO:           "Номер ошибки:",
            MSG_ERROR_LINENO:       "Номер строки ошибки:",

            /*Errors and messages*/
            ERR_FORM:               "Sourceform не найдена, потому что элемент не находится внутри <form>, либо были найдены элементы <form> с рдинаковым именем или идентификатором. Обработка ajax остановлена",
            ERR_VIEWSTATE:          "jsf.viewState: Параметру присвоено значение, не являющееся элементом <form>!",
            ERR_TRANSPORT:          "Несуществующий тип транспорта {0}",
            ERR_EVT_PASS:           "Параметр event необходим, и не может быть null или undefined",
            ERR_CONSTRUCT:          "Часть ответа не удалось прочитать при создании данных события: {0} ",
            ERR_MALFORMEDXML:       "Ответ сервера не может быть обработан, он не в формате xml !",
            ERR_SOURCE_FUNC:        "source не может быть функцией (возможно, для source и event не были даны значения",
            ERR_EV_OR_UNKNOWN:      "Объект event или unknown должен быть всторым параметром",
            ERR_SOURCE_NOSTR:       "source не может быть типа string",
            ERR_SOURCE_DEF_NULL:    "source должно быть присвоено значение или null",

            //_Lang.js
            ERR_MUST_STRING:        "{0}: {1} namespace должно быть типа String",
            ERR_REF_OR_ID:          "{0}: {1} a Ссылочный узел (reference node) или идентификатор необходимы",
            ERR_PARAM_GENERIC:      "{0}: параметр {1} должен быть типа {2}",
            ERR_PARAM_STR:          "{0}: {1} параметр должен быть типа string",
            ERR_PARAM_STR_RE:       "{0}: {1} параметр должен быть типа string string или regular expression",
            ERR_PARAM_MIXMAPS:      "{0}: source b destination map необходимы",
            ERR_MUST_BE_PROVIDED:   "{0}: {1} и {2} необходимы",
            ERR_MUST_BE_PROVIDED1:  "{0}: {1} должно быть присвоено значение",

            ERR_REPLACE_EL:         "replaceElements вызвана, с evalNodes, не являющимся массивом",
            ERR_EMPTY_RESPONSE:     "{0}: Ответ не может бвть null или пустым!",
            ERR_ITEM_ID_NOTFOUND:   "{0}: Элемент с идентификатором {1} не найден",
            ERR_PPR_IDREQ:          "{0}: Ошибка в PPR Insert, id необходим",
            ERR_PPR_INSERTBEFID:    "{0}: Ошибка в PPR Insert, before id или after id необходимы",
            ERR_PPR_INSERTBEFID_1:  "{0}: Ошибка в PPR Insert, before node c id {1} не найден в документе",
            ERR_PPR_INSERTBEFID_2:  "{0}: Ошибка в PPR Insert, after node с id {1} не найден в документе",

            ERR_PPR_DELID:          "{0}: Ошибка в удалении, id не найден в xml документе",
            ERR_PPR_UNKNOWNCID:     "{0}: Неопознанный Html-Component-ID: {1}",
            ERR_NO_VIEWROOTATTR:    "{0}: Изменение атрибутов ViewRoot не предусмотрено",
            ERR_NO_HEADATTR:        "{0}: Изменение атрибутов Head не предусмотрено",
            ERR_RED_URL:            "{0}: Перенаправление (Redirect) без url"

        });
}
/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
if (_MF_CLS) {
    /**
     * System messages Simplified Chinese version
     *
     * @class
     * @name Messages_zh_CN
     * @extends myfaces._impl.i18n.Messages
     * @memberOf myfaces._impl.i18n
     */
    _MF_CLS && _MF_CLS(_PFX_I18N+"Messages_zh_CN", myfaces._impl.i18n.Messages,
        /** @lends myfaces._impl.i18n.Messages_zh_CN.prototype */
        {

            MSG_TEST:               "测试信息",

            /*Messages*/
            /** @constant */
            MSG_DEV_MODE:           "请注意，此信息只在项目发展阶段，及没有注册错误监听器而发放。",
            /** @constant */
            MSG_AFFECTED_CLASS:     "受影响类别：",
            /** @constant */
            MSG_AFFECTED_METHOD:    "受影响方法：",
            /** @constant */
            MSG_ERROR_NAME:         "错误名称：",
            /** @constant */
            MSG_ERROR_MESSAGE:      "错误信息：",
            /** @constant */
            MSG_SERVER_ERROR_NAME:  "伺服器错误名称：",
            /** @constant */
            MSG_ERROR_DESC:         "错误说明：",
            /** @constant */
            MSG_ERROR_NO:           "错误号码：",
            /** @constant */
            MSG_ERROR_LINENO:       "错误行号：",

            /*Errors and messages*/
            /** @constant */
            ERR_FORM:               "不能判定源表单，要么没有连接元件到表单，要么有多个相同标识符或名称的表单，AJAX处理停止运作",
            /** @constant */
            ERR_VIEWSTATE:          "jsf.viewState：参数值不是表单类型！",
            /** @constant */
            ERR_TRANSPORT:          "不存在{0}传输类型",
            /** @constant */
            ERR_EVT_PASS:           "必须放弃事件（可能事件物件为空或未定义）",
            /** @constant */
            ERR_CONSTRUCT:          "构建事件数据时部分回应不能取得，原因是：{0}",
            /** @constant */
            ERR_MALFORMEDXML:       "无法解析伺服器的回应，伺服器返回的回应不是XML！",
            /** @constant */
            ERR_SOURCE_FUNC:        "来源不能是一个函数（可能来源和事件没有定义或设定为空）",
            /** @constant */
            ERR_EV_OR_UNKNOWN:      "事件物件或不明必须作为第二个参数传递",
            /** @constant */
            ERR_SOURCE_NOSTR:       "来源不能是字串",
            /** @constant */
            ERR_SOURCE_DEF_NULL:    "来源必须定义或为空",

            //_Lang.js
            /** @constant */
            ERR_MUST_STRING:        "{0}：{1} 名称空间必须是字串类型",
            /** @constant */
            ERR_REF_OR_ID:          "{0}：{1} 必须提供参考节点或标识符",
            /** @constant */
            ERR_PARAM_GENERIC:      "{0}：{1} 参数必须是 {2} 类型",
            /** @constant */
            ERR_PARAM_STR:          "{0}：{1} 参数必须是字串类型",
            /** @constant */
            ERR_PARAM_STR_RE:       "{0}：{1} 参数必须是字串类型或正规表达式",
            /** @constant */
            ERR_PARAM_MIXMAPS:      "{0}：必须提供来源及目标映射",
            /** @constant */
            ERR_MUST_BE_PROVIDED:   "{0}：必须提供 {1} 及 {2}",
            /** @constant */
            ERR_MUST_BE_PROVIDED1:  "{0}：必须设定 {1}",

            /** @constant */
            ERR_REPLACE_EL:         "调用replaceElements函数时evalNodes变量不是阵列类型",

            /** @constant */
            ERR_EMPTY_RESPONSE:     "{0}：回应不能为空的！",
            /** @constant */
            ERR_ITEM_ID_NOTFOUND:   "{0}：找不到有 {1} 标识符的项目",
            /** @constant */
            ERR_PPR_IDREQ:          "{0}：局部页面渲染嵌入错误，标识符必须存在",
            /** @constant */
            ERR_PPR_INSERTBEFID:    "{0}：局部页面渲染嵌入错误，前或后标识符必须存在",
            /** @constant */
            ERR_PPR_INSERTBEFID_1:  "{0}：局部页面渲染嵌入错误，前节点的标识符 {1} 不在文件内",
            /** @constant */
            ERR_PPR_INSERTBEFID_2:  "{0}：局部页面渲染嵌入错误，后节点的标识符 {1} 不在文件内",

            /** @constant */
            ERR_PPR_DELID:          "{0}：删除错误，标识符不在XML标记中",
            /** @constant */
            ERR_PPR_UNKNOWNCID:     "{0}：不明的HTML组件标识符：{1}",

            /** @constant */
            ERR_NO_VIEWROOTATTR:    "{0}：不支援改变ViewRoot属性",
            /** @constant */
            ERR_NO_HEADATTR:        "{0}：不支援改变Head的属性",
            /** @constant */
            ERR_RED_URL:            "{0}：没有重导向网址",

            /** @constant */
            ERR_REQ_FAILED_UNKNOWN: "请求失败，状态不明",

            /** @constant */
            ERR_REQU_FAILED: "请求失败，状态是 {0} 和原因是 {1}",

            /** @constant */
            UNKNOWN: "不明"
        });
}

/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * System messages Traditional Chinese (Hong Kong) version
 *
 * @class
 * @name Messages_zh_HK
 * @extends myfaces._impl.i18n.Messages
 * @memberOf myfaces._impl.i18n
 */
_MF_CLS && _MF_CLS(_PFX_I18N + "Messages_zh_HK", myfaces._impl.i18n.Messages,
    /** @lends myfaces._impl.i18n.Messages_zh_HK.prototype */
    {

        MSG_TEST:               "測試信息",

        /*Messages*/
        /** @constant */
        MSG_DEV_MODE:           "請注意，此信息只在項目發展階段，及沒有註冊錯誤監聽器而發放。",
        /** @constant */
        MSG_AFFECTED_CLASS:     "受影響類別：",
        /** @constant */
        MSG_AFFECTED_METHOD:    "受影響方法：",
        /** @constant */
        MSG_ERROR_NAME:         "錯誤名稱：",
        /** @constant */
        MSG_ERROR_MESSAGE:      "錯誤信息：",
        /** @constant */
        MSG_SERVER_ERROR_NAME:  "伺服器錯誤名稱：",
        /** @constant */
        MSG_ERROR_DESC:         "錯誤說明：",
        /** @constant */
        MSG_ERROR_NO:           "錯誤號碼：",
        /** @constant */
        MSG_ERROR_LINENO:       "錯誤行號：",

        /*Errors and messages*/
        /** @constant */
        ERR_FORM:               "不能判定源表單，要麼沒有連接元件到表單，要麼有多個相同標識符或名稱的表單，AJAX處理停止運作",
        /** @constant */
        ERR_VIEWSTATE:          "jsf.viewState：參數值不是表單類型！",
        /** @constant */
        ERR_TRANSPORT:          "不存在{0}傳輸類型",
        /** @constant */
        ERR_EVT_PASS:           "必須放棄事件（可能事件物件為空或未定義）",
        /** @constant */
        ERR_CONSTRUCT:          "構建事件數據時部分回應不能取得，原因是：{0}",
        /** @constant */
        ERR_MALFORMEDXML:       "無法解析伺服器的回應，伺服器返回的回應不是XML！",
        /** @constant */
        ERR_SOURCE_FUNC:        "來源不能是一個函數（可能來源和事件沒有定義或設定為空）",
        /** @constant */
        ERR_EV_OR_UNKNOWN:      "事件物件或不明必須作為第二個參數傳遞",
        /** @constant */
        ERR_SOURCE_NOSTR:       "來源不能是字串",
        /** @constant */
        ERR_SOURCE_DEF_NULL:    "來源必須定義或為空",

        //_Lang.js
        /** @constant */
        ERR_MUST_STRING:        "{0}：{1} 名稱空間必須是字串類型",
        /** @constant */
        ERR_REF_OR_ID:          "{0}：{1} 必須提供參考節點或標識符",
        /** @constant */
        ERR_PARAM_GENERIC:      "{0}：{1} 參數必須是 {2} 類型",
        /** @constant */
        ERR_PARAM_STR:          "{0}：{1} 參數必須是字串類型",
        /** @constant */
        ERR_PARAM_STR_RE:       "{0}：{1} 參數必須是字串類型或正規表達式",
        /** @constant */
        ERR_PARAM_MIXMAPS:      "{0}：必須提供來源及目標映射",
        /** @constant */
        ERR_MUST_BE_PROVIDED:   "{0}：必須提供 {1} 及 {2}",
        /** @constant */
        ERR_MUST_BE_PROVIDED1:  "{0}：必須設定 {1}",

        /** @constant */
        ERR_REPLACE_EL:         "調用replaceElements函數時evalNodes變量不是陣列類型",

        /** @constant */
        ERR_EMPTY_RESPONSE:     "{0}：回應不能為空的！",
        /** @constant */
        ERR_ITEM_ID_NOTFOUND:   "{0}：找不到有 {1} 標識符的項目",
        /** @constant */
        ERR_PPR_IDREQ:          "{0}：局部頁面渲染嵌入錯誤，標識符必須存在",
        /** @constant */
        ERR_PPR_INSERTBEFID:    "{0}：局部頁面渲染嵌入錯誤，前或後標識符必須存在",
        /** @constant */
        ERR_PPR_INSERTBEFID_1:  "{0}：局部頁面渲染嵌入錯誤，前節點的標識符 {1} 不在文件內",
        /** @constant */
        ERR_PPR_INSERTBEFID_2:  "{0}：局部頁面渲染嵌入錯誤，後節點的標識符 {1} 不在文件內",

        /** @constant */
        ERR_PPR_DELID:          "{0}：刪除錯誤，標識符不在XML標記中",
        /** @constant */
        ERR_PPR_UNKNOWNCID:     "{0}：不明的HTML組件標識符：{1}",

        /** @constant */
        ERR_NO_VIEWROOTATTR:    "{0}：不支援改變ViewRoot屬性",
        /** @constant */
        ERR_NO_HEADATTR:        "{0}：不支援改變Head的屬性",
        /** @constant */
        ERR_RED_URL:            "{0}：沒有重導向網址",

        /** @constant */
        ERR_REQ_FAILED_UNKNOWN: "請求失敗，狀態不明",

        /** @constant */
        ERR_REQU_FAILED: "請求失敗，狀態是 {0} 和原因是 {1}",

        /** @constant */
        UNKNOWN: "不明"
    });


/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
if (_MF_CLS) {
    /**
     * System messages Traditional Chinese (Taiwan) version
     *
     * @class
     * @name Messages_zh_TW
     * @extends myfaces._impl.i18n.Messages
     * @memberOf myfaces._impl.i18n
     */
    _MF_CLS &&  _MF_CLS(_PFX_I18N + "Messages_zh_TW", myfaces._impl.i18n.Messages,
        /** @lends myfaces._impl.i18n.Messages_zh_TW.prototype */
        {

            MSG_TEST:               "測試信息",

            /*Messages*/
            /** @constant */
            MSG_DEV_MODE:           "請注意，此信息只在項目發展階段，及沒有註冊錯誤監聽器而發放。",
            /** @constant */
            MSG_AFFECTED_CLASS:     "受影響類別：",
            /** @constant */
            MSG_AFFECTED_METHOD:    "受影響方法：",
            /** @constant */
            MSG_ERROR_NAME:         "錯誤名稱：",
            /** @constant */
            MSG_ERROR_MESSAGE:      "錯誤信息：",
            /** @constant */
            MSG_SERVER_ERROR_NAME:  "伺服器錯誤名稱：",
            /** @constant */
            MSG_ERROR_DESC:         "錯誤說明：",
            /** @constant */
            MSG_ERROR_NO:           "錯誤號碼：",
            /** @constant */
            MSG_ERROR_LINENO:       "錯誤行號：",

            /*Errors and messages*/
            /** @constant */
            ERR_FORM:               "不能判定源表單，要麼沒有連接元件到表單，要麼有多個相同標識符或名稱的表單，AJAX處理停止運作",
            /** @constant */
            ERR_VIEWSTATE:          "jsf.viewState：參數值不是表單類型！",
            /** @constant */
            ERR_TRANSPORT:          "不存在{0}傳輸類型",
            /** @constant */
            ERR_EVT_PASS:           "必須放棄事件（可能事件物件為空或未定義）",
            /** @constant */
            ERR_CONSTRUCT:          "構建事件數據時部分回應不能取得，原因是：{0}",
            /** @constant */
            ERR_MALFORMEDXML:       "無法解析伺服器的回應，伺服器返回的回應不是XML！",
            /** @constant */
            ERR_SOURCE_FUNC:        "來源不能是一個函數（可能來源和事件沒有定義或設定為空）",
            /** @constant */
            ERR_EV_OR_UNKNOWN:      "事件物件或不明必須作為第二個參數傳遞",
            /** @constant */
            ERR_SOURCE_NOSTR:       "來源不能是字串",
            /** @constant */
            ERR_SOURCE_DEF_NULL:    "來源必須定義或為空",

            //_Lang.js
            /** @constant */
            ERR_MUST_STRING:        "{0}：{1} 名稱空間必須是字串類型",
            /** @constant */
            ERR_REF_OR_ID:          "{0}：{1} 必須提供參考節點或標識符",
            /** @constant */
            ERR_PARAM_GENERIC:      "{0}：{1} 參數必須是 {2} 類型",
            /** @constant */
            ERR_PARAM_STR:          "{0}：{1} 參數必須是字串類型",
            /** @constant */
            ERR_PARAM_STR_RE:       "{0}：{1} 參數必須是字串類型或正規表達式",
            /** @constant */
            ERR_PARAM_MIXMAPS:      "{0}：必須提供來源及目標映射",
            /** @constant */
            ERR_MUST_BE_PROVIDED:   "{0}：必須提供 {1} 及 {2}",
            /** @constant */
            ERR_MUST_BE_PROVIDED1:  "{0}：必須設定 {1}",

            /** @constant */
            ERR_REPLACE_EL:         "調用replaceElements函數時evalNodes變量不是陣列類型",

            /** @constant */
            ERR_EMPTY_RESPONSE:     "{0}：回應不能為空的！",
            /** @constant */
            ERR_ITEM_ID_NOTFOUND:   "{0}：找不到有 {1} 標識符的項目",
            /** @constant */
            ERR_PPR_IDREQ:          "{0}：局部頁面渲染嵌入錯誤，標識符必須存在",
            /** @constant */
            ERR_PPR_INSERTBEFID:    "{0}：局部頁面渲染嵌入錯誤，前或後標識符必須存在",
            /** @constant */
            ERR_PPR_INSERTBEFID_1:  "{0}：局部頁面渲染嵌入錯誤，前節點的標識符 {1} 不在文件內",
            /** @constant */
            ERR_PPR_INSERTBEFID_2:  "{0}：局部頁面渲染嵌入錯誤，後節點的標識符 {1} 不在文件內",

            /** @constant */
            ERR_PPR_DELID:          "{0}：刪除錯誤，標識符不在XML標記中",
            /** @constant */
            ERR_PPR_UNKNOWNCID:     "{0}：不明的HTML組件標識符：{1}",

            /** @constant */
            ERR_NO_VIEWROOTATTR:    "{0}：不支援改變ViewRoot屬性",
            /** @constant */
            ERR_NO_HEADATTR:        "{0}：不支援改變Head的屬性",
            /** @constant */
            ERR_RED_URL:            "{0}：沒有重導向網址",

            /** @constant */
            ERR_REQ_FAILED_UNKNOWN: "請求失敗，狀態不明",

            /** @constant */
            ERR_REQU_FAILED: "請求失敗，狀態是 {0} 和原因是 {1}",

            /** @constant */
            UNKNOWN: "不明"
        });
}

/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 theoretically we could save some code
 by
 defining the parent object as
 var parent = new Object();
 parent.prototype = new myfaces._impl.core._Runtime();
 extendClass(function () {
 }, parent , {
 But for now we are not doing it the little bit of saved
 space is not worth the loss of readability
 */
/**
 * @memberOf myfaces._impl
 * @namespace
 * @name _util
 */
/**
 * @class
 * @name _Lang
 * @memberOf myfaces._impl._util
 * @extends myfaces._impl.core._Runtime
 * @namespace
 * @description Object singleton for Language related methods, this object singleton
 * decorates the namespace myfaces._impl.core._Runtime and adds a bunch of new methods to
 * what _Runtime provided
 * */
_MF_SINGLTN(_PFX_UTIL + "_Lang", Object, /** @lends myfaces._impl._util._Lang.prototype */ {
    _processedExceptions:{},
    _installedLocale:null,
    _RT:myfaces._impl.core._Runtime,
    /**
     * returns a given localized message upon a given key
     * basic java log like templating functionality is included
     *
     * @param {String} key the key for the message
     * @param {String} defaultMessage optional default message if none was found
     *
     * Additionally you can pass additional arguments, which are used
     * in the same way java log templates use the params
     *
     * @param key
     */
    getMessage:function (key, defaultMessage /*,vararg templateParams*/) {
        if (!this._installedLocale) {
            //we first try to install language and variant, if that one fails
            //we try to install the language only, and if that one fails
            //we install the base messages
            this.initLocale();
        }
        var msg = this._installedLocale[key] || defaultMessage || key + " - undefined message";
        //we now make a simple templating replace of {0}, {1} etc... with their corresponding
        //arguments
        for (var cnt = 2; cnt < arguments.length; cnt++) {
            msg = msg.replace(new RegExp(["\\{", cnt - 2, "\\}"].join(""), "g"), new String(arguments[cnt]));
        }
        return msg;
    },
    /**
     * (re)inits the currently installed
     * messages so that after loading the main scripts
     * a new locale can be installed optionally
     * to our i18n subsystem
     *
     * @param newLocale locale override
     */
    initLocale:function (newLocale) {
        if (newLocale) {
            this._installedLocale = new newLocale();
            return;
        }
        var language_Variant = this._RT.getLanguage(this._RT.getGlobalConfig("locale")),
            langStr = language_Variant ? language_Variant.language : "",
            variantStr = language_Variant ? [language_Variant.language, "_", language_Variant.variant || ""].join("") : "",
            i18nRoot = myfaces._impl.i18n, i18nHolder = i18nRoot["Messages_" + variantStr] || i18nRoot["Messages_" + langStr] || i18nRoot["Messages"];
        this._installedLocale = new i18nHolder();
    },
    assertType:function (probe, theType) {
        return this._RT.assertType(probe, theType);
    },
    exists:function (nms, theType) {
        return this._RT.exists(nms, theType);
    },
    fetchNamespace:function (namespace) {
        this._assertStr(namespace, "fetchNamespace", "namespace");
        return this._RT.fetchNamespace(namespace);
    },
    reserveNamespace:function (namespace) {
        this._assertStr(namespace, "reserveNamespace", "namespace");
        return this._RT.reserveNamespace(namespace);
    },
    globalEval:function (code) {
        this._assertStr(code, "globalEval", "code");
        return  this._RT.globalEval(code);
    },
    /**
     * determines the correct event depending
     * on the browsers state
     *
     * @param evt incoming event object (note not all browsers
     * have this)
     *
     * @return an event object no matter what is incoming
     */
    getEvent:function (evt) {
        evt = (!evt) ? window.event || {} : evt;
        return evt;
    },
    /**
     * cross port from the dojo lib
     * browser save event resolution
     * @param evt the event object
     * (with a fallback for ie events if none is present)
     */
    getEventTarget:function (evt) {
        //ie6 and 7 fallback
        evt = this.getEvent(evt);
        /**
         * evt source is defined in the jsf events
         * seems like some component authors use our code
         * so we add it here see also
         * https://issues.apache.org/jira/browse/MYFACES-2458
         * not entirely a bug but makes sense to add this
         * behavior. I dont use it that way but nevertheless it
         * does not break anything so why not
         * */
        var t = evt.srcElement || evt.target || evt.source || null;
        while ((t) && (t.nodeType != 1)) {
            t = t.parentNode;
        }
        return t;
    },

    /**
     * equalsIgnoreCase, case insensitive comparison of two strings
     *
     * @param source
     * @param destination
     */
    equalsIgnoreCase:function (source, destination) {
        //either both are not set or null
        if (!source && !destination) {
            return true;
        }
        //source or dest is set while the other is not
        if (!source || !destination) return false;
        //in any other case we do a strong string comparison
        return source.toLowerCase() === destination.toLowerCase();
    },

    /**
     * Save document.getElementById (this code was ported over from dojo)
     * the idea is that either a string or domNode can be passed
     * @param {Object} reference the reference which has to be byIded
     */
    byId:function (/*object*/ reference) {
        if (!reference) {
            throw this.makeException(new Error(), null, null, this._nameSpace, "byId", this.getMessage("ERR_REF_OR_ID", null, "_Lang.byId", "reference"));
        }
        return (this.isString(reference)) ? document.getElementById(reference) : reference;
    },

    /**
     * String to array function performs a string to array transformation
     * @param {String} it the string which has to be changed into an array
     * @param {RegExp} splitter our splitter reglar expression
     * @return an array of the splitted string
     */
    strToArray:function (/*string*/ it, /*regexp*/ splitter) {
        //	summary:
        //		Return true if it is a String
        this._assertStr(it, "strToArray", "it");
        if (!splitter) {
            throw this.makeException(new Error(), null, null, this._nameSpace, "strToArray", this.getMessage("ERR_PARAM_STR_RE", null, "myfaces._impl._util._Lang.strToArray", "splitter"));
        }
        var retArr = it.split(splitter);
        var len = retArr.length;
        for (var cnt = 0; cnt < len; cnt++) {
            retArr[cnt] = this.trim(retArr[cnt]);
        }
        return retArr;
    },
    _assertStr:function (it, functionName, paramName) {
        if (!this.isString(it)) {
            throw this.makeException(new Error(), null, null, this._nameSpace, arguments.caller.toString(), this.getMessage("ERR_PARAM_STR", null, "myfaces._impl._util._Lang." + functionName, paramName));
        }
    },
    /**
     * hyperfast trim
     * http://blog.stevenlevithan.com/archives/faster-trim-javascript
     * crossported from dojo
     */
    trim:function (/*string*/ str) {
        this._assertStr(str, "trim", "str");
        str = str.replace(/^\s\s*/, '');
        var ws = /\s/, i = str.length;

        while (ws.test(str.charAt(--i))) {
            //do nothing
        }
        return str.slice(0, i + 1);
    },
    /**
     * Backported from dojo
     * a failsafe string determination method
     * (since in javascript String != "" typeof alone fails!)
     * @param it {|Object|} the object to be checked for being a string
     * @return true in case of being a string false otherwise
     */
    isString:function (/*anything*/ it) {
        //	summary:
        //		Return true if it is a String
        return !!arguments.length && it != null && (typeof it == "string" || it instanceof String); // Boolean
    },
    /**
     * hitch backported from dojo
     * hitch allows to assign a function to a dedicated scope
     * this is helpful in situations when function reassignments
     * can happen
     * (notably happens often in lazy xhr code)
     *
     * @param {Function} scope of the function to be executed in
     * @param {Function} method to be executed, the method must be of type function
     *
     * @return whatever the executed method returns
     */
    hitch:function (scope, method) {
        return !scope ? method : function () {
            return method.apply(scope, arguments || []);
        }; // Function
    },
    /**
     * Helper function to merge two maps
     * into one
     * @param {Object} dest the destination map
     * @param {Object} src the source map
     * @param {boolean} overwrite if set to true the destination is overwritten if the keys exist in both maps
     **/
    mixMaps:function (dest, src, overwrite, blockFilter, whitelistFilter) {
        if (!dest || !src) {
            throw this.makeException(new Error(), null, null, this._nameSpace, "mixMaps", this.getMessage("ERR_PARAM_MIXMAPS", null, "_Lang.mixMaps"));
        }
        var _undef = "undefined";
        for (var key in src) {
            if (!src.hasOwnProperty(key)) continue;
            if (blockFilter && blockFilter[key]) {
                continue;
            }
            if (whitelistFilter && !whitelistFilter[key]) {
                continue;
            }
            if (!overwrite) {
                /**
                 *we use exists instead of booleans because we cannot rely
                 *on all values being non boolean, we would need an elvis
                 *operator in javascript to shorten this :-(
                 */
                dest[key] = (_undef != typeof dest[key]) ? dest[key] : src[key];
            } else {
                dest[key] = (_undef != typeof src[key]) ? src[key] : dest[key];
            }
        }
        return dest;
    },
    /**
     * checks if an array contains an element
     * @param {Array} arr   array
     * @param {String} str string to check for
     */
    contains:function (arr, str) {
        if (!arr || !str) {
            throw this.makeException(new Error(), null, null, this._nameSpace, "contains", this.getMessage("ERR_MUST_BE_PROVIDED", null, "_Lang.contains", "arr {array}", "str {string}"));
        }
        return this.arrIndexOf(arr, str) != -1;
    },
    arrToMap:function (arr, offset) {
        var ret = new Array(arr.length);
        var len = arr.length;
        offset = (offset) ? offset : 0;
        for (var cnt = 0; cnt < len; cnt++) {
            ret[arr[cnt]] = cnt + offset;
        }
        return ret;
    },
    objToArray:function (obj, offset, pack) {
        if (!obj) {
            return null;
        }
        //since offset is numeric we cannot use the shortcut due to 0 being false
        //special condition array delivered no offset no pack
        if (obj instanceof Array && !offset && !pack)  return obj;
        var finalOffset = ('undefined' != typeof offset || null != offset) ? offset : 0;
        var finalPack = pack || [];
        try {
            return finalPack.concat(Array.prototype.slice.call(obj, finalOffset));
        } catch (e) {
            //ie8 (again as only browser) delivers for css 3 selectors a non convertible object
            //we have to do it the hard way
            //ie8 seems generally a little bit strange in its behavior some
            //objects break the function is everything methodology of javascript
            //and do not implement apply call, or are pseudo arrays which cannot
            //be sliced
            for (var cnt = finalOffset; cnt < obj.length; cnt++) {
                finalPack.push(obj[cnt]);
            }
            return finalPack;
        }
    },
    /**
     * foreach implementation utilizing the
     * ECMAScript wherever possible
     * with added functionality
     *
     * @param arr the array to filter
     * @param func the closure to apply the function to, with the syntax defined by the ecmascript functionality
     * function (element<,key, array>)
     * <p />
     * optional params
     * <p />
     * <ul>
     *      <li>param startPos (optional) the starting position </li>
     *      <li>param scope (optional) the scope to apply the closure to  </li>
     * </ul>
     */
    arrForEach:function (arr, func /*startPos, scope*/) {
        if (!arr || !arr.length) return;
        var startPos = Number(arguments[2]) || 0;
        var thisObj = arguments[3];
        //check for an existing foreach mapping on array prototypes
        //IE9 still does not pass array objects as result for dom ops
        arr = this.objToArray(arr);
        (startPos) ? arr.slice(startPos).forEach(func, thisObj) : arr.forEach(func, thisObj);
    },
    /**
     * foreach implementation utilizing the
     * ECMAScript wherever possible
     * with added functionality
     *
     * @param arr the array to filter
     * @param func the closure to apply the function to, with the syntax defined by the ecmascript functionality
     * function (element<,key, array>)
     * <p />
     * additional params
     * <ul>
     *  <li> startPos (optional) the starting position</li>
     *  <li> scope (optional) the scope to apply the closure to</li>
     * </ul>
     */
    arrFilter:function (arr, func /*startPos, scope*/) {
        if (!arr || !arr.length) return [];
        arr = this.objToArray(arr);
        return ((startPos) ? arr.slice(startPos).filter(func, thisObj) : arr.filter(func, thisObj));
    },
    /**
     * adds a EcmaScript optimized indexOf to our mix,
     * checks for the presence of an indexOf functionality
     * and applies it, otherwise uses a fallback to the hold
     * loop method to determine the index
     *
     * @param arr the array
     * @param element the index to search for
     */
    arrIndexOf:function (arr, element /*fromIndex*/) {
        if (!arr || !arr.length) return -1;
        var pos = Number(arguments[2]) || 0;
        arr = this.objToArray(arr);
        return arr.indexOf(element, pos);
    },
    /**
     * helper to automatically apply a delivered arguments map or array
     * to its destination which has a field "_"<key> and a full field
     *
     * @param dest the destination object
     * @param args the arguments array or map
     * @param argNames the argument names to be transferred
     */
    applyArgs:function (dest, args, argNames) {
        var UDEF = 'undefined';
        if (argNames) {
            for (var cnt = 0; cnt < args.length; cnt++) {
                //dest can be null or 0 hence no shortcut
                if (UDEF != typeof dest["_" + argNames[cnt]]) {
                    dest["_" + argNames[cnt]] = args[cnt];
                }
                if (UDEF != typeof dest[ argNames[cnt]]) {
                    dest[argNames[cnt]] = args[cnt];
                }
            }
        } else {
            for (var key in args) {
                if (!args.hasOwnProperty(key)) continue;
                if (UDEF != typeof dest["_" + key]) {
                    dest["_" + key] = args[key];
                }
                if (UDEF != typeof dest[key]) {
                    dest[key] = args[key];
                }
            }
        }
    },

    /**
     * transforms a key value pair into a string
     * @param key the key
     * @param val the value
     * @param delimiter the delimiter
     */
    keyValToStr:function (key, val, delimiter) {
        var ret = [], pushRet = this.hitch(ret, ret.push);
        pushRet(key);
        pushRet(val);
        delimiter = delimiter || "\n";
        pushRet(delimiter);
        return ret.join("");
    },
    parseXML:function (txt) {
        try {
            var parser = new DOMParser();
            return parser.parseFromString(txt, "text/xml");
        } catch (e) {
            //undefined internal parser error
            return null;
        }
    },
    serializeXML:function (xmlNode, escape) {
        if (!escape) {
            if (xmlNode.data) return xmlNode.data; //CDATA block has raw data
            if (xmlNode.textContent) return xmlNode.textContent; //textNode has textContent
        }
        return (new XMLSerializer()).serializeToString(xmlNode);
    },
    serializeChilds:function (xmlNode) {
        var buffer = [];
        if (!xmlNode.childNodes) return "";
        for (var cnt = 0; cnt < xmlNode.childNodes.length; cnt++) {
            buffer.push(this.serializeXML(xmlNode.childNodes[cnt]));
        }
        return buffer.join("");
    },
    isXMLParseError:function (xmlContent) {
        //no xml content
        if (xmlContent == null) return true;
        var findParseError = function (node) {
            if (!node || !node.childNodes) return false;
            for (var cnt = 0; cnt < node.childNodes.length; cnt++) {
                var childNode = node.childNodes[cnt];
                if (childNode.tagName && childNode.tagName == "parsererror") return true;
            }
            return false;
        };
        return !xmlContent ||
            (this.exists(xmlContent, "parseError.errorCode") && xmlContent.parseError.errorCode != 0) ||
            findParseError(xmlContent);
    },
    /**
     * fetches the error message from the xml content
     * in a browser independent way
     *
     * @param xmlContent
     * @return a map with the following structure {errorMessage: the error Message, sourceText: the text with the error}
     */
    fetchXMLErrorMessage:function (text, xmlContent) {
        var _t = this;
        var findParseError = function (node) {
            if (!node || !node.childNodes) return false;
            for (var cnt = 0; cnt < node.childNodes.length; cnt++) {
                var childNode = node.childNodes[cnt];
                if (childNode.tagName && childNode.tagName == "parsererror") {
                    var errorMessage = _t.serializeXML(childNode.childNodes[0]);
                    //we now have to determine the row and column position
                    var lastLine = errorMessage.split("\n");
                    lastLine = lastLine[lastLine.length-1];
                    var positions = lastLine.match(/[^0-9]*([0-9]+)[^0-9]*([0-9]+)[^0-9]*/);

                    var ret = {
                        errorMessage: errorMessage,
                        sourceText: _t.serializeXML(childNode.childNodes[1].childNodes[0])
                    }
                    if(positions) {
                        ret.line = Math.max(0, parseInt(positions[1])-1);
                        ret.linePos = Math.max(0, parseInt(positions[2])-1);
                    }
                    return ret;
                }
            }
            return null;
        };
        var ret = null;
        if (!xmlContent) {
            //chrome does not deliver any further data
            ret =  (this.trim(text || "").length > 0)? {errorMessage:"Illegal response",sourceText:""} : {errorMessage:"Empty Response",sourceText:""};
        } else if (this.exists(xmlContent, "parseError.errorCode") && xmlContent.parseError.errorCode != 0) {
            ret =   {
                errorMessage:xmlContent.parseError.reason,
                line:Math.max(0, parseInt(xmlContent.parseError.line)-1),
                linePos:Math.max(0,parseInt(xmlContent.parseError.linepos) -1),
                sourceText:xmlContent.parseError.srcText
            };
        } else {
            ret = findParseError(xmlContent);
        }
        //we have a line number we now can format the source accordingly
        if(ret && 'undefined' != typeof ret.line) {
            var source = ret.sourceText ||"";
            source = source.split("\n");
            if(source.length-1 < ret.line) return ret;
            source = source[ret.line];
            var secondLine = [];
            var lineLen = (ret.linePos - 2);
            for(var cnt = 0; cnt < lineLen; cnt++) {
                secondLine.push(" ");
            }
            secondLine.push("^^");
            ret.sourceText = source;
            ret.visualError = secondLine;
        }
        return ret;
    },

    /**
     * creates a neutral form data wrapper over an existing form Data element
     * the wrapper delegates following methods, append
     * and adds makeFinal as finalizing method which returns the final
     * send representation of the element
     *
     * @param formData an array
     */
    createFormDataDecorator:function (formData) {
        //we simulate the dom level 2 form element here
        var _newCls = null;
        var bufInstance = null;
        if (!this.FormDataDecoratorArray) {
            this.FormDataDecoratorArray = function (theFormData) {
                this._valBuf = theFormData;
                this._idx = {};
            };
            _newCls = this.FormDataDecoratorArray;
            _newCls.prototype.append = function (key, val) {
                this._valBuf.push([encodeURIComponent(key), encodeURIComponent(val)].join("="));
                this._idx[key] = true;
            };
            _newCls.prototype.hasKey = function (key) {
                return !!this._idx[key];
            };
            _newCls.prototype.makeFinal = function () {
                return this._valBuf.join("&");
            };
        }
        if (!this.FormDataDecoratorString) {
            this.FormDataDecoratorString = function (theFormData) {
                this._preprocessedData = theFormData;
                this._valBuf = [];
                this._idx = {};
            };
            _newCls = this.FormDataDecoratorString;
            _newCls.prototype.append = function (key, val) {
                this._valBuf.push([encodeURIComponent(key), encodeURIComponent(val)].join("="));
                this._idx[key] = true;
            };
            //for now we check only for keys which are added subsequently otherwise we do not perform any checks
            _newCls.prototype.hasKey = function (key) {
                return !!this._idx[key];
            };
            _newCls.prototype.makeFinal = function () {
                if (this._preprocessedData != "") {
                    return this._preprocessedData + "&" + this._valBuf.join("&")
                } else {
                    return this._valBuf.join("&");
                }
            };
        }
        if (!this.FormDataDecoratorOther) {
            this.FormDataDecoratorOther = function (theFormData) {
                this._valBuf = theFormData;
                this._idx = {};
            };
            _newCls = this.FormDataDecoratorOther;
            _newCls.prototype.append = function (key, val) {
                this._valBuf.append(key, val);
                this._idx[key] = true;
            };
            _newCls.prototype.hasKey = function (key) {
                return !!this._idx[key];
            };
            _newCls.prototype.makeFinal = function () {
                return this._valBuf;
            };
        }
        if (formData instanceof Array) {
            bufInstance = new this.FormDataDecoratorArray(formData);
        } else if (this.isString(formData)) {
            bufInstance = new this.FormDataDecoratorString(formData);
        } else {
            bufInstance = new this.FormDataDecoratorOther(formData);
        }
        return bufInstance;
    },
    /**
     * define a property mechanism which is browser neutral
     * we cannot use the existing setter and getter mechanisms
     * for now because old browsers do not support them
     * in the long run we probably can switch over
     * or make a code split between legacy and new
     *
     *
     * @param obj
     * @param name
     * @param value
     */
    attr:function (obj, name, value) {
        var findAccessor = function (theObj, theName) {
            return (theObj["_" + theName]) ? "_" + theName : ( (theObj[theName]) ? theName : null)
        };
        var applyAttr = function (theObj, theName, value, isFunc) {
            if (value) {
                if (isFunc) {
                    theObj[theName](value);
                } else {
                    theObj[theName] = value;
                }
                return null;
            }
            return (isFunc) ? theObj[theName]() : theObj[theName];
        };
        try {
            var finalAttr = findAccessor(obj, name);
            //simple attibute no setter and getter overrides
            if (finalAttr) {
                return applyAttr(obj, finalAttr, value);
            }
            //lets check for setter and getter overrides
            var found = false;
            var prefix = (value) ? "set" : "get";
            finalAttr = [prefix, name.substr(0, 1).toUpperCase(), name.substr(1)].join("");
            finalAttr = findAccessor(obj, finalAttr);
            if (finalAttr) {
                return applyAttr(obj, finalAttr, value, true);
            }

            throw this.makeException(new Error(), null, null, this._nameSpace, "contains", "property " + name + " not found");
        } finally {
            findAccessor = null;
            applyAttr = null;
        }
    },

    /**
     * creates an exeption with additional internal parameters
     * for extra information
     *
     * @param {String} title the exception title
     * @param {String} name  the exception name
     * @param {String} callerCls the caller class
     * @param {String} callFunc the caller function
     * @param {String} message the message for the exception
     */
    makeException:function (error, title, name, callerCls, callFunc, message) {
        error.name = name || "clientError";
        error.title = title || "";
        error.message = message || "";
        error._mfInternal = {};
        error._mfInternal.name = name || "clientError";
        error._mfInternal.title = title || "clientError";
        error._mfInternal.caller = callerCls || this._nameSpace;
        error._mfInternal.callFunc = callFunc || ("" + arguments.caller.toString());
        return error;
    }
});

/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 Base class which provides several helper functions over all objects
 */
_MF_CLS(_PFX_CORE+"Object", Object, {



    constructor_: function() {
        this._resettableContent = {};
        //to make those singleton references
        //overridable in the instance we have
        //to load them into the prototype instead
        //of the instance
        var proto = this._mfClazz.prototype;
        var impl = myfaces._impl;
        if(!proto._RT) {
            proto._RT  =  impl.core._Runtime;
            proto._Lang = impl._util._Lang;
            proto._Dom =  impl._util._Dom;
        }
    },

    /*optional functionality can be provided
     * for ie6 but is turned off by default*/
    _initDefaultFinalizableFields: function() {
        var isIE = this._RT.browser.isIE;
        if(!isIE || isIE > 7) return;
        for (var key in this) {
            //per default we reset everything which is not preinitalized
            if (null == this[key] && key != "_resettableContent" && key.indexOf("_mf") != 0 && key.indexOf("_") == 0) {
                this._resettableContent[key] = true;
            }
        }
    },



    attr: function(name, value) {
        return this._Lang.attr(this, name, value);
    },

    getImpl: function() {
        this._Impl = this._Impl || this._RT.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
        return this._Impl;
    },

    applyArgs: function(args) {
        this._Lang.applyArgs(this, args);
    },

    updateSingletons: function(key) {
        var _T = this;
        _T._RT.iterateSingletons(function(namespace) {
            if(namespace[key]) namespace[key] = _T;
        });
    }

});

(function() {
    /*some mobile browsers do not have a window object*/
    var target = window ||document;
    var _RT = myfaces._impl.core._Runtime;
    _RT._MF_OBJECT = target._MF_OBJECT;

    target._MF_OBJECT = myfaces._impl.core.Object;
})();

/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @class
 * @name _Queue
 * @memberOf myfaces._impl._util
 * @description Queue implementation used by our runtime system
 * improved version of
 * @see <a href="http://safalra.com/web-design/javascript/queues/Queue.js">http://safalra.com/web-design/javascript/queues/Queue.js</a>
 */
_MF_CLS(_PFX_UTIL+"_Queue", _MF_OBJECT,
    /**
     * @lends myfaces._impl._util._Queue.prototype
     */
    {
        //faster queue by http://safalra.com/web-design/javascript/queues/Queue.js
        //license public domain
        //The trick is to simply reduce the number of slice and slice ops to a bare minimum.

        _q : null,
        _space : 0,
        _size: -1,

        /**
         * Standard constructor
         */
        constructor_: function() {
            this._callSuper("constructor_");
            this._q = [];
        },

        /**
         * @return the length of the queue as integer
         */
        length: function() {
            // return the number of elements in the queue
            return this._q.length - this._space;

        },

        /**
         * @return true if the current queue is empty false otherwise
         */
        isEmpty: function() {
            // return true if the queue is empty, and false otherwise
            return (this._q.length == 0);
        },

        /**
         * Sets the current queue to a new size, all overflow elements at the end are stripped
         * automatically
         *
         * @param {int} newSize as numeric value
         */
        setQueueSize: function(newSize) {
            this._size = newSize;
            this._readjust();
        },

        /**
         * adds a listener to the queue
         *
         * @param element the listener to be added
         */
        enqueue : function(/*function*/element) {
            this._q.push(element);
            //qeuesize is bigger than the limit we drop one element so that we are
            //back in line

            this._readjust();
        },

        _readjust: function() {
            var size = this._size;
            while (size && size > -1 && this.length() > size) {
                this.dequeue();
            }
        },

        /**
         * removes a listener form the queue
         *
         * @param element the listener to be removed
         */
        remove : function(/*function*/element) {
            /*find element in queue*/
            var index = this.indexOf(element);
            /*found*/
            if (index != -1) {
                this._q.splice(index, 1);
            }
        },

        /**
         * dequeues the last element in the queue
         * @return {Object} element which is dequeued
         */
        dequeue: function() {
            // initialise the element to return to be undefined
            var element = null;

            // check whether the queue is empty
            var qLen = this._q.length;
            var queue = this._q;

            if (qLen) {

                // fetch the oldest element in the queue
                element = queue[this._space];

                // update the amount of space and check whether a shift should occur
                //added here a max limit of 30
                //now bit shift left is a tad faster than multiplication on most vms and does the same
                //unless we run into a bit skipping which is impossible in our usecases here
                if ((++this._space) << 1 >= qLen) {

                    // set the queue equal to the non-empty portion of the queue
                    this._q = queue.slice(this._space);

                    // reset the amount of space at the front of the queue
                    this._space = 0;

                }

            }

            // return the removed element
            return element;
        },

        /**
         * simple foreach
         *
         * @param closure a closure which processes the element
         * @code
         *   queue.each(function(element) {
         *      //do something with the element
         *   });
         */
        each: function(closure) {
            this._Lang.arrForEach(this._q, closure, this._space);
        },

        /**
         * Simple filter
         *
         * @param closure a closure which returns true or false depending
         * whether the filter has triggered
         *
         * @return an array of filtered queue entries
         */
        arrFilter: function(closure) {
            return this._Lang.arrFilter(this._q, closure, this._space);
        },

        /**
         * @param element
         * @return the current index of the element in the queue or -1 if it is not found
         */
        indexOf: function(element) {
            return this._Lang.arrIndexOf(this._q, element);
        },

        /**
         * resets the queue to initial empty state
         */
        cleanup: function() {
            this._q = [];
            this._space = 0;
        }
    });


/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * a classical listener queue pattern
 */



/**
 * @class
 * @name _ListenerQueue
 * @extends myfaces._impl._util._Queue
 * @memberOf myfaces._impl._util
 * @description Implementation of the listener queue for jsf.js
 * <p>It is based upon our high performance queue and adds dedicated
 * methods for listener based closures to the mix </p>
 * */
_MF_CLS(_PFX_UTIL+"_ListenerQueue", myfaces._impl._util._Queue,
    /**
     * @lends myfaces._impl._util._ListenerQueue.prototype
     */
    {
        /**
         * listener type safety assertion function
         *
         * @param {function} listener must be of type function otherwise an error is raised
         */
        _assertListener : function( listener) {
            if ("function" != typeof (listener)) {
                var msg = myfaces._impl._util._Lang.getMessage("ERR_PARAM_GENERIC",null,"_ListenerQueue", arguments.caller.toString(),"function" );
                throw this._Lang.makeException(new Error(), null, null, this._nameSpace,arguments.caller.toString(),  msg);
            }
        },

        /**
         * adds a listener to the queue
         *
         * @param {function} listener the listener to be added
         */
        enqueue : function(listener) {
            this._assertListener(listener);
            this._callSuper("enqueue", listener);
        },

        /**
         * removes a listener form the queue
         *
         * @param {function} listener the listener to be removed
         */
        remove : function(listener) {
            this._assertListener(listener);
            this._callSuper("remove", listener);
        },

        /**
         * generic broadcast with a number of arguments being passed down
         * @param {Object} args the arguments passed down which are broadcast
         */
        broadcastEvent : function(args) {
            var _args = myfaces._impl._util._Lang.objToArray(arguments); // XXX arguments vs. args?

            var broadCastFunc = function(element) {
                element.apply(null, _args);
            };
            try {
                this.each(broadCastFunc);
            } finally {
                broadCastFunc = null;
            }
        }
    });
/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,©
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @class
 * @name _Dom
 * @memberOf myfaces._impl._util
 * @extends myfaces._impl.core._Runtime
 * @description Object singleton collection of dom helper routines
 * (which in later incarnations will
 * get browser specific speed optimizations)
 *
 * Since we have to be as tight as possible
 * we will focus with our dom routines to only
 * the parts which our impl uses.
 * A jquery like query API would be nice
 * but this would increase up our codebase significantly
 *
 * <p>This class provides the proper fallbacks for ie8- and Firefox 3.6-</p>
 */
_MF_SINGLTN(_PFX_UTIL + "_Dom", Object, /** @lends myfaces._impl._util._Dom.prototype */ {

    /*table elements which are used in various parts */
    TABLE_ELEMS:  {
        "thead": 1,
        "tbody": 1,
        "tr": 1,
        "th": 1,
        "td": 1,
        "tfoot" : 1
    },

    _Lang:  myfaces._impl._util._Lang,
    _RT:    myfaces._impl.core._Runtime,
    _dummyPlaceHolder:null,

    /**
     * standard constructor
     */
    constructor_: function() {
    },

    runCss: function(item/*, xmlData*/) {

        var  UDEF = "undefined",
            _RT = this._RT,
            _Lang = this._Lang,
            applyStyle = function(item, style) {
                var newSS = document.createElement("style");

                newSS.setAttribute("rel", item.getAttribute("rel") || "stylesheet");
                newSS.setAttribute("type", item.getAttribute("type") || "text/css");
                if(item.getAttribute("nonce")) {
                    newSS.setAttribute("nonce", item.getAttribute("nonce"));
                }

                document.getElementsByTagName("head")[0].appendChild(newSS);
                //ie merrily again goes its own way
                if (window.attachEvent && !_RT.isOpera && UDEF != typeof newSS.styleSheet && UDEF != newSS.styleSheet.cssText) newSS.styleSheet.cssText = style;
                else newSS.appendChild(document.createTextNode(style));
            },

            execCss = function(item) {
                var equalsIgnoreCase = _Lang.equalsIgnoreCase;
                var tagName = item.tagName;
                if (tagName && equalsIgnoreCase(tagName, "link") && equalsIgnoreCase(item.getAttribute("type"), "text/css")) {
                    applyStyle(item, "@import url('" + item.getAttribute("href") + "');");
                } else if (tagName && equalsIgnoreCase(tagName, "style") && equalsIgnoreCase(item.getAttribute("type"), "text/css")) {
                    var innerText = [];
                    //compliant browsers know child nodes
                    var childNodes = item.childNodes;
                    if (childNodes) {
                        var len = childNodes.length;
                        for (var cnt = 0; cnt < len; cnt++) {
                            innerText.push(childNodes[cnt].innerHTML || childNodes[cnt].data);
                        }
                        //non compliant ones innerHTML
                    } else if (item.innerHTML) {
                        innerText.push(item.innerHTML);
                    }

                    applyStyle(item, innerText.join(""));
                }
            };

        try {
            var scriptElements = this.findByTagNames(item, {"link":1,"style":1}, true);
            if (scriptElements == null) return;
            for (var cnt = 0; cnt < scriptElements.length; cnt++) {
                execCss(scriptElements[cnt]);
            }

        } finally {
            //the usual ie6 fix code
            //the IE6 garbage collector is broken
            //nulling closures helps somewhat to reduce
            //mem leaks, which are impossible to avoid
            //at this browser
            execCss = null;
            applyStyle = null;
        }
    },


    /**
     * Run through the given Html item and execute the inline scripts
     * (IE doesn't do this by itself)
     * @param {Node} item
     */
    runScripts: function(item, xmlData) {
        var _Lang = this._Lang,
            _RT = this._RT,
            finalScripts = [],
            execScrpt = function(item) {
                var tagName = item.tagName;
                var type = item.type || "";
                //script type javascript has to be handled by eval, other types
                //must be handled by the browser
                if (tagName && _Lang.equalsIgnoreCase(tagName, "script") &&
                    (type === "" ||
                        _Lang.equalsIgnoreCase(type,"text/javascript") ||
                        _Lang.equalsIgnoreCase(type,"javascript") ||
                        _Lang.equalsIgnoreCase(type,"text/ecmascript") ||
                        _Lang.equalsIgnoreCase(type,"ecmascript"))) {

                    var nonce = item.getAttribute("nonce") || null;

                    var src = item.getAttribute('src');
                    if ('undefined' != typeof src
                        && null != src
                        && src.length > 0
                    ) {
                        //we have to move this into an inner if because chrome otherwise chokes
                        //due to changing the and order instead of relying on left to right
                        //if jsf.js is already registered we do not replace it anymore
                        if ((src.indexOf("ln=scripts") == -1 && src.indexOf("ln=javax.faces") == -1) || (src.indexOf("/jsf.js") == -1
                            && src.indexOf("/jsf-uncompressed.js") == -1)) {

                            if (finalScripts.length) {
                                //script source means we have to eval the existing
                                //scripts before running the include
                                for(var cnt = 0; cnt < finalScripts.length; cnt++) {
                                    _RT.globalEval(finalScripts[cnt].text, finalScripts[cnt]["cspMeta"] || null);
                                }

                                finalScripts = [];
                            }
                            _RT.loadScriptEval(src, item.getAttribute('type'), false, "UTF-8", false, nonce ? {nonce: nonce} : null );
                        }

                    } else {
                        // embedded script auto eval
                        var test = (!xmlData) ? item.text : _Lang.serializeChilds(item);
                        var go = true;
                        while (go) {
                            go = false;
                            if (test.substring(0, 1) == " ") {
                                test = test.substring(1);
                                go = true;
                            }
                            if (test.substring(0, 4) == "<!--") {
                                test = test.substring(4);
                                go = true;
                            }
                            if (test.substring(0, 11) == "//<![CDATA[") {
                                test = test.substring(11);
                                go = true;
                            }
                        }
                        // we have to run the script under a global context
                        //we store the script for less calls to eval
                        finalScripts.push(nonce ? {
                            cspMeta: {nonce: nonce},
                            text: test
                        }: {
                            text: test
                        });

                    }
                }
            };
        try {
            var scriptElements = this.findByTagName(item, "script", true);
            if (scriptElements == null) return;
            for (var cnt = 0; cnt < scriptElements.length; cnt++) {
                execScrpt(scriptElements[cnt]);
            }
            if (finalScripts.length) {
                for(var cnt = 0; cnt < finalScripts.length; cnt++) {
                    _RT.globalEval(finalScripts[cnt].text, finalScripts[cnt]["cspMeta"] || null);
                }
            }
        } catch (e) {
            //we are now in accordance with the rest of the system of showing errors only in development mode
            //the default error output is alert we always can override it with
            //window.myfaces = window.myfaces || {};
            //myfaces.config =  myfaces.config || {};
            //myfaces.config.defaultErrorOutput = console.error;
            if(jsf.getProjectStage() === "Development") {
                var defaultErrorOutput = myfaces._impl.core._Runtime.getGlobalConfig("defaultErrorOutput", alert);
                defaultErrorOutput("Error in evaluated javascript:"+ (e.message || e.description || e));
            }
        } finally {
            //the usual ie6 fix code
            //the IE6 garbage collector is broken
            //nulling closures helps somewhat to reduce
            //mem leaks, which are impossible to avoid
            //at this browser
            execScrpt = null;
        }
    },


    /**
     * determines to fetch a node
     * from its id or name, the name case
     * only works if the element is unique in its name
     * @param {String} elem
     */
    byIdOrName: function(elem) {
        if (!elem) return null;
        if (!this._Lang.isString(elem)) return elem;

        var ret = this.byId(elem);
        if (ret) return ret;
        //we try the unique name fallback
        var items = document.getElementsByName(elem);
        return ((items.length == 1) ? items[0] : null);
    },

    /**
     * node id or name, determines the valid form identifier of a node
     * depending on its uniqueness
     *
     * Usually the id is chosen for an elem, but if the id does not
     * exist we try a name fallback. If the passed element has a unique
     * name we can use that one as subsequent identifier.
     *
     *
     * @param {String} elem
     */
    nodeIdOrName: function(elem) {
        if (elem) {
            //just to make sure that the pas

            elem = this.byId(elem);
            if (!elem) return null;
            //detached element handling, we also store the element name
            //to get a fallback option in case the identifier is not determinable
            // anymore, in case of a framework induced detachment the element.name should
            // be shared if the identifier is not determinable anymore
            //the downside of this method is the element name must be unique
            //which in case of jsf it is
            var elementId = elem.id || elem.name;
            if ((elem.id == null || elem.id == '') && elem.name) {
                elementId = elem.name;

                //last check for uniqueness
                if (document.getElementsByName(elementId).length > 1) {
                    //no unique element name so we need to perform
                    //a return null to let the caller deal with this issue
                    return null;
                }
            }
            return elementId;
        }
        return null;
    },

    deleteItems: function(items) {
        if (! items || ! items.length) return;
        for (var cnt = 0; cnt < items.length; cnt++) {
            this.deleteItem(items[cnt]);
        }
    },

    /**
     * Simple delete on an existing item
     */
    deleteItem: function(itemIdToReplace) {
        var item = this.byId(itemIdToReplace);
        if (!item) {
            throw this._Lang.makeException(new Error(),null, null, this._nameSpace, "deleteItem",  "_Dom.deleteItem  Unknown Html-Component-ID: " + itemIdToReplace);
        }

        this._removeNode(item, false);
    },

    /**
     * creates a node upon a given node name
     * @param nodeName {String} the node name to be created
     * @param attrs {Array} a set of attributes to be set
     */
    createElement: function(nodeName, attrs) {
        var ret = document.createElement(nodeName);
        if (attrs) {
            for (var key in attrs) {
                if(!attrs.hasOwnProperty(key)) continue;
                this.setAttribute(ret, key, attrs[key]);
            }
        }
        return ret;
    },

    /**
     * Checks whether the browser is dom compliant.
     * Dom compliant means that it performs the basic dom operations safely
     * without leaking and also is able to perform a native setAttribute
     * operation without freaking out
     *
     *
     * Not dom compliant browsers are all microsoft browsers in quirks mode
     * and ie6 and ie7 to some degree in standards mode
     * and pretty much every browser who cannot create ranges
     * (older mobile browsers etc...)
     *
     * We dont do a full browser detection here because it probably is safer
     * to test for existing features to make an assumption about the
     * browsers capabilities
     */
    isDomCompliant: function() {
        return true;
    },

    /**
     * proper insert before which takes tables into consideration as well as
     * browser deficiencies
     * @param item the node to insert before
     * @param markup the markup to be inserted
     */
    insertBefore: function(item, markup) {
        this._assertStdParams(item, markup, "insertBefore");

        markup = this._Lang.trim(markup);
        if (markup === "") return null;

        var evalNodes = this._buildEvalNodes(item, markup),
            currentRef = item,
            parentNode = item.parentNode,
            ret = [];
        for (var cnt = evalNodes.length - 1; cnt >= 0; cnt--) {
            currentRef = parentNode.insertBefore(evalNodes[cnt], currentRef);
            ret.push(currentRef);
        }
        ret = ret.reverse();
        this._eval(ret);
        return ret;
    },

    /**
     * proper insert before which takes tables into consideration as well as
     * browser deficiencies
     * @param item the node to insert before
     * @param markup the markup to be inserted
     */
    insertAfter: function(item, markup) {
        this._assertStdParams(item, markup, "insertAfter");
        markup = this._Lang.trim(markup);
        if (markup === "") return null;

        var evalNodes = this._buildEvalNodes(item, markup),
            currentRef = item,
            parentNode = item.parentNode,
            ret = [];

        for (var cnt = 0; cnt < evalNodes.length; cnt++) {
            if (currentRef.nextSibling) {
                //Winmobile 6 has problems with this strategy, but it is not really fixable
                currentRef = parentNode.insertBefore(evalNodes[cnt], currentRef.nextSibling);
            } else {
                currentRef = parentNode.appendChild(evalNodes[cnt]);
            }
            ret.push(currentRef);
        }
        this._eval(ret);
        return ret;
    },

    propertyToAttribute: function(name) {
        if (name === 'className') {
            return 'class';
        } else if (name === 'xmllang') {
            return 'xml:lang';
        } else {
            return name.toLowerCase();
        }
    },

    isFunctionNative: function(func) {
        return /^\s*function[^{]+{\s*\[native code\]\s*}\s*$/.test(String(func));
    },

    detectAttributes: function(element) {
        //test if 'hasAttribute' method is present and its native code is intact
        //for example, Prototype can add its own implementation if missing
        //JSF 2.4 we now can reduce the complexity here, one of the functions now
        //is definitely implemented
        if (element.hasAttribute && this.isFunctionNative(element.hasAttribute)) {
            return function(name) {
                return element.hasAttribute(name);
            }
        } else {
            return function (name) {
                return !!element.getAttribute(name);
            }
        }
    },

    /**
     * copy all attributes from one element to another - except id
     * @param target element to copy attributes to
     * @param source element to copy attributes from
     * @ignore
     */
    cloneAttributes: function(target, source) {

        // enumerate core element attributes - without 'dir' as special case
        var coreElementProperties = ['className', 'title', 'lang', 'xmllang'];
        // enumerate additional input element attributes
        var inputElementProperties = [
            'name', 'value', 'size', 'maxLength', 'src', 'alt', 'useMap', 'tabIndex', 'accessKey', 'accept', 'type'
        ];
        // enumerate additional boolean input attributes
        var inputElementBooleanProperties = [
            'checked', 'disabled', 'readOnly'
        ];

        // Enumerate all the names of the event listeners
        var listenerNames =
            [ 'onclick', 'ondblclick', 'onmousedown', 'onmousemove', 'onmouseout',
                'onmouseover', 'onmouseup', 'onkeydown', 'onkeypress', 'onkeyup',
                'onhelp', 'onblur', 'onfocus', 'onchange', 'onload', 'onunload', 'onabort',
                'onreset', 'onselect', 'onsubmit'
            ];

        var sourceAttributeDetector = this.detectAttributes(source);
        var targetAttributeDetector = this.detectAttributes(target);

        var isInputElement = target.nodeName.toLowerCase() === 'input';
        var propertyNames = isInputElement ? coreElementProperties.concat(inputElementProperties) : coreElementProperties;
        var isXML = !source.ownerDocument.contentType || source.ownerDocument.contentType == 'text/xml';
        for (var iIndex = 0, iLength = propertyNames.length; iIndex < iLength; iIndex++) {
            var propertyName = propertyNames[iIndex];
            var attributeName = this.propertyToAttribute(propertyName);
            if (sourceAttributeDetector(attributeName)) {

                //With IE 7 (quirks or standard mode) and IE 8/9 (quirks mode only),
                //you cannot get the attribute using 'class'. You must use 'className'
                //which is the same value you use to get the indexed property. The only
                //reliable way to detect this (without trying to evaluate the browser
                //mode and version) is to compare the two return values using 'className'
                //to see if they exactly the same.  If they are, then use the property
                //name when using getAttribute.
                if( attributeName == 'class'){
                    if( this._RT.browser.isIE && (source.getAttribute(propertyName) === source[propertyName]) ){
                        attributeName = propertyName;
                    }
                }

                var newValue = isXML ? source.getAttribute(attributeName) : source[propertyName];
                var oldValue = target[propertyName];
                if (oldValue != newValue) {
                    target[propertyName] = newValue;
                }
            } else {
                target.removeAttribute(attributeName);
                if (attributeName == "value") {
                    target[propertyName] = '';
                }
            }
        }

        var booleanPropertyNames = isInputElement ? inputElementBooleanProperties : [];
        for (var jIndex = 0, jLength = booleanPropertyNames.length; jIndex < jLength; jIndex++) {
            var booleanPropertyName = booleanPropertyNames[jIndex];
            var newBooleanValue = source[booleanPropertyName];
            var oldBooleanValue = target[booleanPropertyName];
            if (oldBooleanValue != newBooleanValue) {
                target[booleanPropertyName] = newBooleanValue;
            }
        }

        //'style' attribute special case
        if (sourceAttributeDetector('style')) {
            var newStyle;
            var oldStyle;
            if (this._RT.browser.isIE) {
                newStyle = source.style.cssText;
                oldStyle = target.style.cssText;
                if (newStyle != oldStyle) {
                    target.style.cssText = newStyle;
                }
            } else {
                newStyle = source.getAttribute('style');
                oldStyle = target.getAttribute('style');
                if (newStyle != oldStyle) {
                    target.setAttribute('style', newStyle);
                }
            }
        } else if (targetAttributeDetector('style')){
            target.removeAttribute('style');
        }

        // Special case for 'dir' attribute
        if (!this._RT.browser.isIE && source.dir != target.dir) {
            if (sourceAttributeDetector('dir')) {
                target.dir = source.dir;
            } else if (targetAttributeDetector('dir')) {
                target.dir = '';
            }
        }

        for (var lIndex = 0, lLength = listenerNames.length; lIndex < lLength; lIndex++) {
            var name = listenerNames[lIndex];
            target[name] = source[name] ? source[name] : null;
            if (source[name]) {
                source[name] = null;
            }
        }

        //clone HTML5 data-* attributes
        try{
            var targetDataset = target.dataset;
            var sourceDataset = source.dataset;
            if (targetDataset || sourceDataset) {
                //cleanup the dataset
                for (var tp in targetDataset) {
                    delete targetDataset[tp];
                }
                //copy dataset's properties
                for (var sp in sourceDataset) {
                    targetDataset[sp] = sourceDataset[sp];
                }
            }
        } catch (ex) {
            //most probably dataset properties are not supported
        }
    },
    //from
    // http://blog.vishalon.net/index.php/javascript-getting-and-setting-caret-position-in-textarea/
    getCaretPosition:function (ctrl) {
        var caretPos = 0;

        try {

            // other browsers make it simpler by simply having a selection start element
            if (ctrl.selectionStart || ctrl.selectionStart == '0')
                caretPos = ctrl.selectionStart;
            // ie 5 quirks mode as second option because
            // this option is flakey in conjunction with text areas
            // TODO move this into the quirks class
            else if (document.selection) {
                ctrl.focus();
                var selection = document.selection.createRange();
                //the selection now is start zero
                selection.moveStart('character', -ctrl.value.length);
                //the caretposition is the selection start
                caretPos = selection.text.length;
            }
        } catch (e) {
            //now this is ugly, but not supported input types throw errors for selectionStart
            //this way we are future proof by having not to define every selection enabled
            //input in an if (which will be a lot in the near future with html5)
        }
        return caretPos;
    },

    setCaretPosition:function (ctrl, pos) {

        if (ctrl.createTextRange) {
            var range = ctrl.createTextRange();
            range.collapse(true);
            range.moveEnd('character', pos);
            range.moveStart('character', pos);
            range.select();
        }
        //IE quirks mode again, TODO move this into the quirks class
        else if (ctrl.setSelectionRange) {
            ctrl.focus();
            //the selection range is our caret position
            ctrl.setSelectionRange(pos, pos);
        }
    },

    /**
     * outerHTML replacement which works cross browserlike
     * but still is speed optimized
     *
     * @param item the item to be replaced
     * @param markup the markup for the replacement
     * @param preserveFocus, tries to preserve the focus within the outerhtml operation
     * if set to true a focus preservation algorithm based on document.activeElement is
     * used to preserve the focus at the exactly same location as it was
     *
     */
    outerHTML : function(item, markup, preserveFocus) {
        this._assertStdParams(item, markup, "outerHTML");
        // we can work on a single element in a cross browser fashion
        // regarding the focus thanks to the
        // icefaces team for providing the code
        if (item.nodeName.toLowerCase() === 'input') {
            var replacingInput = this._buildEvalNodes(item, markup)[0];
            this.cloneAttributes(item, replacingInput);
            return item;
        } else {
            markup = this._Lang.trim(markup);
            if (markup !== "") {
                var ret = null;

                var focusElementId = null;
                var caretPosition = 0;
                if (preserveFocus && 'undefined' != typeof document.activeElement) {
                    focusElementId = (document.activeElement) ? document.activeElement.id : null;
                    caretPosition = this.getCaretPosition(document.activeElement);
                }
                // we try to determine the browsers compatibility
                // level to standards dom level 2 via various methods
                if (this.isDomCompliant()) {
                    ret = this._outerHTMLCompliant(item, markup);
                } else {
                    //call into abstract method
                    ret = this._outerHTMLNonCompliant(item, markup);
                }
                if (focusElementId) {
                    var newFocusElement = this.byId(focusElementId);
                    if (newFocusElement && newFocusElement.nodeName.toLowerCase() === 'input') {
                        //just in case the replacement element is not focusable anymore
                        if ("undefined" != typeof newFocusElement.focus) {
                            newFocusElement.focus();
                        }
                    }
                    if (newFocusElement && caretPosition) {
                        //zero caret position is set automatically on focus
                        this.setCaretPosition(newFocusElement, caretPosition);
                    }
                }

                // and remove the old item
                //first we have to save the node newly insert for easier access in our eval part
                this._eval(ret);
                return ret;
            }
            // and remove the old item, in case of an empty newtag and do nothing else
            this._removeNode(item, false);
            return null;
        }
    },

    /**
     * detaches a set of nodes from their parent elements
     * in a browser independend manner
     * @param {Object} items the items which need to be detached
     * @return {Array} an array of nodes with the detached dom nodes
     */
    detach: function(items) {
        var ret = [];
        if ('undefined' != typeof items.nodeType) {
            if (items.parentNode) {
                ret.push(items.parentNode.removeChild(items));
            } else {
                ret.push(items);
            }
            return ret;
        }
        //all ies treat node lists not as arrays so we have to take
        //an intermediate step
        var nodeArr = this._Lang.objToArray(items);
        for (var cnt = 0; cnt < nodeArr.length; cnt++) {
            ret.push(nodeArr[cnt].parentNode.removeChild(nodeArr[cnt]));
        }
        return ret;
    },

    _outerHTMLCompliant: function(item, markup) {
        //table element replacements like thead, tbody etc... have to be treated differently
        var evalNodes = this._buildEvalNodes(item, markup);

        if (evalNodes.length == 1) {
            var ret = evalNodes[0];
            item.parentNode.replaceChild(ret, item);
            return ret;
        } else {
            return this.replaceElements(item, evalNodes);
        }
    },

    /**
     * checks if the provided element is a subelement of a table element
     * @param item
     */
    _isTableElement: function(item) {
        return !!this.TABLE_ELEMS[(item.nodeName || item.tagName).toLowerCase()];
    },

    /**
     * non ie browsers do not have problems with embedded scripts or any other construct
     * we simply can use an innerHTML in a placeholder
     *
     * @param markup the markup to be used
     */
    _buildNodesCompliant: function(markup) {
        var dummyPlaceHolder = this.getDummyPlaceHolder(); //document.createElement("div");
        dummyPlaceHolder.innerHTML = markup;
        return this._Lang.objToArray(dummyPlaceHolder.childNodes);
    },




    /**
     * builds up a correct dom subtree
     * if the markup is part of table nodes
     * The usecase for this is to allow subtable rendering
     * like single rows thead or tbody
     *
     * @param item
     * @param markup
     */
    _buildTableNodes: function(item, markup) {
        var itemNodeName = (item.nodeName || item.tagName).toLowerCase();

        var tmpNodeName = itemNodeName;
        var depth = 0;
        while (tmpNodeName != "table") {
            item = item.parentNode;
            tmpNodeName = (item.nodeName || item.tagName).toLowerCase();
            depth++;
        }

        var dummyPlaceHolder = this.getDummyPlaceHolder();
        if (itemNodeName == "td") {
            dummyPlaceHolder.innerHTML = "<table><tbody><tr>" + markup + "</tr></tbody></table>";
        } else {
            dummyPlaceHolder.innerHTML = "<table>" + markup + "</table>";
        }

        for (var cnt = 0; cnt < depth; cnt++) {
            dummyPlaceHolder = dummyPlaceHolder.childNodes[0];
        }

        return this.detach(dummyPlaceHolder.childNodes);
    },

    _removeChildNodes: function(node /*, breakEventsOpen */) {
        if (!node) return;
        node.innerHTML = "";
    },



    _removeNode: function(node /*, breakEventsOpen*/) {
        if (!node) return;
        var parentNode = node.parentNode;
        if (parentNode) //if the node has a parent
            parentNode.removeChild(node);
    },


    /**
     * build up the nodes from html markup in a browser independend way
     * so that it also works with table nodes
     *
     * @param item the parent item upon the nodes need to be processed upon after building
     * @param markup the markup to be built up
     */
    _buildEvalNodes: function(item, markup) {
        var evalNodes = null;
        if (this._isTableElement(item)) {
            evalNodes = this._buildTableNodes(item, markup);
        } else {
            var nonIEQuirks = (!this._RT.browser.isIE || this._RT.browser.isIE > 8);
            //ie8 has a special problem it still has the swallow scripts and other
            //elements bug, but it is mostly dom compliant so we have to give it a special
            //treatment, IE9 finally fixes that issue finally after 10 years
            evalNodes = (this.isDomCompliant() &&  nonIEQuirks) ?
                this._buildNodesCompliant(markup) :
                //ie8 or quirks mode browsers
                this._buildNodesNonCompliant(markup);
        }
        return evalNodes;
    },

    /**
     * we have lots of methods with just an item and a markup as params
     * this method builds an assertion for those methods to reduce code
     *
     * @param item  the item to be tested
     * @param markup the markup
     * @param caller caller function
     * @param {optional} params array of assertion param names
     */
    _assertStdParams: function(item, markup, caller, params) {
        //internal error
        if (!caller) {
            throw this._Lang.makeException(new Error(), null, null, this._nameSpace, "_assertStdParams",  "Caller must be set for assertion");
        }
        var _Lang = this._Lang,
            ERR_PROV = "ERR_MUST_BE_PROVIDED1",
            DOM = "myfaces._impl._util._Dom.",
            finalParams = params || ["item", "markup"];

        if (!item || !markup) {
            _Lang.makeException(new Error(), null, null,DOM, ""+caller,  _Lang.getMessage(ERR_PROV, null, DOM +"."+ caller, (!item) ? finalParams[0] : finalParams[1]));
            //throw Error(_Lang.getMessage(ERR_PROV, null, DOM + caller, (!item) ? params[0] : params[1]));
        }
    },

    /**
     * internal eval handler used by various functions
     * @param _nodeArr
     */
    _eval: function(_nodeArr) {
        if (this.isManualScriptEval()) {
            var isArr = _nodeArr instanceof Array;
            if (isArr && _nodeArr.length) {
                for (var cnt = 0; cnt < _nodeArr.length; cnt++) {
                    this.runScripts(_nodeArr[cnt]);
                }
            } else if (!isArr) {
                this.runScripts(_nodeArr);
            }
        }
    },

    /**
     * for performance reasons we work with replaceElement and replaceElements here
     * after measuring performance it has shown that passing down an array instead
     * of a single node makes replaceElement twice as slow, however
     * a single node case is the 95% case
     *
     * @param item
     * @param evalNode
     */
    replaceElement: function(item, evalNode) {
        //browsers with defect garbage collection
        item.parentNode.insertBefore(evalNode, item);
        this._removeNode(item, false);
    },


    /**
     * replaces an element with another element or a set of elements
     *
     * @param item the item to be replaced
     *
     * @param evalNodes the elements
     */
    replaceElements: function (item, evalNodes) {
        var evalNodesDefined = evalNodes && 'undefined' != typeof evalNodes.length;
        if (!evalNodesDefined) {
            throw this._Lang.makeException(new Error(), null, null, this._nameSpace, "replaceElements",  this._Lang.getMessage("ERR_REPLACE_EL"));
        }

        var parentNode = item.parentNode,

            sibling = item.nextSibling,
            resultArr = this._Lang.objToArray(evalNodes);

        for (var cnt = 0; cnt < resultArr.length; cnt++) {
            if (cnt == 0) {
                this.replaceElement(item, resultArr[cnt]);
            } else {
                if (sibling) {
                    parentNode.insertBefore(resultArr[cnt], sibling);
                } else {
                    parentNode.appendChild(resultArr[cnt]);
                }
            }
        }
        return resultArr;
    },

    /**
     * optimized search for an array of tag names
     * deep scan will always be performed.
     * @param fragment the fragment which should be searched for
     * @param tagNames an map indx of tag names which have to be found
     *
     */
    findByTagNames: function(fragment, tagNames) {
        this._assertStdParams(fragment, tagNames, "findByTagNames", ["fragment", "tagNames"]);

        var nodeType = fragment.nodeType;
        if (nodeType != 1 && nodeType != 9 && nodeType != 11) return null;

        //we can use the shortcut
        if (fragment.querySelectorAll) {
            var query = [];
            for (var key in tagNames) {
                if(!tagNames.hasOwnProperty(key)) continue;
                query.push(key);
            }
            var res = [];
            if (fragment.tagName && tagNames[fragment.tagName.toLowerCase()]) {
                res.push(fragment);
            }
            return res.concat(this._Lang.objToArray(fragment.querySelectorAll(query.join(", "))));
        }

        //now the filter function checks case insensitively for the tag names needed
        var filter = function(node) {
            return node.tagName && tagNames[node.tagName.toLowerCase()];
        };

        //now we run an optimized find all on it
        try {
            return this.findAll(fragment, filter, true);
        } finally {
            //the usual IE6 is broken, fix code
            filter = null;
        }
    },

    /**
     * determines the number of nodes according to their tagType
     *
     * @param {Node} fragment (Node or fragment) the fragment to be investigated
     * @param {String} tagName the tag name (lowercase)
     * (the normal usecase is false, which means if the element is found only its
     * adjacent elements will be scanned, due to the recursive descension
     * this should work out with elements with different nesting depths but not being
     * parent and child to each other
     *
     * @return the child elements as array or null if nothing is found
     *
     */
    findByTagName : function(fragment, tagName) {
        this._assertStdParams(fragment, tagName, "findByTagName", ["fragment", "tagName"]);
        var _Lang = this._Lang,
            nodeType = fragment.nodeType;
        if (nodeType != 1 && nodeType != 9 && nodeType != 11) return null;

        //remapping to save a few bytes

        var ret = _Lang.objToArray(fragment.getElementsByTagName(tagName));
        if (fragment.tagName && _Lang.equalsIgnoreCase(fragment.tagName, tagName)) ret.unshift(fragment);
        return ret;
    },

    findByName : function(fragment, name) {
        this._assertStdParams(fragment, name, "findByName", ["fragment", "name"]);

        var nodeType = fragment.nodeType;
        if (nodeType != 1 && nodeType != 9 && nodeType != 11) return null;

        var ret = this._Lang.objToArray(fragment.getElementsByName(name));
        if (fragment.name == name) ret.unshift(fragment);
        return ret;
    },

    /**
     * a filtered findAll for subdom treewalking
     * (which uses browser optimizations wherever possible)
     *
     * @param {|Node|} rootNode the rootNode so start the scan
     * @param filter filter closure with the syntax {boolean} filter({Node} node)
     * @param deepScan if set to true or not set at all a deep scan is performed (for form scans it does not make much sense to deeply scan)
     */
    findAll : function(rootNode, filter, deepScan) {
        this._Lang.assertType(filter, "function");
        deepScan = !!deepScan;

        if (document.createTreeWalker && NodeFilter) {
            return this._iteratorSearchAll(rootNode, filter, deepScan);
        } else {
            //will not be called in dom level3 compliant browsers
            return this._recursionSearchAll(rootNode, filter, deepScan);
        }
    },

    /**
     * the faster dom iterator based search, works on all newer browsers
     * except ie8 which already have implemented the dom iterator functions
     * of html 5 (which is pretty all standard compliant browsers)
     *
     * The advantage of this method is a faster tree iteration compared
     * to the normal recursive tree walking.
     *
     * @param rootNode the root node to be iterated over
     * @param filter the iteration filter
     * @param deepScan if set to true a deep scan is performed
     */
    _iteratorSearchAll: function(rootNode, filter, deepScan) {
        var retVal = [];
        //Works on firefox and webkit, opera and ie have to use the slower fallback mechanis
        //we have a tree walker in place this allows for an optimized deep scan
        if (filter(rootNode)) {

            retVal.push(rootNode);
            if (!deepScan) {
                return retVal;
            }
        }
        //we use the reject mechanism to prevent a deep scan reject means any
        //child elements will be omitted from the scan
        var FILTER_ACCEPT = NodeFilter.FILTER_ACCEPT,
            FILTER_SKIP = NodeFilter.FILTER_SKIP,
            FILTER_REJECT = NodeFilter.FILTER_REJECT;

        var walkerFilter = function (node) {
            var retCode = (filter(node)) ? FILTER_ACCEPT : FILTER_SKIP;
            retCode = (!deepScan && retCode == FILTER_ACCEPT) ? FILTER_REJECT : retCode;
            if (retCode == FILTER_ACCEPT || retCode == FILTER_REJECT) {
                retVal.push(node);
            }
            return retCode;
        };

        var treeWalker = document.createTreeWalker(rootNode, NodeFilter.SHOW_ELEMENT, walkerFilter, false);
        //noinspection StatementWithEmptyBodyJS
        while (treeWalker.nextNode());
        return retVal;
    },

    /**
     * bugfixing for ie6 which does not cope properly with setAttribute
     */
    setAttribute : function(node, attr, val) {
        this._assertStdParams(node, attr, "setAttribute", ["fragment", "name"]);
        if (!node.setAttribute) {
            return;
        }

        if (attr === 'disabled') {
            node.disabled = val === 'disabled' || val === 'true';
        } else if (attr === 'checked') {
            node.checked = val === 'checked' || val === 'on' || val === 'true';
        } else if (attr == 'readonly') {
            node.readOnly = val === 'readonly' || val === 'true';
        } else {
            node.setAttribute(attr, val);
        }
    },

    /**
     * fuzzy form detection which tries to determine the form
     * an item has been detached.
     *
     * The problem is some Javascript libraries simply try to
     * detach controls by reusing the names
     * of the detached input controls. Most of the times,
     * the name is unique in a jsf scenario, due to the inherent form mapping.
     * One way or the other, we will try to fix that by
     * identifying the proper form over the name
     *
     * We do it in several ways, in case of no form null is returned
     * in case of multiple forms we check all elements with a given name (which we determine
     * out of a name or id of the detached element) and then iterate over them
     * to find whether they are in a form or not.
     *
     * If only one element within a form and a given identifier found then we can pull out
     * and move on
     *
     * We cannot do much further because in case of two identical named elements
     * all checks must fail and the first elements form is served.
     *
     * Note, this method is only triggered in case of the issuer or an ajax request
     * is a detached element, otherwise already existing code has served the correct form.
     *
     * This method was added because of
     * https://issues.apache.org/jira/browse/MYFACES-2599
     * to support the integration of existing ajax libraries which do heavy dom manipulation on the
     * controls side (Dojos Dijit library for instance).
     *
     * @param {Node} elem - element as source, can be detached, undefined or null
     *
     * @return either null or a form node if it could be determined
     *
     * TODO move this into extended and replace it with a simpler algorithm
     */
    fuzzyFormDetection : function(elem) {
        var forms = document.forms, _Lang = this._Lang;

        if (!forms || !forms.length) {
            return null;
        }

        // This will not work well on portlet case, because we cannot be sure
        // the returned form is right one.
        //we can cover that case by simply adding one of our config params
        //the default is the weaker, but more correct portlet code
        //you can override it with myfaces_config.no_portlet_env = true globally
        else if (1 == forms.length && this._RT.getGlobalConfig("no_portlet_env", false)) {
            return forms[0];
        }

        //before going into the more complicated stuff we try the simple approach
        var finalElem = this.byId(elem);
        var fetchForm = _Lang.hitch(this, function(elem) {
            //element of type form then we are already
            //at form level for the issuing element
            //https://issues.apache.org/jira/browse/MYFACES-2793

            return (_Lang.equalsIgnoreCase(elem.tagName, "form")) ? elem :
                ( this.html5FormDetection(elem) || this.getParent(elem, "form"));
        });

        if (finalElem) {
            var elemForm = fetchForm(finalElem);
            if (elemForm) return elemForm;
        }

        /**
         * name check
         */
        var foundElements = [];
        var name = (_Lang.isString(elem)) ? elem : elem.name;
        //id detection did not work
        if (!name) return null;
        /**
         * the lesser chance is the elements which have the same name
         * (which is the more likely case in case of a brute dom replacement)
         */
        var nameElems = document.getElementsByName(name);
        if (nameElems) {
            for (var cnt = 0; cnt < nameElems.length && foundElements.length < 2; cnt++) {
                // we already have covered the identifier case hence we only can deal with names,
                var foundForm = fetchForm(nameElems[cnt]);
                if (foundForm) {
                    foundElements.push(foundForm);
                }
            }
        }

        return (1 == foundElements.length ) ? foundElements[0] : null;
    },

    html5FormDetection:function (item) {
        var elemForm = this.getAttribute(item, "form");
        return (elemForm) ? this.byId(elemForm) : null;
    },


    /**
     * gets a parent of an item with a given tagname
     * @param {Node} item - child element
     * @param {String} tagName - TagName of parent element
     */
    getParent : function(item, tagName) {

        if (!item) {
            throw this._Lang.makeException(new Error(), null, null, this._nameSpace, "getParent",
                this._Lang.getMessage("ERR_MUST_BE_PROVIDED1", null, "_Dom.getParent", "item {DomNode}"));
        }

        var _Lang = this._Lang;
        var searchClosure = function(parentItem) {
            return parentItem && parentItem.tagName
                && _Lang.equalsIgnoreCase(parentItem.tagName, tagName);
        };
        try {
            return this.getFilteredParent(item, searchClosure);
        } finally {
            searchClosure = null;
            _Lang = null;
        }
    },

    /**
     * A parent walker which uses
     * a filter closure for filtering
     *
     * @param {Node} item the root item to ascend from
     * @param {function} filter the filter closure
     */
    getFilteredParent : function(item, filter) {
        this._assertStdParams(item, filter, "getFilteredParent", ["item", "filter"]);

        //search parent tag parentName
        var parentItem = (item.parentNode) ? item.parentNode : null;

        while (parentItem && !filter(parentItem)) {
            parentItem = parentItem.parentNode;
        }
        return (parentItem) ? parentItem : null;
    },

    /**
     * cross ported from dojo
     * fetches an attribute from a node
     *
     * @param {String} node the node
     * @param {String} attr the attribute
     * @return the attributes value or null
     */
    getAttribute : function(/* HTMLElement */node, /* string */attr) {
        return node.getAttribute(attr);
    },

    /**
     * checks whether the given node has an attribute attached
     *
     * @param {String|Object} node the node to search for
     * @param {String} attr the attribute to search for
     * @true if the attribute was found
     */
    hasAttribute : function(/* HTMLElement */node, /* string */attr) {
        //	summary
        //	Determines whether or not the specified node carries a value for the attribute in question.
        return this.getAttribute(node, attr) ? true : false;	//	boolean
    },

    /**
     * concatenation routine which concats all childnodes of a node which
     * contains a set of CDATA blocks to one big string
     * @param {Node} node the node to concat its blocks for
     */
    concatCDATABlocks : function(/*Node*/ node) {
        var cDataBlock = [];
        // response may contain several blocks
        for (var i = 0; i < node.childNodes.length; i++) {
            cDataBlock.push(node.childNodes[i].data);
        }
        return cDataBlock.join('');
    },

    //all modern browsers evaluate the scripts
    //manually this is a w3d recommendation
    isManualScriptEval: function() {
        return true;
    },

    /**
     * jsf2.2
     * checks if there is a fileupload element within
     * the executes list
     *
     * @param executes the executes list
     * @return {Boolean} true if there is a fileupload element
     */
    isMultipartCandidate:function (executes) {
        if (this._Lang.isString(executes)) {
            executes = this._Lang.strToArray(executes, /\s+/);
        }

        for (var cnt = 0, len = executes.length; cnt < len ; cnt ++) {
            var element = this.byId(executes[cnt]);
            var inputs = this.findByTagName(element, "input", true);
            for (var cnt2 = 0, len2 = inputs.length; cnt2 < len2 ; cnt2++) {
                if (this.getAttribute(inputs[cnt2], "type") == "file") return true;
            }
        }
        return false;
    },

    insertFirst: function(newNode) {
        var body = document.body;
        if (body.childNodes.length > 0) {
            body.insertBefore(newNode, body.firstChild);
        } else {
            body.appendChild(newNode);
        }
    },

    byId: function(id) {
        return this._Lang.byId(id);
    },

    getDummyPlaceHolder: function() {
        this._dummyPlaceHolder = this._dummyPlaceHolder ||this.createElement("div");
        return this._dummyPlaceHolder;
    },

    getNamedElementFromForm: function(form, elementId) {
        return form[elementId];
    }
});



/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @class
 * @name _HtmlStripper
 * @memberOf myfaces._impl._util
 * @extends myfaces._impl.core._Runtime
 * @description
 *  Fallback routine if the browser embedded xml parser fails on the document
 *  This fallback is not failsafe but should give enough cover to handle all cases
 */

/** @namespace myfaces._impl._util._HtmlStripper */
_MF_CLS(_PFX_UTIL + "_HtmlStripper", _MF_OBJECT, /** @lends myfaces._impl._util._HtmlStripper.prototype */ {

    /**
     * main parse routine parses the document for a given tag name
     *
     *
     * @param theString  the markup string to be parsed
     * @param tagNameStart the tag name to be parsed for
     */
    parse : function(theString, tagNameStart) {

        var BEGIN_TAG = "html",
            _tagStart = -1,
            _tagEnd = -1,
            _contentStart = -1,
            _contentEnd = -1,
            _tokenPos = 0,
            _tokenForward = 1,
            tagNameStart = (!tagNameStart) ? BEGIN_TAG : tagNameStart;

        var proposedTagStartPos = theString.indexOf("<" + tagNameStart);
        var _T = this;

        //we use closures instead of private methods to improve the compressability

        var isValidPositionCombination = function(pos1, pos2, pos3, pos4) {
            return pos1 <= pos2 && pos3 <= pos4;
        };

        /**
         * trace for a forward comment
         *
         * @param theStr the string to be checked
         * @param tagPos the tag position from which the check onwards has to be perfomed
         * @return true in case a comment is found
         */
        var checkForwardForComment = function(theStr, tagPos) {
            var toCheck = theStr.substring(tagPos),
                indexOf = _T._Lang.hitch(toCheck, toCheck.indexOf),
                firstBeginComment = indexOf("<!--"),
                firstEndComment = indexOf("-->"),

                firstBeginCDATA = indexOf("<[CDATA["),
                firstEndCDATA = indexOf("]]>");

            if (isValidPositionCombination(firstBeginComment, firstEndComment, firstBeginCDATA, firstEndCDATA)) {
                return true;
            }

            return firstBeginComment <= firstEndComment && firstBeginCDATA <= firstEndCDATA;
        };

        /**
         * check backwards for a comment
         *
         * @param theStr the check string
         * @param tagPos the tag position from which the check should be performed
         * @return true in case a comment is found
         */
        var checkBackForComment = function(theStr, tagPos) {
            var toCheck = theStr.substring(tagPos),
                indexOf = _T._Lang.hitch(toCheck, toCheck.indexOf),
                lastBeginComment = indexOf("<!--"),
                lastEndComment = indexOf("-->"),
                lastBeginCDATA = indexOf("<[CDATA["),
                lastEndCDATA = indexOf("]]>");

            if (isValidPositionCombination(lastBeginComment, lastEndComment, lastBeginCDATA, lastEndCDATA)) {
                //TODO we have to handle the embedded cases, for now we leave them out
                return true;
            }
        };

        //no need for ll parsing a handful of indexofs instead of slower regepx suffices
        var theSubStr = this._Lang.hitch(theString, theString.substring);
        while (_contentStart == -1 && proposedTagStartPos != -1) {
            if (checkBackForComment(theString, proposedTagStartPos)) {
                _tagStart = proposedTagStartPos;
                _contentStart = proposedTagStartPos + theSubStr(proposedTagStartPos).indexOf(">") + 1;
            }
            proposedTagStartPos = theSubStr(proposedTagStartPos + tagNameStart.length + 2).indexOf("<" + tagNameStart);
        }

        var proposedEndTagPos = theString.lastIndexOf("</" + tagNameStart);
        while (_contentEnd == -1 && proposedEndTagPos > 0) {
            if (checkForwardForComment(theString, proposedEndTagPos)) {
                _tagEnd = proposedEndTagPos;
                _contentEnd = proposedEndTagPos;
            }
            proposedTagStartPos = theSubStr(proposedTagStartPos - tagNameStart.length - 2).lastIndexOf("</" + tagNameStart);
        }
        if (_contentStart != -1 && _contentEnd != -1) {
            return theSubStr(_contentStart, _contentEnd);
        }
        return null;
    }
});




/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


/**
 * legacy code to enable various aspects
 * of myfaces, used to be rendered inline
 * for jsf 2.0 we can externalized it into its own custom resource
 */

(!window.myfaces) ? window.myfaces = {} : null;
if (!myfaces.oam) {
    myfaces.oam = new function() {

        /**
         * sets a hidden input field
         * @param formname the formName
         * @param name the hidden field
         * @param value the value to be rendered
         */
        this.setHiddenInput = function(formname, name, value) {
            var form = document.forms[formname];
            if (typeof form == 'undefined') {
                form = document.getElementById(formname);
            }

            if (typeof form.elements[name] != 'undefined' && (form.elements[name].nodeName == 'INPUT' || form.elements[name].nodeName == 'input')) {
                form.elements[name].value = value;
            }
            else {
                var newInput = document.createElement('input');
                newInput.setAttribute('type', 'hidden');
                newInput.setAttribute('id', name);
                newInput.setAttribute('name', name);
                newInput.setAttribute('value', value);
                form.appendChild(newInput);
            }
        };

        /**
         * clears a hidden input field
         *
         * @param formname formName for the input
         * @param name the name of the input field
         * @param value the value to be cleared
         */
        this.clearHiddenInput = function(formname, name, value) {
            var form = document.forms[formname];

            if (typeof form == 'undefined') {
                form = document.getElementById(formname);
            }

            var hInput = form.elements[name];
            if (typeof hInput != 'undefined') {
                form.removeChild(hInput);
            }
        };

        /**
         * does special form submit remapping
         * remaps the issuing command link into something
         * the decode of the command link on the server can understand
         *
         * @param formName
         * @param linkId
         * @param target
         * @param params
         */
        this.submitForm = function(formName, linkId, target, params) {

            var clearFn = 'clearFormHiddenParams_' + formName.replace(/-/g, '\$:').replace(/:/g, '_');
            if (typeof window[clearFn] == 'function') {
                window[clearFn](formName);
            }

            var form = document.forms[formName];
            if (typeof form == 'undefined') {
                form = document.getElementById(formName);
            }

            //autoscroll code
            if (myfaces.core.config.autoScroll && typeof window.getScrolling != 'undefined') {
                myfaces.oam.setHiddenInput(formName, 'autoScroll', getScrolling());
            }

            var oldTarget = form.target;
            if (target != null) {
                form.target = target;
            }
            if ((typeof params != 'undefined') && params != null) {
                for (var i = 0, param; (param = params[i]); i++) {
                    myfaces.oam.setHiddenInput(formName, param[0], param[1]);
                }

            }

            myfaces.oam.setHiddenInput(formName, formName + ':' + '_idcl', linkId);

            if (form.onsubmit) {
                var result = form.onsubmit();
                if ((typeof result == 'undefined') || result) {
                    try {
                        form.submit();
                    }
                    catch(e) {
                        if (window.console) {
                            console.error(e);
                        }
                    }
                }

            }
            else {
                try {
                    form.submit();
                }
                catch(e) {
                    if (window.console) {
                        console.error(e);
                    }
                }
            }

            form.target = oldTarget;
            if ((typeof params != 'undefined') && params != null) {

                for (var i = 0, param; (param = params[i]); i++) {
                    myfaces.oam.clearHiddenInput(formName, param[0], param[1]);
                }

            }

            myfaces.oam.clearHiddenInput(formName, formName + ':' + '_idcl', linkId);
            return false;
        };
    }
}

//reserve a cofig namespace for impl related stuff
(!myfaces.core) ? myfaces.core = {} : null;
(!myfaces.core.config) ? myfaces.core.config = {} : null;


/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @memberOf myfaces._impl.xhrCore
 * @namespace
 * @name engine
 */

/**
 * @class
 * @name XhrConst
 * @memberOf myfaces._impl.xhrCore.engine
 */
_MF_SINGLTN(_PFX_XHR+"engine.XhrConst", Object,
    /** @lends myfaces._impl.xhrCore.engine.XhrConst.prototype */
    {
        READY_STATE_UNSENT:     0,
        READY_STATE_OPENED:     1,
        READY_STATE_HEADERS_RECEIVED: 2,
        READY_STATE_LOADING:    3,
        READY_STATE_DONE:       4,

        STATUS_OK_MINOR:        200,
        STATUS_OK_MAJOR:        300,

        constructor_: function() {
        }
    });
/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @class
 * @name BaseRequest
 * @memberOf myfaces._impl.xhrCore.engine
 * @extends myfaces._impl.core.Object
 * @description
 * Abstract Base for all classes which simulate the xhr level2 object
 * with a different transport
 *
 * <h3>Every class inheriting the interface must expose following methods and attributes</h3>
 *
 * <ul>
 *      <li>open(method, url, async)</li>
 *      <li>send(formData)</li>
 *      <li>setRequestHeader(key, value)</li>
 *      <li>abort()</li>
 *      <li>onloadstart()</li>
 *      <li>onprogress()</li>
 *      <li>onabort()</li>
 *      <li>onerror()</li>
 *      <li>onload()</li>
 *      <li>ontimeout()</li>
 *      <li>onloadend()</li>
 *      <li>onreadystatechange()</li>
 * </ul>
 * <h3>following attributes are supported</h3>
 * <ul>
 *      <li>async</li>
 *      <li>url</li>
 *      <li>method</li>
 *      <li>timeout</li>
 *      <li>response</li>
 *      <li>responseText</li>
 *      <li>responseXML</li>
 *      <li>status</li>
 *      <li>statusText</li>
 * </ul>
 */
_MF_CLS(_PFX_XHR + "engine.BaseRequest", _MF_OBJECT, /** @lends myfaces._impl.xhrCore.engine.BaseRequest.prototype */ {
    /*standard attributes*/

    /**
     * timeout attribute with a timeout for the request in miliseconds
     */
    timeout:0,
    /**
     * readonly ready stte attribute
     */
    readyState:0,
    /**
     * send method, allowed values POST and GET
     */
    method:"POST",
    /**
     * the url for the call
     */
    url:null,
    /**
     * asynchronous request, if set to true then the request happens
     * asynchronously, if possible.
     */
    async:true,
    /**
     * read only response object, containing the response as json/dom representation
     */
    response:null,
    /**
     * read only plain text representation of the response
     */
    responseText:null,
    /**
     * xml dom readonly representation of the response
     */
    responseXML:null,
    /**
     * readonly status code of the response
     */
    status:null,
    /**
     * readonly status text of the response
     */
    statusText:null,

    constructor_:function (params) {
        this._callSuper("constructor_", params);
        this._initDefaultFinalizableFields();

        this._XHRConst = myfaces._impl.xhrCore.engine.XhrConst;
        this._Lang.applyArgs(this, params);
    },

    //open send, abort etc... abstract
    /**
     * opens the transport element
     * @param {String} method transport method allowed values <i>POST</i> and <i>GET</i>
     * @param {String} url optional url
     * @param {Boolean} async optional param asynchronous transmission if set to true
     */
    open:function (method, url, async) {
        this._implementThis();
    },
    /**
     * send method
     * @param {Object} formData data to be posted within the request
     */
    send:function (formData) {
        this._implementThis();
    },
    /**
     * appends a key value pair to the request header if possible
     * @param {String} key the key of the request header entry
     * @param {String} value  the value for the key
     */
    setRequestHeader:function (key, value) {
        this._implementThis();
    },
    /**
     * aborts the transmission
     */
    abort:function () {
        this._implementThis();
    },

    //empty implementations for the callback handlers
    /**
     * callback once the transmission has started
     * @param evt
     */
    onloadstart:function (evt) {
    },
    onprogress:function (evt) {
    },
    onabort:function (evt) {
    },
    onerror:function (evt) {
    },
    onload:function (evt) {
    },
    ontimeout:function (evt) {
    },
    onloadend:function (evt) {
    },
    onreadystatechange:function (evt) {
    },

    _implementThis:function () {
        throw Error("the function needs to be implemented");
    }
});
/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @class
 * @name _AjaxUtils
 * @memberOf myfaces._impl.xhrCore
 * @description
 *
 * A set of helper routines which are utilized within our Ajax subsystem and nowhere else
 *
 * TODO move this into a singleton, the current structure is
 * still a j4fry legacy we need to get rid of it in the long run
 */
_MF_SINGLTN(_PFX_XHR+"_AjaxUtils", _MF_OBJECT,
    /** @lends myfaces._impl.xhrCore._AjaxUtils.prototype */
    {


        /**
         * determines fields to submit
         * @param {Object} targetBuf - the target form buffer receiving the data
         * @param {Node} parentItem - form element item is nested in
         * @param {Array} partialIds - ids fo PPS
         */
        encodeSubmittableFields : function(targetBuf,
                                           parentItem, partialIds) {
            if (!parentItem) throw "NO_PARITEM";
            if (partialIds ) {
                this.encodePartialSubmit(parentItem, false, partialIds, targetBuf);
            } else {
                // add all nodes
                var eLen = parentItem.elements.length;
                for (var e = 0; e < eLen; e++) {
                    this.encodeElement(parentItem.elements[e], targetBuf);
                } // end of for (formElements)
            }

        },

        /**
         * appends the issuing item if not given already
         * @param item
         * @param targetBuf
         */
        appendIssuingItem: function (item, targetBuf) {
            // if triggered by a Button send it along
            if (item && item.type && item.type.toLowerCase() == "submit") {
                targetBuf.append(item.name, item.value);
            }
        },


        /**
         * encodes a single input element for submission
         *
         * @param {Node} element - to be encoded
         * @param {} targetBuf - a target array buffer receiving the encoded strings
         */
        encodeElement : function(element, targetBuf) {

            //browser behavior no element name no encoding (normal submit fails in that case)
            //https://issues.apache.org/jira/browse/MYFACES-2847
            if (!element.name) {
                return;
            }

            var _RT = this._RT;
            var name = element.name;
            var tagName = element.tagName.toLowerCase();
            var elemType = element.type;
            if (elemType != null) {
                elemType = elemType.toLowerCase();
            }

            // routine for all elements
            // rules:
            // - process only inputs, textareas and selects
            // - elements muest have attribute "name"
            // - elements must not be disabled
            if (((tagName == "input" || tagName == "textarea" || tagName == "select") &&
                (name != null && name != "")) && !element.disabled) {

                // routine for select elements
                // rules:
                // - if select-one and value-Attribute exist => "name=value"
                // (also if value empty => "name=")
                // - if select-one and value-Attribute don't exist =>
                // "name=DisplayValue"
                // - if select multi and multple selected => "name=value1&name=value2"
                // - if select and selectedIndex=-1 don't submit
                if (tagName == "select") {
                    // selectedIndex must be >= 0 sein to be submittet
                    if (element.selectedIndex >= 0) {
                        var uLen = element.options.length;
                        for (var u = 0; u < uLen; u++) {
                            // find all selected options
                            //var subBuf = [];
                            if (element.options[u].selected) {
                                var elementOption = element.options[u];
                                targetBuf.append(name, (elementOption.getAttribute("value") != null) ?
                                    elementOption.value : elementOption.text);
                            }
                        }
                    }
                }

                // routine for remaining elements
                // rules:
                // - don't submit no selects (processed above), buttons, reset buttons, submit buttons,
                // - submit checkboxes and radio inputs only if checked
                if ((tagName != "select" && elemType != "button"
                    && elemType != "reset" && elemType != "submit" && elemType != "image")
                    && ((elemType != "checkbox" && elemType != "radio") || element.checked)) {
                    if ('undefined' != typeof element.files && element.files != null && _RT.getXHRLvl() >= 2 && element.files.length) {
                        //xhr level2
                        targetBuf.append(name, element.files[0]);
                    } else {
                        targetBuf.append(name, element.value);
                    }
                }

            }
        }
    });
/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/** @namespace myfaces._impl.xhrCore._AjaxRequestQueue */
_MF_CLS(_PFX_XHR + "_AjaxRequestQueue", myfaces._impl._util._Queue, /** @lends  myfaces._impl.xhrCore._AjaxRequestQueue.prototype */ {

    /**
     * a pointer towards the currently processed
     * request in our queue
     */
    _curReq : null,

    /**
     * delay request, then call enqueue
     * @param {Object} request (myfaces._impl.xhrCore._AjaxRequest) request to send
     */
    enqueue : function(request) {

        if (this._curReq == null) {
            this._curReq = request;
            this._curReq.send();
        } else {
            this._callSuper("enqueue", request);
            if (request._queueSize != this._size) {
                this.setQueueSize(request._queueSize);
            }
        }

    },

    /**
     * process queue, send request, if exists
     */
    processQueue: function() {
        this._curReq = this.dequeue();
        if (this._curReq) {
            this._curReq.send();
        }
    },

    /**
     * cleanup queue
     */
    cleanup: function() {
        this._curReq = null;
        this._callSuper("cleanup");
    }
});


/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * An implementation of an xhr request object
 * with partial page submit functionality, and jsf
 * ppr request and timeout handling capabilities
 *
 * Author: Werner Punz (latest modification by $Author: ganeshpuri $)
 * Version: $Revision: 1.4 $ $Date: 2009/05/31 09:16:44 $
 */

/**
 * @class
 * @name _AjaxRequest
 * @memberOf myfaces._impl.xhrCore
 * @extends myfaces._impl.core.Object
 */
_MF_CLS(_PFX_XHR + "_AjaxRequest", _MF_OBJECT, /** @lends myfaces._impl.xhrCore._AjaxRequest.prototype */ {

    _contentType: "application/x-www-form-urlencoded",
    /** source element issuing the request */
    _source: null,
    /** context passed down from the caller */
    _context:null,
    /** source form issuing the request */
    _sourceForm: null,
    /** passthrough parameters */
    _passThrough: null,

    /** queue control */
    _timeout: null,
    /** enqueuing delay */
    //_delay:null,
    /** queue size */
    _queueSize:-1,

    /**
     back reference to the xhr queue,
     only set if the object really is queued
     */
    _xhrQueue: null,

    /** pps an array of identifiers which should be part of the submit, the form is ignored */
    _partialIdsArray : null,

    /** xhr object, internal param */
    _xhr: null,

    /** predefined method */
    _ajaxType:"POST",

    //CONSTANTS
    ENCODED_URL:"javax.faces.encodedURL",
    /*
     * constants used internally
     */
    _CONTENT_TYPE:"Content-Type",
    _HEAD_FACES_REQ:"Faces-Request",
    _VAL_AJAX: "partial/ajax",
    _XHR_CONST: myfaces._impl.xhrCore.engine.XhrConst,

    // _exception: null,
    // _requestParameters: null,
    /**
     * Constructor
     * <p />
     * note there is a load of common properties
     * inherited by the base class which define the corner
     * parameters and the general internal behavior
     * like _onError etc...
     * @param {Object} args an arguments map which an override any of the given protected
     * instance variables, by a simple name value pair combination
     */
    constructor_: function(args) {

        try {
            this._callSuper("constructor_", args);

            this._initDefaultFinalizableFields();
            delete this._resettableContent["_xhrQueue"];

            this.applyArgs(args);

            /*namespace remapping for readability*/
            //we fetch in the standard arguments
            //and apply them to our protected attributes
            //we do not gc the entry hence it is not defined on top
            var xhrCore = myfaces._impl.xhrCore;
            this._AJAXUTIL = xhrCore._AjaxUtils;

        } catch (e) {
            //_onError
            this._stdErrorHandler(this._xhr, this._context, e);
        }
    },

    /**
     * Sends an Ajax request
     */
    send : function() {

        var _Lang = this._Lang;
        var _RT = this._RT;

        try {

            var scopeThis = _Lang.hitch(this, function(functionName) {
                return _Lang.hitch(this, this[functionName]);
            });
            this._xhr = _Lang.mixMaps(this._getTransport(), {
                onprogress: scopeThis("onprogress"),
                ontimeout:  scopeThis("ontimeout"),
                //remove for xhr level2 support (chrome has problems with it)
                onloadend:  scopeThis("ondone"),
                onload:     scopeThis("onsuccess"),
                onerror:    scopeThis("onerror")

            }, true);
            var xhr = this._xhr,
                sourceForm = this._sourceForm,
                targetURL = (typeof sourceForm.elements[this.ENCODED_URL] == 'undefined') ?
                    sourceForm.action :
                    sourceForm.elements[this.ENCODED_URL].value,
                formData = this.getFormData();

            for (var key in this._passThrough) {
                if(!this._passThrough.hasOwnProperty(key)) continue;
                formData.append(key, this._passThrough[key]);
            }

            xhr.open(this._ajaxType, targetURL +
                ((this._ajaxType == "GET") ? "?" + this._formDataToURI(formData) : "")
                , true);

            xhr.timeout = this._timeout || 0;

            this._applyContentType(xhr);
            xhr.setRequestHeader(this._HEAD_FACES_REQ, this._VAL_AJAX);

            //some webkit based mobile browsers do not follow the w3c spec of
            // setting the accept headers automatically
            if(this._RT.browser.isWebKit) {
                xhr.setRequestHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
            }
            this._sendEvent("BEGIN");
            //Check if it is a custom form data object
            //if yes we use makefinal for the final handling
            if (formData && formData.makeFinal) {
                formData = formData.makeFinal()
            }
            xhr.send((this._ajaxType != "GET") ? formData : null);

        } catch (e) {
            //_onError//_onError
            e = (e._mfInternal)? e: this._Lang.makeException(new Error(), "sendError","sendError", this._nameSpace, "send", e.message);
            this._stdErrorHandler(this._xhr, this._context, e);
        }
    },

    /**
     * helper, in multipart situations we might alter the content type
     * from the urlencoded one
     */
    _applyContentType: function(xhr) {
        var contentType = this._contentType+"; charset=utf-8";

        xhr.setRequestHeader(this._CONTENT_TYPE, contentType);
    },

    ondone: function() {
        this._requestDone();
    },


    onsuccess: function(/*evt*/) {

        var context = this._context;
        var xhr = this._xhr;
        try {
            this._sendEvent("COMPLETE");
            //now we have to reroute into our official api
            //because users might want to decorate it, we will split it apart afterwards

            context._mfInternal = context._mfInternal || {};
            jsf.ajax.response((xhr.getXHRObject) ? xhr.getXHRObject() : xhr, context);



        } catch (e) {
            this._stdErrorHandler(this._xhr, this._context, e);
        }
        //add for xhr level2 support
        //}  finally {
        //W3C spec onloadend must be called no matter if success or not
        //    this.ondone();
        //}
    },

    onerror: function(/*evt*/) {
        //TODO improve the error code detection here regarding server errors etc...
        //and push it into our general error handling subframework
        var context = this._context;
        var xhr = this._xhr;
        var _Lang = this._Lang;

        var errorText = "";
        this._sendEvent("COMPLETE");
        try {
            var UNKNOWN = _Lang.getMessage("UNKNOWN");
            //status can be 0 and statusText can be ""
            var status = ('undefined' != xhr.status  && null != xhr.status)? xhr.status : UNKNOWN;
            var statusText = ('undefined' != xhr.statusText  && null != xhr.statusText)? xhr.statusText : UNKNOWN;
            errorText = _Lang.getMessage("ERR_REQU_FAILED", null,status,statusText);

        } catch (e) {
            errorText = _Lang.getMessage("ERR_REQ_FAILED_UNKNOWN", null);
        } finally {
            var _Impl = this.attr("impl");
            _Impl.sendError(xhr, context, _Impl.HTTPERROR,
                _Impl.HTTPERROR, errorText,"","myfaces._impl.xhrCore._AjaxRequest","onerror");
            //add for xhr level2 support
            //since chrome does not call properly the onloadend we have to do it manually
            //to eliminate xhr level1 for the compile profile modern
            //W3C spec onloadend must be called no matter if success or not
            //this.ondone();
        }
        //_onError
    },

    onprogress: function(/*evt*/) {
        //do nothing for now
    },

    ontimeout: function(/*evt*/) {
        try {
            //we issue an event not an error here before killing the xhr process
            this._sendEvent("TIMEOUT_EVENT");
            //timeout done we process the next in the queue
        } finally {
            this._requestDone();
        }
    },

    _formDataToURI: function(formData) {
        if (formData && formData.makeFinal) {
            formData = formData.makeFinal()
        }
        return formData;
    },

    /**
     * change for jsf 2.3 since we drop legacy browser support
     * there is no need anymore to support xhr level 1.
     * @returns {XMLHttpRequest} the transport object
     * @private
     */
    _getTransport: function() {
        return new XMLHttpRequest();
    },


    //----------------- backported from the base request --------------------------------
    //non abstract ones


    /**
     * Spec. 13.3.1
     * Collect and encode input elements.
     * Additionally the hidden element javax.faces.ViewState
     * Enhancement partial page submit
     *
     * @return  an element of formDataWrapper
     * which keeps the final Send Representation of the
     */
    getFormData : function() {
        var _AJAXUTIL = this._AJAXUTIL, myfacesOptions = this._context.myfaces, ret = null;



        if (!this._partialIdsArray || !this._partialIdsArray.length) {
            var _AJAXUTIL = this._AJAXUTIL, myfacesOptions = this._context.myfaces;
            return this._Lang.createFormDataDecorator(jsf.getViewState(this._sourceForm));
        } else {
            //now this is less performant but we have to call it to allow viewstate decoration
            ret = this._Lang.createFormDataDecorator(new Array());
            _AJAXUTIL.encodeSubmittableFields(ret, this._sourceForm, this._partialIdsArray);
            if (this._source && myfacesOptions && myfacesOptions.form)
                _AJAXUTIL.appendIssuingItem(this._source, ret);

        }
        return ret;

    },



    /**
     * Client error handlers which also in the long run route into our error queue
     * but also are able to deliver more meaningful messages
     * note, in case of an error all subsequent xhr requests are dropped
     * to get a clean state on things
     *
     * @param request the xhr request object
     * @param context the context holding all values for further processing
     * @param exception the embedded exception
     */
    _stdErrorHandler: function(request, context, exception) {
        var xhrQueue = this._xhrQueue;
        try {
            this.attr("impl").stdErrorHandler(request, context, exception);
        } finally {
            if (xhrQueue) {
                xhrQueue.cleanup();
            }
        }
    },

    _sendEvent: function(evtType) {
        var _Impl = this.attr("impl");
        _Impl.sendEvent(this._xhr, this._context, _Impl[evtType]);
    },

    _requestDone: function() {
        var queue = this._xhrQueue;
        if (queue) {
            queue.processQueue();
        }
        //ie6 helper cleanup
        delete this._context.source;

    }
});


/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @class
 * @name _AjaxResponse
 * @memberOf myfaces._impl.xhrCore
 * @extends myfaces._impl.core.Object
 * @description
 * This singleton is responsible for handling the standardized xml ajax response
 * Note: since the semantic processing can be handled about 90% in a functional
 * style we make this class stateless. Every state information is stored
 * temporarily in the context.
 *
 * The singleton approach also improves performance
 * due to less object gc compared to the old instance approach.
 *
 */
_MF_SINGLTN(_PFX_XHR + "_AjaxResponse", _MF_OBJECT, /** @lends myfaces._impl.xhrCore._AjaxResponse.prototype */ {

    /*partial response types*/
    RESP_PARTIAL: "partial-response",
    RESP_TYPE_ERROR: "error",
    RESP_TYPE_REDIRECT: "redirect",
    RESP_TYPE_CHANGES: "changes",

    /*partial commands*/
    CMD_CHANGES: "changes",
    CMD_UPDATE: "update",
    CMD_DELETE: "delete",
    CMD_INSERT: "insert",
    CMD_EVAL: "eval",
    CMD_ERROR: "error",
    CMD_ATTRIBUTES: "attributes",
    CMD_EXTENSION: "extension",
    CMD_REDIRECT: "redirect",

    /*other constants*/
    P_VIEWSTATE: "javax.faces.ViewState",
    P_CLIENTWINDOW: "javax.faces.ClientWindow",
    P_VIEWROOT: "javax.faces.ViewRoot",
    P_VIEWHEAD: "javax.faces.ViewHead",
    P_VIEWBODY: "javax.faces.ViewBody",
    P_RESOURCE: "javax.faces.Resource",

    /**
     * uses response to start Html element replacement
     *
     * @param {Object} request (xhrRequest) - xhr request object
     * @param {Object} context (Map) - AJAX context
     *
     * A special handling has to be added to the update cycle
     * according to the JSDoc specs if the CDATA block contains html tags the outer rim must be stripped
     * if the CDATA block contains a head section the document head must be replaced
     * and if the CDATA block contains a body section the document body must be replaced!
     *
     */
    processResponse: function (request, context) {
        //mfinternal handling, note, the mfinternal is only optional
        //according to the spec
        context._mfInternal = context._mfInternal || {};
        var mfInternal = context._mfInternal;

        //the temporary data is hosted here
        mfInternal._updateElems = [];
        mfInternal._updateForms = [];
        mfInternal.appliedViewState = null;
        mfInternal.appliedClientWindow = null;
        mfInternal.namingModeId = null;


        try {
            var _Impl = this.attr("impl"), _Lang = this._Lang;
            // TODO:
            // Solution from
            // http://www.codingforums.com/archive/index.php/t-47018.html
            // to solve IE error 1072896658 when a Java server sends iso88591
            // istead of ISO-8859-1

            if (!request || !_Lang.exists(request, "responseXML")) {
                throw this.makeException(new Error(), _Impl.EMPTY_RESPONSE, _Impl.EMPTY_RESPONSE, this._nameSpace, "processResponse", "");
            }
            //check for a parseError under certain browsers

            var xmlContent = request.responseXML;
            //ie6+ keeps the parsing response under xmlContent.parserError
            //while the rest of the world keeps it as element under the first node
            var xmlErr = _Lang.fetchXMLErrorMessage(request.responseText || request.response, xmlContent)
            if (xmlErr) {
                throw this._raiseError(new Error(), xmlErr.errorMessage + "\n" + xmlErr.sourceText + "\n" + xmlErr.visualError + "\n", "processResponse");
            }
            var partials = xmlContent.childNodes[0];
            if ('undefined' == typeof partials || partials == null) {
                throw this._raiseError(new Error(), "No child nodes for response", "processResponse");

            } else {
                if (partials.tagName != this.RESP_PARTIAL) {
                    // IE 8 sees XML Header as first sibling ...
                    partials = partials.nextSibling;
                    if (!partials || partials.tagName != this.RESP_PARTIAL) {
                        throw this._raiseError(new Error(), "Partial response not set", "processResponse");
                    }
                }
            }


            /**
             * jsf 2.3 naming mode partial response,
             * we either viewstate all forms (non id mode)
             * or the forms under the viewroot defined by id
             *
             * @type {string} ... the naming mode id is set or an empty string
             * definitely not a null value to avoid type confusions later on
             */
            mfInternal.namingModeId = (partials.id || "");


            var childNodesLength = partials.childNodes.length;

            for (var loop = 0; loop < childNodesLength; loop++) {
                var childNode = partials.childNodes[loop];
                var tagName = childNode.tagName;
                /**
                 * <eval>
                 *      <![CDATA[javascript]]>
                 * </eval>
                 */

                //this ought to be enough for eval
                //however the run scripts still makes sense
                //in the update and insert area for components
                //which do not use the response writer properly
                //we might add this one as custom option in update and
                //insert!
                if (tagName == this.CMD_ERROR) {
                    this.processError(request, context, childNode);
                } else if (tagName == this.CMD_REDIRECT) {
                    this.processRedirect(request, context, childNode);
                } else if (tagName == this.CMD_CHANGES) {
                    this.processChanges(request, context, childNode);
                }
            }

            //fixup missing viewStates due to spec deficiencies
            if (mfInternal.appliedViewState) {
                this.fixViewStates(context);
            }
            if (mfInternal.appliedClientWindow) {
                this.fixClientWindows(context);
            }

            //spec jsdoc, the success event must be sent from response
            _Impl.sendEvent(request, context, _Impl["SUCCESS"]);
        } catch (e) {

            if (window.console && window.console.error) {
                //any error should be logged
                console.error(e);
            }
            throw e;
        } finally {
            delete mfInternal._updateElems;
            delete mfInternal._updateForms;
            delete mfInternal.appliedViewState;
            delete mfInternal.appliedClientWindow;
            delete mfInternal.namingModeId;
        }
    },

    /**
     * fixes the viewstates in the current page
     *
     * @param context
     */
    fixViewStates: function (context) {
        var _Lang = this._Lang;
        var mfInternal = context._mfInternal;

        if (null == mfInternal.appliedViewState) {
            return;
        }

        /**
         * JSF 2.3 we set all the viewstates under a given declared viewRoot or all forms
         * if none is given
         */
        this._updateJSFClientArtifacts(context,  mfInternal.appliedViewState, this.P_VIEWSTATE);
    },


    fixClientWindows: function (context, theForm) {
        var _Lang = this._Lang;
        var mfInternal = context._mfInternal;

        if (null == mfInternal.appliedClientWindow) {
            return;
        }

        /**
         * JSF 2.3 we set all the viewstates under a given declared viewRoot or all forms
         * if none is given
         */

        this._updateJSFClientArtifacts(context, mfInternal.appliedClientWindow, this.P_CLIENTWINDOW);

    },


    /**
     * sets the a jsf artifact element with a given identifier to a new value or adds this element
     *
     * @param theForm {Node} the form to which the element has to be set to
     * @param context the current request context
     */
    _applyJSFArtifactValueToForm: function (context, theForm, value, identifier) {

        if (!theForm) return;
        var _Lang = this._Lang;
        var _Dom = this._Dom;
        var prefix = this._getPrefix(context);

        //in IE7 looking up form elements with complex names (such as 'javax.faces.ViewState') fails in certain cases
        //iterate through the form elements to find the element, instead
        var fieldsFound = [];

        var elements = theForm.elements;
        for (var i = 0, l = elements.length; i < l; i++) {
            var e = elements[i];
            //https://issues.apache.org/jira/browse/MYFACES-4230
            //ie11 has a deviation from the standard behavior, we have to remap the null/undefined name
            //to an empty string
            var eName = e.name || "";

            if (eName.indexOf(identifier) != -1) {
                fieldsFound.push(e);
            }
        }

        if (fieldsFound.length) {
            _Lang.arrForEach(fieldsFound, function (fieldFound) {
                _Dom.setAttribute(fieldFound, "value", value);
            });
        } else {
            var element = this._Dom.getDummyPlaceHolder();

            //per JSF 2.3 spec the identifier of the element must be unique in the dom tree
            //otherwise we will break the html spec here
            element.innerHTML = ["<input type='hidden'", "id='", this._fetchUniqueId(prefix, identifier), "' name='", identifier, "' value='", value, "' />"].join("");
            //now we go to proper dom handling after having to deal with another ie screw-up
            try {
                theForm.appendChild(element.childNodes[0]);
            } finally {
                element.innerHTML = "";
            }
        }
    },

    _fetchUniqueId: function(prefix, identifier) {
        var cnt = 0;
        var retVal = prefix + identifier + jsf.separatorchar + cnt;
        while(this._Dom.byId(retVal) != null) {
            cnt++;
            retVal = prefix + identifier + jsf.separatorchar + cnt;
        }
        return retVal;
    },

    /**
     * updates/inserts the jsf client artifacts under a given viewroot element
     *
     * @param context the client context holding all request context data and some internal data
     * @param elem the root to start with, must be a dom node not an identifier
     * @param value the new value
     * @param identifier the identifier for the client artifact aka javax.faces.ViewState, ClientWindowId etc...
     *
     * @private
     */
    _updateJSFClientArtifacts: function (context, value, identifier) {

        //elem not found for whatever reason
        //https://issues.apache.org/jira/browse/MYFACES-3544

        var prefix = this._getPrefix(context);

        //do we still need the issuing form update? I guess it is needed.
        //jsf spec 2.3 and earlier all issuing forms must update
        var sourceForm = (context._mfInternal._mfSourceFormId) ? this._Dom.byId(context._mfInternal._mfSourceFormId) : null;
        if (sourceForm) {
            sourceForm = this._Dom.byId(sourceForm);
            if (sourceForm) {
                //some cases where the source form cannot be updated
                //because it is gone
                this._applyJSFArtifactValueToForm(context, sourceForm, value, identifier);
            }
        }



        var viewRoot = this._getViewRoot(context);
        var forms = this._Dom.findByTagNames(viewRoot, {"form": 1}) || [];

        //since the spec thanks to the over intrusive portlet api still is broken
        //we need our old fallback hack for proper handling without having
        //to deal with multiple render targets.


        if(this._RT.getLocalOrGlobalConfig(context, "no_portlet_env", false)) {

            //We update all elements under viewroot
            //this clearly violates the jsf 2.3 jsdocs
            //however I think that the jsdocs were sloppily updated
            //because just updating the render targets under one viewroot and the issuing form
            //again would leave broken viewstates, in the end the portlet spec is at fault here
            //which came late to the game and expected all frameworks to adapt to their needs.
            //instead of properly adapting to the frameworks
            //now the viewroot mechanism per se would work, but people are dropping
            //jsf 2.3 into old portlet containers which then expose the legacy behavior
            //of having just one view root.
            this._Lang.arrForEach(forms, this._Lang.hitch(this, function (elem) {
                //update all forms which start with prefix (all render and execute targets
                this._applyJSFArtifactValueToForm(context, elem, value, identifier);
            }));
        } else {


            //check for a portlet condition a present viewroot

            var viewRootId = viewRoot.id || "";

            for(var cnt = 0; cnt < context._mfInternal._updateForms.length; cnt++) {
                var updateForm = context._mfInternal._updateForms[cnt];

                //follow the spec 2.3 path 1:1 we update the forms hosting the render targets which start
                //with the viewroot
                //if there is a viewroot present, however we seem to have a bug in myfaces
                //even if we have a naming container response we
                //cannot rely on the naming container being prefixed

                //This atm is not bad, because we safely can assume
                //that if no viewroot can be found we are under
                //one single viewroot and can omit the prefix check
                //(aka fallback into the old behavior)


                if(updateForm.indexOf(viewRootId) != 0) {
                    continue;
                } else { //either an empty viewroot, or a namespace match
                    this._applyJSFArtifactValueToForm(context, this._Dom.byId(updateForm), value, identifier);
                }
            }

        }

    },

    _getViewRoot: function (context) {
        var prefix = this._getPrefix(context);
        if (prefix == "") {
            return document.getElementsByTagName("body")[0];
        }
        prefix = prefix.substr(0, prefix.length - 1);
        var viewRoot = document.getElementById(prefix);
        if (viewRoot) {
            return viewRoot;
        }
        return document.getElementsByTagName("body")[0];
    },


    _getPrefix: function (context) {
        var mfInternal = context._mfInternal;
        var prefix = mfInternal.namingModeId;
        if (prefix != "") {
            prefix = prefix + jsf.separatorchar;
        }
        return prefix;
    },

    /**
     * processes an incoming error from the response
     * which is hosted under the &lt;error&gt; tag
     * @param request the current request
     * @param context the contect object
     * @param node the node in the xml hosting the error message
     */
    processError: function (request, context, node) {
        /**
         * <error>
         *      <error-name>String</error-name>
         *      <error-message><![CDATA[message]]></error-message>
         * <error>
         */
        var errorName = node.firstChild.textContent || node.firstChild.text || "",
            errorMessage = node.childNodes[1].firstChild.data || "";

        this.attr("impl").sendError(request, context, this.attr("impl").SERVER_ERROR, errorName, errorMessage, "myfaces._impl.xhrCore._AjaxResponse", "processError");
    },

    /**
     * processes an incoming xml redirect directive from the ajax response
     * @param request the request object
     * @param context the context
     * @param node the node hosting the redirect data
     */
    processRedirect: function (request, context, node) {
        /**
         * <redirect url="url to redirect" />
         */
        var _Lang = this._Lang;
        var redirectUrl = node.getAttribute("url");
        if (!redirectUrl) {
            throw this._raiseError(new Error(), _Lang.getMessage("ERR_RED_URL", null, "_AjaxResponse.processRedirect"), "processRedirect");
        }
        redirectUrl = _Lang.trim(redirectUrl);
        if (redirectUrl == "") {
            return false;
        }
        window.location = redirectUrl;
        return true;
    }
    ,

    /**
     * main entry point for processing the changes
     * it deals with the &lt;changes&gt; node of the
     * response
     *
     * @param request the xhr request object
     * @param context the context map
     * @param node the changes node to be processed
     */
    processChanges: function (request, context, node) {
        var changes = node.childNodes;
        var _Lang = this._Lang;
        //note we need to trace the changes which could affect our insert update or delete
        //se that we can realign our ViewStates afterwards
        //the realignment must happen post change processing

        for (var i = 0; i < changes.length; i++) {

            switch (changes[i].tagName) {

                case this.CMD_UPDATE:
                    this.processUpdate(request, context, changes[i]);
                    break;
                //this one needs a csp spec extension for the global eval
                //for now we recycle the csp for this case from the jsf.js file
                case this.CMD_EVAL:
                    _Lang.globalEval(changes[i].firstChild.data);
                    break;
                case this.CMD_INSERT:
                    this.processInsert(request, context, changes[i]);
                    break;
                case this.CMD_DELETE:
                    this.processDelete(request, context, changes[i]);
                    break;
                case this.CMD_ATTRIBUTES:
                    this.processAttributes(request, context, changes[i]);
                    break;
                case this.CMD_EXTENSION:
                    break;
                case undefined:
                    // ignoring white spaces
                    break;
                default:
                    throw this._raiseError(new Error(), "_AjaxResponse.processChanges: Illegal Command Issued", "processChanges");
            }
        }

        return true;
    },

    /**
     * First sub-step process a pending update tag
     *
     * @param request the xhr request object
     * @param context the context map
     * @param node the changes node to be processed
     */
    processUpdate: function (request, context, node) {
        var mfInternal = context._mfInternal;
        if ((node.getAttribute('id').indexOf(this.P_VIEWSTATE) != -1) || (node.getAttribute('id').indexOf(this.P_CLIENTWINDOW) != -1)) {
            if (node.getAttribute('id').indexOf(this.P_VIEWSTATE) != -1) {
// begin TOBAGO-JSF-JS
                mfInternal.appliedViewState = this._Lang.trim(this._Dom.concatCDATABlocks(node));
/* original
                mfInternal.appliedViewState = this._Dom.concatCDATABlocks(node);//node.firstChild.nodeValue;
*/
// end TOBAGO-JSF-JS
                            } else if (node.getAttribute('id').indexOf(this.P_CLIENTWINDOW) != -1) {
                                mfInternal.appliedClientWindow = node.firstChild.nodeValue;
                            }
                        }
                        else {
                            // response may contain several blocks
                            var cDataBlock = this._Dom.concatCDATABlocks(node),
                                resultNode = null,
                                pushOpRes = this._Lang.hitch(this, this._pushOperationResult);

// begin TOBAGO-JSF-JS
                          if (cDataBlock.startsWith("{\"reload\"")) {
                            console.debug("Found reload-JSON in response!");
                          } else {
// end TOBAGO-JSF-JS
                            switch (node.getAttribute('id')) {
                                case this.P_VIEWROOT:

                                    cDataBlock = cDataBlock.substring(cDataBlock.indexOf("<html"));

                                    var parsedData = this._replaceHead(request, context, cDataBlock);

                                    ('undefined' != typeof parsedData && null != parsedData) ? this._replaceBody(request, context, cDataBlock, parsedData) : this._replaceBody(request, context, cDataBlock);

                                    break;
                                case this.P_VIEWHEAD:
                                    //we cannot replace the head, almost no browser allows this, some of them throw errors
                                    //others simply ignore it or replace it and destroy the dom that way!
                                    this._replaceHead(request, context, cDataBlock);

                                    break;
                                case this.P_VIEWBODY:
                                    //we assume the cdata block is our body including the tag
                                    resultNode = this._replaceBody(request, context, cDataBlock);
                                    if (resultNode) {
                                        pushOpRes(context, resultNode);
                                    }
                                    break;
                                case this.P_RESOURCE:

                                    this._addResourceToHead(request, context, cDataBlock);
                                    break;
                                default:

// begin TOBAGO-JSF-JS
// XXX hack
                                    if (node.id === document.getElementsByTagName("tobago-page")[0].id) {
                                        // newDoc = document.open("text/html", "replace");
                                        // newDoc.write(cDataBlock);
                                        // newDoc.close();
                                        //change only the body, because change the head doesn't work with CSP
                                        var newPage = jQuery(cDataBlock).filter("tobago-page");
                                        jQuery("tobago-page").replaceWith(newPage);
                                        // XXX remove jQuery
                                        resultNode = document.documentElement;
                                    } else {
                                        resultNode = this.replaceHtmlItem(request, context, node.getAttribute('id'), cDataBlock);
                                    }
/* original
                                    resultNode = this.replaceHtmlItem(request, context, node.getAttribute('id'), cDataBlock);
*/
// end TOBAGO-JSF-JS
                                    if (resultNode) {
                                        pushOpRes(context, resultNode);
                                    }
                                    break;
                            }
// begin TOBAGO-JSF-JS
                          }
// end TOBAGO-JSF-JS
                        }

                        return true;
                    },

                    _pushOperationResult: function(context, resultNode) {
                        var mfInternal = context._mfInternal;
                        var pushSubnode = this._Lang.hitch(this, function(currNode) {
                            var parentForm = this._Dom.getParent(currNode, "form");
                            //if possible we work over the ids
                            //so that elements later replaced are referenced
                            //at the latest possibility
                            if (null != parentForm) {
                                mfInternal._updateForms.push(parentForm.id || parentForm);
                            }
                            else {
                                mfInternal._updateElems.push(currNode.id || currNode);
                            }
                        });

                        var pushEmbedded = this._Lang.hitch(this, function(currNode) {
                            if(currNode.tagName && this._Lang.equalsIgnoreCase(currNode.tagName, "form")) {
                                if(currNode.id)  { //should not happen but just in case someone manipulates the html
                                    mfInternal._updateForms.push(currNode.id);
                                }
                            } else {
                                var childForms = this._Dom.findByTagName(currNode, "form");
                                if(childForms && childForms.length) {
                                    for(var cnt = 0; cnt < childForms.length; cnt++) {
                                        if(childForms[cnt].id) {
                                            mfInternal._updateForms.push(childForms[cnt].id);
                                        }
                                    }
                                }
                            }

                        });


                        var isArr = 'undefined' != typeof resultNode.length && 'undefined' == typeof resultNode.nodeType;
                        if (isArr && resultNode.length) {
                            for (var cnt = 0; cnt < resultNode.length; cnt++) {
                                pushSubnode(resultNode[cnt]);
                                pushEmbedded(resultNode[cnt]);
                            }
                        } else if (!isArr) {
                            pushSubnode(resultNode);
                            pushEmbedded(resultNode);
                        }

                    },


                    /**
                     * replaces a current head theoretically,
                     * pratically only the scripts are evaled anew since nothing else
                     * can be changed.
                     *
                     * @param request the current request
                     * @param context the ajax context
                     * @param newData the data to be processed
                     *
                     * @return an xml representation of the page for further processing if possible
                     */
    _replaceHead: function (request, context, newData) {

        var _Lang = this._Lang,
            _Dom = this._Dom,
            isWebkit = this._RT.browser.isWebKit,
            //we have to work around an xml parsing bug in Webkit
            //see https://issues.apache.org/jira/browse/MYFACES-3061
            doc = (!isWebkit) ? _Lang.parseXML(newData) : null,
            newHead = null;

        if (!isWebkit && _Lang.isXMLParseError(doc)) {
            doc = _Lang.parseXML(newData.replace(/<!\-\-[\s\n]*<!\-\-/g, "<!--").replace(/\/\/-->[\s\n]*\/\/-->/g, "//-->"));
        }

        if (isWebkit || _Lang.isXMLParseError(doc)) {
            //the standard xml parser failed we retry with the stripper
            var parser = new (this._RT.getGlobalConfig("updateParser", myfaces._impl._util._HtmlStripper))();
            var headData = parser.parse(newData, "head");
            //We cannot avoid it here, but we have reduced the parsing now down to the bare minimum
            //for further processing
            newHead = _Lang.parseXML("<head>" + headData + "</head>");
            //last and slowest option create a new head element and let the browser
            //do its slow job
            if (_Lang.isXMLParseError(newHead)) {
                try {
                    newHead = _Dom.createElement("head");
                    newHead.innerHTML = headData;
                } catch (e) {
                    //we give up no further fallbacks
                    throw this._raiseError(new Error(), "Error head replacement failed reason:" + e.toString(), "_replaceHead");
                }
            }
        } else {
            //parser worked we go on
            newHead = doc.getElementsByTagName("head")[0];
        }

        var oldTags = _Dom.findByTagNames(document.getElementsByTagName("head")[0], {"link": true, "style": true});
        _Dom.runCss(newHead, true);
        _Dom.deleteItems(oldTags);

        //var oldTags = _Dom.findByTagNames(document.getElementsByTagName("head")[0], {"script": true});
        //_Dom.deleteScripts(oldTags);
        _Dom.runScripts(newHead, true);

        return doc;
    },

    _addResourceToHead: function (request, context, newData) {
        var lastHeadChildTag = document.getElementsByTagName("head")[0].lastChild;

        this._Dom.insertAfter(lastHeadChildTag, newData);

    },

    /**
     * special method to handle the body dom manipulation,
     * replacing the entire body does not work fully by simply adding a second body
     * and by creating a range instead we have to work around that by dom creating a second
     * body and then filling it properly!
     *
     * @param {Object} request our request object
     * @param {Object} context (Map) the response context
     * @param {String} newData the markup which replaces the old dom node!
     * @param {Node} parsedData (optional) preparsed XML representation data of the current document
     */
    _replaceBody: function (request, context, newData /*varargs*/) {
        var _RT = this._RT,
            _Dom = this._Dom,
            _Lang = this._Lang,

            oldBody = document.getElementsByTagName("body")[0],
            placeHolder = document.createElement("div"),
            isWebkit = _RT.browser.isWebKit;

        placeHolder.id = "myfaces_bodyplaceholder";

        _Dom._removeChildNodes(oldBody);
        oldBody.innerHTML = "";
        oldBody.appendChild(placeHolder);

        var bodyData, doc = null, parser;

        //we have to work around an xml parsing bug in Webkit
        //see https://issues.apache.org/jira/browse/MYFACES-3061
        if (!isWebkit) {
            doc = (arguments.length > 3) ? arguments[3] : _Lang.parseXML(newData);
        }

        if (!isWebkit && _Lang.isXMLParseError(doc)) {
            doc = _Lang.parseXML(newData.replace(/<!\-\-[\s\n]*<!\-\-/g, "<!--").replace(/\/\/-->[\s\n]*\/\/-->/g, "//-->"));
        }

        if (isWebkit || _Lang.isXMLParseError(doc)) {
            //the standard xml parser failed we retry with the stripper

            parser = new (_RT.getGlobalConfig("updateParser", myfaces._impl._util._HtmlStripper))();

            bodyData = parser.parse(newData, "body");
        } else {
            //parser worked we go on
            var newBodyData = doc.getElementsByTagName("body")[0];

            //speedwise we serialize back into the code
            //for code reduction, speedwise we will take a small hit
            //there which we will clean up in the future, but for now
            //this is ok, I guess, since replace body only is a small subcase
            //bodyData = _Lang.serializeChilds(newBodyData);
            var browser = _RT.browser;
            if (!browser.isIEMobile || browser.isIEMobile >= 7) {
                //TODO check what is failing there
                for (var cnt = 0; cnt < newBodyData.attributes.length; cnt++) {
                    var value = newBodyData.attributes[cnt].value;
                    if (value)
                        _Dom.setAttribute(oldBody, newBodyData.attributes[cnt].name, value);
                }
            }
        }
        //we cannot serialize here, due to escape problems
        //we must parse, this is somewhat unsafe but should be safe enough
        parser = new (_RT.getGlobalConfig("updateParser", myfaces._impl._util._HtmlStripper))();
        bodyData = parser.parse(newData, "body");

        var returnedElement = this.replaceHtmlItem(request, context, placeHolder, bodyData);

        if (returnedElement) {
            this._pushOperationResult(context, returnedElement);
        }
        return returnedElement;
    },

    /**
     * Replaces HTML elements through others and handle errors if the occur in the replacement part
     *
     * @param {Object} request (xhrRequest)
     * @param {Object} context (Map)
     * @param {Object} itemIdToReplace (String|Node) - ID of the element to replace
     * @param {String} markup - the new tag
     */
    replaceHtmlItem: function (request, context, itemIdToReplace, markup) {
        var _Lang = this._Lang, _Dom = this._Dom;

        var item = (!_Lang.isString(itemIdToReplace)) ? itemIdToReplace :
            _Dom.byIdOrName(itemIdToReplace);

        if (!item) {
            throw this._raiseError(new Error(), _Lang.getMessage("ERR_ITEM_ID_NOTFOUND", null, "_AjaxResponse.replaceHtmlItem", (itemIdToReplace) ? itemIdToReplace.toString() : "undefined"), "replaceHtmlItem");
        }
        return _Dom.outerHTML(item, markup, this._RT.getLocalOrGlobalConfig(context, "preserveFocus", false));
    },

    /**
     * xml insert command handler
     *
     * @param request the ajax request element
     * @param context the context element holding the data
     * @param node the xml node holding the insert data
     * @return true upon successful completion, false otherwise
     *
     **/
    processInsert: function (request, context, node) {
        /*remapping global namespaces for speed and readability reasons*/
        var _Dom = this._Dom,
            _Lang = this._Lang,
            //determine which path to go:
            insertData = this._parseInsertData(request, context, node);

        if (!insertData) return false;

        var opNode = _Dom.byIdOrName(insertData.opId);
        if (!opNode) {
            throw this._raiseError(new Error(), _Lang.getMessage("ERR_PPR_INSERTBEFID_1", null, "_AjaxResponse.processInsert", insertData.opId), "processInsert");
        }

        //call insertBefore or insertAfter in our dom routines
        var replacementFragment = _Dom[insertData.insertType](opNode, insertData.cDataBlock);
        if (replacementFragment) {
            this._pushOperationResult(context, replacementFragment);
        }
        return true;
    },

    /**
     * determines the corner data from the insert tag parsing process
     *
     *
     * @param request request
     * @param context context
     * @param node the current node pointing to the insert tag
     * @return false if the parsing failed, otherwise a map with follwing attributes
     * <ul>
     *     <li>inserType - a ponter to a constant which maps the direct function name for the insert operation </li>
     *     <li>opId - the before or after id </li>
     *     <li>cDataBlock - the html cdata block which needs replacement </li>
     * </ul>
     *
     * TODO we have to find a mechanism to replace the direct sendError calls with a javascript exception
     * which we then can use for cleaner error code handling
     */
    _parseInsertData: function (request, context, node) {
        var _Lang = this._Lang,
            _Dom = this._Dom,
            concatCDATA = _Dom.concatCDATABlocks,

            INSERT_TYPE_BEFORE = "insertBefore",
            INSERT_TYPE_AFTER = "insertAfter",

            id = node.getAttribute("id"),
            beforeId = node.getAttribute("before"),
            afterId = node.getAttribute("after"),
            ret = {};

        //now we have to make a distinction between two different parsing paths
        //due to a spec malalignment
        //a <insert id="... beforeId|AfterId ="...
        //b <insert><before id="..., <insert> <after id="....
        //see https://issues.apache.org/jira/browse/MYFACES-3318
        //simple id, case1
        if (id && beforeId && !afterId) {
            ret.insertType = INSERT_TYPE_BEFORE;
            ret.opId = beforeId;
            ret.cDataBlock = concatCDATA(node);

            //<insert id=".. afterId="..
        } else if (id && !beforeId && afterId) {
            ret.insertType = INSERT_TYPE_AFTER;
            ret.opId = afterId;
            ret.cDataBlock = concatCDATA(node);

            //<insert><before id="... <insert><after id="...
        } else if (!id) {
            var opType = node.childNodes[0].tagName;

            if (opType != "before" && opType != "after") {
                throw this._raiseError(new Error(), _Lang.getMessage("ERR_PPR_INSERTBEFID"), "_parseInsertData");
            }
            opType = opType.toLowerCase();
            var beforeAfterId = node.childNodes[0].getAttribute("id");
            ret.insertType = (opType == "before") ? INSERT_TYPE_BEFORE : INSERT_TYPE_AFTER;
            ret.opId = beforeAfterId;
            ret.cDataBlock = concatCDATA(node.childNodes[0]);
        } else {
            throw this._raiseError(new Error(), [_Lang.getMessage("ERR_PPR_IDREQ"),
                "\n ",
                _Lang.getMessage("ERR_PPR_INSERTBEFID")].join(""), "_parseInsertData");
        }
        ret.opId = _Lang.trim(ret.opId);
        return ret;
    },

    processDelete: function (request, context, node) {

        var _Lang = this._Lang,
            _Dom = this._Dom,
            deleteId = node.getAttribute('id');

        if (!deleteId) {
            throw this._raiseError(new Error(), _Lang.getMessage("ERR_PPR_UNKNOWNCID", null, "_AjaxResponse.processDelete", ""), "processDelete");
        }

        var item = _Dom.byIdOrName(deleteId);
        if (!item) {
            throw this._raiseError(new Error(), _Lang.getMessage("ERR_PPR_UNKNOWNCID", null, "_AjaxResponse.processDelete", deleteId), "processDelete");
        }

        var parentForm = this._Dom.getParent(item, "form");
        if (null != parentForm) {
            context._mfInternal._updateForms.push(parentForm);
        }
        _Dom.deleteItem(item);

        return true;
    },

    processAttributes: function (request, context, node) {
        //we now route into our attributes function to bypass
        //IE quirks mode incompatibilities to the biggest possible extent
        //most browsers just have to do a setAttributes but IE
        //behaves as usual not like the official standard
        //myfaces._impl._util.this._Dom.setAttribute(domNode, attribute, value;

        var _Lang = this._Lang,
            //<attributes id="id of element"> <attribute name="attribute name" value="attribute value" />* </attributes>
            elemId = node.getAttribute('id');

        if (!elemId) {
            throw this._raiseError(new Error(), "Error in attributes, id not in xml markup", "processAttributes");
        }
        var childNodes = node.childNodes;

        if (!childNodes) {
            return false;
        }
        for (var loop2 = 0; loop2 < childNodes.length; loop2++) {
            var attributesNode = childNodes[loop2],
                attrName = attributesNode.getAttribute("name"),
                attrValue = attributesNode.getAttribute("value");

            if (!attrName) {
                continue;
            }

            attrName = _Lang.trim(attrName);
            /*no value means reset*/
            //value can be of boolean value hence full check
            if ('undefined' == typeof attrValue || null == attrValue) {
                attrValue = "";
            }

            switch (elemId) {
                case this.P_VIEWROOT:
                    throw  this._raiseError(new Error(), _Lang.getMessage("ERR_NO_VIEWROOTATTR", null, "_AjaxResponse.processAttributes"), "processAttributes");

                case this.P_VIEWHEAD:
                    throw  this._raiseError(new Error(), _Lang.getMessage("ERR_NO_HEADATTR", null, "_AjaxResponse.processAttributes"), "processAttributes");

                case this.P_VIEWBODY:
                    var element = document.getElementsByTagName("body")[0];
                    this._Dom.setAttribute(element, attrName, attrValue);
                    break;

                default:
                    this._Dom.setAttribute(document.getElementById(elemId), attrName, attrValue);
                    break;
            }
        }
        return true;
    },

    /**
     * internal helper which raises an error in the
     * format we need for further processing
     *
     * @param message the message
     * @param title the title of the error (optional)
     * @param name the name of the error (optional)
     */
    _raiseError: function (error, message, caller, title, name) {
        var _Impl = this.attr("impl");
        var finalTitle = title || _Impl.MALFORMEDXML;
        var finalName = name || _Impl.MALFORMEDXML;
        var finalMessage = message || "";

        return this._Lang.makeException(error, finalTitle, finalName, this._nameSpace, caller || ( (arguments.caller) ? arguments.caller.toString() : "_raiseError"), finalMessage);
    }
});

/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @class
 * @name _Transports
 * @memberOf myfaces._impl.xhrCore
 * @description
 *
 * The xhr core adapter
 * which provides the transport mechanisms to the calling
 * objects, and controls the queue behavior, the error handling
 * and partial page submit functionality among other things
 * <p />
 * The idea behind this is to make the ajax request object as barebones
 * as possible and shift the extra functionality like queuing
 * parameter handling etc... to this class so that our transports become more easily
 * pluggable. This should keep the path open to iframe submits and other transport layers
 * <p />
 * the call to the corresponding transport just should be a
 * transport.xhrQueuedPost <br />
 * or transport.xhrPost,transport.xhrGet  etc... in the future
 * <p />
 * Note we have taken a pattern lesson or two from the dojo toolkit and its excellent handling
 * of transports by our patterns here (which is mainly a centralized transport singleton which routes
 * to different transport implementations and the auto passing of parameters into their
 * corresponding protected attributes on class level in the transports themselves)
 */
_MF_SINGLTN(_PFX_XHR + "_Transports", _MF_OBJECT,
    /** @lends myfaces._impl.xhrCore._Transports.prototype */ {

        _PAR_ERRORLEVEL: "errorlevel",
        _PAR_QUEUESIZE: "queuesize",
        _PAR_PPS: "pps",
        _PAR_TIMEOUT: "timeout",
        _PAR_DELAY: "delay",


        /**
         * a singleton queue
         * note the structure of our inheritance
         * is that that _queue is attached to prototype
         * and hence the pointer to the request qeue
         * is shared over all instances
         *
         * if you need to have it per instance for complex objects
         * you have to initialize in the constructor
         *
         * (This is the same limitation dojo class inheritance
         * where our inheritance pattern is derived from has)
         */
        _q: new myfaces._impl.xhrCore._AjaxRequestQueue(),

        /**
         * xhr post with enqueuing as defined by the jsf 2.0 specification
         *
         * mapped options already have the exec and view properly in place
         * myfaces specifics can be found under mappedOptions.myFaces
         * @param {Node} source the source of this call
         * @param {Node} sourceForm the html form which is the source of this call
         * @param {Object} context (Map) the internal pass through context
         * @param {Object} passThrgh (Map) values to be passed through
         **/
        xhrQueuedPost: function (source, sourceForm, context, passThrgh) {
            this._q.enqueue(
                new (this._getAjaxReqClass(context))(this._getArguments(source, sourceForm, context, passThrgh)));
        },


        /**
         * a simple not enqueued xhr post
         *
         * mapped options already have the exec and view properly in place
         * myfaces specifics can be found under mappedOptions.myFaces
         * @param {Node} source the source of this call
         * @param {Node} sourceForm the html form which is the source of this call
         * @param {Object} context (Map) the internal pass through context
         * @param {Object} passThrgh (Map) values to be passed through
         **/
        xhrPost: function (source, sourceForm, context, passThrgh) {
            var args = this._getArguments(source, sourceForm, context, passThrgh);
            delete args.xhrQueue;
            (new (this._getAjaxReqClass(context))(args)).send();
        },


        /**
         * xhr get without enqueuing
         *
         * mapped options already have the exec and view properly in place
         * myfaces specifics can be found under mappedOptions.myFaces
         * @param {Node} source the source of this call
         * @param {Node} sourceForm the html form which is the source of this call
         * @param {Object} context (Map) the internal pass through context
         * @param {Object} passThrgh (Map) values to be passed through
         **/
        xhrGet: function (source, sourceForm, context, passThrgh) {
            var args = this._getArguments(source, sourceForm, context, passThrgh);
            // note in get the timeout is not working delay however is and queue size as well
            // since there are no cross browser ways to resolve a timeout on xhr level
            // we have to live with it
            args.ajaxType = "GET";
            delete args.xhrQueue;
            (new (this._getAjaxReqClass(context))(args)).send();
        },

        /**
         * xhr get which takes the existing queue into consideration to by synchronized
         * to previous queued post requests
         *
         * mapped options already have the exec and view properly in place
         * myfaces specifics can be found under mappedOptions.myFaces
         * @param {Node} source the source of this call
         * @param {Node} sourceForm the html form which is the source of this call
         * @param {Object} context (Map) the internal pass through context
         * @param {Object} passThrgh (Map) values to be passed through
         **/
        xhrQueuedGet: function (source, sourceForm, context, passThrgh) {
            var args = this._getArguments(source, sourceForm, context, passThrgh);
            // note in get the timeout is not working delay however is and queue size as well
            // since there are no cross browser ways to resolve a timeout on xhr level
            // we have to live with it
            args.ajaxType = "GET";
            this._q.enqueue(
                new (this._getAjaxReqClass(context))(args));
        },


        /**
         * multipart post without queueing
         *
         * mapped options already have the exec and view properly in place
         * myfaces specifics can be found under mappedOptions.myFaces
         * @param {Node} source the source of this call
         * @param {Node} sourceForm the html form which is the source of this call
         * @param {Object} context (Map) the internal pass through context
         * @param {Object} passThrgh (Map) values to be passed through
         **/
        multipartPost: function (source, sourceForm, context, passThrgh) {
            var args = this._getArguments(source, sourceForm, context, passThrgh);
            // note in get the timeout is not working delay however is and queue size as well
            // since there are no cross browser ways to resolve a timeout on xhr level
            // we have to live with it
            delete args.xhrQueue;
            (new (this._getMultipartReqClass(context))(args)).send();
        },

        /**
         * multipart queued post
         *
         * mapped options already have the exec and view properly in place
         * myfaces specifics can be found under mappedOptions.myFaces
         * @param {Node} source the source of this call
         * @param {Node} sourceForm the html form which is the source of this call
         * @param {Object} context (Map) the internal pass through context
         * @param {Object} passThrgh (Map) values to be passed through
         **/
        multipartQueuedPost: function (source, sourceForm, context, passThrgh) {
            var args = this._getArguments(source, sourceForm, context, passThrgh);
            // note in get the timeout is not working delay however is and queue size as well
            // since there are no cross browser ways to resolve a timeout on xhr level
            this._q.enqueue(
                new (this._getMultipartReqClass(context))(args));
        },

        /**
         * iframe get without queueing
         *
         * mapped options already have the exec and view properly in place
         * myfaces specifics can be found under mappedOptions.myFaces
         * @param {Node} source the source of this call
         * @param {Node} sourceForm the html form which is the source of this call
         * @param {Object} context (Map) the internal pass through context
         * @param {Object} passThrgh (Map) values to be passed through
         **/
        multipartGet: function (source, sourceForm, context, passThrgh) {
            var args = this._getArguments(source, sourceForm, context, passThrgh);
            // note in get the timeout is not working delay however is and queue size as well
            // since there are no cross browser ways to resolve a timeout on xhr level
            // we have to live with it
            args.ajaxType = "GET";
            delete args.xhrQueue;
            (new (this._getMultipartReqClass(context))(args)).send();
        },

        /**
         * multipart queued http get
         *
         * mapped options already have the exec and view properly in place
         * myfaces specifics can be found under mappedOptions.myFaces
         * @param {Node} source the source of this call
         * @param {Node} sourceForm the html form which is the source of this call
         * @param {Object} context (Map) the internal pass through context
         * @param {Object} passThrgh (Map) values to be passed through
         **/
        multipartQueuedGet: function (source, sourceForm, context, passThrgh) {
            var args = this._getArguments(source, sourceForm, context, passThrgh);
            // note in get the timeout is not working delay however is and queue size as well
            // since there are no cross browser ways to resolve a timeout on xhr level
            args.ajaxType = "GET";
            this._q.enqueue(
                new (this._getMultipartReqClass(context))(args));
        },


        /**
         * creates the arguments map and
         * fetches the config params in a proper way in to
         * deal with them in a flat way (from the nested context way)
         *
         * @param source the source of the request
         * @param sourceForm the sourceform
         * @param context   the context holding all values
         * @param passThrgh the passThrough values to be blended into the response
         */
        _getArguments: function (source, sourceForm, context, passThrgh) {
            var _RT = myfaces._impl.core._Runtime,
                /** @ignore */
                _Lang = myfaces._impl._util._Lang,
                applyCfg = _Lang.hitch(this, this._applyConfig),
                //RT does not have this references, hence no hitch needed
                getCfg = _RT.getLocalOrGlobalConfig,


                ret = {
                    "source": source,
                    "sourceForm": sourceForm,
                    "context": context,
                    "passThrough": passThrgh,
                    "xhrQueue": this._q
                };

            //we now mix in the config settings which might either be set globally
            //or pushed in under the context myfaces.<contextValue> into the current request
            applyCfg(ret, context, "alarmThreshold", this._PAR_ERRORLEVEL);
            applyCfg(ret, context, "queueSize", this._PAR_QUEUESIZE);
            //TODO timeout probably not needed anymore
            applyCfg(ret, context, "timeout", this._PAR_TIMEOUT);
            //applyCfg(ret, context, "delay", this._PAR_DELAY);

            //now partial page submit needs a different treatment
            //since pps == execute strings
            if (getCfg(context, this._PAR_PPS, false)
                && _Lang.exists(passThrgh, myfaces._impl.core.Impl.P_EXECUTE)
                && passThrgh[myfaces._impl.core.Impl.P_EXECUTE].length > 0) {
                ret['partialIdsArray'] = passThrgh[myfaces._impl.core.Impl.P_EXECUTE].split(" ");
            }
            return ret;
        },

        /**
         * helper method to apply a config setting to our varargs param list
         *
         * @param destination the destination map to receive the setting
         * @param context the current context
         * @param destParm the destination param of the destination map
         * @param srcParm the source param which is the key to our config setting
         */
        _applyConfig: function (destination, context, destParm, srcParm) {
            var _RT = myfaces._impl.core._Runtime;
            /** @ignore */
            var _getConfig = _RT.getLocalOrGlobalConfig;
            if (_getConfig(context, srcParm, null) != null) {
                destination[destParm] = _getConfig(context, srcParm, null);
            }
        },

        /**
         * centralized transport switching helper
         * for the multipart submit case
         *
         * @param context the context which is passed down
         */
        _getMultipartReqClass: function (context) {
            return myfaces._impl.xhrCore._FormDataRequest;
        },


        _getAjaxReqClass: function (context) {
            return myfaces._impl.xhrCore._AjaxRequest;
        }

    });

/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @class
 * @name Impl
 * @memberOf myfaces._impl.core
 * @description Implementation singleton which implements all interface method
 * defined by our jsf.js API
 * */
_MF_SINGLTN(_PFX_CORE + "Impl", _MF_OBJECT, /**  @lends myfaces._impl.core.Impl.prototype */ {

    //third option myfaces._impl.xhrCoreAjax which will be the new core impl for now
    _transport:myfaces._impl.core._Runtime.getGlobalConfig("transport", myfaces._impl.xhrCore._Transports),

    /**
     * external event listener queue!
     */
    _evtListeners:new (myfaces._impl.core._Runtime.getGlobalConfig("eventListenerQueue", myfaces._impl._util._ListenerQueue))(),

    /**
     * external error listener queue!
     */
    _errListeners:new (myfaces._impl.core._Runtime.getGlobalConfig("errorListenerQueue", myfaces._impl._util._ListenerQueue))(),

    /*CONSTANTS*/

    /*internal identifiers for options*/
    IDENT_ALL:"@all",
    IDENT_NONE:"@none",
    IDENT_THIS:"@this",
    IDENT_FORM:"@form",

    /*
     * [STATIC] constants
     */

    P_PARTIAL_SOURCE:"javax.faces.source",
    P_VIEWSTATE:"javax.faces.ViewState",
    P_CLIENTWINDOW:"javax.faces.ClientWindow",
    P_AJAX:"javax.faces.partial.ajax",
    P_EXECUTE:"javax.faces.partial.execute",
    P_RENDER:"javax.faces.partial.render",
    P_EVT:"javax.faces.partial.event",
    P_WINDOW_ID:"javax.faces.ClientWindow",
    P_RESET_VALUES:"javax.faces.partial.resetValues",

    /* message types */
    ERROR:"error",
    EVENT:"event",

    /* event emitting stages */
    BEGIN:"begin",
    COMPLETE:"complete",
    SUCCESS:"success",

    /*ajax errors spec 14.4.2*/
    HTTPERROR:"httpError",
    EMPTY_RESPONSE:"emptyResponse",
    MALFORMEDXML:"malformedXML",
    SERVER_ERROR:"serverError",
    CLIENT_ERROR:"clientError",
    TIMEOUT_EVENT:"timeout",

    /*error reporting threshold*/
    _threshold:"ERROR",

    /*blockfilter for the passthrough filtering, the attributes given here
     * will not be transmitted from the options into the passthrough*/
    _BLOCKFILTER:{onerror:1, onevent:1, render:1, execute:1, myfaces:1, delay:1, resetValues:1},

    /**
     * collect and encode data for a given form element (must be of type form)
     * find the javax.faces.ViewState element and encode its value as well!
     * return a concatenated string of the encoded values!
     *
     * @throws Error in case of the given element not being of type form!
     * https://issues.apache.org/jira/browse/MYFACES-2110
     */
    getViewState:function (form) {
        /**
         *  typecheck assert!, we opt for strong typing here
         *  because it makes it easier to detect bugs
         */
        if (form) {
            form = this._Lang.byId(form);
        }

        if (!form
            || !form.nodeName
            || form.nodeName.toLowerCase() != "form") {
            throw new Error(this._Lang.getMessage("ERR_VIEWSTATE"));
        }

        var ajaxUtils = myfaces._impl.xhrCore._AjaxUtils;

        var ret = this._Lang.createFormDataDecorator([]);
        ajaxUtils.encodeSubmittableFields(ret, form, null);

        return ret.makeFinal();
    },

    /**
     * this function has to send the ajax requests
     *
     * following request conditions must be met:
     * <ul>
     *  <li> the request must be sent asynchronously! </li>
     *  <li> the request must be a POST!!! request </li>
     *  <li> the request url must be the form action attribute </li>
     *  <li> all requests must be queued with a client side request queue to ensure the request ordering!</li>
     * </ul>
     *
     * @param {String|Node} elem any dom element no matter being it html or jsf, from which the event is emitted
     * @param {|Event|} event any javascript event supported by that object
     * @param {|Object|} options  map of options being pushed into the ajax cycle
     *
     *
     * a) transformArguments out of the function
     * b) passThrough handling with a map copy with a filter map block map
     */
    request:function (elem, event, options) {
        if (this._delayTimeout) {
            clearTimeout(this._delayTimeout);
            delete this._delayTimeout;
        }
        /*namespace remap for our local function context we mix the entire function namespace into
         *a local function variable so that we do not have to write the entire namespace
         *all the time
         **/
        var _Lang = this._Lang,
            _Dom = this._Dom;
        /*assert if the onerror is set and once if it is set it must be of type function*/
        _Lang.assertType(options.onerror, "function");
        /*assert if the onevent is set and once if it is set it must be of type function*/
        _Lang.assertType(options.onevent, "function");

        //options not set we define a default one with nothing
        options = options || {};

        /**
         * we cross reference statically hence the mapping here
         * the entire mapping between the functions is stateless
         */
        //null definitely means no event passed down so we skip the ie specific checks
        if ('undefined' == typeof event) {
            event = window.event || null;
        }

        //improve the error messages if an empty elem is passed
        if (!elem) {
            throw _Lang.makeException(new Error(), "ArgNotSet", null, this._nameSpace, "request", _Lang.getMessage("ERR_MUST_BE_PROVIDED1", "{0}: source  must be provided", "jsf.ajax.request", "source element id"));
        }
        var oldElem = elem;
        elem = _Dom.byIdOrName(elem);
        if (!elem) {
            throw _Lang.makeException(new Error(), "Notfound", null, this._nameSpace, "request", _Lang.getMessage("ERR_PPR_UNKNOWNCID", "{0}: Node with id {1} could not be found from source", this._nameSpace + ".request", oldElem));
        }

        var elementId = _Dom.nodeIdOrName(elem);

        /*
         * We make a copy of our options because
         * we should not touch the incoming params!
         * this copy is also the pass through parameters
         * which are sent down our request
         */
        var passThrgh = _Lang.mixMaps({}, options, true, this._BLOCKFILTER);

        if (event) {
            passThrgh[this.P_EVT] = event.type;
        }

        /**
         * ajax pass through context with the source
         * onevent and onerror
         */
        var context = {
            source:elem,
            onevent:options.onevent,
            onerror:options.onerror,

            //TODO move the myfaces part into the _mfInternal part
            myfaces:options.myfaces,
            _mfInternal:{}
        };
        //additional meta information to speed things up, note internal non jsf
        //pass through options are stored under _mfInternal in the context
        var mfInternal = context._mfInternal;

        /**
         * fetch the parent form
         *
         * note we also add an override possibility here
         * so that people can use dummy forms and work
         * with detached objects
         */
        var form = (options.myfaces && options.myfaces.form) ?
            _Lang.byId(options.myfaces.form) :
            this._getForm(elem, event);

        /**
         * JSF2.2 client window must be part of the issuing form so it is encoded
         * automatically in the request
         */
            //we set the client window before encoding by a call to jsf.getClientWindow
        var clientWindow = jsf.getClientWindow(form);
        //in case someone decorates the getClientWindow we reset the value from
        //what we are getting
        if ('undefined' != typeof clientWindow && null != clientWindow) {
            var formElem = _Dom.getNamedElementFromForm(form, this.P_CLIENTWINDOW);
            if (formElem) {
                //we store the value for later processing during the ajax phase
                //job so that we do not get double values
                context._mfInternal._clientWindow = jsf.getClientWindow(form);
            } else {
                passThrgh[this.P_CLIENTWINDOW] = jsf.getClientWindow(form);
            }
        } /*  spec proposal
        else {
            var formElem = _Dom.getNamedElementFromForm(form, this.P_CLIENTWINDOW);
            if (formElem) {
                context._mfInternal._clientWindow = "undefined";
            } else {
                passThrgh[this.P_CLIENTWINDOW] = "undefined";
            }
        }
        */

        /**
         * binding contract the javax.faces.source must be set
         */
        passThrgh[this.P_PARTIAL_SOURCE] = elementId;

        /**
         * javax.faces.partial.ajax must be set to true
         */
        passThrgh[this.P_AJAX] = true;

        /**
         * if resetValues is set to true
         * then we have to set javax.faces.resetValues as well
         * as pass through parameter
         * the value has to be explicitly true, according to
         * the specs jsdoc
         */
        if(options.resetValues === true) {
            passThrgh[this.P_RESET_VALUES] = true;
        }

        if (options.execute) {
            /*the options must be a blank delimited list of strings*/
            /*compliance with Mojarra which automatically adds @this to an execute
             * the spec rev 2.0a however states, if none is issued nothing at all should be sent down
             */
            options.execute = (options.execute.indexOf("@this") == -1) ? options.execute : options.execute;

            this._transformList(passThrgh, this.P_EXECUTE, options.execute, form, elementId);
        } else {
            passThrgh[this.P_EXECUTE] = elementId;
        }

        if (options.render) {
            this._transformList(passThrgh, this.P_RENDER, options.render, form, elementId);
        }

        /**
         * multiple transports upcoming jsf 2.x feature currently allowed
         * default (no value) xhrQueuedPost
         *
         * xhrQueuedPost
         * xhrPost
         * xhrGet
         * xhrQueuedGet
         * iframePost
         * iframeQueuedPost
         *
         */
        var transportType = this._getTransportType(context, passThrgh, form);

        mfInternal["_mfSourceFormId"] = form.id;
        mfInternal["_mfSourceControlId"] = elementId;
        mfInternal["_mfTransportType"] = transportType;

        //mojarra compatibility, mojarra is sending the form id as well
        //this is not documented behavior but can be determined by running
        //mojarra under blackbox conditions
        //i assume it does the same as our formId_submit=1 so leaving it out
        //wont hurt but for the sake of compatibility we are going to add it
        passThrgh[form.id] = form.id;

        /* jsf2.2 only: options.delay || */
        var delayTimeout = options.delay || this._RT.getLocalOrGlobalConfig(context, "delay", false);
        if (delayTimeout) {
            if (this._delayTimeout) {
                clearTimeout(this._delayTimeout);
            }
            this._delayTimeout = setTimeout(_Lang.hitch(this, function () {
                this._transport[transportType](elem, form, context, passThrgh);
                this._delayTimeout = null;
            }), parseInt(delayTimeout));
        } else {
            this._transport[transportType](elem, form, context, passThrgh);
        }
    },

    /**
     * fetches the form in an unprecise manner depending
     * on an element or event target
     *
     * @param elem
     * @param event
     */
    _getForm:function (elem, event) {
        var _Dom = this._Dom;
        var _Lang = this._Lang;
        var form = _Dom.fuzzyFormDetection(elem);

        if (!form && event) {
            //in case of no form is given we retry over the issuing event
            form = _Dom.fuzzyFormDetection(_Lang.getEventTarget(event));
            if (!form) {
                throw _Lang.makeException(new Error(), null, null, this._nameSpace, "_getForm", _Lang.getMessage("ERR_FORM"));
            }
        } else if (!form) {
            throw _Lang.makeException(new Error(), null, null, this._nameSpace, "_getForm", _Lang.getMessage("ERR_FORM"));

        }
        return form;
    },

    /**
     * determines the transport type to be called
     * for the ajax call
     *
     * @param context the context
     * @param passThrgh  pass through values
     * @param form the form which issues the request
     */
    _getTransportType:function (context, passThrgh, form) {
        /**
         * if execute or render exist
         * we have to pass them down as a blank delimited string representation
         * of an array of ids!
         */
            //for now we turn off the transport auto selection, to enable 2.0 backwards compatibility
            //on protocol level, the file upload only can be turned on if the auto selection is set to true
        var getConfig = this._RT.getLocalOrGlobalConfig,
            _Lang = this._Lang,
            _Dom = this._Dom;

        var transportAutoSelection = getConfig(context, "transportAutoSelection", true);
        /*var isMultipart = (transportAutoSelection && _Dom.getAttribute(form, "enctype") == "multipart/form-data") ?
         _Dom.isMultipartCandidate((!getConfig(context, "pps",false))? form : passThrgh[this.P_EXECUTE]) :
         false;
         **/
        if (!transportAutoSelection) {
            return getConfig(context, "transportType", "xhrQueuedPost");
        }
        var multiPartCandidate = _Dom.isMultipartCandidate((!getConfig(context, "pps", false)) ?
            form : passThrgh[this.P_EXECUTE]);
        var multipartForm = (_Dom.getAttribute(form, "enctype") || "").toLowerCase() == "multipart/form-data";
        //spec section jsdoc, if we have a multipart candidate in our execute (aka fileupload)
        //and the form is not multipart then we have to raise an error
        if (multiPartCandidate && !multipartForm) {
            throw _Lang.makeException(new Error(), null, null, this._nameSpace, "_getTransportType", _Lang.getMessage("ERR_NO_MULTIPART_FORM", "No Multipart form", form.id));
        }
        var isMultipart = multiPartCandidate && multipartForm;
        /**
         * multiple transports upcoming jsf 2.2 feature currently allowed
         * default (no value) xhrQueuedPost
         *
         * xhrQueuedPost
         * xhrPost
         * xhrGet
         * xhrQueuedGet
         * iframePost
         * iframeQueuedPost
         *
         */
        var transportType = (!isMultipart) ?
            getConfig(context, "transportType", "xhrQueuedPost") :
            getConfig(context, "transportType", "multipartQueuedPost");
        if (!this._transport[transportType]) {
            //throw new Error("Transport type " + transportType + " does not exist");
            throw new Error(_Lang.getMessage("ERR_TRANSPORT", null, transportType));
        }
        return transportType;

    },

    /**
     * transforms the list to the expected one
     * with the proper none all form and this handling
     * (note we also could use a simple string replace but then
     * we would have had double entries under some circumstances)
     *
     * @param passThrgh
     * @param target
     * @param srcStr
     * @param form
     * @param elementId
     */
    _transformList:function (passThrgh, target, srcStr, form, elementId) {
        var _Lang = this._Lang;
        //this is probably the fastest transformation method
        //it uses an array and an index to position all elements correctly
        //the offset variable is there to prevent 0 which results in a javascript
        //false
        srcStr = this._Lang.trim(srcStr);
        var offset = 1,
            vals = (srcStr) ? srcStr.split(/\s+/) : [],
            idIdx = (vals.length) ? _Lang.arrToMap(vals, offset) : {},

            //helpers to improve speed and compression
            none = idIdx[this.IDENT_NONE],
            all = idIdx[this.IDENT_ALL],
            theThis = idIdx[this.IDENT_THIS],
            theForm = idIdx[this.IDENT_FORM];

        if (none) {
            //in case of none nothing is returned
            if ('undefined' != typeof passThrgh.target) {
                delete passThrgh.target;
            }
            return passThrgh;
        }
        if (all) {
            //in case of all only one value is returned
            passThrgh[target] = this.IDENT_ALL;
            return passThrgh;
        }

        if (theForm) {
            //the form is replaced with the proper id but the other
            //values are not touched
            vals[theForm - offset] = form.id;
        }
        if (theThis && !idIdx[elementId]) {
            //in case of this, the element id is set
            vals[theThis - offset] = elementId;
        }

        //the final list must be blank separated
        passThrgh[target] = vals.join(" ");
        return passThrgh;
    },

    addOnError:function (/*function*/errorListener) {
        /*error handling already done in the assert of the queue*/
        this._errListeners.enqueue(errorListener);
    },

    addOnEvent:function (/*function*/eventListener) {
        /*error handling already done in the assert of the queue*/
        this._evtListeners.enqueue(eventListener);
    },

    /**
     * implementation triggering the error chain
     *
     * @param {Object} request the request object which comes from the xhr cycle
     * @param {Object} context (Map) the context object being pushed over the xhr cycle keeping additional metadata
     * @param {String} name the error name
     * @param {String} errorName the server error name in case of a server error
     * @param {String} errorMessage the server error message in case of a server error
     * @param {String} caller optional caller reference for extended error messages
     * @param {String} callFunc optional caller Function reference for extended error messages
     *
     *  handles the errors, in case of an onError exists within the context the onError is called as local error handler
     *  the registered error handlers in the queue receiv an error message to be dealt with
     *  and if the projectStage is at development an alert box is displayed
     *
     *  note: we have additional functionality here, via the global config myfaces.config.defaultErrorOutput a function can be provided
     *  which changes the default output behavior from alert to something else
     *
     *
     */
    sendError:function sendError(/*Object*/request, /*Object*/ context, /*String*/ name, /*String*/ errorName, /*String*/ errorMessage, caller, callFunc) {
        var _Lang = myfaces._impl._util._Lang;
        var UNKNOWN = _Lang.getMessage("UNKNOWN");

        var eventData = {};
        //we keep this in a closure because we might reuse it for our errorMessage
        var malFormedMessage = function () {
            return (name && name === myfaces._impl.core.Impl.MALFORMEDXML) ? _Lang.getMessage("ERR_MALFORMEDXML") : "";
        };

        //by setting unknown values to unknown we can handle cases
        //better where a simulated context is pushed into the system
        eventData.type = this.ERROR;

        eventData.status = name || UNKNOWN;
        eventData.errorName = errorName || UNKNOWN;
        eventData.errorMessage = errorMessage || UNKNOWN;

        try {
            eventData.source = context.source || UNKNOWN;
            eventData.responseCode = request.status || UNKNOWN;
            eventData.responseText = request.responseText || UNKNOWN;
            eventData.responseXML = request.responseXML || UNKNOWN;
        } catch (e) {
            // silently ignore: user can find out by examining the event data
        }
        //extended error message only in dev mode
        if (jsf.getProjectStage() === "Development") {
            eventData.errorMessage = eventData.errorMessage || "";
            eventData.errorMessage = (caller) ? eventData.errorMessage + "\nCalling class: " + caller : eventData.errorMessage;
            eventData.errorMessage = (callFunc) ? eventData.errorMessage + "\n Calling function: " + callFunc : eventData.errorMessage;
        }

        /**/
        if (context["onerror"]) {
            context.onerror(eventData);
        }

        /*now we serve the queue as well*/
        this._errListeners.broadcastEvent(eventData);

        if (jsf.getProjectStage() === "Development" && this._errListeners.length() == 0 && !context["onerror"]) {
            var DIVIDER = "--------------------------------------------------------",
                defaultErrorOutput = myfaces._impl.core._Runtime.getGlobalConfig("defaultErrorOutput", alert),
                finalMessage = [],
                //we remap the function to achieve a better compressability
                pushMsg = _Lang.hitch(finalMessage, finalMessage.push);

            (errorMessage) ? pushMsg(_Lang.getMessage("MSG_ERROR_MESSAGE") + " " + errorMessage + "\n") : null;

            pushMsg(DIVIDER);

            (caller) ? pushMsg("Calling class:" + caller) : null;
            (callFunc) ? pushMsg("Calling function:" + callFunc) : null;
            (name) ? pushMsg(_Lang.getMessage("MSG_ERROR_NAME") + " " + name) : null;
            (errorName && name != errorName) ? pushMsg("Server error name: " + errorName) : null;

            pushMsg(malFormedMessage());
            pushMsg(DIVIDER);
            pushMsg(_Lang.getMessage("MSG_DEV_MODE"));
            defaultErrorOutput(finalMessage.join("\n"));
        }
    },

    /**
     * sends an event
     */
    sendEvent:function sendEvent(/*Object*/request, /*Object*/ context, /*event name*/ name) {
        var _Lang = myfaces._impl._util._Lang;
        var eventData = {};
        var UNKNOWN = _Lang.getMessage("UNKNOWN");

        eventData.type = this.EVENT;

        eventData.status = name;
        eventData.source = context.source;

        if (name !== this.BEGIN) {

            try {
                //we bypass a problem with ie here, ie throws an exception if no status is given on the xhr object instead of just passing a value
                var getValue = function (value, key) {
                    try {
                        return value[key]
                    } catch (e) {
                        return UNKNOWN;
                    }
                };

                eventData.responseCode = getValue(request, "status");
                eventData.responseText = getValue(request, "responseText");
                eventData.responseXML = getValue(request, "responseXML");

            } catch (e) {
                var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
                impl.sendError(request, context, this.CLIENT_ERROR, "ErrorRetrievingResponse",
                    _Lang.getMessage("ERR_CONSTRUCT", e.toString()));

                //client errors are not swallowed
                throw e;
            }

        }

        /**/
        if (context.onevent) {
            /*calling null to preserve the original scope*/
            context.onevent.call(null, eventData);
        }

        /*now we serve the queue as well*/
        this._evtListeners.broadcastEvent(eventData);
    },

    /**
     * Spec. 13.3.3
     * Examining the response markup and updating the DOM tree
     * @param {XMLHttpRequest} request - the ajax request
     * @param {Object} context - the ajax context
     */
    response:function (request, context) {
        this._RT.getLocalOrGlobalConfig(context, "responseHandler", myfaces._impl.xhrCore._AjaxResponse).processResponse(request, context);
    },

    /**
     * fetches the separator char from the given script tags
     *
     * @return {char} the separator char for the given script tags
     */
    getSeparatorChar:function () {
        if (this._separator) {
            return this.separatorchar;
        }
        var SEPARATOR_CHAR = "separatorchar",
            found = false,
            getConfig = myfaces._impl.core._Runtime.getGlobalConfig,
            scriptTags = document.getElementsByTagName("script");
        for (var i = 0; i < scriptTags.length && !found; i++) {
            if (scriptTags[i].src.search(/\/javax\.faces\.resource.*\/jsf\.js.*separator/) != -1) {
                found = true;
                var result = scriptTags[i].src.match(/separator=([^&;]*)/);
                this._separator = decodeURIComponent(result[1]);
            }
        }
        this._separator = getConfig(SEPARATOR_CHAR, this._separator || ":");
        return this._separator;
    },

    /**
     * @return the project stage also emitted by the server:
     * it cannot be cached and must be delivered over the server
     * The value for it comes from the request parameter of the jsf.js script called "stage".
     */
    getProjectStage:function () {
        //since impl is a singleton we only have to do it once at first access

        if (!this._projectStage) {
            var PRJ_STAGE = "projectStage",
                STG_PROD = "Production",

                scriptTags = document.getElementsByTagName("script"),
                getConfig = myfaces._impl.core._Runtime.getGlobalConfig,
                projectStage = null,
                found = false,
                allowedProjectStages = {STG_PROD:1, "Development":1, "SystemTest":1, "UnitTest":1};

            /* run through all script tags and try to find the one that includes jsf.js */
            for (var i = 0; i < scriptTags.length && !found; i++) {
                if (scriptTags[i].src.search(/\/javax\.faces\.resource\/jsf\.js.*ln=javax\.faces/) != -1) {
                    var result = scriptTags[i].src.match(/stage=([^&;]*)/);
                    found = true;
                    if (result) {
                        // we found stage=XXX
                        // return only valid values of ProjectStage
                        projectStage = (allowedProjectStages[result[1]]) ? result[1] : null;

                    }
                    else {
                        //we found the script, but there was no stage parameter -- Production
                        //(we also add an override here for testing purposes, the default, however is Production)
                        projectStage = getConfig(PRJ_STAGE, STG_PROD);
                    }
                }
            }
            /* we could not find anything valid --> return the default value */
            this._projectStage = getConfig(PRJ_STAGE, projectStage || STG_PROD);
        }
        return this._projectStage;
    },

    /**
     * implementation of the external chain function
     * moved into the impl
     *
     *  @param {Object} source the source which also becomes
     * the scope for the calling function (unspecified side behavior)
     * the spec states here that the source can be any arbitrary code block.
     * Which means it either is a javascript function directly passed or a code block
     * which has to be evaluated separately.
     *
     * After revisiting the code additional testing against components showed that
     * the this parameter is only targeted at the component triggering the eval
     * (event) if a string code block is passed. This is behavior we have to resemble
     * in our function here as well, I guess.
     *
     * @param {Event} event the event object being passed down into the the chain as event origin
     *   the spec is contradicting here, it on one hand defines event, and on the other
     *   it says it is optional, after asking, it meant that event must be passed down
     *   but can be undefined
     */
    chain:function (source, event) {
        var len = arguments.length;
        var _Lang = this._Lang;
        var throwErr = function (msgKey) {
            throw Error("jsf.util.chain: " + _Lang.getMessage(msgKey));
        };
        /**
         * generic error condition checker which raises
         * an exception if the condition is met
         * @param assertion
         * @param message
         */
        var errorCondition = function (assertion, message) {
            if (assertion === true) throwErr(message);
        };
        var FUNC = 'function';
        var ISSTR = _Lang.isString;

        //the spec is contradicting here, it on one hand defines event, and on the other
        //it says it is optional, I have cleared this up now
        //the spec meant the param must be passed down, but can be 'undefined'

        errorCondition(len < 2, "ERR_EV_OR_UNKNOWN");
        errorCondition(len < 3 && (FUNC == typeof event || ISSTR(event)), "ERR_EVT_PASS");
        if (len < 3) {
            //nothing to be done here, move along
            return true;
        }
        //now we fetch from what is given from the parameter list
        //we cannot work with splice here in any performant way so we do it the hard way
        //arguments only are give if not set to undefined even null values!

        //assertions source either null or set as dom element:
        errorCondition('undefined' == typeof source, "ERR_SOURCE_DEF_NULL");
        errorCondition(FUNC == typeof source, "ERR_SOURCE_FUNC");
        errorCondition(ISSTR(source), "ERR_SOURCE_NOSTR");

        //assertion if event is a function or a string we already are in our function elements
        //since event either is undefined, null or a valid event object
        errorCondition(FUNC == typeof event || ISSTR(event), "ERR_EV_OR_UNKNOWN");

        for (var cnt = 2; cnt < len; cnt++) {
            //we do not change the scope of the incoming functions
            //but we reuse the argument array capabilities of apply
            var ret;

            if (FUNC == typeof arguments[cnt]) {
                ret = arguments[cnt].call(source, event);
            } else {
                //either a function or a string can be passed in case of a string we have to wrap it into another function
                ret = new Function("event", arguments[cnt]).call(source, event);
            }
            //now if one function returns false in between we stop the execution of the cycle
            //here, note we do a strong comparison here to avoid constructs like 'false' or null triggering
            if (ret === false /*undefined check implicitly done here by using a strong compare*/) {
                return false;
            }
        }
        return true;
    },

    /**
     * error handler behavior called internally
     * and only into the impl it takes care of the
     * internal message transformation to a myfaces internal error
     * and then uses the standard send error mechanisms
     * also a double error logging prevention is done as well
     *
     * @param request the request currently being processed
     * @param context the context affected by this error
     * @param exception the exception being thrown
     */
    stdErrorHandler:function (request, context, exception) {
        //newer browsers do not allow to hold additional values on native objects like exceptions
        //we hence capsule it into the request, which is gced automatically
        //on ie as well, since the stdErrorHandler usually is called between requests
        //this is a valid approach
        if (this._threshold == "ERROR") {
            var mfInternal = exception._mfInternal || {};

            var finalMsg = [];
            finalMsg.push(exception.message);
            this.sendError(request, context,
                mfInternal.title || this.CLIENT_ERROR, mfInternal.name || exception.name, finalMsg.join("\n"), mfInternal.caller, mfInternal.callFunc);
        }
    },

    /**
     * @return the client window id of the current window, if one is given
     */
    getClientWindow:function (node) {
        var fetchWindowIdFromForms = this._Lang.hitch(this, function (forms) {
            var result_idx = {};
            var result;
            var foundCnt = 0;
            for (var cnt = forms.length - 1; cnt >= 0; cnt--) {

                var currentForm = forms[cnt];
                var winIdElement = this._Dom.getNamedElementFromForm(currentForm, this.P_WINDOW_ID);
                var windowId = (winIdElement) ? winIdElement.value : null;

                if (windowId) {
                    if (foundCnt > 0 && "undefined" == typeof result_idx[windowId]) throw Error("Multiple different windowIds found in document");
                    result = windowId;
                    result_idx[windowId] = true;
                    foundCnt++;
                }
            }
            return result;
        });

        var fetchWindowIdFromURL = function () {
            var href = window.location.href, windowId = "jfwid";
            var regex = new RegExp("[\\?&]" + windowId + "=([^&#\\;]*)");
            var results = regex.exec(href);
            //initial trial over the url and a regexp
            if (results != null) return results[1];
            return null;
        };

        //byId ($)
        var finalNode = (node) ? this._Dom.byId(node) : document.body;

        var forms = this._Dom.findByTagName(finalNode, "form");
        var result = fetchWindowIdFromForms(forms);
        return (null != result) ? result : fetchWindowIdFromURL();
    }
});



/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*last file loaded, must restore the state of affairs*/
(function() {
    //some mobile browsers do not have a window object
    var target = window || document;

    var resetAbbreviation = function (name) {
            var _temp = target.myfaces._implTemp;
            (!!_temp[name]) ?
                target[name] = _temp[name] : null;
        },
        resetArr = ["_MF_CLS",
            "_MF_SINGLTN",
            "_MF_OBJECT",
            "_PFX_UTIL",
            "_PFX_XHR",
            "_PFX_CORE",
            "_PFX_I18N"];
    for (var cnt = resetArr.length - 1; cnt >= 0; cnt--) {
        resetAbbreviation(resetArr[cnt]);
    }
})();



/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

/**
 *MyFaces core javascripting libraries
 *
 *  Those are the central public API functions in the JSF2
 *  Ajax API! They handle the entire form submit and ajax send
 *  and resolve cycle!
 */

/**
 * reserve the root namespace
 */
if ('undefined' != typeof OpenAjax && ('undefined' == typeof jsf || null == typeof jsf)) {
    OpenAjax.hub.registerLibrary("jsf", "www.sun.com", "1.0", null);
}
//just in case openajax has failed (testing environment)
/**
 * @ignore
 */
if (!window.jsf) {
    /**
     * @namespace jsf
     */
    var jsf = new function() {
        /*
         * Version of the implementation for the jsf.js.
         * <p />
         * as specified within the jsf specifications jsf.html:
         * <ul>
         * <li>left two digits major release number</li>
         * <li>middle two digits minor spec release number</li>
         * <li>right two digits bug release number</li>
         * </ul>
		 * @constant
         */
        this.specversion = 220000;
        /**
         * Implementation version as specified within the jsf specification.
         * <p />
         * A number increased with every implementation version
         * and reset by moving to a new spec release number
         *
         * @constant
         */
        this.implversion = 0;

        /**
         * SeparatorChar as defined by UINamingContainer.getNamingContainerSeparatorChar()
         * @type {Char}
         */
        this.separatorchar = getSeparatorChar();

        /**
         * This method is responsible for the return of a given project stage as defined
         * by the jsf specification.
         * <p/>
         * Valid return values are:
         * <ul>
         *     <li>&quot;Production&quot;</li>
         *     <li>&quot;Development&quot;</li>
         *     <li>&quot;SystemTest&quot;</li>
         *     <li>&quot;UnitTest&quot;</li>
         * </li>
         *
         * @return {String} the current project state emitted by the server side method:
         * <i>javax.faces.application.Application.getProjectStage()</i>
         */
        this.getProjectStage = function() {
            var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
            return impl.getProjectStage();
        };

        /**
         * collect and encode data for a given form element (must be of type form)
         * find the javax.faces.ViewState element and encode its value as well!
         * return a concatenated string of the encoded values!
         *
         * @throws an exception in case of the given element not being of type form!
         * https://issues.apache.org/jira/browse/MYFACES-2110
         */
        this.getViewState = function(formElement) {
            /*we are not allowed to add the impl on a global scope so we have to inline the code*/
            var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
            return impl.getViewState(formElement);
        };

        /**
         * returns the window identifier for the given node / window
         * @param {optional String | DomNode}  the node for which the client identifier has to be determined
         * @return the window identifier or null if none is found
         */
        this.getClientWindow = function() {
            /*we are not allowed to add the impl on a global scope so we have to inline the code*/
            var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
            return (arguments.length)? impl.getClientWindow(arguments[0]) : impl.getClientWindow();
        }

        //private helper functions
        function getSeparatorChar() {
            var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
            return impl.getSeparatorChar();
        }

    };
    //jsdoc helper to avoid warnings, we map later
    window.jsf = jsf;
}

/**
 * just to make sure no questions arise, I simply prefer here a weak
 * typeless comparison just in case some frameworks try to interfere
 * by overriding null or fiddeling around with undefined or typeof in some ways
 * it is safer in this case than the standard way of doing a strong comparison
 **/
if (!jsf.ajax) {
    /**
     * @namespace jsf.ajax
     */
    jsf.ajax = new function() {


        /**
         * this function has to send the ajax requests
         *
         * following request conditions must be met:
         * <ul>
         *  <li> the request must be sent asynchronously! </li>
         *  <li> the request must be a POST!!! request </li>
         *  <li> the request url must be the form action attribute </li>
         *  <li> all requests must be queued with a client side request queue to ensure the request ordering!</li>
         * </ul>
         *
         * @param {String|Node} element: any dom element no matter being it html or jsf, from which the event is emitted
         * @param {EVENT} event: any javascript event supported by that object
         * @param {Map} options : map of options being pushed into the ajax cycle
         */
        this.request = function(element, event, options) {
            if (!options) {
                options = {};
            }
            /*we are not allowed to add the impl on a global scope so we have to inline the code*/
            var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
            return impl.request(element, event, options);
        };

        /**
         * Adds an error handler to our global error queue.
         * the error handler must be of the format <i>function errorListener(&lt;errorData&gt;)</i>
         * with errorData being of following format:
         * <ul>
         *     <li> errorData.type : &quot;error&quot;</li>
         *     <li> errorData.status : the error status message</li>
         *     <li> errorData.errorName : the server error name in case of a server error</li>
         *     <li> errorData.errorMessage : the server error message in case of a server error</li>
         *     <li> errorData.source  : the issuing source element which triggered the request </li>
         *     <li> eventData.responseCode: the response code (aka http request response code, 401 etc...) </li>
         *     <li> eventData.responseText: the request response text </li>
         *     <li> eventData.responseXML: the request response xml </li>
         * </ul>
         *
         * @param {function} errorListener error handler must be of the format <i>function errorListener(&lt;errorData&gt;)</i>
         */
        this.addOnError = function(/*function*/errorListener) {
            var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
            return impl.addOnError(errorListener);
        };

        /**
         * Adds a global event listener to the ajax event queue. The event listener must be a function
         * of following format: <i>function eventListener(&lt;eventData&gt;)</i>
         *
         * @param {function} eventListener event must be of the format <i>function eventListener(&lt;eventData&gt;)</i>
         */
        this.addOnEvent = function(/*function*/eventListener) {
            var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
            return impl.addOnEvent(eventListener);
        };

        /**
         * processes the ajax response if the ajax request completes successfully
         * @param request the ajax request!
         * @param context the ajax context!
         */
        this.response = function(/*xhr request object*/request, context) {
            var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
            return impl.response(request, context);
        };
    }
}

if (!jsf.util) {
    /**
     * @namespace jsf.util
     */
    jsf.util = new function() {

        /**
         * varargs function which executes a chain of code (functions or any other code)
         *
         * if any of the code returns false, the execution
         * is terminated prematurely skipping the rest of the code!
         *
         * @param {DomNode} source, the callee object
         * @param {Event} event, the event object of the callee event triggering this function
         * @param {optional} functions to be chained, if any of those return false the chain is broken
         */
        this.chain = function(source, event) {
            var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
            return impl.chain.apply(impl, arguments);
        };
    }
}

if (!jsf.push) {

    /**
     * @namespace jsf.push
     */
    jsf.push = new function() {

        // "Constant" fields ----------------------------------------------------------------------------------------------
        var URL_PROTOCOL = window.location.protocol.replace("http", "ws") + "//";
        var RECONNECT_INTERVAL = 500;
        var MAX_RECONNECT_ATTEMPTS = 25;
        var REASON_EXPIRED = "Expired";

        // Private static fields ------------------------------------------------------------------------------------------

        /* socket map by token */
        var sockets = {};
        /* component attributes by clientId */
        var components = {};
        /* client ids by token (share websocket connection) */
        var clientIdsByTokens = {};
        var self = {};

        // Private constructor functions ----------------------------------------------------------------------------------
        /**
         * Creates a reconnecting web socket. When the web socket successfully connects on first attempt, then it will
         * automatically reconnect on timeout with cumulative intervals of 500ms with a maximum of 25 attempts (~3 minutes).
         * The <code>onclose</code> function will be called with the error code of the last attempt.
         * @constructor
         * @param {string} channelToken the channel token associated with this websocket connection
         * @param {string} url The URL of the web socket
         * @param {string} channel The name of the web socket channel.
         */
        function Socket(channelToken, url, channel) {

            // Private fields -----------------------------------------------------------------------------------------

            var socket;
            var reconnectAttempts = 0;
            var self = this;

            // Public functions ---------------------------------------------------------------------------------------

            /**
             * Opens the reconnecting web socket.
             */
            self.open = function() {
                if (socket && socket.readyState == 1) {
                    return;
                }

                socket = new WebSocket(url);

                socket.onopen = function(event) {
                    if (!reconnectAttempts) {
                        var clientIds = clientIdsByTokens[channelToken];
                        for (var i = clientIds.length - 1; i >= 0; i--){
                            var socketClientId = clientIds[i];
                            components[socketClientId]['onopen'](channel);
                        }
                    }
                    reconnectAttempts = 0;
                };

                socket.onmessage = function(event) {
                    var message = JSON.parse(event.data);
                    for (var i = clientIdsByTokens[channelToken].length - 1; i >= 0; i--){
                        var socketClientId = clientIdsByTokens[channelToken][i];
                        if(document.getElementById(socketClientId)) {
                            try{
                                components[socketClientId]['onmessage'](message, channel, event);
                            }catch(e){
                                //Ignore
                            }
                            var behaviors = components[socketClientId]['behaviors'];
                            var functions = behaviors[message];
                            if (functions && functions.length) {
                                for (var j = 0; j < functions.length; j++) {
                                    try{
                                        functions[j](null);
                                    }catch(e){
                                        //Ignore
                                    }
                                }
                            }
                        } else {
                            clientIdsByTokens[channelToken].splice(i,1);
                        }
                    }
                    if (clientIdsByTokens[channelToken].length == 0){
                        //tag dissapeared
                        self.close();
                    }

                };

                socket.onclose = function(event) {
                    if (!socket
                        || (event.code == 1000 && event.reason == REASON_EXPIRED)
                        || (event.code == 1008)
                        || (!reconnectAttempts)
                        || (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS))
                    {
                        var clientIds = clientIdsByTokens[channelToken];
                        for (var i = clientIds.length - 1; i >= 0; i--){
                            var socketClientId = clientIds[i];
                            components[socketClientId]['onclose'](event.code, channel, event);
                        }
                    }
                    else {
                        setTimeout(self.open, RECONNECT_INTERVAL * reconnectAttempts++);
                    }
                };
            };

            /**
             * Closes the reconnecting web socket.
             */
            self.close = function() {
                if (socket) {
                    var s = socket;
                    socket = null;
                    s.close();
                }
            }

        }

        // Public static functions ----------------------------------------------------------------------------------------

        /**
         *
         * @param {function} onopen The function to be invoked when the web socket is opened.
         * @param {function} onmessage The function to be invoked when a message is received.
         * @param {function} onclose The function to be invoked when the web socket is closed.
         * @param {boolean} autoconnect Whether or not to immediately open the socket. Defaults to <code>false</code>.
         */
        this.init = function(socketClientId, uri, channel, onopen, onmessage, onclose, behaviorScripts, autoconnect) {

            onclose = resolveFunction(onclose);

            if (!window.WebSocket) { // IE6-9.
                onclose(-1, channel);
                return;
            }

            var channelToken = uri.substr(uri.indexOf('?')+1);

            if (!components[socketClientId]) {
                components[socketClientId] = {
                    'channelToken': channelToken,
                    'onopen': resolveFunction(onopen),
                    'onmessage' : resolveFunction(onmessage),
                    'onclose': onclose,
                    'behaviors': behaviorScripts,
                    'autoconnect': autoconnect};
                if (!clientIdsByTokens[channelToken]) {
                    clientIdsByTokens[channelToken] = [];
                }
                clientIdsByTokens[channelToken].push(socketClientId);
                if (!sockets[channelToken]){
                    sockets[channelToken] = new Socket(channelToken,
                        getBaseURL(uri), channel);
                }
            }

            if (autoconnect) {
                this.open(socketClientId);
            }
        }

        /**
         * Open the web socket on the given channel.
         * @param {string} channel The name of the web socket channel.
         * @throws {Error} When channel is unknown.
         */
        this.open = function(socketClientId) {
            getSocket(components[socketClientId]['channelToken']).open();
        }

        /**
         * Close the web socket on the given channel.
         * @param {string} channel The name of the web socket channel.
         * @throws {Error} When channel is unknown.
         */
        this.close = function(socketClientId) {
            getSocket(components[socketClientId]['channelToken']).close();
        }

        // Private static functions ---------------------------------------------------------------------------------------

        /**
         *
         */
        function getBaseURL(url) {
            if (url.indexOf("://") < 0)
            {
                var base = window.location.hostname+":"+window.location.port
                return URL_PROTOCOL + base + url;
            }else
            {
                return url;
            }
        }

        /**
         * Get socket associated with given channelToken.
         * @param {string} channelToken The name of the web socket channelToken.
         * @return {Socket} Socket associated with given channelToken.
         * @throws {Error} When channelToken is unknown, you may need to initialize
         *                 it first via <code>init()</code> function.
         */
        function getSocket(channelToken) {
            var socket = sockets[channelToken];
            if (socket) {
                return socket;
            } else {
                throw new Error("Unknown channelToken: " + channelToken);
            }
        }

        function resolveFunction(fn) {
            return (typeof fn !== "function") && (fn = window[fn] || function(){}), fn;
        }
        // Expose self to public ------------------------------------------------------------------------------------------

        //return self;
    }
}

