Show:
                            (function() {
                            /**
                             * Simulate user interaction by generating native DOM events.
                             *
                             * @module event-simulate
                             * @requires event
                             */
                            
                            //shortcuts
                            var L   = Y.Lang,
                                win = Y.config.win,
                                isFunction  = L.isFunction,
                                isString    = L.isString,
                                isBoolean   = L.isBoolean,
                                isObject    = L.isObject,
                                isNumber    = L.isNumber,
                            
                                //mouse events supported
                                mouseEvents = {
                                    click:      1,
                                    dblclick:   1,
                                    mouseover:  1,
                                    mouseout:   1,
                                    mousedown:  1,
                                    mouseup:    1,
                                    mousemove:  1,
                                    contextmenu:1
                                },
                            
                                pointerEvents = (win && win.PointerEvent) ? {
                                    pointerover:  1,
                                    pointerout:   1,
                                    pointerdown:  1,
                                    pointerup:    1,
                                    pointermove:  1
                                } : {
                                    MSPointerOver:  1,
                                    MSPointerOut:   1,
                                    MSPointerDown:  1,
                                    MSPointerUp:    1,
                                    MSPointerMove:  1
                                },
                            
                                //key events supported
                                keyEvents   = {
                                    keydown:    1,
                                    keyup:      1,
                                    keypress:   1
                                },
                            
                                //HTML events supported
                                uiEvents  = {
                                    submit:     1,
                                    blur:       1,
                                    change:     1,
                                    focus:      1,
                                    resize:     1,
                                    scroll:     1,
                                    select:     1
                                },
                            
                                //events that bubble by default
                                bubbleEvents = {
                                    scroll:     1,
                                    resize:     1,
                                    reset:      1,
                                    submit:     1,
                                    change:     1,
                                    select:     1,
                                    error:      1,
                                    abort:      1
                                },
                            
                                //touch events supported
                                touchEvents = {
                                    touchstart: 1,
                                    touchmove: 1,
                                    touchend: 1,
                                    touchcancel: 1
                                },
                            
                                gestureEvents = {
                                    gesturestart: 1,
                                    gesturechange: 1,
                                    gestureend: 1
                                };
                            
                            //all key, mouse and touch events bubble
                            Y.mix(bubbleEvents, mouseEvents);
                            Y.mix(bubbleEvents, keyEvents);
                            Y.mix(bubbleEvents, touchEvents);
                            
                            /*
                             * Note: Intentionally not for YUIDoc generation.
                             * Simulates a key event using the given event information to populate
                             * the generated event object. This method does browser-equalizing
                             * calculations to account for differences in the DOM and IE event models
                             * as well as different browser quirks. Note: keydown causes Safari 2.x to
                             * crash.
                             * @method simulateKeyEvent
                             * @private
                             * @static
                             * @param {HTMLElement} target The target of the given event.
                             * @param {String} type The type of event to fire. This can be any one of
                             *      the following: keyup, keydown, and keypress.
                             * @param {Boolean} [bubbles=true] Indicates if the event can be
                             *      bubbled up. DOM Level 3 specifies that all key events bubble by
                             *      default.
                             * @param {Boolean} [cancelable=true] Indicates if the event can be
                             *      canceled using preventDefault(). DOM Level 3 specifies that all
                             *      key events can be cancelled.
                             * @param {Window} [view=window] The view containing the target. This is
                             *      typically the window object.
                             * @param {Boolean} [ctrlKey=false] Indicates if one of the CTRL keys
                             *      is pressed while the event is firing.
                             * @param {Boolean} [altKey=false] Indicates if one of the ALT keys
                             *      is pressed while the event is firing.
                             * @param {Boolean} [shiftKey=false] Indicates if one of the SHIFT keys
                             *      is pressed while the event is firing.
                             * @param {Boolean} [metaKey=false] Indicates if one of the META keys
                             *      is pressed while the event is firing.
                             * @param {Number} [keyCode=0] The code for the key that is in use.
                             * @param {Number} [charCode=0] The Unicode code for the character
                             *      associated with the key being used.
                             */
                            function simulateKeyEvent(target /*:HTMLElement*/, type /*:String*/,
                                                         bubbles /*:Boolean*/,  cancelable /*:Boolean*/,
                                                         view /*:Window*/,
                                                         ctrlKey /*:Boolean*/,    altKey /*:Boolean*/,
                                                         shiftKey /*:Boolean*/,   metaKey /*:Boolean*/,
                                                         keyCode /*:int*/,        charCode /*:int*/) /*:Void*/
                            {
                                //check target
                                if (!target){
                                    Y.error("simulateKeyEvent(): Invalid target.");
                                }
                            
                                //check event type
                                if (isString(type)){
                                    type = type.toLowerCase();
                                    switch(type){
                                        case "textevent": //DOM Level 3
                                            type = "keypress";
                                            break;
                                        case "keyup":
                                        case "keydown":
                                        case "keypress":
                                            break;
                                        default:
                                            Y.error("simulateKeyEvent(): Event type '" + type + "' not supported.");
                                    }
                                } else {
                                    Y.error("simulateKeyEvent(): Event type must be a string.");
                                }
                            
                                //setup default values
                                if (!isBoolean(bubbles)){
                                    bubbles = true; //all key events bubble
                                }
                                if (!isBoolean(cancelable)){
                                    cancelable = true; //all key events can be cancelled
                                }
                                if (!isObject(view)){
                                    view = Y.config.win; //view is typically window
                                }
                                if (!isBoolean(ctrlKey)){
                                    ctrlKey = false;
                                }
                                if (!isBoolean(altKey)){
                                    altKey = false;
                                }
                                if (!isBoolean(shiftKey)){
                                    shiftKey = false;
                                }
                                if (!isBoolean(metaKey)){
                                    metaKey = false;
                                }
                                if (!isNumber(keyCode)){
                                    keyCode = 0;
                                }
                                if (!isNumber(charCode)){
                                    charCode = 0;
                                }
                            
                                //try to create a mouse event
                                var customEvent /*:MouseEvent*/ = null;
                            
                                //check for DOM-compliant browsers first
                                if (isFunction(Y.config.doc.createEvent)){
                            
                                    try {
                            
                                        //try to create key event
                                        customEvent = Y.config.doc.createEvent("KeyEvents");
                            
                                        /*
                                         * Interesting problem: Firefox implemented a non-standard
                                         * version of initKeyEvent() based on DOM Level 2 specs.
                                         * Key event was removed from DOM Level 2 and re-introduced
                                         * in DOM Level 3 with a different interface. Firefox is the
                                         * only browser with any implementation of Key Events, so for
                                         * now, assume it's Firefox if the above line doesn't error.
                                         */
                                        // @TODO: Decipher between Firefox's implementation and a correct one.
                                        customEvent.initKeyEvent(type, bubbles, cancelable, view, ctrlKey,
                                            altKey, shiftKey, metaKey, keyCode, charCode);
                            
                                    } catch (ex /*:Error*/){
                            
                                        /*
                                         * If it got here, that means key events aren't officially supported.
                                         * Safari/WebKit is a real problem now. WebKit 522 won't let you
                                         * set keyCode, charCode, or other properties if you use a
                                         * UIEvent, so we first must try to create a generic event. The
                                         * fun part is that this will throw an error on Safari 2.x. The
                                         * end result is that we need another try...catch statement just to
                                         * deal with this mess.
                                         */
                                        try {
                            
                                            //try to create generic event - will fail in Safari 2.x
                                            customEvent = Y.config.doc.createEvent("Events");
                            
                                        } catch (uierror /*:Error*/){
                            
                                            //the above failed, so create a UIEvent for Safari 2.x
                                            customEvent = Y.config.doc.createEvent("UIEvents");
                            
                                        } finally {
                            
                                            customEvent.initEvent(type, bubbles, cancelable);
                            
                                            //initialize
                                            customEvent.view = view;
                                            customEvent.altKey = altKey;
                                            customEvent.ctrlKey = ctrlKey;
                                            customEvent.shiftKey = shiftKey;
                                            customEvent.metaKey = metaKey;
                                            customEvent.keyCode = keyCode;
                                            customEvent.charCode = charCode;
                            
                                        }
                            
                                    }
                            
                                    //fire the event
                                    target.dispatchEvent(customEvent);
                            
                                } else if (isObject(Y.config.doc.createEventObject)){ //IE
                            
                                    //create an IE event object
                                    customEvent = Y.config.doc.createEventObject();
                            
                                    //assign available properties
                                    customEvent.bubbles = bubbles;
                                    customEvent.cancelable = cancelable;
                                    customEvent.view = view;
                                    customEvent.ctrlKey = ctrlKey;
                                    customEvent.altKey = altKey;
                                    customEvent.shiftKey = shiftKey;
                                    customEvent.metaKey = metaKey;
                            
                                    /*
                                     * IE doesn't support charCode explicitly. CharCode should
                                     * take precedence over any keyCode value for accurate
                                     * representation.
                                     */
                                    customEvent.keyCode = (charCode > 0) ? charCode : keyCode;
                            
                                    //fire the event
                                    target.fireEvent("on" + type, customEvent);
                            
                                } else {
                                    Y.error("simulateKeyEvent(): No event simulation framework present.");
                                }
                            }
                            
                            /*
                             * Note: Intentionally not for YUIDoc generation.
                             * Simulates a mouse event using the given event information to populate
                             * the generated event object. This method does browser-equalizing
                             * calculations to account for differences in the DOM and IE event models
                             * as well as different browser quirks.
                             * @method simulateMouseEvent
                             * @private
                             * @static
                             * @param {HTMLElement} target The target of the given event.
                             * @param {String} type The type of event to fire. This can be any one of
                             *      the following: click, dblclick, mousedown, mouseup, mouseout,
                             *      mouseover, and mousemove.
                             * @param {Boolean} bubbles (Optional) Indicates if the event can be
                             *      bubbled up. DOM Level 2 specifies that all mouse events bubble by
                             *      default. The default is true.
                             * @param {Boolean} cancelable (Optional) Indicates if the event can be
                             *      canceled using preventDefault(). DOM Level 2 specifies that all
                             *      mouse events except mousemove can be cancelled. The default
                             *      is true for all events except mousemove, for which the default
                             *      is false.
                             * @param {Window} view (Optional) The view containing the target. This is
                             *      typically the window object. The default is window.
                             * @param {Number} detail (Optional) The number of times the mouse button has
                             *      been used. The default value is 1.
                             * @param {Number} screenX (Optional) The x-coordinate on the screen at which
                             *      point the event occured. The default is 0.
                             * @param {Number} screenY (Optional) The y-coordinate on the screen at which
                             *      point the event occured. The default is 0.
                             * @param {Number} clientX (Optional) The x-coordinate on the client at which
                             *      point the event occured. The default is 0.
                             * @param {Number} clientY (Optional) The y-coordinate on the client at which
                             *      point the event occured. The default is 0.
                             * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
                             *      is pressed while the event is firing. The default is false.
                             * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
                             *      is pressed while the event is firing. The default is false.
                             * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
                             *      is pressed while the event is firing. The default is false.
                             * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
                             *      is pressed while the event is firing. The default is false.
                             * @param {Number} button (Optional) The button being pressed while the event
                             *      is executing. The value should be 0 for the primary mouse button
                             *      (typically the left button), 1 for the terciary mouse button
                             *      (typically the middle button), and 2 for the secondary mouse button
                             *      (typically the right button). The default is 0.
                             * @param {HTMLElement} relatedTarget (Optional) For mouseout events,
                             *      this is the element that the mouse has moved to. For mouseover
                             *      events, this is the element that the mouse has moved from. This
                             *      argument is ignored for all other events. The default is null.
                             */
                            function simulateMouseEvent(target /*:HTMLElement*/, type /*:String*/,
                                                           bubbles /*:Boolean*/,  cancelable /*:Boolean*/,
                                                           view /*:Window*/,        detail /*:int*/,
                                                           screenX /*:int*/,        screenY /*:int*/,
                                                           clientX /*:int*/,        clientY /*:int*/,
                                                           ctrlKey /*:Boolean*/,    altKey /*:Boolean*/,
                                                           shiftKey /*:Boolean*/,   metaKey /*:Boolean*/,
                                                           button /*:int*/,         relatedTarget /*:HTMLElement*/) /*:Void*/
                            {
                                //check target
                                if (!target){
                                    Y.error("simulateMouseEvent(): Invalid target.");
                                }
                            
                            
                                if (isString(type)){
                            
                                    //make sure it's a supported mouse event or an msPointerEvent.
                                    if (!mouseEvents[type.toLowerCase()] && !pointerEvents[type]){
                                        Y.error("simulateMouseEvent(): Event type '" + type + "' not supported.");
                                    }
                                }
                                else {
                                    Y.error("simulateMouseEvent(): Event type must be a string.");
                                }
                            
                                //setup default values
                                if (!isBoolean(bubbles)){
                                    bubbles = true; //all mouse events bubble
                                }
                                if (!isBoolean(cancelable)){
                                    cancelable = (type !== "mousemove"); //mousemove is the only one that can't be cancelled
                                }
                                if (!isObject(view)){
                                    view = Y.config.win; //view is typically window
                                }
                                if (!isNumber(detail)){
                                    detail = 1;  //number of mouse clicks must be at least one
                                }
                                if (!isNumber(screenX)){
                                    screenX = 0;
                                }
                                if (!isNumber(screenY)){
                                    screenY = 0;
                                }
                                if (!isNumber(clientX)){
                                    clientX = 0;
                                }
                                if (!isNumber(clientY)){
                                    clientY = 0;
                                }
                                if (!isBoolean(ctrlKey)){
                                    ctrlKey = false;
                                }
                                if (!isBoolean(altKey)){
                                    altKey = false;
                                }
                                if (!isBoolean(shiftKey)){
                                    shiftKey = false;
                                }
                                if (!isBoolean(metaKey)){
                                    metaKey = false;
                                }
                                if (!isNumber(button)){
                                    button = 0;
                                }
                            
                                relatedTarget = relatedTarget || null;
                            
                                //try to create a mouse event
                                var customEvent /*:MouseEvent*/ = null;
                            
                                //check for DOM-compliant browsers first
                                if (isFunction(Y.config.doc.createEvent)){
                            
                                    customEvent = Y.config.doc.createEvent("MouseEvents");
                            
                                    //Safari 2.x (WebKit 418) still doesn't implement initMouseEvent()
                                    if (customEvent.initMouseEvent){
                                        customEvent.initMouseEvent(type, bubbles, cancelable, view, detail,
                                                             screenX, screenY, clientX, clientY,
                                                             ctrlKey, altKey, shiftKey, metaKey,
                                                             button, relatedTarget);
                                    } else { //Safari
                            
                                        //the closest thing available in Safari 2.x is UIEvents
                                        customEvent = Y.config.doc.createEvent("UIEvents");
                                        customEvent.initEvent(type, bubbles, cancelable);
                                        customEvent.view = view;
                                        customEvent.detail = detail;
                                        customEvent.screenX = screenX;
                                        customEvent.screenY = screenY;
                                        customEvent.clientX = clientX;
                                        customEvent.clientY = clientY;
                                        customEvent.ctrlKey = ctrlKey;
                                        customEvent.altKey = altKey;
                                        customEvent.metaKey = metaKey;
                                        customEvent.shiftKey = shiftKey;
                                        customEvent.button = button;
                                        customEvent.relatedTarget = relatedTarget;
                                    }
                            
                                    /*
                                     * Check to see if relatedTarget has been assigned. Firefox
                                     * versions less than 2.0 don't allow it to be assigned via
                                     * initMouseEvent() and the property is readonly after event
                                     * creation, so in order to keep YAHOO.util.getRelatedTarget()
                                     * working, assign to the IE proprietary toElement property
                                     * for mouseout event and fromElement property for mouseover
                                     * event.
                                     */
                                    if (relatedTarget && !customEvent.relatedTarget){
                                        if (type === "mouseout"){
                                            customEvent.toElement = relatedTarget;
                                        } else if (type === "mouseover"){
                                            customEvent.fromElement = relatedTarget;
                                        }
                                    }
                            
                                    //fire the event
                                    target.dispatchEvent(customEvent);
                            
                                } else if (isObject(Y.config.doc.createEventObject)){ //IE
                            
                                    //create an IE event object
                                    customEvent = Y.config.doc.createEventObject();
                            
                                    //assign available properties
                                    customEvent.bubbles = bubbles;
                                    customEvent.cancelable = cancelable;
                                    customEvent.view = view;
                                    customEvent.detail = detail;
                                    customEvent.screenX = screenX;
                                    customEvent.screenY = screenY;
                                    customEvent.clientX = clientX;
                                    customEvent.clientY = clientY;
                                    customEvent.ctrlKey = ctrlKey;
                                    customEvent.altKey = altKey;
                                    customEvent.metaKey = metaKey;
                                    customEvent.shiftKey = shiftKey;
                            
                                    //fix button property for IE's wacky implementation
                                    switch(button){
                                        case 0:
                                            customEvent.button = 1;
                                            break;
                                        case 1:
                                            customEvent.button = 4;
                                            break;
                                        case 2:
                                            //leave as is
                                            break;
                                        default:
                                            customEvent.button = 0;
                                    }
                            
                                    /*
                                     * Have to use relatedTarget because IE won't allow assignment
                                     * to toElement or fromElement on generic events. This keeps
                                     * YAHOO.util.customEvent.getRelatedTarget() functional.
                                     */
                                    customEvent.relatedTarget = relatedTarget;
                            
                                    //fire the event
                                    target.fireEvent("on" + type, customEvent);
                            
                                } else {
                                    Y.error("simulateMouseEvent(): No event simulation framework present.");
                                }
                            }
                            
                            /*
                             * Note: Intentionally not for YUIDoc generation.
                             * Simulates a UI event using the given event information to populate
                             * the generated event object. This method does browser-equalizing
                             * calculations to account for differences in the DOM and IE event models
                             * as well as different browser quirks.
                             * @method simulateHTMLEvent
                             * @private
                             * @static
                             * @param {HTMLElement} target The target of the given event.
                             * @param {String} type The type of event to fire. This can be any one of
                             *      the following: click, dblclick, mousedown, mouseup, mouseout,
                             *      mouseover, and mousemove.
                             * @param {Boolean} bubbles (Optional) Indicates if the event can be
                             *      bubbled up. DOM Level 2 specifies that all mouse events bubble by
                             *      default. The default is true.
                             * @param {Boolean} cancelable (Optional) Indicates if the event can be
                             *      canceled using preventDefault(). DOM Level 2 specifies that all
                             *      mouse events except mousemove can be cancelled. The default
                             *      is true for all events except mousemove, for which the default
                             *      is false.
                             * @param {Window} view (Optional) The view containing the target. This is
                             *      typically the window object. The default is window.
                             * @param {Number} detail (Optional) The number of times the mouse button has
                             *      been used. The default value is 1.
                             */
                            function simulateUIEvent(target /*:HTMLElement*/, type /*:String*/,
                                                           bubbles /*:Boolean*/,  cancelable /*:Boolean*/,
                                                           view /*:Window*/,        detail /*:int*/) /*:Void*/
                            {
                            
                                //check target
                                if (!target){
                                    Y.error("simulateUIEvent(): Invalid target.");
                                }
                            
                                //check event type
                                if (isString(type)){
                                    type = type.toLowerCase();
                            
                                    //make sure it's a supported mouse event
                                    if (!uiEvents[type]){
                                        Y.error("simulateUIEvent(): Event type '" + type + "' not supported.");
                                    }
                                } else {
                                    Y.error("simulateUIEvent(): Event type must be a string.");
                                }
                            
                                //try to create a mouse event
                                var customEvent = null;
                            
                            
                                //setup default values
                                if (!isBoolean(bubbles)){
                                    bubbles = (type in bubbleEvents);  //not all events bubble
                                }
                                if (!isBoolean(cancelable)){
                                    cancelable = (type === "submit"); //submit is the only one that can be cancelled
                                }
                                if (!isObject(view)){
                                    view = Y.config.win; //view is typically window
                                }
                                if (!isNumber(detail)){
                                    detail = 1;  //usually not used but defaulted to this
                                }
                            
                                //check for DOM-compliant browsers first
                                if (isFunction(Y.config.doc.createEvent)){
                            
                                    //just a generic UI Event object is needed
                                    customEvent = Y.config.doc.createEvent("UIEvents");
                                    customEvent.initUIEvent(type, bubbles, cancelable, view, detail);
                            
                                    //fire the event
                                    target.dispatchEvent(customEvent);
                            
                                } else if (isObject(Y.config.doc.createEventObject)){ //IE
                            
                                    //create an IE event object
                                    customEvent = Y.config.doc.createEventObject();
                            
                                    //assign available properties
                                    customEvent.bubbles = bubbles;
                                    customEvent.cancelable = cancelable;
                                    customEvent.view = view;
                                    customEvent.detail = detail;
                            
                                    //fire the event
                                    target.fireEvent("on" + type, customEvent);
                            
                                } else {
                                    Y.error("simulateUIEvent(): No event simulation framework present.");
                                }
                            }
                            
                            /*
                             * (iOS only) This is for creating native DOM gesture events which only iOS
                             * v2.0+ is supporting.
                             *
                             * @method simulateGestureEvent
                             * @private
                             * @param {HTMLElement} target The target of the given event.
                             * @param {String} type The type of event to fire. This can be any one of
                             *      the following: touchstart, touchmove, touchend, touchcancel.
                             * @param {Boolean} bubbles (Optional) Indicates if the event can be
                             *      bubbled up. DOM Level 2 specifies that all mouse events bubble by
                             *      default. The default is true.
                             * @param {Boolean} cancelable (Optional) Indicates if the event can be
                             *      canceled using preventDefault(). DOM Level 2 specifies that all
                             *      touch events except touchcancel can be cancelled. The default
                             *      is true for all events except touchcancel, for which the default
                             *      is false.
                             * @param {Window} view (Optional) The view containing the target. This is
                             *      typically the window object. The default is window.
                             * @param {Number} detail (Optional) Specifies some detail information about
                             *      the event depending on the type of event.
                             * @param {Number} screenX (Optional) The x-coordinate on the screen at which
                             *      point the event occured. The default is 0.
                             * @param {Number} screenY (Optional) The y-coordinate on the screen at which
                             *      point the event occured. The default is 0.
                             * @param {Number} clientX (Optional) The x-coordinate on the client at which
                             *      point the event occured. The default is 0.
                             * @param {Number} clientY (Optional) The y-coordinate on the client at which
                             *      point the event occured. The default is 0.
                             * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
                             *      is pressed while the event is firing. The default is false.
                             * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
                             *      is pressed while the event is firing. The default is false.
                             * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
                             *      is pressed while the event is firing. The default is false.
                             * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
                             *      is pressed while the event is firing. The default is false.
                             * @param {Number} scale (iOS v2+ only) The distance between two fingers
                             *      since the start of an event as a multiplier of the initial distance.
                             *      The default value is 1.0.
                             * @param {Number} rotation (iOS v2+ only) The delta rotation since the start
                             *      of an event, in degrees, where clockwise is positive and
                             *      counter-clockwise is negative. The default value is 0.0.
                             */
                            function simulateGestureEvent(target, type,
                                bubbles,            // boolean
                                cancelable,         // boolean
                                view,               // DOMWindow
                                detail,             // long
                                screenX, screenY,   // long
                                clientX, clientY,   // long
                                ctrlKey, altKey, shiftKey, metaKey, // boolean
                                scale,              // float
                                rotation            // float
                            ) {
                                var customEvent;
                            
                                if(!Y.UA.ios || Y.UA.ios<2.0) {
                                    Y.error("simulateGestureEvent(): Native gesture DOM eventframe is not available in this platform.");
                                }
                            
                                // check taget
                                if (!target){
                                    Y.error("simulateGestureEvent(): Invalid target.");
                                }
                            
                                //check event type
                                if (Y.Lang.isString(type)) {
                                    type = type.toLowerCase();
                            
                                    //make sure it's a supported touch event
                                    if (!gestureEvents[type]){
                                        Y.error("simulateTouchEvent(): Event type '" + type + "' not supported.");
                                    }
                                } else {
                                    Y.error("simulateGestureEvent(): Event type must be a string.");
                                }
                            
                                // setup default values
                                if (!Y.Lang.isBoolean(bubbles)) { bubbles = true; } // bubble by default
                                if (!Y.Lang.isBoolean(cancelable)) { cancelable = true; }
                                if (!Y.Lang.isObject(view))     { view = Y.config.win; }
                                if (!Y.Lang.isNumber(detail))   { detail = 2; }     // usually not used.
                                if (!Y.Lang.isNumber(screenX))  { screenX = 0; }
                                if (!Y.Lang.isNumber(screenY))  { screenY = 0; }
                                if (!Y.Lang.isNumber(clientX))  { clientX = 0; }
                                if (!Y.Lang.isNumber(clientY))  { clientY = 0; }
                                if (!Y.Lang.isBoolean(ctrlKey)) { ctrlKey = false; }
                                if (!Y.Lang.isBoolean(altKey))  { altKey = false; }
                                if (!Y.Lang.isBoolean(shiftKey)){ shiftKey = false; }
                                if (!Y.Lang.isBoolean(metaKey)) { metaKey = false; }
                            
                                if (!Y.Lang.isNumber(scale)){ scale = 1.0; }
                                if (!Y.Lang.isNumber(rotation)){ rotation = 0.0; }
                            
                                customEvent = Y.config.doc.createEvent("GestureEvent");
                            
                                customEvent.initGestureEvent(type, bubbles, cancelable, view, detail,
                                    screenX, screenY, clientX, clientY,
                                    ctrlKey, altKey, shiftKey, metaKey,
                                    target, scale, rotation);
                            
                                target.dispatchEvent(customEvent);
                            }
                            
                            
                            /*
                             * @method simulateTouchEvent
                             * @private
                             * @param {HTMLElement} target The target of the given event.
                             * @param {String} type The type of event to fire. This can be any one of
                             *      the following: touchstart, touchmove, touchend, touchcancel.
                             * @param {Boolean} bubbles (Optional) Indicates if the event can be
                             *      bubbled up. DOM Level 2 specifies that all mouse events bubble by
                             *      default. The default is true.
                             * @param {Boolean} cancelable (Optional) Indicates if the event can be
                             *      canceled using preventDefault(). DOM Level 2 specifies that all
                             *      touch events except touchcancel can be cancelled. The default
                             *      is true for all events except touchcancel, for which the default
                             *      is false.
                             * @param {Window} view (Optional) The view containing the target. This is
                             *      typically the window object. The default is window.
                             * @param {Number} detail (Optional) Specifies some detail information about
                             *      the event depending on the type of event.
                             * @param {Number} screenX (Optional) The x-coordinate on the screen at which
                             *      point the event occured. The default is 0.
                             * @param {Number} screenY (Optional) The y-coordinate on the screen at which
                             *      point the event occured. The default is 0.
                             * @param {Number} clientX (Optional) The x-coordinate on the client at which
                             *      point the event occured. The default is 0.
                             * @param {Number} clientY (Optional) The y-coordinate on the client at which
                             *      point the event occured. The default is 0.
                             * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
                             *      is pressed while the event is firing. The default is false.
                             * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
                             *      is pressed while the event is firing. The default is false.
                             * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
                             *      is pressed while the event is firing. The default is false.
                             * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
                             *      is pressed while the event is firing. The default is false.
                             * @param {TouchList} touches A collection of Touch objects representing
                             *      all touches associated with this event.
                             * @param {TouchList} targetTouches A collection of Touch objects
                             *      representing all touches associated with this target.
                             * @param {TouchList} changedTouches A collection of Touch objects
                             *      representing all touches that changed in this event.
                             * @param {Number} scale (iOS v2+ only) The distance between two fingers
                             *      since the start of an event as a multiplier of the initial distance.
                             *      The default value is 1.0.
                             * @param {Number} rotation (iOS v2+ only) The delta rotation since the start
                             *      of an event, in degrees, where clockwise is positive and
                             *      counter-clockwise is negative. The default value is 0.0.
                             */
                            function simulateTouchEvent(target, type,
                                bubbles,            // boolean
                                cancelable,         // boolean
                                view,               // DOMWindow
                                detail,             // long
                                screenX, screenY,   // long
                                clientX, clientY,   // long
                                ctrlKey, altKey, shiftKey, metaKey, // boolean
                                touches,            // TouchList
                                targetTouches,      // TouchList
                                changedTouches,     // TouchList
                                scale,              // float
                                rotation            // float
                            ) {
                            
                                var customEvent;
                            
                                // check taget
                                if (!target){
                                    Y.error("simulateTouchEvent(): Invalid target.");
                                }
                            
                                //check event type
                                if (Y.Lang.isString(type)) {
                                    type = type.toLowerCase();
                            
                                    //make sure it's a supported touch event
                                    if (!touchEvents[type]){
                                        Y.error("simulateTouchEvent(): Event type '" + type + "' not supported.");
                                    }
                                } else {
                                    Y.error("simulateTouchEvent(): Event type must be a string.");
                                }
                            
                                // note that the caller is responsible to pass appropriate touch objects.
                                // check touch objects
                                // Android(even 4.0) doesn't define TouchList yet
                                /*if(type === 'touchstart' || type === 'touchmove') {
                                    if(!touches instanceof TouchList) {
                                        Y.error('simulateTouchEvent(): Invalid touches. It must be a TouchList');
                                    } else {
                                        if(touches.length === 0) {
                                            Y.error('simulateTouchEvent(): No touch object found.');
                                        }
                                    }
                                } else if(type === 'touchend') {
                                    if(!changedTouches instanceof TouchList) {
                                        Y.error('simulateTouchEvent(): Invalid touches. It must be a TouchList');
                                    } else {
                                        if(changedTouches.length === 0) {
                                            Y.error('simulateTouchEvent(): No touch object found.');
                                        }
                                    }
                                }*/
                            
                                if(type === 'touchstart' || type === 'touchmove') {
                                    if(touches.length === 0) {
                                        Y.error('simulateTouchEvent(): No touch object in touches');
                                    }
                                } else if(type === 'touchend') {
                                    if(changedTouches.length === 0) {
                                        Y.error('simulateTouchEvent(): No touch object in changedTouches');
                                    }
                                }
                            
                                // setup default values
                                if (!Y.Lang.isBoolean(bubbles)) { bubbles = true; } // bubble by default.
                                if (!Y.Lang.isBoolean(cancelable)) {
                                    cancelable = (type !== "touchcancel"); // touchcancel is not cancelled
                                }
                                if (!Y.Lang.isObject(view))     { view = Y.config.win; }
                                if (!Y.Lang.isNumber(detail))   { detail = 1; } // usually not used. defaulted to # of touch objects.
                                if (!Y.Lang.isNumber(screenX))  { screenX = 0; }
                                if (!Y.Lang.isNumber(screenY))  { screenY = 0; }
                                if (!Y.Lang.isNumber(clientX))  { clientX = 0; }
                                if (!Y.Lang.isNumber(clientY))  { clientY = 0; }
                                if (!Y.Lang.isBoolean(ctrlKey)) { ctrlKey = false; }
                                if (!Y.Lang.isBoolean(altKey))  { altKey = false; }
                                if (!Y.Lang.isBoolean(shiftKey)){ shiftKey = false; }
                                if (!Y.Lang.isBoolean(metaKey)) { metaKey = false; }
                                if (!Y.Lang.isNumber(scale))    { scale = 1.0; }
                                if (!Y.Lang.isNumber(rotation)) { rotation = 0.0; }
                            
                            
                                //check for DOM-compliant browsers first
                                if (Y.Lang.isFunction(Y.config.doc.createEvent)) {
                                    if (Y.UA.android) {
                                        /*
                                            * Couldn't find android start version that supports touch event.
                                            * Assumed supported(btw APIs broken till icecream sandwitch)
                                            * from the beginning.
                                        */
                                        if(Y.UA.android < 4.0) {
                                            /*
                                                * Touch APIs are broken in androids older than 4.0. We will use
                                                * simulated touch apis for these versions.
                                                * App developer still can listen for touch events. This events
                                                * will be dispatched with touch event types.
                                                *
                                                * (Note) Used target for the relatedTarget. Need to verify if
                                                * it has a side effect.
                                            */
                                            customEvent = Y.config.doc.createEvent("MouseEvents");
                                            customEvent.initMouseEvent(type, bubbles, cancelable, view, detail,
                                                screenX, screenY, clientX, clientY,
                                                ctrlKey, altKey, shiftKey, metaKey,
                                                0, target);
                            
                                            customEvent.touches = touches;
                                            customEvent.targetTouches = targetTouches;
                                            customEvent.changedTouches = changedTouches;
                                        } else {
                                            customEvent = Y.config.doc.createEvent("TouchEvent");
                            
                                            // Andoroid isn't compliant W3C initTouchEvent method signature.
                                            customEvent.initTouchEvent(touches, targetTouches, changedTouches,
                                                type, view,
                                                screenX, screenY, clientX, clientY,
                                                ctrlKey, altKey, shiftKey, metaKey);
                                        }
                                    } else if (Y.UA.ios) {
                                        if(Y.UA.ios >= 2.0) {
                                            customEvent = Y.config.doc.createEvent("TouchEvent");
                            
                                            // Available iOS 2.0 and later
                                            customEvent.initTouchEvent(type, bubbles, cancelable, view, detail,
                                                screenX, screenY, clientX, clientY,
                                                ctrlKey, altKey, shiftKey, metaKey,
                                                touches, targetTouches, changedTouches,
                                                scale, rotation);
                                        } else {
                                            Y.error('simulateTouchEvent(): No touch event simulation framework present for iOS, '+Y.UA.ios+'.');
                                        }
                                    } else {
                                        Y.error('simulateTouchEvent(): Not supported agent yet, '+Y.UA.userAgent);
                                    }
                            
                                    //fire the event
                                    target.dispatchEvent(customEvent);
                                //} else if (Y.Lang.isObject(doc.createEventObject)){ // Windows Mobile/IE, support later
                                } else {
                                    Y.error('simulateTouchEvent(): No event simulation framework present.');
                                }
                            }
                            
                            /**
                             * Simulates the event or gesture with the given name on a target.
                             * @param {HTMLElement} target The DOM element that's the target of the event.
                             * @param {String} type The type of event or name of the supported gesture to simulate
                             *      (i.e., "click", "doubletap", "flick").
                             * @param {Object} options (Optional) Extra options to copy onto the event object.
                             *      For gestures, options are used to refine the gesture behavior.
                             * @for Event
                             * @method simulate
                             * @static
                             */
                            Y.Event.simulate = function(target, type, options){
                            
                                options = options || {};
                            
                                if (mouseEvents[type] || pointerEvents[type]){
                                    simulateMouseEvent(target, type, options.bubbles,
                                        options.cancelable, options.view, options.detail, options.screenX,
                                        options.screenY, options.clientX, options.clientY, options.ctrlKey,
                                        options.altKey, options.shiftKey, options.metaKey, options.button,
                                        options.relatedTarget);
                                } else if (keyEvents[type]){
                                    simulateKeyEvent(target, type, options.bubbles,
                                        options.cancelable, options.view, options.ctrlKey,
                                        options.altKey, options.shiftKey, options.metaKey,
                                        options.keyCode, options.charCode);
                                } else if (uiEvents[type]){
                                    simulateUIEvent(target, type, options.bubbles,
                                        options.cancelable, options.view, options.detail);
                            
                                // touch low-level event simulation
                                } else if (touchEvents[type]) {
                                    if((Y.config.win && ("ontouchstart" in Y.config.win)) && !(Y.UA.phantomjs) && !(Y.UA.chrome && Y.UA.chrome < 6)) {
                                        simulateTouchEvent(target, type,
                                            options.bubbles, options.cancelable, options.view, options.detail,
                                            options.screenX, options.screenY, options.clientX, options.clientY,
                                            options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
                                            options.touches, options.targetTouches, options.changedTouches,
                                            options.scale, options.rotation);
                                    } else {
                                        Y.error("simulate(): Event '" + type + "' can't be simulated. Use gesture-simulate module instead.");
                                    }
                            
                                // ios gesture low-level event simulation (iOS v2+ only)
                                } else if(Y.UA.ios && Y.UA.ios >= 2.0 && gestureEvents[type]) {
                                    simulateGestureEvent(target, type,
                                        options.bubbles, options.cancelable, options.view, options.detail,
                                        options.screenX, options.screenY, options.clientX, options.clientY,
                                        options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
                                        options.scale, options.rotation);
                            
                                // anything else
                                } else {
                                    Y.error("simulate(): Event '" + type + "' can't be simulated.");
                                }
                            };
                            
                            
                            })();