/*******************************************************************************
 * OpenAjax-mashup.js
 *
 * Reference implementation of the OpenAjax Hub, as specified by OpenAjax Alliance.
 * Specification is under development at:
 *
 *   http://www.openajax.org/member/wiki/OpenAjax_Hub_Specification
 *
 * Copyright 2006-2009 OpenAjax Alliance
 *
 * Licensed 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.
 *
 ******************************************************************************/

var OpenAjax = OpenAjax || {};

if ( !OpenAjax.hub ) {  // prevent re-definition of the OpenAjax.hub object

OpenAjax.hub = function() {
	var libs = {};
	var ooh = "org.openajax.hub.";

	return /** @scope OpenAjax.hub */ {
		implementer: "http://openajax.org",
		implVersion: "2.0.4",
		specVersion: "2.0",
		implExtraData: {},
		libraries: libs,

		registerLibrary: function(prefix, nsURL, version, extra) {
			libs[prefix] = {
				prefix: prefix,
				namespaceURI: nsURL,
				version: version,
				extraData: extra
			};
			this.publish(ooh+"registerLibrary", libs[prefix]);
		},

		unregisterLibrary: function(prefix) {
			this.publish(ooh+"unregisterLibrary", libs[prefix]);
			delete libs[prefix];
		}
	};
}();

/**
 * Error
 *
 * Standard Error names used when the standard functions need to throw Errors.
 */
OpenAjax.hub.Error = {
	// Either a required argument is missing or an invalid argument was provided
	BadParameters: "OpenAjax.hub.Error.BadParameters",
	// The specified hub has been disconnected and cannot perform the requested
	// operation:
	Disconnected: "OpenAjax.hub.Error.Disconnected",
	// Container with specified ID already exists:
	Duplicate: "OpenAjax.hub.Error.Duplicate",
	// The specified ManagedHub has no such Container (or it has been removed)
	NoContainer: "OpenAjax.hub.Error.NoContainer",
	// The specified ManagedHub or Container has no such subscription
	NoSubscription: "OpenAjax.hub.Error.NoSubscription",
	// Permission denied by manager's security policy
	NotAllowed: "OpenAjax.hub.Error.NotAllowed",
	// Wrong communications protocol identifier provided by Container or HubClient
	WrongProtocol: "OpenAjax.hub.Error.WrongProtocol",
	// A 'tunnelURI' param was specified, but current browser does not support security features
	IncompatBrowser: "OpenAjax.hub.Error.IncompatBrowser"
};

/**
 * SecurityAlert
 *
 * Standard codes used when attempted security violations are detected. Unlike
 * Errors, these codes are not thrown as exceptions but rather passed into the
 * SecurityAlertHandler function registered with the Hub instance.
 */
OpenAjax.hub.SecurityAlert = {
	// Container did not load (possible frame phishing attack)
	LoadTimeout: "OpenAjax.hub.SecurityAlert.LoadTimeout",
	// Hub suspects a frame phishing attack against the specified container
	FramePhish: "OpenAjax.hub.SecurityAlert.FramePhish",
	// Hub detected a message forgery that purports to come to a specified
	// container
	ForgedMsg: "OpenAjax.hub.SecurityAlert.ForgedMsg"
};

/**
 * Debugging Help
 *
 * OpenAjax.hub.enableDebug
 *
 *      If OpenAjax.hub.enableDebug is set to true, then the "debugger" keyword
 *      will get hit whenever a user callback throws an exception, thereby
 *      bringing up the JavaScript debugger.
 */
OpenAjax.hub._debugger = function() {
};


////////////////////////////////////////////////////////////////////////////////

/**
 * OpenAjax.hub.ManagedHub
 *
 * Managed hub API for the manager application and for Containers.
 *
 * Implements OpenAjax.hub.Hub.
 */

/**
 * Create a new ManagedHub instance
 * @constructor
 *
 * This constructor automatically sets the ManagedHub's state to
 * CONNECTED.
 *
 * @param {Object} params
 *     Parameters used to instantiate the ManagedHub.
 *     Once the constructor is called, the params object belongs exclusively to
 *     the ManagedHub. The caller MUST not modify it.
 *
 * The params object may contain the following properties:
 *
 * @param {Function} params.onPublish
 *     Callback function that is invoked whenever a
 *     data value published by a Container is about
 *     to be delivered to some (possibly the same) Container.
 *     This callback function implements a security policy;
 *     it returns true if the delivery of the data is
 *     permitted and false if permission is denied.
 * @param {Function} params.onSubscribe
 *     Called whenever a Container tries to subscribe
 *     on behalf of its client.
 *     This callback function implements a security policy;
 *     it returns true if the subscription is permitted
 *     and false if permission is denied.
 * @param {Function} [params.onUnsubscribe]
 *     Called whenever a Container unsubscribes on behalf of its client.
 *     Unlike the other callbacks, onUnsubscribe is intended only for
 *     informative purposes, and is not used to implement a security
 *     policy.
 * @param {Object} [params.scope]
 *     Whenever one of the ManagedHub's callback functions is called,
 *     references to the JavaScript "this" keyword in the callback
 *     function refer to this scope object
 *     If no scope is provided, default is window.
 * @param {Function} [params.log]  Optional logger function. Would
 *     be used to log to console.log or equivalent.
 *
 * @throws {OpenAjax.hub.Error.BadParameters} if any of the required
 *     parameters are missing
 */
OpenAjax.hub.ManagedHub = function( params ) {
	if ( ! params || ! params.onPublish || ! params.onSubscribe )
		throw new Error( OpenAjax.hub.Error.BadParameters );

	this._p = params;
	this._onUnsubscribe = params.onUnsubscribe ? params.onUnsubscribe : null;
	this._scope = params.scope || window;

	if ( params.log ) {
		var that = this;
		this._log = function( msg ) {
			try {
				params.log.call( that._scope, "ManagedHub: " + msg );
			} catch( e ) {
				OpenAjax.hub._debugger();
			}
		};
	} else {
		this._log = function() {};
	}

	this._subscriptions = { c:{}, s:null };
	this._containers = {};

	// Sequence # used to create IDs that are unique within this hub
	this._seq = 0;

	this._active = true;

	this._isPublishing = false;
	this._pubQ = [];
};

/**
 * Subscribe to a topic on behalf of a Container. Called only by
 * Container implementations, NOT by manager applications.
 *
 * This function:
 * 1. Checks with the ManagedHub's onSubscribe security policy
 *    to determine whether this Container is allowed to subscribe
 *    to this topic.
 * 2. If the subscribe operation is permitted, subscribes to the
 *    topic and returns the ManagedHub's subscription ID for this
 *    subscription.
 * 3. If the subscribe operation is not permitted, throws
 *    OpenAjax.hub.Error.NotAllowed.
 *
 * When data is published on the topic, the ManagedHub's
 * onPublish security policy will be invoked to ensure that
 * this Container is permitted to receive the published data.
 * If the Container is allowed to receive the data, then the
 * Container's sendToClient function will be invoked.
 *
 * When a Container needs to create a subscription on behalf of
 * its client, the Container MUST use this function to create
 * the subscription.
 *
 * @param {OpenAjax.hub.Container} container
 *     A Container
 * @param {String} topic
 *     A valid topic
 * @param {String} containerSubID
 *     Arbitrary string ID that the Container uses to
 *     represent the subscription. Must be unique within the
 *     context of the Container
 *
 * @returns managerSubID
 *     Arbitrary string ID that this ManagedHub uses to
 *     represent the subscription. Will be unique within the
 *     context of this ManagedHub
 * @type {String}
 *
 * @throws {OpenAjax.hub.Error.Disconnected} if this.isConnected() returns false
 * @throws {OpenAjax.hub.Error.NotAllowed} if subscription request is denied by the onSubscribe security policy
 * @throws {OpenAjax.hub.Error.BadParameters} if one of the parameters, e.g. the topic, is invalid
 */
OpenAjax.hub.ManagedHub.prototype.subscribeForClient = function( container, topic, containerSubID )
{
	this._assertConn();
	// check subscribe permission
	if ( this._invokeOnSubscribe( topic, container ) ) {
		// return ManagedHub's subscriptionID for this subscription
		return this._subscribe( topic, this._sendToClient, this, { c: container, sid: containerSubID } );
	}
	throw new Error(OpenAjax.hub.Error.NotAllowed);
};

/**
 * Unsubscribe from a subscription on behalf of a Container. Called only by
 * Container implementations, NOT by manager application code.
 *
 * This function:
 * 1. Destroys the specified subscription
 * 2. Calls the ManagedHub's onUnsubscribe callback function
 *
 * This function can be called even if the ManagedHub is not in a CONNECTED state.
 *
 * @param {OpenAjax.hub.Container} container
 *    container instance that is unsubscribing
 * @param {String} managerSubID
 *    opaque ID of a subscription, returned by previous call to subscribeForClient()
 *
 * @throws {OpenAjax.hub.Error.NoSubscription} if subscriptionID does not refer to a valid subscription
 */
OpenAjax.hub.ManagedHub.prototype.unsubscribeForClient = function( container, managerSubID )
{
	this._unsubscribe( managerSubID );
	this._invokeOnUnsubscribe( container, managerSubID );
};

/**
 * Publish data on a topic on behalf of a Container. Called only by
 * Container implementations, NOT by manager application code.
 *
 * @param {OpenAjax.hub.Container} container
 *      Container on whose behalf data should be published
 * @param {String} topic
 *      Valid topic string. Must NOT contain wildcards.
 * @param {*} data
 *      Valid publishable data. To be portable across different
 *      Container implementations, this value SHOULD be serializable
 *      as JSON.
 *
 * @throws {OpenAjax.hub.Error.Disconnected} if this.isConnected() returns false
 * @throws {OpenAjax.hub.Error.BadParameters} if one of the parameters, e.g. the topic, is invalid
 */
OpenAjax.hub.ManagedHub.prototype.publishForClient = function( container, topic, data )
{
	this._assertConn();
	this._publish( topic, data, container );
};

/**
 * Destroy this ManagedHub
 *
 * 1. Sets state to DISCONNECTED. All subsequent attempts to add containers,
 *  publish or subscribe will throw the Disconnected error. We will
 *  continue to allow "cleanup" operations such as removeContainer
 *  and unsubscribe, as well as read-only operations such as
 *  isConnected
 * 2. Remove all Containers associated with this ManagedHub
 */
OpenAjax.hub.ManagedHub.prototype.disconnect = function()
{
	this._active = false;
	for (var c in this._containers) {
		this.removeContainer( this._containers[c] );
	}
};

/**
 * Get a container belonging to this ManagedHub by its clientID, or null
 * if this ManagedHub has no such container
 *
 * This function can be called even if the ManagedHub is not in a CONNECTED state.
 *
 * @param {String} containerId
 *      Arbitrary string ID associated with the container
 *
 * @returns container associated with given ID
 * @type {OpenAjax.hub.Container}
 */
OpenAjax.hub.ManagedHub.prototype.getContainer = function( containerId )
{
	var container = this._containers[containerId];
	return container ? container : null;
};

/**
 * Returns an array listing all containers belonging to this ManagedHub.
 * The order of the Containers in this array is arbitrary.
 *
 * This function can be called even if the ManagedHub is not in a CONNECTED state.
 *
 * @returns container array
 * @type {OpenAjax.hub.Container[]}
 */
OpenAjax.hub.ManagedHub.prototype.listContainers = function()
{
	var res = [];
	for (var c in this._containers) {
		res.push(this._containers[c]);
	}
	return res;
};

/**
 * Add a container to this ManagedHub.
 *
 * This function should only be called by a Container constructor.
 *
 * @param {OpenAjax.hub.Container} container
 *      A Container to be added to this ManagedHub
 *
 * @throws {OpenAjax.hub.Error.Duplicate} if there is already a Container
 *      in this ManagedHub whose clientId is the same as that of container
 * @throws {OpenAjax.hub.Error.Disconnected} if this.isConnected() returns false
 */
OpenAjax.hub.ManagedHub.prototype.addContainer = function( container )
{
	this._assertConn();
	var containerId = container.getClientID();
	if ( this._containers[containerId] ) {
		throw new Error(OpenAjax.hub.Error.Duplicate);
	}
	this._containers[containerId] = container;
};

/**
 * Remove a container from this ManagedHub immediately
 *
 * This function can be called even if the ManagedHub is not in a CONNECTED state.
 *
 * @param {OpenAjax.hub.Container} container
 *      A Container to be removed from this ManagedHub
 *
 * @throws {OpenAjax.hub.Error.NoContainer}  if no such container is found
 */
OpenAjax.hub.ManagedHub.prototype.removeContainer = function( container )
{
	var containerId = container.getClientID();
	if ( ! this._containers[ containerId ] ) {
		throw new Error(OpenAjax.hub.Error.NoContainer);
	}
	container.remove();
	delete this._containers[ containerId ];
};

	/*** OpenAjax.hub.Hub interface implementation ***/

/**
 * Subscribe to a topic.
 *
 * This implementation of Hub.subscribe is synchronous. When subscribe
 * is called:
 *
 * 1. The ManagedHub's onSubscribe callback is invoked. The
 * 		container parameter is null, because the manager application,
 * 		rather than a container, is subscribing.
 * 2. If onSubscribe returns true, then the subscription is created.
 * 3. The onComplete callback is invoked.
 * 4. Then this function returns.
 *
 * @param {String} topic
 *     A valid topic string. MAY include wildcards.
 * @param {Function} onData
 *     Callback function that is invoked whenever an event is
 *     published on the topic
 * @param {Object} [scope]
 *     When onData callback or onComplete callback is invoked,
 *     the JavaScript "this" keyword refers to this scope object.
 *     If no scope is provided, default is window.
 * @param {Function} [onComplete]
 *     Invoked to tell the client application whether the
 *     subscribe operation succeeded or failed.
 * @param {*} [subscriberData]
 *     Client application provides this data, which is handed
 *     back to the client application in the subscriberData
 *     parameter of the onData and onComplete callback functions.
 *
 * @returns subscriptionID
 *     Identifier representing the subscription. This identifier is an
 *     arbitrary ID string that is unique within this Hub instance
 * @type {String}
 *
 * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
 * @throws {OpenAjax.hub.Error.BadParameters} if the topic is invalid (e.g. contains an empty token)
 */
OpenAjax.hub.ManagedHub.prototype.subscribe = function( topic, onData, scope, onComplete, subscriberData )
{
	this._assertConn();
	this._assertSubTopic(topic);
	if ( ! onData ) {
		throw new Error( OpenAjax.hub.Error.BadParameters );
	}

	scope = scope || window;

	// check subscribe permission
	if ( ! this._invokeOnSubscribe( topic, null ) ) {
		this._invokeOnComplete( onComplete, scope, null, false, OpenAjax.hub.Error.NotAllowed );
		return;
	}

	// on publish event, check publish permissions
	var that = this;
	function publishCB( topic, data, sd, pcont ) {
		if ( that._invokeOnPublish( topic, data, pcont, null ) ) {
			try {
				onData.call( scope, topic, data, subscriberData );
			} catch( e ) {
				OpenAjax.hub._debugger();
				that._log( "caught error from onData callback to Hub.subscribe(): " + e.message );
			}
		}
	}
	var subID = this._subscribe( topic, publishCB, scope, subscriberData );
	this._invokeOnComplete( onComplete, scope, subID, true );
	return subID;
};

/**
 * Publish an event on a topic
 *
 * This implementation of Hub.publish is synchronous. When publish
 * is called:
 *
 * 1. The target subscriptions are identified.
 * 2. For each target subscription, the ManagedHub's onPublish
 * 		callback is invoked. Data is only delivered to a target
 * 		subscription if the onPublish callback returns true.
 * 		The pcont parameter of the onPublish callback is null.
 *      This is because the ManagedHub, rather than a container,
 *      is publishing the data.
 *
 * @param {String} topic
 *     A valid topic string. MUST NOT include wildcards.
 * @param {*} data
 *     Valid publishable data. To be portable across different
 *     Container implementations, this value SHOULD be serializable
 *     as JSON.
 *
 * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
 * @throws {OpenAjax.hub.Error.BadParameters} if the topic cannot be published (e.g. contains
 *     wildcards or empty tokens) or if the data cannot be published (e.g. cannot be serialized as JSON)
 */
OpenAjax.hub.ManagedHub.prototype.publish = function( topic, data )
{
	this._assertConn();
	this._assertPubTopic(topic);
	this._publish( topic, data, null );
};

/**
 * Unsubscribe from a subscription
 *
 * This implementation of Hub.unsubscribe is synchronous. When unsubscribe
 * is called:
 *
 * 1. The subscription is destroyed.
 * 2. The ManagedHub's onUnsubscribe callback is invoked, if there is one.
 * 3. The onComplete callback is invoked.
 * 4. Then this function returns.
 *
 * @param {String} subscriptionID
 *     A subscriptionID returned by Hub.subscribe()
 * @param {Function} [onComplete]
 *     Callback function invoked when unsubscribe completes
 * @param {Object} [scope]
 *     When onComplete callback function is invoked, the JavaScript "this"
 *     keyword refers to this scope object.
 *     If no scope is provided, default is window.
 *
 * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
 * @throws {OpenAjax.hub.Error.NoSubscription} if no such subscription is found
 */
OpenAjax.hub.ManagedHub.prototype.unsubscribe = function( subscriptionID, onComplete, scope )
{
	this._assertConn();
	if ( ! subscriptionID ) {
		throw new Error( OpenAjax.hub.Error.BadParameters );
	}
	this._unsubscribe( subscriptionID );
	this._invokeOnUnsubscribe( null, subscriptionID );
	this._invokeOnComplete( onComplete, scope, subscriptionID, true );
};

/**
 * Returns true if disconnect() has NOT been called on this ManagedHub,
 * else returns false
 *
 * @returns Boolean
 * @type {Boolean}
 */
OpenAjax.hub.ManagedHub.prototype.isConnected = function()
{
	return this._active;
};

/**
* Returns the scope associated with this Hub instance and which will be used
* with callback functions.
*
* This function can be called even if the Hub is not in a CONNECTED state.
*
* @returns scope object
* @type {Object}
 */
OpenAjax.hub.ManagedHub.prototype.getScope = function()
{
	return this._scope;
};

/**
 * Returns the subscriberData parameter that was provided when
 * Hub.subscribe was called.
 *
 * @param subscriberID
 *     The subscriberID of a subscription
 *
 * @returns subscriberData
 * @type {*}
 *
 * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
 * @throws {OpenAjax.hub.Error.NoSubscription} if there is no such subscription
 */
OpenAjax.hub.ManagedHub.prototype.getSubscriberData = function( subscriberID )
{
	this._assertConn();
	var path = subscriberID.split(".");
	var sid = path.pop();
	var sub = this._getSubscriptionObject( this._subscriptions, path, 0, sid );
	if ( sub )
		return sub.data;
	throw new Error( OpenAjax.hub.Error.NoSubscription );
};

/**
 * Returns the scope associated with a specified subscription.  This scope will
 * be used when invoking the 'onData' callback supplied to Hub.subscribe().
 *
 * @param subscriberID
 *     The subscriberID of a subscription
 *
 * @returns scope
 * @type {*}
 *
 * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
 * @throws {OpenAjax.hub.Error.NoSubscription} if there is no such subscription
 */
OpenAjax.hub.ManagedHub.prototype.getSubscriberScope = function( subscriberID )
{
	this._assertConn();
	var path = subscriberID.split(".");
	var sid = path.pop();
	var sub = this._getSubscriptionObject( this._subscriptions, path, 0, sid );
	if ( sub ) {
		return sub.scope;
	}
	throw new Error( OpenAjax.hub.Error.NoSubscription );
};

/**
 * Returns the params object associated with this Hub instance.
 * Allows mix-in code to access parameters passed into constructor that created
 * this Hub instance.
 *
 * @returns params  the params object associated with this Hub instance
 * @type {Object}
 */
OpenAjax.hub.ManagedHub.prototype.getParameters = function()
{
	return this._p;
};


/* PRIVATE FUNCTIONS */

/**
 * Send a message to a container's client.
 * This is an OAH subscriber's data callback. It is private to ManagedHub
 * and serves as an adapter between the OAH 1.0 API and Container.sendToClient.
 *
 * @param {String} topic Topic on which data was published
 * @param {Object} data  Data to be delivered to the client
 * @param {Object} sd    Object containing properties
 *     c: container to which data must be sent
 *     sid: subscription ID within that container
 * @param {Object} pcont  Publishing container, or null if this data was
 *      published by the manager
 */
OpenAjax.hub.ManagedHub.prototype._sendToClient = function(topic, data, sd, pcont)
{
	if (!this.isConnected()) {
		return;
	}
	if ( this._invokeOnPublish( topic, data, pcont, sd.c ) ) {
		sd.c.sendToClient( topic, data, sd.sid );
	}
};

OpenAjax.hub.ManagedHub.prototype._assertConn = function()
{
	if (!this.isConnected()) {
		throw new Error(OpenAjax.hub.Error.Disconnected);
	}
};

OpenAjax.hub.ManagedHub.prototype._assertPubTopic = function(topic)
{
	if ( !topic || topic === "" || (topic.indexOf("*") != -1) ||
		(topic.indexOf("..") != -1) ||  (topic.charAt(0) == ".") ||
		(topic.charAt(topic.length-1) == "."))
	{
		throw new Error(OpenAjax.hub.Error.BadParameters);
	}
};

OpenAjax.hub.ManagedHub.prototype._assertSubTopic = function(topic)
{
	if ( ! topic ) {
		throw new Error(OpenAjax.hub.Error.BadParameters);
	}
	var path = topic.split(".");
	var len = path.length;
	for (var i = 0; i < len; i++) {
		var p = path[i];
		if ((p === "") ||
		((p.indexOf("*") != -1) && (p != "*") && (p != "**"))) {
			throw new Error(OpenAjax.hub.Error.BadParameters);
		}
		if ((p == "**") && (i < len - 1)) {
			throw new Error(OpenAjax.hub.Error.BadParameters);
		}
	}
};

OpenAjax.hub.ManagedHub.prototype._invokeOnComplete = function( func, scope, item, success, errorCode )
{
	if ( func ) { // onComplete is optional
		try {
			scope = scope || window;
			func.call( scope, item, success, errorCode );
		} catch( e ) {
			OpenAjax.hub._debugger();
			this._log( "caught error from onComplete callback: " + e.message );
		}
	}
};

OpenAjax.hub.ManagedHub.prototype._invokeOnPublish = function( topic, data, pcont, scont )
{
	try {
		return this._p.onPublish.call( this._scope, topic, data, pcont, scont );
	} catch( e ) {
		OpenAjax.hub._debugger();
		this._log( "caught error from onPublish callback to constructor: " + e.message );
	}
	return false;
};

OpenAjax.hub.ManagedHub.prototype._invokeOnSubscribe = function( topic, container )
{
	try {
		return this._p.onSubscribe.call( this._scope, topic, container );
	} catch( e ) {
		OpenAjax.hub._debugger();
		this._log( "caught error from onSubscribe callback to constructor: " + e.message );
	}
	return false;
};

OpenAjax.hub.ManagedHub.prototype._invokeOnUnsubscribe = function( container, managerSubID )
{
	if ( this._onUnsubscribe ) {
		var topic = managerSubID.slice( 0, managerSubID.lastIndexOf(".") );
		try {
			this._onUnsubscribe.call( this._scope, topic, container );
		} catch( e ) {
			OpenAjax.hub._debugger();
			this._log( "caught error from onUnsubscribe callback to constructor: " + e.message );
		}
	}
};

OpenAjax.hub.ManagedHub.prototype._subscribe = function( topic, onData, scope, subscriberData )
{
	var handle = topic + "." + this._seq;
	var sub = { scope: scope, cb: onData, data: subscriberData, sid: this._seq++ };
	var path = topic.split(".");
	this._recursiveSubscribe( this._subscriptions, path, 0, sub );
	return handle;
};

OpenAjax.hub.ManagedHub.prototype._recursiveSubscribe = function(tree, path, index, sub)
{
	var token = path[index];
	if (index == path.length) {
		sub.next = tree.s;
		tree.s = sub;
	} else {
		if (typeof tree.c == "undefined") {
			tree.c = {};
		}
		if (typeof tree.c[token] == "undefined") {
			tree.c[token] = { c: {}, s: null };
			this._recursiveSubscribe(tree.c[token], path, index + 1, sub);
		} else {
			this._recursiveSubscribe( tree.c[token], path, index + 1, sub);
		}
	}
};

OpenAjax.hub.ManagedHub.prototype._publish = function( topic, data, pcont )
{
	// if we are currently handling a publish event, then queue this request
	// and handle later, one by one
	if ( this._isPublishing ) {
		this._pubQ.push( { t: topic, d: data, p: pcont } );
		return;
	}

	this._safePublish( topic, data, pcont );

	while ( this._pubQ.length > 0 ) {
		var pub = this._pubQ.shift();
		this._safePublish( pub.t, pub.d, pub.p );
	}
};

OpenAjax.hub.ManagedHub.prototype._safePublish = function( topic, data, pcont )
{
	this._isPublishing = true;
	var path = topic.split(".");
	this._recursivePublish( this._subscriptions, path, 0, topic, data, pcont );
	this._isPublishing = false;
};

OpenAjax.hub.ManagedHub.prototype._recursivePublish = function(tree, path, index, name, msg, pcont)
{
	if (typeof tree != "undefined") {
		var node;
		if (index == path.length) {
			node = tree;
		} else {
			this._recursivePublish(tree.c[path[index]], path, index + 1, name, msg, pcont);
			this._recursivePublish(tree.c["*"], path, index + 1, name, msg, pcont);
			node = tree.c["**"];
		}
		if (typeof node != "undefined") {
			var sub = node.s;
			while ( sub ) {
				var sc = sub.scope;
				var cb = sub.cb;
				var d = sub.data;
				if (typeof cb == "string") {
					// get a function object
					cb = sc[cb];
				}
				cb.call(sc, name, msg, d, pcont);
				sub = sub.next;
			}
		}
	}
};

OpenAjax.hub.ManagedHub.prototype._unsubscribe = function( subscriptionID )
{
	var path = subscriptionID.split(".");
	var sid = path.pop();
	if ( ! this._recursiveUnsubscribe( this._subscriptions, path, 0, sid ) ) {
		throw new Error( OpenAjax.hub.Error.NoSubscription );
	}
};

/**
 * @returns 'true' if properly unsubscribed; 'false' otherwise
 */
OpenAjax.hub.ManagedHub.prototype._recursiveUnsubscribe = function(tree, path, index, sid)
{
	if ( typeof tree == "undefined" ) {
		return false;
	}

	if (index < path.length) {
		var childNode = tree.c[path[index]];
		if ( ! childNode ) {
			return false;
		}
		this._recursiveUnsubscribe(childNode, path, index + 1, sid);
		if ( ! childNode.s ) {
			for (var x in childNode.c) {
				return true;
			}
			delete tree.c[path[index]];
		}
	} else {
		var sub = tree.s;
		var sub_prev = null;
		var found = false;
		while ( sub ) {
			if ( sid == sub.sid ) {
				found = true;
				if ( sub == tree.s ) {
					tree.s = sub.next;
				} else {
					sub_prev.next = sub.next;
				}
				break;
			}
			sub_prev = sub;
			sub = sub.next;
		}
		if ( ! found ) {
			return false;
		}
	}

	return true;
};

OpenAjax.hub.ManagedHub.prototype._getSubscriptionObject = function( tree, path, index, sid )
{
	if (typeof tree != "undefined") {
		if (index < path.length) {
			var childNode = tree.c[path[index]];
			return this._getSubscriptionObject(childNode, path, index + 1, sid);
		}

		var sub = tree.s;
		while ( sub ) {
			if ( sid == sub.sid ) {
				return sub;
			}
			sub = sub.next;
		}
	}
	return null;
};


/**
 * OpenAjax.hub._hub is the default ManagedHub instance that we use to
 * provide OAH 1.0 behavior.
 */
OpenAjax.hub._hub = new OpenAjax.hub.ManagedHub({
	onSubscribe: function(topic, ctnr) { return true; },
	onPublish: function(topic, data, pcont, scont) { return true; }
});

/**
 * Subscribe to a topic.
 *
 * @param {String} topic
 *     A valid topic string. MAY include wildcards.
 * @param {Function|String} onData
 *     Callback function that is invoked whenever an event is published on the
 *     topic.  If 'onData' is a string, then it represents the name of a
 *     function on the 'scope' object.
 * @param {Object} [scope]
 *     When onData callback is invoked,
 *     the JavaScript "this" keyword refers to this scope object.
 *     If no scope is provided, default is window.
 * @param {*} [subscriberData]
 *     Client application provides this data, which is handed
 *     back to the client application in the subscriberData
 *     parameter of the onData callback function.
 *
 * @returns {String} Identifier representing the subscription.
 *
 * @throws {OpenAjax.hub.Error.BadParameters} if the topic is invalid
 *     (e.g.contains an empty token)
 */
OpenAjax.hub.subscribe = function(topic, onData, scope, subscriberData)
{
	// resolve the 'onData' function if it is a string
	if ( typeof onData === "string" ) {
		scope = scope || window;
		onData = scope[ onData ] || null;
	}

	return OpenAjax.hub._hub.subscribe( topic, onData, scope, null, subscriberData );
};

/**
 * Unsubscribe from a subscription.
 *
 * @param {String} subscriptionID
 *     Subscription identifier returned by subscribe()
 *
 * @throws {OpenAjax.hub.Error.NoSubscription} if no such subscription is found
 */
OpenAjax.hub.unsubscribe = function(subscriptionID)
{
	return OpenAjax.hub._hub.unsubscribe( subscriptionID );
};

/**
 * Publish an event on a topic.
 *
 * @param {String} topic
 *     A valid topic string. MUST NOT include wildcards.
 * @param {*} data
 *     Valid publishable data.
 *
 * @throws {OpenAjax.hub.Error.BadParameters} if the topic cannot be published
 *     (e.g. contains wildcards or empty tokens)
 */
OpenAjax.hub.publish = function(topic, data)
{
	OpenAjax.hub._hub.publish(topic, data);
};

////////////////////////////////////////////////////////////////////////////////

// Register the OpenAjax Hub itself as a library.
OpenAjax.hub.registerLibrary("OpenAjax", "http://openajax.org/hub", "2.0", {});

} // !OpenAjax.hub
/*

		Copyright 2006-2009 OpenAjax Alliance

		Licensed 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.
*/

/**
 * Create a new Inline Container.
 * @constructor
 * @extends OpenAjax.hub.Container
 *
 * InlineContainer implements the Container interface to provide a container
 * that places components within the same browser frame as the main mashup
 * application. As such, this container does not isolate client components into
 * secure sandboxes.
 *
 * @param {OpenAjax.hub.ManagedHub} hub
 *    Managed Hub instance to which this Container belongs
 * @param {String} clientID
 *    A string ID that identifies a particular client of a Managed Hub. Unique
 *    within the context of the ManagedHub.
 * @param {Object} params
 *    Parameters used to instantiate the InlineContainer.
 *    Once the constructor is called, the params object belongs exclusively to
 *    the InlineContainer. The caller MUST not modify it.
 *    The following are the pre-defined properties on params:
 * @param {Function} params.Container.onSecurityAlert
 *    Called when an attempted security breach is thwarted.  Function is defined
 *    as follows:  function(container, securityAlert)
 * @param {Function} [params.Container.onConnect]
 *    Called when the client connects to the Managed Hub.  Function is defined
 *    as follows:  function(container)
 * @param {Function} [params.Container.onDisconnect]
 *    Called when the client disconnects from the Managed Hub.  Function is
 *    defined as follows:  function(container)
 * @param {Object} [params.Container.scope]
 *    Whenever one of the Container's callback functions is called, references
 *    to "this" in the callback will refer to the scope object. If no scope is
 *    provided, default is window.
 * @param {Function} [params.Container.log]
 *    Optional logger function. Would be used to log to console.log or
 *    equivalent.
 *
 * @throws {OpenAjax.hub.Error.BadParameters}   if required params are not
 *    present or null
 * @throws {OpenAjax.hub.Error.Duplicate}   if a Container with this clientID
 *    already exists in the given Managed Hub
 * @throws {OpenAjax.hub.Error.Disconnected}   if ManagedHub is not connected
 */
OpenAjax.hub.InlineContainer = function( hub, clientID, params )
{
	if ( ! hub || ! clientID || ! params ||
			! params.Container || ! params.Container.onSecurityAlert ) {
		throw new Error(OpenAjax.hub.Error.BadParameters);
	}

	var cbScope = params.Container.scope || window;
	var connected = false;
	var subs = [];
	var subIndex = 0;
	var client = null;

	if ( params.Container.log ) {
		var log = function( msg ) {
			try {
				params.Container.log.call( cbScope, "InlineContainer::" + clientID + ": " + msg );
			} catch( e ) {
				OpenAjax.hub._debugger();
			}
		};
	} else {
		log = function() {};
	}

	this._init = function() {
		hub.addContainer( this );
	};

/*** OpenAjax.hub.Container interface implementation ***/

	this.getHub = function() {
		return hub;
	};

	this.sendToClient = function( topic, data, subscriptionID ) {
		if ( connected ) {
			var sub = subs[ subscriptionID ];
			try {
				sub.cb.call( sub.sc, topic, data, sub.d );
			} catch( e ) {
				OpenAjax.hub._debugger();
				client._log( "caught error from onData callback to HubClient.subscribe(): " + e.message );
			}
		}
	};

	this.remove = function() {
		if ( connected ) {
			finishDisconnect();
		}
	};

	this.isConnected = function() {
		return connected;
	};

	this.getClientID = function() {
		return clientID;
	};

	this.getPartnerOrigin = function() {
		if ( connected ) {
			return window.location.protocol + "//" + window.location.hostname;
		}
		return null;
	};

	this.getParameters = function() {
		return params;
	};

/*** OpenAjax.hub.HubClient interface implementation ***/

	this.connect = function( hubClient, onComplete, scope ) {
		if ( connected ) {
			throw new Error( OpenAjax.hub.Error.Duplicate );
		}

		connected = true;
		client = hubClient;

		if ( params.Container.onConnect ) {
			try {
				params.Container.onConnect.call( cbScope, this );
			} catch( e ) {
				OpenAjax.hub._debugger();
				log( "caught error from onConnect callback to constructor: " + e.message );
			}
		}

		invokeOnComplete( onComplete, scope, hubClient, true );
	};

	this.disconnect = function( hubClient, onComplete, scope ) {
		if ( ! connected ) {
			throw new Error( OpenAjax.hub.Error.Disconnected );
		}

		finishDisconnect();

		if ( params.Container.onDisconnect ) {
			try {
				params.Container.onDisconnect.call( cbScope, this );
			} catch( e ) {
				OpenAjax.hub._debugger();
				log( "caught error from onDisconnect callback to constructor: " + e.message );
			}
		}

		invokeOnComplete( onComplete, scope, hubClient, true );
	};

/*** OpenAjax.hub.Hub interface implementation ***/

	this.subscribe = function( topic, onData, scope, onComplete, subscriberData ) {
		assertConn();
		assertSubTopic( topic );
		if ( ! onData ) {
			throw new Error( OpenAjax.hub.Error.BadParameters );
		}

		var subID = "" + subIndex++;
		var success = false;
		var msg = null;
		try {
			var handle = hub.subscribeForClient( this, topic, subID );
			success = true;
		} catch( e ) {
			// failure
			subID = null;
			msg = e.message;
		}

		scope = scope || window;
		if ( success ) {
			subs[ subID ] = { h: handle, cb: onData, sc: scope, d: subscriberData };
		}

		invokeOnComplete( onComplete, scope, subID, success, msg );
		return subID;
	};

	this.publish = function( topic, data ) {
		assertConn();
		assertPubTopic( topic );
		hub.publishForClient( this, topic, data );
	};

	this.unsubscribe = function( subscriptionID, onComplete, scope ) {
		assertConn();
		if ( typeof subscriptionID === "undefined" || subscriptionID === null ) {
			throw new Error( OpenAjax.hub.Error.BadParameters );
		}
		var sub = subs[ subscriptionID ];
		if ( ! sub ) {
			throw new Error( OpenAjax.hub.Error.NoSubscription );
		}
		hub.unsubscribeForClient( this, sub.h );
		delete subs[ subscriptionID ];

		invokeOnComplete( onComplete, scope, subscriptionID, true );
	};

	this.getSubscriberData = function( subID ) {
		assertConn();
		return getSubscription( subID ).d;
	};

	this.getSubscriberScope = function( subID ) {
		assertConn();
		return getSubscription( subID ).sc;
	};

/*** PRIVATE FUNCTIONS ***/

	function invokeOnComplete( func, scope, item, success, errorCode ) {
		if ( func ) { // onComplete is optional
			try {
				scope = scope || window;
				func.call( scope, item, success, errorCode );
			} catch( e ) {
				OpenAjax.hub._debugger();
				// invokeOnComplete is only called for client interfaces (Hub and HubClient)
				client._log( "caught error from onComplete callback: " + e.message );
			}
		}
	}

	function finishDisconnect() {
		for ( var subID in subs ) {
			hub.unsubscribeForClient( this, subs[subID].h );
		}
		subs = [];
		subIndex = 0;
		connected = false;
	}

	function assertConn() {
		if ( ! connected ) {
			throw new Error( OpenAjax.hub.Error.Disconnected );
		}
	}

	function assertPubTopic( topic ) {
		if ((topic == null) || (topic === "") || (topic.indexOf("*") != -1) ||
			(topic.indexOf("..") != -1) ||  (topic.charAt(0) == ".") ||
			(topic.charAt(topic.length-1) == "."))
		{
			throw new Error(OpenAjax.hub.Error.BadParameters);
		}
	}

	function assertSubTopic( topic ) {
		if ( ! topic ) {
			throw new Error(OpenAjax.hub.Error.BadParameters);
		}
		var path = topic.split(".");
		var len = path.length;
		for (var i = 0; i < len; i++) {
			var p = path[i];
			if ((p === "") ||
			((p.indexOf("*") != -1) && (p != "*") && (p != "**"))) {
				throw new Error(OpenAjax.hub.Error.BadParameters);
			}
			if ((p == "**") && (i < len - 1)) {
				throw new Error(OpenAjax.hub.Error.BadParameters);
			}
		}
	}

	function getSubscription( subID ) {
		var sub = subs[ subID ];
		if ( sub ) {
			return sub;
		}
		throw new Error( OpenAjax.hub.Error.NoSubscription );
	}


	this._init();
};

////////////////////////////////////////////////////////////////////////////////

/**
 * Create a new InlineHubClient.
 * @constructor
 * @extends OpenAjax.hub.HubClient
 *
 * @param {Object} params
 *    Parameters used to instantiate the HubClient.
 *    Once the constructor is called, the params object belongs to the
 *    HubClient. The caller MUST not modify it.
 *    The following are the pre-defined properties on params:
 * @param {Function} params.HubClient.onSecurityAlert
 *     Called when an attempted security breach is thwarted
 * @param {Object} [params.HubClient.scope]
 *     Whenever one of the HubClient's callback functions is called,
 *     references to "this" in the callback will refer to the scope object.
 *     If not provided, the default is window.
 * @param {Function} [params.HubClient.log]
 *     Optional logger function. Would be used to log to console.log or
 *     equivalent.
 * @param {OpenAjax.hub.InlineContainer} params.InlineHubClient.container
 *     Specifies the InlineContainer to which this HubClient will connect
 *
 * @throws {OpenAjax.hub.Error.BadParameters} if any of the required
 *     parameters are missing
 */
OpenAjax.hub.InlineHubClient = function( params )
{
	if ( ! params || ! params.HubClient || ! params.HubClient.onSecurityAlert ||
			! params.InlineHubClient || ! params.InlineHubClient.container ) {
		throw new Error(OpenAjax.hub.Error.BadParameters);
	}

	var container = params.InlineHubClient.container;
	var scope = params.HubClient.scope || window;

	if ( params.HubClient.log ) {
		var log = function( msg ) {
			try {
				params.HubClient.log.call( scope, "InlineHubClient::" + container.getClientID() + ": " + msg );
			} catch( e ) {
				OpenAjax.hub._debugger();
			}
		};
	} else {
		log = function() {};
	}
	this._log = log;

/*** OpenAjax.hub.HubClient interface implementation ***/

	/**
	 * Requests a connection to the ManagedHub, via the InlineContainer
	 * associated with this InlineHubClient.
	 *
	 * If the Container accepts the connection request, this HubClient's
	 * state is set to CONNECTED and the HubClient invokes the
	 * onComplete callback function.
	 *
	 * If the Container refuses the connection request, the HubClient
	 * invokes the onComplete callback function with an error code.
	 * The error code might, for example, indicate that the Container
	 * is being destroyed.
	 *
	 * If the HubClient is already connected, calling connect will cause
	 * the HubClient to immediately invoke the onComplete callback with
	 * the error code OpenAjax.hub.Error.Duplicate.
	 *
	 * @param {Function} [onComplete]
	 *     Callback function to call when this operation completes.
	 * @param {Object} [scope]
	 *     When the onComplete function is invoked, the JavaScript "this"
	 *     keyword refers to this scope object.
	 *     If no scope is provided, default is window.
	 *
	 * In this implementation of InlineHubClient, this function operates
	 * SYNCHRONOUSLY, so the onComplete callback function is invoked before
	 * this connect function returns. Developers are cautioned that in
	 * IframeHubClient implementations, this is not the case.
	 *
	 * A client application may call InlineHubClient.disconnect and then call
	 * InlineHubClient.connect to reconnect to the Managed Hub.
	 */
	this.connect = function( onComplete, scope ) {
		container.connect( this, onComplete, scope );
	};

	/**
	 * Disconnect from the ManagedHub
	 *
	 * Disconnect immediately:
	 *
	 * 1. Sets the HubClient's state to DISCONNECTED.
	 * 2. Causes the HubClient to send a Disconnect request to the
	 * 		associated Container.
	 * 3. Ensures that the client application will receive no more
	 * 		onData or onComplete callbacks associated with this
	 * 		connection, except for the disconnect function's own
	 * 		onComplete callback.
	 * 4. Automatically destroys all of the HubClient's subscriptions.
	 *
	 * @param {Function} [onComplete]
	 *     Callback function to call when this operation completes.
	 * @param {Object} [scope]
	 *     When the onComplete function is invoked, the JavaScript "this"
	 *     keyword refers to the scope object.
	 *     If no scope is provided, default is window.
	 *
	 * In this implementation of InlineHubClient, the disconnect function operates
	 * SYNCHRONOUSLY, so the onComplete callback function is invoked before
	 * this function returns. Developers are cautioned that in IframeHubClient
	 * implementations, this is not the case.
	 *
	 * A client application is allowed to call HubClient.disconnect and
	 * then call HubClient.connect in order to reconnect.
	 */
	this.disconnect = function( onComplete, scope ) {
		container.disconnect( this, onComplete, scope );
	};

	this.getPartnerOrigin = function() {
		return container.getPartnerOrigin();
	};

	this.getClientID = function() {
		return container.getClientID();
	};

/*** OpenAjax.hub.Hub interface implementation ***/

	/**
	 * Subscribe to a topic.
	 *
	 * @param {String} topic
	 *     A valid topic string. MAY include wildcards.
	 * @param {Function} onData
	 *     Callback function that is invoked whenever an event is
	 *     published on the topic
	 * @param {Object} [scope]
	 *     When onData callback or onComplete callback is invoked,
	 *     the JavaScript "this" keyword refers to this scope object.
	 *     If no scope is provided, default is window.
	 * @param {Function} [onComplete]
	 *     Invoked to tell the client application whether the
	 *     subscribe operation succeeded or failed.
	 * @param {*} [subscriberData]
	 *     Client application provides this data, which is handed
	 *     back to the client application in the subscriberData
	 *     parameter of the onData and onComplete callback functions.
	 *
	 * @returns subscriptionID
	 *     Identifier representing the subscription. This identifier is an
	 *     arbitrary ID string that is unique within this Hub instance
	 * @type {String}
	 *
	 * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance is not in CONNECTED state
	 * @throws {OpenAjax.hub.Error.BadParameters} if the topic is invalid (e.g. contains an empty token)
	 *
	 * In this implementation of InlineHubClient, the subscribe function operates
	 * Thus, onComplete is invoked before this function returns. Developers are
	 * cautioned that in most implementations of HubClient, onComplete is invoked
	 * after this function returns.
	 *
	 * If unsubscribe is called before subscribe completes, the subscription is
	 * immediately terminated, and onComplete is never invoked.
	 */
	this.subscribe = function( topic, onData, scope, onComplete, subscriberData ) {
		return container.subscribe( topic, onData, scope, onComplete, subscriberData );
	};

	/**
	 * Publish an event on 'topic' with the given data.
	 *
	 * @param {String} topic
	 *     A valid topic string. MUST NOT include wildcards.
	 * @param {*} data
	 *     Valid publishable data. To be portable across different
	 *     Container implementations, this value SHOULD be serializable
	 *     as JSON.
	 *
	 * @throws {OpenAjax.hub.Error.Disconnected} if this Hub instance
	 *     is not in CONNECTED state
	 *
	 * In this implementation, publish operates SYNCHRONOUSLY.
	 * Data will be delivered to subscribers after this function returns.
	 * In most implementations, publish operates synchronously,
	 * delivering its data to the clients before this function returns.
	 */
	this.publish = function( topic, data ) {
		container.publish( topic, data );
	};

	/**
	 * Unsubscribe from a subscription
	 *
	 * @param {String} subscriptionID
	 *     A subscriptionID returned by InlineHubClient.prototype.subscribe()
	 * @param {Function} [onComplete]
	 *     Callback function invoked when unsubscribe completes
	 * @param {Object} [scope]
	 *     When onComplete callback function is invoked, the JavaScript "this"
	 *     keyword refers to this scope object.
	 *
	 * @throws {OpenAjax.hub.Error.NoSubscription} if no such subscription is found
	 *
	 * To facilitate cleanup, it is possible to call unsubscribe even
	 * when the HubClient is in a DISCONNECTED state.
	 *
	 * In this implementation of HubClient, this function operates SYNCHRONOUSLY.
	 * Thus, onComplete is invoked before this function returns. Developers are
	 * cautioned that in most implementations of HubClient, onComplete is invoked
	 * after this function returns.
	 */
	this.unsubscribe = function( subscriptionID, onComplete, scope ) {
		container.unsubscribe( subscriptionID, onComplete, scope );
	};

	this.isConnected = function() {
		return container.isConnected();
	};

	this.getScope = function() {
		return scope;
	};

	this.getSubscriberData = function( subID ) {
		return container.getSubscriberData( subID );
	};

	this.getSubscriberScope = function( subID ) {
		return container.getSubscriberScope( subID );
	};

	/**
	 * Returns the params object associated with this Hub instance.
	 * Allows mix-in code to access parameters passed into constructor that created
	 * this Hub instance.
	 *
	 * @returns params  the params object associated with this Hub instance
	 * @type {Object}
	 */
	this.getParameters = function() {
		return params;
	};
};/*

		Copyright 2006-2009 OpenAjax Alliance

		Licensed 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.
*/

var OpenAjax = OpenAjax || {};
OpenAjax.hub = OpenAjax.hub || {};
OpenAjax.gadgets = typeof OpenAjax.gadgets === 'object' ? OpenAjax.gadgets :
				typeof gadgets === 'object' ? gadgets :
				{};
OpenAjax.gadgets.rpctx = OpenAjax.gadgets.rpctx || {};

(function() {
	// For now, we only use "oaaConfig" for the global "gadgets" object.  If the "gadgets" global
	// already exists, then there is no reason to check for "oaaConfig".  In the future, if we use
	// "oaaConfig" for other purposes, we'll need to remove the check for "!window.gadgets".
	if (typeof gadgets === 'undefined') {
		// "oaaConfig" can be specified as a global object.  If not found, then look for it as an
		// attribute on the script line for the OpenAjax Hub JS file.
		if (typeof oaaConfig === 'undefined') {
			var scripts = document.getElementsByTagName("script");
			// match "OpenAjax-mashup.js", "OpenAjaxManagedHub-all*.js", "OpenAjaxManagedHub-core*.js"
			var reHub = /openajax(?:managedhub-(?:all|core).*|-mashup)\.js$/i;
			for ( var i = scripts.length - 1; i >= 0; i-- ) {
				var src = scripts[i].getAttribute( "src" );
				if ( !src ) {
					continue;
				}

				var m = src.match( reHub );
				if ( m ) {
					var config = scripts[i].getAttribute( "oaaConfig" );
					if ( config ) {
						try {
							oaaConfig = eval( "({ " + config + " })" );
						} catch (e) {}
					}
					break;
				}
			}
		}

		if (typeof oaaConfig !== 'undefined' && oaaConfig.gadgetsGlobal) {
			gadgets = OpenAjax.gadgets;
		}
	}
})();


if (!OpenAjax.hub.IframeContainer) {

(function(){

/**
 * Create a new Iframe Container.
 * @constructor
 * @extends OpenAjax.hub.Container
 *
 * IframeContainer implements the Container interface to provide a container
 * that isolates client components into secure sandboxes by leveraging the
 * isolation features provided by browser iframes.
 *
 * SECURITY
 *
 * In order for the connection between the IframeContainer and IframeHubClient
 * to be fully secure, you must specify a valid 'tunnelURI'. Note that if you
 * do specify a 'tunnelURI', then only the WPM and NIX transports are used,
 * covering the following browsers:
 *   IE 6+, Firefox 3+, Safari 4+, Chrome 2+, Opera 9+.
 *
 * If no 'tunnelURI' is specified, then some security features are disabled:
 * the IframeContainer will not report FramePhish errors, and on some browsers
 * IframeContainer and IframeHubClient will not be able to validate the
 * identity of their partner (i.e. getPartnerOrigin() will return 'null').
 * However, not providing 'tunnelURI' allows the additional use of the RMR
 * and FE transports -- in addition to the above browsers, the Hub code will
 * also work on:
 *   Firefox 1 & 2, Safari 2 & 3, Chrome 1.
 *
 * @param {OpenAjax.hub.ManagedHub} hub
 *    Managed Hub instance to which this Container belongs
 * @param {String} clientID
 *    A string ID that identifies a particular client of a Managed Hub. Unique
 *    within the context of the ManagedHub.
 * @param {Object} params
 *    Parameters used to instantiate the IframeContainer.
 *    Once the constructor is called, the params object belongs exclusively to
 *    the IframeContainer. The caller MUST not modify it.
 *    The following are the pre-defined properties on params:
 * @param {Function} params.Container.onSecurityAlert
 *    Called when an attempted security breach is thwarted.  Function is defined
 *    as follows:  function(container, securityAlert)
 * @param {Function} [params.Container.onConnect]
 *    Called when the client connects to the Managed Hub.  Function is defined
 *    as follows:  function(container)
 * @param {Function} [params.Container.onDisconnect]
 *    Called when the client disconnects from the Managed Hub.  Function is
 *    defined as follows:  function(container)
 * @param {Object} [params.Container.scope]
 *    Whenever one of the Container's callback functions is called, references
 *    to "this" in the callback will refer to the scope object. If no scope is
 *    provided, default is window.
 * @param {Function} [params.Container.log]
 *    Optional logger function. Would be used to log to console.log or
 *    equivalent.
 * @param {Object} params.IframeContainer.parent
 *    DOM element that is to be parent of iframe
 * @param {String} params.IframeContainer.uri
 *    Initial Iframe URI (Container will add parameters to this URI)
 * @param {String} [params.IframeContainer.tunnelURI]
 *    URI of the tunnel iframe. Must be from the same origin as the page which
 *    instantiates the IframeContainer. If not specified, connection will not
 *    be fully secure (see SECURITY section).
 * @param {Object} [params.IframeContainer.iframeAttrs]
 *    Attributes to add to IFRAME DOM entity.  For example:
 *              { style: { width: "100%",
 *                         height: "100%" },
 *                className: "some_class" }
 * @param {Number} [params.IframeContainer.timeout]
 *    Load timeout in milliseconds.  If not specified, defaults to 15000.  If
 *    the client at params.IframeContainer.uri does not establish a connection
 *    with this container in the given time, the onSecurityAlert callback is
 *    called with a LoadTimeout error code.
 * @param {Function} [params.IframeContainer.seed]
 *    A function that returns a string that will be used to seed the
 *    pseudo-random number generator, which is used to create the security
 *    tokens.  An implementation of IframeContainer may choose to ignore this
 *    value.
 * @param {Number} [params.IframeContainer.tokenLength]
 *    Length of the security tokens used when transmitting messages.  If not
 *    specified, defaults to 6.  An implementation of IframeContainer may choose
 *    to ignore this value.
 *
 * @throws {OpenAjax.hub.Error.BadParameters}   if required params are not
 *          present or null
 * @throws {OpenAjax.hub.Error.Duplicate}   if a Container with this clientID
 *          already exists in the given Managed Hub
 * @throws {OpenAjax.hub.Error.Disconnected}   if hub is not connected
 */
OpenAjax.hub.IframeContainer = function( hub, clientID, params )
{
	assertValidParams( arguments );

	var container = this;
	var scope = params.Container.scope || window;
	var connected = false;
	var subs = {};
	var securityToken;
	var internalID;
	var timeout = params.IframeContainer.timeout || 15000;
	var loadTimer;

	if ( params.Container.log ) {
		var log = function( msg ) {
			try {
				params.Container.log.call( scope, "IframeContainer::" + clientID + ": " + msg );
			} catch( e ) {
				OpenAjax.hub._debugger();
			}
		};
	} else {
		log = function() {};
	}


	this._init = function() {
		// add to ManagedHub first, to see if clientID is a duplicate
		hub.addContainer( this );

		// Create an "internal" ID, which is guaranteed to be unique within the
		// window, not just within the hub.
		internalID = OpenAjax.hub.IframeContainer._rpcRouter.add( clientID, this );
		securityToken = generateSecurityToken( params, scope, log );

		var relay = null;
		var transportName = OpenAjax.gadgets.rpc.getRelayChannel();
		if ( params.IframeContainer.tunnelURI ) {
			if ( transportName !== "wpm" && transportName !== "nix" ) {
				throw new Error( OpenAjax.hub.Error.IncompatBrowser );
			}
		} else {
			log( "WARNING: Parameter 'IframeContaienr.tunnelURI' not specified. Connection will not be fully secure." );
			if ( transportName === "rmr" ) {
				relay = OpenAjax.gadgets.rpc.getOrigin( params.IframeContainer.uri ) + "/robots.txt";
			}
		}

		// Create IFRAME to hold the client
		createIframe();

		OpenAjax.gadgets.rpc.setupReceiver( internalID, relay );

		startLoadTimer();
	};


/*** OpenAjax.hub.Container interface ***/

	this.sendToClient = function( topic, data, subscriptionID ) {
		OpenAjax.gadgets.rpc.call( internalID, "openajax.pubsub", null, "pub", topic, data,
								subscriptionID );
	};

	this.remove = function() {
		finishDisconnect();
		clearTimeout( loadTimer );
		OpenAjax.gadgets.rpc.removeReceiver( internalID );
		var iframe = document.getElementById( internalID );
		iframe.parentNode.removeChild( iframe );
		OpenAjax.hub.IframeContainer._rpcRouter.remove( internalID );
	};

	this.isConnected = function() {
		return connected;
	};

	this.getClientID = function() {
		return clientID;
	};

	this.getPartnerOrigin = function() {
		if ( connected ) {
			var origin = OpenAjax.gadgets.rpc.getReceiverOrigin( internalID );
			if ( origin ) {
				// remove port if present
				return ( /^([a-zA-Z]+:\/\/[^:]+).*/.exec( origin )[1] );
			}
		}
		return null;
	};

	this.getParameters = function() {
		return params;
	};

	this.getHub = function() {
		return hub;
	};


/*** OpenAjax.hub.IframeContainer interface ***/

	/**
	 * Get the iframe associated with this iframe container
	 *
	 * This function returns the iframe associated with an IframeContainer,
	 * allowing the Manager Application to change its size, styles, scrollbars, etc.
	 *
	 * CAUTION: The iframe is owned exclusively by the IframeContainer. The Manager
	 * Application MUST NOT destroy the iframe directly. Also, if the iframe is
	 * hidden and disconnected, the Manager Application SHOULD NOT attempt to make
	 * it visible. The Container SHOULD automatically hide the iframe when it is
	 * disconnected; to make it visible would introduce security risks.
	 *
	 * @returns iframeElement
	 * @type {Object}
	 */
	this.getIframe = function() {
		return document.getElementById( internalID );
	};


/*** private functions ***/

	function assertValidParams( args ) {
		var hub = args[0],
			clientID = args[1],
			params = args[2];
		if ( ! hub || ! clientID || ! params || ! params.Container ||
			! params.Container.onSecurityAlert || ! params.IframeContainer ||
			! params.IframeContainer.parent || ! params.IframeContainer.uri ) {
			throw new Error( OpenAjax.hub.Error.BadParameters );
		}
	}

	this._handleIncomingRPC = function( command, topic, data ) {
		switch ( command ) {
			// publish
			// 'data' is topic message
			case "pub":
				hub.publishForClient( container, topic, data );
				break;

			// subscribe
			// 'data' is subscription ID
			case "sub":
				var errCode = "";  // empty string is success
				try {
					subs[ data ] = hub.subscribeForClient( container, topic, data );
				} catch( e ) {
					errCode = e.message;
				}
				return errCode;

			// unsubscribe
			// 'data' is subscription ID
			case "uns":
				var handle = subs[ data ];
				hub.unsubscribeForClient( container, handle );
				delete subs[ data ];
				return data;

			// connect
			case "con":
				finishConnect();
				return true;

			// disconnect
			case "dis":
				startLoadTimer();
				finishDisconnect();
				if ( params.Container.onDisconnect ) {
					try {
						params.Container.onDisconnect.call( scope, container );
					} catch( e ) {
						OpenAjax.hub._debugger();
						log( "caught error from onDisconnect callback to constructor: " + e.message );
					}
				}
				return true;
		}
	};

	this._onSecurityAlert = function( error ) {
		invokeSecurityAlert( rpcErrorsToOAA[ error ] );
	};

	// The RPC code requires that the 'name' attribute be properly set on the
	// iframe.  However, setting the 'name' property on the iframe object
	// returned from 'createElement("iframe")' doesn't work on IE --
	// 'window.name' returns null for the code within the iframe.  The
	// workaround is to set the 'innerHTML' of a span to the iframe's HTML code,
	// with 'name' and other attributes properly set.
	function createIframe() {
		var span = document.createElement( "span" );
		params.IframeContainer.parent.appendChild( span );

		var iframeText = '<iframe id="' + internalID + '" name="' + internalID +
				'" src="javascript:\'<html></html>\'"';

		// Add iframe attributes
		var styleText = '';
		var attrs = params.IframeContainer.iframeAttrs;
		if ( attrs ) {
			for ( var attr in attrs ) {
				switch ( attr ) {
					case "style":
						for ( var style in attrs.style ) {
							styleText += style + ':' + attrs.style[ style ] + ';';
						}
						break;
					case "className":
						iframeText += ' class="' + attrs[ attr ] + '"';
						break;
					default:
						iframeText += ' ' + attr + '="' + attrs[ attr ] + '"';
				}
			}
		}

		// initially hide IFRAME content, in order to lessen frame phishing impact
		styleText += 'visibility:hidden;';
		iframeText += ' style="' + styleText + '"></iframe>';

		span.innerHTML = iframeText;

		var tunnel = params.IframeContainer.tunnelURI;
		document.getElementById( internalID ).src = params.IframeContainer.uri +
				"#rpctoken=" + securityToken +
				(tunnel ? "&parent=" + encodeURIComponent( tunnel ) + "&forcesecure=true" :
						"&oaaParent=" + encodeURIComponent( OpenAjax.gadgets.rpc.getOrigin( window.location.href )));
	}

	// If the relay iframe used by RPC has not been loaded yet, then we won't have unload protection
	// at this point.  Since we can't detect when the relay iframe has loaded, we use a two stage
	// connection process.  First, the child sends a connection msg and the container sends an ack.
	// Then the container sends a connection msg and the child replies with an ack.  Since the
	// container can only send a message if the relay iframe has loaded, then we know if we get an
	// ack here that the relay iframe is ready.  And we are fully connected.
	function finishConnect() {
		// connect acknowledgement
		function callback( result ) {
			if ( result ) {
				connected = true;
				clearTimeout( loadTimer );
				document.getElementById( internalID ).style.visibility = "visible";
				if ( params.Container.onConnect ) {
					try {
						params.Container.onConnect.call( scope, container );
					} catch( e ) {
						OpenAjax.hub._debugger();
						log( "caught error from onConnect callback to constructor: " + e.message );
					}
				}
			}
		}
		OpenAjax.gadgets.rpc.call( internalID, "openajax.pubsub", callback, "cmd", "con" );
	}

	function finishDisconnect() {
		if ( connected ) {
			connected = false;
			document.getElementById( internalID ).style.visibility = "hidden";

			// unsubscribe from all subs
			for ( var s in subs ) {
				hub.unsubscribeForClient( container, subs[s] );
			}
			subs = {};
		}
	}

	function invokeSecurityAlert( errorMsg ) {
		try {
			params.Container.onSecurityAlert.call( scope, container, errorMsg );
		} catch( e ) {
			OpenAjax.hub._debugger();
			log( "caught error from onSecurityAlert callback to constructor: " + e.message );
		}
	}

	function startLoadTimer() {
		loadTimer = setTimeout(
			function() {
				// alert the security alert callback
				invokeSecurityAlert( OpenAjax.hub.SecurityAlert.LoadTimeout );
				// don't receive any more messages from HubClient
				container._handleIncomingRPC = function() {};
			},
			timeout
		);
	}


	this._init();
};

////////////////////////////////////////////////////////////////////////////////

/**
 * Create a new IframeHubClient.
 * @constructor
 * @extends OpenAjax.hub.HubClient
 *
 * @param {Object} params
 *    Once the constructor is called, the params object belongs to the
 *    HubClient. The caller MUST not modify it.
 *    The following are the pre-defined properties on params:
 * @param {Function} params.HubClient.onSecurityAlert
 *     Called when an attempted security breach is thwarted
 * @param {Object} [params.HubClient.scope]
 *     Whenever one of the HubClient's callback functions is called,
 *     references to "this" in the callback will refer to the scope object.
 *     If not provided, the default is window.
 * @param {Function} [params.HubClient.log]
 *     Optional logger function. Would be used to log to console.log or
 *     equivalent.
 * @param {Boolean} [params.IframeHubClient.requireParentVerifiable]
 *     Set to true in order to require that this IframeHubClient use a
 *     transport that can verify the parent Container's identity.
 * @param {Function} [params.IframeHubClient.seed]
 *     A function that returns a string that will be used to seed the
 *     pseudo-random number generator, which is used to create the security
 *     tokens.  An implementation of IframeHubClient may choose to ignore
 *     this value.
 * @param {Number} [params.IframeHubClient.tokenLength]
 *     Length of the security tokens used when transmitting messages.  If
 *     not specified, defaults to 6.  An implementation of IframeHubClient
 *     may choose to ignore this value.
 *
 * @throws {OpenAjax.hub.Error.BadParameters} if any of the required
 *          parameters is missing, or if a parameter value is invalid in
 *          some way.
 */
OpenAjax.hub.IframeHubClient = function( params )
{
	if ( ! params || ! params.HubClient || ! params.HubClient.onSecurityAlert ) {
		throw new Error( OpenAjax.hub.Error.BadParameters );
	}

	var client = this;
	var scope = params.HubClient.scope || window;
	var connected = false;
	var subs = {};
	var subIndex = 0;
	var clientID;
//    var securityToken;    // XXX still need "securityToken"?

	if ( params.HubClient.log ) {
		var log = function( msg ) {
			try {
				params.HubClient.log.call( scope, "IframeHubClient::" + clientID + ": " + msg );
			} catch( e ) {
				OpenAjax.hub._debugger();
			}
		};
	} else {
		log = function() {};
	}

	this._init = function() {
		var urlParams = OpenAjax.gadgets.util.getUrlParameters();
		if ( ! urlParams.parent ) {
			// The RMR transport does not require a valid relay file, but does need a URL
			// in the parent's domain. The URL does not need to point to valid file, so just
			// point to 'robots.txt' file. See RMR transport code for more info.
			var parent = urlParams.oaaParent + "/robots.txt";
			OpenAjax.gadgets.rpc.setupReceiver( "..", parent );
		}

		if ( params.IframeHubClient && params.IframeHubClient.requireParentVerifiable &&
			OpenAjax.gadgets.rpc.getReceiverOrigin( ".." ) === null ) {
			// If user set 'requireParentVerifiable' to true but RPC transport does not
			// support this, throw error.
			OpenAjax.gadgets.rpc.removeReceiver( ".." );
			throw new Error( OpenAjax.hub.Error.IncompatBrowser );
		}

		OpenAjax.hub.IframeContainer._rpcRouter.add( "..", this );
// XXX The RPC layer initializes immediately on load, in the child (IframeHubClient). So it is too
//    late here to specify a security token for the RPC layer.  At the moment, only the NIX
//    transport requires a child token (IFPC [aka FIM] is not supported).
//        securityToken = generateSecurityToken( params, scope, log );

		var internalID = OpenAjax.gadgets.rpc.RPC_ID;
		if ( ! internalID ) {
			throw new Error( OpenAjax.hub.Error.WrongProtocol );
		}
		clientID = internalID.substr( internalID.indexOf("_") + 1 );
	};

/*** HubClient interface ***/

	this.connect = function( onComplete, scope ) {
		if ( connected ) {
			throw new Error( OpenAjax.hub.Error.Duplicate );
		}

		// connect acknowledgement
		function callback( result ) {
			if ( result ) {
				connected = true;
				if ( onComplete ) {
					try {
						onComplete.call( scope || window, client, true );
					} catch( e ) {
						OpenAjax.hub._debugger();
						log( "caught error from onComplete callback to connect(): " + e.message );
					}
				}
			}
		}
		OpenAjax.gadgets.rpc.call( "..", "openajax.pubsub", callback, "con" );
	};

	this.disconnect = function( onComplete, scope ) {
		if ( !connected ) {
			throw new Error( OpenAjax.hub.Error.Disconnected );
		}

		connected = false;

		// disconnect acknowledgement
		var callback = null;
		if ( onComplete ) {
			callback = function( result ) {
				try {
					onComplete.call( scope || window, client, true );
				} catch( e ) {
					OpenAjax.hub._debugger();
					log( "caught error from onComplete callback to disconnect(): " + e.message );
				}
			};
		}
		OpenAjax.gadgets.rpc.call( "..", "openajax.pubsub", callback, "dis" );
	};

	this.getPartnerOrigin = function() {
		if ( connected ) {
			var origin = OpenAjax.gadgets.rpc.getReceiverOrigin( ".." );
			if ( origin ) {
				// remove port if present
				return ( /^([a-zA-Z]+:\/\/[^:]+).*/.exec( origin )[1] );
			}
		}
		return null;
	};

	this.getClientID = function() {
		return clientID;
	};

/*** Hub interface ***/

	this.subscribe = function( topic, onData, scope, onComplete, subscriberData ) {
		assertConn();
		assertSubTopic( topic );
		if ( ! onData ) {
			throw new Error( OpenAjax.hub.Error.BadParameters );
		}

		scope = scope || window;
		var subID = "" + subIndex++;
		subs[ subID ] = { cb: onData, sc: scope, d: subscriberData };

		// subscribe acknowledgement
		function callback( result ) {
			if ( result !== '' ) {    // error
				delete subs[ subID ];
			}
			if ( onComplete ) {
				try {
					onComplete.call( scope, subID, result === "", result );
				} catch( e ) {
					OpenAjax.hub._debugger();
					log( "caught error from onComplete callback to subscribe(): " + e.message );
				}
			}
		}
		OpenAjax.gadgets.rpc.call( "..", "openajax.pubsub", callback, "sub", topic, subID );

		return subID;
	};

	this.publish = function( topic, data ) {
		assertConn();
		assertPubTopic( topic );
		OpenAjax.gadgets.rpc.call( "..", "openajax.pubsub", null, "pub", topic, data );
	};

	this.unsubscribe = function( subscriptionID, onComplete, scope ) {
		assertConn();
		if ( ! subscriptionID ) {
			throw new Error( OpenAjax.hub.Error.BadParameters );
		}

		// if no such subscriptionID, or in process of unsubscribing given ID, throw error
		if ( ! subs[ subscriptionID ] || subs[ subscriptionID ].uns ) {
			throw new Error( OpenAjax.hub.Error.NoSubscription );
		}

		// unsubscribe in progress
		subs[ subscriptionID ].uns = true;

		// unsubscribe acknowledgement
		function callback( result ) {
			delete subs[ subscriptionID ];
			if ( onComplete ) {
				try {
					onComplete.call( scope || window, subscriptionID, true );
				} catch( e ) {
					OpenAjax.hub._debugger();
					log( "caught error from onComplete callback to unsubscribe(): " + e.message );
				}
			}
		}
		OpenAjax.gadgets.rpc.call( "..", "openajax.pubsub", callback, "uns", null, subscriptionID );
	};

	this.isConnected = function() {
		return connected;
	};

	this.getScope = function() {
		return scope;
	};

	this.getSubscriberData = function( subscriptionID ) {
		assertConn();
		if ( subs[ subscriptionID ] ) {
			return subs[ subscriptionID ].d;
		}
		throw new Error( OpenAjax.hub.Error.NoSubscription );
	};

	this.getSubscriberScope = function( subscriptionID ) {
		assertConn();
		if ( subs[ subscriptionID ] ) {
			return subs[ subscriptionID ].sc;
		}
		throw new Error( OpenAjax.hub.Error.NoSubscription );
	};

	this.getParameters = function() {
		return params;
	};

/*** private functions ***/

	this._handleIncomingRPC = function( command, topic, data, subscriptionID ) {
		if ( command === "pub" ) {
			// if subscription exists and we are not in process of unsubscribing...
			if ( subs[ subscriptionID ] && ! subs[ subscriptionID ].uns ) {
				try {
					subs[ subscriptionID ].cb.call( subs[ subscriptionID ].sc, topic,
							data, subs[ subscriptionID ].d );
				} catch( e ) {
					OpenAjax.hub._debugger();
					log( "caught error from onData callback to subscribe(): " + e.message );
				}
			}
		}
		// else if command === "cmd"...

		// First time this function is called, topic should be "con".  This is the 2nd stage of the
		// connection process.  Simply need to return "true" in order to send an acknowledgement
		// back to container.  See finishConnect() in the container object.
		if ( topic === "con" ) {
		return true;
		}
		return false;
	};

	function assertConn() {
		if ( ! connected ) {
			throw new Error( OpenAjax.hub.Error.Disconnected );
		}
	}

	function assertSubTopic( topic )
	{
		if ( ! topic ) {
			throw new Error( OpenAjax.hub.Error.BadParameters );
		}
		var path = topic.split(".");
		var len = path.length;
		for (var i = 0; i < len; i++) {
			var p = path[i];
			if ((p === "") ||
			((p.indexOf("*") != -1) && (p != "*") && (p != "**"))) {
				throw new Error( OpenAjax.hub.Error.BadParameters );
			}
			if ((p == "**") && (i < len - 1)) {
				throw new Error( OpenAjax.hub.Error.BadParameters );
			}
		}
	}

	function assertPubTopic( topic ) {
		if ( !topic || topic === "" || (topic.indexOf("*") != -1) ||
			(topic.indexOf("..") != -1) ||  (topic.charAt(0) == ".") ||
			(topic.charAt(topic.length-1) == "."))
		{
			throw new Error( OpenAjax.hub.Error.BadParameters );
		}
	}

	this._init();
};

////////////////////////////////////////////////////////////////////////////////

	// RPC object contents:
	//   s: Service Name
	//   f: From
	//   c: The callback ID or 0 if none.
	//   a: The arguments for this RPC call.
	//   t: The authentication token.
OpenAjax.hub.IframeContainer._rpcRouter = function() {
	var receivers = {};

	function router() {
		var r = receivers[ this.f ];
		if ( r ) {
			return r._handleIncomingRPC.apply( r, arguments );
		}
	}

	function onSecurityAlert( receiverId, error ) {
		var r = receivers[ receiverId ];
		if ( r ) {
		r._onSecurityAlert.call( r, error );
		}
	}

	return {
		add: function( id, receiver ) {
			function _add( id, receiver ) {
				if ( id === ".." ) {
					if ( ! receivers[ ".." ] ) {
						receivers[ ".." ] = receiver;
					}
					return;
				}

				do {
					// a client with the specified ID already exists on this page;
					// create a unique ID
					newID = ((0x7fff * Math.random()) | 0).toString(16) + "_" + id;
				} while ( receivers[ newID ] );
				receivers[ newID ] = receiver;
				return newID;
			}

			// when this function is first called, register the RPC service
			OpenAjax.gadgets.rpc.register( "openajax.pubsub", router );
			OpenAjax.gadgets.rpc.config({
				securityCallback: onSecurityAlert
			});

			rpcErrorsToOAA[ OpenAjax.gadgets.rpc.SEC_ERROR_LOAD_TIMEOUT ] = OpenAjax.hub.SecurityAlert.LoadTimeout;
			rpcErrorsToOAA[ OpenAjax.gadgets.rpc.SEC_ERROR_FRAME_PHISH ] = OpenAjax.hub.SecurityAlert.FramePhish;
			rpcErrorsToOAA[ OpenAjax.gadgets.rpc.SEC_ERROR_FORGED_MSG ] = OpenAjax.hub.SecurityAlert.ForgedMsg;

			this.add = _add;
			return _add( id, receiver );
		},

		remove: function( id ) {
			delete receivers[ id ];
		}
	};
}();

var rpcErrorsToOAA = {};

////////////////////////////////////////////////////////////////////////////////

function generateSecurityToken( params, scope, log ) {
	if ( ! OpenAjax.hub.IframeContainer._prng ) {
		// create pseudo-random number generator with a default seed
		var seed = new Date().getTime() + Math.random() + document.cookie;
		OpenAjax.hub.IframeContainer._prng = OpenAjax._smash.crypto.newPRNG( seed );
	}

	var p = params.IframeContainer || params.IframeHubClient;
	if ( p && p.seed ) {
		try {
			var extraSeed = p.seed.call( scope );
			OpenAjax.hub.IframeContainer._prng.addSeed( extraSeed );
		} catch( e ) {
			OpenAjax.hub._debugger();
			log( "caught error from 'seed' callback: " + e.message );
		}
	}

	var tokenLength = (p && p.tokenLength) || 6;
	return OpenAjax.hub.IframeContainer._prng.nextRandomB64Str( tokenLength );
}

})();
}/*

		Copyright 2006-2009 OpenAjax Alliance

		Licensed 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.
*/
// SMASH.CRYPTO
//
// Small library containing some minimal crypto functionality for a
// - a hash-function: SHA-1 (see FIPS PUB 180-2 for definition)
//     BigEndianWord[5] <- smash.crypto.sha1( BigEndianWord[*] dataWA, int lenInBits)
//
// - a message authentication code (MAC): HMAC-SHA-1 (RFC2104/2202)
//     BigEndianWord[5] <- smash.crypto.hmac_sha1(
//                            BigEndianWord[3-16] keyWA,
//                            Ascii or Unicode string dataS,
//		 		 		       int chrsz (8 for Asci/16 for Unicode)
//
// - pseudo-random number generator (PRNG): HMAC-SHA-1 in counter mode, following
//   Barak & Halevi, An architecture for robust pseudo-random generation and applications to /dev/random, CCS 2005
//     rngObj <- smash.crypto.newPRNG( String[>=12] seedS)
//   where rngObj has methods
//     addSeed(String seed)
//     BigEndianWord[len] <- nextRandomOctets(int len)
//     Base64-String[len] <- nextRandomB64Str(int len)
//   Note: HMAC-SHA1 in counter-mode does not provide forward-security on corruption.
//         However, the PRNG state is kept inside a closure. So if somebody can break the closure, he probably could
//         break a whole lot more and forward-security of the prng is not the highest of concerns anymore :-)

if ( typeof OpenAjax._smash == 'undefined' ) { OpenAjax._smash = {}; }

OpenAjax._smash.crypto = {

// Some utilities
// convert a string to an array of big-endian words
'strToWA': function (/* Ascii or Unicode string */ str, /* int 8 for Asci/16 for Unicode */ chrsz){
	var bin = Array();
	var mask = (1 << chrsz) - 1;
	for(var i = 0; i < str.length * chrsz; i += chrsz)
	bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
	return bin;
},


// MAC
'hmac_sha1' : function(
		/* BigEndianWord[3-16]*/             keyWA,
	/* Ascii or Unicode string */       dataS,
	/* int 8 for Asci/16 for Unicode */ chrsz)
{
	// write our own hmac derived from paj's so we do not have to do constant key conversions and length checking ...
	var ipad = Array(16), opad = Array(16);
	for(var i = 0; i < 16; i++) {
	ipad[i] = keyWA[i] ^ 0x36363636;
	opad[i] = keyWA[i] ^ 0x5C5C5C5C;
	}

	var hash = this.sha1( ipad.concat(this.strToWA(dataS, chrsz)), 512 + dataS.length * chrsz);
	return     this.sha1( opad.concat(hash), 512 + 160);
},


// PRNG factory method
// see below 'addSeed', 'nextRandomOctets' & 'nextRandomB64Octets' for public methods of returnd prng object
'newPRNG' : function (/* String[>=12] */ seedS) {
	var that = this;

	// parameter checking
	// We cannot really verify entropy but obviously the string must have at least a minimal length to have enough entropy
	// However, a 2^80 security seems ok, so we check only that at least 12 chars assuming somewhat random ASCII
	if ( (typeof seedS != 'string') || (seedS.length < 12) ) {
	alert("WARNING: Seed length too short ...");
	}

	// constants
	var __refresh_keyWA = [ 0xA999, 0x3E36, 0x4706, 0x816A,
								0x2571, 0x7850, 0xC26C, 0x9CD0,
								0xBA3E, 0xD89D, 0x1233, 0x9525,
								0xff3C, 0x1A83, 0xD491, 0xFF15 ]; // some random key for refresh ...

	// internal state
	var _keyWA = []; // BigEndianWord[5]
	var _cnt = 0;  // int

	function extract(seedS) {
	return that.hmac_sha1(__refresh_keyWA, seedS, 8);
	}

	function refresh(seedS) {
	// HMAC-SHA1 is not ideal, Rijndal 256bit block/key in CBC mode with fixed key might be better
	// but to limit the primitives and given that we anyway have only limited entropy in practise
	// this seems good enough
	var uniformSeedWA = extract(seedS);
	for(var i = 0; i < 5; i++) {
		_keyWA[i] ^= uniformSeedWA[i];
	}
	}

	// inital state seeding
	refresh(seedS);

	// public methods
	return {
	// Mix some additional seed into the PRNG state
	'addSeed'         : function (/* String */ seed) {
		// no parameter checking. Any added entropy should be fine ...
		refresh(seed);
	},


	// Get an array of len random octets
	'nextRandomOctets' : /* BigEndianWord[len] <- */ function (/* int */ len) {
		var randOctets = [];
		while (len > 0) {
		_cnt+=1;
		var nextBlock = that.hmac_sha1(_keyWA, (_cnt).toString(16), 8);
		for (var i=0; (i < 20) & (len > 0); i++, len--) {
			randOctets.push( (nextBlock[i>>2] >> (i % 4) ) % 256);
		}
		// Note: if len was not a multiple 20, some random octets are ignored here but who cares ..
		}
		return randOctets;
	},


	// Get a random string of Base64-like (see below) chars of length len
	// Note: there is a slightly non-standard Base64 with no padding and '-' and '_' for '+' and '/', respectively
	'nextRandomB64Str' : /* Base64-String <- */ function (/* int */ len) {
		var b64StrMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";

		var randOctets = this.nextRandomOctets(len);
		var randB64Str = '';
		for (var i=0; i < len; i++) {
		randB64Str += b64StrMap.charAt(randOctets[i] & 0x3F);
		}
		return randB64Str;
	}

	};
},


// Digest function:
// BigEndianWord[5] <- sha1( BigEndianWord[*] dataWA, int lenInBits)
'sha1' : function(){
	// Note: all Section references below refer to FIPS 180-2.

	// private utility functions

	// - 32bit addition with wrap-around
	var add_wa = function (x, y){
		var lsw = (x & 0xFFFF) + (y & 0xFFFF);
		var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
		return (msw << 16) | (lsw & 0xFFFF);
	};

	// - 32bit rotatate left
	var rol = function(num, cnt) {
		return (num << cnt) | (num >>> (32 - cnt));
	};

	// - round-dependent function f_t from Section 4.1.1
	function sha1_ft(t, b, c, d) {
		if(t < 20) return (b & c) | ((~b) & d);
		if(t < 40) return b ^ c ^ d;
		if(t < 60) return (b & c) | (b & d) | (c & d);
		return b ^ c ^ d;
	}

	// - round-dependent SHA-1 constants from Section 4.2.1
	function sha1_kt(t) {
	return (t < 20) ?  1518500249 :
			(t < 40) ?  1859775393 :
			(t < 60) ? -1894007588 :
		/* (t < 80) */ -899497514 ;
	}

	// main algorithm.
	return function( /* BigEndianWord[*] */ dataWA, /* int */ lenInBits) {

	// Section 6.1.1: Preprocessing
	//-----------------------------
	// 1. padding:  (see also Section 5.1.1)
	//  - append one 1 followed by 0 bits filling up 448 bits of last (512bit) block
	dataWA[lenInBits >> 5] |= 0x80 << (24 - lenInBits % 32);
	//  - encode length in bits in last 64 bits
	//    Note: we rely on javascript to zero file elements which are beyond last (partial) data-block
	//    but before this length encoding!
	dataWA[((lenInBits + 64 >> 9) << 4) + 15] = lenInBits;

	// 2. 512bit blocks (actual split done ondemand later)
	var W = Array(80);

	// 3. initial hash using SHA-1 constants on page 13
	var H0 =  1732584193;
	var H1 = -271733879;
	var H2 = -1732584194;
	var H3 =  271733878;
	var H4 = -1009589776;

	// 6.1.2 SHA-1 Hash Computation
	for(var i = 0; i < dataWA.length; i += 16) {
		// 1. Message schedule, done below
		// 2. init working variables
		var a = H0; var b = H1; var c = H2; var d = H3; var e = H4;

		// 3. round-functions
		for(var j = 0; j < 80; j++)
		{
			// postponed step 2
		W[j] = ( (j < 16) ? dataWA[i+j] : rol(W[j-3] ^ W[j-8] ^ W[j-14] ^ W[j-16], 1));

		var T = add_wa( add_wa( rol(a, 5), sha1_ft(j, b, c, d)),
						add_wa( add_wa(e, W[j]), sha1_kt(j)) );
		e = d;
		d = c;
		c = rol(b, 30);
		b = a;
		a = T;
		}

		// 4. intermediate hash
		H0 = add_wa(a, H0);
		H1 = add_wa(b, H1);
		H2 = add_wa(c, H2);
		H3 = add_wa(d, H3);
		H4 = add_wa(e, H4);
	}

	return Array(H0, H1, H2, H3, H4);
	};
}()

};

/*
	http://www.JSON.org/json2.js
	2008-11-19

	Public Domain.

	NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.

	See http://www.JSON.org/js.html

	This file creates a global JSON object containing two methods: stringify
	and parse.

		JSON.stringify(value, replacer, space)
			value       any JavaScript value, usually an object or array.

			replacer    an optional parameter that determines how object
						values are stringified for objects. It can be a
						function or an array of strings.

			space       an optional parameter that specifies the indentation
						of nested structures. If it is omitted, the text will
						be packed without extra whitespace. If it is a number,
						it will specify the number of spaces to indent at each
						level. If it is a string (such as '\t' or '&nbsp;'),
						it contains the characters used to indent at each level.

			This method produces a JSON text from a JavaScript value.

			When an object value is found, if the object contains a toJSON
			method, its toJSON method will be called and the result will be
			stringified. A toJSON method does not serialize: it returns the
			value represented by the name/value pair that should be serialized,
			or undefined if nothing should be serialized. The toJSON method
			will be passed the key associated with the value, and this will be
			bound to the object holding the key.

			For example, this would serialize Dates as ISO strings.

				Date.prototype.toJSON = function (key) {
					function f(n) {
						// Format integers to have at least two digits.
						return n < 10 ? '0' + n : n;
					}

					return this.getUTCFullYear()   + '-' +
						f(this.getUTCMonth() + 1) + '-' +
						f(this.getUTCDate())      + 'T' +
						f(this.getUTCHours())     + ':' +
						f(this.getUTCMinutes())   + ':' +
						f(this.getUTCSeconds())   + 'Z';
				};

			You can provide an optional replacer method. It will be passed the
			key and value of each member, with this bound to the containing
			object. The value that is returned from your method will be
			serialized. If your method returns undefined, then the member will
			be excluded from the serialization.

			If the replacer parameter is an array of strings, then it will be
			used to select the members to be serialized. It filters the results
			such that only members with keys listed in the replacer array are
			stringified.

			Values that do not have JSON representations, such as undefined or
			functions, will not be serialized. Such values in objects will be
			dropped; in arrays they will be replaced with null. You can use
			a replacer function to replace those with JSON values.
			JSON.stringify(undefined) returns undefined.

			The optional space parameter produces a stringification of the
			value that is filled with line breaks and indentation to make it
			easier to read.

			If the space parameter is a non-empty string, then that string will
			be used for indentation. If the space parameter is a number, then
			the indentation will be that many spaces.

			Example:

			text = JSON.stringify(['e', {pluribus: 'unum'}]);
			// text is '["e",{"pluribus":"unum"}]'


			text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
			// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'

			text = JSON.stringify([new Date()], function (key, value) {
				return this[key] instanceof Date ?
					'Date(' + this[key] + ')' : value;
			});
			// text is '["Date(---current time---)"]'


		JSON.parse(text, reviver)
			This method parses a JSON text to produce an object or array.
			It can throw a SyntaxError exception.

			The optional reviver parameter is a function that can filter and
			transform the results. It receives each of the keys and values,
			and its return value is used instead of the original value.
			If it returns what it received, then the structure is not modified.
			If it returns undefined then the member is deleted.

			Example:

			// Parse the text. Values that look like ISO date strings will
			// be converted to Date objects.

			myData = JSON.parse(text, function (key, value) {
				var a;
				if (typeof value === 'string') {
					a =
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
					if (a) {
						return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
							+a[5], +a[6]));
					}
				}
				return value;
			});

			myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
				var d;
				if (typeof value === 'string' &&
						value.slice(0, 5) === 'Date(' &&
						value.slice(-1) === ')') {
					d = new Date(value.slice(5, -1));
					if (d) {
						return d;
					}
				}
				return value;
			});


	This is a reference implementation. You are free to copy, modify, or
	redistribute.

	This code should be minified before deployment.
	See http://javascript.crockford.com/jsmin.html

	USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
	NOT CONTROL.
*/

/*jslint evil: true */

/*global JSON */

/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
	call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
	getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
	lastIndex, length, parse, prototype, push, replace, slice, stringify,
	test, toJSON, toString, valueOf
*/

// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.

if (!this.JSON) {
	JSON = {};
}
(function () {

	function f(n) {
		// Format integers to have at least two digits.
		return n < 10 ? '0' + n : n;
	}

	if (typeof Date.prototype.toJSON !== 'function') {

		Date.prototype.toJSON = function (key) {

			return this.getUTCFullYear()   + '-' +
				f(this.getUTCMonth() + 1) + '-' +
				f(this.getUTCDate())      + 'T' +
				f(this.getUTCHours())     + ':' +
				f(this.getUTCMinutes())   + ':' +
				f(this.getUTCSeconds())   + 'Z';
		};

		String.prototype.toJSON =
		Number.prototype.toJSON =
		Boolean.prototype.toJSON = function (key) {
			return this.valueOf();
		};
	}

	var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
		escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
		gap,
		indent,
		meta = {    // table of character substitutions
			'\b': '\\b',
			'\t': '\\t',
			'\n': '\\n',
			'\f': '\\f',
			'\r': '\\r',
			'"' : '\\"',
			'\\': '\\\\'
		},
		rep;


	function quote(string) {

// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.

		escapable.lastIndex = 0;
		return escapable.test(string) ?
			'"' + string.replace(escapable, function (a) {
				var c = meta[a];
				return typeof c === 'string' ? c :
					'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
			}) + '"' :
			'"' + string + '"';
	}


	function str(key, holder) {

// Produce a string from holder[key].

		var i,          // The loop counter.
			k,          // The member key.
			v,          // The member value.
			length,
			mind = gap,
			partial,
			value = holder[key];

// If the value has a toJSON method, call it to obtain a replacement value.

		if (value && typeof value === 'object' &&
				typeof value.toJSON === 'function') {
			value = value.toJSON(key);
		}

// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.

		if (typeof rep === 'function') {
			value = rep.call(holder, key, value);
		}

// What happens next depends on the value's type.

		switch (typeof value) {
		case 'string':
			return quote(value);

		case 'number':

// JSON numbers must be finite. Encode non-finite numbers as null.

			return isFinite(value) ? String(value) : 'null';

		case 'boolean':
		case 'null':

// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.

			return String(value);

// If the type is 'object', we might be dealing with an object or an array or
// null.

		case 'object':

// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.

			if (!value) {
				return 'null';
			}

// Make an array to hold the partial results of stringifying this object value.

			gap += indent;
			partial = [];

// Is the value an array?

			if (Object.prototype.toString.apply(value) === '[object Array]') {

// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.

				length = value.length;
				for (i = 0; i < length; i += 1) {
					partial[i] = str(i, value) || 'null';
				}

// Join all of the elements together, separated with commas, and wrap them in
// brackets.

				v = partial.length === 0 ? '[]' :
					gap ? '[\n' + gap +
							partial.join(',\n' + gap) + '\n' +
								mind + ']' :
						'[' + partial.join(',') + ']';
				gap = mind;
				return v;
			}

// If the replacer is an array, use it to select the members to be stringified.

			if (rep && typeof rep === 'object') {
				length = rep.length;
				for (i = 0; i < length; i += 1) {
					k = rep[i];
					if (typeof k === 'string') {
						v = str(k, value);
						if (v) {
							partial.push(quote(k) + (gap ? ': ' : ':') + v);
						}
					}
				}
			} else {

// Otherwise, iterate through all of the keys in the object.

				for (k in value) {
					if (Object.hasOwnProperty.call(value, k)) {
						v = str(k, value);
						if (v) {
							partial.push(quote(k) + (gap ? ': ' : ':') + v);
						}
					}
				}
			}

// Join all of the member texts together, separated with commas,
// and wrap them in braces.

			v = partial.length === 0 ? '{}' :
				gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
						mind + '}' : '{' + partial.join(',') + '}';
			gap = mind;
			return v;
		}
	}

// If the JSON object does not yet have a stringify method, give it one.

	if (typeof JSON.stringify !== 'function') {
		JSON.stringify = function (value, replacer, space) {

// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.

			var i;
			gap = '';
			indent = '';

// If the space parameter is a number, make an indent string containing that
// many spaces.

			if (typeof space === 'number') {
				for (i = 0; i < space; i += 1) {
					indent += ' ';
				}

// If the space parameter is a string, it will be used as the indent string.

			} else if (typeof space === 'string') {
				indent = space;
			}

// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.

			rep = replacer;
			if (replacer && typeof replacer !== 'function' &&
					(typeof replacer !== 'object' ||
					typeof replacer.length !== 'number')) {
				throw new Error('JSON.stringify');
			}

// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.

			return str('', {'': value});
		};
	}


// If the JSON object does not yet have a parse method, give it one.

	if (typeof JSON.parse !== 'function') {
		JSON.parse = function (text, reviver) {

// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.

			var j;

			function walk(holder, key) {

// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.

				var k, v, value = holder[key];
				if (value && typeof value === 'object') {
					for (k in value) {
						if (Object.hasOwnProperty.call(value, k)) {
							v = walk(value, k);
							if (v !== undefined) {
								value[k] = v;
							} else {
								delete value[k];
							}
						}
					}
				}
				return reviver.call(holder, key, value);
			}


// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.

			cx.lastIndex = 0;
			if (cx.test(text)) {
				text = text.replace(cx, function (a) {
					return '\\u' +
						('0000' + a.charCodeAt(0).toString(16)).slice(-4);
				});
			}

// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.

// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.

			if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.

				j = eval('(' + text + ')');

// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.

				return typeof reviver === 'function' ?
					walk({'': j}, '') : j;
			}

// If the text is not JSON parseable, then a SyntaxError is thrown.

			throw new SyntaxError('JSON.parse');
		};
	}
})();
/*
 * 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.
 */

/**
 * @fileoverview External functions used by the OpenSocial RPC code.  This file
 *               is for use by OpenAjax only.
 */

	//---   from core.util/util.js   ---//

/**
 * @static
 * @class Provides general-purpose utility functions.
 * @name gadgets.util
 */

OpenAjax.gadgets.util = function() {
/**
   * Parses URL parameters into an object.
   * @param {string} url - the url parameters to parse
   * @return {Array.<string>} The parameters as an array
   */
function parseUrlParams(url) {
	// Get settings from url, 'hash' takes precedence over 'search' component
	// don't use document.location.hash due to browser differences.
	var query;
	var queryIdx = url.indexOf("?");
	var hashIdx = url.indexOf("#");
	if (hashIdx === -1) {
	query = url.substr(queryIdx + 1);
	} else {
	// essentially replaces "#" with "&"
	query = [url.substr(queryIdx + 1, hashIdx - queryIdx - 1), "&",
			url.substr(hashIdx + 1)].join("");
	}
	return query.split("&");
}

var parameters = null;
var onLoadHandlers = [];

return /** @scope gadgets.util */ {

	/**
	 * Gets the URL parameters.
	 *
	 * @param {string=} opt_url Optional URL whose parameters to parse.
	 *                         Defaults to window's current URL.
	 * @return {Object} Parameters passed into the query string
	 * @member gadgets.util
	 * @private Implementation detail.
	 */
	getUrlParameters : function (opt_url) {
	if (parameters !== null && typeof opt_url === "undefined") {
		// "parameters" is a cache of current window params only.
		return parameters;
	}
	var parsed = {};
	var pairs = parseUrlParams(opt_url || document.location.href);
	var unesc = window.decodeURIComponent ? decodeURIComponent : unescape;
	for (var i = 0, j = pairs.length; i < j; ++i) {
		var pos = pairs[i].indexOf('=');
		if (pos === -1) {
		continue;
		}
		var argName = pairs[i].substring(0, pos);
		var value = pairs[i].substring(pos + 1);
		// difference to IG_Prefs, is that args doesn't replace spaces in
		// argname. Unclear on if it should do:
		// argname = argname.replace(/\+/g, " ");
		value = value.replace(/\+/g, " ");
		parsed[argName] = unesc(value);
	}
	if (typeof opt_url === "undefined") {
		// Cache current-window params in parameters var.
		parameters = parsed;
	}
	return parsed;
	},

	/**
	 * Registers an onload handler.
	 * @param {function()} callback The handler to run
	 *
	 * @member gadgets.util
	 */
	registerOnLoadHandler : function (callback) {
	onLoadHandlers.push(callback);
	},

	/**
	 * Runs all functions registered via registerOnLoadHandler.
	 * @private Only to be used by the container, not gadgets.
	 */
	runOnLoadHandlers : function () {
	for (var i = 0, j = onLoadHandlers.length; i < j; ++i) {
		onLoadHandlers[i]();
	}
	},

	/**
	 * Attach an event listener to given DOM element
	 *
	 * @param {object} elem  DOM element on which to attach event.
	 * @param {string} eventName  Event type to listen for.
	 * @param {function} callback  Invoked when specified event occurs.
	 * @param {boolean} useCapture  If true, initiates capture.
	 */
	'attachBrowserEvent': function(elem, eventName, callback, useCapture) {
	if (elem.addEventListener) {
		elem.addEventListener(eventName, callback, useCapture);
	} else if (elem.attachEvent) {
		elem.attachEvent('on' + eventName, callback);
	}
	},

	/**
	 * Remove event listener
	 *
	 * @param {object} elem  DOM element from which to remove event.
	 * @param {string} eventName  Event type to remove.
	 * @param {function} callback  Listener to remove.
	 * @param {boolean} useCapture  Specifies whether listener being removed was added with
	 *                              capture enabled.
	 */
	'removeBrowserEvent': function(elem, eventName, callback, useCapture) {
	if (elem.removeEventListener) {
		elem.removeEventListener(eventName, callback, useCapture);
	} else if (elem.detachEvent){
		elem.detachEvent('on' + eventName, callback);
	}
	}
};
}();
// Initialize url parameters so that hash data is pulled in before it can be
// altered by a click.
OpenAjax.gadgets.util.getUrlParameters();


	//---   from core.json/json.js   ---//

OpenAjax.gadgets.json = OpenAjax.gadgets.json || {};
if ( ! OpenAjax.gadgets.json.stringify ) {
OpenAjax.gadgets.json = {
	parse: function(str) {
	try {
		if (str==="postmessage.test"){return false;}
		return window.JSON.parse(str);
	} catch (e) {
		return false;
	}
	},
	stringify: function(obj) {
	try {
		return window.JSON.stringify(obj);
	} catch (e) {
		return null;
	}
	}
};
}


	//---   from core.log/log.js   ---//

/**
 * Log an informational message
 */
OpenAjax.gadgets.log = function(message) {
OpenAjax.gadgets.log.logAtLevel(OpenAjax.gadgets.log.INFO, message);
};


/**
 * Log a warning
 */
OpenAjax.gadgets.warn = function(message) {
OpenAjax.gadgets.log.logAtLevel(OpenAjax.gadgets.log.WARNING, message);
};

/**
 * Log an error
 */
OpenAjax.gadgets.error = function(message) {
OpenAjax.gadgets.log.logAtLevel(OpenAjax.gadgets.log.ERROR, message);
};

/**
 * Sets the log level threshold.
 * @param {Number} logLevel - New log level threshold.
 * @static
 */
OpenAjax.gadgets.setLogLevel = function(logLevel) {
OpenAjax.gadgets.log.logLevelThreshold_ = logLevel;
};

/**
 * Logs a log message if output console is available, and log threshold is met.
 * @param {Number} level - the level to log with. Optional, defaults to
 * @param {Object} message - The message to log
 * gadgets.log.INFO.
 * @static
 */
OpenAjax.gadgets.log.logAtLevel = function(level, message) {
if (level < OpenAjax.gadgets.log.logLevelThreshold_ || !OpenAjax.gadgets.log._console) {
	return;
}

var gadgetconsole = OpenAjax.gadgets.log._console;

if (level == OpenAjax.gadgets.log.WARNING && gadgetconsole.warn) {
	gadgetconsole.warn(message);
} else if (level == OpenAjax.gadgets.log.ERROR && gadgetconsole.error) {
	gadgetconsole.error(message);
} else if (gadgetconsole.log) {
	gadgetconsole.log(message);
}
};

/**
 * Log level for informational logging.
 * @static
 */
OpenAjax.gadgets.log.INFO = 1;

/**
 * Log level for warning logging.
 * @static
 */
OpenAjax.gadgets.log.WARNING = 2;

/**
 * Log level for error logging.
 * @static
 */
OpenAjax.gadgets.log.ERROR = 3;

/**
 * Log level for no logging
 * @static
 */
OpenAjax.gadgets.log.NONE = 4;

/**
 * Current log level threshold.
 * @type Number
 * @private
 * @static
 */
OpenAjax.gadgets.log.logLevelThreshold_ = OpenAjax.gadgets.log.INFO;

/**
 * Console to log to
 * @private
 * @static
 */
OpenAjax.gadgets.log._console = window.console ? window.console :
					window.opera   ? window.opera.postError : undefined;


////////////////////////////////////////////////////////////////////////////////////////////////////
//  onload handler compatibility code
////////////////////////////////////////////////////////////////////////////////////////////////////

(function() {
// XXX What if this script file (iframe.js) is dynamically loaded after the page has loaded.
if ( ! window.__isgadget ) {
	var loaded = false;
	function onload() {
		if ( ! loaded ) {
			loaded = true;
			// This is necessary for the RMR and FE transports.
			OpenAjax.gadgets.util.runOnLoadHandlers();
			// Since the page has now loaded, change registerOnLoadHandler() to immediately fire
			// callback.
			OpenAjax.gadgets.util.registerOnLoadHandler = function( callback ) {
				setTimeout( callback, 0 );
			};
			// prevent IE memory leak
			if ( window.detachEvent ) {
				window.detachEvent( "onload", onload );
			}
		}
	}
	if ( window.addEventListener ) {
		document.addEventListener( "DOMContentLoaded", onload, false );
		window.addEventListener( "load", onload, false );
	} else if ( window.attachEvent ) {
		// XXX use doScroll trick?
		window.attachEvent( "onload", onload );
	}
}
})();
/*
 * 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.
 */

OpenAjax.gadgets.rpctx = OpenAjax.gadgets.rpctx || {};

/*
 * For Gecko-based browsers, the security model allows a child to call a
 * function on the frameElement of the iframe, even if the child is in
 * a different domain. This method is dubbed "frameElement" (fe).
 *
 * The ability to add and call such functions on the frameElement allows
 * a bidirectional channel to be setup via the adding of simple function
 * references on the frameElement object itself. In this implementation,
 * when the container sets up the authentication information for that gadget
 * (by calling setAuth(...)) it as well adds a special function on the
 * gadget's iframe. This function can then be used by the gadget to send
 * messages to the container. In turn, when the gadget tries to send a
 * message, it checks to see if this function has its own function stored
 * that can be used by the container to call the gadget. If not, the
 * function is created and subsequently used by the container.
 * Note that as a result, FE can only be used by a container to call a
 * particular gadget *after* that gadget has called the container at
 * least once via FE.
 *
 *   fe: Gecko-specific frameElement trick.
 *      - Firefox 1+
 */
if (!OpenAjax.gadgets.rpctx.frameElement) {  // make lib resilient to double-inclusion

OpenAjax.gadgets.rpctx.frameElement = function() {
// Consts for FrameElement.
var FE_G2C_CHANNEL = '__g2c_rpc';
var FE_C2G_CHANNEL = '__c2g_rpc';
var process;
var ready;

function callFrameElement(targetId, from, rpc) {
	try {
	if (from !== '..') {
		// Call from gadget to the container.
		var fe = window.frameElement;

		if (typeof fe[FE_G2C_CHANNEL] === 'function') {
		// Complete the setup of the FE channel if need be.
		if (typeof fe[FE_G2C_CHANNEL][FE_C2G_CHANNEL] !== 'function') {
			fe[FE_G2C_CHANNEL][FE_C2G_CHANNEL] = function(args) {
			process(OpenAjax.gadgets.json.parse(args));
			};
		}

		// Conduct the RPC call.
		fe[FE_G2C_CHANNEL](OpenAjax.gadgets.json.stringify(rpc));
		return;
		}
	} else {
		// Call from container to gadget[targetId].
		var frame = document.getElementById(targetId);

		if (typeof frame[FE_G2C_CHANNEL] === 'function' &&
			typeof frame[FE_G2C_CHANNEL][FE_C2G_CHANNEL] === 'function') {

		// Conduct the RPC call.
		frame[FE_G2C_CHANNEL][FE_C2G_CHANNEL](OpenAjax.gadgets.json.stringify(rpc));
		return;
		}
	}
	} catch (e) {
	}
	return true;
}

return {
	getCode: function() {
	return 'fe';
	},

	isParentVerifiable: function() {
	return false;
	},

	init: function(processFn, readyFn) {
	// No global setup.
	process = processFn;
	ready = readyFn;
	return true;
	},

	setup: function(receiverId, token) {
	// Indicate OK to call to container. This will be true
	// by the end of this method.
	if (receiverId !== '..') {
		try {
		var frame = document.getElementById(receiverId);
		frame[FE_G2C_CHANNEL] = function(args) {
			process(OpenAjax.gadgets.json.parse(args));
		};
		} catch (e) {
		return false;
		}
	}
	if (receiverId === '..') {
		ready('..', true);
		var ackFn = function() {
		window.setTimeout(function() {
			OpenAjax.gadgets.rpc.call(receiverId, OpenAjax.gadgets.rpc.ACK);
		}, 500);
		};
		// Setup to container always happens before onload.
		// If it didn't, the correct fix would be in gadgets.util.
		OpenAjax.gadgets.util.registerOnLoadHandler(ackFn);
	}
	return true;
	},

	call: function(targetId, from, rpc) {
	callFrameElement(targetId, from, rpc);
	}

};
}();

} // !end of double-inclusion guard
/*
 * 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.
 */

OpenAjax.gadgets.rpctx = OpenAjax.gadgets.rpctx || {};

/*
 * For all others, we have a fallback mechanism known as "ifpc". IFPC
 * exploits the fact that while same-origin policy prohibits a frame from
 * accessing members on a window not in the same domain, that frame can,
 * however, navigate the window heirarchy (via parent). This is exploited by
 * having a page on domain A that wants to talk to domain B create an iframe
 * on domain B pointing to a special relay file and with a message encoded
 * after the hash (#). This relay, in turn, finds the page on domain B, and
 * can call a receipt function with the message given to it. The relay URL
 * used by each caller is set via the gadgets.rpc.setRelayUrl(..) and
 * *must* be called before the call method is used.
 *
 *   ifpc: Iframe-based method, utilizing a relay page, to send a message.
 *      - No known major browsers still use this method, but it remains
 *        useful as a catch-all fallback for the time being.
 */
if (!OpenAjax.gadgets.rpctx.ifpc) {  // make lib resilient to double-inclusion

OpenAjax.gadgets.rpctx.ifpc = function() {
var iframePool = [];
var callId = 0;
var ready;

/**
   * Encodes arguments for the legacy IFPC wire format.
   *
   * @param {Object} args
   * @return {string} the encoded args
   */
function encodeLegacyData(args) {
	var argsEscaped = [];
	for(var i = 0, j = args.length; i < j; ++i) {
	argsEscaped.push(encodeURIComponent(OpenAjax.gadgets.json.stringify(args[i])));
	}
	return argsEscaped.join('&');
}

/**
   * Helper function to emit an invisible IFrame.
   * @param {string} src SRC attribute of the IFrame to emit.
   * @private
   */
function emitInvisibleIframe(src) {
	var iframe;
	// Recycle IFrames
	for (var i = iframePool.length - 1; i >=0; --i) {
	var ifr = iframePool[i];
	try {
		if (ifr && (ifr.recyclable || ifr.readyState === 'complete')) {
		ifr.parentNode.removeChild(ifr);
		if (window.ActiveXObject) {
			// For MSIE, delete any iframes that are no longer being used. MSIE
			// cannot reuse the IFRAME because a navigational click sound will
			// be triggered when we set the SRC attribute.
			// Other browsers scan the pool for a free iframe to reuse.
			iframePool[i] = ifr = null;
			iframePool.splice(i, 1);
		} else {
			ifr.recyclable = false;
			iframe = ifr;
			break;
		}
		}
	} catch (e) {
		// Ignore; IE7 throws an exception when trying to read readyState and
		// readyState isn't set.
	}
	}
	// Create IFrame if necessary
	if (!iframe) {
	iframe = document.createElement('iframe');
	iframe.style.border = iframe.style.width = iframe.style.height = '0px';
	iframe.style.visibility = 'hidden';
	iframe.style.position = 'absolute';
	iframe.onload = function() { this.recyclable = true; };
	iframePool.push(iframe);
	}
	iframe.src = src;
	window.setTimeout(function() { document.body.appendChild(iframe); }, 0);
}

return {
	getCode: function() {
	return 'ifpc';
	},

	isParentVerifiable: function() {
	return true;
	},

	init: function(processFn, readyFn) {
	// No global setup.
	ready = readyFn;
	ready('..', true);  // Ready immediately.
	return true;
	},

	setup: function(receiverId, token) {
	// Indicate readiness to send to receiver.
	ready(receiverId, true);
	return true;
	},

	call: function(targetId, from, rpc) {
	// Retrieve the relay file used by IFPC. Note that
	// this must be set before the call, and so we conduct
	// an extra check to ensure it is not blank.
	var relay = OpenAjax.gadgets.rpc.getRelayUrl(targetId);
	++callId;

	if (!relay) {
		OpenAjax.gadgets.warn('No relay file assigned for IFPC');
		return;
	}

	// The RPC mechanism supports two formats for IFPC (legacy and current).
	var src = null;
	if (rpc.l) {
		// Use legacy protocol.
		// Format: #iframe_id&callId&num_packets&packet_num&block_of_data
		var callArgs = rpc.a;
		src = [relay, '#', encodeLegacyData([from, callId, 1, 0,
			encodeLegacyData([from, rpc.s, '', '', from].concat(
				callArgs))])].join('');
	} else {
		// Format: #targetId & sourceId@callId & packetNum & packetId & packetData
		src = [relay, '#', targetId, '&', from, '@', callId,
			'&1&0&', encodeURIComponent(OpenAjax.gadgets.json.stringify(rpc))].join('');
	}

	// Conduct the IFPC call by creating the Iframe with
	// the relay URL and appended message.
	emitInvisibleIframe(src);
	return true;
	}
};
}();

} // !end of double inclusion guard
/*
 * 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.
 */

OpenAjax.gadgets.rpctx = OpenAjax.gadgets.rpctx || {};

/**
 * For Internet Explorer before version 8, the security model allows anyone
 * parent to set the value of the "opener" property on another window,
 * with only the receiving window able to read it.
 * This method is dubbed "Native IE XDC" (NIX).
 *
 * This method works by placing a handler object in the "opener" property
 * of a gadget when the container sets up the authentication information
 * for that gadget (by calling setAuthToken(...)). At that point, a NIX
 * wrapper is created and placed into the gadget by calling
 * theframe.contentWindow.opener = wrapper. Note that as a result, NIX can
 * only be used by a container to call a particular gadget *after* that
 * gadget has called the container at least once via NIX.
 *
 * The NIX wrappers in this RPC implementation are instances of a VBScript
 * class that is created when this implementation loads. The reason for
 * using a VBScript class stems from the fact that any object can be passed
 * into the opener property.
 * While this is a good thing, as it lets us pass functions and setup a true
 * bidirectional channel via callbacks, it opens a potential security hole
 * by which the other page can get ahold of the "window" or "document"
 * objects in the parent page and in turn wreak havok. This is due to the
 * fact that any JS object useful for establishing such a bidirectional
 * channel (such as a function) can be used to access a function
 * (eg. obj.toString, or a function itself) created in a specific context,
 * in particular the global context of the sender. Suppose container
 * domain C passes object obj to gadget on domain G. Then the gadget can
 * access C's global context using:
 * var parentWindow = (new obj.toString.constructor("return window;"))();
 * Nulling out all of obj's properties doesn't fix this, since IE helpfully
 * restores them to their original values if you do something like:
 * delete obj.toString; delete obj.toString;
 * Thus, we wrap the necessary functions and information inside a VBScript
 * object. VBScript objects in IE, like DOM objects, are in fact COM
 * wrappers when used in JavaScript, so we can safely pass them around
 * without worrying about a breach of context while at the same time
 * allowing them to act as a pass-through mechanism for information
 * and function calls. The implementation details of this VBScript wrapper
 * can be found in the setupChannel() method below.
 *
 *   nix: Internet Explorer-specific window.opener trick.
 *     - Internet Explorer 6
 *     - Internet Explorer 7
 */
if (!OpenAjax.gadgets.rpctx.nix) {  // make lib resilient to double-inclusion

OpenAjax.gadgets.rpctx.nix = function() {
// Consts for NIX. VBScript doesn't
// allow items to start with _ for some reason,
// so we need to make these names quite unique, as
// they will go into the global namespace.
var NIX_WRAPPER = 'GRPC____NIXVBS_wrapper';
var NIX_GET_WRAPPER = 'GRPC____NIXVBS_get_wrapper';
var NIX_HANDLE_MESSAGE = 'GRPC____NIXVBS_handle_message';
var NIX_CREATE_CHANNEL = 'GRPC____NIXVBS_create_channel';
var MAX_NIX_SEARCHES = 10;
var NIX_SEARCH_PERIOD = 500;

// JavaScript reference to the NIX VBScript wrappers.
// Gadgets will have but a single channel under
// nix_channels['..'] while containers will have a channel
// per gadget stored under the gadget's ID.
var nix_channels = {};
var isForceSecure = {};

// Store the ready signal method for use on handshake complete.
var ready;
var numHandlerSearches = 0;

// Search for NIX handler to parent. Tries MAX_NIX_SEARCHES times every
// NIX_SEARCH_PERIOD milliseconds.
function conductHandlerSearch() {
	// Call from gadget to the container.
	var handler = nix_channels['..'];
	if (handler) {
	return;
	}

	if (++numHandlerSearches > MAX_NIX_SEARCHES) {
	// Handshake failed. Will fall back.
	OpenAjax.gadgets.warn('Nix transport setup failed, falling back...');
	ready('..', false);
	return;
	}

	// If the gadget has yet to retrieve a reference to
	// the NIX handler, try to do so now. We don't do a
	// typeof(window.opener.GetAuthToken) check here
	// because it means accessing that field on the COM object, which,
	// being an internal function reference, is not allowed.
	// "in" works because it merely checks for the prescence of
	// the key, rather than actually accessing the object's property.
	// This is just a sanity check, not a validity check.
	if (!handler && window.opener && "GetAuthToken" in window.opener) {
	handler = window.opener;

	// Create the channel to the parent/container.
	// First verify that it knows our auth token to ensure it's not
	// an impostor.
	if (handler.GetAuthToken() == OpenAjax.gadgets.rpc.getAuthToken('..')) {
		// Auth match - pass it back along with our wrapper to finish.
		// own wrapper and our authentication token for co-verification.
		var token = OpenAjax.gadgets.rpc.getAuthToken('..');
		handler.CreateChannel(window[NIX_GET_WRAPPER]('..', token),
							token);
		// Set channel handler
		nix_channels['..'] = handler;
		window.opener = null;

		// Signal success and readiness to send to parent.
		// Container-to-gadget bit flipped in CreateChannel.
		ready('..', true);
		return;
	}
	}

	// Try again.
	window.setTimeout(function() { conductHandlerSearch(); },
					NIX_SEARCH_PERIOD);
}

// Returns current window location, without hash values
function getLocationNoHash() {
	var loc = window.location.href;
	var idx = loc.indexOf('#');
	if (idx == -1) {
	return loc;
	}
	return loc.substring(0, idx);
}

// When "forcesecure" is set to true, use the relay file and a simple variant of IFPC to first
// authenticate the container and gadget with each other.  Once that is done, then initialize
// the NIX protocol.
function setupSecureRelayToParent(rpctoken) {
	// To the parent, transmit the child's URL, the passed in auth
	// token, and another token generated by the child.
	var childToken = (0x7FFFFFFF * Math.random()) | 0;    // TODO expose way to have child set this value
	var data = [
	getLocationNoHash(),
	childToken
	];
	OpenAjax.gadgets.rpc._createRelayIframe(rpctoken, data);

	// listen for response from parent
	var hash = window.location.href.split('#')[1] || '';

	function relayTimer() {
	var newHash = window.location.href.split('#')[1] || '';
	if (newHash !== hash) {
		clearInterval(relayTimerId);
		var params = OpenAjax.gadgets.util.getUrlParameters(window.location.href);
		if (params.childtoken == childToken) {
		// parent has been authenticated; now init NIX
		conductHandlerSearch();
		return;
		}
		// security error -- token didn't match
		ready('..', false);
	}
	}
	var relayTimerId = setInterval( relayTimer, 100 );
}

return {
	getCode: function() {
	return 'nix';
	},

	isParentVerifiable: function(opt_receiverId) {
	// NIX is only parent verifiable if a receiver was setup with "forcesecure" set to TRUE.
	if (opt_receiverId) {
		return isForceSecure[opt_receiverId];
	}
	return false;
	},

	init: function(processFn, readyFn) {
	ready = readyFn;

	// Ensure VBScript wrapper code is in the page and that the
	// global Javascript handlers have been set.
	// VBScript methods return a type of 'unknown' when
	// checked via the typeof operator in IE. Fortunately
	// for us, this only applies to COM objects, so we
	// won't see this for a real Javascript object.
	if (typeof window[NIX_GET_WRAPPER] !== 'unknown') {
		window[NIX_HANDLE_MESSAGE] = function(data) {
		window.setTimeout(
			function() { processFn(OpenAjax.gadgets.json.parse(data)); }, 0);
		};

		window[NIX_CREATE_CHANNEL] = function(name, channel, token) {
		// Verify the authentication token of the gadget trying
		// to create a channel for us.
		if (OpenAjax.gadgets.rpc.getAuthToken(name) === token) {
			nix_channels[name] = channel;
			ready(name, true);
		}
		};

		// Inject the VBScript code needed.
		var vbscript =
		// We create a class to act as a wrapper for
		// a Javascript call, to prevent a break in of
		// the context.
		'Class ' + NIX_WRAPPER + '\n '

		// An internal member for keeping track of the
		// name of the document (container or gadget)
		// for which this wrapper is intended. For
		// those wrappers created by gadgets, this is not
		// used (although it is set to "..")
		+ 'Private m_Intended\n'

		// Stores the auth token used to communicate with
		// the gadget. The GetChannelCreator method returns
		// an object that returns this auth token. Upon matching
		// that with its own, the gadget uses the object
		// to actually establish the communication channel.
		+ 'Private m_Auth\n'

		// Method for internally setting the value
		// of the m_Intended property.
		+ 'Public Sub SetIntendedName(name)\n '
		+ 'If isEmpty(m_Intended) Then\n'
		+ 'm_Intended = name\n'
		+ 'End If\n'
		+ 'End Sub\n'

		// Method for internally setting the value of the m_Auth property.
		+ 'Public Sub SetAuth(auth)\n '
		+ 'If isEmpty(m_Auth) Then\n'
		+ 'm_Auth = auth\n'
		+ 'End If\n'
		+ 'End Sub\n'

		// A wrapper method which actually causes a
		// message to be sent to the other context.
		+ 'Public Sub SendMessage(data)\n '
		+ NIX_HANDLE_MESSAGE + '(data)\n'
		+ 'End Sub\n'

		// Returns the auth token to the gadget, so it can
		// confirm a match before initiating the connection
		+ 'Public Function GetAuthToken()\n '
		+ 'GetAuthToken = m_Auth\n'
		+ 'End Function\n'

		// Method for setting up the container->gadget
		// channel. Not strictly needed in the gadget's
		// wrapper, but no reason to get rid of it. Note here
		// that we pass the intended name to the NIX_CREATE_CHANNEL
		// method so that it can save the channel in the proper place
		// *and* verify the channel via the authentication token passed
		// here.
		+ 'Public Sub CreateChannel(channel, auth)\n '
		+ 'Call ' + NIX_CREATE_CHANNEL + '(m_Intended, channel, auth)\n'
		+ 'End Sub\n'
		+ 'End Class\n'

		// Function to get a reference to the wrapper.
		+ 'Function ' + NIX_GET_WRAPPER + '(name, auth)\n'
		+ 'Dim wrap\n'
		+ 'Set wrap = New ' + NIX_WRAPPER + '\n'
		+ 'wrap.SetIntendedName name\n'
		+ 'wrap.SetAuth auth\n'
		+ 'Set ' + NIX_GET_WRAPPER + ' = wrap\n'
		+ 'End Function';

		try {
		window.execScript(vbscript, 'vbscript');
		} catch (e) {
		return false;
		}
	}
	return true;
	},

	setup: function(receiverId, token, forcesecure) {
	isForceSecure[receiverId] = !!forcesecure;
	if (receiverId === '..') {
		if (forcesecure) {
		setupSecureRelayToParent(token);
		} else {
		conductHandlerSearch();
		}
		return true;
	}
	try {
		var frame = document.getElementById(receiverId);
		var wrapper = window[NIX_GET_WRAPPER](receiverId, token);
		frame.contentWindow.opener = wrapper;
	} catch (e) {
		return false;
	}
	return true;
	},

	call: function(targetId, from, rpc) {
	try {
		// If we have a handler, call it.
		if (nix_channels[targetId]) {
		nix_channels[targetId].SendMessage(OpenAjax.gadgets.json.stringify(rpc));
		}
	} catch (e) {
		return false;
	}
	return true;
	},

	// data = [child URL, child auth token]
	relayOnload: function(receiverId, data) {
	// transmit childtoken back to child to complete authentication
	var src = data[0] + '#childtoken=' + data[1];
	var childIframe = document.getElementById(receiverId);
	childIframe.src = src;
	}
};
}();

} // !end of double-inclusion guard
/*
 * 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.
 */

OpenAjax.gadgets.rpctx = OpenAjax.gadgets.rpctx || {};

/*
 * For older WebKit-based browsers, the security model does not allow for any
 * known "native" hacks for conducting cross browser communication. However,
 * a variation of the IFPC (see below) can be used, entitled "RMR". RMR is
 * a technique that uses the resize event of the iframe to indicate that a
 * message was sent (instead of the much slower/performance heavy polling
 * technique used when a defined relay page is not avaliable). Simply put,
 * RMR uses the same "pass the message by the URL hash" trick that IFPC
 * uses to send a message, but instead of having an active relay page that
 * runs a piece of code when it is loaded, RMR merely changes the URL
 * of the relay page (which does not even have to exist on the domain)
 * and then notifies the other party by resizing the relay iframe. RMR
 * exploits the fact that iframes in the dom of page A can be resized
 * by page A while the onresize event will be fired in the DOM of page B,
 * thus providing a single bit channel indicating "message sent to you".
 * This method has the added benefit that the relay need not be active,
 * nor even exist: a 404 suffices just as well.
 *
 *   rmr: WebKit-specific resizing trick.
 *      - Safari 2+
 *      - Chrome 1
 */
if (!OpenAjax.gadgets.rpctx.rmr) {  // make lib resilient to double-inclusion

OpenAjax.gadgets.rpctx.rmr = function() {
// Consts for RMR, including time in ms RMR uses to poll for
// its relay frame to be created, and the max # of polls it does.
var RMR_SEARCH_TIMEOUT = 500;
var RMR_MAX_POLLS = 10;

// JavaScript references to the channel objects used by RMR.
// Gadgets will have but a single channel under
// rmr_channels['..'] while containers will have a channel
// per gadget stored under the gadget's ID.
var rmr_channels = {};

var process;
var ready;

/**
   * Append an RMR relay frame to the document. This allows the receiver
   * to start receiving messages.
   *
   * @param {Node} channelFrame Relay frame to add to the DOM body.
   * @param {string} relayUri Base URI for the frame.
   * @param {string} data to pass along to the frame.
   * @param {string=} opt_frameId ID of frame for which relay is being appended (optional).
   */
function appendRmrFrame(channelFrame, relayUri, data, opt_frameId) {
	var appendFn = function() {
	// Append the iframe.
	document.body.appendChild(channelFrame);

	// Set the src of the iframe to 'about:blank' first and then set it
	// to the relay URI. This prevents the iframe from maintaining a src
	// to the 'old' relay URI if the page is returned to from another.
	// In other words, this fixes the bfcache issue that causes the iframe's
	// src property to not be updated despite us assigning it a new value here.
	channelFrame.src = 'about:blank';
	if (opt_frameId) {
		// Process the initial sent payload (typically sent by container to
		// child/gadget) only when the relay frame has finished loading. We
		// do this to ensure that, in processRmrData(...), the ACK sent due
		// to processing can actually be sent. Before this time, the frame's
		// contentWindow is null, making it impossible to do so.
		channelFrame.onload = function() {
		processRmrData(opt_frameId);
		};
	}
	channelFrame.src = relayUri + '#' + data;
	};

	if (document.body) {
	appendFn();
	} else {
	// Common gadget case: attaching header during in-gadget handshake,
	// when we may still be in script in head. Attach onload.
	OpenAjax.gadgets.util.registerOnLoadHandler(function() { appendFn(); });
	}
}

/**
   * Sets up the RMR transport frame for the given frameId. For gadgets
   * calling containers, the frameId should be '..'.
   *
   * @param {string} frameId The ID of the frame.
   */
function setupRmr(frameId) {
	if (typeof rmr_channels[frameId] === "object") {
	// Sanity check. Already done.
	return;
	}

	var channelFrame = document.createElement('iframe');
	var frameStyle = channelFrame.style;
	frameStyle.position = 'absolute';
	frameStyle.top = '0px';
	frameStyle.border = '0';
	frameStyle.opacity = '0';

	// The width here is important as RMR
	// makes use of the resize handler for the frame.
	// Do not modify unless you test thoroughly!
	frameStyle.width = '10px';
	frameStyle.height = '1px';
	channelFrame.id = 'rmrtransport-' + frameId;
	channelFrame.name = channelFrame.id;

	// Use the explicitly set relay, if one exists. Otherwise,
	// Construct one using the parent parameter plus robots.txt
	// as a synthetic relay. This works since browsers using RMR
	// treat 404s as legitimate for the purposes of cross domain
	// communication.
	var relayUri = OpenAjax.gadgets.rpc.getRelayUrl(frameId);
	if (!relayUri) {
	relayUri =
		OpenAjax.gadgets.rpc.getOrigin(OpenAjax.gadgets.util.getUrlParameters()["parent"]) +
		'/robots.txt';
	}

	rmr_channels[frameId] = {
	frame: channelFrame,
	receiveWindow: null,
	relayUri: relayUri,
	searchCounter : 0,
	width: 10,

	// Waiting means "waiting for acknowledgement to be received."
	// Acknowledgement always comes as a special ACK
	// message having been received. This message is received
	// during handshake in different ways by the container and
	// gadget, and by normal RMR message passing once the handshake
	// is complete.
	waiting: true,
	queue: [],

	// Number of non-ACK messages that have been sent to the recipient
	// and have been acknowledged.
	sendId: 0,

	// Number of messages received and processed from the sender.
	// This is the number that accompanies every ACK to tell the
	// sender to clear its queue.
	recvId: 0
	};

	if (frameId !== '..') {
	// Container always appends a relay to the gadget, before
	// the gadget appends its own relay back to container. The
	// gadget, in the meantime, refuses to attach the container
	// relay until it finds this one. Thus, the container knows
	// for certain that gadget to container communication is set
	// up by the time it finds its own relay. In addition to
	// establishing a reliable handshake protocol, this also
	// makes it possible for the gadget to send an initial batch
	// of messages to the container ASAP.
	appendRmrFrame(channelFrame, relayUri, getRmrData(frameId));
	}

	// Start searching for our own frame on the other page.
	conductRmrSearch(frameId);
}

/**
   * Searches for a relay frame, created by the sender referenced by
   * frameId, with which this context receives messages. Once
   * found with proper permissions, attaches a resize handler which
   * signals messages to be sent.
   *
   * @param {string} frameId Frame ID of the prospective sender.
   */
function conductRmrSearch(frameId) {
	var channelWindow = null;

	// Increment the search counter.
	rmr_channels[frameId].searchCounter++;

	try {
	var targetWin = OpenAjax.gadgets.rpc._getTargetWin(frameId);
	if (frameId === '..') {
		// We are a gadget.
		channelWindow = targetWin.frames['rmrtransport-' + OpenAjax.gadgets.rpc.RPC_ID];
	} else {
		// We are a container.
		channelWindow = targetWin.frames['rmrtransport-..'];
	}
	} catch (e) {
	// Just in case; may happen when relay is set to about:blank or unset.
	// Catching exceptions here ensures that the timeout to continue the
	// search below continues to work.
	}

	var status = false;

	if (channelWindow) {
	// We have a valid reference to "our" RMR transport frame.
	// Register the proper event handlers.
	status = registerRmrChannel(frameId, channelWindow);
	}

	if (!status) {
	// Not found yet. Continue searching, but only if the counter
	// has not reached the threshold.
	if (rmr_channels[frameId].searchCounter > RMR_MAX_POLLS) {
		// If we reach this point, then RMR has failed and we
		// fall back to IFPC.
		return;
	}

	window.setTimeout(function() {
		conductRmrSearch(frameId);
	}, RMR_SEARCH_TIMEOUT);
	}
}

/**
   * Attempts to conduct an RPC call to the specified
   * target with the specified data via the RMR
   * method. If this method fails, the system attempts again
   * using the known default of IFPC.
   *
   * @param {string} targetId Module Id of the RPC service provider.
   * @param {string} serviceName Name of the service to call.
   * @param {string} from Module Id of the calling provider.
   * @param {Object} rpc The RPC data for this call.
   */
function callRmr(targetId, serviceName, from, rpc) {
	var handler = null;

	if (from !== '..') {
	// Call from gadget to the container.
	handler = rmr_channels['..'];
	} else {
	// Call from container to the gadget.
	handler = rmr_channels[targetId];
	}

	if (handler) {
	// Queue the current message if not ACK.
	// ACK is always sent through getRmrData(...).
	if (serviceName !== OpenAjax.gadgets.rpc.ACK) {
		handler.queue.push(rpc);
	}

	if (handler.waiting ||
		(handler.queue.length === 0 &&
		!(serviceName === OpenAjax.gadgets.rpc.ACK && rpc && rpc.ackAlone === true))) {
		// If we are awaiting a response from any previously-sent messages,
		// or if we don't have anything new to send, just return.
		// Note that we don't short-return if we're ACKing just-received
		// messages.
		return true;
	}

	if (handler.queue.length > 0) {
		handler.waiting = true;
	}

	var url = handler.relayUri + "#" + getRmrData(targetId);

	try {
		// Update the URL with the message.
		handler.frame.contentWindow.location = url;

		// Resize the frame.
		var newWidth = handler.width == 10 ? 20 : 10;
		handler.frame.style.width = newWidth + 'px';
		handler.width = newWidth;

		// Done!
	} catch (e) {
		// Something about location-setting or resizing failed.
		// This should never happen, but if it does, fall back to
		// the default transport.
		return false;
	}
	}

	return true;
}

/**
   * Returns as a string the data to be appended to an RMR relay frame,
   * constructed from the current request queue plus an ACK message indicating
   * the currently latest-processed message ID.
   *
   * @param {string} toFrameId Frame whose sendable queued data to retrieve.
   */
function getRmrData(toFrameId) {
	var channel = rmr_channels[toFrameId];
	var rmrData = {id: channel.sendId};
	if (channel) {
	rmrData.d = Array.prototype.slice.call(channel.queue, 0);
	rmrData.d.push({s:OpenAjax.gadgets.rpc.ACK, id:channel.recvId});
	}
	return OpenAjax.gadgets.json.stringify(rmrData);
}

/**
   * Retrieve data from the channel keyed by the given frameId,
   * processing it as a batch. All processed data is assumed to have been
   * generated by getRmrData(...), pairing that method with this.
   *
   * @param {string} fromFrameId Frame from which data is being retrieved.
   */
function processRmrData(fromFrameId) {
	var channel = rmr_channels[fromFrameId];
	var data = channel.receiveWindow.location.hash.substring(1);

	// Decode the RPC object array.
	var rpcObj = OpenAjax.gadgets.json.parse(decodeURIComponent(data)) || {};
	var rpcArray = rpcObj.d || [];

	var nonAckReceived = false;
	var noLongerWaiting = false;

	var numBypassed = 0;
	var numToBypass = (channel.recvId - rpcObj.id);
	for (var i = 0; i < rpcArray.length; ++i) {
	var rpc = rpcArray[i];

	// If we receive an ACK message, then mark the current
	// handler as no longer waiting and send out the next
	// queued message.
	if (rpc.s === OpenAjax.gadgets.rpc.ACK) {
		// ACK received - whether this came from a handshake or
		// an active call, in either case it indicates readiness to
		// send messages to the from frame.
		ready(fromFrameId, true);

		if (channel.waiting) {
		noLongerWaiting = true;
		}

		channel.waiting = false;
		var newlyAcked = Math.max(0, rpc.id - channel.sendId);
		channel.queue.splice(0, newlyAcked);
		channel.sendId = Math.max(channel.sendId, rpc.id || 0);
		continue;
	}

	// If we get here, we've received > 0 non-ACK messages to
	// process. Indicate this bit for later.
	nonAckReceived = true;

	// Bypass any messages already received.
	if (++numBypassed <= numToBypass) {
		continue;
	}

	++channel.recvId;
	process(rpc);  // actually dispatch the message
	}

	// Send an ACK indicating that we got/processed the message(s).
	// Do so if we've received a message to process or if we were waiting
	// before but a received ACK has cleared our waiting bit, and we have
	// more messages to send. Performing this operation causes additional
	// messages to be sent.
	if (nonAckReceived ||
		(noLongerWaiting && channel.queue.length > 0)) {
	var from = (fromFrameId === '..') ? OpenAjax.gadgets.rpc.RPC_ID : '..';
	callRmr(fromFrameId, OpenAjax.gadgets.rpc.ACK, from, {ackAlone: nonAckReceived});
	}
}

/**
   * Registers the RMR channel handler for the given frameId and associated
   * channel window.
   *
   * @param {string} frameId The ID of the frame for which this channel is being
   *   registered.
   * @param {Object} channelWindow The window of the receive frame for this
   *   channel, if any.
   *
   * @return {boolean} True if the frame was setup successfully, false
   *   otherwise.
   */
function registerRmrChannel(frameId, channelWindow) {
	var channel = rmr_channels[frameId];

	// Verify that the channel is ready for receiving.
	try {
	var canAccess = false;

	// Check to see if the document is in the window. For Chrome, this
	// will return 'false' if the channelWindow is inaccessible by this
	// piece of JavaScript code, meaning that the URL of the channelWindow's
	// parent iframe has not yet changed from 'about:blank'. We do this
	// check this way because any true *access* on the channelWindow object
	// will raise a security exception, which, despite the try-catch, still
	// gets reported to the debugger (it does not break execution, the try
	// handles that problem, but it is still reported, which is bad form).
	// This check always succeeds in Safari 3.1 regardless of the state of
	// the window.
	canAccess = 'document' in channelWindow;

	if (!canAccess) {
		return false;
	}

	// Check to see if the document is an object. For Safari 3.1, this will
	// return undefined if the page is still inaccessible. Unfortunately, this
	// *will* raise a security issue in the debugger.
	// TODO Find a way around this problem.
	canAccess = typeof channelWindow['document'] == 'object';

	if (!canAccess) {
		return false;
	}

	// Once we get here, we know we can access the document (and anything else)
	// on the window object. Therefore, we check to see if the location is
	// still about:blank (this takes care of the Safari 3.2 case).
	var loc = channelWindow.location.href;

	// Check if this is about:blank for Safari.
	if (loc === 'about:blank') {
		return false;
	}
	} catch (ex) {
	// For some reason, the iframe still points to about:blank. We try
	// again in a bit.
	return false;
	}

	// Save a reference to the receive window.
	channel.receiveWindow = channelWindow;

	// Register the onresize handler.
	function onresize() {
	processRmrData(frameId);
	}

	if (typeof channelWindow.attachEvent === "undefined") {
	channelWindow.onresize = onresize;
	} else {
	channelWindow.attachEvent("onresize", onresize);
	}

	if (frameId === '..') {
	// Gadget to container. Signal to the container that the gadget
	// is ready to receive messages by attaching the g -> c relay.
	// As a nice optimization, pass along any gadget to container
	// queued messages that have backed up since then. ACK is enqueued in
	// getRmrData to ensure that the container's waiting flag is set to false
	// (this happens in the below code run on the container side).
	appendRmrFrame(channel.frame, channel.relayUri, getRmrData(frameId), frameId);
	} else {
	// Process messages that the gadget sent in its initial relay payload.
	// We can do this immediately because the container has already appended
	// and loaded a relay frame that can be used to ACK the messages the gadget
	// sent. In the preceding if-block, however, the processRmrData(...) call
	// must wait. That's because appendRmrFrame may not actually append the
	// frame - in the context of a gadget, this code may be running in the
	// head element, so it cannot be appended to body. As a result, the
	// gadget cannot ACK the container for messages it received.
	processRmrData(frameId);
	}

	return true;
}

return {
	getCode: function() {
	return 'rmr';
	},

	isParentVerifiable: function() {
	return true;
	},

	init: function(processFn, readyFn) {
	// No global setup.
	process = processFn;
	ready = readyFn;
	return true;
	},

	setup: function(receiverId, token) {
	try {
		setupRmr(receiverId);
	} catch (e) {
		OpenAjax.gadgets.warn('Caught exception setting up RMR: ' + e);
		return false;
	}
	return true;
	},

	call: function(targetId, from, rpc) {
	return callRmr(targetId, rpc.s, from, rpc);
	}
};
}();

} // !end of double-inclusion guard
/*
 * 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.
 */

OpenAjax.gadgets.rpctx = OpenAjax.gadgets.rpctx || {};

/**
 * Transport for browsers that support native messaging (various implementations
 * of the HTML5 postMessage method). Officially defined at
 * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html.
 *
 * postMessage is a native implementation of XDC. A page registers that
 * it would like to receive messages by listening the the "message" event
 * on the window (document in DPM) object. In turn, another page can
 * raise that event by calling window.postMessage (document.postMessage
 * in DPM) with a string representing the message and a string
 * indicating on which domain the receiving page must be to receive
 * the message. The target page will then have its "message" event raised
 * if the domain matches and can, in turn, check the origin of the message
 * and process the data contained within.
 *
 *   wpm: postMessage on the window object.
 *      - Internet Explorer 8+
 *      - Safari 4+
 *      - Chrome 2+
 *      - Webkit nightlies
 *      - Firefox 3+
 *      - Opera 9+
 */
if (!OpenAjax.gadgets.rpctx.wpm) {  // make lib resilient to double-inclusion

OpenAjax.gadgets.rpctx.wpm = function() {
var process, ready;
var postMessage;
var pmSync = false;
var pmEventDomain = false;

// Some browsers (IE, Opera) have an implementation of postMessage that is
// synchronous, although HTML5 specifies that it should be asynchronous.  In
// order to make all browsers behave consistently, we run a small test to detect
// if postMessage is asynchronous or not.  If not, we wrap calls to postMessage
// in a setTimeout with a timeout of 0.
// Also, Opera's "message" event does not have an "origin" property (at least,
// it doesn't in version 9.64;  presumably, it will in version 10).  If
// event.origin does not exist, use event.domain.  The other difference is that
// while event.origin looks like <scheme>://<hostname>:<port>, event.domain
// consists only of <hostname>.
//
function testPostMessage() {
	var hit = false;

	function receiveMsg(event) {
	if (event.data == "postmessage.test") {
		hit = true;
		if (typeof event.origin === "undefined") {
		pmEventDomain = true;
		}
	}
	}

	OpenAjax.gadgets.util.attachBrowserEvent(window, "message", receiveMsg, false);
	window.postMessage("postmessage.test", "*");

	// if 'hit' is true here, then postMessage is synchronous
	if (hit) {
	pmSync = true;
	}

	OpenAjax.gadgets.util.removeBrowserEvent(window, "message", receiveMsg, false);
}

function onmessage(packet) {
	var rpc = OpenAjax.gadgets.json.parse(packet.data);
	if (!rpc || !rpc.f) {
	return;
	}

	// for security, check origin against expected value
	var origRelay = OpenAjax.gadgets.rpc.getRelayUrl(rpc.f) ||
					OpenAjax.gadgets.util.getUrlParameters()["parent"];
	var origin = OpenAjax.gadgets.rpc.getOrigin(origRelay);
	if (!pmEventDomain ? packet.origin !== origin :
						packet.domain !== /^.+:\/\/([^:]+).*/.exec( origin )[1]) {
	return;
	}

	process(rpc);
}

return {
	getCode: function() {
	return 'wpm';
	},

	isParentVerifiable: function() {
	return true;
	},

	init: function(processFn, readyFn) {
	process = processFn;
	ready = readyFn;

	testPostMessage();
	if (!pmSync) {
		postMessage = function(win, msg, origin) {
		win.postMessage(msg, origin);
		};
	} else {
		postMessage = function(win, msg, origin) {
		window.setTimeout( function() {
			win.postMessage(msg, origin);
		}, 0);
		};
	}

	// Set up native postMessage handler.
	OpenAjax.gadgets.util.attachBrowserEvent(window, 'message', onmessage, false);

	ready('..', true);  // Immediately ready to send to parent.
	return true;
	},

	setup: function(receiverId, token, forcesecure) {
	// If we're a gadget, send an ACK message to indicate to container
	// that we're ready to receive messages.
	if (receiverId === '..') {
		if (forcesecure) {
		OpenAjax.gadgets.rpc._createRelayIframe(token);
		} else {
		OpenAjax.gadgets.rpc.call(receiverId, OpenAjax.gadgets.rpc.ACK);
		}
	}
	return true;
	},

	call: function(targetId, from, rpc) {
	var targetWin = OpenAjax.gadgets.rpc._getTargetWin(targetId);
	// targetOrigin = canonicalized relay URL
	var origRelay = OpenAjax.gadgets.rpc.getRelayUrl(targetId) ||
					OpenAjax.gadgets.util.getUrlParameters()["parent"];
	var origin = OpenAjax.gadgets.rpc.getOrigin(origRelay);
	if (origin) {
		postMessage(targetWin, OpenAjax.gadgets.json.stringify(rpc), origin);
	} else {
		OpenAjax.gadgets.error("No relay set (used as window.postMessage targetOrigin)" +
			", cannot send cross-domain message");
	}
	return true;
	},

	relayOnload: function(receiverId, data) {
	ready(receiverId, true);
	}
};
}();

} // !end of double-inclusion guard
/*
 * 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.
 */

/**
 * @fileoverview Remote procedure call library for gadget-to-container,
 * container-to-gadget, and gadget-to-gadget (thru container) communication.
 */

/**
 * gadgets.rpc Transports
 *
 * All transports are stored in object gadgets.rpctx, and are provided
 * to the core gadgets.rpc library by various build rules.
 *
 * Transports used by core gadgets.rpc code to actually pass messages.
 * each transport implements the same interface exposing hooks that
 * the core library calls at strategic points to set up and use
 * the transport.
 *
 * The methods each transport must implement are:
 * + getCode(): returns a string identifying the transport. For debugging.
 * + isParentVerifiable(): indicates (via boolean) whether the method
 *     has the property that its relay URL verifies for certain the
 *     receiver's protocol://host:port.
 * + init(processFn, readyFn): Performs any global initialization needed. Called
 *     before any other gadgets.rpc methods are invoked. processFn is
 *     the function in gadgets.rpc used to process an rpc packet. readyFn is
 *     a function that must be called when the transport is ready to send
 *     and receive messages bidirectionally. Returns
 *     true if successful, false otherwise.
 * + setup(receiverId, token): Performs per-receiver initialization, if any.
 *     receiverId will be '..' for gadget-to-container. Returns true if
 *     successful, false otherwise.
 * + call(targetId, from, rpc): Invoked to send an actual
 *     message to the given targetId, with the given serviceName, from
 *     the sender identified by 'from'. Payload is an rpc packet. Returns
 *     true if successful, false otherwise.
 */

if (!OpenAjax.gadgets.rpc) { // make lib resilient to double-inclusion

/**
 * @static
 * @namespace Provides operations for making rpc calls.
 * @name gadgets.rpc
 */

OpenAjax.gadgets.rpc = function() {
/**
   * @const
   * @private
   */
var CALLBACK_NAME = '__cb';

/**
   * @const
   * @private
   */
var DEFAULT_NAME = '';

/** Exported constant, for use by transports only.
   * @const
   * @type {string}
   * @member gadgets.rpc
   */
var ACK = '__ack';

/**
   * Timeout and number of attempts made to setup a transport receiver.
   * @const
   * @private
   */
var SETUP_FRAME_TIMEOUT = 500;

/**
   * @const
   * @private
   */
var SETUP_FRAME_MAX_TRIES = 10;

var services = {};
var relayUrl = {};
var useLegacyProtocol = {};
var authToken = {};
var callId = 0;
var callbacks = {};
var setup = {};
var sameDomain = {};
var params = {};
var receiverTx = {};
var earlyRpcQueue = {};

// isGadget =~ isChild for the purposes of rpc (used only in setup).
var isChild = (window.top !== window.self);

// Set the current rpc ID from window.name immediately, to prevent
// shadowing of window.name by a "var name" declaration, or similar.
var rpcId = window.name;

var securityCallback = function() {};
var LOAD_TIMEOUT = 0;
var FRAME_PHISH = 1;
var FORGED_MSG = 2;

// Fallback transport is simply a dummy impl that emits no errors
// and logs info on calls it receives, to avoid undesired side-effects
// from falling back to IFPC or some other transport.
var fallbackTransport = (function() {
	function logFn(name) {
	return function() {
		OpenAjax.gadgets.log("gadgets.rpc." + name + "(" +
					OpenAjax.gadgets.json.stringify(Array.prototype.slice.call(arguments)) +
					"): call ignored. [caller: " + document.location +
					", isChild: " + isChild + "]");
	};
	}
	return {
	getCode: function() {
		return "noop";
	},
	isParentVerifiable: function() {
		return true;  // Not really, but prevents transport assignment to IFPC.
	},
	init: logFn("init"),
	setup: logFn("setup"),
	call: logFn("call")
	};
})();

// Load the authentication token for speaking to the container
// from the gadget's parameters, or default to '0' if not found.
if (OpenAjax.gadgets.util) {
	params = OpenAjax.gadgets.util.getUrlParameters();
}

/**
   * Return a transport representing the best available cross-domain
   * message-passing mechanism available to the browser.
   *
   * <p>Transports are selected on a cascading basis determined by browser
   * capability and other checks. The order of preference is:
   * <ol>
   * <li> wpm: Uses window.postMessage standard.
   * <li> dpm: Uses document.postMessage, similar to wpm but pre-standard.
   * <li> nix: Uses IE-specific browser hacks.
   * <li> rmr: Signals message passing using relay file's onresize handler.
   * <li> fe: Uses FF2-specific window.frameElement hack.
   * <li> ifpc: Sends messages via active load of a relay file.
   * </ol>
   * <p>See each transport's commentary/documentation for details.
   * @return {Object}
   * @member gadgets.rpc
   */
function getTransport() {
	return typeof window.postMessage === 'function' ? OpenAjax.gadgets.rpctx.wpm :
		typeof window.postMessage === 'object' ? OpenAjax.gadgets.rpctx.wpm :
		window.ActiveXObject ? OpenAjax.gadgets.rpctx.nix :
		navigator.userAgent.indexOf('WebKit') > 0 ? OpenAjax.gadgets.rpctx.rmr :
		navigator.product === 'Gecko' ? OpenAjax.gadgets.rpctx.frameElement :
		OpenAjax.gadgets.rpctx.ifpc;
}

/**
   * Function passed to, and called by, a transport indicating it's ready to
   * send and receive messages.
   */
function transportReady(receiverId, readySuccess) {
	var tx = transport;
	if (!readySuccess) {
	tx = fallbackTransport;
	}
	receiverTx[receiverId] = tx;

	// If there are any early-queued messages, send them now directly through
	// the needed transport.
	var earlyQueue = earlyRpcQueue[receiverId] || [];
	for (var i = 0; i < earlyQueue.length; ++i) {
	var rpc = earlyQueue[i];
	// There was no auth/rpc token set before, so set it now.
	rpc.t = getAuthToken(receiverId);
	tx.call(receiverId, rpc.f, rpc);
	}

	// Clear the queue so it won't be sent again.
	earlyRpcQueue[receiverId] = [];
}

//  Track when this main page is closed or navigated to a different location
// ("unload" event).
//  NOTE: The use of the "unload" handler here and for the relay iframe
// prevents the use of the in-memory page cache in modern browsers.
// See: https://developer.mozilla.org/en/using_firefox_1.5_caching
// See: http://webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/
var mainPageUnloading = false,
	hookedUnload = false;

function hookMainPageUnload() {
	if ( hookedUnload ) {
	return;
	}
	function onunload() {
	mainPageUnloading = true;
	}
	OpenAjax.gadgets.util.attachBrowserEvent(window, 'unload', onunload, false);
	hookedUnload = true;
}

function relayOnload(targetId, sourceId, token, data, relayWindow) {
	// Validate auth token.
	if (!authToken[sourceId] || authToken[sourceId] !== token) {
	OpenAjax.gadgets.error("Invalid auth token. " + authToken[sourceId] + " vs " + token);
	securityCallback(sourceId, FORGED_MSG);
	}

	relayWindow.onunload = function() {
	if (setup[sourceId] && !mainPageUnloading) {
		securityCallback(sourceId, FRAME_PHISH);
		OpenAjax.gadgets.rpc.removeReceiver(sourceId);
	}
	};
	hookMainPageUnload();

	data = OpenAjax.gadgets.json.parse(decodeURIComponent(data));
	transport.relayOnload(sourceId, data);
}

/**
   * Helper function to process an RPC request
   * @param {Object} rpc RPC request object
   * @private
   */
function process(rpc) {
	//
	// RPC object contents:
	//   s: Service Name
	//   f: From
	//   c: The callback ID or 0 if none.
	//   a: The arguments for this RPC call.
	//   t: The authentication token.
	//
	if (rpc && typeof rpc.s === 'string' && typeof rpc.f === 'string' &&
		rpc.a instanceof Array) {

	// Validate auth token.
	if (authToken[rpc.f]) {
		// We don't do type coercion here because all entries in the authToken
		// object are strings, as are all url params. See setupReceiver(...).
		if (authToken[rpc.f] !== rpc.t) {
		OpenAjax.gadgets.error("Invalid auth token. " + authToken[rpc.f] + " vs " + rpc.t);
		securityCallback(rpc.f, FORGED_MSG);
		}
	}

	if (rpc.s === ACK) {
		// Acknowledgement API, used to indicate a receiver is ready.
		window.setTimeout(function() { transportReady(rpc.f, true); }, 0);
		return;
	}

	// If there is a callback for this service, attach a callback function
	// to the rpc context object for asynchronous rpc services.
	//
	// Synchronous rpc request handlers should simply ignore it and return a
	// value as usual.
	// Asynchronous rpc request handlers, on the other hand, should pass its
	// result to this callback function and not return a value on exit.
	//
	// For example, the following rpc handler passes the first parameter back
	// to its rpc client with a one-second delay.
	//
	// function asyncRpcHandler(param) {
	//   var me = this;
	//   setTimeout(function() {
	//     me.callback(param);
	//   }, 1000);
	// }
	if (rpc.c) {
		rpc.callback = function(result) {
		OpenAjax.gadgets.rpc.call(rpc.f, CALLBACK_NAME, null, rpc.c, result);
		};
	}

	// Call the requested RPC service.
	var result = (services[rpc.s] ||
					services[DEFAULT_NAME]).apply(rpc, rpc.a);

	// If the rpc request handler returns a value, immediately pass it back
	// to the callback. Otherwise, do nothing, assuming that the rpc handler
	// will make an asynchronous call later.
	if (rpc.c && typeof result !== 'undefined') {
		OpenAjax.gadgets.rpc.call(rpc.f, CALLBACK_NAME, null, rpc.c, result);
	}
	}
}

/**
   * Helper method returning a canonicalized protocol://host[:port] for
   * a given input URL, provided as a string. Used to compute convenient
   * relay URLs and to determine whether a call is coming from the same
   * domain as its receiver (bypassing the try/catch capability detection
   * flow, thereby obviating Firebug and other tools reporting an exception).
   *
   * @param {string} url Base URL to canonicalize.
   * @memberOf gadgets.rpc
   */

function getOrigin(url) {
	if (!url) {
	return "";
	}
	url = url.toLowerCase();
	if (url.indexOf("//") == 0) {
	url = window.location.protocol + url;
	}
	if (url.indexOf("://") == -1) {
	// Assumed to be schemaless. Default to current protocol.
	url = window.location.protocol + "//" + url;
	}
	// At this point we guarantee that "://" is in the URL and defines
	// current protocol. Skip past this to search for host:port.
	var host = url.substring(url.indexOf("://") + 3);

	// Find the first slash char, delimiting the host:port.
	var slashPos = host.indexOf("/");
	if (slashPos != -1) {
	host = host.substring(0, slashPos);
	}

	var protocol = url.substring(0, url.indexOf("://"));

	// Use port only if it's not default for the protocol.
	var portStr = "";
	var portPos = host.indexOf(":");
	if (portPos != -1) {
	var port = host.substring(portPos + 1);
	host = host.substring(0, portPos);
	if ((protocol === "http" && port !== "80") ||
		(protocol === "https" && port !== "443")) {
		portStr = ":" + port;
	}
	}

	// Return <protocol>://<host>[<port>]
	return protocol + "://" + host + portStr;
}

function getTargetWin(id) {
	if (typeof id === "undefined" ||
		id === "..") {
	return window.parent;
	}

	// Cast to a String to avoid an index lookup.
	id = String(id);

	// Try window.frames first
	var target = window.frames[id];
	if (target) {
	return target;
	}

	// Fall back to getElementById()
	target = document.getElementById(id);
	if (target && target.contentWindow) {
	return target.contentWindow;
	}

	return null;
}

// Pick the most efficient RPC relay mechanism.
var transport = getTransport();

// Create the Default RPC handler.
services[DEFAULT_NAME] = function() {
	OpenAjax.gadgets.warn('Unknown RPC service: ' + this.s);
};

// Create a Special RPC handler for callbacks.
services[CALLBACK_NAME] = function(callbackId, result) {
	var callback = callbacks[callbackId];
	if (callback) {
	delete callbacks[callbackId];
	callback(result);
	}
};

/**
   * Conducts any frame-specific work necessary to setup
   * the channel type chosen. This method is called when
   * the container page first registers the gadget in the
   * RPC mechanism. Gadgets, in turn, will complete the setup
   * of the channel once they send their first messages.
   */
function setupFrame(frameId, token, forcesecure) {
	if (setup[frameId] === true) {
	return;
	}

	if (typeof setup[frameId] === 'undefined') {
	setup[frameId] = 0;
	}

	var tgtFrame = document.getElementById(frameId);
	if (frameId === '..' || tgtFrame != null) {
	if (transport.setup(frameId, token, forcesecure) === true) {
		setup[frameId] = true;
		return;
	}
	}

	if (setup[frameId] !== true && setup[frameId]++ < SETUP_FRAME_MAX_TRIES) {
	// Try again in a bit, assuming that frame will soon exist.
	window.setTimeout(function() { setupFrame(frameId, token, forcesecure); },
						SETUP_FRAME_TIMEOUT);
	} else {
	// Fail: fall back for this gadget.
	receiverTx[frameId] = fallbackTransport;
	setup[frameId] = true;
	}
}

/**
   * Attempts to make an rpc by calling the target's receive method directly.
   * This works when gadgets are rendered on the same domain as their container,
   * a potentially useful optimization for trusted content which keeps
   * RPC behind a consistent interface.
   *
   * @param {string} target Module id of the rpc service provider
   * @param {Object} rpc RPC data
   * @return {boolean}
   */
function callSameDomain(target, rpc) {
	if (typeof sameDomain[target] === 'undefined') {
	// Seed with a negative, typed value to avoid
	// hitting this code path repeatedly.
	sameDomain[target] = false;
	var targetRelay = OpenAjax.gadgets.rpc.getRelayUrl(target);
	if (getOrigin(targetRelay) !== getOrigin(window.location.href)) {
		// Not worth trying -- avoid the error and just return.
		return false;
	}

	var targetEl = getTargetWin(target);
	try {
		// If this succeeds, then same-domain policy applied
		sameDomain[target] = targetEl.OpenAjax.gadgets.rpc.receiveSameDomain;
	} catch (e) {
		// Shouldn't happen due to origin check. Caught to emit
		// more meaningful error to the caller.
		OpenAjax.gadgets.error("Same domain call failed: parent= incorrectly set.");
	}
	}

	if (typeof sameDomain[target] === 'function') {
	// Call target's receive method
	sameDomain[target](rpc);
	return true;
	}

	return false;
}

/**
   * Sets the relay URL of a target frame.
   * @param {string} targetId Name of the target frame.
   * @param {string} url Full relay URL of the target frame.
   * @param {boolean=} opt_useLegacy True if this relay needs the legacy IFPC
   *     wire format.
   *
   * @member gadgets.rpc
   * @deprecated
   */
function setRelayUrl(targetId, url, opt_useLegacy) {
	// make URL absolute if necessary
	if (!/http(s)?:\/\/.+/.test(url)) {
	if (url.indexOf("//") == 0) {
		url = window.location.protocol + url;
	} else if (url.charAt(0) == '/') {
		url = window.location.protocol + "//" + window.location.host + url;
	} else if (url.indexOf("://") == -1) {
		// Assumed to be schemaless. Default to current protocol.
		url = window.location.protocol + "//" + url;
	}
	}
	relayUrl[targetId] = url;
	useLegacyProtocol[targetId] = !!opt_useLegacy;
}

/**
   * Helper method to retrieve the authToken for a given gadget.
   * Not to be used directly.
   * @member gadgets.rpc
   * @return {string}
   */
function getAuthToken(targetId) {
	return authToken[targetId];
}

/**
   * Sets the auth token of a target frame.
   * @param {string} targetId Name of the target frame.
   * @param {string} token The authentication token to use for all
   *     calls to or from this target id.
   *
   * @member gadgets.rpc
   * @deprecated
   */
function setAuthToken(targetId, token, forcesecure) {
	token = token || "";

	// Coerce token to a String, ensuring that all authToken values
	// are strings. This ensures correct comparison with URL params
	// in the process(rpc) method.
	authToken[targetId] = String(token);

	setupFrame(targetId, token, forcesecure);
}

function setupContainerGadgetContext(rpctoken, opt_forcesecure) {
	/**
	 * Initializes gadget to container RPC params from the provided configuration.
	 */
	function init(config) {
	var configRpc = config ? config.rpc : {};
	var parentRelayUrl = configRpc.parentRelayUrl;

	// Allow for wild card parent relay files as long as it's from a
	// white listed domain. This is enforced by the rendering servlet.
	if (parentRelayUrl.substring(0, 7) !== 'http://' &&
		parentRelayUrl.substring(0, 8) !== 'https://' &&
		parentRelayUrl.substring(0, 2) !== '//') {
		// Relative path: we append to the parent.
		// We're relying on the server validating the parent parameter in this
		// case. Because of this, parent may only be passed in the query, not fragment.
		if (typeof params.parent === "string" && params.parent !== "") {
		// Otherwise, relayUrl['..'] will be null, signaling transport
		// code to ignore rpc calls since they cannot work without a
		// relay URL with host qualification.
		if (parentRelayUrl.substring(0, 1) !== '/') {
			// Path-relative. Trust that parent is passed in appropriately.
			var lastSlash = params.parent.lastIndexOf('/');
			parentRelayUrl = params.parent.substring(0, lastSlash + 1) + parentRelayUrl;
		} else {
			// Host-relative.
			parentRelayUrl = getOrigin(params.parent) + parentRelayUrl;
		}
		}
	}

	var useLegacy = !!configRpc.useLegacyProtocol;
	setRelayUrl('..', parentRelayUrl, useLegacy);

	if (useLegacy) {
		transport = OpenAjax.gadgets.rpctx.ifpc;
		transport.init(process, transportReady);
	}

	// Sets the auth token and signals transport to setup connection to container.
	var forceSecure = opt_forcesecure || params.forcesecure || false;
	setAuthToken('..', rpctoken, forceSecure);
	}

	var requiredConfig = {
	parentRelayUrl : OpenAjax.gadgets.config.NonEmptyStringValidator
	};
	OpenAjax.gadgets.config.register("rpc", requiredConfig, init);
}

function setupContainerGenericIframe(rpctoken, opt_parent, opt_forcesecure) {
	// Generic child IFRAME setting up connection w/ its container.
	// Use the opt_parent param if provided, or the "parent" query param
	// if found -- otherwise, do nothing since this call might be initiated
	// automatically at first, then actively later in IFRAME code.
	var forcesecure = opt_forcesecure || params.forcesecure || false;
	var parent = opt_parent || params.parent;
	if (parent) {
	setRelayUrl('..', parent);
	setAuthToken('..', rpctoken, forcesecure);
	}
}

function setupChildIframe(gadgetId, opt_frameurl, opt_authtoken, opt_forcesecure) {
	if (!OpenAjax.gadgets.util) {
	return;
	}
	var childIframe = document.getElementById(gadgetId);
	if (!childIframe) {
	throw new Error("Cannot set up gadgets.rpc receiver with ID: " + gadgetId +
		", element not found.");
	}

	// The "relay URL" can either be explicitly specified or is set as
	// the child IFRAME URL verbatim.
	var relayUrl = opt_frameurl || childIframe.src;
	setRelayUrl(gadgetId, relayUrl);

	// The auth token is parsed from child params (rpctoken) or overridden.
	var childParams = OpenAjax.gadgets.util.getUrlParameters(childIframe.src);
	var rpctoken = opt_authtoken || childParams.rpctoken;
	var forcesecure = opt_forcesecure || childParams.forcesecure;
	setAuthToken(gadgetId, rpctoken, forcesecure);
}

/**
   * Sets up the gadgets.rpc library to communicate with the receiver.
   * <p>This method replaces setRelayUrl(...) and setAuthToken(...)
   *
   * <p>Simplified instructions - highly recommended:
   * <ol>
   * <li> Generate &lt;iframe id="&lt;ID&gt;" src="...#parent=&lt;PARENTURL&gt;&rpctoken=&lt;RANDOM&gt;"/&gt;
   *      and add to DOM.
   * <li> Call gadgets.rpc.setupReceiver("&lt;ID>");
   *      <p>All parent/child communication initializes automatically from here.
   *         Naturally, both sides need to include the library.
   * </ol>
   *
   * <p>Detailed container/parent instructions:
   * <ol>
   * <li> Create the target IFRAME (eg. gadget) with a given &lt;ID> and params
   *    rpctoken=<token> (eg. #rpctoken=1234), which is a random/unguessbable
   *    string, and parent=&lt;url>, where &lt;url> is the URL of the container.
   * <li> Append IFRAME to the document.
   * <li> Call gadgets.rpc.setupReceiver(&lt;ID>)
   * <p>[Optional]. Strictly speaking, you may omit rpctoken and parent. This
   *             practice earns little but is occasionally useful for testing.
   *             If you omit parent, you MUST pass your container URL as the 2nd
   *             parameter to this method.
   * </ol>
   *
   * <p>Detailed gadget/child IFRAME instructions:
   * <ol>
   * <li> If your container/parent passed parent and rpctoken params (query string
   *    or fragment are both OK), you needn't do anything. The library will self-
   *    initialize.
   * <li> If "parent" is omitted, you MUST call this method with targetId '..'
   *    and the second param set to the parent URL.
   * <li> If "rpctoken" is omitted, but the container set an authToken manually
   *    for this frame, you MUST pass that ID (however acquired) as the 2nd param
   *    to this method.
   * </ol>
   *
   * @member gadgets.rpc
   * @param {string} targetId
   * @param {string=} opt_receiverurl
   * @param {string=} opt_authtoken
   * @param {boolean=} opt_forcesecure
   */
function setupReceiver(targetId, opt_receiverurl, opt_authtoken, opt_forcesecure) {
	if (targetId === '..') {
	// Gadget/IFRAME to container.
	var rpctoken = opt_authtoken || params.rpctoken || params.ifpctok || "";
	if (window['__isgadget'] === true) {
		setupContainerGadgetContext(rpctoken, opt_forcesecure);
	} else {
		setupContainerGenericIframe(rpctoken, opt_receiverurl, opt_forcesecure);
	}
	} else {
	// Container to child.
	setupChildIframe(targetId, opt_receiverurl, opt_authtoken, opt_forcesecure);
	}
}

return /** @scope gadgets.rpc */ {
	config: function(config) {
	if (typeof config.securityCallback === 'function') {
		securityCallback = config.securityCallback;
	}
	},

	/**
	 * Registers an RPC service.
	 * @param {string} serviceName Service name to register.
	 * @param {function(Object,Object)} handler Service handler.
	 *
	 * @member gadgets.rpc
	 */
	register: function(serviceName, handler) {
	if (serviceName === CALLBACK_NAME || serviceName === ACK) {
		throw new Error("Cannot overwrite callback/ack service");
	}

	if (serviceName === DEFAULT_NAME) {
		throw new Error("Cannot overwrite default service:"
						+ " use registerDefault");
	}

	services[serviceName] = handler;
	},

	/**
	 * Unregisters an RPC service.
	 * @param {string} serviceName Service name to unregister.
	 *
	 * @member gadgets.rpc
	 */
	unregister: function(serviceName) {
	if (serviceName === CALLBACK_NAME || serviceName === ACK) {
		throw new Error("Cannot delete callback/ack service");
	}

	if (serviceName === DEFAULT_NAME) {
		throw new Error("Cannot delete default service:"
						+ " use unregisterDefault");
	}

	delete services[serviceName];
	},

	/**
	 * Registers a default service handler to processes all unknown
	 * RPC calls which raise an exception by default.
	 * @param {function(Object,Object)} handler Service handler.
	 *
	 * @member gadgets.rpc
	 */
	registerDefault: function(handler) {
	services[DEFAULT_NAME] = handler;
	},

	/**
	 * Unregisters the default service handler. Future unknown RPC
	 * calls will fail silently.
	 *
	 * @member gadgets.rpc
	 */
	unregisterDefault: function() {
	delete services[DEFAULT_NAME];
	},

	/**
	 * Forces all subsequent calls to be made by a transport
	 * method that allows the caller to verify the message receiver
	 * (by way of the parent parameter, through getRelayUrl(...)).
	 * At present this means IFPC or WPM.
	 * @member gadgets.rpc
	 */
	forceParentVerifiable: function() {
	if (!transport.isParentVerifiable()) {
		transport = OpenAjax.gadgets.rpctx.ifpc;
	}
	},

	/**
	 * Calls an RPC service.
	 * @param {string} targetId Module Id of the RPC service provider.
	 *                          Empty if calling the parent container.
	 * @param {string} serviceName Service name to call.
	 * @param {function()|null} callback Callback function (if any) to process
	 *                                 the return value of the RPC request.
	 * @param {*} var_args Parameters for the RPC request.
	 *
	 * @member gadgets.rpc
	 */
	call: function(targetId, serviceName, callback, var_args) {
	targetId = targetId || '..';
	// Default to the container calling.
	var from = '..';

	if (targetId === '..') {
		from = rpcId;
	}

	++callId;
	if (callback) {
		callbacks[callId] = callback;
	}

	var rpc = {
		s: serviceName,
		f: from,
		c: callback ? callId : 0,
		a: Array.prototype.slice.call(arguments, 3),
		t: authToken[targetId],
		l: useLegacyProtocol[targetId]
	};

	if (targetId !== '..' && !document.getElementById(targetId)) {
		// The target has been removed from the DOM. Don't even try.
		OpenAjax.gadgets.log("WARNING: attempted send to nonexistent frame: " + targetId);
		return;
	}

	// If target is on the same domain, call method directly
	if (callSameDomain(targetId, rpc)) {
		return;
	}

	// Attempt to make call via a cross-domain transport.
	// Retrieve the transport for the given target - if one
	// target is misconfigured, it won't affect the others.
	var channel = receiverTx[targetId];

	if (!channel) {
		// Not set up yet. Enqueue the rpc for such time as it is.
		if (!earlyRpcQueue[targetId]) {
		earlyRpcQueue[targetId] = [ rpc ];
		} else {
		earlyRpcQueue[targetId].push(rpc);
		}
		return;
	}

	// If we are told to use the legacy format, then we must
	// default to IFPC.
	if (useLegacyProtocol[targetId]) {
		channel = OpenAjax.gadgets.rpctx.ifpc;
	}

	if (channel.call(targetId, from, rpc) === false) {
		// Fall back to IFPC. This behavior may be removed as IFPC is as well.
		receiverTx[targetId] = fallbackTransport;
		transport.call(targetId, from, rpc);
	}
	},

	/**
	 * Gets the relay URL of a target frame.
	 * @param {string} targetId Name of the target frame.
	 * @return {string|undefined} Relay URL of the target frame.
	 *
	 * @member gadgets.rpc
	 */
	getRelayUrl: function(targetId) {
	var url = relayUrl[targetId];
	// Some RPC methods (wpm, for one) are unhappy with schemeless URLs.
	if (url && url.substring(0,1) === '/') {
		if (url.substring(1,2) === '/') {    // starts with '//'
		url = document.location.protocol + url;
		} else {    // relative URL, starts with '/'
		url = document.location.protocol + '//' + document.location.host + url;
		}
	}

	return url;
	},

	setRelayUrl: setRelayUrl,
	setAuthToken: setAuthToken,
	setupReceiver: setupReceiver,
	getAuthToken: getAuthToken,

	// Note: Does not delete iframe
	removeReceiver: function(receiverId) {
	delete relayUrl[receiverId];
	delete useLegacyProtocol[receiverId];
	delete authToken[receiverId];
	delete setup[receiverId];
	delete sameDomain[receiverId];
	delete receiverTx[receiverId];
	},

	/**
	 * Gets the RPC relay mechanism.
	 * @return {string} RPC relay mechanism. See above for
	 *   a list of supported types.
	 *
	 * @member gadgets.rpc
	 */
	getRelayChannel: function() {
	return transport.getCode();
	},

	/**
	 * Receives and processes an RPC request. (Not to be used directly.)
	 * Only used by IFPC.
	 * @param {Array.<string>} fragment An RPC request fragment encoded as
	 *        an array. The first 4 elements are target id, source id & call id,
	 *        total packet number, packet id. The last element stores the actual
	 *        JSON-encoded and URI escaped packet data.
	 *
	 * @member gadgets.rpc
	 * @deprecated
	 */
	receive: function(fragment, otherWindow) {
	if (fragment.length > 4) {
		process(OpenAjax.gadgets.json.parse(
			decodeURIComponent(fragment[fragment.length - 1])));
	} else {
		relayOnload.apply(null, fragment.concat(otherWindow));
	}
	},

	/**
	 * Receives and processes an RPC request sent via the same domain.
	 * (Not to be used directly). Converts the inbound rpc object's
	 * Array into a local Array to pass the process() Array test.
	 * @param {Object} rpc RPC object containing all request params
	 * @member gadgets.rpc
	 */
	receiveSameDomain: function(rpc) {
	// Pass through to local process method but converting to a local Array
	rpc.a = Array.prototype.slice.call(rpc.a);
	window.setTimeout(function() { process(rpc); }, 0);
	},

	// Helper method to get the protocol://host:port of an input URL.
	// see docs above
	getOrigin: getOrigin,

	getReceiverOrigin: function(receiverId) {
	var channel = receiverTx[receiverId];
	if (!channel) {
		// not set up yet
		return null;
	}
	if (!channel.isParentVerifiable(receiverId)) {
		// given transport cannot verify receiver origin
		return null;
	}
	var origRelay = OpenAjax.gadgets.rpc.getRelayUrl(receiverId) ||
					OpenAjax.gadgets.util.getUrlParameters().parent;
	return OpenAjax.gadgets.rpc.getOrigin(origRelay);
	},

	/**
	 * Internal-only method used to initialize gadgets.rpc.
	 * @member gadgets.rpc
	 */
	init: function() {
	// Conduct any global setup necessary for the chosen transport.
	// Do so after gadgets.rpc definition to allow transport to access
	// gadgets.rpc methods.
	if (transport.init(process, transportReady) === false) {
		transport = fallbackTransport;
	}
	if (isChild) {
		setupReceiver('..');
	}
	},

	/** Returns the window keyed by the ID. null/".." for parent, else child */
	_getTargetWin: getTargetWin,

	/** Create an iframe for loading the relay URL. Used by child only. */
	_createRelayIframe: function(token, data) {
	var relay = OpenAjax.gadgets.rpc.getRelayUrl('..');
	if (!relay) {
		return;
	}

	// Format: #targetId & sourceId & authToken & data
	var src = relay + '#..&' + rpcId + '&' + token + '&' +
		encodeURIComponent(OpenAjax.gadgets.json.stringify(data));

	var iframe = document.createElement('iframe');
	iframe.style.border = iframe.style.width = iframe.style.height = '0px';
	iframe.style.visibility = 'hidden';
	iframe.style.position = 'absolute';

	function appendFn() {
		// Append the iframe.
		document.body.appendChild(iframe);

		// Set the src of the iframe to 'about:blank' first and then set it
		// to the relay URI. This prevents the iframe from maintaining a src
		// to the 'old' relay URI if the page is returned to from another.
		// In other words, this fixes the bfcache issue that causes the iframe's
		// src property to not be updated despite us assigning it a new value here.
		iframe.src = 'javascript:"<html></html>"';
		iframe.src = src;
	}

	if (document.body) {
		appendFn();
	} else {
		OpenAjax.gadgets.util.registerOnLoadHandler(function() { appendFn(); });
	}

	return iframe;
	},

	ACK: ACK,

	RPC_ID: rpcId,

	SEC_ERROR_LOAD_TIMEOUT: LOAD_TIMEOUT,
	SEC_ERROR_FRAME_PHISH: FRAME_PHISH,
	SEC_ERROR_FORGED_MSG : FORGED_MSG
};
}();

// Initialize library/transport.
OpenAjax.gadgets.rpc.init();

} // !end of double-inclusion guard



/** Licensed Materials - Property of IBM, 5724-U69, (C) Copyright IBM Corp. 2008, 2012 - All Rights reserved.  **/

require(["dojo/_base/connect", "dojo/string", "dojo/back", "dojox/xml/parser", "dojox/uuid/generateRandomUuid"], function(dConnect, dString, dBack){

dojo.provide("com.ibm.mm.enabler.core");
dojo.i18n._preloadLocalizations("com.ibm.mm.enabler.nls.enabler", ["ROOT","ar","ca","cs","da","de","el","en","es","fi","fr","he","hr","hu","it","ja","ko","nb","nl","no","pl","pt","pt-br","ro","ru","sk","sl","sv","th","tr","uk","zh","zh-tw"]);

(function() {
    var ver = "3.0.0.20110927-1750".split(".");
    var flag = "enabler.core";

    if (flag) {
		flag = "_" + flag;
	}

    if (ver.length == 4) {
        dojo.setObject("com.ibm.mashups.enabler.version",{
            major: ver[0],
            minor: ver[1],
            patch: ver[2],
            "flag": flag,
            revision: ver[3],
            toString: function() {
            	return this.major + "." + this.minor + "." + this.patch + (this.flag || "") + " (" + this.revision + ")";    // String
            }
        });
    }
})();

if(!dojo._hasResource["com.ibm.mashups.enabler.Deferred_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.Deferred_API"] = true;
dojo.provide("com.ibm.mashups.enabler.Deferred_API");
dojo.provide("com.ibm.mashups.enabler.Deferred");

/**
 * Base interface for all classes which handle actions asynchronously.
 * An action may involve one or more operations, for example creating or
 * updating a model resource, which in turn may involve one or more HTTP
 * requests. The Deferred interface allows to trigger a callback after
 * the entire action, i.e. all involved HTTP requests, is finished. Thus,
 * the Deferred interface may be used to get the overall result of an action.
 * @ibm-api
 * @ibm-module Base2
 */
dojo.declare( "com.ibm.mashups.enabler.Deferred", null, {

    /**
     * Sets the handler of the deferred action. It is called when the entire
     * action has finished.<br>
     * Please note that the status of the action is transported only with
     * callbacks, even if you use synchronous mode. If you need to check the status,
     * you must use callback functions.
     * @param {Object} callback the callback funtion in the format of <code>Function(Object resource, int statusCode, Object[] params)</code>.
     * Must not be <code>null</code><br>
     * &nbsp;&nbsp;&nbsp;&nbsp;<b>Callbackparameters</b><br>
     * &nbsp;&nbsp;&nbsp;&nbsp;<code>resource</code> - resource object or id string
     * of the related resource.
     * May be <code>null</code> in case the action does not relate
     * to a particular resource. In case multiple resources are involved in the
     * action, the DeferredOperation interface may be used to obtain the resource
     * objects or string <code>id</code>s of those resources.<br>
     * &nbsp;&nbsp;&nbsp;&nbsp;<code>statusCode</code> - the overall HTTP status
     * code of the action (the highest status code of the involved operations).<br>
     * &nbsp;&nbsp;&nbsp;&nbsp;<code>params</code> - the parameters
     * passed into the callback
     * @param {Object[]} parameters optional array of parameters to be
     * passed on to the callback function. May be <code>null</code>
     * @return {com.ibm.mashups.enabler.Deferred} the deferred object
     */
    setFinishedCallback: function(callback, parameters) {
    },

    /**
     * Executes the deferred action and invokes the callback functions set
     * with the deferred object.
     * @param {Boolean} sync indicates if the deferred action is executed
     * synchronously or asynchronously. Optional, defaults to true.
     * @return {Object} resource if called asynchronously, the return value is
     * <code>undefined</code>, otherwise a resource object or id string of the
     * related resource is returned.<br> In order to obtain information on
     * the resource as well as on the status code of the operation, you
     * must use the callback functions of the deferred object.
     */
    start: function(sync) {
        return {};
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.DeferredImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.DeferredImpl"] = true;
dojo.provide("com.ibm.mm.enabler.DeferredImpl");






// base
dojo.declare("com.ibm.mm.enabler.DeferredImpl", [com.ibm.mashups.enabler.Deferred], {

    _chainedDeferred: null,

    _sync: false,
    _previous: null,

    // If you mixin the DeferredImpl into your class, you may use a different
    // set of parameters for the constructor, but then you do not have access
    // to the parameters 'context', 'startfn', as well as 'params' and thus,
    // you need to overwrite the start function, which accesses those parameters.
    // If you want to use the start function defined in DeferredImpl, you need
    // to make sure, the parameters 'context', 'startfn', as well as 'params'
    // are set in the constructor of DeferredImpl.
    constructor: function(context, startfn, params){
        // context for start function
        this.context = context;

        // start function
        this.startfn = startfn;

        // parameters to pass to start function
        this.params = params;
    },

    // deprecated
    addErrorCallback: function(callback, parameters){
        dojo.deprecated("com.ibm.mashups.enabler.Deferred.addErrorCallback()", "use com.ibm.mashups.enabler.Deferred.setFinishedCallback() instead");
        this.errorCallback = callback;
        this.errorCallbackParameters = parameters;
    },

    // deprecated
    addFinishedCallback: function(callback, parameters){
        dojo.deprecated("com.ibm.mashups.enabler.Deferred.addFinishedCallback()", "use com.ibm.mashups.enabler.Deferred.setFinishedCallback() instead");
        this.finishedCallback = callback;
        this.finishedCallbackParameters = parameters;

        // forward compatibility
        //this.setFinishedCallback(callback, parameters);
    },

    setFinishedCallback: function(callback, parameters){
        this.finishedCallback2 = callback;
        this.finishedCallbackParameters2 = parameters;
        return this;
    },

    start: function(sync, previous){
        this._sync = (sync || typeof(sync) == 'undefined');
        var ret = null;
        if (dojo.isFunction(this.startfn)) {
            ret = dojo.hitch(this.context || null, this.startfn)(this, this._sync, this.params, previous || null);
        }
        return ret;
    },

    getFinishedCallback: function(){
        return this.finishedCallback2;
    },

    getFinishedCallbackParameters: function(){
        return this.finishedCallbackParameters2;
    },

    setChainedDeferred: function(deferred){
        this._chainedDeferred = deferred;
    },

    getChainedDeferred: function(){
        return this._chainedDeferred;
    },

    getPrevious: function(){
        return this._previous;
    },

    _setPreviousDeferred: function(deferred, result, status){
        this._previous = {
            deferred: deferred,
            result: result,
            status: status
        };
    },

    removeChainedDeferred: function(){
        this._chainedDeferred = null;
    },

    /**
     * call this at the end of whatever you are doing
     *
     * @param {Object} result
     * @param {Object} status
     */
    finish: function(result, status){
        try {
            if (dojo.isFunction(this.getFinishedCallback())) {
                // call callback
                dojo.partial(this.getFinishedCallback())(result, status, this.getFinishedCallbackParameters());
            }
            else {
                if (dojo.isFunction(this.finishedCallback) && ("" + status).indexOf('2') === 0) {
                    // backwards compatibility
                    dojo.partial(this.finishedCallback)(result, this.finishedCallbackParameters);
                }
                else {
                    if (dojo.isFunction(this.errorCallback) && status >= 400) {
                        dojo.partial(this.errorCallback)(result, this.errorCallbackParameters);
                    }
                }
            }
        }
        catch (e) {
        }
        if (this._chainedDeferred) {
            this._chainedDeferred._setPreviousDeferred(this, result, status);
            this._chainedDeferred.start(this._sync);
        }
    }

});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.Deferred"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.Deferred"] = true;
dojo.provide( "com.ibm.mashups.enabler.Deferred");



dojo.require( "com.ibm.mm.enabler.DeferredImpl" );

}

if(!dojo._hasResource["com.ibm.mashups.enabler.context.LocalizedContext_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.context.LocalizedContext_API"] = true;
dojo.provide("com.ibm.mashups.enabler.context.LocalizedContext_API");
dojo.provide("com.ibm.mashups.enabler.context.LocalizedContext");

/**
 * LocalizedContext to get the preferred locale, the default locale, as well as
 * titles and descriptions of localized resources within this localized context.
 *
 * @ibm-api
 * @ibm-module Base2
 */
dojo.declare("com.ibm.mashups.enabler.context.LocalizedContext", null, {
	/**
	 * Returns the preferred locale of this LocalizedContext.
	 * @ibm-api
	 * @type {String}
	 * @return the preferred locale
	 */
	getPreferredLocale : function() {
	},

	/**
	 * Returns the default locale of this LocalizedContext.
	 * @ibm-api
	 * @type {String}
	 * @return the default locale
	 */
	getDefaultLocale : function() {
	},

	/**
	 * Returns the locale of the localized resource, which matches best the locale set with
	 * the browser.
	 * @ibm-api
	 * @param {com.ibm.mashups.enabler.Localized} localized resource implementing the Localized interface; must not be <code>null</code>
	 * @type {String}
	 * @return the preferred locale. Returns <code>null</code> if no locale is available.
	 */
	getLocale : function(localized) {
	},

	/**
	 * Returns the display locale set with the browser matching the specified locale.
	 * @ibm-api
	 * @param {String} locale; mandatory, must not be <code>null</code>
	 * @type {String}
	 * @return the display locale. Returns <code>null</code> if no display locale is available.
	 */
	getDisplayLocale : function(locale) {
	},

	/**
	 * Returns the title of the localized resource in the locale, which matches best the locale
	 * set with the browser.
	 * @ibm-api
	 * @param {com.ibm.mashups.enabler.Localized} localized resource implementing the Localized interface; must not be <code>null</code>
	 * @type {String}
	 * @return the title string in the preferred locale. Returns <code>null</code> if no locale is available.
	 */
	getTitle : function(localized) {
	},

	/**
	 * Returns the description of the localized resource in the locale, which matches best the
	 * locale set with the browser.
	 * @ibm-api
	 * @param {com.ibm.mashups.enabler.Localized} localized resource implementing the Localized interface; must not be <code>null</code>
	 * @type {String}
	 * @return the description string in the preferred locale. Returns <code>null</code> if no locale is available.
	 */
	getDescription : function(localized) {
	}
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.xml.XPath_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.xml.XPath_API"] = true;
dojo.provide("com.ibm.mashups.enabler.xml.XPath_API");
dojo.provide("com.ibm.mashups.enabler.xml.XPath");

/**
 * Interface provides functions to select nodes by evaluating XPATH expression
 *
 * @ibm-api
 * @ibm-module Base2
 */
dojo.declare("com.ibm.mashups.enabler.xml.XPath", null, {
	/**
	 * This interface returns a list of XMLNodes upon XPATH evaluation.
	 * @param {String} xpathExpr the xpath expression (i.e. /atom:content). Must not be NULL.
	 * @param {XMLDocument} doc the XML document. Must not be NULL.
	 * @param {JSON} namespaces the namespaces used as part of the xpath expression. The json must be of the format {"prefix": "URL", ... }; must not be NULL.<br>
	 * Example: { "atom" : "http://www.w3.org/2005/Atom", "app" : "http://www.w3.org/2007/app" };
	 *
	 * @return {XMLNodeList} select nodes from XML document with xpath; may be <code>null</code>.
	 */
	evaluateXPath : function(xpathExpr, doc, namespaces) {
	},


    /**
	 * This interface returns a single Entry upon XPATH evaluation or null if the entry is not present.
	 *
	 * @param {String} xpathExpr the xpath expression (i.e. /atom:content). Must not be NULL.
	 * @param {XMLDocument} doc the XML document. Must not be NULL.
	 * @param {JSON} namespaces the namespaces used as part of the xpath expression. The json must be of the format {"prefix": "URL", ... }; must not be NULL.<br>
	 * Example: { "atom" : "http://www.w3.org/2005/Atom", "app" : "http://www.w3.org/2007/app" };
	 *
	 * @return {Object}
     */
    evaluateEntry: function(xpathExpr, doc, namespaces) {
    },

    /**
	 * This interface returns a boolean upon XPATH evaluation. Returns false if the result is not valid (e.g. node does not exist, etc.).
	 *
	 * @param {String} xpathExpr the xpath expression (i.e. /atom:content). Must not be NULL.
	 * @param {XMLDocument} doc the XML document. Must not be NULL.
	 * @param {JSON} namespaces the namespaces used as part of the xpath expression. The json must be of the format {"prefix": "URL", ... }; must not be NULL.<br>
	 * Example: { "atom" : "http://www.w3.org/2005/Atom", "app" : "http://www.w3.org/2007/app" };
	 *
	 * @return {Boolean}
     */
    evaluateBoolean: function(xpathExpr, doc, namespaces) {
    },

    /**
	 * This interface returns a String upon XPATH evaluation. Returns an empty String if the result is not valid (e.g. node does not exist, etc.).
	 * If you want to check for existence of an attribute/element use either evaluateBoolean (which returns false if the element is not present) or evaluateEntry (which returns null if the element is not present).
	 *
	 * @param {String} xpathExpr the xpath expression (i.e. /atom:content). Must not be NULL.
	 * @param {XMLDocument} doc the XML document. Must not be NULL.
	 * @param {JSON} namespaces the namespaces used as part of the xpath expression. The json must be of the format {"prefix": "URL", ... }; must not be NULL.<br>
	 * Example: { "atom" : "http://www.w3.org/2005/Atom", "app" : "http://www.w3.org/2007/app" };
	 *
	 * @return {String}
     */
    evaluateString: function(xpathExpr, doc, namespaces) {
    },

    /**
	 * This interface returns a Number upon XPATH evaluation. Returns zero (0) if the result is not valid (e.g. node does not exist, etc.).
	 * If you want to check for existence of an attribute/element use either evaluateBoolean (which returns false if the element is not present) or evaluateEntry (which returns null if the element is not present).
	 *
	 * @param {String} xpathExpr the xpath expression (i.e. /atom:content). Must not be NULL.
	 * @param {XMLDocument} doc the XML document. Must not be NULL.
	 * @param {JSON} namespaces the namespaces used as part of the xpath expression. The json must be of the format {"prefix": "URL", ... }; must not be NULL.<br>
	 * Example: { "atom" : "http://www.w3.org/2005/Atom", "app" : "http://www.w3.org/2007/app" };
	 *
	 * @return {Number}
     */
    evaluateNumber: function(xpathExpr, doc, namespaces) {
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.utils.Dom"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.utils.Dom"] = true;
dojo.provide("com.ibm.mm.enabler.utils.Dom");




com.ibm.mm.enabler.utils.Dom = {
    getAttributeWithNS: function(element, attName, localAttName, nsUri) {
        if (!element) {
            return null;
        }
        if (!attName) {
            return null;
        }
        if (!localAttName) {
            return null;
        }
        if (!nsUri) {
            return null;
        }
        var value = null;
        if (dojo.isIE) {
            // IE with no namepsace
            value = element.getAttribute(attName);
            if (value === null || value == "") {
                // IE with namepsace
                var attributes = element.attributes;
                for (var i = attributes.length; i > 0; i--) {
                    if (attributes[i - 1].baseName == localAttName && attributes[i - 1].namespaceURI == nsUri) {
                        value = attributes[i - 1].value;
                        break;
                    }
                }
            }
        }
        else {
            // Safari & Firefox
            value = element.getAttributeNS(nsUri, localAttName);
        }
        return value;
    },
    setAttributeWithNS: function(dom, element, attName, localAttName, nsUri, value) {
        if (!dojo.isObject(element)) {
            throw new Error("element must be a DOMNode");
        }
        if (dojo.isIE) {
            var attr = dom.createNode(2, attName, nsUri);
            // set value
			if (value === null || value === undefined) {
				value = "";
			}
            attr.nodeValue = value;
            // attach to element
            element.setAttributeNode(attr);
        }
        else {
            element.setAttributeNS(nsUri, attName, value);
        }
    },
    textContent: function(node, text) {
        if (!node) {
            return "";
        }
        if (arguments.length > 1) {
            var doc = node.ownerDocument;
            var aNode = doc.createTextNode(text || ""); // IE8 createTextNode fails when text == null
            com.ibm.mm.enabler.utils.Dom.replaceChildren(node, aNode);
            return;
        }
        else {
            var tc = dojox.xml.parser.textContent(node);
            if (tc) {
                return tc;
            }

            return dojo.map(node.childNodes || [], function(node) {
            	return (node.nodeType > 0 && node.nodeType < 4) ? node.nodeValue : "";
            }).join("");
        }
    },
    createElement: function(dom, name, ns) {
        var newElem;
        if (dojo.isIE) {
            if (ns) {
                newElem = dom.createNode(1, name, ns);
            }
            else {
                newElem = dom.createElement(name);
            }
        }
        else {
            newElem = dom.createElementNS(ns, name);
        }
        return newElem;
    },
    destroyNode: function(node) {
        //avoid pseudo leaks since our webpage are open for long long time!
        var garbageBin = dojo.byId('IELeakGarbageBin');
        if (!garbageBin) {
        	garbageBin = dojo.create("div",{
        		id: "IELeakGarbageBin",
        		style: {display: "none"}
        	}, dojo.body());
        }

        // move the element to the garbage bin
        dojo.place(node,garbageBin);
        dojo.attr(garbageBin,'innerHTML','');

        if (node.nodeType != 3) { // ingore TEXT_NODE
            if (dojo.isIE) {
            	dojo.attr(node,'outerHTML',''); //prevent ugly IE mem leak
            }
        }
    },
    createDocument: function(/*string?*/str, /*string?*/ mimetype) {
        return dojox.xml.parser.parse(str, mimetype);
    },
    replaceChildren: function(/*Element*/node, /*Node || array*/ newChildren) {
        return dojox.xml.parser.replaceChildren(node, newChildren);
    },
    innerXML: function(node) {
        return node ? dojox.xml.parser.innerXML(node) : null;
    },
    removeChildren: function(node) {
        return dojox.xml.parser.removeChildren(node);
    },
    copyChildren: function(/*Element*/srcNode, /*Element*/ destNode, /*boolean?*/ trim) {
        var clonedNode = srcNode.cloneNode(true);
        return this.moveChildren(clonedNode, destNode, trim); //	number
    },
    moveChildren: function(srcNode, destNode, trim) {
        var count = 0;
        if (trim) {
            while (srcNode.hasChildNodes() &&
            srcNode.firstChild.nodeType == 3) {
                srcNode.removeChild(srcNode.firstChild);
            }
            while (srcNode.hasChildNodes() &&
            srcNode.lastChild.nodeType == 3) {
                srcNode.removeChild(srcNode.lastChild);
            }
        }
        while (srcNode.hasChildNodes()) {
            destNode.appendChild(srcNode.firstChild);
            count++;
        }
        return count; //	number
    },
    /**
     * Get's the local name of the node passed in as parameter
     *
     * @param {Node} node the node of which to get the local name
     * @return {String} the local name of the node or <tt>null</tt> if the node doesn't have a local name
     */
    getLocalName: function(node) {
        if (!node) {
            return null;
        }
        switch (node.nodeType) {
            case 3:
                return "#text";
            case 1:
                return node.localName || com.ibm.mm.enabler.utils.Dom.removeNodeNS(node.nodeName);
        }

        return null;
    },
    /**
     * Get's the namespace prefix from the given nodename or <tt>null</tt> if there is no NS Prefix.
     *
     * @param {String} nodeName The name of the node
     * @return {String} the namespace prefix of the node name or <tt>null</tt> if there is none.
     */
    getNodeNSPrefix: function(nodeName) {
        var tN = '' + nodeName;
        var hasColon = tN.indexOf(':');
        return (hasColon != -1) ? tN.substring(0, hasColon) : null;
    },
    /**
     * Removes the namespace from a node name.
     * This is a copy of com.ibm.mashups.widget.dijit.url.util.Dom.removeNodeNs and should
     * replace this method in case, this one here becomes public.
     *
     * @private
     * @param {String} nodeName the node name with or without namespace
     * @return {String} the node name without namespace
     * @see com.ibm.mashups.widget.dijit.url.util.Dom#removeNodeNs(String)
     */
    removeNodeNS: function(nodeName) {
        var tN = '' + nodeName;
        var hasColon = tN.indexOf(':');
        return (hasColon != -1) ? tN.substring(1 + hasColon) : nodeName;
    },
    /**
     * Looks up the namespace for the specified prefix
     * @param {Node} node the node for which to lookup the namespace
     * @param {String} prefix the prefix to lookup the namespace for.
     * @return {String} the namespace for the specified prefix or <tt>null</tt> if the namespace for the prefix wasn't found.
     */
    lookupNamespaceURI: function(node, prefix) {
        // If we are not on IE, we have native support for this
        if (!dojo.isIE) {
            return node.lookupNamespaceURI(prefix);
        }

        // seems we are on IE, so let's do some magic here
        var lastNode = node;

        // while node != null and node isn't a document
        while (lastNode && lastNode.nodeType != 9) {
            var attrValue = lastNode.getAttribute("xmlns:" + prefix);

            if (attrValue) {
                return attrValue;
            }

            lastNode = lastNode.parentNode;
        }

        return null;
    }
};

}

if(!dojo._hasResource["com.ibm.mm.enabler.xml.xpath._Generic"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.xml.xpath._Generic"] = true;
dojo.provide("com.ibm.mm.enabler.xml.xpath._Generic");




// generic impl
dojo.declare("com.ibm.mm.enabler.xml.xpath._Generic", null, {
    constructor: function(){
    },

    _evaluateXPath: function(/*String*/xpathExpr, /*DOMDocument*/ doc, /*Object{prefix:ns,prefix2:ns2,...}*/ namespaces){
        if (dojo.isSafari) {
            return this._safariEvaluateXPath(xpathExpr, doc, namespaces);
        } else if (dojo.isIE) {
            return this._ieEvaluateXPath(xpathExpr, doc, namespaces);
        } else {
            return this._geckoEvaluateXPath(xpathExpr, doc, namespaces);
        }
    },

    _transformNode: function(result, resType){
        if (typeof XPathResult != "undefined" && result instanceof XPathResult) {
            return this._xpathResultValue(result, resType);
        } else {
            if (resType == com.ibm.mm.enabler.xml.xpath._Generic.ANY_TYPE) {
                return result;
            } else if (resType == com.ibm.mm.enabler.xml.xpath._Generic.NUMBER_TYPE) {
                return parseFloat(com.ibm.mm.enabler.utils.Dom.textContent(result));
            } else if (resType == com.ibm.mm.enabler.xml.xpath._Generic.STRING_TYPE) {
                return com.ibm.mm.enabler.utils.Dom.textContent(result);
            } else if (resType == com.ibm.mm.enabler.xml.xpath._Generic.BOOLEAN_TYPE) {
                return !!result;
            }
        }
        return null;
    },

    _xpathResultValue: function(node, resType){
        if (resType == com.ibm.mm.enabler.xml.xpath._Generic.ANY_TYPE) {
            return node;
        } else if (resType == com.ibm.mm.enabler.xml.xpath._Generic.NUMBER_TYPE) {
            return node.numberValue;
        } else if (resType == com.ibm.mm.enabler.xml.xpath._Generic.STRING_TYPE) {
            return node.stringValue;
        } else if (resType == com.ibm.mm.enabler.xml.xpath._Generic.BOOLEAN_TYPE) {
            return node.booleanValue;
        }
        return null;
    },

    _evaluateXPathSingle: function(xpathExpr, doc, namespaces, resType){
        resType = resType || com.ibm.mm.enabler.xml.xpath._Generic.ANY_TYPE;

        var result;
        if (dojo.isSafari) {
            result = this._safariEvaluateXPathRaw(xpathExpr, doc, namespaces, resType);
            if (XPathResult && result instanceof XPathResult) {
                if (resType == com.ibm.mm.enabler.xml.xpath._Generic.ANY_TYPE) {
                    return result.iterateNext();
                }
                return this._transformNode(result, resType);
            } else if (result) {
                return this._transformNode(result[0], resType);
            }
        } else if (dojo.isIE) {
            result = this._ieEvaluateXPathRawSingle(xpathExpr, doc, namespaces);
            if (result || result === null) {
                return this._transformNode(result, resType);
            }
        } else {
            result = this._geckoEvaluateXPathRaw(xpathExpr, doc, namespaces, resType);
            if (result && resType == com.ibm.mm.enabler.xml.xpath._Generic.ANY_TYPE) {
                return result.iterateNext();
            } else {
                return this._transformNode(result, resType);
            }
        }
        return result || null;
    },

    _geckoEvaluateXPath: function(/*String*/xpathExpr, /*DOMDocument*/ doc, /*Object{prefix:ns,prefix2:ns2,...}*/ namespaces){
        var result = this._geckoEvaluateXPathRaw(xpathExpr, doc, namespaces, com.ibm.mm.enabler.xml.xpath._Generic.ANY_TYPE);

        var resultSet = [];
        if (result) {
            var thisResult;
            while ((thisResult = result.iterateNext())) {
                resultSet.push(thisResult);
            }
        }
        return resultSet;
    },

    _geckoEvaluateXPathRaw: function(xpathExpr, doc, namespaces, type){
        var xmlDocument = doc;
        if (doc.nodeType != 9) {
            xmlDocument = doc.ownerDocument;
        }
        return xmlDocument.evaluate(xpathExpr, doc, function(prefix){
            return namespaces[prefix] ? namespaces[prefix].toString() : null;
        }, type, null);
    },

    _ieEvaluateXPath: function(/*String*/xpathExpr, /*DOMDocument*/ doc, /*Object{prefix:ns,prefix2:ns2,...}*/ namespaces){
        
		var result = this._ieEvaluateXPathRaw(xpathExpr, doc, namespaces);
        return result || [];
    },
	
	


    _setIeNamespaces: function(doc, namespaces) {
        if (namespaces) {
            var ns = [];
            var item;
            for (var prop in namespaces) { // JSLINT-IGNORE: Filtering for prototype properties must not be done here, as namespaces often use dojo.delegate to save memory - dojo.delegate uses the prototype functionality for doing so - we use dojo.isFunction() which should suffice.
                // ATTENTION: DON'T ADD .hasOwnProperty() CHECK HERE!
                item = namespaces[prop];
                if (prop != "xml") { // we cannot use !dojo.isFunction(item) as it costs too much performance
                    // There is no automatic namespace recognition, this is a workaround
                    ns.push("xmlns:", prop, "='", item, "' ");
                }
            }
			if(dojo.isIE !=11){
				var sDoc = doc.ownerDocument || doc;
				sDoc.setProperty("SelectionNamespaces", ns.join(""));
				sDoc.setProperty("SelectionLanguage", "XPath");
			}
        }
    },

    _ieEvaluateXPathRaw: function(xpathExpr, doc, namespaces){
    	this._setIeNamespaces(doc, namespaces);
        return doc.selectNodes(xpathExpr);
    },

    _ieEvaluateXPathRawSingle: function(xpathExpr, doc, namespaces){
    	this._setIeNamespaces(doc, namespaces);
    	return doc.selectSingleNode(xpathExpr);
    },
	
	


    _safariEvaluateXPath: function(/*String*/xpathExpr, /*DOMDocument*/ doc, /*Object{prefix:ns,prefix2:ns2,...}*/ namespaces){
        var result = this._safariEvaluateXPathRaw(xpathExpr, doc, namespaces, com.ibm.mm.enabler.xml.xpath._Generic.ANY_TYPE);
        if (XPathResult && result instanceof XPathResult) {
            var resultSet = [];
            var thisResult;
            while ((thisResult = result.iterateNext())) {
                resultSet.push(thisResult);
            }
            return resultSet;
        }
        return result || [];
    },

    _safariEvaluateXPathRaw: function(xpathExpr, doc, namespaces, type){
        if (typeof XPathResult != "undefined") {
            //use build in xpath support for Safari 3.0
            return document.evaluate(xpathExpr, doc, function(prefix){
                return namespaces[prefix] ? namespaces[prefix].toString() : null;
            }, type, null);
        } else if (doc.selectNodes) {
            //use javeline Safari2 xpath support
            return doc.selectNodes(xpathExpr);
        }
    }

});

com.ibm.mm.enabler.xml.xpath._Generic.ANY_TYPE = 0;
com.ibm.mm.enabler.xml.xpath._Generic.NUMBER_TYPE = 1;
com.ibm.mm.enabler.xml.xpath._Generic.STRING_TYPE = 2;
com.ibm.mm.enabler.xml.xpath._Generic.BOOLEAN_TYPE = 3;

}

if(!dojo._hasResource["com.ibm.mm.enabler.xml.XPathImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.xml.XPathImpl"] = true;
dojo.provide("com.ibm.mm.enabler.xml.XPathImpl");









dojo.declare("com.ibm.mm.enabler.xml.XPathImpl", [com.ibm.mashups.enabler.xml.XPath, com.ibm.mm.enabler.xml.xpath._Generic], {

    modelMessages: null,

    constructor: function() {
        this.modelMessages = dojo.i18n.getLocalization("com.ibm.mm.enabler", "modelMessages");
    },

    ANY_TYPE: com.ibm.mm.enabler.xml.xpath._Generic.ANY_TYPE,
    NUMBER_TYPE: com.ibm.mm.enabler.xml.xpath._Generic.NUMBER_TYPE,
    STRING_TYPE: com.ibm.mm.enabler.xml.xpath._Generic.STRING_TYPE,
    BOOLEAN_TYPE: com.ibm.mm.enabler.xml.xpath._Generic.BOOLEAN_TYPE,

    evaluateXPath: function(xpathExpr, doc, namespaces) {
        if(!dojo.isString(xpathExpr) || xpathExpr.length === 0) {
            throw new Error(this.modelMessages.E_INVALID_XPATH_EXPR_0);
        }

        if(!doc) {
            throw new Error(this.modelMessages.E_INVALID_DOCUMENT_0);
        }

        var ret = this._evaluateXPath(xpathExpr, doc, namespaces);
        return ret;
    },

    evaluateSingle: function(xpathExpr, doc, namespaces, type) {

        if(!dojo.isString(xpathExpr) || xpathExpr.length === 0) {
            throw new Error(this.modelMessages.E_INVALID_XPATH_EXPR_0);
        }

        if(!doc) {
            throw new Error(this.modelMessages.E_INVALID_DOCUMENT_0);
        }


        return this._evaluateXPathSingle(xpathExpr, doc, namespaces, type);
    },

    evaluateEntry: function(xpathExpr, doc, namespaces) {
        return this.evaluateSingle(xpathExpr, doc, namespaces, com.ibm.mashups.enabler.xml.XPath.ANY_TYPE);
    },

    evaluateBoolean: function(xpathExpr, doc, namespaces) {
        return this.evaluateSingle(xpathExpr, doc, namespaces, com.ibm.mashups.enabler.xml.XPath.BOOLEAN_TYPE);
    },

    evaluateString: function(xpathExpr, doc, namespaces) {
        return this.evaluateSingle(xpathExpr, doc, namespaces, com.ibm.mashups.enabler.xml.XPath.STRING_TYPE);
    },

    evaluateNumber: function(xpathExpr, doc, namespaces) {
        return this.evaluateSingle(xpathExpr, doc, namespaces, com.ibm.mashups.enabler.xml.XPath.NUMBER_TYPE);
    },

    /**
     * evaluates the specified xpath, but creates xml elements, which are not part
     * of the document; please note that attributes are not supported
     *
     * @param {Object} xPath
     * @param {Object} node
     * @param {Object} namespaces
     */
    createXPath: function(xPath, node, namespaces) {

        // split off first part of xpath
        var xPathParts = xPath.split("/");

        // handle head
        var qName = xPathParts[0];

        // extract name and name space
        var qNameParts = qName.split(":");
        var name, namespace;
        if (qNameParts.length > 1) {
            namespace = qNameParts[0];
            name = qNameParts[1];
        }
        else {
            name = qNameParts[0];
        }

        // search for first part of xpath (what about case insensitive search for attributes, especially "_" vs "-" in locales?)
        var names = com.ibm.mashups.enabler.xml.XPath.evaluateXPath((namespace ? namespace + ":" : "") + name, node, namespaces);
        var result;
        if (names && names.length > 0) {
            // use existing xml element
            result = names[0];
        }
        else {
            // what about attributes?
            // create xml element
            result = com.ibm.mm.enabler.utils.Dom.createElement(node.ownerDocument, (namespace ? namespace + ":" : "") + name, namespace ? namespaces[namespace] : null);
            node.appendChild(result);
        }

        // handle remaining parts of xpath
        if (xPathParts.length > 1) {
            // recursive call with remaining xpath part
            result = com.ibm.mashups.enabler.xml.XPath.createXPath(xPath.substr(xPath.indexOf("/") + 1), result, namespaces);
        }
        return result;
    }
});

// create the singleton
com.ibm.mashups.enabler.xml.XPath = new com.ibm.mm.enabler.xml.XPathImpl();

// backwards compatibility - still needed?
// TODO remove this in next enabler version
com.ibm.mm.enabler.xml.xpath.evaluateXPath = function(xpathExpr, doc, namespaces) {
    dojo.deprecated("com.ibm.mm.enabler.xml.xpath.evaluateXPath", "The method com.ibm.mm.enabler.xml.xpath.evaluateXPath is deprecated, please use com.ibm.mashups.enabler.xml.XPath.evaluateXPath instead");
    return com.ibm.mm.enabler.xml.xpath._Generic.evaluateXPath.apply(null, arguments);
};

}

if(!dojo._hasResource["com.ibm.mashups.enabler.xml.XPath"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.xml.XPath"] = true;
dojo.provide("com.ibm.mashups.enabler.xml.XPath");





}

if(!dojo._hasResource["com.ibm.mm.enabler.utils.LocaleHelper"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.utils.LocaleHelper"] = true;
dojo.provide("com.ibm.mm.enabler.utils.LocaleHelper");




com.ibm.mm.enabler.utils.LocaleHelper = {
    getLocale:function(/*com.ibm.mashups.enabler.Localized*/localized,aLocale,defaultLocale){
        if (typeof localized == "undefined" || localized === null) {
            return null;
        }

        var localeArr = localized.getLocales();
        if (typeof localeArr == "undefined" || localeArr === null || !dojo.isArray(localeArr)) {
            return null;
        }

        if (localeArr.length === 0) {
            return null;
        }

        var returnLocale = null;
        if (localeArr.length === 1) {
            returnLocale = localeArr[0];
        }

        var arr = {};
        for (var i in localeArr) {
            if (Object.prototype.hasOwnProperty.call(localeArr,i)) {
                var temp = localeArr[i];
                arr[temp] = temp;
            }
        }

        var tempArr;
        if (returnLocale === null) {
            if (typeof aLocale != "undefined" && aLocale !== null) {
                returnLocale = this.findMatchLocale(arr, aLocale);
                if (returnLocale === null) {
                    tempArr = aLocale.split(/-|_/);
                    if (tempArr.length == 2) {
                        var iLocale = tempArr[0];
                        if (typeof arr[iLocale] != "undefined" && arr[iLocale] !== null) {
                            returnLocale = iLocale;
                        }
                    }
                }
            }
        }
        if (returnLocale === null) {
            //get browser locale
            var browserLocale = (dojo.isIE ? navigator.userLanguage : navigator.language).toLowerCase();
            if (typeof ibmConfig != "undefined" && ibmConfig && typeof(ibmConfig.locale) != "undefined" && ibmConfig.locale) {
                browserLocale = ibmConfig.locale;
            }
            if (browserLocale !== null) {
                //browserLocale = browserLocale.replace(/-/,"_");
                returnLocale = this.findMatchLocale(arr, browserLocale);
                if (returnLocale === null) {
                    tempArr = browserLocale.split(/-|_/);
                    if (tempArr.length == 2) {
                        var tempLocale = tempArr[0];
                        if (typeof arr[tempLocale] != "undefined" && arr[tempLocale] !== null) {
                            returnLocale = tempLocale;
                        }
                    }
                }
            }
        }

        if (returnLocale === null) {
            if (defaultLocale) {
                returnLocale = defaultLocale;
            }
        }
        if (returnLocale === null) {
            if (arr.en) {
                returnLocale = "en";
            }
        }
        if (returnLocale === null) {
            returnLocale = localeArr[0];
        }
        return returnLocale;
    },
    findMatchLocale:function(arr,locale){
        var returnLocale = null;
        if (arr[locale]) {
            returnLocale = locale;
        }
        var serverLocale = this.toServerLocale(locale);
        if (returnLocale === null && arr[serverLocale]) {
            returnLocale = serverLocale;
        }
        var serverLocaleLowercase = serverLocale.toLowerCase();
        if (returnLocale === null && arr[serverLocaleLowercase]) {
            returnLocale = serverLocaleLowercase;
        }
        return returnLocale;
    },

    /**
     * match a locale against an array of locales
     *
     * TODO: also allow preferred to be an array
     *
     * @param {String} preferred
     * @param {Array} available
     */
    matchLocale: function(preferred, available) {
        return com.ibm.mm.enabler.utils.LocaleHelper._matchLocale(
            com.ibm.mm.enabler.utils.LocaleHelper._getLocaleObj(preferred),
            com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(available));
    },

    /**
     * match a normalized locale against an array of normalized locales
     *
     * FIXME: we need to add handling of multiple possible locales matching against multiple available ones,
     * keeping in mind the order the user defined and also handling for exceptions
     * (e.g. pt-br must not fall back to pt, sh traditional must fall back to simplified, etc.)
     *
     * @param {Object} locale an locale object
     * @param {Array} locales an Array of normalized locale strings
     */
    _matchLocale: function(locale, locales, stop) {

        // console.debug("match locale:",locale,"against",locales);

        var _origLocale = locale;

        var match = null;
        var found = dojo.some(locales, function(item) {
            if (item == com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(locale.toString())) {
                match = item;
                return true;
            }
        });
        if (found && match) {
            return match;
        }

        if (locale.variant) {
            // try without variant
            locale.variant = null;
            return com.ibm.mm.enabler.utils.LocaleHelper._matchLocale(locale, locales);
        }

        if (locale.country) {
            // try without country
            locale.country = null;
            return com.ibm.mm.enabler.utils.LocaleHelper._matchLocale(locale, locales);
        }
        if (!stop) {
            // TODO: make list of aliases [he,iw], to automate this for other fallbacks.

            locale = _origLocale;
            switch (locale.language) {
                case 'he':
                    // special handling for hebrew (he and iw (old) are equal)
                    locale.language = "iw";
                    break;
                case 'iw':
                    // special handling for hebrew (he and iw (old) are equal)
                    locale.language = "he";
                    break;
            }
            return com.ibm.mm.enabler.utils.LocaleHelper._matchLocale(locale, locales, true);
        }

        return null;
    },

    /**
     * (DE_dE_VariAnt -> de_DE)
     * removes the variant part to sustain backwards compatibility - please use com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale
     * whitespaces are trimmed at the beginning and end
     *
     * @deprecated
     *
     * @param {Object} locale
     */
    toServerLocale:function(locale) {
        if (!locale) {
            return null;
        }
        if (locale.indexOf("-") < 0) {
            return locale;
        }
        locale = locale.replace(/-/, "_");
        var tempArr = locale.split('_');
        var lang = tempArr[0];
        var country = tempArr[1].toUpperCase();
        var returnLocale = lang + "_" + country;
        return returnLocale;
    },

    /**
     * returns a locale object with normalized parts
     *
     * (DE_dE_VariAnt -> {language: 'de', country: 'DE', variant: 'VariAnt'})
     * whitespaces are trimmed at the beginning and end
     *
     * @param {String|Array} locale
     *
     */
    _getLocaleObj: function(locale) {

        if (dojo.isArray(locale)) {
            return dojo.map(locale, function(item) {
                return com.ibm.mm.enabler.utils.LocaleHelper._getLocaleObj(item);
            });
        }
        else if (dojo.isString(locale) && dojo.string.trim(locale).length > 0) {
            var localeObj = {
                language: null,
                country: null,
                variant: null,
                toString: function() {
                    return (this.language ? this.language + (this.country ? "_" + this.country + (this.variant ? "_" + this.variant : "") : "") : "");
                },
                isValid: function() {
                    return !!this.language;
                }
            };
            var parts = dojo.string.trim(locale).replace(/-/g, "_").split('_');
            switch (parts.length) {
                case 3:
                    // we have got a variant
                    localeObj.variant = parts[2]; // JSLINT-IGNORE: NO BREAK HERE
                // ATTN: no break here
                case 2:
                    // we have got a country
                    localeObj.country = parts[1].toUpperCase(); // JSLINT-IGNORE: NO BREAK HERE
                // ATTN: no break here
                case 1:
                    // and we have got a language
                    localeObj.language = parts[0].toLowerCase();
                    break;
            }
            return localeObj;
        }
        else {
            return null;
        }
    },

    /**
     * normalizes a locale or an array of locales
     *
     * (DE_dE_VariAnt -> de-DE_VariAnt)
     * whitespaces are trimmed at the beginning and end
     * @param {String|Array} locale
     */
    normalizeLocale: function(locale) {

        if (dojo.isArray(locale)) {
            return dojo.map(locale, function(item) {
                return com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(item);
            });
        }
        else if (locale && dojo.isString(locale)) {
            return locale.replace(/_/g, "-").toLowerCase();
        }
        else {
            return null;
        }
    }
};

}

if(!dojo._hasResource["com.ibm.mm.enabler.model.NameSpaceFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.NameSpaceFactory"] = true;
dojo.provide("com.ibm.mm.enabler.model.NameSpaceFactory");

dojo.declare( "com.ibm.mm.enabler.model.NameSpaceFactoryImpl", null,
    {
        constructor:function () {

            // name space prefixes
            this.NS_APP 	    		= "app";
            this.NS_ATOM 	    		= "atom";
            this.NS_THR 	    		= "thr";
            this.NS_UM 		   	 		= "um";
            this.NS_XHTML      			= "xhtml";
            this.NS_XML 	    		= "xml";
            this.NS_XSI 	    		= "xsi";
            this.NS_OPENSEARCH  		= "opensearch";
            this.NS_CM          		= "cm";
            this.NS_CA          		= "ca";
            this.NS_AC                  = "ac";
            this.NS_EVENT_DATATYPES     = "event-datatypes";
            this.NS_XMLNS               = "xmlns";
			this.NS_XSD                 = "xsd";
			this.NS_JS                  = "js";

            // name space URIs
            this.namespaces = {};
            this.namespaces[this.NS_APP]        		= "http://www.w3.org/2007/app";
            this.namespaces[this.NS_ATOM]       		= "http://www.w3.org/2005/Atom";
            this.namespaces[this.NS_THR]        		= "http://purl.org/syndication/thread/1.0";
            this.namespaces[this.NS_UM]         		= "http://www.ibm.com/xmlns/prod/websphere/um.xsd";
            this.namespaces[this.NS_XHTML]      		= "http://www.w3.org/1999/xhtml";
            this.namespaces[this.NS_XML]        		= "http://www.w3.org/XML/1998/namespace";
            this.namespaces[this.NS_XSI]        		= "http://www.w3.org/2001/XMLSchema-instance";
            this.namespaces[this.NS_XMLNS]              = "http://www.w3.org/2000/xmlns/";
            this.namespaces[this.NS_OPENSEARCH] 		= "http://a9.com/-/spec/opensearch/1.1/";
            this.namespaces[this.NS_CM]         		= "http://www.ibm.com/xmlns/prod/composite-applications/v1.0";
            this.namespaces[this.NS_CA]         		= "http://www.ibm.com/xmlns/prod/composite-applications/v1.0";
            this.namespaces[this.NS_AC]                 = "http://www.ibm.com/xmlns/prod/lotus/access-control/v1.0";
            this.namespaces[this.NS_EVENT_DATATYPES]    = "http://www.ibm.com/xmlns/prod/lotus/mashups/event-datatypes";
			this.namespaces[this.NS_XSD]                = "http://www.w3.org/2001/XMLSchema";
			this.namespaces[this.NS_JS]                 = "text/javascript";
        },

        /**
		 * Returns an object with a property for each element in the
		 * passed in array and the corresponding name space uri as value
		 * @param {Array} prefixes
		 */
        getNameSpaces: function(prefixes) {
            var result = {};
            var len = prefixes.length;
            for (var i=0; i<len; i++) {
                var name = prefixes[i];
            	result[name] = this.namespaces[name];
            }
            return result;
        },

        /**
         * Returns the name space uri that corresponds to the passed in prefix
         */
        getNameSpaceUri: function(prefix) {
            return this.namespaces[prefix];
        }
    }
);

//internal
com.ibm.mm.enabler.model.NameSpaceFactory = new com.ibm.mm.enabler.model.NameSpaceFactoryImpl();

}

if(!dojo._hasResource["com.ibm.mm.enabler.context.LocalizedContextImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.context.LocalizedContextImpl"] = true;
dojo.provide("com.ibm.mm.enabler.context.LocalizedContextImpl");









dojo.declare("com.ibm.mm.enabler.context.LocalizedContextImpl", [com.ibm.mashups.enabler.context.LocalizedContext], {
    constructor: function(preferredLocale, defaultLocale){
        var nsf = com.ibm.mm.enabler.model.NameSpaceFactory;
        this.ns = nsf.getNameSpaces([nsf.NS_ATOM, nsf.NS_XML]);

        // if no locales are specified for this context, use the
        // basic fallback mechanism (atom:title, atom:summary)
        this.basicFallback = !(preferredLocale || defaultLocale);

        // preferred locale
        this.preferredLocale = preferredLocale || null;
        if (this.preferredLocale === null) {
            // get browser locale, respectively locale set with ibmConfig
            if (typeof ibmConfig != "undefined" && ibmConfig !== null && typeof(ibmConfig.locale) != "undefined" && ibmConfig.locale !== null) {
                this.preferredLocale = ibmConfig.locale;
            }
            else {
                this.preferredLocale = (dojo.isIE ? navigator.userLanguage : navigator.language).toLowerCase();
            }
        }
        // default locale
        this.defaultLocale = defaultLocale || "en";

        // title element
        this._DEFAULT_TITLE = "atom:title";

        // summary element
        this._DEFAULT_DESCRIPTION = "atom:summary";

        // title element language
        this._DEFAULT_LOCALE = this._DEFAULT_TITLE + "/@xml:lang";
    },

    getPreferredLocale: function(){
        return this.preferredLocale;
    },

    getDefaultLocale: function(){
        return this.defaultLocale;
    },

    getLocale: function(localized){
        // if no localized resource is specified, return null
        if (typeof localized == "undefined" || localized === null) {
            return null;
        }

        // check for default locale
        if (this.basicFallback && dojo.isFunction(localized.getDefaultLocale)) {
            // TODO only if localized object is not dirty
            return localized.getDefaultLocale();
        }

        // resource locales
        var localesArray = localized.getLocales();

        switch (localesArray.length) {
            case 0:
                // there is no localization
                return null;
            case 1:
                // there is only one localization, so use that
                return com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(localesArray[0]);
            default:
                var preferredMatch = com.ibm.mm.enabler.utils.LocaleHelper.matchLocale(this.preferredLocale, localesArray);
                if (preferredMatch) {
                    // preferred was matched
                    return preferredMatch;
                }
                var defaultMatch = com.ibm.mm.enabler.utils.LocaleHelper.matchLocale(this.defaultLocale, localesArray);
                if (defaultMatch) {
                    // default was matched
                    return defaultMatch;
                }

                // nothing was matched, return first (as defaultLocale is not available)
                return com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(localesArray[0]);
        }
    },

    getTitle: function(localized){
        // if no localized resource is specified, return null
        if (typeof localized == "undefined" || localized === null) {
            return null;
        }

        var title;
        if (this.basicFallback && dojo.isFunction(localized.getDefaultTitle)) {
            // TODO only if localized object is not dirty
            title = localized.getDefaultTitle();
        }
        if (!title) {
            var locale = this.getLocale(localized);
            if (locale) {
                title = localized.getTitle(locale);
            }
        }
        if (typeof title == "undefined") {
            title = null;
        }
        return title;
    },

    getDescription: function(localized){
        // if no localized resource is specified, return null
        if (typeof localized == "undefined" || localized === null) {
            return null;
        }
        var description;
        // basic fallback
        if (this.basicFallback && dojo.isFunction(localized.getDefaultDescription)) {
            // TODO only if localized object is not dirty
            description = localized.getDefaultDescription();
        }
        if (!description) {
            var locale = this.getLocale(localized);
            if (locale) {
                description = localized.getDescription(locale);
            }
        }
        if (typeof description == "undefined") {
            description = null;
        }
        return description;
    },

    getDisplayLocale: function(locales){
        var localesArray = dojo.isArray(locales) ? locales : [locales];
        if (ibmConfig && ibmConfig.displayLocale) {
            var displayLocalesArray = ibmConfig.displayLocale.split(",");
            com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(displayLocalesArray);
            for (var i = 0; i < displayLocalesArray.length; i++) {
                var displayLocale = displayLocalesArray[i];
                if (displayLocale) {
                    var match = com.ibm.mm.enabler.utils.LocaleHelper.matchLocale(displayLocale, localesArray);
                    if (match) {
                        return displayLocale;
                    }
                }
            }
        }
        return localesArray[0];
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.context.LocalizedContext"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.context.LocalizedContext"] = true;
dojo.provide("com.ibm.mashups.enabler.context.LocalizedContext");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.context.PageContext_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.context.PageContext_API"] = true;
dojo.provide("com.ibm.mashups.enabler.context.PageContext_API");
dojo.provide("com.ibm.mashups.enabler.context.PageContext");

/**
 * Page context to set the page title.
 *
 * @since 2.4
 *
 * @ibm-spi
 * @ibm-module Base2
 */
dojo.declare("com.ibm.mashups.enabler.context.PageContext", null, {
    /**
     * Sets the browser title. Note that the browser title is
     * not persisted.
     *
     * @param {String} title the browser title
     * @return {void}
     */
    setBrowserTitle: function(title){
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.context.PageContextImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.context.PageContextImpl"] = true;
dojo.provide("com.ibm.mm.enabler.context.PageContextImpl");




dojo.declare("com.ibm.mm.enabler.context.PageContextImpl", [com.ibm.mashups.enabler.context.PageContext], {
    constructor: function(){
    },

    setBrowserTitle: function(title){
        // decode &, < and >
        dojo.doc.title = title.replace(/&amp;/g,"&").replace(/&quot;/g,"\"").replace(/&gt;/g,">").replace(/&lt;/g,"<");
    }
});



com.ibm.mm.enabler.context.PageContext = new com.ibm.mm.enabler.context.PageContextImpl();

}

if(!dojo._hasResource["com.ibm.mashups.enabler.context.PageContext"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.context.PageContext"] = true;
dojo.provide("com.ibm.mashups.enabler.context.PageContext");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.context.Factory_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.context.Factory_API"] = true;
dojo.provide("com.ibm.mashups.enabler.context.Factory_API");
dojo.provide("com.ibm.mashups.enabler.context.Factory");




/**
 * Factory to get context objects.
 *
 * @ibm-module Base2
 */
dojo.declare("com.ibm.mashups.enabler.context.Factory", null, {
    /**
     * Returns a LocalizedContext.
     *
     * @ibm-api
     *
     * @return {com.ibm.mashups.enabler.context.LocalizedContext} localized context.
     */
    getLocalizedContext: function(){
    },

    /**
    * Returns a LocalizedContext for the specified locales.
    *
    * @ibm-spi
    *
    * @param {String} preferredLocale preferred locale to use; optional, defaults to the preferred
    * locale set with the browser.
    * @param {String} defaultLocale default locale to use; optional, defaults to the locale "en"
    * @return {com.ibm.mashups.enabler.context.LocalizedContext} localized context for the specified locales.
    */
   getLocalizedContext: function(preferredLocale, defaultLocale){	// JSLINT-IGNORE: separation between public API and SPI
   },

    /**
     * Returns a PageContext.
     *
     * @ibm-spi
     * @since 2.4
     *
     * @return {com.ibm.mashups.enabler.context.PageContext} the page context
     */
    getPageContext: function(){
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.context.FactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.context.FactoryImpl"] = true;
dojo.provide("com.ibm.mm.enabler.context.FactoryImpl");





// factory implementation
dojo.declare( "com.ibm.mm.enabler.context.FactoryImpl", [com.ibm.mashups.enabler.context.Factory],
    {
        constructor:function () {
        },

        getLocalizedContext: function(preferredLocale, defaultLocale) {
            return new com.ibm.mm.enabler.context.LocalizedContextImpl(preferredLocale, defaultLocale);
        },

        getPageContext: function() {
            return new com.ibm.mm.enabler.context.PageContextImpl();
        }
    }
);

// factory singleton
com.ibm.mashups.enabler.context.Factory = new com.ibm.mm.enabler.context.FactoryImpl();

}

if(!dojo._hasResource["com.ibm.mashups.enabler.context.Factory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.context.Factory"] = true;
dojo.provide("com.ibm.mashups.enabler.context.Factory");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.services.ConfigConstants"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.services.ConfigConstants"] = true;
dojo.provide("com.ibm.mashups.enabler.services.ConfigConstants");

/**
 * This constants class contains well defined constants available to the config service.
 * They are defined in the ConfigService.properties
 * @ibm-spi
 * @ibm-module Base2
 */
dojo.declare("com.ibm.mashups.enabler.services.ConfigConstants", null, {
    /**
     * URL pointing to the proxy
     * @type String
     */
    PROXY_URL: "com.ibm.mashups.proxy.url",

    /**
     * URL pointing to the hub
     * @type String
     */
    HUB_URL: "com.ibm.mashups.hub.url",

    /**
     * URL pointing to login
     * @type String
     */
    LOGIN_URL: "com.ibm.mashups.url.login",

    /**
     * URL pointing to logout
     * @type String
     */
    LOGOUT_URL: "com.ibm.mashups.url.logout",

    /**
     * context root of the server
     * @type String
     */
    CONTEXT_ROOT: "com.ibm.mashups.contextroot",

    /**
     * context root of the enabler component
     * @type String
     */
    CONTEXT_ROOT_ENABLER: "com.ibm.mashups.contextroot.enabler",

    /**
     * context root of the builder component
     * @type String
     */
    CONTEXT_ROOT_BUILDER: "com.ibm.mashups.contextroot.builder",

    /**
     * public name of the content handler servlet
     * @type String
     */
    CONTENTHANDLER_PUBLIC: "com.ibm.mashups.contenthandler.public",
    /**
     * private name of the content handler servlet
     * @type String
     */
    CONTENTHANDLER_PRIVATE: "com.ibm.mashups.contenthandler.private",

    /**
     * public name of the embedding handler servlet
     * @type String
     */
    EMBEDDING_PUBLIC: "com.ibm.mashups.embedding.public",
    /**
     * private name of the content handler servlet
     * @type String
     */
    EMBEDDING_PRIVATE: "com.ibm.mashups.embedding.private",

    /**
     * TBD
     * @type String
     */
    THEMES_FEEDS_EXPIRATION: "themes.feed.expiration",

    /**
     * comma separated list of all available locales in the system
     * @type String
     */
    AVAILABLE_LOCALES: "availableLocales",
    /**
     * the default locale of the mashups system
     * @type String
     */
    DEFAULT_LOCALE: "default.locale",
		 /**
     * the default locale that's based on user preference for UI components to display date,currency etc.
     * @type String
     */
    DISPLAY_LOCALE: "displayLocale",
    /**
     * defines whether PUT/DELETE tunneling over POST should be used
     * @type String
     */
    TUNNEL_MODE: "tunnel.mode",

    /**
     * turns on debugging
     * @type String
     */
    CLIENT_IS_DEBUG: "isDebug",

    /**
     * BiDi setting
     * @type String
     */
    CLIENT_IS_BIDI: "isBidi",

    /**
     * Definition Url list of the widgets which is sandbox disabled: /dataEditor/dataEditor.xml,id1,id2
     * @type String
     */
    WIDGETDEFID_SANDBOX_DISABLED: "com.ibm.mashups.sandbox.force.disable",

    /**
     * Trace configuration for the client runtime
     * @type String
     */
    TRACE_CONFIG: "traceConfig",
    /**
     * tbd
     * @type String
     */
    CLIENT_POPUP_CONSOLE: "popupConsole",
    /**
     * tbd
     * @type String
     */
    CLIENT_ALLOW_PUBLISH_LOGGING: "allowPublishLogging",
    /**
     * tbd
     * @type String
     */
    CLIENT_ALLOW_PUBLISH_TRACING: "allowPublishTracing",
    /**
     * tbd
     * @type String
     */
    CLIENT_ADDITIONAL_SERVICES: "additionalServices",

    /**
     * Theme id used in case no theme is set.
     * @type String
     */
    CLIENT_DEFAULT_THEME_ID: "com.ibm.mashups.theme.defaultThemeId",
    /**
     * tbd
     * @type String
     */
    CLIENT_PAGE_SOURCE_READ_ONLY: "pageSourceReadOnly",
    /**
     * Group name used for auto accepting pages
     * @type String
     */
    CLIENT_AUTO_ACCEPT_SHARED_GROUPNAME: "autoAcceptSharedGroupName",
    /**
     * Default value for page level auto wiring enablement
     * @type String
     */
    AUTO_WIRING_DEFAULT_ENABLED: "autoWiringDefaultEnabled",
    /**
     * tbd
     * @type String
     */
    CLIENT_USER_ID_KEY: "userIdKey",
    /**
     * tbd
     * @type String
     */
    CLIENT_GROUP_CN_KEY: "groupCNKey",
    /**
     * Url used to fetch the service document
     * @type String
     */
    SERVICE_DOCUMENT_URL: "serviceDocumentUrl",
    /**
     * turns on multipart support
     * @type String
     */
    MULTIPART_ENABLED: "com.ibm.mashups.multipart.enabled",
    /**
     * if multipart support is enabled, determines if requests are correlated
     * by hostname
     * @type String
     */
    MULTIPART_CORRELATE_HOSTS: "com.ibm.mashups.multipart.correlatehosts",
    /**
     * if multipart support is enabled, should URLs with query strings be
     * considered cacheable
     * @type String
     */
    MULTIPART_CACHE_QUERIES: "com.ibm.mashups.multipart.cachequeries",
    /**
     * Returns the semicolon separated list of Endpoint IDs
     * @type String
     */
    ENDPOINTS: "endpointIDs",
    /**
     * Returns the name of the Endpoints Config Provider
     * @type String
     */
    ENDPOINT_CONFIG_PROVIDER: "Endpoints",
    /**
     * Returns the name of the Anonymous User Config setting
     * @type {String}
     */
    ANONYMOUS_USER: "anonymousUser",
    /**
     * MetaData name used to recognize whether a page is hidden or not
     * @type String
     */
    NAVIGATION_HIDDEN: "com.ibm.mashups.navigation.hidden",
    /**
     * MetaData name used to recognize whether a space is hidden or not
     * @type String
     */
    SPACE_HIDDEN: "com.ibm.mashups.space.hidden",
    /**
     * Returns the name of the current User Config setting
     * @type String
     */
    USER: "user",
    /**
     * Returns the name of subdomains Config setting, subdomains are used to create sandboxed iwidgets
     * @type String
     */
    SUBDOMAINS: "subdomains",
    /**
     * Returns the name of server domain Config setting
     * @type String
     */
    SERVERDOMAIN: "serverdomain",
    /**
     * Returns the name of sandboxenabled Config setting, sandboxed feature is disabled if this configuration is set to false
     * @type String
     */
    SANDBOXENABLED: "sandboxenabled",
    /**
     * Returns the name of config setting that decides if subdomain should be reused when an existing sandboxed iwidget is removed from the page.
     * @type String
     */
    SUBDOMAINREUSE: "subdomainreuse",
    /**
     * MetaData name used to indicate attributes that need to added to url
     * @type String
     */
    NAVSTATE_PERSISTENCE_URL: "navstate.persistence.url",
    /**
     * MetaData name used to indicate attributes that need to added to persistence store
     * @type String
     */
    NAVSTATE_PERSISTENCE_PSTORE: "navstate.persistence.pstore",
    /**
     * MetaData name used to indicate number of widgets whose navigation state will be added to url
     * @type String
     */
    NAVSTATE_PERSISTENCE_URL_LIMIT: "navstate.persistence.url.limit",
	  /**
     * MetaData name used to indicate number of sharedparametersets whose navigation state will be added to url
     * @type String
     */
    NAVSTATE_PERSISTENCE_URL_SPLIMIT: "navstate.persistence.url.splimit",
    /**
     * MetaData name used to indicate if navigation state is huffmann encoded or not
     * @type String
     */
    NAVSTATE_HUFFMANNENCODE_ENABLED: "navstate.huffmannencode.enabled",
    /**
     * MetaData name used to indicate the html fragment that's displayed when a widget is under loading
     * @type String
     */
    LOADING_HTML: "loadingHTML",

    /**
     * Specified whether pageloading should be optimized (Multipart)
     * @type String
     */
    PAGE_LOAD_OPTIMIZATION: "pageLoadOptimization",

    /**
     * Specified whether pageloading should be optimized for themes (Multipart)
     * @type String
     */
    PAGE_LOAD_OPTIMIZATION_THEME: "pageLoadOptimizationTheme",

	/**
	 * Specifies whether application widgets should be optimized (Multipart)
     * @type String
	 */
	PAGE_LOAD_OPTIMIZATION_APP_WIDGETS: "pageLoadOptimizationAppWidgets",

    /**
     * Allows to create New Spaces and Pages for anonymous users
     * @type String
     */
    ANONYMOUS_ALLOW_CREATE: "com.ibm.mashups.anonymous.allow.create",

    /**
     * If displayName is not sent from server use this property for User Display Name
     * @type String
     */
    DEFAULT_USER_DISPLAY_PROP: "com.ibm.mashups.default.user.display.prop",

    /**
     * The product name which will show up in the browser title, other product can replace it.
     * @type String
     */
    PRODUCT_NAME: "com.ibm.mashups.productname",

    /**
     * If displayName is not sent from server use this property for Group Display Name
     * @type String
     */
    DEFAULT_GROUP_DISPLAY_PROP: "com.ibm.mashups.default.group.display.prop",

    /**
     * The unique name of the welcome space
     * @type String
     */
    WELCOME_SPACE_ID: "com.ibm.mashups.welcome.space.name",

    /**
     * The filter as regexp for characters used on page and space title.
     * @type String
     */
    BUILDER_TITLE_FILTER_REGEXP : "com.ibm.mashups.builder.filter.title.regexp",

	/**
     * ID of the Anonymous Virtual User
     * @type String
     */
    ANON_VIRTUAL_USER_ID : "com.ibm.mashups.anonUserId",

	/**
     * ID of the All Authenticated Users Virtual Group
     * @type String
     */
    ALL_AUTH_VIRTUAL_GROUP_ID : "com.ibm.mashups.allAuthGroupId",

    /**
     * The server type this enabler is connected to. It can be either SERVER_TYPE_MASHUPS or SERVER_TYPE_PORTAL
     * @type String
     */
    SERVER_TYPE : "com.ibm.mashups.server",

    /**
     * The server type value for Lotus Mashups
     * @type String
     */
    SERVER_TYPE_MASHUPS : "Lotus_Mashups",

    /**
     * The server type value for WebSphere Portal
     * @type String
     */
    SERVER_TYPE_PORTAL : "WebSphere_Portal",

    /**
     * The server type value for Business Space
     */
    SERVER_TYPE_BSPACE : "Business_Space",

	/**
	 * Anonymous mode enabled default is false
     * @type String
	 */
	ANON_MODE_ENABLED : "com.ibm.mashups.anonymous.mode",

	/**
	 * Setting to true will prevent search clients for automatically adding wildcards
	 * to user and group searches.  Default is false.
	 * @type String
	 */
	AUTO_WILDCARD_DISABLED : "com.ibm.mashups.autoWildcardSearchDisabled",

	/**
	 * Sets the name of the property in the ContextMenu_Provider to use for the
	 * context menu
	 * @type String
	 */
	CONTEXT_MENU_NAME : "com.ibm.mashups.contextmenu.name",

	WIDGET_BUILDER_ENABLED : "com.ibm.mashups.widgetBuilder.enabled",

	CREATE_SPACE_TEMPLATE_MODE: "createSpaceOnTemplateMode",

	FAVORITE_SPACES_MAXIMUM_NUMBER: "favorite.spaces.maximum.number",
	RECENT_SPACES_MAXIMUM_NUMBER: "recent.spaces.maximum.number",
	/**
	 * Register resources that's preloaded with enabler so enabler won't load it anymore
	 * For example:
	 *  [{globalid: "lconn.coreUtilities", version: "2.5"}, {globalid: "lconn.coreCSS", version: "2.5"}]
	 * @type String
	 */
	REGISTER_LOADEDRESOURCES:"register.loadedresources",

    /**
     * Defines the persistence mode that should be used by the iContext. Default is <tt>DOM</tt>.
     */
    PERSISTENCE_MODE: "com.ibm.mashups.enabler.icontext.persistence.mode",

    /**
     * Defines the read-only persistence mode for the event provider that is used by the iContext. It overwrites any mode defined as part of <tt>PERSISTENCE_MODE</tt>.Default is <tt>DOM</tt>.
     */
    PERSISTENCE_MODE_EVENTS: "com.ibm.mashups.enabler.icontext.persistence.mode.events",
    /**
     * Defines the modifiable persistence mode for the event provider that is used by the iContext. It overwrites any mode defined as part of <tt>PERSISTENCE_MODE</tt>.Default is <tt>DOM</tt>.
     */
    PERSISTENCE_MODE_EVENTS_MODIFIABLE: "com.ibm.mashups.enabler.icontext.persistence.mode.events.modifiable",

    /**
     * Defines the read-only persistence mode for the wire provider that is used by the iContext. It overwrites any mode defined as part of <tt>PERSISTENCE_MODE</tt>.Default is <tt>DOM</tt>.
     */
    PERSISTENCE_MODE_WIRES: "com.ibm.mashups.enabler.icontext.persistence.mode.wires",
    /**
     * Defines the modifiable persistence mode for the wire provider that is used by the iContext. It overwrites any mode defined as part of <tt>PERSISTENCE_MODE</tt>.Default is <tt>DOM</tt>.
     */
    PERSISTENCE_MODE_WIRES_MODIFIABLE: "com.ibm.mashups.enabler.icontext.persistence.mode.wires.modifiable",

    /**
     * Defines the read-only persistence mode for the attributes provider that is used by the iContext. It overwrites any mode defined as part of <tt>PERSISTENCE_MODE</tt>.Default is <tt>DOM</tt>.
     */
    PERSISTENCE_MODE_ATTRIBUTES: "com.ibm.mashups.enabler.icontext.persistence.mode.attributes",
    /**
     * Defines the modifiable persistence mode for the attributes provider that is used by the iContext. It overwrites any mode defined as part of <tt>PERSISTENCE_MODE</tt>.Default is <tt>DOM</tt>.
     */
    PERSISTENCE_MODE_ATTRIBUTES_MODIFIABLE: "com.ibm.mashups.enabler.icontext.persistence.mode.attributes.modifiable",

    /**
     * Defines whether the json attributes implementation will be injecting the attributes defined in the widget xml
     * as well into the attributes map. This will only apply if the json attributes have been enabled through the PERSISTENCE_MODE_ATTRIBUTES setting.
     */
    PERSISTENCE_MODE_ATTRIBUTES_JSON_INJECTXML: "com.ibm.mashups.enabler.icontext.attributes.json.injectxml",

    /**
     * Defines whether autocommit is enabled on the iContext. If set to <tt>true</tt> the iContext will automatically commit data to the
     * backend if commit is called on e.g. the iWidgetAttributes.
     */
    ICONTEXT_AUTO_COMMIT: "com.ibm.mashups.enabler.icontext.autocommit",

	ID_PREFIX: "com.ibm.mashups.iWidget.idPrefix",
    /**
     * Defines how violations of enabler usage is prompted to the user; see
     * <ul>
     * <li><code>API_ENFORCEMENT_MODE_WARN</code></li>
     * <li><code>API_ENFORCEMENT_MODE_ERROR</code></li>
     * </ul>
     * Defaults to <code>API_ENFORCEMENT_MODE_WARN</code>.
     * @type String
     * @private
     */
    API_ENFORCEMENT_MODE: "com.ibm.mashups.enabler.enforcement",

    /**
     * Warnings will be prompted in the console denoting usage errors of the enabler api.
     * @type String
     * @private
     */
    API_ENFORCEMENT_MODE_WARN: "warning",

    /**
     * Errors will be thrown denoting usage errors of the enabler api, note that
     * this potentially breaks the driver if the api is used incorrectly.
     * @type String
     * @private
     */
    API_ENFORCEMENT_MODE_ERROR: "error",

    /**
     * With this option the location (a URL) of the widget which will be displayed for non previewable content can be defined.
     * If empty (thats the default) the widget delivered with the enabler will be used.
     *
     * @since 3.0
     * @type String
     */
    NON_PREVIEWABLE_WIDGET_LOCATION: "com.ibm.mashups.enabler.layout.widget.NonPreviewableContentWidget.location",

    /**
     * Size limit of page descriptions, implied from persistence
     * @since 3.0
     * @type String
     */
    LIMIT_PAGE_DESCRIPTION: "com.ibm.mashups.persistence.page.description.limit",

    /**
     * Defines whether personalize is allowed or not for users. Defaults to true.
     * @since 3.0
     * @type Boolean
     */
    WIDGET_PERSONALIZE_ENABLED: "com.ibm.mashups.widget.attributes.personalize.enabled",

    /**
     * Defines maximum page number when creating page base on page from hub. Defaults to 50.
     * @since 3.0
     * @type String
     */
	SPACEMANAGER_PAGE_QUERYCOUNT : "com.ibm.mashups.spacemanager.page.queryCount",
    /**
     * Defines the search keyword when pages in hub are queried. Keep it empty will return all pages.
     * @since 3.0
     * @type String
     */
	SPACEMANAGER_PAGE_QUERYKEYWORD : "com.ibm.mashups.spacemanager.page.queryKeyword",
    /**
     * Defines maximum space number when creating space base on space from hub. Defaults to 50.
     * @since 3.0
     * @type String
     */
	SPACEMANAGER_SPACE_QUERYCOUNT : "com.ibm.mashups.spacemanager.spacetemplate.queryCount",
    /**
     * Defines the search keyword when spaces in hub are queried. Keep it empty will return all spaces.
     * @since 3.0
     * @type String
     */
	SPACEMANAGER_SPACE_QUERYKEYWORD : "com.ibm.mashups.spacemanager.spacetemplate.queryKeyword",

     /**
     * Defines the search keyword when spaces in hub are queried. Keep it empty will return all spaces.
     * @since 3.0
     * @type String
     */

    LOCALAPPS_REGEX : "com.ibm.mashups.multipart.localapps.regex",

    /**
     * Defines the format (as a regular expression) of the server side object IDs.
     * @since 3.0
     * @type String
     */
    SERVER_OBJECT_ID_FORMAT: "com.ibm.mashups.server.oid.format",

	/**
	 * Defines whether to use queued widget rendering. Default to true.
	 * @since 3.0.0.1
     * @type Boolean
	 */
    QUEUE_RENDERING: "com.ibm.mashups.queueRendering"

});

com.ibm.mashups.enabler.services.ConfigConstants = new com.ibm.mashups.enabler.services.ConfigConstants();

}

if(!dojo._hasResource["com.ibm.mashups.enabler.services.ConfigObject_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.services.ConfigObject_API"] = true;
dojo.provide("com.ibm.mashups.enabler.services.ConfigObject_API");
dojo.provide("com.ibm.mashups.enabler.services.ConfigObject");

/**
 * The Config Object allows to access config variables as defined by the system.
 * for a specific config provider.
 * @ibm-spi
 * @ibm-module Base2
 */
dojo.declare("com.ibm.mashups.enabler.services.ConfigObject", null, {
    /**
     * This method returns the value of the config variable as defined by the system
     * @param {String} name the name of the config variable
     * @return {String} the value of the config variable. Maybe be NULL.
     */
    getValue: function(name) {
        return null;
    },

	/**
     * This method returns the value of the config variable as defined by the system in a async way
     * @param {String} name the name of the config variable
     * @return {com.ibm.mashups.enabler.Deferred} a deferred object used to start this operation. The return value
     * when executed through the deferred object is the value of the config variable. Maybe be NULL
     */
	getValueDeferred: function(name) {
        return null;
    }

});

}

if(!dojo._hasResource["com.ibm.mm.enabler.services.ConfigObjectDefaultImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.services.ConfigObjectDefaultImpl"] = true;
dojo.provide("com.ibm.mm.enabler.services.ConfigObjectDefaultImpl");




dojo.declare("com.ibm.mm.enabler.services.ConfigObjectDefaultImpl", [com.ibm.mashups.enabler.services.ConfigObject], {
    constructor: function(provider, configService) {
        this.provider = provider;
        this.configService = configService;
        this.ns = {};
        this.ns.app = "http://www.w3.org/2007/app";
        this.ns.atom = "http://www.w3.org/2005/Atom";
    },

    /**
     * @deprecated
     */
    getPreferenceValue: function( /*string*/name) {
        if (this.provider == "all") {
            return this.configService.getValue(name);
        }
        else {
            return this._getValue(this.provider, name);
        }

        return null;
    },

    getValue: function( /*string*/name) {
        if (this.provider == "all") {
            return this.configService.getValue(name, internal);
        }
        else {
            return this._getValue(this.provider, name);
        }

        return null;
    },

    _getValue: function(/*string*/provider, /*string*/ name) {
        return null;
    },

	getValueDeferred: function(/*string*/name){
		if (this.provider == "all") {
			return new com.ibm.mm.enabler.DeferredImpl(this, function(deferred, sync, name) {
				var callBack = deferred.getFinishedCallback();
				var retValue = this.configService.getValue(name, internal);
				if (retValue && callBack ) {
					callBack(retValue, com.ibm.mm.enabler.model.HttpStatusCodes.HTTP_OK, deferred.getFinishedCallbackParameters());
				}
				return retValue;
			});
		}
		else {
			return this._getValueDeferred(this.provider, name);
		}
	},

	_getValueDeferred: function(/*string*/provider, /*string*/ name) {
        return null;
    }
});

// IMPORTANT
// ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
// This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "Base")>=0)) {
    dojo["require"]("com.ibm.mm.enabler.services.ConfigObjectExtendedImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
}

}

if(!dojo._hasResource["com.ibm.mashups.enabler.services.ConfigObject"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.services.ConfigObject"] = true;
dojo.provide("com.ibm.mashups.enabler.services.ConfigObject");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.services.ConfigService_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.services.ConfigService_API"] = true;
dojo.provide("com.ibm.mashups.enabler.services.ConfigService_API");
dojo.provide("com.ibm.mashups.enabler.services.ConfigService");



/**
 * The Config Service allows to access config variables as defined by the system.
 * The service can be retrieved using the following code: <br>
 * <code>var configService = com.ibm.mashups.services.ServiceManager.getService(<br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);</code><br/>
 * @ibm-spi
 * @ibm-module Base2
 */
dojo.declare("com.ibm.mashups.enabler.services.ConfigService", null, {
    /**
     * The service name to be used to fetch the service from the ServiceManager
     * @type String
     */
    SERVICE_NAME: "configService",

    /**
     * This method returns the value of the config variable as defined by the system
     * @param {String} name the name of the config variable
     * @return {String} the value of the config variable. Maybe be NULL.
     */
    getValue: function(name) {
        return null;
    },

    /**
     * This method returns the value of the config object for a config provider
     * @param {String} name the name of the config provider
     * @return {com.ibm.mashups.enabler.services.ConfigObject} the config provider. Maybe be NULL.
     */
    getConfigObject: function(name) {
        return null;
    },

    /**
     * This method returns the Config Provider names.  Each Config Provider will
     * have a corresponding ConfigObject.
     * @return {String[]} the config provider names. Never NULL.
     */
    getConfigProviderNames: function() {
        return null;
    }
});
// make sure we can reference this globally
com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME = "configService";

}

if(!dojo._hasResource["com.ibm.mashups.services.ServiceManager_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.services.ServiceManager_API"] = true;
dojo.provide("com.ibm.mashups.services.ServiceManager_API");
dojo.provide("com.ibm.mashups.services.ServiceManager");

/**
 * This interface manages services that are provided to the system, i.e. to iWidgets and other components.<br/>
 * It provides capability to access Services in Lotus Mashups. <br/>
 * By default EventService and ConfigService are provided.<br/>
 * Page components are able to use event services by using following api:<p/>
 * <code>var eventService = com.ibm.mashups.services.ServiceManager.getService(<br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;com.ibm.mashups.iwidget.services.EventService.SERVICE_NAME);</code><br/>
 * <p/><p/>
 * <b>Configuration of services:</b><br/>
 * This section describes how each service is configured and  how additional services can be added.<p/>
 *
 * Through the ConfigService.properties one can define an additional property named "additionalServices"
 * defining additional services besides EventService and ConfigService.<p/>
 * Each entry should have the following format.<p />
 * <code>"name": service name.</code><br/>
 * <code>"path": url that point to the service js file.</code><br/>
 * <code>"baseClass": the class that implements the service. one instance of this class will be generated.</code><br />
 * <p/>
 * Example:<br/>
 *  &nbsp;&nbsp;&nbsp;additionalServices = [<br/>
 *  &nbsp;&nbsp;&nbsp;{ "name":"SecurityService",<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"path":"/mum/js/com/ibm/enabler/iw/securityservices.js",<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"baseClass":"com.ibm.mm.iwidget.services.SecurityService"}<br/>
 *  &nbsp;&nbsp;&nbsp;] <p />
 *
 * @ibm-spi
 * @ibm-module Base2
 */
dojo.declare("com.ibm.mashups.services.ServiceManager",null,
  {
    /**
     * @private
     */
    constructor:function(){
    },
    /**
    This interface allow page components to get the required service.
    @param{String} serviceName required service name that's used to uniquely identify a service .
    @type Object
    @returns{Object} an instance of required service. NULL if configured incorrectly.
    */
    getService:function(serviceName) {
    }
  }
);

}

if(!dojo._hasResource["com.ibm.mashups.services.ServiceManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.services.ServiceManager"] = true;
dojo.provide("com.ibm.mashups.services.ServiceManager");





}

if(!dojo._hasResource["com.ibm.mm.services.ServiceManagerImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.services.ServiceManagerImpl"] = true;
dojo.provide("com.ibm.mm.services.ServiceManagerImpl");






dojo.declare("com.ibm.mm.services.ServiceManagerImpl", com.ibm.mashups.services.ServiceManager, {
    constructor: function() {
        this._serviceEntries = {};

        //allow overwritten if ibmConfig.loadServices is set
        ibmConfig = ibmConfig || {};
        ibmConfig.additionalServices = ibmConfig.additionalServices || null;
        if (ibmConfig.additionalServices) {
            var entries = dojo.fromJson(ibmConfig.additionalServices);
            for (var i in entries) {
                if (Object.prototype.hasOwnProperty.call(entries,i)) {
                    var anEntry = entries[i];
                    this._serviceEntries[anEntry.name] = anEntry;
                }
            }
        }
    },
    getService: function(serviceName) {

        var serviceEntry = this._serviceEntries[serviceName];
        serviceEntry = serviceEntry || null;
        if (serviceEntry !== null) {
            var serviceHandler = serviceEntry.serviceHandler;
            serviceHandler = serviceHandler || null;
            if (serviceHandler === null) {
                // assume js is already loaded, create service object
                serviceHandler = this._createService(serviceEntry);
                serviceHandler = serviceHandler || null;
                if (serviceHandler === null) {
                    this._loadScript(serviceEntry);
                    //  serviceHandler = this._createService(serviceEntry);
                }
                else {
                    this._serviceEntries[serviceName].serviceHandler = serviceHandler;
                }
            }
        }
        return this._serviceEntries[serviceName].serviceHandler;
    },
    //if serviceHandler is String, then it's baseClass
    //if it's object, then it's the service handler instance
    setService: function(serviceName, serviceHandler) {
        serviceHandler = serviceHandler || null;
        if (serviceHandler === null) {
            return null;
        }
        //create new service or overwrite an existing service
        var serviceEntry = this._serviceEntries[serviceName];
        serviceEntry = serviceEntry || null;
        if (serviceEntry !== null) {
            delete this._serviceEntries[serviceName];
        }
        if (!this._serviceEntries[serviceName]) {
            this._serviceEntries[serviceName] = {};
        }
        if (dojo.isString(serviceHandler)) {
            this._serviceEntries[serviceName].baseClass = serviceHandler;
        }
        else {
            this._serviceEntries[serviceName].serviceHandler = serviceHandler;
        }
    },

    _loadScript: function(serviceEntry) {
        var me = this;
        dojo.xhrGet({
            url: serviceEntry.path,
            handleAs: "text",
            sync: true,
            load: function(result) {
                dojo.eval(result); // JSLINT-IGNORE: We have to evaluate the services JavaScript in this case
                var serviceHandler = me._createService(serviceEntry);
                if (typeof serviceHandler != "undefined" && serviceHandler !== null) {
                    var serviceName = serviceEntry.name;
                    serviceEntry.serviceHandler = serviceHandler;
                }
            },
            error: function(data, ioArgs) {
            }
        });
    },

    _createService: function(serviceEntry) {
        var service = null;
        try {
            service = new (dojo.getObject(serviceEntry.baseClass))();
        }
        catch (err) {
        }
        return service;
    }
});

com.ibm.mashups.services.ServiceManager = new com.ibm.mm.services.ServiceManagerImpl();


}

if(!dojo._hasResource["com.ibm.mm.enabler.services.AbstractConfigServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.services.AbstractConfigServiceImpl"] = true;
dojo.provide("com.ibm.mm.enabler.services.AbstractConfigServiceImpl");




dojo.declare("com.ibm.mm.enabler.services.AbstractConfigServiceImpl", com.ibm.mashups.enabler.services.ConfigService, {

    constructor: function(){
    },

    /**
     * @deprecated
     */
    getPreferenceValue: function( /*string*/name){
        return this.getValue(name);
    },

    getValue: function( /*string*/name, internal){
        var value = ibmConfig[name];
        return value;
    },

    getConfigObject: function(/*string*/configProvider){
        return null;
    },

    getConfigProviderNames: function(){
        return null;
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.services.ConfigServiceDefaultImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.services.ConfigServiceDefaultImpl"] = true;
dojo.provide("com.ibm.mm.enabler.services.ConfigServiceDefaultImpl");

// inject this service into the ServiceManager at the end. Therefore we have to require the implementation




//
//
//



dojo.declare("com.ibm.mm.enabler.services.ConfigServiceDefaultImpl", [com.ibm.mm.enabler.services.AbstractConfigServiceImpl], {
    constructor: function() {
    },

    _getConfigObject: function(/*string*/configProvider) {
        if (!ibmConfig["CO_" + configProvider]) {
            var co = new com.ibm.mm.enabler.services.ConfigObjectDefaultImpl(configProvider, this);
            ibmConfig["CO_" + configProvider] = co;
        }

        return ibmConfig["CO_" + configProvider];
    },

    _getConfigProviderNames: function() {
        var ret = [];
        ret.push("all");
        return ret;
    },

    getValue: function(name) {
        var ret = this.inherited(arguments, [name, true]);
        return ret;
    },

    getConfigObject: function(name) {
        var ret = this._getConfigObject(name);
       return ret;
    },

    getConfigProviderNames: function() {
        var ret = this._getConfigProviderNames();
        return ret;
    }

});

com.ibm.mashups.services.ServiceManager.setService("configService", "com.ibm.mm.enabler.services.ConfigServiceDefaultImpl");

// IMPORTANT
// ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
// This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "Base")>=0)) {
    dojo["require"]("com.ibm.mm.enabler.services.ConfigServiceExtendedImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
}

}

if(!dojo._hasResource["com.ibm.mashups.enabler.services.ConfigService"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.services.ConfigService"] = true;
dojo.provide("com.ibm.mashups.enabler.services.ConfigService");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.utils.EndpointHelper_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.utils.EndpointHelper_API"] = true;
dojo.provide("com.ibm.mashups.enabler.utils.EndpointHelper_API");
dojo.provide("com.ibm.mashups.enabler.utils.EndpointHelper");

/**
 * Helper utility for endpoint encoded urls.
 *
 * @ibm-module Base2
 * TODO: Change/Remove
 */
dojo.declare("com.ibm.mashups.enabler.utils.EndpointHelper", null, {
	/**
	 * This method resolves endpoint://{endpointid}/relativeurl
	 *
	 * @param {String} url the url to resolve for endpoints
     * @return {String} the url with endpoints resolved
     */
    resolve: function(url) {
        return null;
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.EndpointUtils"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.EndpointUtils"] = true;
dojo.provide("com.ibm.mm.enabler.EndpointUtils");

dojo.declare("com.ibm.mm.enabler.EndpointUtilsDefaultImpl", null, {
    constructor: function(){
    },

    checkForEndpoints: function(/*String*/url){
        return null;
    }
});
com.ibm.mm.enabler.EndpointUtils = new com.ibm.mm.enabler.EndpointUtilsDefaultImpl();

// IMPORTANT
// ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
// This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "iWidget")>=0)) {
    dojo["require"]("com.ibm.mm.enabler.EndpointUtilsExtendedImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
}

}

if(!dojo._hasResource["com.ibm.mm.enabler.utils.EndpointHelperImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.utils.EndpointHelperImpl"] = true;
dojo.provide("com.ibm.mm.enabler.utils.EndpointHelperImpl");




dojo.declare("com.ibm.mm.enabler.utils.EndpointHelperImpl", null,
    {
        resolve: function(url) {
            if (!url) {
                return url;
            }

            var url2 = com.ibm.mm.enabler.EndpointUtils.checkForEndpoints(url);
            if (url2) {
               return url2;
            }

            return url;
        }
    }
);

com.ibm.mashups.enabler.utils.EndpointHelper = new com.ibm.mm.enabler.utils.EndpointHelperImpl();

}

if(!dojo._hasResource["com.ibm.mashups.enabler.utils.EndpointHelper"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.utils.EndpointHelper"] = true;
dojo.provide("com.ibm.mashups.enabler.utils.EndpointHelper");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.utils.URLHelper_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.utils.URLHelper_API"] = true;
dojo.provide("com.ibm.mashups.enabler.utils.URLHelper_API");
dojo.provide("com.ibm.mashups.enabler.utils.URLHelper");

/**
 * Helper utility for encoding urls.
 *
 * @ibm-module Base2
 */
dojo.declare("com.ibm.mashups.enabler.utils.URLHelper", null, {
    /**
     * This method rewrites a url and takes care for instance to proxify the given url
     *
     * @ibm-api
     *
     * @param {String} url the url to rewrite
     * @return {String} the encoded url
     */
    rewriteURL: function(targetUrl){
        return null;
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.utils.Misc"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.utils.Misc"] = true;
dojo.provide("com.ibm.mm.enabler.utils.Misc");




com.ibm.mm.enabler.utils.Misc = {
    /**
     * Example usage:
     *
     *
     *
     * var myObj = {a: 1, b: "bla", c: function(){}};
     *
     * com.ibm.mm.enabler.utils.Misc.forIn(myObj,function(item,idx,arr) {
     *    console.debug(arguments);
     *   });
     *   // prints:
     *   // [1, "a", Object { a=1,  more...}]
     *   // ["bla", "b", Object { a=1, more...}]
     *   // [function(), "c", Object { a=1, more...}]
     *
     *
     *  var myScope = {
     *     count: 0,
     *    f: function(item,idx,arr) {
     *          this.count++;
     *         }
     *   }
     *  com.ibm.mm.enabler.utils.Misc.forIn(myObj,'f',myScope);
     *
     *  console.debug(myScope.count); // prints: 3

     * @param {Object} obj The object to iterate over
     * @param {Function|String} func The function to call on each object with three parameters: value, key, object
     * @param {Object} scope Optional, the scope to call the function on.
     */
    forIn: function(obj, func, scope) {
       if(!obj || typeof obj != "object") {
          return;
       }
       scope = scope || null;
       var item;
       for(var idx in obj) {
           if(Object.prototype.hasOwnProperty.call(obj,idx)) {
               item = obj[idx];
               dojo.hitch(scope,func)(item,idx,obj);
           }
       }
    },

    encodePath: function(path, decoded) {
        if (path.length === 0) {
            return path;
        }

        var parts = path.split("/");

        for (var i=0; i<parts.length; ++i) {
            parts[i] = decoded ? com.ibm.mm.enabler.utils.Misc._pathPartUnescape(parts[i]) :
                com.ibm.mm.enabler.utils.Misc._pathPartEscape(com.ibm.mm.enabler.utils.Misc._pathPartUnescape(parts[i]));
        }

        return parts.join("/");
    },
    // Acccording to RFC 1738
    // those are the allowed characters in a path element
    // reserved:        ";" | "/" | "?" | ":" | "@" | "&" | "="
    // allowed in path: ";" |             ":" | "@" | "&" | "="
    _pathPartUnescape:function(pathPart) {
        pathPart = decodeURIComponent(pathPart);
/* Removed per #18252
        pathPart = pathPart.replace(/%2F/g, '/');
        pathPart = pathPart.replace(/%2f/g, '/');
        pathPart = pathPart.replace(/%3F/g, '?');
        pathPart = pathPart.replace(/%3f/g, '?');
*/
        return pathPart;
    },
    _pathPartEscape:function(pathPart) {
        pathPart = encodeURIComponent(pathPart);
/* Removed per #18252
        pathPart = pathPart.replace(/\//g, '%2F');
        pathPart = pathPart.replace(/\?/g, '%3F');
*/
        // we do not encode a colon as this is allowed by the spec and the OpenSocial container requires it
        pathPart = pathPart.replace(/%3a/g, ':');
        pathPart = pathPart.replace(/%3A/g, ':');
        return pathPart;
    },
    inStringArray:function(str,/*[]*/arrayObj)
    {
        var rc = false;
        for (var i in arrayObj) {
            if (Object.prototype.hasOwnProperty.call(arrayObj,i)) {
                var temp1 = arrayObj[i];
                if (temp1 == str) {
                    rc = true;
                    break;
                }
            }
        }
        return rc;
    },
    isEmpty: function (object) {
    	if(object === null || typeof object == "undefined") {
    		return true;
    	} else if(dojo.isString(object)) {
    		return object.length === 0;
    	} else {
            for (var i in object) {
                if (Object.prototype.hasOwnProperty.call(object, i)) {
                    return false;
                }
            }
            return true;
    	}
    },
    encodeModelID4Uri:function(uri)
    {
        // encode uri part correctly
        var pos = uri.indexOf(":");
        if (pos != -1) {
            var start = uri.slice(0,pos+1);
            var end = uri.slice(pos+1);
            uri = start + encodeURIComponent(end);
        }
        return encodeURIComponent(uri);
    },
    preloadImage:function(path,width,height){
        var image = (width && height) ? new Image(width, height) : new Image();
        image.src = path;
        return image;
    },
    isInstanceOf:function(obj1, obj2) {
        if (obj1 && obj2) {
            if (typeof obj1.isInstanceOf == "function") {
                 if (obj1.isInstanceOf(obj2)) {
                    return true;
                 }

            }
            return (obj1 instanceof obj2);
        }
        return false;

    },
	isPocUrl: function(urlString) {

    	var supportedSchema =  {
        	http: "http",
        	https: "https",
        	file: "file" //not resolver will handle web dav:/ url
    	};
        var rc = false;
        if (urlString.indexOf(":") > 0) {
            if (urlString.indexOf("/") === 0) {
                return false;
            }
			if (urlString.indexOf("?") === 0) {
                return false;
            }
            var schema = urlString.substring(0, urlString.indexOf(":"));
            if (!supportedSchema[schema]) {
                rc = true;
            }
        }
        return rc;
    }
};

}

if(!dojo._hasResource["com.ibm.mm.enabler.utils.HttpUrl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.utils.HttpUrl"] = true;
dojo.provide("com.ibm.mm.enabler.utils.HttpUrl");








dojo.declare("com.ibm.mm.enabler.utils.HttpUrl", null, {
    constructor: function( /*String*/urlString, /*boolean*/ resolveEndpoints){

        if (resolveEndpoints !== false) {
            var resolved = com.ibm.mm.enabler.EndpointUtils.checkForEndpoints(urlString);
            if (resolved) {
                urlString = resolved;
            }
        }

        this.pocurl = this._resolvePocUrl(urlString);
        if (!this.pocurl) {
            this.scheme = this._extractScheme(urlString);
            this.server = this._extractServer(urlString);
            this.port = this._extractPort(urlString);
            this.path = this._extractPath(urlString);
            this.parameters = this._extractQuery(urlString);
            this.anchor = this._extractAnchor(urlString);
        }
    },
    _resolvePocUrl: function(urlString){

        var rv = null;
        if (com.ibm.mm.enabler.utils.Misc.isPocUrl(urlString)) {
            var prefix = this._getPrefix();
            urlString = escape(unescape(urlString)); // encode before adding as parameter
            rv = prefix.concat(urlString);
        }
        return rv;
    },
    _getPrefix: function(){
        var cs = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
        var serverRoot = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT);
        var anonymousUser = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.ANONYMOUS_USER);
        var contenthandlerPath;

        if (anonymousUser) {
            contenthandlerPath = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PUBLIC);
        }
        else {
            contenthandlerPath = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PRIVATE);
        }

        var rv = serverRoot.concat(contenthandlerPath).concat("?uri=");
        return rv;
    },

    addParameter: function( /*String*/name, /*String*/ value){
        if (dojo.isString(this.parameters[name])) {
            this.parameters[name] = [this.parameters[name], value];
        }
        else
            if (dojo.isArray(this.parameters[name])) {
                this.parameters[name].push(value);
            }
            else {
                this.parameters[name] = value;
            }
    },
    setParameter: function(/*String*/name, /*Object*/ value){
        if (!this.parameters) {
            this.parameters = {};
        }
        this.parameters[name] = value;
    },
    getParameter: function(/*String*/name){
        if (!this.parameters) {
            return false;
        }
        return this.parameters[name];
    },
    getParameters: function(){
        return this.parameters;
    },
    isProxyNeeded: function(){
        var loc = document.location;
        // first test the scheme:
        if (loc.protocol != this.scheme) {
            return true;
        }
        // test the host
        if (!this._equalsServer(loc.hostname)) {
            return true;
        }
        // simplest case, ports are the same, return false
        if (loc.port == this.port) {
            return false;
        }

        var defaultPort;
        // tests for http with default port
        if (this.scheme == "http:") {
            defaultPort = "80";

            if ((loc.port == "" && this.port == defaultPort) ||
            (loc.port == defaultPort && this.port == "")) {
                return false;
            }
        }

        // tests for https with default port
        if (this.scheme == "https:") {
            defaultPort = "443";

            if ((loc.port == "" && this.port == defaultPort) ||
            (loc.port == defaultPort && this.port == "")) {
                return false;
            }
        }

        return true;
    },
    toServerRelativeString: function(decoded){
        if (this.pocurl) {
            return this.pocurl;
        }
        var str = "";

        if (this.path != "") {
            str += "/" + com.ibm.mm.enabler.utils.Misc.encodePath(this.path, decoded);
        }
        if (!com.ibm.mm.enabler.utils.Misc.isEmpty(this.parameters)) {
            str += "?" + (decoded ? this._parametersToQuery(this.parameters) : dojo.objectToQuery(this.parameters));
        }
        if (this.anchor != "") {
            str += "#" + this.anchor;
        }

        return str;
    },
    toProxifiedString: function(){
        //check if we need the proxy
        if (this.pocurl) {
            return this.pocurl;
        }
        if (typeof ibmConfig == 'undefined') {
            return this.toString();
        }

        var newURL = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.PROXY_URL);
        if (!newURL) {
            return this.toString();
        }
        newURL += "/";

        if (window.location.protocol == this.scheme && this._equalsServer(window.location.hostname)) {
            if (window.location.port == this.port) {
                return this.toString();
            }
            else
                if (this.scheme == "http:" && window.location.port == "" && this.port == "80") {
                    return this.toString();
                }
                else
                    if (this.scheme == "https:" && window.location.port == "" && this.port == "443") {
                        return this.toString();
                    }
                    else
                        if (this.scheme == "http:" && window.location.port == "80" && this.port == "") {
                            return this.toString();
                        }
                        else
                            if (this.scheme == "https:" && window.location.port == "443" && this.port == "") {
                                return this.toString();
                            }
        }

        // rewrite
        if (this.scheme == "https:") {
            newURL += "https/" + this.server + ((this.port != "443" && this.port != "") ? ":" + this.port : "");
        }
        else {
            newURL += "http/" + this.server + ((this.port != "80" && this.port != "") ? ":" + this.port : "");
        }

        // add the slash portion in ANY case
        newURL += "/";

        if (this.path != "") {
            newURL += com.ibm.mm.enabler.utils.Misc.encodePath(this.path);
        }

        if (!com.ibm.mm.enabler.utils.Misc.isEmpty(this.parameters)) {
            newURL += "?" + dojo.objectToQuery(this.parameters);
        }

        if (this.anchor != "") {
            newURL += "#" + this.anchor;
        }

        return newURL;
    },
    toString: function(decoded){
        if (this.pocurl) {
            return this.pocurl;
        }
        var str = "";
        //safari doesn't support url normalization on xhr request
        if (this.server != "") {
            str += this.scheme + "//" + this.server;
            if (this.port != "") {
                if (this.scheme == "http:" && this.port == "80") {
                    str += "";
                }
                else
                    if (this.scheme == "https:" && this.port == "443") {
                        str += "";
                    }
                    else {
                        str += ":" + this.port;
                    }
            }
        }

        // add the slash portion in ANY case
        str += "/";

        if (this.path != "") {
            str += com.ibm.mm.enabler.utils.Misc.encodePath(this.path, decoded);
        }

        if (!com.ibm.mm.enabler.utils.Misc.isEmpty(this.parameters)) {
            str += "?" + (decoded ? this._parametersToQuery(this.parameters) : dojo.objectToQuery(this.parameters));
        }

        if (this.anchor != "") {
            str += "#" + this.anchor;
        }

        return str;
    },
    _parametersToQuery: function(params){
        var str = "";
        // concatenation function (defined outside of the for-loop)
        var fn = function(value){
            str += k + "=" + value + "&";
        };
        for (var k in params) {
            // concatenate parameters
            if (dojo.isArray(params[k])) {
                dojo.forEach(params[k], fn);
            }
            else {
                fn(params[k]);
            }
        }
        // remove trailing ampersand
        if (str.lastIndexOf('&') === str.length - 1) {
            str = str.substr(0, str.length - 1);
        }
        return str;
    },
    _isAbsolute: function(){
        return this._absoluteURL;
    },
    _extractScheme: function(/*String*/urlString){
        // important check as :// may appear as query parameter and then below logic doesn't work in case it is a relative URL
        var isRelative = urlString.indexOf("/") === 0;
        if (isRelative) {
            return window.location.protocol; // location.protocol returns the protocol like http: or https:
        }
        var indexOfScheme = urlString.indexOf("://");
        if (indexOfScheme == -1) {
            this._absoluteURL = false;
            return window.location.protocol; // location.protocol returns the protocol like http: or https:
        }
        this._absoluteURL = true;
        return urlString.substring(0, indexOfScheme + 1);
    },
    _extractServer: function(/*String*/urlString){
        var indexOfScheme = urlString.indexOf(this.scheme);
        var retVal = "";
        if (indexOfScheme === 0) {
            var serverAndPort;
            var indexOfSlash = urlString.indexOf("/", indexOfScheme + this.scheme.length + 2);
            if (indexOfSlash != -1) {
                serverAndPort = urlString.substring(indexOfScheme + this.scheme.length + 2, indexOfSlash);
            }
            else {
                serverAndPort = urlString.substring(indexOfScheme + this.scheme.length + 2);
            }
            retVal = serverAndPort.split(":")[0];
        }
        else {
            var hostname = window.location.hostname;
            retVal = this._isIPv6(hostname) ? "[" + hostname + "]" : hostname;
        }

        return retVal;
    },
    _extractPort: function(/*String*/urlString){
        var indexOfServer = urlString.indexOf(this.server);
        var retVal = "";
        if (indexOfServer >= 0) {
            var serverAndPort;
            var indexOfSlash = urlString.indexOf("/", indexOfServer);
            if (indexOfSlash != -1) {
                serverAndPort = urlString.substring(indexOfServer, indexOfSlash);
            }
            else {
                serverAndPort = urlString.substring(indexOfServer);
            }
            var serverAndPortParts = serverAndPort.split(":");
            if (serverAndPortParts.length > 1) {
                retVal = serverAndPortParts[1];
            }
        }

        if (retVal == "") {
            if (urlString.indexOf("/") === 0) {
                retVal = window.location.port;
            }
            else {
                retVal = "";
            }
        }

        return retVal;
    },
    _extractPath: function( /*String*/urlString){
        var indexOfScheme = urlString.indexOf(this.scheme);
        var startIndex = 0;

        if (indexOfScheme === 0) {
            startIndex = this.scheme.length + 2;
        }

        var retVal = "";

        var indexOfSlash = urlString.indexOf("/", startIndex);
        var indexOfQuery = urlString.indexOf("?");
        var indexOfHash = urlString.lastIndexOf("#");
        if (indexOfQuery >= 0) {
            retVal = urlString.substring(indexOfSlash + 1, indexOfQuery);
        }
        else {
            if (indexOfHash >= 0 && indexOfSlash != -1) {
                retVal = urlString.substring(indexOfSlash + 1, indexOfHash);
            }
            else
                if (indexOfSlash != -1) {
                    retVal = urlString.substring(indexOfSlash + 1);
                }
        }

        return retVal;
    },
    _extractQuery: function( /*String*/urlString){
        var retVal = {};
        var urlParts = urlString.split("?");

        if (urlParts.length > 1) {
            retVal = dojo.queryToObject(urlParts[1].split("#")[0]);
        }

        return retVal;
    },
    _extractAnchor: function( /*String*/urlString){
        var retVal = "";
        var urlParts = urlString.split("#");

        if (urlParts.length > 1) {
            retVal = urlParts[urlParts.length - 1];
        }

        return retVal;
    },
    _isIPv6: function(hostname){
        // only IPv6 addresses contain colons
        // note: the input hostname MUST NOT contain a port
        return hostname.indexOf(":") != -1;
    },

    _equalsServer: function(hostname){
        // consider square brackets in IPv6 case
        return this.server == (this._isIPv6(hostname) ? "[" + hostname + "]" : hostname);
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.utils.URLHelper"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.utils.URLHelper"] = true;
dojo.provide("com.ibm.mm.enabler.utils.URLHelper");




dojo.declare("com.ibm.mm.enabler.utils.URLHelperImpl", com.ibm.mashups.enabler.utils.URLHelper, {
    rewriteURL: function(targetUrl){
        var _targetURL = new com.ibm.mm.enabler.utils.HttpUrl(targetUrl);
        return _targetURL.toProxifiedString();
    }
});

com.ibm.mashups.enabler.utils.URLHelper = new com.ibm.mm.enabler.utils.URLHelperImpl();
com.ibm.mm.enabler.utils.URLHelper = com.ibm.mashups.enabler.utils.URLHelper;

}

if(!dojo._hasResource["com.ibm.mashups.enabler.utils.URLHelper"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.utils.URLHelper"] = true;
dojo.provide("com.ibm.mashups.enabler.utils.URLHelper");





}

if(!dojo._hasResource["com.ibm.mm.enabler.services.ConfigObjectExtendedImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.services.ConfigObjectExtendedImpl"] = true;
dojo.provide("com.ibm.mm.enabler.services.ConfigObjectExtendedImpl");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module Base
 *
 * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
 * Any number that is smaller causes this class to be written out before any other with a higher number
 * @ibm-dojo-profile-level 40
 */




dojo.declare("com.ibm.mm.enabler.services.ConfigObjectExtendedImpl", [com.ibm.mm.enabler.services.ConfigObjectDefaultImpl], {
    constructor: function(provider, configService) {
        this.valuesArray = null;
        this.provider = provider;
        this.configService = configService;
    },

    _getValue: function(/*string*/provider, /*string*/ name) {
        if (!this.valuesArray) {
            this._loadConfigData(provider);
        }

        return this.valuesArray[name];
    },

    _getValueDeferred: function(/*string*/provider, /*string*/ name) {
        return new com.ibm.mm.enabler.DeferredImpl(this, function(deferred, sync, name) {
            var callBack = deferred.getFinishedCallback();
            if (!this.valuesArray) {
                // lazy load, to support dojo layer build
                dojo["require"]("com.ibm.mashups.enabler.xml.XPath"); // JSLINT-IGNORE: This needs to be done to allow modularization and not break the layer build
                dojo["require"]("com.ibm.mashups.enabler.model.url.ModelUrlFactory"); // JSLINT-IGNORE: This needs to be done to allow modularization and not break the layer build
                dojo["require"]("com.ibm.mm.enabler.services.ModelRestServiceRequest"); // JSLINT-IGNORE: This needs to be done to allow modularization and not break the layer build
                var providerCheck = "ConfigProvider." + provider;
                var provider2 = ibmConfig[providerCheck];
                if ((typeof provider2 != "undefined") || (provider2 !== null)) {
                    provider = provider2;
                }
                var myUrl = com.ibm.mashups.enabler.model.url.ModelUrlFactory.createModelURL(com.ibm.mashups.enabler.model.url.ModelUrlFactory.CONFIG_URL, this);
                myUrl.setSchemeSpecificPart("/" + provider + "/*");

                var serviceReq = new com.ibm.mm.enabler.services.ModelRestServiceRequest(myUrl, null, null, false, sync);
                var me = this;
                serviceReq.read(function(type, data, xhr, args) {
                	if(!me.valuesArray) {
                		me.valuesArray = {};
                	}
                    var configXmls = com.ibm.mashups.enabler.xml.XPath.evaluateXPath("//atom:entry/atom:content/preferences/root/node/map/*", data, me.ns);
                    if (configXmls && configXmls.length > 0) {
                        for (var i = 0, l = configXmls.length; i < l; i++) {
                            var key = configXmls[i].getAttribute("key");
                            var value = configXmls[i].getAttribute("value");
                            me.valuesArray[key] = value;
                        }
                    }
                    if (me.valuesArray[name] && callBack) {
                        callBack(me.valuesArray[name], com.ibm.mm.enabler.model.HttpStatusCodes.HTTP_OK, deferred.getFinishedCallbackParameters());
                    }
                });
            }
            else if (this.valuesArray[name] && callBack) {
                callBack(this.valuesArray[name], com.ibm.mm.enabler.model.HttpStatusCodes.HTTP_OK, deferred.getFinishedCallbackParameters());
            }
            return this.valuesArray && this.valuesArray[name];
        }, name);
    },

    _loadConfigData: function(/*string*/provider) {
        // lazy load, to support dojo layer build
        dojo["require"]("com.ibm.mashups.enabler.xml.XPath"); // JSLINT-IGNORE: This needs to be done to allow modularization and not break the layer build
        dojo["require"]("com.ibm.mashups.enabler.model.url.ModelUrlFactory"); // JSLINT-IGNORE: This needs to be done to allow modularization and not break the layer build
        dojo["require"]("com.ibm.mm.enabler.services.ModelRestServiceRequest"); // JSLINT-IGNORE: This needs to be done to allow modularization and not break the layer build
        var providerCheck = "ConfigProvider." + provider;

        var provider2 = ibmConfig[providerCheck];
        if ((typeof provider2 != "undefined") || (provider2 !== null)) {
            provider = provider2;
        }

        var ret = {};
        var myUrl = com.ibm.mashups.enabler.model.url.ModelUrlFactory.createModelURL(com.ibm.mashups.enabler.model.url.ModelUrlFactory.CONFIG_URL, this);
        myUrl.setSchemeSpecificPart("/" + provider + "/*");

        var serviceReq = new com.ibm.mm.enabler.services.ModelRestServiceRequest(myUrl, null, null, false, true);
        var me = this;
        serviceReq.read(function(type, data, xhr, args) {
            var configXmls = com.ibm.mashups.enabler.xml.XPath.evaluateXPath("//atom:entry/atom:content/preferences/root/node/map/*", data, me.ns);
            if (configXmls && configXmls.length > 0) {
                for (var i = 0; i < configXmls.length; i++) {
                    var name = configXmls[i].getAttribute("key");
                    var value = configXmls[i].getAttribute("value");
                    ret[name] = value;
                }
            }
        });

        this.valuesArray = ret;
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.strategy.Strategy"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.strategy.Strategy"] = true;
dojo.provide("com.ibm.mashups.enabler.strategy.Strategy");

/**
 * Interface that acts as base interface for all strategies. It can be set on
 * models to define the behavior of the model, i.e. how resources are loaded
 * from the server.
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.strategy.Strategy", null, {});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.Model_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.Model_API"] = true;
dojo.provide("com.ibm.mashups.enabler.model.Model_API");
dojo.provide("com.ibm.mashups.enabler.model.Model");



/**
 * Base class for all models
 *
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.model.Model", null, {
    /**
     * Sets the specified array of strategies or in case none has been
     * defined falls back to the default strategy
     * @param {com.ibm.mashups.enabler.strategy.Strategy[]}  strategy    array of strategies to set;
     *                                  may be <code>null</code>
     * @type void
     */
    setStrategy : function(strategy) {
    },

    /**
     * Returns the array of strategies which are in use
     * @return {com.ibm.mashups.enabler.strategy.Strategy[]} array of strategies in use, <code>null</code> if no
     *                      strategies are in use
     */
    getStrategies : function() {
    },

    /**
     * Returns the specified strategy
     * @param {strategy} strategy class name or array index of strategy
     * @return {com.ibm.mashups.enabler.strategy.Strategy} strategy in use, <code>null</code> if no
     * strategy with the specified type is in use
     * @ibm-spi
     */
    getStrategy : function(strategy) {
    },

    /**
     * Adds a strategy to the strategies array
     * @param {com.ibm.mashups.enabler.strategy.Strategy} strategy strategy to add; must not be <code>null</code>
     * @return {int} index where the strategy was added in the strategies array
     */
    addStrategy : function(strategy) {
    },

    /**
     * Removes the specified strategy
     * @param {strategy} strategy class name or array index of the strategy; must not be
     * <code>null</code>
     * @type void
     */
    removeStrategy : function(strategy) {
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.Model"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.Model"] = true;
dojo.provide("com.ibm.mashups.enabler.model.Model");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.strategy.NoCacheStrategy"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.strategy.NoCacheStrategy"] = true;
dojo.provide("com.ibm.mashups.enabler.strategy.NoCacheStrategy");



/**
 * Interface to control, if caching is used for obtaining model artifacts
 *
 * @since 3.0
 *
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.strategy.NoCacheStrategy", com.ibm.mashups.enabler.strategy.Strategy, {
    /**
     * @private
     */
    _apply: function(restRequest) {
        // this is the spec way, but nobody cares. Try it yourself: http://www.mnot.net/javascript/xmlhttprequest/cache.html
        restRequest.setHeader("Pragma", "no-cache");
        restRequest.setHeader("Cache-Control", "no-cache");
        // This works on all major browsers even though it is not the spec way
        restRequest.setHeader("If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 GMT");
        // the only other solution is to use the existing parameter solution (pragma=no-cache) or something like dojo with a random parameter
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.model.ModelImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.ModelImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.ModelImpl");









dojo.declare("com.ibm.mm.enabler.model.ModelImpl", com.ibm.mashups.enabler.model.Model, {

    /**
     * @private
     */
    // FIXME: use _strategies
    strategy: null,

    constructor: function() {
        // messages
        this.modelMessages = dojo.i18n.getLocalization("com.ibm.mm.enabler", "modelMessages");
    },

    setStrategy: function(strategy) {
        if (strategy === null || typeof strategy == 'undefined') {
            this.strategy = null;
        }
        else if (com.ibm.mm.enabler.utils.Misc.isInstanceOf(strategy, Array)) {
            if (strategy.length > 0) {
                this.strategy = [];
                dojo.forEach(strategy, function(item, idx, arr) {
                    this.strategy.push(item);
                    this._preprocessStrategy(item);
                }, this);
            }
        }
        else {
            this.strategy = [strategy];
            this._preprocessStrategy(strategy);
        }
    },

    getStrategies: function() {
        // FIXME: expose copy of array
        return this.strategy || [];
    },

    addStrategy: function(strategy) {
        if (strategy === null || typeof strategy == 'undefined') {
            throw new Error(this.modelMessages.E_PARAM_ISNULL_0);
        }

        if (null === this.strategy) {
            // null strategy array
            this.strategy = [];
        }
        // do preprocessing of strategies
        this._preprocessStrategy(strategy);

        // potentially replace existing strategy of same type
        for (var i = 0, l = this.strategy.length; i < l; i++) {
            // only dojo objects have declaredClass
            if (this.strategy[i].declaredClass) {
                if (strategy instanceof (dojo.getObject(this.strategy[i].declaredClass))) {
                    this.strategy[i] = strategy;
                    return i;
                }
            }
        }
        return (this.strategy.push(strategy) - 1);
    },

    removeStrategy: function(s) {
        if (s === null || typeof s == 'undefined') {
            throw new Error(this.modelMessages.E_PARAM_ISNULL_0);
        }

        if (!this.strategy) {
            return;
        }
        else if (dojo.isString(s)) {
            s = this._getIndexOfStrategyByType(s);
        }
        if (!isNaN(s) && (s < this.strategy.length) && (s >= 0)) {
            this.strategy.splice(s, 1 + s);
        }
    },

    getStrategy: function(s) {
        if (!this.strategy) {
            return null;
        }
        else if (dojo.isString(s)) {
            return this._findStrategyByType(s);
        }
        else {
            if (!isNaN(s) && (s < this.strategy.length) && (s >= 0)) {
                return this.strategy[s];
            }
            else {
                return null;
            }
        }
    },

    _findStrategyByType: function(type) {
        var i = this._getIndexOfStrategyByType(type);
        return i >= 0 ? this.strategy[i] : null;
    },

    _getIndexOfStrategyByType: function(type) {
        if (this.strategy) {
            for (var i = 0, l = this.strategy.length; i < l; i++) {
                // only dojo objects have declaredClass
                if (this.strategy[i].declaredClass) {
                    if (type == this.strategy[i].declaredClass) {
                        return i;
                    }
                }
            }
        }
        return -1;
    },

    _preprocessStrategy: function(s) {
        if (com.ibm.mm.enabler.utils.Misc.isInstanceOf(s, com.ibm.mashups.enabler.strategy.NoCacheStrategy)) {
            if (dojo.isFunction(this.invalidate)) {
                this.invalidate();
            }
        }
    }
});


}

if(!dojo._hasResource["com.ibm.mm.enabler.services.ModelRestServiceRequest"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.services.ModelRestServiceRequest"] = true;
dojo.provide("com.ibm.mm.enabler.services.ModelRestServiceRequest");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need
 * to define the @ibm-module so that the build process is picking it up
 * @ibm-module Base
 *
 * This value defines the order in which the packages should be printed out into
 * the dojo profile. Default is 100. Any number that is smaller causes this
 * class to be written out before any other with a higher number
 * @ibm-dojo-profile-level 50
 */










dojo.declare("com.ibm.mm.enabler.services.ModelRestServiceRequest", null, {
    REQUEST_METHOD_POST: "POST",
    REQUEST_METHOD_PUT: "PUT",
    REQUEST_METHOD_DELETE: "DELETE",
    POST_ACTION_HEADER: "X-Method-Override",
    MODIFICATION_COOKIE: "modified.id",

    constructor: function( /* HttpUrl */feedlocation, /* HTMLFormElement? */ formNode, /* Function? */ formFilter, /* boolean? */ textOnly, /* boolean? */ sync) {
        if (com.ibm.mm.enabler.services.ModelRestServiceRequestStatic.getXRequestDigest()) {
            feedlocation.setParameter("digest", com.ibm.mm.enabler.services.ModelRestServiceRequestStatic.getXRequestDigest());
        }
        this._feedURI = feedlocation.toProxifiedString();
        this._textOnly = textOnly;

        if (textOnly) {
            this._handleAs = "text";
        } else {
            this._handleAs = "xml";
        }

        this._sync = sync;
        this._formNode = formNode;
        this._formFilter = formFilter;
        this._config = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
        this._headers = {};
        this.logoutVerificationForRaw = false;

        // Make sure this isn't undefined.
        if (!this._sync) {
            this._sync = false;
        }
    },
    setHandleAs: function(handleAs) {
        if (handleAs == "atom") {
            this._handleAs = "xml";
        } else {
            this._handleAs = handleAs;
        }
    },
    setHeader: function(name, value) {
        this._headers[name] = value;
    },
    enableLogoutVerificationForRawRetrieval: function() {
        this.logoutVerificationForRaw = true;
    },

    // summary: Sends a request to one of the Portal REST Services and handles
    // the response.
    // description: Create a new instance of this object for every REST service
    // request that is
    // sent. The URL is passed in to the constructor. If a form node and form
    // filter is
    // passed into the constructor, the REST service request is handled as a
    // form submit.
    // The request can also be executed synchronously if TRUE is passed into the
    // constructor.
    // In general, only the model implementations should send these requests.

    create: function( /* ibm.atom.Feed */feed, /* Function */ callbackfn, /* Object? */ addtlCallbackFnArguments) {
        // summary: Creates an entry in a feed.
        // description: Creates an entry in a feed. This operation is not
        // implemented in this
        // class. It should be overridden by subclasses and properly implemented
        // if
        // the REST service supports the create operation.
        // feed: the ATOM feed object
        // entry: the ATOM entry to create
        // callbackfn: the function to call when the operation is complete

        this._updateCookie();

        var me = this;
        var args = {
            url: this._feedURI,
            headers: {
// "If-Modified-Since": "Thu, 1 Jan 1970 00:00:00 GMT",
                "Content-Type": "application/atom+xml; charset=utf-8"
            }, // temporary to force the browser to ignore cached requests
            load: function(response, ioArgs) {

                var xhr = ioArgs.xhr;
                var data = response;

                var xrd = xhr.getResponseHeader("X-Request-Digest");
                if (xrd !== null) {
                    com.ibm.mm.enabler.services.ModelRestServiceRequestStatic.setXRequestDigest(xrd);
                }

                var contentType = xhr.getResponseHeader("Content-Type");
                if (typeof contentType != "undefined" && contentType !== null && contentType.indexOf("text/html") >= 0) {
                    me._doLogin();

                    return;
                }

                if (dojo.isIE) {
                    data = dojox.xml.parser.parse(xhr.responseText);
                }
                callbackfn(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_LOAD, data, xhr, addtlCallbackFnArguments);
            },
            error: function(response, ioArgs) {
                var xhr = ioArgs.xhr;
                var status = xhr.status;

                // Check whether we are having an authorization problem
                if (status == 401) {
                    me._doLogin();
                    return;
                }

                callbackfn(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_ERROR, null, xhr, addtlCallbackFnArguments);
            },
            sync: this._sync,
            postData: feed.toString(),
            handleAs: this._handleAs
        };

		dojo.rawXhrPost(args);
    },
    read: function( /* Function? */callbackfn, /* Object? */ addtlCallbackFnArguments) {
        // summary: Read the ATOM feed provided by the REST service.
        // description: If textOnly is set to true, the ATOM feed is returned as
        // text and
        // passed in as a single argument to the specified callback function.
        // Otherwise, the ATOM feed is parsed into an {@link ibm.atom.Feed}
        // object
        // and passed into the callback function along with the original XML
        // Document
        // Object Model object.
        // callbackfn: the function to call when the operation is complete (only
        // valid if
        // sync is false)
        // addtlCallbackFnArguments: any arguments to pass through to the
        // callback function
        if (this._textOnly) {
            this._retrieveRawFeed(callbackfn, addtlCallbackFnArguments);
        }
        else {
            this._retrieve(callbackfn, addtlCallbackFnArguments);
        }
    },

    update: function( /* ibm.atom.Feed */feed, /* Function */ callbackfn, /* Object? */ addtlCallbackFnArguments) {
        // summary: Updates an entry in a feed.
        // description: Updates an entry in a feed. This operation is not
        // implemented in this
        // class. It should be overridden by subclasses and properly implemented
        // if the
        // REST service supports the update operation.
        // feed: the ATOM feed object
        // entry: the ATOM entry to create
        // callbackfn: the function to call when the operation is complete
        this._updateCookie();
        var me = this;
        var args = {
            url: this._feedURI,
            load: function(response, ioArgs) {
                var xhr = ioArgs.xhr;

                var xrd = xhr.getResponseHeader("X-Request-Digest");
                if (xrd !== null) {
                    com.ibm.mm.enabler.services.ModelRestServiceRequestStatic.setXRequestDigest(xrd);
                }

                var contentType = xhr.getResponseHeader("Content-Type");

                if (typeof contentType != "undefined" && contentType !== null && contentType.indexOf("text/html") >= 0) {
                    me._doLogin();
                    return;
                }

// this seems to be fixed with dojo 1.4.1 ... WTF ? Seems or IS ???
// if (dojo.isIE < 7) {
// data = dojox.xml.parser.parse(xhr.responseText,"application/xml");
// }
                dojo.partial(callbackfn)(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_LOAD, response, xhr, addtlCallbackFnArguments);
            },
            error: function(response, ioArgs) {
                var xhr = ioArgs.xhr;
                var status = xhr.status;

                // Check whether we are having an authorization problem
                if (status == 401) {
                    me._doLogin();
                    return;
                }

                dojo.partial(callbackfn)(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_ERROR, null, xhr, addtlCallbackFnArguments);
            },
            sync: this._sync,
            handleAs: this._handleAs
        };
        var requestHeaders = {
// "If-Modified-Since": "Thu, 1 Jan 1970 00:00:00 GMT",
            "Content-Type": "application/atom+xml; charset=utf-8"
        };

        var mpHandler = com.ibm.mashups.enabler.io.XHRMultipartFactory.create();
        var inTrans = mpHandler.isTransaction();
        // we verify for sync here as well because we know that the transactions
        // gets aborted by the multipart processing and hence we can do the PUT
        // right away
        if (com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.TUNNEL_MODE) === true && (!inTrans || this._sync)) {
            requestHeaders[this.POST_ACTION_HEADER] = this.REQUEST_METHOD_PUT;
            args.headers = requestHeaders;
            args.postData = feed;
            dojo.rawXhrPost(args);
        }
        else {
            args.putData = feed;
            args.headers = requestHeaders;
            dojo.rawXhrPut(args);
        }
    },
    remove: function(/* Function */callbackfn, /* Object? */ addtlCallbackFnArguments) {
        // summary: Removes an entry from a feed.
        // description: Removes an entry from a feed. This operation is not
        // implemented in this
        // class. It should be overridden by subclasses and properly implemented
        // if the
        // REST service supports the remove operation.
        // feed: the ATOM feed object
        // entry: the ATOM entry to create
        // callbackfn: the function to call when the operation is complete
        this._updateCookie();
        var me = this;
        var args = {
            url: this._feedURI,
            load: function(response, ioArgs) {
                var type = com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_LOAD;
                var data = response;

                var xhr = ioArgs.xhr;

                var xrd = xhr.getResponseHeader("X-Request-Digest");
                if (xrd !== null) {
                    com.ibm.mm.enabler.services.ModelRestServiceRequestStatic.setXRequestDigest(xrd);
                }

                var contentType = xhr.getResponseHeader("Content-Type");

                if (typeof contentType != "undefined" && contentType !== null && contentType.indexOf("text/html") >= 0) {
                    me._doLogin();

                    return;
                }

                if (dojo.isIE) {
                    data = dojox.xml.parser.parse(xhr.responseText);
                }
                callbackfn(type, data, xhr, addtlCallbackFnArguments);
            },
            error: function(response, ioArgs) {
                var xhr = ioArgs.xhr;
                var status = xhr.status;

                // Check whether we are having an authorization problem
                if (status == 401) {
                    me._doLogin();
                    return;
                }

                callbackfn(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_ERROR, null, xhr, addtlCallbackFnArguments);
            },
            sync: this._sync,
            handleAs: this._handleAs
        };
        var requestHeaders = {
// "If-Modified-Since": "Thu, 1 Jan 1970 00:00:00 GMT",
            "Content-Type": "application/atom+xml"
        };
        if (com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.TUNNEL_MODE) === true) {
            requestHeaders[this.POST_ACTION_HEADER] = this.REQUEST_METHOD_DELETE;
            args.headers = requestHeaders;
            dojo.rawXhrPost(args);
        }
        else {
            args.headers = requestHeaders;
            dojo.xhrDelete(args);
        }
    },
    _retrieveRawFeed: function(callbackfn, callbackargs) {
        var me = this;
        dojo.xhrGet({
            url: this._feedURI,
            headers: this._headers,
            load: function(data, ioArgs) {
                var xhr = ioArgs.xhr;

                var xrd = xhr.getResponseHeader("X-Request-Digest");
                if (xrd !== null) {
                    com.ibm.mm.enabler.services.ModelRestServiceRequestStatic.setXRequestDigest(xrd);
                }
                if (me.logoutVerificationForRaw) {
                    // in this case we assume that a X-Request-Digest is always returned from the resolver
                    // if it is not coming back it had to be due to a login challange
                    if (!xrd) {
                        me._doLogin();
                        return;
                    }
                }

                callbackfn(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_LOAD, data, ioArgs.xhr, callbackargs);
            },
            error: function(data, ioArgs) {
                var xhr = ioArgs.xhr;
                var status = xhr.status;

                // Check whether we are having an authorization problem
                if (status == 401) {
                    me._doLogin();
                    return;
                }

                callbackfn(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_ERROR, data, ioArgs.xhr, callbackargs);
            },
            sync: this._sync,
            handleAs: this._handleAs
        });
    },
    _retrieve: function(callbackfn, callbackargs, formNode, formFilter) {
        var content = {};
        // temp my ass
        var mt = "xml"; // temp
        if (dojo.isIE) {
            // content = { "com.ibm.wps.web2.contenttype": "text/xml" };
            mt = "text"; // temp
        }

        var me = this;
        var args = {
            url: this._feedURI,
            content: content,
            headers: this._headers,
            load: function(response, ioArgs) {
                var data = response;
                var xhr = ioArgs.xhr;

                var xrd = xhr.getResponseHeader("X-Request-Digest");
                if (xrd !== null) {
                    com.ibm.mm.enabler.services.ModelRestServiceRequestStatic.setXRequestDigest(xrd);
                }

                var contentType = xhr.getResponseHeader("Content-Type");

                // If the HTML content is returned, this is probably another
                // re-direction so we need to
                // force a full-page refresh.

                if (typeof contentType != "undefined" && contentType !== null && contentType.indexOf("text/html") >= 0) {
                    me._doLogin();

                    return;
                }

                if (dojo.isIE) {
                    var doc = com.ibm.mm.enabler.utils.Dom.createDocument(data);
                    callbackfn(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_LOAD, doc, xhr, callbackargs);
                }
                else {
                    callbackfn(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_LOAD, data, xhr, callbackargs);
                }
            },
            error: function(response, ioArgs) {
                var data = response;
                var xhr = ioArgs.xhr;

                var status = xhr.status;

                // Check whether we are having an authorization problem
                if (status == 401) {
                    me._doLogin();
                    return;
                }

                if (dojo.isIE) {
                    var doc = null;
                    try {
                    	if (data) {
                    		doc = com.ibm.mm.enabler.utils.Dom.createDocument(data);
                    	}
                    }
                    catch (e) {

                    }
                    callbackfn(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_ERROR, doc, xhr, callbackargs);
                }
                else {
                    callbackfn(com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_ERROR, data, xhr, callbackargs);
                }
            },
            sync: this._sync,
            handleAs: mt
        };

        var method = "Get";
        if (this._formNode) {
            args.form = this._formNode;
            method = "Post";
        }

        if (this._formFilter) {
            args.formFilter = this._formFilter;
        }
        dojo["xhr" + method](args);
    },

    _updateCookie: function() {
        var dt = new Date();
        var properties = {};
        properties.path = this._config.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT);
        dojo.cookie(this.MODIFICATION_COOKIE, dt.getTime(), properties);
    },
    _doLogin: function() {
        // lazy load, to support dojo layer build
        dojo["require"]("com.ibm.mashups.enabler.model.state.NavigationStateModelFactory"); // JSLINT-IGNORE:
                                                                                            // This
                                                                                            // needs
                                                                                            // to
                                                                                            // be
                                                                                            // done
                                                                                            // to
                                                                                            // allow
                                                                                            // modularization
                                                                                            // and
                                                                                            // not
                                                                                            // break
                                                                                            // the
                                                                                            // layer
                                                                                            // build
        dojo["require"]("com.ibm.mashups.enabler.model.state.UrlGeneratorFactory"); // JSLINT-IGNORE:
                                                                                    // This
                                                                                    // needs
                                                                                    // to
                                                                                    // be
                                                                                    // done
                                                                                    // to
                                                                                    // allow
                                                                                    // modularization
                                                                                    // and
                                                                                    // not
                                                                                    // break
                                                                                    // the
                                                                                    // layer
                                                                                    // build

        var pid = null;
        var url = document.location.href;

        // get full page refresh redirect url
        var cb = function(url) {
            if (url) {
                top.location.href = url;
            }
        };
        var navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
        com.ibm.mashups.enabler.model.state.UrlGeneratorFactory.getURLGenerator().getUrl(navStateModel, cb, {
            nohash: "true"
        });
    },
    toString: function() {
        return this._feedURI;
    }
});

com.ibm.mm.enabler.services.ModelRestServiceRequestStatic = {
    xRequestDigest : null,

    getXRequestDigest: function() {
        if ((null === this.xRequestDigest) && (ibmConfig["com.ibm.resolver.digest"])) {
            this.xRequestDigest = ibmConfig["com.ibm.resolver.digest"];
        }
        return this.xRequestDigest;
    },
    setXRequestDigest: function(digest) {
        this.xRequestDigest = digest;
    },
    invalidateXRequestDigest: function() {
        // update digest
        var dt = new Date();
        var digest = dt.getTime();
        this.setXRequestDigest(digest);
        // update cookie
        var properties = {};
        var cs = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
        properties.path = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT);
        dojo.cookie("modified.id", digest, properties);
    }
};

// constants
com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_LOAD = "load";
com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_ERROR = "error";

dojo.declare("com.ibm.mm.enabler.services.XHRModelHeaderExtensionImpl", null, {
    constructor: function() {
        this.originalDojoXHR = dojo.xhr;

        dojo.xhr = dojo.hitch(this, function(/* String */method, /* dojo.__XhrArgs */ args, /* Boolean */ hasBody) {
            if (!args.headers) {
                args.headers = {};
            }
            args.headers["X-IBM-XHR"] = "true";

            var ret = this.originalDojoXHR(method, args, hasBody);
            return ret;
        });
    }
});


com.ibm.mm.enabler.services.XHRModelHeaderExtension = new com.ibm.mm.enabler.services.XHRModelHeaderExtensionImpl();


}

if(!dojo._hasResource["com.ibm.mm.enabler.endpoints.XHREndpointExtensionImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.endpoints.XHREndpointExtensionImpl"] = true;
dojo.provide("com.ibm.mm.enabler.endpoints.XHREndpointExtensionImpl");




dojo.declare("com.ibm.mm.enabler.endpoints.XHREndpointExtensionImpl", null, {
    constructor: function(){
        this.originalDojoXHR = dojo.xhr;

        dojo.xhr = dojo.hitch(this, function(/* String */ method, /* dojo.__XhrArgs */ args, /* Boolean */ hasBody) {
            var url = args.url;
            var url2 = com.ibm.mm.enabler.EndpointUtils.checkForEndpoints(url);
            url2 = url2 || null;
            if (url2 !== null) {
                args.url = url2;
            }

            var ret = this.originalDojoXHR(method, args, hasBody);
            return ret;
        });
    }
});

com.ibm.mm.enabler.endpoints.XHREndpointExtension = new com.ibm.mm.enabler.endpoints.XHREndpointExtensionImpl();

}

if(!dojo._hasResource["com.ibm.mm.enabler.services.ConfigServiceExtendedImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.services.ConfigServiceExtendedImpl"] = true;
dojo.provide("com.ibm.mm.enabler.services.ConfigServiceExtendedImpl");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module Base
 *
 * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
 * Any number that is smaller causes this class to be written out before any other with a higher number
 * @ibm-dojo-profile-level 40
 */

// inject this service into the ServiceManager at the end. Therefore we have to require the implementation










dojo.declare("com.ibm.mm.enabler.services.ConfigServiceExtendedImpl", [com.ibm.mm.enabler.services.ConfigServiceDefaultImpl], {
    constructor: function() {
    },

    _getConfigObject: function(/*string*/configProvider) {
        if (!ibmConfig["CO_" + configProvider]) {
            var co = new com.ibm.mm.enabler.services.ConfigObjectExtendedImpl(configProvider, this);
            ibmConfig["CO_" + configProvider] = co;
        }

        return ibmConfig["CO_" + configProvider];
    },

    _getConfigProviderNames: function() {
        // lazy load, to support dojo layer build
        dojo["require"]("com.ibm.mashups.enabler.model.url.ModelUrlFactory"); // JSLINT-IGNORE: This needs to be done to allow modularization and not break the layer build

        var ret = [];
        ret.push("all");

        var myUrl = com.ibm.mashups.enabler.model.url.ModelUrlFactory.createModelURL(com.ibm.mashups.enabler.model.url.ModelUrlFactory.CONFIG_URL, this);
        myUrl.setSchemeSpecificPart("/*");
        myUrl.setParameter("rep", "compact");

        var serviceReq = new com.ibm.mm.enabler.services.ModelRestServiceRequest(myUrl, null, null, false, true);
        var me = this;
        serviceReq.read(function(type, data, xhr, args) {
            var configXmls = com.ibm.mashups.enabler.xml.XPath.evaluateXPath("//atom:entry/atom:id", data, me.ns);
            if (configXmls && configXmls.length > 0) {
                for (var i = 0, l = configXmls.length; i < l; i++) {
                    var configXml = com.ibm.mm.enabler.utils.Dom.textContent(configXmls[i]);
                    var lastSlash = configXml.indexOf("/", 9);
                    configXml = configXml.substring(8, lastSlash).trim();
                    for (var config in ibmConfig) {
                        if (ibmConfig[config] === configXml) {
                            configXml = config.substring(15);
                        }
                    }
                    ret.push(configXml);
                }
            }
        });


        return ret;
    }
});

com.ibm.mashups.services.ServiceManager.setService("configService", "com.ibm.mm.enabler.services.ConfigServiceExtendedImpl");

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.ServiceDocumentModel_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.ServiceDocumentModel_API"] = true;
dojo.provide("com.ibm.mashups.enabler.model.ServiceDocumentModel_API");
dojo.provide("com.ibm.mashups.enabler.model.ServiceDocumentModel");

/**
 * An singleton that represents the Service Document
 *
 * @ibm-spi
 * @ibm-module Base
 *
 * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
 * Any number that is smaller causes this class to be written out before any other with a higher number
 * @ibm-dojo-profile-level 50
 */

dojo.declare("com.ibm.mashups.enabler.model.ServiceDocumentModel", null,
    {
        /**
         * Constant representing the navigation service
         * @type {String}
         */
        SERVICE_NAVIGATION: "navigation",
        /**
         * Constant representing the space navigation service
         * @type {String}
         */
        SERVICE_SPACE_NAVIGATION: "space-navigation",
        /**
         * Constant representing the shared navigation service
         * @type {String}
         */
        SERVICE_SHARED_NAVIGATION: "shared-navigation",
        /**
         * Constant representing the content service
         * @type {String}
         */
        SERVICE_CONTENT: "content",
        /**
         * Constant representing the catalog service
         * @type {String}
         */
        SERVICE_CATALOG: "catalog",
        /**
         * Constant representing the resource service
         * @type {String}
         */
        SERVICE_RESOURCE: "resource",
        /**
         * Constant representing the widget service
         * @type {String}
         */
        SERVICE_WIDGET: "widget",
        /**
         * Constant representing the theme service
         * @type {String}
         */
        SERVICE_THEME: "theme",
        /**
         * Constant representing the user service
         * @type {String}
         */
        SERVICE_USER: "user",
        /**
         * Constant representing generic model services
         * @type {String}
         */
        SERVICE_MODEL: "model",
        /**
         * Constant representing multipart services
         * @type {String}
         */
        SERVICE_MULTIPART: "multipart",
        /**
         * Constant representing the huffman encoding of multipart services
         * @type {String}
         */
        SERVICE_HUFFMAN: "huffman",
        /**
         * Constant representing the sitemap encoding of multipart services
         * @type {String}
         */
        SERVICE_SITEMAP: "sitemap",
        /**
         * Constant representing the commit handler sitemap encoding of multipart services
         * @type {String}
         */
        SERVICE_SITEMAP_COMMITHANDLER: "commit-handler",
        /**
         * Constant representing the composite application service
         * @type {String}
         */
        SERVICE_COMPOSITE: "composite-applications",
        /**
         * Constant representing the space service
         * @type {String}
         */
        SERVICE_SPACE: "application",
        /**
         * Constant representing the space favorites service
         * @type {String}
         */
        SERVICE_SPACE_FAVORITE: "application-favorite",
        /**
         * Constant representing the template service
         * @type {String}
         */
        SERVICE_TEMPLATE: "template",
        /**
         * Constant representing the config service
         * @type {String}
         */
        SERVICE_CONFIG: "config",
        /**
         * Constant representing the webdav filestore
         * @type {String}
         */
        SERVICE_FILESTORE: "filestore",
        /**
         * Constant representing generic webdav services
         * @type {String}
         */
        SERVICE_WEBDAV: "webdav",

        /**
         * Invalidates the Service Document Model in order for it to be re-initialized again.
         *
         * @type void
         */
        invalidate: function() {
        },
        /**
         * Returns a two-dimensional array of IDs representing services which are attached to a specific endpoint namespace.
         * The IDs in the second dimension are required to lookup the service data.<br/>
         * Example: [["webdav"],["filestore"]]<br/>
         * Only the combination of both IDs make the service unique and must be used to lookup the service data
         *
         * @Returns {String[][]} A two-dimensional array with the second dimension being a list of IDs which represent the service.
         */
        getModelCollections: function() {
        },
        /**
         * Returns a two-dimensional array of IDs representing services which are attached to mashups specifically.
         * The IDs in the second dimension are required to lookup the service data.<br/>
         * Example: [["webdav"],["filestore"]]<br/>
         * Only the combination of both IDs make the service unique and must be used to lookup the service data
         *
         * @return {String[][]} A two-dimensional array with the second dimension being a list of IDs which represent the service.
         */
        getMashupsCollections: function() {
        },
        /**
         * Returns a JSON object for a given collection link in the service document. Not all elements are mandatory.<br/>
         * JSON format<br/>
         * { id: "the id array",<br/>
         * url :"the url",<br/>
         * template :"the template",<br/>
         * idprefix: "id|oid",<br/>
         * namespaces : { "base" : "base-url", "model" : "model-url", "ext" : "ext-url", "creation-context" : "creation-context-url" },<br/>
         * accept: "accept MIME type",<br/>
         * version: "major.minor"<br/>
         * }<br/>
         * @param {String[]} idArray The ID Array to lookup the service for.
         * @type Object
         * @return {Object} Returns a JSON object for a given collection link in the service document
         */
        getCollectionData: function(idArray) {
        }
    }
);

}

if(!dojo._hasResource["com.ibm.mm.enabler.model.ServiceDocumentModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.ServiceDocumentModel"] = true;
dojo.provide("com.ibm.mm.enabler.model.ServiceDocumentModel");









dojo.declare("com.ibm.mm.enabler.model.ServiceDocumentModelImpl", com.ibm.mashups.enabler.model.ServiceDocumentModel,
    {
        SERVICE_NAVIGATION: "navigation",
        SERVICE_SPACE_NAVIGATION: "space-navigation",
        SERVICE_SHARED_NAVIGATION: "shared-navigation",
        SERVICE_CONTENT: "content",
        SERVICE_CATALOG: "catalog",
        SERVICE_RESOURCE: "resource",
        SERVICE_WIDGET: "widget",
        SERVICE_THEME: "theme",
        SERVICE_USER: "user",
        SERVICE_MODEL: "model",
        SERVICE_MULTIPART: "multipart",
        SERVICE_HUFFMAN: "huffman",
        SERVICE_SITEMAP: "sitemap",
        SERVICE_SITEMAP_COMMITHANDLER: "commit-handler",
        SERVICE_COMPOSITE: "composite-applications",
        SERVICE_SPACE: "application",
        SERVICE_SPACE_FAVORITE: "application-favorite",
        SERVICE_TEMPLATE: "template",
        SERVICE_CONFIG: "config",
        SERVICE_FILESTORE: "filestore",
        SERVICE_WEBDAV: "webdav",

        constructor: function () {
            this.prefix = "service";
            this.ns = { "atom" : "http://www.w3.org/2005/Atom",
                        "app" : "http://www.w3.org/2007/app",
                        "service" : "http://www.ibm.com/xmlns/prod/sw/model/service/1.0"};
            this.xmlData = null;
            this.xmlDataAsString = null;
            this.max_version = null;
            this.cache = [];
        },

        getInstance: function() {
            var instance = com.ibm.mm.enabler.model.ServiceDocumentModelImpl._instance;
            return instance ? instance : (com.ibm.mm.enabler.model.ServiceDocumentModelImpl._instance = new com.ibm.mm.enabler.model.ServiceDocumentModelImpl());
        },

        invalidate: function() {
            this.xmlData = null;
            this.max_version = null;
        },

        _loadAhead: function() {
            // lazy load, to support dojo layer build
            dojo["require"]("com.ibm.mashups.enabler.model.url.ModelUrlFactory"); // JSLINT-IGNORE: This needs to be done to allow modularization and not break the layer build

            if (ibmConfig.servicedocument) {
                if (this.xmlDataAsString != ibmConfig.servicedocument) {
                    this.xmlData = null;
                }
            }
            if (this.xmlData) {
                return;
            }
            if (ibmConfig.servicedocument) {
                this.xmlData = dojox.xml.parser.parse( ibmConfig.servicedocument );
                this.xmlDataAsString = ibmConfig.servicedocument;
            } else {
                var myUrl;
                if (ibmConfig.serviceDocumentUrl) {
                    myUrl = new com.ibm.mm.enabler.utils.HttpUrl(ibmConfig.serviceDocumentUrl);
                } else {
                    myUrl = com.ibm.mashups.enabler.model.url.ModelUrlFactory.createModelURL("service", null);
                    myUrl.setNodes([{
                            value: "collection",
                            isID: false
                        }]);
                }
                var serviceReq = new com.ibm.mm.enabler.services.ModelRestServiceRequest(myUrl, null, null, false, true);
                serviceReq.read(
                    dojo.hitch(this,
                        function (type, data, xhr, args) {
                            if (type == com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_LOAD) {
                                this.xmlData = data;
                            } else if (type == com.ibm.mm.enabler.services.ModelRestServiceRequest.XHR_STATUS_ERROR) {
                                // TODO
                            }
                        }
                    )
                );
            }
            this._fillCache();
        },

        _fillCache: function() {
            this.max_version = null;
            if (ibmConfig.servicedocument_version_max) {
                this.max_version = parseInt(ibmConfig.servicedocument_version_max.replace(/\./g, ""),10);
            }
            var matches = [];
            var i, l, found;
            var expr = "//app:collection";
            var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(expr, this.xmlData, this.ns);
            for (i=0, l = nodes.length; i<l; ++i) {
                found = this._processCollection(i, nodes[i]);
                if (found) {
                    this.cache[this.cache.length] = found;
                }
            }
            expr = "//service:collection";
            nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(expr, this.xmlData, this.ns);
            for (i=0, l = nodes.length; i<l; ++i) {
                found = this._processCollection(i, nodes[i]);
                if (found) {
                    this.cache[this.cache.length] = found;
                }
            }
        },

        /**
        Returns an array of available model ids which are compatible for the enabler runtime
        */
        getModelCollections: function() {
            this._loadAhead();
            var ret = [];
            var count = 0;
            var expr = "//atom:category[@term='enabler-ns-base']";
            var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(expr, this.xmlData, this.ns);
            for (var i=0, l = nodes.length; i<l; ++i) {
                var parent = nodes[i].parentNode;
                var expr2 = "//atom:category[not (@term='enabler-ns-base' or @term='enabler-ns-model' or @term='enabler-ns-ext' or @term='enabler-ns-creationcontext' or @term='mashups')]";
                var nodes2 = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(expr2, parent, this.ns);
                if (nodes2 && nodes2.length>0) {
                    var terms = [];
                    for (var ii=0, ll = nodes2.length; ii<ll; ++ii) {
                        if (nodes2[ii].parentNode==parent) {
                            terms.push(nodes2[ii].getAttribute("term"));
                        }
                    }
                    terms.sort();
                    // verify if already exists(e.g. due to another version)
                    var dup = this._isDuplicate(ret, terms);
                    if (!dup) {
                        ret[count] = terms;
                        count++;
                    }
                }
            }
            return ret;
        },
        _isDuplicate: function(array, newterm) {
            var dup = false;
            for (var ii=0; ii<array.length; ii++) {
                if (array[ii].length==newterm.length) {
                    var equal = true;
                    for (var c=0; c<newterm.length; c++) {
                        if (array[ii][c]!=newterm[c]) {
                            equal = false;
                            break;
                        }
                    }
                    if (equal) {
                        dup = true;
                        break;
                    }
                }
            }
            return dup;
        },
        /**
        Returns an array of available model ids which are compatible for the enabler runtime
        */
        getMashupsCollections: function() {
            this._loadAhead();
            var ret = [];
            var count = 0;
            var expr = "//atom:category[@term='mashups']";
            var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(expr, this.xmlData, this.ns);
            for (var i=0, l = nodes.length; i<l; ++i) {
                var parent = nodes[i].parentNode;
                var expr2 = "//atom:category[not (@term='enabler-ns-base' or @term='enabler-ns-model' or @term='enabler-ns-ext' or @term='enabler-ns-creationcontext' or @term='mashups')]";
                var nodes2 = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(expr2, parent, this.ns);
                if (nodes2 && nodes2.length>0) {
                    var terms = [];
                    for (var ii=0,ll=nodes2.length; ii<ll; ++ii) {
                        if (nodes2[ii].parentNode==parent) {
                            terms.push(nodes2[ii].getAttribute("term"));
                        }
                    }
                    terms.sort();
                    // verify if already exists(e.g. due to another version)
                    var dup = this._isDuplicate(ret, terms);
                    if (!dup) {
                        ret[count] = terms;
                        count++;
                    }
                }
            }
            return ret;
        },
        /**
        Returns a JSON object for a given collection link in the service document. Not all elements are mandatory
        JSON format
        { id: "the id array",
          url :"the url",
          template :"the template",
          idprefix: "id|oid",
          namespaces : { "base" : "base-url", "model" : "model-url", "ext" : "ext-url", "creation-context" : "creation-context-url" },
          accept: "accept MIME type",
          version: "major.minor"
        };
        @param {Array} idArray
        @type Object
        @return {Object} Returns a JSON object for a given collection link in the service document
        */
        getCollectionData: function(idArray) {
            this._loadAhead();
            var ret = {};
            this.xmlData = this.xmlData || null;
            if (!this.xmlData) {
                return ret;
            }
            var ids = [];
            if (dojo.isArray(idArray)) {
                ids = idArray;
            }
            else {
                ids = [idArray];
            }

            ret = this._getCachedValue(ids);
            return ret;
        },
        _getCachedValue: function(ids)
        {
            // try the best match
            var scoreCard = [];
            var i, cl, lo, m, l, scl;
            for (i = 0, cl = this.cache.length; i < cl; i++) {
                var matchIds = this.cache[i].id;
                var score = 0;
                for (j = 0, lo = matchIds.length; j < lo; j++) {
                    if (matchIds[j] == "mashups") {
                        // we prefer the mashups link. therefore we give score for it
                        score += 500;
                    }
                    for (m = 0, l = ids.length; m < l; m++) {
                        if (matchIds[j] == ids[m]) {
                            score += 1000;
                        }
                    }
                }
                var intVersion = parseInt(this.cache[i].version.replace(/\./g, ""),10);
                score += intVersion;
                if (this.max_version && (intVersion>this.max_version)) {
                    score = -1000; // disregard;
                }
                scoreCard[i] = score;
            }
            // see who won
            var winner = -1;
            var winningScore = 1000; // we need at least one matched item, therefore the minimum is 1000 points
            for (i = 0, scl = scoreCard.length; i < scl; i++) {
                if (scoreCard[i] > winningScore) {
                    winner = i;
                    winningScore = scoreCard[i];
                }
            }
            if (winner == -1) {
            	return null;
            }
            return this.cache[winner];
        },
        _processCollection: function(i, node)
        {
            var ret = {};
            // we found a match
            var expr3 = "app:categories//atom:category[@term]";
            var nodes3 = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(expr3, node, this.ns);
            var nodeIDs = [];
            if (nodes3) {
                for (var jj = 0, ll = nodes3.length; jj < ll; jj++) {
                    var term = nodes3[jj].getAttribute('term');
                    if (term.indexOf("enabler-ns-")===0) {
                        continue;
                    }
                    nodeIDs.push(term);
                }
            }
            ret.id = nodeIDs;
            ret.url = node.getAttribute("href");
            ret.version = com.ibm.mm.enabler.utils.Dom.getAttributeWithNS(
                node,"service:version","version",this.ns.service);
            if (!ret.version) {
                ret.version = "1.0";
            }
            ret.template = com.ibm.mm.enabler.utils.Dom.getAttributeWithNS(
                node,"service:template","template",this.ns.service);
            ret.idprefix = "id";
            var ns = {};
            expr3 = "app:categories/atom:category[@term='enabler-ns-base']";
            nodes3 = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(expr3, node, this.ns);
            if (nodes3) {
                ns.base = nodes3.getAttribute("scheme");
                if (ns.base.indexOf("/mashups/")==-1) {
                    ret.idprefix = "oid";
                }
            }
            expr3 = "app:categories/atom:category[@term='enabler-ns-model']";
            nodes3 = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(expr3, node, this.ns);
            if (nodes3) {
                ns.model = nodes3.getAttribute("scheme");
            }
            expr3 = "app:categories/atom:category[@term='enabler-ns-ext']";
            nodes3 = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(expr3, node, this.ns);
            if (nodes3) {
                ns.ext = nodes3.getAttribute("scheme");
            }
            expr3 = "app:categories/atom:category[@term='enabler-ns-creationcontext']";
            nodes3 = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(expr3, node, this.ns);
            if (nodes3) {
                ns["creation-context"] = nodes3.getAttribute("scheme");
            }
            ret.namespaces = ns;
            expr3 = "app:accept";
            nodes3 = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(expr3, node, this.ns);
            if (nodes3) {
                ret.accept = nodes3.firstChild.nodeValue;
            }
            return ret;
        }
    }
);

com.ibm.mm.enabler.model.ServiceDocumentModel = com.ibm.mm.enabler.model.ServiceDocumentModelImpl.prototype.getInstance();
com.ibm.mashups.enabler.model.ServiceDocumentModel = com.ibm.mm.enabler.model.ServiceDocumentModel;

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.ServiceDocumentModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.ServiceDocumentModel"] = true;
dojo.provide("com.ibm.mashups.enabler.model.ServiceDocumentModel");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.Commitable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.Commitable"] = true;
dojo.provide("com.ibm.mashups.enabler.Commitable");



/**
 * An interface that adds methods for checking for changes and appyling them.
 * @since 2.4
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.Commitable", null, {
    /**
     * States whether this object is &quot;dirty&quot;, meaning changes where done on this object.
     * @return {boolean} <tt>true</tt> if changes where made to the object, <tt>false</tt> otherwise.
     */
    isDirty: function(){
        return false;
    },

    /**
    * Commits the modifications applied to this object.<br>
    * @return {DeferredOperation} a deferred object used to start this operation.
    * The return value when executed through the deferred object is <code>null</null>
    */
    commit: function(){
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.DefaultLocalized"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.DefaultLocalized"] = true;
dojo.provide("com.ibm.mashups.enabler.DefaultLocalized");

/**
 * Read-Only interface providing methods to obtain default title, description,
 * and locale
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.DefaultLocalized", null, {

    /**
     * Returns the default locale.<br>
     * <br>
     * @return {String} the default locale; may be <code>null</code>.
     */
    getDefaultLocale: function(){
    },

    /**
     * Returns the default title.
     * @return {String} the default title of this node; may be <code>null</code>.
     */
    getDefaultTitle: function(){
    },

    /**
     * Returns the default description of this object.
     * @return {String} the default description; may be <code>null</code>.
     */
    getDefaultDescription: function(){
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.Iterator"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.Iterator"] = true;
dojo.provide("com.ibm.mashups.enabler.Iterator");

/**
 * Extended iterator interface, which allows iterating over elements
 * in a sequentiell order. It allows to set the starting point of the
 * iteration and exposes the number of elements in the iteration.
 *
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.Iterator", null, {

    /**
     * Returns <tt>true</tt> if the iteration has more elements.
     * @return  {Boolean} <tt>true</tt> if the iterator has more elements,
     *          otherwise <tt>false</tt>.
     */
    hasNext: function(){
    },

    /**
     * Returns the next element in the iteration.  Calling this method
     * repeatedly until the hasNext() method returns false will return
     * each element in the underlying collection exactly once.
     * The cursor position is increased by one. if no element is available
     * at the specified position, <code>null</code> is returned and the
     * position is not changed
     *
     * @returns {Object} the next element in the iteration
     */
    next: function(){
    },

    /**
     * Returns the number of elements in this iterator.
     *
     * @return {com.ibm.mashups.enabler.Deferred} a deferred object used to start this operation. The
     *          return value when executed through the deferred object
     *          is the number of elements in this iterator
     */
    size: function(){
    },

    /**
     * Sets the zero-based position of the cursor, i.e the last
     * element is addressed through size()-1.
     * A position which is out of the bounds of the current iteration
     * is ignored and in this case the position is set to the nearest
     * possible value within valid bounds.
     *
     * @param {int} position    position of the cursor. Defaults to zero
     * @type void
     */
    setCursorPosition: function(position){
    },

    /**
     * Returns the zero-based position of the cursor, i.e. zero for the first element
     *
     * @return {int} the position of the cursor
     */
    getCursorPosition: function(){
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.DeferredIterator_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.DeferredIterator_API"] = true;
dojo.provide("com.ibm.mashups.enabler.DeferredIterator_API");
dojo.provide("com.ibm.mashups.enabler.DeferredIterator");

/**
 * The DeferredIterator can be used to iterate over a list of objects
 * in an asynchronous fashion. The callback handler is called as
 * soon as the next object has been loaded.
 * The start method is only used for the asynchronous aspect of
 * the deferred iterator. For the synchronous aspect the methods
 * such as hasNext() can be called directly.
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.DeferredIterator", [com.ibm.mashups.enabler.Deferred, com.ibm.mashups.enabler.Iterator], {

    /**
     * Sets the handler of the deferred action. It is called when the
     * next object in the list has been loaded and is ready to be processed.
     * @param {Object} callback the callback funtion in the format of <code>Function(object nextElement, Object[] params)</code>. Must not be <code>null</code><br>
     * &nbsp;&nbsp;&nbsp;&nbsp;<b>Callbackparameters</b><br/>
     * &nbsp;&nbsp;&nbsp;&nbsp;<code>nextElement</code> - the next
     * object in the list<br/>
     * &nbsp;&nbsp;&nbsp;&nbsp;<code>params</code> - the parameters
     * passed into the addForEachCallback
     * @param {Object[]} parameters optional array of parameters to be
     * passed on to the callback function
     * @return {com.ibm.mashups.enabler.DeferredIterator} the deferred object
     */
    setForEachCallback: function(callback, parameters){
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.DeferredIteratorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.DeferredIteratorImpl"] = true;
dojo.provide("com.ibm.mm.enabler.DeferredIteratorImpl");




// iterator
dojo.declare("com.ibm.mm.enabler.DeferredIteratorImpl", [com.ibm.mashups.enabler.DeferredIterator, com.ibm.mm.enabler.DeferredImpl], {
    setForEachCallback: function(callback, parameters){
        this.foreachCallback = callback;
        this.foreachCallbackParameters = parameters;
        return this;
    },

    /**
     * there's a typo in this one, keeping it around for backwards compat
     *
     * @param {Object} callback
     * @param {Object} parameters
     */
    setForeachCallback: function(callback, parameters){
        return this.setForEachCallback(callback, parameters);
    },

    getForeachCallback: function(){
        return this.foreachCallback;
    },

    getForeachCallbackParameters: function(){
        return this.foreachCallbackParameters;
    },

    nextFinish: function(entry) {
        if(dojo.isFunction(this.getForeachCallback())) {
            // call callback
            dojo.partial(this.getForeachCallback())(entry, this.getForeachCallbackParameters());
        }
    },

    start: function(sync){
        while (this.hasNext(this, sync)) {
            this.next(this, sync);
        }
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.DeferredIterator"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.DeferredIterator"] = true;
dojo.provide("com.ibm.mashups.enabler.DeferredIterator");







}

if(!dojo._hasResource["com.ibm.mashups.enabler.DeferredOperation_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.DeferredOperation_API"] = true;
dojo.provide("com.ibm.mashups.enabler.DeferredOperation_API");
dojo.provide("com.ibm.mashups.enabler.DeferredOperation");

/**
 * In addition to the Deferred interface, which allows to trigger callbacks after the
 * entire action  has finished, the DeferredOperation interface allows to trigger a
 * callback for each involved operation.
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare( "com.ibm.mashups.enabler.DeferredOperation", [com.ibm.mashups.enabler.Deferred], {

	/**
	 * Mode of operation: retrieving a resource
	 * @type String
	 */
    OPERATION_GET: "GET",

	/**
	 * Mode of operation: creating a resource
	 * @type String
	 */
    OPERATION_CREATE: "CREATE",

	/**
	 * Mode of operation: modifying a resource
	 * @type String
	 */
    OPERATION_MODIFY: "MODIFY",

	/**
	 * Mode of operation: deleting a resource
	 * @type String
	 */
    OPERATION_DELETE: "DELETE",


    /**
     * Sets the handler of the deferred action. The handler is called for each
     * operation the action involves.
     * @param {Object} callback the callback funtion in the format of <code>Function(Object node, string mode, int statusCode, Object[] params)</code>. Must not be <code>null</code><br/>
     * &nbsp;&nbsp;&nbsp;&nbsp;<b>Callbackparameters</b><br/>
     * &nbsp;&nbsp;&nbsp;&nbsp;<code>node</code> - resource object or string id of the
     * related resource, depending on the operation. For example, when a resource is created, the
     * resource itself is returned. In case of a delete operation, the id is returned
     * instead.<br/>
     * &nbsp;&nbsp;&nbsp;&nbsp;<code>mode</code> - the mode of the operation.
     * May be one of <code>OPERATION_GET</code>, <code>OPERATION_CREATE</code>,
     * <code>OPERATION_MODIFY</code>, or <code>OPERATION_DELETE</code>.<br/>
     * &nbsp;&nbsp;&nbsp;&nbsp;<code>statusCode</code> - the overall HTTP status code
     * of the operation.<br/>
     * &nbsp;&nbsp;&nbsp;&nbsp;<code>params</code> - the parameters
     * passed into the callback
     * @param {Object[]} parameters optional array of parameters to be
     * passed on to the callback function. May be <code>null</code>
     * @return {com.ibm.mashups.enabler.DeferredOperation} the deferred object
     */
    setOperationCallback: function(callback, parameters) {
    }
});

com.ibm.mashups.enabler.DeferredOperation.OPERATION_GET = "GET";
com.ibm.mashups.enabler.DeferredOperation.OPERATION_CREATE = "CREATE";
com.ibm.mashups.enabler.DeferredOperation.OPERATION_MODIFY = "MODIFY";
com.ibm.mashups.enabler.DeferredOperation.OPERATION_DELETE = "DELETE";


}

if(!dojo._hasResource["com.ibm.mm.enabler.model.HttpStatusCodes"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.HttpStatusCodes"] = true;
dojo.provide("com.ibm.mm.enabler.model.HttpStatusCodes");
dojo.provide("com.ibm.mm.enabler.model.HttpStatusCodesImpl");

dojo.declare("com.ibm.mm.enabler.model.HttpStatusCodesImpl", null, {
    HTTP_CONTINUE: "100",
    HTTP_SWITCHING_PROTOCOLS: "101",
    HTTP_OK: "200",
    HTTP_CREATED: "201",
    HTTP_BAD_REQUEST: "400",
    HTTP_NOT_FOUND: "404",
    HTTP_REQUEST_TIMEOUT: "408",
    HTTP_INTERNAL_SERVER_ERROR: "500",
    HTTP_SERVICE_UNAVAILABLE: "503"
});

com.ibm.mm.enabler.model.HttpStatusCodes = new com.ibm.mm.enabler.model.HttpStatusCodesImpl();

}

if(!dojo._hasResource["com.ibm.mm.enabler.DeferredOperationImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.DeferredOperationImpl"] = true;
dojo.provide("com.ibm.mm.enabler.DeferredOperationImpl");





// operation
dojo.declare("com.ibm.mm.enabler.DeferredOperationImpl", [com.ibm.mashups.enabler.DeferredOperation, com.ibm.mm.enabler.DeferredImpl], {
    operationCallback: null,
    operationCallbackParameters: null,

    setOperationCallback: function(callback, parameters){
        this.operationCallback = callback;
        this.operationCallbackParameters = parameters;
        return this;
    },

    getOperationCallback: function(){
        return this.operationCallback;
    },

    getOperationCallbackParameters: function(){
        return this.operationCallbackParameters;
    },

    finishOperation: function(result, operation, status) {
        if(dojo.isFunction(this.getOperationCallback())) {
            // call callback

            if(dojo.isOpera && status === 0) {
                status = com.ibm.mm.enabler.model.HttpStatusCodes.HTTP_NOT_FOUND;
            }

            dojo.partial(this.getOperationCallback())(result, operation, status, this.getOperationCallbackParameters());
        }
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.DeferredOperation"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.DeferredOperation"] = true;
dojo.provide("com.ibm.mashups.enabler.DeferredOperation");






}

if(!dojo._hasResource["com.ibm.mashups.enabler.DirtyFlagProvider_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.DirtyFlagProvider_API"] = true;
dojo.provide("com.ibm.mashups.enabler.DirtyFlagProvider_API");
dojo.provide("com.ibm.mashups.enabler.DirtyFlagProvider");

/**
 * Base interface that allows to track whether a node or model has been modified (i.e. became dirty).
 *
 * @since 3.0.0.1
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.DirtyFlagProvider", null, {

    /**
     * Tests whether the instance is dirty. Instances that have been modified, or newly created return true.
     *
     * @return {Boolean} true if the instance is dirty, otherwise false.
     */
    isDirty: function() {},

    /**
     * Marks this instance as dirty.
     */
    setDirty: function() {},

    /**
     * Marks this instance as not dirty, i.e. clean.
     */
    setClean: function() {},

    /**
     * Adds a callback handler to be called when the instance changes its state.
     *
     * @param {Object} ctx The context in which to run the callback handler
     * Must not be <code>null</code>
     * @param {Object} callback the callback funtion in the format of <code>Function(Object[] passed in with addDirtyCallback)</code>.
     * Must not be <code>null</code>
     * @param {Object[]} parameters optional array of parameters to be
     * passed on to the callback function. May be <code>null</code>
     * @param {Boolean} alwaysFire Specifies whether to only fire when clean->dirty (set flag to false) or also fire when dirty->dirty (set flag to true)
     */
    addDirtyCallback: function(ctx, callback, parameters, alwaysFire) {
    },

    /**
     * Removes a callback handler previously added
     *
     * @param {Object} callback the callback funtion to be removed.
     * Must not be <code>null</code>
     */
    removeDirtyCallback: function(fn){
    }

});

}

if(!dojo._hasResource["com.ibm.mm.enabler.DirtyFlagProviderImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.DirtyFlagProviderImpl"] = true;
dojo.provide("com.ibm.mm.enabler.DirtyFlagProviderImpl");



dojo.declare("com.ibm.mm.enabler.DirtyFlagProviderImpl", com.ibm.mashups.enabler.DirtyFlagProvider, {

    _dirty: false,

    setDirty: function() {
        this._setDirty();
    },
    _setDirty: function() {
        var wasFalse = this._dirty === false;
        this._dirty = true;

        if (this._dirtyCallbacks) {
            dojo.forEach(this._dirtyCallbacks, function(cb) {
                if ((wasFalse || cb.alwaysFire) && dojo.isFunction(cb.fn)) {
                    dojo.hitch(cb.ctx || null, cb.fn)(cb.args);
                }
            }, this);
        }
    },

    setClean: function() {
        this._setClean();
    },
    _setClean: function() {
        this._dirty = false;
    },

    isDirty: function() {
        return this._dirty;
    },
    _isDirty: function() {
        return this._dirty;
    },

    addDirtyCallback: function(ctx, fn, args, alwaysFire) {
        this._addDirtyCallback(ctx, fn, args, alwaysFire);
    },
    /**
     * ctx = context
     * fn = function to call
     * args = arguments to that function
     * alwaysFire (boolean) = whether to only fire when clean->dirty (set flag to false) or also fire when dirty->dirty (set flag to true)
     */
    _addDirtyCallback: function(ctx, fn, args, alwaysFire) {
        if (!this._dirtyCallbacks) {
            this._dirtyCallbacks = [];
        }
        this._dirtyCallbacks.push({
            ctx: ctx,
            fn: fn,
            args: args,
            alwaysFire: !!alwaysFire
        });
    },

    removeDirtyCallback: function(fn) {
        this._removeDirtyCallback(fn);
    },
    _removeDirtyCallback: function(fn) {
        if (this._dirtyCallbacks) {
            for (var i = this._dirtyCallbacks.length; i > 0; i--) {
                if (fn === this._dirtyCallbacks[i - 1].fn) {
                    this._dirtyCallbacks.splice(i - 1, 1);
                    break;
                }
            }
        }
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.DirtyFlagProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.DirtyFlagProvider"] = true;
dojo.provide("com.ibm.mashups.enabler.DirtyFlagProvider");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.Discardable_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.Discardable_API"] = true;
dojo.provide("com.ibm.mashups.enabler.Discardable_API");
dojo.provide("com.ibm.mashups.enabler.Discardable");

/**
 * Discardable interface, which allows to discard artifacts or the whole
 * model.
 *
 * @since 2.4
 *
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.Discardable", null, {

	/**
	 * Discards the specified node, or the whole model if no node is specified.
	 * @parameter {Object} node node to discard, must not be <code>null</code>; optional
     * @type void
	 */
	discard : function(node) {
	}
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.Discardable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.Discardable"] = true;
dojo.provide("com.ibm.mashups.enabler.Discardable");



}

if(!dojo._hasResource["com.ibm.mashups.enabler.Identifiable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.Identifiable"] = true;
dojo.provide("com.ibm.mashups.enabler.Identifiable");

/**
 * Interface for any resource in the system that can be identified
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.Identifiable", null, {
    /**
     * Returns the ID of the resource that implements the <code>Identifiable</code> interface.
     * @return {String} the identifier; never <code>null</code>
     */
    getID: function(){
    },

    /**
     * Returns the unique name of the resource that implements the <code>Identifiable</code> interface.
     * @return {String} the unique name; never <code>null</code>
     * @private
     */
    getUniqueName: function(){
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.Invalidatable_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.Invalidatable_API"] = true;
dojo.provide("com.ibm.mashups.enabler.Invalidatable_API");
dojo.provide("com.ibm.mashups.enabler.Invalidatable");

/**
 * Invalidatable interface, which allows to invalidate artifacts or the whole
 * model.
 *
 * @since 2.4
 *
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.Invalidatable", null, {

	/**
	 * Invalidates the specified node, or the whole model if no node is specified.
	 *
	 * @param {Object} node node to invalidate, must not be <code>null</code>; optional
     * @type void
	 */
	invalidate : function(node) {
	}
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.Invalidatable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.Invalidatable"] = true;
dojo.provide("com.ibm.mashups.enabler.Invalidatable");



}

if(!dojo._hasResource["com.ibm.mashups.enabler.Locator"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.Locator"] = true;
dojo.provide( "com.ibm.mashups.enabler.Locator");




/**
 * This interface defines search methods that allow locating resources in a model.
 * A resource is identified by its ID (mandatory). This interface is the base for all locators;
 * other locators allow a more specific search in the context they are offered in,
 * e.g. a search for a node with certain properties in a model.<br>
 * A <code>Locator</code> is usually obtained using the <code>getLocator()</code> method .
 * <pre>
 * var treeModel model = ...;
 * var locator = model.getLocator();
 * var node = locator.find(...);
 * </pre>
 * This locator returns an {@code Object} which is part of some model.
 * What exact kind of object is returned depends on the locator.
 * Please refer to individual JavaScriptDoc for the locator used.
 * The result object can be expected to be an element of the model
 * the locator is used on unless specified otherwise.
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare( "com.ibm.mashups.enabler.Locator", null,     {
    /**
     * Returns an element of a model with the given ID.
     * @param {com.ibm.mashups.enabler.Identifiable} id identifiable or string id of the object to find;
     * must not be <code>null</code>.
     * @return {com.ibm.mashups.enabler.Deferred} a deferred object used to start this operation.
     * The return value when executed through the deferred object is
     * the element with the given ID or <code>null</code> if the element cannot be found.
     */
    find: function (id) {
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.ListModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.ListModel"] = true;
dojo.provide("com.ibm.mashups.enabler.ListModel");





/**
 * A read-only model representing a list. Acting as a base class for all concrete list models.
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.ListModel", [com.ibm.mashups.enabler.model.Model, com.ibm.mashups.enabler.Locator], {
    /**
     * Returns an iterator over elements of the list.
     *
     * @return {com.ibm.mashups.enabler.DeferredIterator} a deferred iterator
     */
    iterator: function(){
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.ListModelController"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.ListModelController"] = true;
dojo.provide("com.ibm.mashups.enabler.ListModelController");



/**
 * A modifiable model representing a list. Acting as a base class for all concrete list models.
 * @ibm-api
 * @ibm-module Base
*/
dojo.declare("com.ibm.mashups.enabler.ListModelController", com.ibm.mashups.enabler.ListModel, {
    /**
     * Creates a new model object. The created node can be inserted
     * into the model using an appropriate <code>insert</code> method defined
     * on a subinterface of this interface. The node will not appear in the model
     * unless it is inserted.
     * @param {JSON} context array of predefined information
     * used for the creation of the node. May be <code>null</code>. Accepted
     * names are defined in the appropriate subinterfaces
     * @type Object
     * @return the created node
     */
    create: function(context){
    },
    /**
     * Confirms whether creating the node is possible.
     * @param {JSON} context array of predefined information
     * used for the creation of the node. May be <code>null</code>. Accepted
     * names are defined in the appropriate subinterfaces
     * @return {Boolean} true if the node can be created, otherwise false.
     */
    confirmCreate: function(context){
    },

    /**
     * Inserts the specified node into the list model at the specified
     * position; the node must be created with the create method of the
     * concrete ListModel
     *
     * @param {Object} node     node or node uri (without any scope) to
     *                          insert into the list model. Must not be
     *                          <code>null</code>
     * @param {Object} nextNode node object or node uri (without any scope) of
     *                          the successor node before which the node
     *                          is to be inserted;
     *                          if <code>null</code> is specified, the
     *                          node is appended at the end of the existing nodes
     * @type void
     */
    insert: function(node, nextNode){
    },

    /**
     * Confirms whether inserting the node is possible.
     * @param {Object} node     node or node uri (without any scope) to
     *                          insert into the list model. Must not be
     *                          <code>null</code>
     * @param {Object} nextNode node object or node uri (without any scope) of
     *                          the successor node before which the node
     *                          is to be inserted;
     *                          if <code>null</code> is specified, the
     *                          node is appended at the end of the existing nodes
     * @return {Boolean} true if the node can be inserted, otherwise false.
     */
    confirmInsert: function(node, nextNode){
    },

    /**
     * Removes the specified node from the list model
     *
     * @param{Object} node  node object or node uri (without any scope).
     *                      Must not be <code>null</code>
     * @type void
     */
    remove: function(node){
    },

    /**
     * Confirms whether removing the node is possible.
     * @param{Object} node  node object or node uri (without any scope).
     *                      Must not be <code>null</code>
     * @return {Boolean} true if the node can be removed, otherwise false.
     */
    confirmRemove: function(node){
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.Localized_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.Localized_API"] = true;
dojo.provide("com.ibm.mashups.enabler.Localized_API");
dojo.provide("com.ibm.mashups.enabler.Localized");

/**
 * Read-Only interface providing methods to obtain title and description of a
 * resource. Please note that title or description are only returned if they
 * are available in the requested locale. No fallback for locales is performed.
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.Localized", null, {
    /**
     * Returns an array containing the locales that are supported by this
     * object. The presence of a locale in this list does not mean that a title
     * <b>and</b> description is available, but rather that either one or both
     * are available in that locale.<br>
     * <br>
     * <b>Note:</b> Modifying the array does not change the supported locales.
     * @return {String[]} a list of locales defined for this object, returns an
     * empty array if no locales are supported. Can never be <code>null</code>.
     */
    getLocales: function(){
    },

    /**
     * Returns the title of this object in the given locale.
     * @param {String} locale the locale for which to retrieve the title,
     * must not be <code>null</code>.
     * @return {String} the title of this node in the given locale. If a title is not
     * available in the given locale, this method will return <code>null</code>.
     * It is up to the invoker of the method to implement an appropriate fallback mechanism.
     */
    getTitle: function(locale){
    },

    /**
     * Returns the titles of this object in a map (key: locale, value: title).
     *
     * @param {String} locale   (optional) the locale for which to retrieve the titles, can be <code>null</code>. If locale is null/omitted, all are returned.
     * @return {Object} the titles of this node in a locale<->title map. If a locale was given, the result will be a map containing only those locales with country specific matches (e.g. if you give a locale "pt", you might also get brazilian portugese ("pt-BR") - if you give a locale "zh-TW", you won't get "zh"). If there are no titles (matching the given locale), an empty object will be returned.
     *
     * @since 3.0
     */
    getTitles: function(){
    },

    /**
     * Returns the description of this object in the given locale.
     * @param {String} locale   the locale for which to retrieve the
     * description, must not be <code>null</code>.
     * @return {String} the description of this node in the given locale. If a
     * description is not available in the given locale, this method
     * will return <code>null</code>. It is up to the invoker of the
     * method to implement an appropriate fallback mechanism.
     */
    getDescription: function(locale){
    },

    /**
     * Returns the descriptions of this object in a map (key: locale, value: description).
     *
     * @param {String} locale   (optional) the locale for which to retrieve the descriptions, can be <code>null</code>. If locale is null/omitted, all are returned.
     * @return {Object} the descriptions of this node in a locale<->description map. If a locale was given, the result will be a map containing only those locales with country specific matches (e.g. if you give a locale "pt", you might also get brazilian portugese ("pt-BR") - if you give a locale "zh-TW", you won't get "zh"). If there are no descriptions (matching the given locale), an empty object will be returned.
     *
     * @since 3.0
     */
    getDescriptions: function(locale){
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.ModifiableLocalized"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.ModifiableLocalized"] = true;
dojo.provide("com.ibm.mashups.enabler.ModifiableLocalized");



/**
 * Modifiable interface providing methods to set title and description of a
 * resource.
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.ModifiableLocalized", com.ibm.mashups.enabler.Localized, {
    /**
     * Sets the title for the given locale.
     * @param {String} title    title to set; must not be <code>null</code>
     * @param {String} locale   locale to set the title for; must not be <code>null</code>
     * @return {String} the former title; if none existed, <code>null</code> is returned
     */
    setTitle: function(title, locale){
    },

    /**
     * Confirms whether setting the title for the given locale is possible.
     * @param {String} title    title to set; must not be <code>null</code>
     * @param {String} locale   locale to set the title for; must not be <code>null</code>
     * @return {Boolean} true if the value can be set, otherwise false.
     */
    confirmSetTitle: function(title, locale){
    },

    /**
     * Removes the title for the given locale.
     * @param {String} locale locale of the title to remove; must not be <code>null</code>
     * @type void
     */
    removeTitle: function(locale){
    },

    /**
     * Indicates if the title for the specified locale may be removed.
     * @param {String} locale locale for which to indicate if the title may be removed; must not be <code>null</code>
     * @return {Boolean} <code>true</code> if the title can be removed, otherwise <code>false</code>.
     */
    confirmRemoveTitle: function(locale){
    },

    /**
     * Removes all titles.
     * @type void
     */
    removeTitles: function(){
    },

    /**
     * Indicates if the titles for all locales may be removed.
     * @return {Boolean} <code>true</code> if all titles can be removed, otherwise
     * <code>false</code>.
     */
    confirmRemoveTitles: function(){
    },

    /**
     * Sets the description for the given locale.
     * @param {String} desc     description to set; must not be <code>null</code>
     * @param {String} locale   locale to set the description for; must not be <code>null</code>
     * @return {String} the former description; if none existed, <code>null</code> is returned
     */
    setDescription: function(desc, locale){
    },

    /**
     * Confirms whether setting the description for the given locale is possible.
     * @param {String} desc     description to set; must not be <code>null</code>
     * @param {String} locale   locale to set the description for; must not be <code>null</code>
     * @return {Boolean} true if the value can be set, otherwise false.
     */
    confirmSetDescription: function(desc, locale){
    },

    /**
     * Removes the description for the given locale.
     * @param {String} locale locale of the description to remove; must not be <code>null</code>
     * @type void
     */
    removeDescription: function(locale){
    },

    /**
     * Indicates if the description for the specified locale may be removed.
     * @param {String} locale locale for which to indicate if the description may be removed; must not be <code>null</code>
     * @return {Boolean} <code>true</code> if the description can be removed, otherwise <code>false</code>.
     */
    confirmRemoveDescription: function(locale){
    },

    /**
     * Removes all description.
     * @type void
     */
    removeDescriptions: function(){
    },

    /**
     * Indicates if the description for all locales may be removed.
     * @return {Boolean} <code>true</code> if all descriptions can be removed, otherwise
     * <code>false</code>.
     */
    confirmRemoveDescriptions: function(){
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.Localized"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.Localized"] = true;
dojo.provide("com.ibm.mashups.enabler.Localized");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.Representation_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.Representation_API"] = true;
dojo.provide("com.ibm.mashups.enabler.Representation_API");
dojo.provide("com.ibm.mashups.enabler.Representation");



/**
 * An interface that allows retrieving a URL and mime type representing the resource.
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.Representation", com.ibm.mashups.enabler.Identifiable, {
    /**
     * Returns the mimetype of the representation.
     * @return {String} the identifier; never <code>null</code>
     */
    getID: function(){
    },

    /**
     * Returns a full or absolute URL pointing to the resource in another representation.
     * @return {String} the URL pointing to the other representation; never <code>null</code>
     */
    getURL: function(){
    },

    /**
     * Returns the mimetype of the content to which the URL is pointing to.
     * @return {String} the mimetype; never <code>null</code>
     */
    getMimeType: function(){
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.RepresentationImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.RepresentationImpl"] = true;
dojo.provide( "com.ibm.mm.enabler.RepresentationImpl");



// representation
dojo.declare( "com.ibm.mm.enabler.RepresentationImpl", com.ibm.mashups.enabler.Representation,
    {
        constructor:function (url, type) {
            this.url = url;
            this.type = type;
        },

        getID: function() {
            return this.type;
        },

        getURL: function() {
            return this.url;
        },

        getMimeType: function() {
            return this.type;
        }
  }
);

}

if(!dojo._hasResource["com.ibm.mashups.enabler.Representation"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.Representation"] = true;
dojo.provide("com.ibm.mashups.enabler.Representation");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.RepresentationProvider_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.RepresentationProvider_API"] = true;
dojo.provide("com.ibm.mashups.enabler.RepresentationProvider_API");
dojo.provide("com.ibm.mashups.enabler.RepresentationProvider");




/**
 * An interface that allows to retrieve information about different representations of the resource.
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.RepresentationProvider", null, {
    /**
     * Returns a ListModel containing information about the alternate representations available. The model contains <code>Representation</code> objects .
     * @see com.ibm.mashups.enabler.Representation
     * @return {com.ibm.mashups.enabler.ListModel} ListModel containing alternate representations of the resource; never <code>null</code>
     */
    getAlternateModel: function(){
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.RepresentationModelImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.RepresentationModelImpl"] = true;
dojo.provide("com.ibm.mm.enabler.RepresentationModelImpl");









// alternate representation list model
dojo.declare("com.ibm.mm.enabler.RepresentationModelImpl", [com.ibm.mashups.enabler.ListModel, com.ibm.mm.enabler.DeferredIteratorImpl], {
    constructor: function(nodes) {
        this.loadedNodes = {};
        this.entries = [];
        this.cursor = 0;
        this.size = null;
        this.start = null;
        this.num = null;
        this.strategy = null;

        // now fill in loadedNodes and entries
        if (nodes && nodes.length > 0) {
            this.size = nodes.length;
            for (var i = 0; i < nodes.length; i++) {
                var link = nodes[i];
                var url = link.getAttribute("href");
                var mimetype = link.getAttribute("type");
                // create a new representation node
                var uri = mimetype;
                var node = new com.ibm.mm.enabler.RepresentationImpl(url, mimetype);
                // setup the internal objects
                this.entries[i] = uri;
                this.loadedNodes[uri] = node;
            }
        }
    },

    find: function(uri) {
        return new com.ibm.mm.enabler.DeferredImpl(this, this._find, uri);
    },

    _find: function(deferred, sync, uri) {
        return this._load(uri, deferred, sync);
    },

    start: function(sync) {
        while (this._hasNext(this, sync)) {
            if (this._next(this, sync)) {
                continue;
            }
            else {
                break;
            }
        }
    },

    hasNext: function() {
        return this._hasNext(null, true);
    },

    _hasNext: function(deferred, sync) {
        if (this.start === null || this.cursor < this.start || (this.cursor >= (this.start + this.num) && (this.size > this.cursor))) {
            this._loadAhead(deferred, sync);
        }
        return (this.size > this.cursor);
    },

    next: function() {
        return this._next(null, true);
    },

    _next: function(deferred, sync) {
        return this._hasNext(deferred, sync) ? this.loadedNodes[this.entries[this.cursor++]] : null;
    },

    size: function() {
        return this.size;
    },

    setCursorPosition: function(position) {
        this.cursor = position;
    },

    getCursorPosition: function() {
        return this.cursor;
    },

    setStrategy: function(strategy) {
        if (com.ibm.mm.enabler.utils.Misc.isInstanceOf(strategy, Array)) {
            // evaluate the first strategy only
            this.strategy = strategy[0];
        }
        else {
            // backwards compatibility
            this.strategy = strategy;
        }
    },

    _load: function(uri, deferred, sync) {
        if (uri in this.loadedNodes) {
            // fetch node from cache
            if(deferred) { deferred.finish(this.loadedNodes[uri], com.ibm.mm.enabler.model.HttpStatusCodes.HTTP_OK); }
        }
        return this.loadedNodes[uri];
    },

    _loadAhead: function(deferred, sync) {
        // noop
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.RepresentationProviderImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.RepresentationProviderImpl"] = true;
dojo.provide("com.ibm.mm.enabler.RepresentationProviderImpl");








// representation provider
dojo.declare("com.ibm.mm.enabler.RepresentationProviderImpl", com.ibm.mashups.enabler.RepresentationProvider, {
    constructor: function() {
        // service document and initialization
        this.serviceJson = com.ibm.mm.enabler.model.ServiceDocumentModel.getCollectionData(com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_NAVIGATION);
        var nsf = com.ibm.mm.enabler.model.NameSpaceFactory;
        this.r_ns = dojo.delegate(this.serviceJson.namespaces, nsf.getNameSpaces([nsf.NS_ATOM, nsf.NS_XML]));
        this.XPATH = "atom:link";
    },

    getAlternateModel: function() {
        var validLinks = [];
        var md = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(this.XPATH, this.xmlData, this.r_ns);
        if (md && md.length > 0) {
            for (var i = 0, l = md.length; i < l; i++) {
                var link = md[i];
                var rel = link.getAttribute("rel");
                var extrel = com.ibm.mm.enabler.utils.Dom.getAttributeWithNS(link, "ext:rel", "rel", this.r_ns.ext);
                if (extrel == "") {
                    extrel = null;
                }
                if (((!rel) || (rel == 'alternate')) && (!extrel)) {
                    validLinks[validLinks.length] = link;
                }
            }
        }
        var model = new com.ibm.mm.enabler.RepresentationModelImpl(validLinks);
        return model;
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.RepresentationProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.RepresentationProvider"] = true;
dojo.provide("com.ibm.mashups.enabler.RepresentationProvider");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.ResourceLocator"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.ResourceLocator"] = true;
dojo.provide("com.ibm.mashups.enabler.ResourceLocator");



/**
 * Interface for finding resources within a model.
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.ResourceLocator", com.ibm.mashups.enabler.Locator, {

    /**
     * Returns the URL of the resource to be located, or <code>null</code> if the resource cannot be found.
     * @param {Object} node A node of the model this locator is implemented on. Must not be <code>null</code>.
     * @param {String} name The name of the resource to be located within the given model. The name can also contain a directory path relative to the model. Must not be <code>null</code>.
     * @return {String} The URL that can be used to fetch the resource, or <code>null</code> if the resource cannot be found.
     * @deprecated Use findResourceURL instead.
     */
    findResourceUrl: function(node, name){
    },

    /**
     * Returns the URL of the resource to be located, or <code>null</code> if the resource cannot be found.
     * @param {Object} node A node of the model this locator is implemented on. Must not be <code>null</code>.
     * @param {String} name The name of the resource to be located within the given model. The name can also contain a directory path relative to the model. Must not be <code>null</code>.
     * @return {String} The URL that can be used to fetch the resource, or <code>null</code> if the resource cannot be found.
     */
    findResourceURL: function(node, name){
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.SubmittableForm_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.SubmittableForm_API"] = true;
dojo.provide("com.ibm.mashups.enabler.SubmittableForm_API");
dojo.provide("com.ibm.mashups.enabler.SubmittableForm");



/**
 * An interface representing a submittable form. Submittable forms can be used
 * to import resources of models, which implement the SubmittableFormProvider
 * interface, for example spaces or templates. The provider of submittable forms
 * automatically set the necessary URL parameters, such as enctype, action and method.
 * To submit a submittable form, you invoke the submit()-method, which in turn
 * imports the resource using an appropriate xhr request.<br><br>
 * Example:<br>
 * <code>
 *   var form = spaceModel.getSubmittableImportForm(spaceId);<br>
 *   form.submit().start();<br>
 * </code>
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.SubmittableForm", com.ibm.mashups.enabler.Identifiable, {
    /**
     * Returns the URL this form is submitted to. Used to fill in the action attribute in the form.
     * @return {String} the URL this form is submitted to; never <code>null</code>
     */
    getURL: function(){
    },

    /**
     * Returns the HTTP method used to submit this form. Used to fill in the method attribute in the form.
     * @return {String} the method; never <code>null</code>
     */
    getMethod: function(){
    },

    /**
     * Submits the form
     * @return {com.ibm.mashups.enabler.Deferred} a deferred object used to start this operation.
     */
    submit: function(){
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.SubmittableFormImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.SubmittableFormImpl"] = true;
dojo.provide("com.ibm.mm.enabler.SubmittableFormImpl");





dojo.declare("com.ibm.mm.enabler.SubmittableFormImpl", com.ibm.mashups.enabler.SubmittableForm, {
    constructor: function(url, method, formId){
        this.url = url;
        this.method = method;
        this.formId = formId;
    },

    /**
     * Returns the URL this form is submitted to. Used to fill in the action attribute in the form.
     * @return {String} the URL this form is submitted to; never <code>null</code>
     */
    getURL: function(){
        return this.url;
    },

    /**
     * Returns the HTTP method used to submit this form. Used to fill in the method attribute in the form.
     * @return {String} the method; never <code>null</code>
     */
    getMethod: function(){
        return this.method;
    },

    /**
     * Submits the form
     * @return {com.ibm.mashups.enabler.Deferred} a deferred object used to start this operation.
     */
    submit: function(){
        return new com.ibm.mm.enabler.DeferredImpl(this, this._submit);
    },

    /**
     * Submits the form
     * @return {com.ibm.mashups.enabler.Deferred} a deferred object used to start this operation.
     */
    _submit: function(deferred){
        dojo.io.iframe.send({
            url: this.url,
            method: this.method,
            handleAs: "text",
            // For IE issue
            form: document.getElementsByName(this.formId)[0],
            load: function(data, ioArgs){
                if(deferred) { deferred.finish(data, com.ibm.mm.enabler.model.HttpStatusCodes.HTTP_CREATED); }
            },
            error: function(data, ioArgs){
                if(deferred) { deferred.finish(data, com.ibm.mm.enabler.model.HttpStatusCodes.HTTP_NOT_FOUND); }
            }
        });
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.SubmittableForm"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.SubmittableForm"] = true;
dojo.provide("com.ibm.mashups.enabler.SubmittableForm");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.SubmittableFormProvider_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.SubmittableFormProvider_API"] = true;
dojo.provide("com.ibm.mashups.enabler.SubmittableFormProvider_API");
dojo.provide("com.ibm.mashups.enabler.SubmittableFormProvider");



/**
 * An interface that allows to retieve submittable form
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.SubmittableFormProvider", null, {
    /**
     * Returns a SubmittableForm object associated with the given id.
     * @param {String} id the id of the html form this object is associated with
     * @return {com.ibm.mashups.enabler.SubmittableForm} SubmittableForm object, maybe <code>null</code>
     */
    getSubmittableForm: function(id){
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.url.ModelUrl_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.url.ModelUrl_API"] = true;
dojo.provide("com.ibm.mashups.enabler.model.url.ModelUrl_API");
dojo.provide("com.ibm.mashups.enabler.model.url.ModelUrl");

/**
 * Interface representing a model URL. This class should be used by the specific model
 * API's in order to generate a valid model URL. The low level classes like ModelRestServiceRequest
 * expect a request to be made with an implementation of the interface. It also allows an easy way
 * to handle URIs. e.g. <br/>
 * <code>&lt;scheme&gt;:&lt;primaryNode&gt;@&lt;secondaryNode&gt;</code><bt/>
 * <code>scheme-specific part = &lt;primaryNode&gt;@&lt;secondaryNode&gt;
 *
 * @ibm-spi
 * @ibm-module Base
*/
dojo.declare("com.ibm.mashups.enabler.model.url.ModelUrl", null, {
        /**
        * @private
        */
        constructor: function () {
        },
        /**
        * Sets the nodes of the scheme-specific part.
        * @param {JSONArray} nodes an array containing the nodes of the scheme-specific part in a JSON notation way.<br/>
        *                          The ordering of the array elements specifies the position of the node, meaning
        *                          the array element 0 will become node 1 and so on and so forth.<br/><br/>
        * valid JSON attributes are: <br/>
        * <ul>
        * <li>value <i>{String} [mandatory]</i></li>
        * <li>isID <i>{boolean} [optional, default: true]</i></li>
        * <li>subModel <i>{String} [optional]</i></li>
        * </ul><br/>
        * example for &quot;nodes&quot;: <br/>
        * <code>
        * [ {<br/>
        * value: &quot;100&quot;,<br/>
        *   isID: false,<br/>
        *   subModel: &quot;member&quot;<br/>
        * } ]
        * </code>
        * @type {void}
        */
        setNodes: function(nodes) {
        },
        /**
        * Sets the scheme-specific part of the unerlying URI.
        * @param {String} value the value for the scheme-specifc part. (Must not be <code>null</code>)
        * @type {void}
        */
        setSchemeSpecificPart: function (value) {
        },
        /**
        * Returns the scheme-specific part of the underlying URI.
        * @type {String}
        * @return the scheme-specific part. If a scheme-specific part was set through <code>setSchemeSpecificPart</code>
        *         the raw value will be returned. If the SSP was set by using <code>setNodes</code>,
        *         the converted part will be returned. If neither a node nor the raw SSP was set,
        *         this method returns <code>null</code>.
        */
        getSchemeSpecificPart: function() {
            return null;
        },
        /**
        * Adds the value of the specified parameter.
        * @param {String} name the name of the parameter; must not be <code>null</code>.
        * @param {String} value the value of the parameter. Valid is only a single String. (Must not be <code>null</code>)
        * @type {void}
        */
        addParameter: function (name, value) {
        },
        /**
        * Sets the value(s) of the specified parameter.
        * @param {String} name the name of the parameter; must not be <code>null</code>.
        * @param {String} value the value of the parameter. Valid are either a single String or a String array. (Must not be <code>null</code>)
        * @type {void}
        */
        setParameter: function (name, value) {
        },
        /**
        * Returns the value(s) of the specified parameter.
        * @param {String} name the name of the parameter; must not be <code>null</code>.
        * @type {String}
        * @return the value(s) of the specified parameter or <code>null</code> if the specified parameter wasn't found. In case the parameter has one value
        *   the return type is String. For multiple values a String array is returned.
        */
        getParameter: function (name) {
            return null;
        },
        /**
        * Returns the parameters as an object. <b>Note: this must be used read-only</b>
        * @type {JSON}
        * @return an object containing all parameters in the format { &lt;name&gt;: [&lt;value&gt;, &lt;value&gt;, ... ], ... }
        */
        getParameters: function() {
            return null;
        },
        /**
        * Returns the absolute URL of this object.
        * @type {String}
        * @return the absolute URL of this object. e.g. <code>http://myhost/contenthandler?uri=acme:id:myid</code>
        *         or <code>/contenthandler?uri=acme:id:myid</code>
        */
        getAbsoluteURL: function () {
        	return null;
        },
        /**
        * The same as <code>getAbsoluteURL</code> with the difference that this URL is (if needed) converted to a proxified URL
        * @type {String}
        * @return the proxified absolute URL. e.g. <code>http://acme.com/proxy/http/myhost/contenthandler?uri=acme:id:myid</code>
        */
        getProxifiedAbsoluteURL: function () {
            return null;
        },
        /**
        * Returns the model URI of this object. If the complete link is e.g. <code>/mum/contenthandler?uri=acme:id:myid</code>,
        * this method will return <code>acme:id:myid</code>.
        * @type {String}
        * @return the URI portion of this Model URL.
        */
        getModelURI: function () {
            return null;
        }
    }
);

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.url.ModelUrl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.url.ModelUrl"] = true;
dojo.provide("com.ibm.mashups.enabler.model.url.ModelUrl");



}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.url.ModelUrlFactory_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.url.ModelUrlFactory_API"] = true;
dojo.provide("com.ibm.mashups.enabler.model.url.ModelUrlFactory_API");
dojo.provide("com.ibm.mashups.enabler.model.url.ModelUrlFactory");

/**
 * Interface for a ModelUrl Factory that allows to generate ModelUrl's a comfortable way.
 * This class should not be instantiated directly, but should be used through it's defined singleton
 * (<code>com.ibm.mashups.enabler.model.url.ModelUrlFactory</code>).
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare( "com.ibm.mashups.enabler.model.url.ModelUrlFactory", null,
    {
        /**
        * Constant for creation of a navigation URL
        * @type {String}
        */
        NAVIGATION_URL:            "nav",

        /**
        * Constant for creation of a layout URL
        * @type {String}
        */
        LAYOUT_URL:                "layout",

        /**
        * Constant for creation of a shared navigation URL
        * @type {String}
        */
        SHARED_NAVIGATION_URL:     "sharednav",
        /**
        * Constant for creation of a fragment URL
        * @type {String}
        */
        FRAGMENT_URL:       "fragment",
        /**
        * Constant for creation of a fragment-media URL
        * @type {String}
        */
        FRAGMENT_MEDIA_URL: "fragment-media",
        /**
        * Constant for creation of a user URL
        * @type {String}
        */
        USER_URL:           "user",
        /**
        * Constant for creation of a theme URL
        * @type {String}
        */
        THEME_URL:          "theme",
        /**
        * Constant for creation of a theme-media URL
        * @type {String}
        */
        THEME_MEDIA_URL:    "theme-media",
        /**
        * Constant for creation of a catalog URL
        * @type {String}
        */
        CATALOG_URL:        "cat",
        /**
        * Constant for creation of a config URL
        * @type {String}
        */
        CONFIG_URL:        "config",
        /**
        * Constant for creation of a space URL
        * @type {String}
        */
        SPACE_URL:      "space",
        		/**
        * Constant for creation of a space-favorite URL
        * @type {String}
        */
        SPACE_FAVORITE_URL:      "space-favorite",
        /**
        * Constant for creation of a ac URL
        * @type {String}
        */
        AC_URL:      "ac",
        /**
        * Constant for creation of a ac URL
        * @type {String}
        */
        AI_URL:      "ai",
        /**
        * Constant for creation of a template URL
        * @type {String}
        */
        TEMPLATE_URL:      "template",
        /**
         * Constant for widget model
         * @type {String}
         */
        WIDGET_URL:        "widget",
        /**
         * Constant for event model
         * @type {String}
         */
        EVENT_URL:         "event",
        /**
        * Constant for member sub model
        * @type {String}
        */
        SUBMODEL_MEMBER:    "member",
        /**
        * Constant for role sub model
        * @type {String}
        */
        SUBMODEL_ROLE:      "role",

        /**
        * Constant for allowed-access sub model
        * @type {String}
        */
        SUBMODEL_ACCESS:      "access",

        /**
        * Constant for resource sub model
        * @type {String}
        */
        SUBMODEL_RESOURCE:      "resource",

        RESOURCE_URL: "resource-service",

        /**
        * @private
        **/
        constructor:function () {
        },

        /**
        * Create a ModelUrl based on the specified urlType. Afterwards parameters and scheme
        * specific parts can be changed.<br />
        * Sample:
        * <pre>var myURL = com.ibm.mashups.enabler.model.url.ModelUrlFactory.createModelURL(com.ibm.mashups.enabler.model.url.ModelUrlFactory.NAVIGATION_URL, this);</pre>
        * @param {String} urlType the type of ModelUrl that should be created. You should use the URL constants that are defined in this interface. (Must not be <code>null</code>)
        * @param {com.ibm.mashups.enabler.model.Model} model the model used to create this ModelUrl object for. (Might be <code>null</code>)
        * @type {com.ibm.mashups.enabler.model.url.ModelUrl}
        * @return the created <code>ModelUrl</code>. Returns <code>null</code> if the specified urlType is not known.
        * @deprecated Use createModelURL instead.
        */
        createModelUrl: function (urlType, model) {
        	return new com.ibm.mashups.enabler.model.url.ModelUrl(urlType, model);
        },
        /**
        * Create a ModelUrl based on the specified urlType. Afterwards parameters and scheme
        * specific parts can be changed.<br />
        * Sample:
        * <pre>var myURL = com.ibm.mashups.enabler.model.url.ModelUrlFactory.createModelURL(com.ibm.mashups.enabler.model.url.ModelUrlFactory.NAVIGATION_URL, this);</pre>
        * @param {String} urlType the type of ModelUrl that should be created. You should use the URL constants that are defined in this interface. (Must not be <code>null</code>)
        * @param {com.ibm.mashups.enabler.model.Model} model the model used to create this ModelUrl object for. (Might be <code>null</code>)
        * @type {com.ibm.mashups.enabler.model.url.ModelUrl}
        * @return the created <code>ModelUrl</code>. Returns <code>null</code> if the specified urlType is not known.
        */
        createModelURL: function (urlType, model) {
        	return new com.ibm.mashups.enabler.model.url.ModelUrl(urlType, model);
        },
        /**
        * Create a ModelUrl based on the specified URL. Afterwards parameters and scheme specific parts can be changed.
        * @param {String} url the URL that should be used to create a <code>ModelUrl</code>. (Must not be <code>null</code>)
        * @param {com.ibm.mashups.enabler.model.Model} model the model used to create this ModelUrl object for. (Might be <code>null</code>)
        * @type {com.ibm.mashups.enabler.model.url.ModelUrl}
        * @return the created <code>ModelUrl</code> (Must not be <code>null</code>).
        * @deprecated Use getModelURL instead.
        */
        getModelUrl: function (url, model) {
        	return new com.ibm.mashups.enabler.model.url.ModelUrl(url, model);
        },
        /**
        * Create a ModelUrl based on the specified URL. Afterwards parameters and scheme specific parts can be changed.
        * @param {String} url the URL that should be used to create a <code>ModelUrl</code>. (Must not be <code>null</code>)
        * @param {com.ibm.mashups.enabler.model.Model} model the model used to create this ModelUrl object for. (Might be <code>null</code>)
        * @type {com.ibm.mashups.enabler.model.url.ModelUrl}
        * @return the created <code>ModelUrl</code> (Must not be <code>null</code>).
        */
        getModelURL: function (url, model) {
        	return new com.ibm.mashups.enabler.model.url.ModelUrl(url, model);
        }
    }
);

}

if(!dojo._hasResource["com.ibm.mm.enabler.model.url.BaseModelUrl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.url.BaseModelUrl"] = true;
dojo.provide("com.ibm.mm.enabler.model.url.BaseModelUrl");





dojo.declare("com.ibm.mm.enabler.model.url.BaseModelUrl", [com.ibm.mashups.enabler.model.url.ModelUrl], {
    modelSchema: null,
    schemeSpecific: null,
    isMediaUrl: false,
    httpUrl: null,

    VALUE: "value",
    IS_ID: "isID",
    SUBMODEL: "submodel",

    constructor: function() {
        this.nodes = [];
        this.prefix = null;

        this.subModelSchemeMap = {};
        this.subModelSchemeMap[com.ibm.mashups.enabler.model.url.ModelUrlFactory.SUBMODEL_RESOURCE] = "resource";
        this.subModelSchemeMap[com.ibm.mashups.enabler.model.url.ModelUrlFactory.SUBMODEL_ROLE] = "role";
        this.subModelSchemeMap[com.ibm.mashups.enabler.model.url.ModelUrlFactory.SUBMODEL_MEMBER] = "member";
        this.subModelSchemeMap[com.ibm.mashups.enabler.model.url.ModelUrlFactory.SUBMODEL_ACCESS] = "access";
    },
    _loadPrefix: function() {
        if (!this.prefix) {
            // service document and initialization
            this.serviceJson = com.ibm.mm.enabler.model.ServiceDocumentModel.getCollectionData(com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_NAVIGATION);
            this.prefix = this.serviceJson.idprefix;
        }
    },
    setPrimaryNode: function(value, isID, subModel) {
        var primary = {};
        primary.value = value;
        primary.isID = (isID === false) ? isID : true;
        primary.subModel = subModel;

        this.nodes[0] = primary;

        this._updateURI();
    },
    setSecondaryNode: function(value, isID, subModel) {
        var secondary = {};
        secondary.value = value;
        secondary.isID = (isID === false) ? isID : true;
        secondary.subModel = subModel;

        this.nodes[1] = secondary;

        this._updateURI();
    },
    setNodes: function(nodes) {
        this.nodes = nodes;

        for (var i = 0; i < nodes.length; i++) {
            nodes[i].isID = (nodes[i].isID === false) ? nodes[i].isID : true;
        }

        this._updateURI();
    },
    setSchemeSpecificPart: function(value) {
        this.nodes = [];
        this.schemeSpecific = value;

        this._updateURI();
    },
    getSchemeSpecificPart: function() {
        if (this.schemeSpecific) {
            return this.schemeSpecific;
        }
        var tempSSP = "";
        if (this.isMediaUrl) {
            tempSSP = "/";
        }
        if (!this.nodes) {
            return tempSSP;
        }
        var i, node;
        if (this.isMediaUrl) {
            for (i = 0; i < this.nodes.length; i++) {
                node = this.nodes[i];
                // the prefix MUST only be loaded if the prefix is needed, since the
                // loading method uses this function as well which would causea infinite loop
                if (node.isID && !this.prefix) {
                    this._loadPrefix();
                }
                if (i > 0) {
                    if (i < this.nodes.length - 1) {
                        tempSSP += "@";
                    }
                    else {
                        tempSSP += "/";
                    }
                }
                tempSSP += node.value;
            }
        }
        else {
            for (i = 0; i < this.nodes.length; i++) {
                node = this.nodes[i];
                // the prefix MUST only be loaded if the prefix is needed, since the
                // loading method uses this function as well which would causea infinite loop
                if (node.isID && !this.prefix) {
                    this._loadPrefix();
                }
                if (tempSSP != "") {
                    tempSSP += "@";
                }
                if (node.subModel) {
                    tempSSP += this.subModelSchemeMap[node.subModel] + ":";
                }
                if (node.isID) {
                    tempSSP += this.prefix + ":";
                }

                tempSSP += node.value;
            }
        }
        return tempSSP;
    },
    _updateURI: function() {
        var uri = this.modelSchema + ":" + this.getSchemeSpecificPart();
        this.httpUrl.setParameter("uri", uri);
    },
    addParameter: function(name, value) {
        this.httpUrl.addParameter(name, value);
    },
    setParameter: function(name, value) {
        this.httpUrl.setParameter(name, value);
    },
    getParameter: function(name) {
        return this.httpUrl.getParameter(name);
    },
    getParameters: function() {
        return this.httpUrl.getParameters();
    },
    getAbsoluteURL: function() {
        return this.httpUrl.toString();
    },
    getProxifiedAbsoluteURL: function() {
        return this.httpUrl.toProxifiedString();
    },
    getModelURI: function() {
        return this.httpUrl.getParameter("uri");
    },
    toProxifiedString: function() {
        // TBD: REMOVE AFTER FULL SWITCH
        return this.httpUrl.toProxifiedString();
    }

});

}

if(!dojo._hasResource["com.ibm.mm.enabler.model.url.SchemeBasedModelUrlImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.url.SchemeBasedModelUrlImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.url.SchemeBasedModelUrlImpl");






dojo.declare("com.ibm.mm.enabler.model.url.SchemeBasedModelUrlImpl", [com.ibm.mm.enabler.model.url.BaseModelUrl], {
    constructor: function(modelSchema, model) {
        this.modelSchema = modelSchema;
        this.model = model;

        var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
        var url = "";

        // add the contextroot
        url += configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT);

        // add the public contenthandler url
        var anonymousUser = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.ANONYMOUS_USER);

        var contenthandlerPath;

        if (anonymousUser) {
            contenthandlerPath = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PUBLIC);
        }
        else {
            contenthandlerPath = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PRIVATE);
        }

        url += contenthandlerPath;

        this.httpUrl = new com.ibm.mm.enabler.utils.HttpUrl(url);

        this.httpUrl.setParameter("uri", this.modelSchema); // first initialization
    }
});


}

if(!dojo._hasResource["com.ibm.mm.enabler.model.url.SchemeBasedModelMediaUrlImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.url.SchemeBasedModelMediaUrlImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.url.SchemeBasedModelMediaUrlImpl");



dojo.declare("com.ibm.mm.enabler.model.url.SchemeBasedModelMediaUrlImpl", [com.ibm.mm.enabler.model.url.SchemeBasedModelUrlImpl], {
    constructor: function(modelSchema, model) {
        this.isMediaUrl = true;
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.model.url.ThemeResourceUrlImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.url.ThemeResourceUrlImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.url.ThemeResourceUrlImpl");




dojo.declare("com.ibm.mm.enabler.model.url.ThemeResourceUrlImpl", [com.ibm.mm.enabler.model.url.BaseModelUrl],
{
    constructor: function (modelSchema, model) {
        this.modelSchema = modelSchema;
        this.model = model;

        this.httpUrl = new com.ibm.mm.enabler.utils.HttpUrl("/");
        this.httpUrl.setParameter("uri", this.modelSchema); // first initialization
    },
    _updateURI: function() {
        // at this point we know it must be a theme or skin resource we try to fetch
        var resource, url;
        if (this.nodes.length==2) { // theme
            var themeId = this.nodes[0].value;
            resource = this.nodes[1].value;
            var themeNode = this.model.find(themeId).start();
            url = themeNode._getBaseUrl();
            this.httpUrl = new com.ibm.mm.enabler.utils.HttpUrl(url+resource);
        }
        else if (this.nodes.length==3) { // skin
            var skinId = this.nodes[0].value;
            //var themeId = this.nodes[1].value;
            resource = this.nodes[2].value;
            var skinNode = this.model.find(skinId).start();
            url = skinNode._getBaseUrl();
            this.httpUrl = new com.ibm.mm.enabler.utils.HttpUrl(url+resource);
        }
        else {
            this.httpUrl = new com.ibm.mm.enabler.utils.HttpUrl("/");
        }
    }
}
);

}

if(!dojo._hasResource["com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl");






dojo.declare("com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl", [com.ibm.mm.enabler.model.url.BaseModelUrl], {
    constructor: function(url, model) {
        if (!com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl.CONTEXT_ROOT) {
            com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl.CONTEXT_ROOT = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT);

            com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl.PRIVATE_HANDLER = com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl.CONTEXT_ROOT +
            com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PRIVATE);

            com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl.PUBLIC_HANDLER = com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl.CONTEXT_ROOT +
            com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PUBLIC);
        }

        if (url.indexOf("?") === 0) {
            // add the public contenthandler url
            var anonymousUser = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.ANONYMOUS_USER);

            var contenthandlerPath;

            if (anonymousUser) {
                contenthandlerPath = com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl.PUBLIC_HANDLER;
            }
            else {
                contenthandlerPath = com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl.PRIVATE_HANDLER;
            }

            var newURL = "";

            // add contenthandlerPath
            newURL += contenthandlerPath;


            url = newURL + url;
        }

        this.httpUrl = new com.ibm.mm.enabler.utils.HttpUrl(url);
    }
});


}

if(!dojo._hasResource["com.ibm.mm.enabler.model.url.ModelUrlFactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.url.ModelUrlFactoryImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.url.ModelUrlFactoryImpl");









dojo.declare("com.ibm.mm.enabler.model.url.ModelUrlFactoryImpl", [com.ibm.mashups.enabler.model.url.ModelUrlFactory], {
    WEBDAV_URL: "webdav",

    /**
     * @private
     **/
    constructor: function() {
        this.schemeMap = {};
        this.schemeMap[this.NAVIGATION_URL] = "nm";
        this.schemeMap[this.SHARED_NAVIGATION_URL] = "snm";
        this.schemeMap[this.FRAGMENT_URL] = "fragment";
        this.schemeMap[this.FRAGMENT_MEDIA_URL] = "fragment-media";
        this.schemeMap[this.USER_URL] = "um";
        this.schemeMap[this.THEME_URL] = "theme";
        this.schemeMap[this.THEME_MEDIA_URL] = "theme-media";
        this.schemeMap[this.CATALOG_URL] = "catalog";
        this.schemeMap[this.CONFIG_URL] = "config";
        this.schemeMap[this.SPACE_URL] = "space";
        this.schemeMap[this.SPACE_FAVORITE_URL] = "space-favorite";
        this.schemeMap[this.AC_URL] = "ac";
        this.schemeMap[this.AI_URL] = "ai";
        this.schemeMap[this.TEMPLATE_URL] = "template";
        this.schemeMap[this.LAYOUT_URL] = "lm";
        // internal, not exposed
        this.schemeMap.service = "service";
        this.schemeMap[this.WEBDAV_URL] = "dav:mmdav";
        this.schemeMap[this.WIDGET_URL] = "wm";
        this.schemeMap[this.EVENT_URL]  = "ce";
        this.schemeMap[this.RESOURCE_URL]  = "resource-service";
    },

    // @deprecated
    createModelUrl: function(urlType, model) {
        return this.createModelURL(urlType, model);
    },
    createModelURL: function(urlType, model) {
        var modelSchema = com.ibm.mashups.enabler.model.url.ModelUrlFactory.schemeMap[urlType];

        if (!modelSchema) {
            return null;
        }

        var urlImpl;
        if (urlType == this.THEME_MEDIA_URL) {
            urlImpl = new com.ibm.mm.enabler.model.url.ThemeResourceUrlImpl(modelSchema, model);
        }
        else if (urlType == this.FRAGMENT_MEDIA_URL) {
            urlImpl = new com.ibm.mm.enabler.model.url.SchemeBasedModelMediaUrlImpl(modelSchema, model);
        }
        else {
            urlImpl = new com.ibm.mm.enabler.model.url.SchemeBasedModelUrlImpl(modelSchema, model);
        }
        return urlImpl;
    },

    // @deprecated
    getModelUrl: function(url, model) {
        return this.getModelURL(url, model);
    },
    getModelURL: function(url, model) {
        return new com.ibm.mm.enabler.model.url.StringBasedModelUrlImpl(url, model);
    }
});
// legacy
com.ibm.mm.enabler.model.UrlFactory = new com.ibm.mm.enabler.model.url.ModelUrlFactoryImpl();
// define public factory
com.ibm.mashups.enabler.model.url.ModelUrlFactory = com.ibm.mm.enabler.model.UrlFactory;
}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.url.ModelUrlFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.url.ModelUrlFactory"] = true;
dojo.provide("com.ibm.mashups.enabler.model.url.ModelUrlFactory");






}

if(!dojo._hasResource["com.ibm.mm.enabler.SubmittableFormProviderImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.SubmittableFormProviderImpl"] = true;
dojo.provide("com.ibm.mm.enabler.SubmittableFormProviderImpl");






// submittable form provider
dojo.declare("com.ibm.mm.enabler.SubmittableFormProviderImpl", com.ibm.mashups.enabler.SubmittableFormProvider, {
    constructor: function(){
    },

    /**
     * Returns a SubmittableForm object associated with the given id.
     * @param {String} id the id of the html form this object is associated with
     * @return {SubmittableForm} SubmittableForm object, maybe <code>null</code>
     */
    getSubmittableForm: function(id){
        var model = null;
        var url;
        if (id == "spaceForm") {
            url = new com.ibm.mashups.enabler.model.url.ModelUrlFactory.createModelURL(com.ibm.mashups.enabler.model.url.ModelUrlFactory.SPACE_URL, null);
            url.setNodes([{
                value: "collection",
                isID: false
            }]);
            url.setParameter("mode", "import");
            url.setParameter("mime-type", "text/html");

            url = url.toProxifiedString();
            /*"/mum/mycontenthandler?uri=space:collection&mode=import"*/
            model = new com.ibm.mm.enabler.SubmittableFormImpl(url, "post", id);
        }
        else
            if (id == "pageForm") {
                var serviceJson = com.ibm.mm.enabler.model.ServiceDocumentModel.getCollectionData(com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_RESOURCE);
                url = new com.ibm.mashups.enabler.model.url.ModelUrlFactory.getModelURL(serviceJson.url, this);
                url.setParameter("mode", "import");
                url.setParameter("mime-type", "text/html");
                // post the spaceId to server.
                if (arguments[1]) {
                    url.setParameter("spaceId", arguments[1]);
                }

                url = url.toProxifiedString();
                /*"/mum/mycontenthandler?uri=resource:collection&mode=import"*/
                model = new com.ibm.mm.enabler.SubmittableFormImpl(url, "post", id);
            }
            else
                if (id == "spacePageForm") {
                    url = new com.ibm.mashups.enabler.model.url.ModelUrlFactory.createModelURL(com.ibm.mashups.enabler.model.url.ModelUrlFactory.SPACE_URL, null);
                    url.setNodes([{
                        value: "collection",
                        isID: false
                    }]);
                    url.setParameter("mode", "import");
                    url.setParameter("mime-type", "text/html");
                    // When we import page .data file came from old BSpace data, we should use the import space rest api, and post spaceId to server.
                    if (arguments[1]) {
                        url.setParameter("spaceId", arguments[1]);
                    }

                    // The form id is come from the arguments[2]
                    var postForm = null;
                    if (arguments[2]) {
                        postForm = arguments[2];
                    }
                    url = url.toProxifiedString();
                    /*"/mum/mycontenthandler?uri=space:collection&mode=import"*/
                    model = new com.ibm.mm.enabler.SubmittableFormImpl(url, "post", postForm);
                }
        return model;
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.SubmittableFormProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.SubmittableFormProvider"] = true;
dojo.provide("com.ibm.mashups.enabler.SubmittableFormProvider");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.TimeStamped_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.TimeStamped_API"] = true;
dojo.provide("com.ibm.mashups.enabler.TimeStamped_API");
dojo.provide("com.ibm.mashups.enabler.TimeStamped");

/**
 * Model interface for specific date access properties: This is information such as the
 * creation date or the last modification date of a resource.
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare( "com.ibm.mashups.enabler.TimeStamped", null, {
	/**
     * Returns the creation date of the resource.
     * @return {Date} the creation date, never <code>null</code>.
     */
    getCreated: function () {
    },
    /**
     * Returns the modification date of the resource.
     * @return {Date} the modification date, never <code>null</code>.
     */
    getLastModified: function () {
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.TimeStamped"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.TimeStamped"] = true;
dojo.provide( "com.ibm.mashups.enabler.TimeStamped" );



}

if(!dojo._hasResource["com.ibm.mashups.enabler.Transformable_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.Transformable_API"] = true;
dojo.provide("com.ibm.mashups.enabler.Transformable_API");
dojo.provide("com.ibm.mashups.enabler.Transformable");

/**
 * Interface for resources in the system that can be transformed
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.Transformable", null, {
    /**
     * Returns the xml representation of the resource. It may be modified,
     * e.g. with an xsl transformation.
     * WARNING: Please note that you must change the xml representation
     * of the resource in a compatible way only, since the Enabler API
     * operates on this representation. Otherwise the Enabler API may
     * function incorrectly or break.
     * @return {Object} the xml representation; never <code>null</code>
     */
    getXml: function() {
    },

    /**
     * Sets the specified xml of the resource.
     * WARNING: Please note that you must set a valid xml representation
     * of the resource, since the Enabler API operates on this representation.
     * Otherwise the Enabler API may function incorrectly or break.
     * @param {Object} xml the xml representation to set for the resource
     */
    setXml: function(xml) {
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.TransformableImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.TransformableImpl"] = true;
dojo.provide("com.ibm.mm.enabler.TransformableImpl");




// transformable
dojo.declare("com.ibm.mm.enabler.TransformableImpl", [com.ibm.mashups.enabler.Transformable, com.ibm.mm.enabler.DirtyFlagProviderImpl], {
    constructor: function() {
    },

    getXml: function() {
        return this.xmlData;
    },

    setXml: function(xml, keepClean) {
        this.xmlData = xml;
        if (this._resetCachedRawID) {
            // if this also implements the IdentifiableXml aspect we need to clean out any cached raw id at this point
            this._resetCachedRawID();
        }
        if (!keepClean) {
            this._setDirty();
        }
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.Transformable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.Transformable"] = true;
dojo.provide("com.ibm.mashups.enabler.Transformable");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.TreeModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.TreeModel"] = true;
dojo.provide("com.ibm.mashups.enabler.TreeModel");




/**
 * This interface provides a generic tree model acting as a base class
 * for all concrete tree models
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.TreeModel", [com.ibm.mashups.enabler.model.Model, com.ibm.mashups.enabler.Locator], {
    /**
     * Returns the root node of the model; may return <code>null</code>
     * if the concrete tree model supports for empty models
     *
     * @type    Deferred
     * @return  a deferred object used to start this operation. The
     *          return value when executed through the deferred object
     *          is the root object of the tree model
     */
    getRoot: function(){
    },

    /**
     * Returns whether or not the given node has children. Please pay
     * attention to the documentation of the return value; it is not
     * guaranteed that children are present if the method returns
     * <code>true</code> - the iterator might be empty.
     *
     * @param   {Object} node   node object or node uri (without any scope)
     *                          for which to check if it has children. Must
     *                          not be <code>null</code>.
     * @return {Boolean} <tt>true</tt> if the specified node has children, <tt>false</tt> otherwise
     */
    hasChildren: function(node){
    },

    /**
     * Returns an iterator over the child elements for the given node.
     *
     * @param {Object} node node object or node uri (without any scope)
     *                      for which to return its children. Must not
     *                      be <code>null</code>.
     * @return {com.ibm.mashups.enabler.DeferredIterator} deferred iterator for the children of the given node.
     *          Never <code>null</code>
     */
    getChildren: function(node){
    },

    /**
     * Returns the parent of a given node.
     * @param {Object} node node object or node uri (without any scope)
     *                      for which to return its parent. Must not
     *                      be <code>null</code>.
     * @return {com.ibm.mashups.enabler.Deferred} a deferred object used to start this operation. The
     *          return value when executed through the deferred object
     *          is the parent of the given node, or <code>null</code>
     *          if the node has no parent
     */
    getParent: function(node){
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.TreeModelController"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.TreeModelController"] = true;
dojo.provide("com.ibm.mashups.enabler.TreeModelController");



/**
 * This modifiable interface provides a generic tree model acting as a base class
 * for all concrete tree models
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.TreeModelController", com.ibm.mashups.enabler.TreeModel, {
    /**
     * creates a new model object. The created node can be inserted
     * into the model using an appropriate <code>insert</code> method defined
     * on a subinterface of this interface. The node will not appear in the model
     * unless it is inserted.
     * @param {JSON} context array of predefined information
     * used for the creation of the node. May be <code>null</code>. Accepted
     * names are defined in the appropriate subinterfaces
     * @type Object
     * @return the created node
     */
    create: function(context){
    },

    /**
     * Confirms whether creating the node is possible.
     * @param {JSON} context array of predefined information
     * used for the creation of the node. May be <code>null</code>. Accepted
     * names are defined in the appropriate subinterfaces
     * @return {Boolean} true if the node can be created, otherwise false.
     */
    confirmCreate: function(context){
    },

    /**
     * Inserts a node into the tree model at the specified location;
     * the node must either be created with the create method of the
     * concrete tree model before, or must exist in the tree model;
     * in this case the existing node is moved to the specified location
     *
     * @param {Object} node         node to insert or move. Must not be
     *                              <code>null</code>.
     * @param {Object} parentNode   node object or node uri (without any
     *                              scope) of the parent node. The given
     *                              node is inserted/moved underneath the
     *                              parent node; must not be <code>null</code>.
     * @param {Object} nextNode     node object or node uri (without any
     *                              scope) of the successor node before
     *                              which the node is to be inserted;
     *                              if <code>null</code> is specified,
     *                              the node is appended at the end of
     *                              the existing nodes
     * @type void
     */
    insert: function(node, parentNode, nextNode){
    },

    /**
     * Confirms whether inserting the node is possible.
     * @param {Object} node         node to insert or move. Must not be
     *                              <code>null</code>.
     * @param {Object} parentNode   node object or node uri (without any
     *                              scope) of the parent node. The given
     *                              node is inserted/moved underneath the
     *                              parent node; must not be <code>null</code>.
     * @param {Object} nextNode     node object or node uri (without any
     *                              scope) of the successor node before
     *                              which the node is to be inserted;
     *                              if <code>null</code> is specified,
     *                              the node is appended at the end of
     *                              the existing nodes
     * @return {Boolean} true if the node can be inserted, otherwise false.
     */
    confirmInsert: function(node, parentNode, nextNode){
    },

    /**
     * Deletes a node from the model. All its children are deleted as well.
     *
     * @param {Object} node node object or node uri (without any scope)
     *                      to delete from the model. Must not be <code>null</code>.
     * @type void
     */
    remove: function(node){
    },

    /**
     * Confirms whether removing the node is possible.
     * @param{Object} node  node object or node uri (without any scope).
     *                      Must not be <code>null</code>
     * @return {Boolean} true if the node can be removed, otherwise false.
     */
    confirmRemove: function(node){
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.io.DynamicResolver_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.io.DynamicResolver_API"] = true;
dojo.provide("com.ibm.mashups.enabler.io.DynamicResolver_API");
dojo.provide("com.ibm.mashups.enabler.io.DynamicResolver");

/**
 * This provides a system plugin point where extensions can be registered
 * to provide immediate resolution of IO requests for data that can be
 * retrieved from the client.  It allows circumvention of remote requests
 * to serve data that is already available in the system.  It also allows
 * an completely extensible URL naming system such that URLs passed to
 * IO requests can take on formats besides typical ones such as http or https.
 * Extension formats and schemes can be handled by custom plugins to allow
 * an arbitrary mapping of resources on the client to URLs that can be serviced
 * through normal IO requests.
 * The service can be retrieved using the following code: <br>
 * <code>var dynamicResolver = com.ibm.mashups.services.ServiceManager.getService(<br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;com.ibm.mashups.enabler.io.DynamicResolver.SERVICE_NAME);</code><br/>
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.io.DynamicResolver", null, {
	/**
     * The service name to be used to fetch the service from the ServiceManager
     * @type String
     */
	SERVICE_NAME: "dynamicResolver",
	/**
	 * Registers a plugin for immediate request resolution.
	 * @param {String} id the id of the plugin
	 * @param {Function} matcher the function that returns a validation result
	 * to verify if the plugin can resolve the current request.  Function format:
	 * <code>Function(String url)</code>.<br>
	 * This function must return a "truthy" value to indicate that it can resolve
	 * this request, or a "falsy" value if it cannot.  Whatever this function returns
	 * will be passed into the plugin's resolver function as the second argument.
	 * @param {Function} resolver the function that resolves the current request
	 * and passes the response data back to the caller.  Function format:
	 * <code>Function(String url, Anything validationResult)</code>.<br>
	 * This function must return the data for the response.
	 * @param {Boolean} first optional argument to specify if this plugin should
	 * take precedence over all existing plugins if set to true.  If it is false
	 * the plugin will take lowest precedence of existing plugins.  Default is false.
	 * @type void
	 */
	register: function(/*String*/ id, /*Function*/matcher, /*Function*/resolver, /*Boolean?*/first) {
	},
	/**
	 * Unregisters a plugin by its registered id.
	 * @param {String} id the id of the plugin to unregister
	 * @type void
	 */
	unregister: function(/*String*/id) {
	}
});
com.ibm.mashups.enabler.io.DynamicResolver.SERVICE_NAME = "dynamicResolver";

}

if(!dojo._hasResource["com.ibm.mm.enabler.io.XHRWrapper"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.io.XHRWrapper"] = true;
dojo.provide("com.ibm.mm.enabler.io.XHRWrapper");

dojo.declare("com.ibm.mm.enabler.io.XHRWrapper", null, {
    constructor: function(ioArgs, partString, statusCode, contentType, partHeaders) {
        this.ioArgs = ioArgs;
        this.xhr = ioArgs.xhr;
        this.readyState = ioArgs.xhr.readyState;
        this.responseText = partString;
        this.responseXML = ioArgs.xhr.responseXML;
        this.status = statusCode;
        this.statusText = ioArgs.xhr.statusText;
        this.contentType = contentType;
        this.partHeaders = partHeaders;
    },

    getAllResponseHeaders: function() {
        return this.xhr.getAllResponseHeaders();
    },

    getInterface: function() {
        return this.xhr.getInterface();
    },

    getResponseHeader: function(header) {
        var headerString = header + '';

        if (this.partHeaders[headerString]) {
            return this.partHeaders[headerString];
        } else if (headerString.toLowerCase() == "content-type") {
            return (this.contentType);
        }
        return this.xhr.getResponseHeader(header);
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.io.DynamicResolver"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.io.DynamicResolver"] = true;
dojo.provide("com.ibm.mm.enabler.io.DynamicResolver");






dojo.declare("com.ibm.mm.enabler.io.DynamicResolver", com.ibm.mashups.enabler.io.DynamicResolver, {
    constructor: function(){
        this._plugins = []; // each plugin has format -> [id,matchFn,resolveFn]
        // Wrap dojo.xhr; if a resolver is found, use it, otherwise delegate to unwrapped dojo.xhr
        var me = this, origXhr = dojo.xhr;
        dojo.xhr = function(){
            var fn = me.getResolver.apply(me, arguments) || origXhr;
            return fn.apply(this, arguments);
        };
    },
    _buildDfdFn: function(fname, obj, ioArgs){
        var func = obj[fname];
        return func ? function(val){
            return func.call(obj, val, ioArgs);
        }
 : null;
    },
    resolve: function(/*Function*/resolver, /*Object*/ validationResult, /* String */ method, /* dojo.__XhrArgs */ args, /* Boolean */ hasBody){
        // called in scope of original xhr call, not in DynamicResolver instance scope
        var data = null, isErr = false, dfd = new dojo.Deferred(), ioArgs = { // dojo.__IoCallbackArgs
            args: args,
            url: com.ibm.mm.enabler.EndpointUtils.checkForEndpoints(args.url) || args.url, // check for endpoint URLs
            handleAs: args.handleAs || "text",
            xhr: { // need this stubbed out for XHRWrapper
                readyState: 4,
                responseXML: null,
                statusText: ""
            }
        };
        dfd.addCallback(this._buildDfdFn("load", args, ioArgs)).addErrback(this._buildDfdFn("error", args, ioArgs)).addBoth(this._buildDfdFn("handle", args, ioArgs));
        ioArgs.xhr = new com.ibm.mm.enabler.io.XHRWrapper(ioArgs, "", 200, "text", {});
        try {
            data = resolver(ioArgs.url, validationResult); // use potentially endpoint-resolved URL
            ioArgs.xhr.status = 200;
            if (data) {
                ioArgs.xhr.responseText = data;
                if (args.handleAs === "xml" && typeof data === "string") {
                    // create document object from text string
                    ioArgs.xhr.responseXML = com.ibm.mm.enabler.utils.Dom.createDocument(data);
                }
            }
        }
        catch (err) {
            ioArgs.xhr.status = 500;
            data = err;
            ioArgs.xhr.responseText = err.toString();
            isErr = true;
        }
        dfd[isErr ? "errback" : "callback"](data);
        return dfd; // dojo.Deferred
    },
    _embedValidation: function(fn, vResult){
        var me = this;
        return function(method, args, hasBody){
            return me.resolve(fn, vResult, method, args, hasBody);
        };
    },
    getResolver: function(/* String */method, /* dojo.__XhrArgs */ args, /* Boolean */ hasBody){
        if (method && method.toLowerCase() == "get") {
            for (var i = 0; i < this._plugins.length; i++) {
                var plg = this._plugins[i];
                var ret = plg[1](args.url);
                if (ret) {
                    // escape closure around the unnecessaries
                    return this._embedValidation(plg[2], ret);
                }
            }
        }
        return null;
    },
    register: function(/*String*/id, /*Function*/ plgMatcher, /*Function*/ plgResolver, /*Boolean?*/ first){
        this._plugins[first ? "unshift" : "push"]([id, plgMatcher, plgResolver]);
    },
    unregister: function(/*String*/id){
        for (var i = 0; i < this._plugins.length; i++) {
            if (id === this._plugins[i][0]) {
                this._plugins.splice(i, 1);
                return;
            }
        }
    }
});

com.ibm.mashups.services.ServiceManager.setService(com.ibm.mashups.enabler.io.DynamicResolver.SERVICE_NAME, "com.ibm.mm.enabler.io.DynamicResolver");

}

if(!dojo._hasResource["com.ibm.mashups.enabler.io.DynamicResolver"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.io.DynamicResolver"] = true;
dojo.provide("com.ibm.mashups.enabler.io.DynamicResolver");




}

if(!dojo._hasResource["com.ibm.mashups.enabler.io.XHRMultipart_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.io.XHRMultipart_API"] = true;
dojo.provide("com.ibm.mashups.enabler.io.XHRMultipart_API");
dojo.provide("com.ibm.mashups.enabler.io.XHRMultipart");

/**
 * Provides Dojo XHR support.  Requests are batched together via a transaction
 * concept - Dojo XHR requests which are made between the start and end
 * transaction calls will be batched.  This would include any Dojo API's which would
 * use Dojo XHR.  If the com.ibm.mashups.multipart.correlatehosts
 * Configuration Service property is set to true, multipart requests will be
 * split by hostname.
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.io.XHRMultipart", null, {
    /**
     * @private
     */
    constructor: function() {
    },

    /**
     * Begins a multipart transaction.  If the com.ibm.mashups.multipart.enabled
     * property is set to false, this method simply returns.
     * @type void
     */
    startTransaction: function() {
    },

    /**
     * Ends a multipart transaction and submits the multipart request to
     * the server.  If the com.ibm.mashups.multipart.enabled
     * property is set to false, this method simply returns.
     * @return {DeferredOperation} a deferred object used to start this operation.
     * The return value when executed through the deferred object is <code>null</null>
     */
    endTransactionDeferred: function() {
    },

	/**
     * Ends a multipart transaction and submits the multipart request to
     * the server.  If the com.ibm.mashups.multipart.enabled
     * property is set to false, this method simply returns.
     * @param {Object} callback the callback funtion in the format of <code>Function(Object[] params)</code>. May be <code>null</code><br>
     * &nbsp;&nbsp;&nbsp;&nbsp;<b>Callbackparameters</b><br>
     * &nbsp;&nbsp;&nbsp;&nbsp;<code>params</code> - the parameters
     * passed into the callback
     * @param {Object[]} parameters optional array of parameters to be
     * passed on to the callback function. May be <code>null</code>
     * @type void
     * @deprecated Use endTransactionDeferred instead.
     */
    endTransaction: function(callback, parameters) {
    },

    /**
     * Suspends a mulitpart transaction, allowing normal XHR requests
     * to be made.  If the com.ibm.mashups.multipart.enabled
     * property is set to false, this method simply returns.
     * @type void
     */
    suspendTransaction: function() {
    },

    /**
     * Resumes a mulitpart transaction.  If the com.ibm.mashups.multipart.enabled
     * property is set to false, this method simply returns.
     * @type void
     */
    resumeTransaction: function() {
    },

    /**
     * Returns if there is an active multipart transaction
     * @return {Boolean} <code>true</code> if there is an active multipart
     * transaction, <code>false</code> otherwise
     */
    isTransaction: function() {
        return false;
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.ServiceDocConsumer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.ServiceDocConsumer"] = true;
dojo.provide("com.ibm.mm.enabler.ServiceDocConsumer");

dojo.declare("com.ibm.mm.enabler.ServiceDocConsumer",null,{
	_noop: function(){},
	_initServiceDoc: function() {
		this._initServiceDoc = this._noop;	// turns this init into a noop for this object
	}
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.encode.huffman.ZEncoder"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.encode.huffman.ZEncoder"] = true;
dojo.provide("com.ibm.mm.enabler.encode.huffman.ZEncoder");



dojo.declare("com.ibm.mm.enabler.encode.huffman.ZEncoder", null, {
    HEX_CHARS: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"],
    UNSAFE_CHARS: "$&+,/:;=?@ <>#%{}|\\^~[]`\"Z",

    constructor: function() {
    },

    isUnsafeChar: function(testChar) {
        if (this.UNSAFE_CHARS.indexOf(testChar) > -1 || testChar.charCodeAt(0) <= 32 || testChar.charCodeAt(0) >= 123) {
            return true;
        }

        return false;
    },

    zEncode: function(value) {
        var retVal = "";
        for (var i = 0; i < value.length; ++i) {
            var currentChar = value.charAt(i);
            if (!this.isUnsafeChar(currentChar)) {
                retVal += currentChar;
                continue;
            }

            retVal += this.zEncodeChar(currentChar);
        }

        return retVal;
    },

    zEncodeChar: function(plainChar) {
        var magicChar = "Z";

        return magicChar + this.byteToHex(plainChar.charCodeAt(0));
    },

    byteToHex: function(byteValue) {
        var upper = Math.floor(byteValue / 16);
        var lower = byteValue % 16;

        return this.HEX_CHARS[upper] + this.HEX_CHARS[lower];
    },
    zDecode: function(value) {
        var retVal = "";
        var magicChar = "Z";

        if (value.indexOf(magicChar) != -1) {

            for (var i = 0, l = value.length; i < l; i++) {
                var charX = value.charAt(i);
                if (charX == magicChar) {
                    var hex = "0x" + value.substr(i + 1, 2);
                    i = i + 2;
                    try {
                        var charCode = parseInt(hex,16);
                        retVal = retVal.concat(String.fromCharCode(charCode));
                    }
                    catch (e) {
                        continue;
                    }
                }
                else {
                    retVal = retVal.concat(value.substr(i, 1)); //concat character
                }
            }
        }
        else {
            retVal = value;
        }
        return retVal;
    }
});

com.ibm.mm.enabler.encode.huffman.ZEncoder = new com.ibm.mm.enabler.encode.huffman.ZEncoder();

}

if(!dojo._hasResource["com.ibm.mm.enabler.encode.huffman.HuffmanURL"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.encode.huffman.HuffmanURL"] = true;
dojo.provide("com.ibm.mm.enabler.encode.huffman.HuffmanURL");





dojo.declare("com.ibm.mm.enabler.encode.huffman.HuffmanURL", null, {
    // alphabet used for base64 encoding, this is NOT the default base64 alphabet but an alphabet that only contains URL safe characters
    URL_ALPHABET: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_!",
    constructor: function() {
    },

    /** Encodes the huffman codes of the tokens in the alphabet into a stream
     * @param the target stream
     * @param the map between token and prefix
     * @param the array of tokens to encode
     */
    _encodeTokens: function(stream, nodes, tokens) {
        // iterate over all tokens
        var len = tokens.length;
        for (var i = 0; i < len; ++i) {
            // add the code for the token
            this._addBits(stream, nodes[tokens[i]].prefix);
        }
        // return the stream
        return this._encodeStream(stream);
    },

    /** Encodes the dwords in the stream into a base64 encoded string
     *
     * @param stream stream to encode
     * @return a string of the base64 encoded dwords
     */
    _encodeStream: function(stream) {
        // number of bytes to encode
        var len = stream.dwords.length * 4;
        // push the last dword
        if (stream.bits > 0) {
            // add the last dword
            stream.dwords.push(stream.dword);
            // update the length
            len += ((stream.bits + 0x07) >> 0x03);
            stream.bits = 0;
        }
        // compute the number of bytes and encode
        return this._encodeBase64(stream.dwords, 0, len);
    },

    /* Initializes the stream object
     * @param stream the stream to be initialized
     * @return the actual stream
     */
    _initStream: function(stream) {
        // reset the masks and the current dword
        stream.dword = 0;
        stream.mask = 1;
        stream.bits = 0;
        // start with an empty array of encoded dwords
        stream.dwords = [];
        // the stream
        return stream;
    },

    /* Encode an array of 0/1 values that are stored in the data array into a sequence of 32 bit values stored
     * in the stream.
     *
     * @param stream target stream that contains a dword array
     * @param data the data array of 0/1 values to be encoded
     */
    _addBits: function(stream, data) {
        // cache the data in local variables and save it back to the stream object at the end
        var mask = stream.mask, dword = stream.dword, bits = stream.bits;
        // add all bits sequentially
        var len = data.length, off = 0;
        while (len > 0) {
            // check how many bits we can add in a batch
            var copy = Math.min(len, 0x20 - bits);
            for (var i = 0; i < copy; ++i) {
                // add the bit
                if (data[off + i] == 1) {
                    dword |= mask;
                }
                mask <<= 1;
            }
            // update
            bits += copy;
            len -= copy;
            off += copy;
            // check for an overflow
            if (bits == 0x20) {
                // add the new word
                stream.dwords.push(dword);
                bits = 0;
                mask = 1;
                dword = 0;
            }
        }
        // update the object
        stream.mask = mask;
        stream.bits = bits;
        stream.dword = dword;
    },

    /* Adds a single bit (0/1) to the the stream
     * @param stream target stream that contains a dword array
     * @param bit to be encoded, must be 1 or 0
     */
    _addBit: function(stream, bit) {
        // add to the dword
        if (bit == 1) {
            stream.dword |= stream.mask;
        }
        stream.mask <<= 1;
        stream.bits++;
        // check for the max mask
        if (stream.bits == 0x20) {
            // add the dword to the list
            stream.dwords.push(stream.dword);
            stream.dword = 0;
            stream.mask = 1;
            stream.bits = 0;
        }
    },

    /**  encodes the data into base64 format, the data is packed in 32bit integer values in little endian notation.
     * Offset and length refer to the actual bytes, not the dwords. */
    _encodeBase64: function(data, off, len) {
        // cache the alphabet
        var ab = this.URL_ALPHABET;
        // starting dword and offset of the byte inside the dword
        var srcIdx = off >> 0x02;
        var shift = off & 0x03;
        // the current dword and a place holder for the next (wrapping) dword
        var value = data[srcIdx++], newValue;
        // the four 6-bit numbers that we decode from three consequtive bytes
        var c1, c2, c3, c4;
        // the resulting base64 encoding
        var result = "";
        // iterate over the range of bytes in three-byte tuples
        for (var i = len; i > 0; i -= 3) {
            /** get the next three bytes. We use direct bit operations based on the packing.
             */
            switch (shift) {
                case 0:
                    // all bytes are available inside the dword
                    c1 = ((value >> 0x02) & 0x3f);
                    c2 = ((value << 0x04) & 0x30) | ((value >> 0x0c) & 0x0f);
                    c3 = ((value >> 0x06) & 0x3c) | ((value >> 0x16) & 0x03);
                    c4 = ((value >> 0x10) & 0x3f);
                    // next shift
                    shift = 3;
                    break;
                case 1:
                    // all bytes are available inside the dword
                    c1 = ((value >> 0x0a) & 0x3f);
                    c2 = ((value >> 0x04) & 0x30) | ((value >> 0x14) & 0x0f);
                    c3 = ((value >> 0x0e) & 0x3c) | ((value >> 0x1e) & 0x03);
                    c4 = ((value >> 0x18) & 0x3f);
                    // next shift
                    shift = 0;
                    value = data[srcIdx++];
                    break;
                case 2:
                    // wrap around to the next dword
                    newValue = data[srcIdx++];
                    c1 = ((value >> 0x12) & 0x3f);
                    c2 = ((value >> 0x0c) & 0x30) | ((value >> 0x1c) & 0x0f);
                    c3 = ((value >> 0x16) & 0x3c) | ((newValue >> 0x06) & 0x03);
                    c4 = (newValue & 0x3f);
                    // next shift
                    value = newValue;
                    shift = 1;
                    break;
                case 3:
                    // wrap around to the next dword
                    newValue = data[srcIdx++];
                    c1 = ((value >> 0x1A) & 0x3f);
                    c2 = ((value >> 0x14) & 0x30) | ((newValue >> 0x04) & 0x0f);
                    c3 = ((newValue << 0x02) & 0x3c) | ((newValue >> 0x0e) & 0x03);
                    c4 = ((newValue >> 0x08) & 0x3f);
                    // next shift
                    value = newValue;
                    shift = 2;
                    break;
            }
            // padding
            switch (i) {
                case 1:
                    c3 = 0x40;
                    c4 = 0x40;
                    break;
                case 2:
                    c4 = 0x40;
                    break;
            }
            // construct the 4-character tuple
            result += ab.charAt(c1);
            result += ab.charAt(c2);
            result += ab.charAt(c3);
            result += ab.charAt(c4);
        }
        // return the result of the encoding process
        return result;
    },
    //decode encoded string
    //conver 4 byte into 3
    //return an array of charcode
    //first item in the array should be the right most in bit stream...
    _decodeBase64: function(encodedStr) {
        var ab = this.URL_ALPHABET;
        var len = encodedStr.length / 4;
        var i = 0;
        var array = []; //each array item contains 3 char
        for (var j = 0; j < len; j++) {
            var padding = 0;
            indexC1 = ab.indexOf(encodedStr.charAt(i++));
            indexC2 = ab.indexOf(encodedStr.charAt(i++));
            indexC3 = ab.indexOf(encodedStr.charAt(i++));
            if (indexC3 == 64) {
                padding++;
            }
            indexC4 = ab.indexOf(encodedStr.charAt(i++));
            if (indexC4 == 64) {
                padding++;
            }

            c1 = (indexC1 << 2) | (indexC2 >> 4); //this is the last byte (from right)
            c2 = ((indexC2 & 15) << 4) | (indexC3 >> 2); //this is the middle byte
            c3 = ((indexC3 & 3) << 6) | indexC4; //this is the byte on the left
            array.push(c1);
            switch (padding) {
                case 0:
                    array.push(c2);
                    array.push(c3);
                    break;
                case 1:
                    array.push(c2);
                    break;
                case 2:
                    break;
            }
        }
        return array;
    },

    /** Callback used by the sort method to compare nodes by frequency
     */
    _frequencyCompare: function(n1, n2) {
        return n1.frequency - n2.frequency;
    },

    /** Initializes the encoding and the prefixes of the huffman tree. The
     * method writes the tree structure as a bit sequence into the stream and
     * initializes the node prefixes with the huffman code.
     *
     * @param stream    the stream that contains the tree structure and the sequence of the node names
     * @param node      the current node in the tree to encode
     * @param prefix    the huffman prefix of the parent node, an array that contains 0/1 bits
     */
    _initTree: function(stream, node, prefix) {
        // iterate into the children
        if (node.left && node.right) {
            // add to the stream
            this._addBit(stream, 1);
            // recurse the left and right branch
            this._initTree(stream, node.left, prefix.concat(0));
            this._initTree(stream, node.right, prefix.concat(1));
        }
        else {
            // add to the stream
            this._addBit(stream, 0);
            // this is our huffman code!
            node.prefix = prefix;
            // add this node
            stream.tokens.push(node.name);
        }
        // ok
        return stream;
    },

    _dumpTokens: function(tree, nodes) {
    },

    /** Constructs the huffman tree from the token sequence
     *
     * @param array of tokens
     * @return the URL that encodes the tokens
     */
    _buildTree: function(tokens) {
        // build a list of token frequencies
        var nodes = {};
        // iterate and fill the node map
        var len = tokens.length;
        var node, i;
        for (i = len - 1; i >= 0; --i) {
            // do we know the node?
            var token = tokens[i];
            node = nodes[token];
            if (node) {
                // increment the frequency of the node
                node.frequency++;
            }
            else {
                // construct the new token
                node = {
                    frequency: 1,
                    name: token
                };
                // add the node
                nodes[token] = node;
            }
        }
        // produce a sorted list based on the frequencies
        var queue = [];
        for (node in nodes) {
            if (Object.prototype.hasOwnProperty.call(nodes,node)) {
                queue.push(nodes[node]);
            }
        }
        queue.sort(this._frequencyCompare);
        // build the huffman tree
        while (queue.length > 1) {
            // remove the smallest items
            var left = queue.shift(), right = queue.shift();
            // construct the new, combined node
            queue.push({
                frequency: left.frequency + right.frequency,
                left: left,
                right: right
            });
            queue.sort(this._frequencyCompare);
        }
        // now, we have the tree, initialize its huffman codes
        var root = queue[0];
        var tree = this._initTree(this._initStream({
            tokens: []
        }), queue.shift(), []);

        this._dumpTokens(tree, nodes);

        // serialize the tree into a prefix
        var url = this._encodeStream(tree);
        // append the tokens
        len = tree.tokens.length;
        for (i = 0; i < len; ++i) {
            url += "/" + com.ibm.mm.enabler.encode.huffman.ZEncoder.zEncode(tree.tokens[i]);
        }
        // serialize the huffman codes
        url += "/" + this._encodeTokens(this._initStream({}), nodes, tokens);
        // return the url
        return url;
    },

    /**  Constructs the huffman tree from a data string an a regular expression that splits
     * the string into tokens. The delimiters are considered part of the tokens.
     * @param data the data string to split
     * @param regexStrg the regular expression string, e.g. "[\/\.<>]"
     *
     * @return the encoded URL
     */
    _buildTreeFromRegex: function(data, regexStrg) {
        // compile the regex
        var regex = new RegExp(regexStrg, "g");
        // record the split positions
        var pos = [];
        var result;
        while ((result = regex.exec(data))) {
            pos.push(result.index);
        }
        // padding
        if (pos[0]) {
            pos.unshift(0);
        }
        if (pos[pos.length - 1] != data.length) {
            pos.push(data.length);
        }
        // split
        var tokens = [];
        for (result = 1; result < pos.length; ++result) {
            tokens.push(data.substring(pos[result - 1], pos[result]));
        }
        // construct the URL
        return this._buildTree(tokens);
    },

    /** Constructs the huffman tree from the token sequence
     *
     * @param array of tokens
     * @return the URL that encodes the tokens
     */
    createRawSchemeSpecificPartFromTokens: function(tokens) {
        return this._buildTree(tokens);
    },

    /**  Constructs the huffman tree from a data string an a regular expression that splits
     * the string into tokens. The delimiters are considered part of the tokens.
     * @param data the data string to split
     * @param regexStrg the regular expression string, e.g. "[\/\.<>]"
     *
     * @return the encoded URL
     */
    createRawSchemeSpecificPartFromRegex: function(data, regexStrg) {
        return this._buildTreeFromRegex(data, regexStrg);
    },

    /** Restores data from the encoded huffman tree based on  the token sequence
     * @param  url encoded data
     * @return the data string that's decoded from huffman tree
     */
    getDataFromHuffmanTree: function(tree) {
        return this._restoreData(tree);
    },
    _restoreData: function(tree) {
        if (!tree) {
            return null;
        }
        var i0 = tree.indexOf("/");
        var i1 = tree.lastIndexOf("/");
        if ((i0 >= 0) && (i1 >= 0)) {
            var treeStream = this._decodeBase64(tree.substring(0, i0));
            var encodedToken = tree.substring(i0 + 1, i1).split("/");
            var codeStream = this._decodeBase64(tree.substring(i1 + 1));
            //array of decoded tokens
            encodedTokens = this._decodeTokens(encodedToken);
            //build tree with token
            var root = this._readStructure(this._convertBitToChar(treeStream), encodedTokens);

            var bitArr = this._convertBitToChar(codeStream);
            var retVal = "";
            while (bitArr.length > 0) {
                retVal = this._buildData(retVal, bitArr, root);
            }
            return retVal;
        }
        return null;
    },
    _buildData: function(retVal, bitArr, root) {
        var found = false;
        var node = null;
        while (!found) {
            var bit = bitArr.shift();
            if (typeof bit == "undefined") {
                node = null;
                break;
            }
            node = this._getNode(bit, root);
            if (node && node.token && node.token) {
                found = true;
            }
            else if (!node) {
                found = true;
            }
            root = node;
        }
        if (found && node) {
            retVal = retVal.concat(node.token);
        }
        return retVal;
    },
    _getNode: function(bit, parent) {
        //0 --left, 1--right
        var node = null;
        node = (bit == 1) ? parent.right : parent.left;
        if (!node) {
            return null;
        }
        return node;
    },
    _convertBitToChar: function(charCodeArr) {
        var arr = [];
        var mask = 0x01;
        var bit = 0;
        for (var i = 0; i < charCodeArr.length; i++) {
            var charCode = charCodeArr[i];
            for (var j = 0; j < 8; j++) {
                bit = charCode & mask;
                arr.push(bit);
                charCode = (charCode >> 1); //remove 1 bit
            }
        }
        return arr;
    },
    _readStructure: function(charArr, encodedTokens) {
        var bit = charArr.shift();
        var node = {};
        if (bit == 1) { // internal node
            node.left = this._readStructure(charArr, encodedTokens);
            node.right = this._readStructure(charArr, encodedTokens);
        }
        else { //leaf node
            var token = encodedTokens.shift();
            node.token = token;
        }
        return node;
    },
    // an array of tokens try to zDecode it
    _decodeTokens: function(encodedToken) {
        var arr = [];
        for (var i in encodedToken) {
            if (Object.prototype.hasOwnProperty.call(encodedToken,i)) {
                arr.push(com.ibm.mm.enabler.encode.huffman.ZEncoder.zDecode(encodedToken[i]));
            }
        }
        return arr;
    }
});

com.ibm.mm.enabler.encode.huffman.HuffmanURL = new com.ibm.mm.enabler.encode.huffman.HuffmanURL();

}

if(!dojo._hasResource["com.ibm.mm.enabler.ArrayMap"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.ArrayMap"] = true;
dojo.provide("com.ibm.mm.enabler.ArrayMap");



dojo.declare("com.ibm.mm.enabler.ArrayMap", null, {
    constructor: function(){
        this.entries = [];
        this.keys = {};
    },
    values: function(){
        return this.entries;
    },
    put: function(/*String*/key,/*object*/ value){
        var index = this.keys[key];
        if (typeof index != 'undefined' && index !== null) {
            this.entries[index] = value;
        }
        else {
            index = this.entries.length;
            this.entries.push(value);
            this.keys[key] = index;
        }
    },
    getKey: function(index){
        if (index < this.entries.length) {
            for (var key in this.keys) {
                if(Object.prototype.hasOwnProperty.call(this.keys,key)) {
                    var temp = this.keys[key];
                    if (temp !== null && temp == index) {
                        return temp;
                    }
                }
            }
        }
        else {
            return null;
        }
    },
    getValue: function(index){
        return (index < this.entries.length) ? this.entries[index] : null;
    },
    get: function(key){
        var index = this.keys[key];
        if (typeof index != 'undefined' && index !== null) {
            var value = this.entries[index];
            return value;
        }
        return null;
    },
    remove: function(key){
        var index = this.keys[key];
        if (typeof index != 'undefined' && index !== null) {
            this.entries.splice(index, 1);
            this.keys[key] = null;
        }
        return index;
    },
    size: function(){
        return this.entries.length;
    },
    keySet: function(){
        var arr = [];
        com.ibm.mm.enabler.utils.Misc.forIn(this.keys,function(value,key) {
            arr.push(key);
        });
        return arr;
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.io.XHRMultipartImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.io.XHRMultipartImpl"] = true;
dojo.provide("com.ibm.mm.enabler.io.XHRMultipartImpl");



















dojo.declare("com.ibm.mm.enabler.io.XHRMultipartImpl", [com.ibm.mashups.enabler.io.XHRMultipart, com.ibm.mm.enabler.ServiceDocConsumer], {
    DYN_RES: com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.io.DynamicResolver.SERVICE_NAME),

    statics: {
        semaphore: 0,
        digest: null,
        suspendedXhr: null
    },

    constructor: function() {
        this.method = "POST";
        this.partsArray = null;
        var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
        this.correlateHosts = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.MULTIPART_CORRELATE_HOSTS);
        this.correlatedHosts = null;
        this.cacheQueries = false;
        var cacheQueriesConfig = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.MULTIPART_CACHE_QUERIES);
        if (typeof(cacheQueriesConfig) !== "undefined" && cacheQueriesConfig !== null && cacheQueriesConfig === true) {
            this.cacheQueries = true;
        }

        this.privateUrl = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT) +
        configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PRIVATE);
        this.publicUrl = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT) +
        configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PUBLIC);
        this.doSiteMap = true;

        this.urlMaxLength = 2000;

        // unique (arbitrary) boundary
        this.boundary = "{EB2F8DA2-5B2C-F66A-CDD0-A2D42143F5AC}";
        this.newL = "\r\n";
        this.sep = "--";
        this.startB = this.newL + this.sep + this.boundary + this.newL;
        this.endB = this.sep + this.boundary + this.sep + this.newL;

        // used to capture the header
        //this.headerRegx = /\r\n\s*([^\r]*)\s*/mg;
        this.headerRegx = new RegExp(this.newL + "\s*([^\r]*)\s*", "mg");// JSLINT-IGNORE: Enabler Team decided to keep this paradigma from dojo in tact
        this.headerPartsRegx = /\s*([^:]*):\s*(.+)/;

        // used to find the boundary
        this.boundaryRegx = /boundary\s*=\s*\"?([^\"]*)\"?/;

        this.multipartParts = false;
        this.replaceDigest = false;
        this.digest = null;
    },

	_initServiceDoc: function() {
		this.inherited("_initServiceDoc", arguments);
		this.doMultipart = com.ibm.mashups.enabler.io.XHRMultipartFactory.isMultipartEnabled();
		if(this.doMultipart) {
			this.serviceMPJson = com.ibm.mm.enabler.model.ServiceDocumentModel.getCollectionData([com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_MODEL, com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_MULTIPART]);
			this.serviceSMJson = com.ibm.mm.enabler.model.ServiceDocumentModel.getCollectionData([com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_MODEL, com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_HUFFMAN]);
            this.serviceCHJson = com.ibm.mm.enabler.model.ServiceDocumentModel.getCollectionData([com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_MODEL, com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_SITEMAP_COMMITHANDLER]);
		}
	},

    _partHandler: function(partArgs, responsePart, ioArgs, partHeaders) {
        var work = dojo.hitch(partArgs, function() {
            try {
                if (com.ibm.mm.enabler.utils.Misc.isInstanceOf(responsePart, Error)) {
                    if (this.error) {
                        this.error(responsePart, ioArgs, partHeaders);
                    }
                }
                else if (ioArgs.xhr.status >= 400) {
                    if (this.error) {
                        this.error(new Error(ioArgs.xhr.status + ":  " + partHeaders.URI), ioArgs, partHeaders);
                    }
                }
                else {
                    if (this.load) {
                        this.load(responsePart, ioArgs, partHeaders);
                    }
                }
                // always call the handle function if it exists
                if (this.handle) {
                    this.handle(responsePart, ioArgs, partHeaders);
                }
            }
            catch (err) {
                // make one attempt to call the error handler
                try {
                    if (this.error) {
                        this.error(responsePart, ioArgs, partHeaders);
                    }
                }
                catch (err2) {
                    //noop
                }
            }
        }); // JSLINT-IGNORE: Enabler Team decided to keep this paradigma from dojo in tact
        work();
    },

    _handleMultiPartResponse: function(parts, multipartParts, scope, response, ioArgs) {
        // Getting the Content-Type header from the response, and extract
        // the boundary string
        var contentType = ioArgs.xhr.getResponseHeader("Content-Type");
        var boundMatch = contentType.match(scope.boundaryRegx);
        if (!boundMatch) {
            throw new Error("No boundary specified in Content-Type response header");
        }
        var bound = boundMatch[1];
        var stripPossibleCharSetIndex = bound.indexOf(";");
        if (stripPossibleCharSetIndex!=-1) {
            bound = bound.substring(0,stripPossibleCharSetIndex);
        }
        // build a regx from the response boundary string used to split the parts
        var splitterRegx = new RegExp(scope.newL + scope.sep + bound, "mg");

        var respParts = response.split(splitterRegx);

        // if handleAs is xml, it comes as text so build it using the domUtilities

        // iterate through the response parts, handling the callbacks for each
        var mpHandler = null;
        if (multipartParts) {
            mpHandler = new com.ibm.mm.enabler.io.XHRMultipartImpl();
            mpHandler.startTransaction();
        }

        var i = 1;
        for (var current in parts) {
            if (Object.prototype.hasOwnProperty.call(parts, current)) {
                var partArgs = parts[current];
                for (var x = 0, l = partArgs.length; x<l; x++) {
                    var requestArgs = partArgs[x];

                    var part = respParts[i++];
                    var partHeaders = {};
                    var header = null;
                    var statusCodeText = null;
                    var contentType = null;

                    scope.headerRegx.lastIndex = 0;
                    // extract the headers for this part, stopping at the blank line
                    while ((header = scope.headerRegx.exec(part)) !== null && (header[1].length > 0)) {
                        // ensure bad headers are not allowed through
                        if (-1 == header[1].indexOf(":")) {
                            continue;
                        }

                        if (-1 == header[1].indexOf("digest=")) {
                            var headerParts = header[1].match(scope.headerPartsRegx);
                            partHeaders[headerParts[1]] = headerParts[2];
                            if (headerParts[1] == "X-Status-Code") {
                                statusCodeText = headerParts[2];
                            }
                            else if (headerParts[1] == "Content-Type") {
                                contentType = headerParts[2];
                            }
                        }
                    }

                    part = dojo.string.trim(part.substr(scope.headerRegx.lastIndex + scope.newL.length));
                    var partString = part;

                    if (requestArgs.handleAs == "xml") {
                        // create document object from text string
                        part = com.ibm.mm.enabler.utils.Dom.createDocument(part);
                    }
                    else {
                        // call the appropriate content handler for this part
                        // dojo.contentHandlers is public since Dojo 1.4
                        part = dojo.contentHandlers[requestArgs.handleAs]({
                            responseText: part
                        });
                    }

                    // Set the appropriate status code
                    var statusCode = parseInt(statusCodeText, 10);
                    var xhrWrapper = new com.ibm.mm.enabler.io.XHRWrapper(ioArgs, partString, statusCode, contentType, partHeaders);
                    var xhr = ioArgs.xhr;
                    ioArgs.xhr = xhrWrapper;
                    scope._partHandler(requestArgs, part, ioArgs, partHeaders);
                    ioArgs.xhr = xhr;
                }
            }
        }
        if (multipartParts) {
            mpHandler.endTransactionDeferred().start();
        }
    },

    _multiPartXhr: function( /*String*/method, /*dojo.__XhrArgs*/ args, /*Array*/ parts, /*boolean*/ multipartParts) {
        // summary: Sends a request with a multi-part body (and content type) to
        //      the server.  Uses dojo.xhr functions under the covers, so the args
        //      object has the same structure as what those functions expect.
        //      The main difference is that this function builds the raw post or put
        //      data automatically from the parts array.  Each item in the parts array
        //      is an object which is a subset of the dojo.__XhrArgs type.  The callbacks
        //      should be specified per part as this function will provide a general
        //      callback that parses the multi-part response and calls the callback
        //      associated with that response part provided in the parts array.
        // method: String specifying the HTTP method used.  Must be either POST or PUT.
        //      Default is POST.
        // args: dojo.__XhrArgs specifying how this XHR should be handled.  The following
        //      properties are not used since they do not make sense in this context -
        //          [form, handle, load, content, handleAs]
        // parts: Array the multiple parts to use to build the multi-part request body.
        //      Each item in the array should be an object with these properties -
        //          {
        //              headers: Object key-value map which is used to write out a
        //                  section at the top of this part in the form key: value.
        //                  Example could be Content-Type of this part of the multi-part
        //                  request.
        //              data: String text to write out the body of this part
        //              load: function(response, ioArgs){} callback called where
        //                  the response body is the body of the part associated this
        //                  request part
        //              error: function(response, ioArgs){} callback called when
        //                  a failure occurs either in the transmission or from the
        //                  server
        //              handle: function(response, ioArgs){} callback called at the
        //                  end of this request with either the response or an error
        //                  if one occured
        //              handleAs: String value indicating how the response body of this
        //                  part should be handled
        //          }
        // returns: Deferred object which can be used to attach additional callbacks to

        var body = "";
        var headersStr = null;
        for (var current in parts) {
            if (Object.prototype.hasOwnProperty.call(parts, current)) {
                for (var entry in parts[current]) {
                    if (Object.prototype.hasOwnProperty.call(parts[current], entry)) {
                        var part = parts[current][entry];
                        part.handleAs = part.handleAs ? part.handleAs.toLowerCase() : "text";
                        headersStr = "";
                        for (var x in part.headers) {
                            if (Object.prototype.hasOwnProperty.call(part.headers, x)) {
                                headersStr += x + ": " + part.headers[x] + this.newL;
                            }
                        }
                        body += this.startB + headersStr + this.newL;
                        if (part.data && part.data.length > 1) {
                            body += part.data + this.newL;
                        }
                        else if (part.postData && part.postData.length > 1) {
                            body += part.postData + this.newL;
                        }
                        else if (part.putData && part.putData.length > 1) {
                            body += part.putData + this.newL;
                        }
                    }
                }
            }
        }

        body += this.endB;

        // if method is PUT, leave it be; otherwise set it to POST
        if (method.toUpperCase() != "PUT") {
            method = "POST";
        }

        var me = this;
        var status;
        var xhrArgs = dojo.mixin({}, args, {
            load: function(response, ioArgs) {
                me._handleMultiPartResponse(parts, multipartParts, me, response, ioArgs);
                status = ioArgs.xhr.status;
            },
            error: function(response, ioArgs) {
                dojo.forEach(parts, function(part) {
                    for (var x = 0, l = part.length; x<l; x++) {
                        var requestArgs = part[x];
                        me._partHandler(requestArgs, response, ioArgs, null);
                    }
                });
                status = ioArgs.xhr.status;
            },
            headers: {
                "Content-type": 'multipart/mixed; boundary="' + me.boundary + '"'
            },
            handleAs: "text",
            form: null,
            content: null,
            postData: null,
            putData: null
        });

        xhrArgs[method.toLowerCase() + "Data"] = body;

        dojo.xhr(method, xhrArgs, true);
        return status;
    },

    suspendTransaction: function() {
        if (0 === this.statics.semaphore) {
            return;
        }

        if (this.statics.suspendedXhr) {
            return;
        }

        this.statics.suspendedXhr = dojo.xhr;
        dojo.xhr = this.statics.oldXhr;
    },

    resumeTransaction: function() {
        if (0 === this.statics.semaphore) {
            return;
        }

        if (!this.statics.suspendedXhr) {
            return;
        }

        dojo.xhr = this.statics.suspendedXhr;
        this.statics.suspendedXhr = null;
    },

    startTransaction: function() {
        this._initServiceDoc();
        if (!this.doMultipart) {
            return;
        }

        this._acquire();

        // return if another handler is in use
        if (1 < this.statics.semaphore) {
            return;
        }

        if (this.correlateHosts) {
            this.correlatedHosts = new com.ibm.mm.enabler.ArrayMap();
        }
        else {
            this.partsArray = [];
        }

        this.statics.oldXhr = dojo.xhr;

        dojo.xhr = dojo.hitch(this, function(/* String */method, /* dojo.__XhrArgs */ args, /* Boolean */ hasBody) {
            var dfd;
            // DynamicResolver will catch this underneath
            if (args.sync) {
                dfd = this.statics.oldXhr(method, args, hasBody);
                return dfd;
            }

            // explicit DynamicResolver support since we may circumvent its
            // wrapped dojo.xhr
            var res = this.DYN_RES.getResolver.apply(this.DYN_RES, arguments);
            if(res) {
            	dfd = res.apply(this, arguments);
                return dfd;
            }

            // Create a header for our method
            var _targetURL = new com.ibm.mm.enabler.utils.HttpUrl(args.url);
            var contentIdHeader = _targetURL.getParameter("uri");

            if (this.doSiteMap && method != "GET") {
                this.doSiteMap = false;
            }
            else if (this.doSiteMap && (!this.cacheQueries) && (method == "GET") &&
            (contentIdHeader) &&
            (null !== contentIdHeader)) {
                this.doSiteMap = false;
            }

            args.method = method;

            if (this.correlateHosts) {
                var proxyURL = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.PROXY_URL);
                var server = _targetURL.server;
                if (null !== proxyURL) {
                    proxyURL += "/";
                    if (args.url.indexOf(proxyURL) === 0) {
                        var index = args.url.indexOf("/", proxyURL.length);
                        server = args.url.substring(0, index);
                    }
                }
                var _partsArray = this.correlatedHosts.get(server);
                if (!_partsArray) {
                    _partsArray = [];
                    this.correlatedHosts.put(server, _partsArray);
                }
                this._addToPartsArray(_partsArray, args);
            }
            else {
                this._addToPartsArray(this.partsArray, args);
            }
        });
    },
    isTransaction: function() {
        return (0 < this.statics.semaphore);
    },

    _encodeUrl: function(url, escapeExclamations) {
        if (escapeExclamations) {
            return escape(url).replace(/\+/g, '%2B').replace(/%20/g, '+').replace(/\*/g, '%2A').replace(/\//g, '%2F').replace(/@/g, '%40').replace(/%21/g, '!');
        }
        return escape(url).replace(/\+/g, '%2B').replace(/%20/g, '+').replace(/\*/g, '%2A').replace(/\//g, '%2F').replace(/@/g, '%40');
    },

    _createHuffmanUrl: function(parts) {
        var cxml = this._createSiteMap(parts);
        cxml = com.ibm.mm.enabler.encode.huffman.HuffmanURL.createRawSchemeSpecificPartFromRegex(cxml, "[/ ]");
        // encode appropriately
        var url;
        this._initServiceDoc();
        if (this.serviceSMJson.template.indexOf('{uri_code}') != -1) {
            cxml = this._encodeUrl(cxml, true);
            url = this.serviceSMJson.template.replace(/\{uri_code\}/, cxml);
        }
        else {
            url = this.serviceSMJson.template.replace(/\{code\}/, cxml);
        }
        // Add/Replace digest
        url = this._updateDigest(url);
        return url;
    },

    _loadResources: function(parts) {
        var status;
        if (this.doSiteMap) {
            var url = this._createHuffmanUrl(parts);
            if (url.length > this.urlMaxLength) {
                // fall back
                status = this._doMultipartPOSTRequest(this.method, parts, this.multipartParts);
            }
            else {
                var me = this;
                xhrArgs = {
                    url: url,
                    load: function(response, ioArgs) {
                        me._handleMultiPartResponse(parts, me.multipartParts, me, response, ioArgs);
                        status = ioArgs.xhr.status;
                    }, // JSLINT-IGNORE: Enabler Team decided to keep this paradigma from dojo in tact
                    error: function(response, ioArgs) {
                        dojo.forEach(parts, function(part) {
                            for (var x = 0, l = part.length; x<l; x++) {
                                var requestArgs = part[x];
                                me._partHandler(requestArgs, response, ioArgs, null);
                            }
                        });
                        status = ioArgs.xhr.status;
                    }, // JSLINT-IGNORE: Enabler Team decided to keep this paradigma from dojo in tact
                    handleAs: "text",
                    sync: true
                };
                dojo.xhrGet(xhrArgs);
            }
        }
        else {
            status = this._doMultipartPOSTRequest(this.method, parts, this.multipartParts);
        }
        return status;
    },


    // deprecated
    endTransaction: function(multipartParts, callback, parameters) {
        if (!this.doMultipart) {
            return;
        }

        this._release();

        // return if another handler is in use
        if (0 < this.statics.semaphore) {
            return;
        }
        dojo.xhr = this.statics.oldXhr;
        var doMultipartParts = false;
        if (multipartParts !== undefined) {
            doMultipartParts = multipartParts;
        }

        var url;
        var xhrArgs;
        var me = this;
        if (this.correlateHosts) {
            var _correlatedHosts = this.correlatedHosts.values();
            for (var i in _correlatedHosts) {
                if (Object.prototype.hasOwnProperty.call(_correlatedHosts, i)) {
                    this._loadResources(_correlatedHosts[i]);
                }
            }

        }
        else {
            // nothing in the parts array
            if (0 === this._assocArraySize(this.partsArray)) {
                return;
            }
            this._loadResources(this.partsArray);
        }

        if (callback) {
            callback(parameters);
        }
    },

    endTransactionDeferred: function(multipartParts) {
        if (typeof multipartParts !== "undefined" && true === multipartParts) {
            this.multipartParts = true;
        }
        return new com.ibm.mm.enabler.DeferredOperationImpl(this, this._endTransaction);
    },

    _endTransaction: function(deferred, sync) {
        if (!this.doMultipart) {
            return;
        }

        this._release();

        // return if another handler is in use
        if (0 < this.statics.semaphore) {
            return;
        }
        dojo.xhr = this.statics.oldXhr;

        var url;
        var xhrArgs;
        var me = this;
        var status;
        if (this.correlateHosts) {
            var _correlatedHosts = this.correlatedHosts.values();
            for (var i in _correlatedHosts) {
                if (Object.prototype.hasOwnProperty.call(_correlatedHosts, i)) {
                    status = this._loadResources(_correlatedHosts[i]);
                }
            }
        }
        else {
            // nothing in the parts array
            if (0 === this._assocArraySize(this.partsArray)) {
                return;
            }
            status = this._loadResources(this.partsArray);
        }

        if (deferred) {
            var callBack = deferred.getOperationCallback();
            if (callBack) {
                callBack(id, com.ibm.mashups.enabler.DeferredOperation.OPERATION_GET, xhr.status, myDeferred.getOperationCallbackParameters());
            }
        }
    },

    _doMultipartPOSTRequest: function(method, partsArray, doMultipartParts) {
        var useCommitHandler = this._processMultipartBody(partsArray);
        this._initServiceDoc();
        var rawMPArgs;
        if (useCommitHandler) {
            rawMPArgs = {
                url: this.serviceCHJson.url,
                sync: true
            };
        } else {
            rawMPArgs = {
                url: this.serviceMPJson.url,
                sync: true
            };
        }
        var status = this._multiPartXhr(method, rawMPArgs, partsArray, doMultipartParts);
        return status;
    },

    _assocArraySize: function(tempArray) {
        var size = 0;
        for (var x in tempArray) {
            if (Object.prototype.hasOwnProperty.call(tempArray, x)) {
                size++;
            }
        }
        return size;
    },

    _addToPartsArray: function(partsArray, args) {
        var existing = partsArray[args.url];
        if (!existing) {
            partsArray[args.url] = [];
            partsArray[args.url][0] = args;
        }
        else {
            existing[existing.length] = args;
        }
    },

    // acquire semaphore
    _acquire: function() {
        this.statics.semaphore++;
    },

    // release semaphore
    _release: function(deferred, statusCode) {
        this.statics.semaphore--;
    },

    _createPocURI: function(args) {
        var url = args.url;

        // OR added de-proxyfication since this is not needed for resolver uri's
        var proxyPrefix = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.PROXY_URL);
        proxyPrefix += "/http/"; // e.g. /mum/proxy/http/
        if (url.indexOf(proxyPrefix) === 0) {
            var newUrl = "http://";
            var slashPos = url.indexOf("/", proxyPrefix.length + 1); // skip /http/ to find next /
            // need to decode the authority part in order to have a valid URI
            if (slashPos > -1) {
                newUrl += unescape(url.substring(proxyPrefix.length, slashPos));
                newUrl += url.substring(slashPos);
            }
            else {
                newUrl = "http://" + url.substring(proxyPrefix.length);
            }

            url = newUrl;
        }

        // OR changed url to be HttpURL and get files by res:/
        var httpUrl = new com.ibm.mm.enabler.utils.HttpUrl(url);

        // extract the digest
        var digest = this._extractDigest(httpUrl, url);
        if (digest) {
            if (null === this.digest && false === this.replaceDigest) {
                this.replaceDigest = true;
            } else if (digest !== this.digest) {
                this.replaceDigest = false;
            }
            this.digest = digest;
        } else {
            this.digest = "";
            this.replaceDigest = false;
        }

        // add any dojo.xhr content parameters
        if (args.content) {
            for (var name in args.content) {
                if (Object.prototype.hasOwnProperty.call(args.content, name)) {
                    var value = args.content[name];
                    httpUrl.addParameter(name, value);
                }
            }
        }

        var uri = "";

        var isProxyNeeded = httpUrl.isProxyNeeded();

        if (isProxyNeeded) {
            uri = httpUrl.toString(); // the URI is the true url
        }
        else {
            // FIXME: currently the server/resolver can't handle res URIs for a data sink
            var method = (args.method) ? args.method.toLowerCase() : null;
            if (method && (method == "post" || method == "put" || method == "delete")) {
                uri = httpUrl.getParameter("uri");
            } else {
                uri = "res:" + httpUrl.toServerRelativeString(); // need to prefix res: before the server relative url
            }
        }
        return uri;
    },

    _processMultipartBody: function(parts) {
        var useCommitHandler = false;
        for (var w in parts) {
            if (Object.prototype.hasOwnProperty.call(parts, w)) {
                for (var x in parts[w]) {
                    if (Object.prototype.hasOwnProperty.call(parts[w], x)) {
                        // Create a header for our method
                        var args = parts[w][x];

                        var uri = this._createPocURI(args);

                        var contentIdHeader = uri;

                        args.headers = dojo.mixin({}, args.headers, {
                            "X-Method-Override": args.method,
                            "Content-ID": contentIdHeader
                        });

                        if ("GET" !== args.method) {
                            useCommitHandler = true;
                        }
                    }
                }
            }
        }
        return useCommitHandler;
    },

    _createSiteMap: function(parts) {
        var cxml = '<mashup:sitemap xmlns:mashup="http://www.ibm.com/xmlns/prod/websphere/portal/v6.0.2/mashup-sitemap">';
        for (var w in parts) {
            if (Object.prototype.hasOwnProperty.call(parts, w)) {
                // Create a header for our method
                var args = parts[w][0];
                args.handleAs = args.handleAs ? args.handleAs.toLowerCase() : "text";

                var uri = this._createPocURI(args).replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/&/g, "&amp;");

                cxml += '<mashup:entry uri="' + uri + '" mode="download"/>';
            }
        }
        cxml += '</mashup:sitemap>';
        return cxml;
    },

    _extractDigest: function(httpUrl, url) {
        // check for a normal parameter
        var digest;
        var tempDigest = httpUrl.getParameter("digest");
        if (!tempDigest) {
            // potentially portal style:
            // /wps/mycontenthandler/!ut/p/digest!YYKwv4D5SWBlr5MXQwCujg/res//mccbuilder/widget-catalog/breadcrumbWidget.xml?pragma=cache&max-age=1209600&cache-scope=public&vary=none&user-context=false?cache-scope=public&vary=none&user-context=false&max-age=1209600
            var start = url.indexOf("digest!");
            if (0 < start) {
                start += 7;
                var end = url.indexOf("/", start);
                digest = url.substring(start, end);
            }
        } else {
            digest = tempDigest;
        }
        return digest;
    },

    _updateDigest: function(url) {
        if (!this.replaceDigest) {
            return url;
        }

        // potentially portal style:
        // /wps/mycontenthandler/!ut/p/digest!YYKwv4D5SWBlr5MXQwCujg/res//mccbuilder/widget-catalog/breadcrumbWidget.xml?pragma=cache&max-age=1209600&cache-scope=public&vary=none&user-context=false?cache-scope=public&vary=none&user-context=false&max-age=1209600
        var digest;
        var end;
        var start = url.indexOf("digest!");
        if (0 < start) {
            start += 7;
            end = url.indexOf("/", start);
            digest = url.substring(start, end);
        } else if (!digest) {
            // url parameter
            start = url.indexOf("digest=");
            if (0 < start) {
                start += 7;
                end = url.indexOf("&", start);
                if (-1 === end) {
                    digest = url.substring(start);
                } else {
                    digest = url.substring (start, end);
                }
            }
        }
        var retval = url;
        if (digest) {
            retval = url.replace(digest, this.digest);
        }
        return retval;
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.io.XHRMultipart"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.io.XHRMultipart"] = true;
dojo.provide("com.ibm.mashups.enabler.io.XHRMultipart");







}

if(!dojo._hasResource["com.ibm.mashups.enabler.io.XHRMultipartFactory_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.io.XHRMultipartFactory_API"] = true;
dojo.provide("com.ibm.mashups.enabler.io.XHRMultipartFactory_API");
dojo.provide("com.ibm.mashups.enabler.io.XHRMultipartFactory");

/**
 * Interface representing the XHR multipart handler factory
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.io.XHRMultipartFactory", null, {

    /**
     * Returns a new XHR multipart handler
     *
     * @return {com.ibm.mashups.enabler.io.XHRMultipart} a new multipart
     * handler, never <code>null</code>
     */
    create: function(){
    },

    /**
     * Returns if multipart is enabled on the server
     * @return {Boolean} <code>true</code> if multipart is
     * enabled, <code>false</code> otherwise
     */
    isMultipartEnabled: function(){
    },

    /**
     * Returns if application widgets should be fetched in multipart requests
     * @return {Boolean} <code>true</code> if application widgets should be
     * fetched in multipart requests, <code>false</code> otherwise
     */
    isMultipartApplicationWidgets: function(){
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.io.XHRMultipartFactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.io.XHRMultipartFactoryImpl"] = true;
dojo.provide("com.ibm.mm.enabler.io.XHRMultipartFactoryImpl");









// public factory
dojo.declare("com.ibm.mm.enabler.io.XHRMultipartFactoryImpl", [com.ibm.mashups.enabler.io.XHRMultipartFactory, com.ibm.mm.enabler.ServiceDocConsumer], {
    constructor: function() {
    	this._init = false;
        this.serviceMPJson = null;

        this.doMultipart = false;
        var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
        var pageLoadOptAppWidgets = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.PAGE_LOAD_OPTIMIZATION_APP_WIDGETS);
        this.multipartAppWidgets = false;
        if (typeof(pageLoadOptAppWidgets) == "undefined" || pageLoadOptAppWidgets === null || pageLoadOptAppWidgets === true) {
            this.multipartAppWidgets = true;
        }
    },

	_initServiceDoc: function() {
		this.inherited("_initServiceDoc", arguments);
		// service document and initialization
		if (dojo.exists("com.ibm.mm.enabler.model.ServiceDocumentModel")) {
			this.serviceMPJson = com.ibm.mm.enabler.model.ServiceDocumentModel.getCollectionData([com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_MODEL, com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_MULTIPART]);
		}
		if(this.serviceMPJson && this.serviceMPJson.url) {
			this.doMultipart = true;
		}
	},

    create: function() {
        return new com.ibm.mm.enabler.io.XHRMultipartImpl();
    },

    isMultipartEnabled: function() {
    	if(!this._init) {
			this._init = true;
			var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
			var multipartConfig = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.MULTIPART_ENABLED);
			// disable on IE6
			if (dojo.isIE != 6 && multipartConfig) {
				this._initServiceDoc();
			}
    	}
        return this.doMultipart;
    },

    isMultipartApplicationWidgets: function() {
        return this.multipartAppWidgets;
    }
});

// public factory
com.ibm.mashups.enabler.io.XHRMultipartFactory = new com.ibm.mm.enabler.io.XHRMultipartFactoryImpl();

}

if(!dojo._hasResource["com.ibm.mashups.enabler.io.XHRMultipartFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.io.XHRMultipartFactory"] = true;
dojo.provide("com.ibm.mashups.enabler.io.XHRMultipartFactory");



dojo.require( "com.ibm.mm.enabler.io.XHRMultipartFactoryImpl" );

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.Accessor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.Accessor"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.Accessor");

/**
 * Interface representing an Accessor.
 *
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.model.state.Accessor", null, {});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.PageAccessor_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.PageAccessor_API"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.PageAccessor_API");
dojo.provide("com.ibm.mashups.enabler.model.state.PageAccessor");


/**
 * Interface representing an PageAccessor.
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare( "com.ibm.mashups.enabler.model.state.PageAccessor", [com.ibm.mashups.enabler.model.state.Accessor] , {
    /**
     * Returns the of the page within a space.
     * @type String
     * @return {String} The page id of provided space
     */
	getPageID:function() {
	},
	 /**
     * Sets the page of the space
     * @param {String} pageId id of page
     * @type void
     */
	setPageID:function(pageId) {
	},
	 /**
     * Confirms if it's possible to set a new page id
     * @param {String} pageId id of page
     * @type Boolean
     * @return{Boolean} return true if it's possible to set a new page id
     */
	confirmSetPageID:function(pageId) {
		return true;
	}
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.model.state.PageAccessorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.state.PageAccessorImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.state.PageAccessorImpl");




dojo.declare("com.ibm.mm.enabler.model.state.PageAccessorImpl", [com.ibm.mashups.enabler.model.state.PageAccessor], {

    constructor: function(navStateModel, spaceid) {
        this.navStateModel = navStateModel;
        if (spaceid) {
            this.spaceid = spaceid;
        }
    },
    getPageID: function() {
        var state = this.navStateModel._state;
        var rc = null;
        if (!state) {
            return null;
        }
        if (!this.spaceid) {
            if (state.pid) {
                return state.pid.value;
            }
            return null;
        }
        else {
            if (state.pageselection && state.pageselection[this.spaceid]) {
                return state.pageselection[this.spaceid].value;
            }
            return null;
        }
        return null;
    },
    setPageID: function(pageId) {
        var state = this.navStateModel._state;
        if (!state) {
            this.navStateModel._state = {};
            state = this.navStateModel._state;
        }

        if (!pageId) {
            state.pid = null;
            if (this.spaceid) {
                if (state.pageselection && state.pageselection[this.spaceid]) {
                    state.pageselection[this.spaceid] = null;
                }
            }
            this.navStateModel.setDirty(true, "pid");
            return;
        }

        var lm = new Date().getTime();
        state.pid = state.pid ? state.pid : {};
        state.pid.value = pageId;
        state.pid.params = state.pid.params ? state.pid.params : {};
        state.pid.params.lm = lm;
        if (this.spaceid) {
            if (!state.pageselection) {
                state.pageselection = {};
            }
            if (!state.pageselection[this.spaceid]) {
                state.pageselection[this.spaceid] = {};
            }
            state.pageselection[this.spaceid].value = pageId;
            state.pageselection[this.spaceid].params = state.pageselection[this.spaceid].params ? state.pageselection[this.spaceid].params : {};
            state.pageselection[this.spaceid].params.lm = lm;
        }
        this.navStateModel.setDirty(true, "pid");
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.PageAccessor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.PageAccessor"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.PageAccessor");




}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.SpaceAccessor_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.SpaceAccessor_API"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.SpaceAccessor_API");
dojo.provide("com.ibm.mashups.enabler.model.state.SpaceAccessor");


/**
 * Interface representing a SpaceAccessor.
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare( "com.ibm.mashups.enabler.model.state.SpaceAccessor", [com.ibm.mashups.enabler.model.state.Accessor], {
	/**
     * Returns the of the currently selected space.
     * @type String
     * @return {String} The spaceid
     */
	getSpaceID:function() {
	},

	/**
     * Sets the space
     * @param {String} spaceId id of space
     * @type void
     */
	setSpaceID:function(spaceId) {
	},
	/**
     * Confirms if it's possible ot set the space id
     * @param {String} spaceId id of space
     * @type Boolean
     * @return{Boolean} return true if it's possible to set the new space id
     */
	confirmSetSpaceID:function(spaceId) {
		return true;
	}

});

}

if(!dojo._hasResource["com.ibm.mm.enabler.model.state.SpaceAccessorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.state.SpaceAccessorImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.state.SpaceAccessorImpl");




dojo.declare("com.ibm.mm.enabler.model.state.SpaceAccessorImpl", [com.ibm.mashups.enabler.model.state.SpaceAccessor], {

    constructor: function(navStateModel) {
        this.navStateModel = navStateModel;
    },
    getSpaceID: function() {
        var state = this.navStateModel._state;
        if (!state) {
            return null;
        }
        if (state.sid && state.sid.value) {
            return state.sid.value;
        }
        return null;
    },

    _setSpaceIDInternal: function(spaceId) {
        var state = this.navStateModel._state;
        if (!state) {
            this.navStateModel._state = {};
            state = this.navStateModel._state;
        }
        var lm = new Date().getTime(); //todo
        if (typeof spaceId == "undefined") {
            state.sid = {};
        }
        else {
            state.sid = state.sid ? state.sid : {};
            state.sid.value = spaceId;
            state.sid.params = state.sid.params ? state.sid.params : {};
            state.sid.params.lm = lm;
        }

        if (state.pid) {
            state.pid = null;
        }
    },

    setSpaceID: function(spaceId) {
        this._setSpaceIDInternal(spaceId);
        this.navStateModel.setDirty(true, "sid");
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.SpaceAccessor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.SpaceAccessor"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.SpaceAccessor");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.WidgetAccessor_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.WidgetAccessor_API"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.WidgetAccessor_API");
dojo.provide("com.ibm.mashups.enabler.model.state.WidgetAccessor");


/**
 * Interface representing a WidgetAccessor. Reserved Widget Paramers:
 * "cp" : the reserved paremeter for widget customized state.
 * "h"  : the reserved paremeter for widget height.
 * "w"  : the reserved paremeter for widget width.
 * "st" : the reserved paremeter for widget window state.
 * "md" : the reserved paremeter for widget mode.
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare( "com.ibm.mashups.enabler.model.state.WidgetAccessor", [com.ibm.mashups.enabler.model.state.Accessor], {
    /**
      * @private
      */
    constructor:function (navStateModel, id) {
    },
	/**
     * Returns the widget id of the Widget
     * @type String
     * @return {String} ID of required Widget
     */
	getWidgetID:function() {
	},
	/**
     * Returns the values of the required widget state parameter. If state has only one value, this method returns a single array with a length of 1.
     *
     * @since 2.4
     * @param {String} key The name of the required parameter of Widget Navigation State
     * 				   "cp" is the reserved parameter for widget customized state.
     * @type String
     * @return {String[]} Values of required parameter
     */
	getWidgetStateValues:function(key) {
	},
		/**
     * Returns the state of the required widget state parameter
     * @param {String} key The name of the required parameter of Widget Navigation State
     * 				   "cp" is the reserved parameter for widget customized state.
     * @type String
     * @return {String} Value of required parameter
     */
	getWidgetState:function(key) {
	},
	/**
     * Set the value of a widget state parameter
     *
     * @since 2.4
     * @param {String} key The name of the required parameter
     * @param {String[]} values The values of the required parameter
     * @type WidgetAccessor
     * @return{WidgetAccessor} return an handle of WidgetAccessor upon successful, <code>null</code> upon failure.
     */
	setWidgetState:function(key,values){
	},
	/**
     *  Confirms whether setting the values for the given widget state parameter is possible.
     *
     * @since 2.4
     * @param {String} key The name of the required parameter
     * @param {String[]} values The values of the required parameter
     * @type Boolean
     * @return {Boolean} true if the values can be set, otherwise false.
     */
	confirmSetWidgetState:function(key,values){
		return true;
	},
	/**
     * Set the value of a widget state parameter
     *
     * @since 2.4
     * @param {String} key The name of the required parameter
     * @param {String} value The value of the required parameter
     * @type WidgetAccessor
     * @return{WidgetAccessor} return an handle of WidgetAccessor upon successful, <code>null</code> upon failure.
     */
	setWidgetState:function(key,value){ // JSLINT-IGNORE: in Java functions with the same name but different signatures are allowed - this is only used for generating JavaDoc
	},
	/**
     *  Confirms whether setting the value for the given widget state parameter is possible.
     *
     * @since 2.4
     * @param {String} key The name of the required parameter
     * @param {String} value The value of the required parameter
     * @type Boolean
     * @return {Boolean} true if the value can be set, otherwise false.
     */
	confirmSetWidgetState:function(key,value){// JSLINT-IGNORE: in Java functions with the same name but different signatures are allowed - this is only used for generating JavaDoc
		return true;
	},
	/**
     * Remove a widget state parameter
     * @param {String} key The name of the required parameter
     * @type WidgetAccessor
     * @return{WidgetAccessor} return an handle of WidgetAccessor upon successful, <code>null</code> upon failure.
     */
	removeWidgetState:function(key){
	},
	/**
     * Confirms whether removing a widget state parameter is possible
     *
     * @since 2.4
     * @param {String} key The name of the required parameter
     * @type Boolean
     * @return{Boolean} return true if the required parameter can be removed
     */
	confirmRemoveWidgetState:function(key){
		return true;
	},
	/**
     * Returns the names of custimized widget state
     * @type String[]
     * @return {String[]} an array of customized widget state names
     */
	getWidgetStateNames:function(){
	},
	/**
     * Returns the mode of the required widget
     * @type String
     * @return {String} The mode of the required widget and <code>null</code> if no mode is set yet.
     */
	getWidgetMode:function() {
	},
	/**
     * Set the mode of a widget
     * @param {String} mode of the required widget
     * @type WidgetAccessor
     * @return{WidgetAccessor} return an handle of WidgetAccessor upon successful, <code>null</code> upon failure.
     */
	setWidgetMode:function(mode) {
	},
	/**
     * Confirms whether it's possible or not to set the widget to a new mode
     * @param {String} mode of the required widget
     * @type Boolean
     * @return{Boolean} return true if it's possible to set widget to the new model
     */
	confirmSetWidgetMode:function(mode) {
		return true;
	},
	/**
     * Returns the window state of the required widget
     * @type String
     * @return {String} The window state of the required widget following states are allowed: "normal","minimize","maximize". It returns <code>null</code> if no windowstate is set yet.
     */
	getWindowState:function() {
	},
	/**
     * Set the window state of a widget
     * @param {String} windowState The window state of the required widget
     * @type WidgetAccessor
     * @return{WidgetAccessor} return an handle of WidgetAccessor upon successful, <code>null</code> upon failure.
     */
	setWindowState:function(windowState) {
	},
	/**
     * Confirms whether it's possible or not to set the widget to a new window state
     * @param {String} windowState The window state of the required widget
     * @type Boolean
     * @return{Boolean} return true if it's possible to set widget to the new window state
     */
	confirmSetWindowState:function(windowState) {
		return true;
	},
	/**
     * Returns the size of the required widget
     * @type Object
     * @return {Object} A JSON object representing the widget width/height, for example: <code>{w:"200",h:"400"}</code>
     */
	getSize:function() {
	},
	/**
     * Set the size of a widget
     * @param {String} width The width of the widget
     * @param {String} height The height of the widget
     * @type WidgetAccessor
     * @return{WidgetAccessor} return an handle of WidgetAccessor upon successful, <code>null</code> upon failure.
     */
	setSize:function(width, height) {
	},
	/**
     * Confirms whether it's possible or not to set the widget to the new width and height
     * @param {String} width The width of the widget
     * @param {String} height The height of the widget
     * @type Boolean
     * @return{Boolean} return true if it's possible to set widget to the new width and height
     */
	confirmSetSize:function(width,height) {
		return true;
	},
   /**
	* "minimize" window state supported by enabler
	* @type String
	*/
	MIN: "minimize",
  /**
	* "maximize" window state supported by enabler
	* @type String
	*/
    MAX: "maximize",
 /**
	* "normal" window state supported by enabler
	* @type String
	*/
    NORMAL: "normal"

});

}

if(!dojo._hasResource["com.ibm.mm.enabler.model.state.WidgetAccessorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.state.WidgetAccessorImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.state.WidgetAccessorImpl");



dojo.declare("com.ibm.mm.enabler.model.state.WidgetAccessorImpl", [com.ibm.mashups.enabler.model.state.WidgetAccessor], {

    constructor: function(navStateModel, id){
        this.navStateModel = navStateModel;
        this.wid = id;
        this.uniqueWid = this._getUniqueWid();
        this.widgetNavStateNode = navStateModel._find(this.WIDGET_PREFIX + this.navStateModel.DELIMITER + this.uniqueWid);
        if (this.wid != this.uniqueWid && !this.widgetNavStateNode) {
            this.widgetNavStateNodeFallback = navStateModel._find(this.WIDGET_PREFIX + this.navStateModel.DELIMITER + this.wid);
        }
    },
    WIDGET_PREFIX: "wparams",
    WIDTH: "w",
    HEIGHT: "h",
    WINDOWSTATE: "st",
    SYSTEMSTATE: "rp",
    CUSTOMSTATE: "cp",
    VALUE: "value",
    PARAMS: "params",
    MODE: "md",
    RP: {
        w: "w",
        h: "h",
        st: "st",
        md: "md"
    },
    VIEW: "view",
    getWidgetID: function(){
        return this.wid;
    },
    _getUniqueWid: function(){
        return this.navStateModel._getUniqueWid(this.wid);
    },
    getWidgetStateSet: function(){
        var value = null;
        if (!this.widgetNavStateNode && !this.widgetNavStateNodeFallback) {
            return null;
        }
        var widgetNavStateNode = this.widgetNavStateNode;
        if (!widgetNavStateNode) {
            widgetNavStateNode = this.widgetNavStateNodeFallback;
        }
        var data = widgetNavStateNode.getRef();

        if (data && data[this.VALUE]) {
            if (data[this.VALUE][this.CUSTOMSTATE]) {
                value = data[this.VALUE][this.CUSTOMSTATE];
            }
        }
        if (value && !dojo.isString(value)) {
            value = dojo.toJson(value);
        }
        return value; //always return string as defined by the spec
    },
    _createWidgetNavStateNode: function(){
        var aNode = this.navStateModel.create({
            key: this.uniqueWid
        });
        var parentNode = this.navStateModel._find(this.WIDGET_PREFIX);
        if (!parentNode) {
            var temp = this.navStateModel.create({
                key: this.WIDGET_PREFIX
            });
            this.navStateModel.insert(temp, this.navStateModel._getRoot());
            parentNode = this.navStateModel._find(this.WIDGET_PREFIX);
        }
        this.navStateModel.insert(aNode, parentNode);
        aNode = this.navStateModel._find(this.WIDGET_PREFIX + this.navStateModel.DELIMITER + this.uniqueWid);
        return aNode;
    },
    setWidgetStateSet: function(object){
        //it should be  a simple String,save as an object internally
        var value = null;
        //need to support both string or object
        //save as object for portal CSA2 support
        if (dojo.isString(object)) {
			try {
				object = dojo.fromJson(object);
			} catch (e) {
				// just use the string
			}
        }
        if (!this.widgetNavStateNode) {
            //create this.widgetNavStateNode
            this.widgetNavStateNode = this._createWidgetNavStateNode();
        }
        var data = this.widgetNavStateNode.getRef();
        data.params = data.params ? data.params : {};
        data.params.lm = new Date().getTime(); //todo
        if (data && data[this.VALUE]) {
            if (data[this.VALUE][this.CUSTOMSTATE]) {
                value = dojo.clone(data[this.VALUE][this.CUSTOMSTATE]);
            }
        }

        data[this.VALUE] = data[this.VALUE] ? data[this.VALUE] : {};
        var obj = object;
        if (value && !dojo.isString(value) && !dojo.isString(object)) {
            obj = dojo.mixin(value, object); //mixin behaviour
        }
        data[this.VALUE][this.CUSTOMSTATE] = obj;


        this.navStateModel.setDirty(true);
        return this;
    },
    _getWidgetSystemState: function(key){
        var value = null;
        if (!this.widgetNavStateNode && !this.widgetNavStateNodeFallback) {
            return null;
        }
        var widgetNavStateNode = this.widgetNavStateNode;
        if (!widgetNavStateNode) {
            widgetNavStateNode = this.widgetNavStateNodeFallback;
        }
        var data = widgetNavStateNode.getRef();
        if (data && data[this.VALUE]) {
            if (data[this.VALUE][this.SYSTEMSTATE]) {
                data = data[this.VALUE][this.SYSTEMSTATE];
                if (data && data[key]) {
                    value = data[key];
                }
            }
        }
        return value;
    },
    _setWidgetSystemState: function(key, value){
        //overwrite behaviour
        if (!this.widgetNavStateNode) {
            this.widgetNavStateNode = this._createWidgetNavStateNode();
        }

        var data = this.widgetNavStateNode.getRef();
        data.params = data.params ? data.params : {};
        data.params.lm = new Date().getTime(); //todo
        var keyRef = null;
        data[this.VALUE] = data[this.VALUE] ? data[this.VALUE] : {};
        data[this.VALUE][this.SYSTEMSTATE] = data[this.VALUE][this.SYSTEMSTATE] ? data[this.VALUE][this.SYSTEMSTATE] : {};
        keyRef = data[this.VALUE][this.SYSTEMSTATE];

        keyRef[key] = value;
        this.navStateModel.setDirty(true);
        return this;
    },
    getWidgetState: function(key){
        var rc = this._getWidgetStateValue(key) || null;
        if (!rc) {
            return null;
        }
        if (!dojo.isString(rc)) {
            rc = dojo.toJson(rc);
        }
        return rc;
    },
    _getWidgetStateValue: function(key){
        if (!key) {
            return null;
        }
        if (key && key == "cp") {
            return this.getWidgetStateSet();
        }

        if (this.RP[key]) {
            return this._getWidgetSystemState(key);
        }

        var value = null;
        if (!this.widgetNavStateNode && !this.widgetNavStateNodeFallback) {
            return null;
        }
        var widgetNavStateNode = this.widgetNavStateNode;
        if (!widgetNavStateNode) {
            widgetNavStateNode = this.widgetNavStateNodeFallback;
        }
        var data = widgetNavStateNode.getRef();
        if (data && data[this.VALUE]) {
            if (data[this.VALUE][this.CUSTOMSTATE]) {
                data = data[this.VALUE][this.CUSTOMSTATE];
                if (dojo.isString(data)) {
                    return null;
                }
                if (data && data[key]) {
                    value = data[key];
                }
            }
        }

        return value;
    },

    getWidgetStateValues: function(key){
        // TODO implement
        var rc = this._getWidgetStateValue(key) || null;
        if (!rc) {
            return null;
        }
        if (dojo.isString(rc)) {
            var arr = [];
            arr.push(rc);
            return arr;
        }
        return rc;
    },

    getWidgetStateNames: function(){
        var names = [];
        if (!this.widgetNavStateNode && !this.widgetNavStateNodeFallback) {
            return null;
        }
        var widgetNavStateNode = this.widgetNavStateNode;
        if (!widgetNavStateNode) {
            widgetNavStateNode = this.widgetNavStateNodeFallback;
        }
        var data = widgetNavStateNode.getRef();

        if (data && data[this.VALUE]) {
            if (data[this.VALUE][this.CUSTOMSTATE]) {
                data = data[this.VALUE][this.CUSTOMSTATE];
                if (dojo.isString(data)) {
                    return null;
                }
                if (data) {
                    for (var i in data) {
                        if (Object.prototype.hasOwnProperty.call(data, i)) {
                            if (data[i]) { //if it's not deleted
                                names.push(i);
                            }
                        }
                    }
                }
            }
        }
        if (names.length === 0) {
            return null;
        }
        return names;
    },
    setWidgetState: function(key, value){
        if (!key || !value) {
            return null;
        }
        if (key && key == "cp") {
            return this.setWidgetStateSet(value);
        }
        var isValidValue = false;
        if (dojo.isArray(value) && value.length >= 1) {
            if (dojo.isString(value[0])) {
                isValidValue = true;
            }
        }
        if (!isValidValue) {
            if (dojo.isString(value)) {
                isValidValue = true;
            }
        }
        if (!isValidValue) {
            return null;
        }

        if (this.RP[key]) {
            return this._setWidgetSystemState(key, value);
        }
        //overwrite behaviour
        if (key && key == "cp") {
            return this.setWidgetStateSet(value);
        }
        if (!this.widgetNavStateNode) {
            this.widgetNavStateNode = this._createWidgetNavStateNode();
        }

        var data = this.widgetNavStateNode.getRef();
        data.params = data.params ? data.params : {};
        data.params.lm = new Date().getTime(); //todo
        var keyRef = null;
        data[this.VALUE] = data[this.VALUE] ? data[this.VALUE] : {};
        data[this.VALUE][this.CUSTOMSTATE] = data[this.VALUE][this.CUSTOMSTATE] ? data[this.VALUE][this.CUSTOMSTATE] : {};
        keyRef = data[this.VALUE][this.CUSTOMSTATE];

        keyRef[key] = value;
        this.navStateModel.setDirty(true);
        return this;
    },
    removeWidgetState: function(key){
        if (!key) {
            return false;
        }
        if (this.RP[key]) {
            return this._removeWidgetSystemState(key);
        }
        if (!this.widgetNavStateNode) {
            return false;
        }
        var data = this.widgetNavStateNode.getRef();
        data.params = data.params ? data.params : {};
        data.params.lm = new Date().getTime(); //todo
        if (key && key == "cp") {
            if (data && data[this.VALUE] && data[this.VALUE][this.CUSTOMSTATE]) {
                data[this.VALUE][this.CUSTOMSTATE] = null;
                this.navStateModel.setDirty(true);
                return true;
            }
            return false;
        }

        if (data && data[this.VALUE] && data[this.VALUE][this.CUSTOMSTATE]) {
            var keyRef = data[this.VALUE][this.CUSTOMSTATE];
            if (keyRef && keyRef[key]) {
                keyRef[key] = null;
                this.navStateModel.setDirty(true);
                return true;
            }
        }
        return false;
    },
    _removeWidgetSystemState: function(key){
        if (!key) {
            return false;
        }
        if (!this.widgetNavStateNode) {
            return false;
        }
        var data = this.widgetNavStateNode.getRef();
        data.params = data.params ? data.params : {};
        data.params.lm = new Date().getTime(); //todo
        if (data && data[this.VALUE] && data[this.VALUE][this.SYSTEMSTATE]) {
            var keyRef = data[this.VALUE][this.SYSTEMSTATE];
            if (keyRef && keyRef[key]) {
                keyRef[key] = null;
                this.navStateModel.setDirty(true);
                return true;
            }
        }
        return false;
    },
    getWindowState: function(){
        rc = this._getWidgetSystemState(this.WINDOWSTATE);
        //rc = rc ? rc : this.NORMAL;
        return rc;
    },
    setWindowState: function(windowState){
        if (windowState && (windowState == this.MIN || windowState == this.MAX || windowState == this.NORMAL)) {
            this._setWidgetSystemState(this.WINDOWSTATE, windowState);
        }
    },
    getWidgetMode: function(){
        var rc = this._getWidgetSystemState(this.MODE);
        //rc = rc ? rc : this.VIEW;
        return rc;
    },
    setWidgetMode: function(aMode){
        if (aMode) {
            this._setWidgetSystemState(this.MODE, aMode);
            return this;
        }
        return null;
    },
    getSize: function(){
        var size = {};
        var height = this._getWidgetSystemState(this.HEIGHT);
        var width = this._getWidgetSystemState(this.WIDTH);
        if (height) {
            size[this.HEIGHT] = height;
        }
        if (width) {
            size[this.WIDTH] = width;
        }
        if (!size[this.HEIGHT] && !size[this.WIDTH]) {
            return null;
        }
        return size;
    },
    setSize: function(width, height){
        if (width) {
            this._setWidgetSystemState(this.WIDTH, width);
        }
        if (height) {
            this._setWidgetSystemState(this.HEIGHT, height);
        }
        return this;
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.WidgetAccessor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.WidgetAccessor"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.WidgetAccessor");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.PageModeAccessor_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.PageModeAccessor_API"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.PageModeAccessor_API");
dojo.provide("com.ibm.mashups.enabler.model.state.PageModeAccessor");


/**
 * Interface representing an PageModeAccessor.
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare( "com.ibm.mashups.enabler.model.state.PageModeAccessor", [com.ibm.mashups.enabler.model.state.Accessor] , {

	/**
    * VIEW mode of page, can be used as com.ibm.mashups.enabler.model.state.PageModeAccessor.VIEW with "view" as the actual value</br>
    * @type String
    */
  	VIEW:"view",

  	/**
    * EDIT mode of page, can be used as com.ibm.mashups.enabler.model.state.PageModeAccessor.EDIT with "edit" as the actual value</br>
    * @type String
    */
	EDIT:"edit",

	/**
     * Returns the of the page mode of current page.
     * @type String
     * @return {String} The page mode of current page
     */
	getPageMode:function() {
	},

	/**
     * Sets the page mode of the page
     * @param {String} pageMode The mode of the page
     * @type void
     */
	setPageMode:function(pageMode) {
	},
	 /**
     * Confirms if it's possible to set a new page mode
     * @param {String} pageMode The mode of the page
     * @type Boolean
     * @return{Boolean} return true if it's possible to set a new page mode
     */
	confirmSetPageMode:function(pageMode) {
		return true;
	}
});

com.ibm.mashups.enabler.model.state.PageModeAccessor.VIEW = "view";
com.ibm.mashups.enabler.model.state.PageModeAccessor.EDIT = "edit";

}

if(!dojo._hasResource["com.ibm.mm.enabler.model.state.PageModeAccessorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.state.PageModeAccessorImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.state.PageModeAccessorImpl");



dojo.declare("com.ibm.mm.enabler.model.state.PageModeAccessorImpl", [com.ibm.mashups.enabler.model.state.PageModeAccessor], {

    constructor: function(navStateModel) {
        // it supports 3 modes: "view","edit","unload" --  unload is internal at this moment and used to indicate a page is being unloaded
        this.navStateModel = navStateModel;
    },
    getPageMode: function() {
        var pageMode = this.navStateModel._getPageMode();
        if (!pageMode) {
            return null;
        }
        return pageMode;
    },
    setPageMode: function(mode) {
        if (mode) {
            this.navStateModel._setPageMode(mode);
        }
        return;
    }
});


}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.PageModeAccessor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.PageModeAccessor"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.PageModeAccessor");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor_API"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor_API");
dojo.provide("com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor");


/**
 * Interface representing a ShareableParameterSetAccessor.
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare( "com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor", [com.ibm.mashups.enabler.model.state.Accessor], {
	/**
     * Returns the id of ShareableParamterSet
     * @type String
     * @return {String}  name of ShareableParameterSet
     */
	getId:function() {
	},
    /**
     * Returns the scope of ShareableParamterSet or null, if this accessor represents the global scope.
     * @type String
     * @return {String}  name of the scope
     */
    getScope:function() {
    },
	/**
     * Returns an array of all Shareable Parameter names within this Shareable Parameter Set
     * @type String[]
     * @return {String[]}  array of all the ShareableParameterSet
     */
	getAllNames:function() {
	},
	/**
     * Set the value of a required item. It will replace the old value. If the value is a serialized version of complex data type, it's recommended for the widget to get the original
     *  value, update the complex object and serialize again before calling this api.
     * @param {String} itemName The name of the required parameter
     * @param {String} value The value of the required parameter
     * @type Boolean
     * @return {Boolean}  return true if item is updated or created successfully.
     */
	setItemValue:function(itemName,value){
	},
		/**
     * Confirm if it's possible to set the value of a required item. It will replace the old value. If the value is a serialized version of complex data type, it's recommended for the widget to get the original
     *  value, update the complex object and serialize again before calling this api.
     * @param {String} itemName The name of the required parameter
     * @param {String} value The value of the required parameter
     * @type Boolean
     * @return {Boolean}  return true if it's possible to set the value
     */
	confirmSetItemValue:function(itemName,value){
		return true;
	},
	/**
     * Remove the required item
     * @param {String} itemName The name of the required parameter that needs to be removed
     * @type Boolean
     * @return {Boolean}  return true if item is removed successfully.
    */
	removeItem:function(itemName){
	},
	/**
     * confirm if it's possible to remove the required item
     * @param {String} itemName The name of the required parameter that needs to be removed
     * @type Boolean
     * @return {Boolean}  return true if it's possible to remove item
    */
	confirmRemoveItem:function(itemName){
		return true;
	},
	/**
     * Returns the value of required item name
     * @param {String} itemName the name of the required parameter
     * @type String
     * @return {String} value of the required item
     */
	getItemValue:function(itemName) {
	},
	/**
     * Register listener so listener will be notified when an item set is updated
     * @param {Function}  listener which is a js function that's already scoped properly.
     * @return{String} listener id
     */
	registerListener:function(listener) {
	},
 /**
     * Remove the listener given a listener id
     * @param {String}  listenerId id of the listener that will be removed.
     * @type Boolean
     * @return {Boolean} return true if listener is removed successfully
     */
	removeListener:function(listenerId) {
	},
	/**
     * Confirm if it's possible to remove the listener given a listener id
     * @param {String}  listenerId id of the listener that will be removed.
     * @type Boolean
     * @return {Boolean} return true if it's possible to remove Listener
     */
	confirmRemoveListener:function(listenerId) {
		return true;
	}
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.model.state.ShareableParameterSetAccessorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.state.ShareableParameterSetAccessorImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.state.ShareableParameterSetAccessorImpl");



dojo.declare("com.ibm.mm.enabler.model.state.ShareableParameterSetAccessorImpl", [com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor], {
    /**
     * @private
     */
    DELETE_TOKEN: "DELETE_TOKEN",
    TYPE_NEW: "newItem",
    TYPE_UPDATE: "changedValue",
    TYPE_REMOVE: "removedItem",
    constructor: function(navStateModel, name, scope) {
        /*{
         value:{//type: newItem/changedValue/removedItem
         page:{value:"3",params:{_isDirty:true,_type:"changedValue",_oldVal:"4"}},
         tablesize:{value:"10"}
         }
         params:{lm:{},_listener:{}}
         }
         */
        if (!scope) {
            this.scope = com.ibm.mm.enabler.model.state.ShareableParameterSetAccessorImpl.GLOBAL_SCOPE;
        } else {
            this.scope = scope;
        }

        this.name = name;
        this.navStateModel = navStateModel;

        this.navStateNode = navStateModel._find("sparams" + this.navStateModel.DELIMITER + name + this.navStateModel.DELIMITER + this.scope);



    },
    _createNavStateNode: function() {
        var temp;

        var parentNode = this.navStateModel._find("sparams");
        if (!parentNode) {
            temp = this.navStateModel.create({
                key: "sparams"
            });
            this.navStateModel.insert(temp, this.navStateModel._getRoot());
            parentNode = this.navStateModel._find("sparams");
        }

        var nameNode = this.navStateModel._find(this.name);
        if (!nameNode) {
            temp = this.navStateModel.create({
                key: this.name
            });
            this.navStateModel.insert(temp, parentNode);
            nameNode = this.navStateModel._find("sparams" + this.navStateModel.DELIMITER + this.name);
        }

        var scopeNode = this.navStateModel.create({
            key: this.scope
        });


        this.navStateModel.insert(scopeNode, nameNode);
        scopeNode = this.navStateModel._find("sparams" + this.navStateModel.DELIMITER + this.name + this.navStateModel.DELIMITER + this.scope);
        return scopeNode;
    },
    getId: function() {
        return this.name;
    },
    getScope: function() {
        return this.scope;
    },
    getAllNames: function() {
        if (!this.navStateNode) {
            return null;
        }
        var arr = [];
        var data = this.navStateNode.getRef();
        if (data && data[this.navStateModel.VALUE]) {
            for (var i in data[this.navStateModel.VALUE]) {
                if (data[this.navStateModel.VALUE].hasOwnProperty(i)) {
                    var value = data[this.navStateModel.VALUE][i][this.navStateModel.VALUE];
                    if (value && value != this.DELETE_TOKEN) {
                        arr.push(i);
                    }
                }
            }
        }
        return arr;
    },
    setItemValue: function(itemName, value) {
        if (!this.navStateNode) {
            //create this.widgetNavStateNode
            this.navStateNode = this._createNavStateNode();
        }
        var data = this.navStateNode.getRef();
        data.params = data.params ? data.params : {};
        data.params.lm = new Date().getTime(); //mark lm of itemset
        data.value = data.value ? data.value : {};
        var change = {};
        if (!data.value[itemName]) {
            //new item
            data.value[itemName] = {};
            data.value[itemName].value = value;
            data.value[itemName].params = data.value[itemName].params ? data.value[itemName].params : {};
            data.value[itemName].params._isDirty = true;
            change.alias = itemName;
            change.type = this.TYPE_NEW;
            change.newVal = value;
            data.value[itemName].params._change = change;
        } else if (data.value[itemName]) {
            var oldValue = dojo.clone(data.value[itemName].value);
            data.value[itemName].value = value;
            data.value[itemName].params = data.value[itemName].params ? data.value[itemName].params : {};
            var isDirty = data.value[itemName].params._isDirty;
            if (isDirty) {
                //check various condition
                change = data.value[itemName].params._change;
                if (change.type == this.TYPE_NEW) {
                    change.newVal = value;
                } else if (change.type == this.TYPE_UPDATE) {
                    change.newVal = value;
                } else if (change.type == this.TYPE_REMOVE) {
                    if (change.oldVal) {
                        change.type = this.TYPE_UPDATE;
                    } else {
                        change.type = this.TYPE_NEW;
                    }
                    change.newVal = value;
                }
            } else {
                change.type = this.TYPE_UPDATE;
                change.oldVal = oldValue;
                change.newVal = value;
                change.alias = itemName;
                data.value[itemName].params._change = change;
            }
            data.value[itemName].params._isDirty = true;
        }
        this.navStateModel.setDirty(true);
        return true;

    },
    removeItem: function(itemName) {
        if (!this.navStateNode) {
            return false;
        }
        var data = this.navStateNode.getRef();
        data.params = data.params ? data.params : {};
        data.params.lm = new Date().getTime(); //mark lm of itemset
        if (data && data[this.navStateModel.VALUE]) {
            if (data[this.navStateModel.VALUE][itemName]) {
                var anItem = data[this.navStateModel.VALUE][itemName];
                var oldValue = dojo.clone(anItem.value);
                anItem.value = this.DELETE_TOKEN;
                anItem.params = anItem.params ? anItem.params : {};
                var isDirty = anItem.params._isDirty;
                var change = {};
                if (isDirty) {
                    change = anItem.params._change;
                    if (change.type == this.TYPE_NEW) {
                        //completely remove this item
                        //data[this.navStateModel.VALUE][itemName];
                        delete data[this.navStateModel.VALUE][itemName];
                    } else if (change.type == this.TYPE_UPDATE) {
                        change.type = this.TYPE_REMOVE;
                        change.newVal = null;
                        delete change.oldVal;
                    } //don't do anything if it's remove
                } else {
                    change.type = this.TYPE_REMOVE;
                    change.alias = itemName;
                    change.oldVal = oldValue;
                    anItem.params._change = change;
                    anItem.params._isDirty = true;
                }
                this.navStateModel.setDirty(true);
            } else {
                return false; //if item not found
            }
        }

        return true;
    },
    getItemValue: function(itemName) {
        if (!this.navStateNode) {
            return null;
        }
        var data = this.navStateNode.getRef();
        if (data && data[this.navStateModel.VALUE]) {
            if (data[this.navStateModel.VALUE][itemName]) {
                var anItemNode = data[this.navStateModel.VALUE][itemName];
                var value = anItemNode[this.navStateModel.VALUE];
                if (value && value != this.DELETE_TOKEN) {
                    return value;
                }
            }
        }
        return null;
    },
    registerListener: function(listener) {
        if (!this.navStateNode) {
            //create this.widgetNavStateNode
            this.navStateNode = this._createNavStateNode();
        }

        var data = this.navStateNode.getRef();
        var params = data[this.navStateModel.PARAMS];
        if (!params) {
            data[this.navStateModel.PARAMS] = {};
            params = data[this.navStateModel.PARAMS];
        }
        if (!params._listeners) {
            params._listeners = {};
        }
        var listenerId = this.navStateModel._generateListenerId();
        params._listeners[listenerId] = listener; //save the function pointer here
        return listenerId;
    },
    removeListener: function(listenerId) {
        if (!this.navStateNode) {
            return null;
        }
        var data = this.navStateNode.getRef();
        var params = data[this.navStateModel.PARAMS];
        if (params && params._listeners) {
            var listeners = params._listeners;
            if (listeners[listenerId]) {
                listeners[listenerId] = null;
                delete listeners[listenerId];
                return true;
            }
        }
        return false;
        //listener not found
    },
    _setItems: function(changedItems) {
        // add data to navigationstate
        for (var i in changedItems) {
            if (changedItems[i] && changedItems[i] == this.DELETE_TOKEN) {
                this.removeItem(i);
            } else if (changedItems[i]) {
                this.setItemValue(i, changedItems[i]);
            }
        }
    }
});

com.ibm.mm.enabler.model.state.ShareableParameterSetAccessorImpl.GLOBAL_SCOPE = "global";

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.LayoutContainerAccessor_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.LayoutContainerAccessor_API"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.LayoutContainerAccessor_API");
dojo.provide("com.ibm.mashups.enabler.model.state.LayoutContainerAccessor");


/**
 * Interface representing a LayoutContainerAccessor. Reserved layout container paramers:
 * "w"  : the reserved parameter for layout container width.
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare( "com.ibm.mashups.enabler.model.state.LayoutContainerAccessor", [com.ibm.mashups.enabler.model.state.Accessor], {
    /**
      * @private
      */
    constructor:function (navStateModel, componentId, pageId) {
    },
	/**
     * Returns the id of the layout container
     * @type String
     * @return {String} ID of required layout container
     */
	getID:function() {
	},
	/**
     * Returns the size of the required layout container
     * @type Object
     * @return {Object} A JSON object representing the layout container width, for example: <code>{w:"70%"}</code>
     */
	getSize:function() {
	},
	/**
     * Set the size of a layout container
     * @param {String} width The width of the layout container
     * @type LayoutContainerAccessor
     * @return{LayoutContainerAccessor} return an handle of LayoutContainerAccessor upon successful, <code>null</code> upon failure.
     */
	setSize:function(width) {
	},
	/**
     * Confirms whether it's possible or not to set the layout container to the new width and height
     * @param {String} width The width of the layout container
     * @type Boolean
     * @return{Boolean} return true if it's possible to set layout container to the new width and height
     */
	confirmSetSize:function(width) {
		return true;
	}

});

}

if(!dojo._hasResource["com.ibm.mm.enabler.model.state.LayoutContainerAccessorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.state.LayoutContainerAccessorImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.state.LayoutContainerAccessorImpl");



dojo.declare("com.ibm.mm.enabler.model.state.LayoutContainerAccessorImpl", [com.ibm.mashups.enabler.model.state.LayoutContainerAccessor], {

    constructor: function(navStateModel, containerId, pageId){
        this.navStateModel = navStateModel;
        this.cid = containerId;
        this.pid = pageId;

        var delim = this.navStateModel.DELIMITER;
        var path = this.LAYOUT_PREFIX;

        path += delim + this.pid;
        this.layoutNavStateNode = navStateModel._find(path);

        if (this.layoutNavStateNode) {
            path += delim + this.VALUE + delim + this.cid;
            this.layoutContainerNavStateNode = navStateModel._find(path);
        }
        else {
            this.layoutContainerNavStateNode = null;
        }
    },
    LAYOUT_PREFIX: "lcparams",
    WIDTH: "w",
    SYSTEMSTATE: "rp",
    VALUE: "value",
    PARAMS: "params",
    MODE: "md",
    RP: {
        w: "w"
    },
    getID: function(){
        return this.cid;
    },
    _getLayoutContainerSystemState: function(key){
        var value = null;
        if (!this.layoutContainerNavStateNode) {
            return null;
        }
        var data = this.layoutContainerNavStateNode.getRef();
        if (data && data[this.VALUE]) {
            if (data[this.VALUE][this.SYSTEMSTATE]) {
                data = data[this.VALUE][this.SYSTEMSTATE];
                if (data && data[key]) {
                    value = data[key];
                }
            }
        }
        return value;
    },
    _setLayoutContainerSystemState: function(key, value){
        var data;

        //overwrite behavior
        if (!this.layoutContainerNavStateNode) {
            this.layoutContainerNavStateNode = this._createLayoutContainerNavStateNode();
        }
        data = this.layoutNavStateNode.getRef();
        data.params = data.params ? data.params : {};
        data.params.lm = new Date().getTime();

        data = this.layoutContainerNavStateNode.getRef();
        var keyRef = null;
        data[this.VALUE] = data[this.VALUE] ? data[this.VALUE] : {};
        data[this.VALUE][this.SYSTEMSTATE] = data[this.VALUE][this.SYSTEMSTATE] ? data[this.VALUE][this.SYSTEMSTATE] : {};
        keyRef = data[this.VALUE][this.SYSTEMSTATE];

        keyRef[key] = value;
        this.navStateModel.setDirty(true);
        return this;
    },

    _createLayoutNavStateNode: function(){
        var aNode = this.navStateModel.create({
            key: this.pid
        });
        var parentNode = this.navStateModel._find(this.LAYOUT_PREFIX);
        if (!parentNode) {
            var temp = this.navStateModel.create({
                key: this.LAYOUT_PREFIX
            });
            this.navStateModel.insert(temp, this.navStateModel._getRoot());
            parentNode = this.navStateModel._find(this.LAYOUT_PREFIX);
        }
        this.navStateModel.insert(aNode, parentNode);
        aNode = this.navStateModel._find(this.LAYOUT_PREFIX + this.navStateModel.DELIMITER + this.pid);
        return aNode;
    },

    _createLayoutContainerNavStateNode: function(){
        //overwrite behaviour
        if (!this.layoutNavStateNode) {
            this.layoutNavStateNode = this._createLayoutNavStateNode();
        }

        var data = this.layoutNavStateNode.getRef();
        data[this.VALUE] = data[this.VALUE] ? data[this.VALUE] : {};

        var delim = this.navStateModel.DELIMITER;
        var path = this.LAYOUT_PREFIX + delim + this.pid + delim + this.VALUE;

        var aNode = this.navStateModel.create({
            key: this.cid
        });
        var parentNode = this.navStateModel._find(path);
        this.navStateModel.insert(aNode, parentNode);
        aNode = this.navStateModel._find(path + delim + this.cid);
        return aNode;
    },
    getSize: function(){
        var size = {};
        var width = this._getLayoutContainerSystemState(this.WIDTH);
        if (width) {
            size[this.WIDTH] = width;
            return size;
        }
        else {
            return null;
        }
        return size;
    },
    setSize: function(width){
        if (width) {
            this._setLayoutContainerSystemState(this.WIDTH, width);
        }
        return this;
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.LayoutContainerAccessor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.LayoutContainerAccessor"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.LayoutContainerAccessor");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.LayoutAccessor_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.LayoutAccessor_API"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.LayoutAccessor_API");
dojo.provide("com.ibm.mashups.enabler.model.state.LayoutAccessor");



/**
 * Interface representing a LayoutAccessor. Reserved layout container parameters:
 * "templateURL"  : the reserved parameter for layout template URL.
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare( "com.ibm.mashups.enabler.model.state.LayoutAccessor", [com.ibm.mashups.enabler.model.state.Accessor], {
    /**
      * @private
      */
    constructor:function (navStateModel, pageId) {
    },
    /**
     * Returns the layout template URL (can be used to determine if the state layout is inconsistent with the page instance layout)
     * @type String
     * @return {String} A url to the layout's template.  Uses dav: endpoint notation, e.g. "dav:filestore/layout-tempates/2ColumnEqual"
     */
    getTemplateURL:function() {
    },
    /**
     * Sets the layout template URL
     * @param {String} url The layout templateURL.  Uses dav: endpoint notation, e.g. "dav:filestore/layout-tempates/2ColumnEqual"
     * @type LayoutAccessor
     * @return{com.ibm.mashups.enabler.model.state.LayoutAccessor} returns a LayoutAccessor upon success, <code>null</code> upon failure.
     */
    setTemplateURL:function(url) {
    },
    /**
    * Returns the layout container accessor for the specified layout container id in this layout.  (Note: Possibly non-intinutively Layout contains LayoutContainers.)
    * @param {String} containerId  The layout container id for the desired layout container.
    * @type LayoutContainerAccessor
    * @return {com.ibm.mashups.enabler.model.state.LayoutContainerAccessor} Returns the specified LayoutContainerAccessor upon success, <code>null</code> upon failure.
    */
   getContainerAccessor:function(containerId) {
   },
    /**
     * Removes all layout containers and the template URL (can be used to remove obsolete layout's i.e. when the state layout is not the same as the page instance layout)
     * @param {Array} pageWidgets Set of widgets on page that if in model should have their size removed.  Optional parameter.
     * @type LayoutContainerAccessor
     * @return{com.ibm.mashups.enabler.model.state.LayoutAccessor} Returns a LayoutAccessor upon success, <code>null</code> upon failure.
     */
    removeAll:function(pageWidgets) {
    }

});

}

if(!dojo._hasResource["com.ibm.mm.enabler.model.state.LayoutAccessorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.state.LayoutAccessorImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.state.LayoutAccessorImpl");




dojo.declare("com.ibm.mm.enabler.model.state.LayoutAccessorImpl", [com.ibm.mashups.enabler.model.state.LayoutAccessor], {

    constructor: function(navStateModel, pageId){
        this.navStateModel = navStateModel;
        this.pid = pageId;

        this.path = this.LAYOUT_PREFIX + this.navStateModel.DELIMITER + this.pid;

        this.layoutNavStateNode = null;
    },

    LAYOUT_PREFIX: "lcparams",
    WIDGET_PREFIX: "wparams",
    VALUE: "value",
    TEMPLATE_URL: "templateURL",
    SYSTEMSTATE: "rp",
    WIDTH: "w",
    HEIGHT: "h",

    _getLayoutState: function(key){
        var value = null;

        // we need to check if the layoutNavsState node exists for each call because
        // layout containers can create this node too.
        if (!this.layoutNavStateNode) {
            this.layoutNavStateNode = this.navStateModel._find(this.path);
            if (!this.layoutNavStateNode)
                return null;
        }

        var data = this.layoutNavStateNode.getRef();
        if (data && data[key])
            value = data[key];

        return value;
    },

    _setLayoutState: function(key, value){
        var data;

        //overwrite behavior
        if (!this.layoutNavStateNode) {
            this.layoutNavStateNode = this.navStateModel._find(this.path);
            if (!this.layoutNavStateNode)
                this.layoutNavStateNode = this._createLayoutNavStateNode();
        }
        data = this.layoutNavStateNode.getRef();
        data.params = data.params ? data.params : {};
        data.params.lm = new Date().getTime();

        data[key] = value;
        this.navStateModel.setDirty(true);
        return this;
    },

    _createLayoutNavStateNode: function(){
        var aNode = this.navStateModel.create({
            key: this.pid
        });
        var parentNode = this.navStateModel._find(this.LAYOUT_PREFIX);
        if (!parentNode) {
            var temp = this.navStateModel.create({
                key: this.LAYOUT_PREFIX
            });
            this.navStateModel.insert(temp, this.navStateModel._getRoot());
            parentNode = this.navStateModel._find(this.LAYOUT_PREFIX);
        }
        this.navStateModel.insert(aNode, parentNode);
        aNode = this.navStateModel._find(this.path);
        return aNode;
    },
    getTemplateURL: function(){
        return this._getLayoutState(this.TEMPLATE_URL);
    },
    setTemplateURL: function(url){
        return this._setLayoutState(this.TEMPLATE_URL, url);
    },
    removeAll: function(pageWidgets) {
        var delim = this.navStateModel.DELIMITER;
        if (pageWidgets && this.navStateModel._find(this.WIDGET_PREFIX)) {
            var i;
            var systemState;
            for (i = 0; i < pageWidgets.length; i++) {
                systemState = this.navStateModel._find(this.WIDGET_PREFIX + delim + pageWidgets[i] + delim + this.VALUE + delim + this.SYSTEMSTATE);
                if (systemState) {
                    systemState = systemState.getRef();
                    delete systemState[this.WIDTH];
                    delete systemState[this.HEIGHT];
                    this.navStateModel.setDirty(true);
                }
            }
        }

        if (this.layoutNavStateNode) {
            this.navStateModel.remove(this.layoutNavStateNode);
            this.navStateModel.setDirty(true);
            delete this.layoutNavStateNode;
        }
        return this;
    },
    getContainerAccessor: function(containerId) {
        return new com.ibm.mm.enabler.model.state.LayoutContainerAccessorImpl(this.navStateModel, containerId, this.pid);
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.LayoutAccessor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.LayoutAccessor"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.LayoutAccessor");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.AccessorFactory_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.AccessorFactory_API"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.AccessorFactory_API");
dojo.provide("com.ibm.mashups.enabler.model.state.AccessorFactory");







/**
 * Interface representing an AccessorFactory. Accessor API should be used to read/write information from NavigationStateModel.
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare( "com.ibm.mashups.enabler.model.state.AccessorFactory", null, {

    /**
     * Returns the Accessor to access Page selection in each Space
     * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navStateModel NavigationStateModel to get Space/Page Selection
     * @param {String} spaceId spaceId to getPage Selection
     * @type com.ibm.mashups.enabler.model.state.PageAccessor
     * @return {com.ibm.mashups.enabler.model.state.PageAccessor} The PageAccessor of NavigationStateModel
     */
	getPageAccessor:function(navStateModel,spaceId) {
        // look for node in model and instatiate the Page Accessor with Node
	},
	 /**
     * Returns the Accessor to access Space selection
     * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navStateModel NavigationStateModel to get Space Selection
     * @type com.ibm.mashups.enabler.model.state.SpaceAccessor
     * @return {com.ibm.mashups.enabler.model.state.SpaceAccessor} The SpaceAccessor of NavigationStateModel
     */
	getSpaceAccessor:function(navStateModel) {
	},
	/**
     * Returns the Widget Accessor to access Widget state information
     * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navStateModel to Widget Navigation State
     * @param {String} widgetId to Widget Navigation State
      * @type com.ibm.mashups.enabler.model.state.WidgetAccessor
     * @return {com.ibm.mashups.enabler.model.state.WidgetAccessor} The WidgetAccessor of NavigationStateModel
     */
	getWidgetAccessor:function(navStateModel, widgetId) {
	},
   /**
     * Returns the Accessor to access Page mode of current page
     * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navStateModel NavigationStateModel to get Space/Page Selection
     * @type com.ibm.mashups.enabler.model.state.PageModeAccessor
     * @return {com.ibm.mashups.enabler.model.state.PageModeAccessor} The PageModeAccessor of NavigationStateModel
     */
	getPageModeAccessor:function(navStateModel) {
        // look for node in model and instatiate the Page Accessor with Node
	},
 /**
     * Returns the Accessor to access the sharable parameters
     * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navStateModel NavigationStateModel to get ShareableParameterSet
     * @param {String}  id  id of ShareableParameterSet
     * @param {String}  scope  optional scope for the sharable item set. If not provided or null, the global scope is returned.
     * @type com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor
     * @return {com.ibm.mashups.enabler.model.state.ShareableParameterSetAccessor} The ShareableParameterSetAccessor of NavigationStateModel
     */
	getShareableParameterSetAccessor:function(navStateModel,id,scope) {
        // look for node in model and instatiate the Page Accessor with Node
	},

	/**
     * Returns the Layout Accessor to access page layout state information
     * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navStateModel to Layout Navigation State
     * @param {String} pageId of the page containing the Layout Container
     * @type com.ibm.mashups.enabler.model.state.LayoutAccessor
     * @return {com.ibm.mashups.enabler.model.state.LayoutAccessor} The LayoutAccessor of NavigationStateModel for the specified page
     */
	getLayoutAccessor:function(navStateModel, pageId){
	}

});

}

if(!dojo._hasResource["com.ibm.mm.enabler.model.state.AccessorFactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.state.AccessorFactoryImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.state.AccessorFactoryImpl");









dojo.declare("com.ibm.mm.enabler.model.state.AccessorFactoryImpl", [com.ibm.mashups.enabler.model.state.AccessorFactory], {

    constructor: function() {
    },
    getPageAccessor: function(navStateModel, spaceId) {
        return new com.ibm.mm.enabler.model.state.PageAccessorImpl(navStateModel, spaceId);
    },
    getPageModeAccessor: function(navStateModel) {
        return new com.ibm.mm.enabler.model.state.PageModeAccessorImpl(navStateModel);
    },
    getSpaceAccessor: function(navStateModel) {
        return new com.ibm.mm.enabler.model.state.SpaceAccessorImpl(navStateModel);
    },
    getWidgetAccessor: function(navStateModel, widgetId) {
        return new com.ibm.mm.enabler.model.state.WidgetAccessorImpl(navStateModel, widgetId);
    },
    getShareableParameterSetAccessor: function(navStateModel, name, scope) {
        return new com.ibm.mm.enabler.model.state.ShareableParameterSetAccessorImpl(navStateModel, name, scope);
    },
	getLayoutAccessor:function(navStateModel, pageId){
		return new com.ibm.mm.enabler.model.state.LayoutAccessorImpl(navStateModel, pageId);
	}
});
com.ibm.mashups.enabler.model.state.AccessorFactory = new com.ibm.mm.enabler.model.state.AccessorFactoryImpl();

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.AccessorFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.AccessorFactory"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.AccessorFactory");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateModel_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateModel_API"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateModel_API");
dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateModel");

/**
 * Interface for a Navigation state model.<br/>
 * Navigation State API does not garantee that any modifications issued on the API have any further impact on the<br/>
 * user experience of any widgets or components on the page.  Widgets or components may choose to listen to changes on the Navigation</br>
 * State Model and react properly upon those changes. However any user experience change cuased by those components are not part of</br>
 * the contract of this API and therefore these UI behaviour may change going forward<br>
 *
 * AccessorFactory API should be used to read/write navigation state within NavigationStateModel.</code><br/>
 * <code>var navStateModel=com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();</code><br/>
 * <code>var widgetAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getWidgetAccessor(navStateModel);</code><br/>
 * <code>widgetAccessor.setSize("200","300");</code><br/>
 * <code>var deferred = navStateModel.commit();</code><br/>
 * <code>deferred.setFinishedCallback(cb);</code><br/>
 * <code>deferred.start();</code><br/>
 *
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare( "com.ibm.mashups.enabler.model.state.NavigationStateModel", null,     {

    /**
    * The name of the event to handle to get NavState update notifications.
    * @type String
    */
	ONNAVSTATEUPDATED:"com.ibm.mashups.enabler.model.state.onNavStateUpdated",

    /**
    * This method starts a global transaction for a NavigationStateModel object<br>
    * @type void
    */
    startTransaction: function () {
        return;
    },
    /**
    * This method commits all changes done withing a global transaction for a NavigationStateModel object<br>
    * @type void
    */
    commitTransaction: function () {
        return;
    },
    /**
    * This method discards all changes done within a  transaction for a NavigationStateModel object and restores the original NavigationStateModel object.<br>
    * @type void
    */
    discardTransaction: function () {
        return;
    },
    /**
    * This method starts a global transaction for a NavigationStateModel object<br>
    * @return {boolean} Returns true if a transaction has been started, false otherwise.
	*/
    isTransaction: function () {
        return false;
    },

    /**
    * Commits the modifications applied to this model and all dependent models.<br>
    * @param {Object} additionalParams <i>Optional</i> JSON object to control various aspects while commiting <br>
    * &nbsp;&nbsp;<b><code>addToHistory</code> (Boolean)</b> - <code>true</code> if the state should be added to the browser history, <code>false</code> otherwise <br>
    * &nbsp;&nbsp;<b><code>allowRedirect</code> (Boolean)</b> - <code>true</code> if the page should be refreshed after the commit, <code>false</code> otherwise.  Note, this parameter is ignored if the commit is synchronous <br>
    * @return {DeferredOperation} a deferred object used to start this operation.
    * The return value when executed through the deferred object is <code>null</code>
    */
    commit: function (additionalParams) {
        return new com.ibm.mashups.enabler.Deferred();
    },

    /**
    * Discards the modifications applied to this model. <br>
    * @type void
    */
    discard: function () {
        return;
    },

    /**
    * Dispose this model completely all the navigation state will be destroyed. <br>
    * @type void
    */
    dispose: function () {
        return;
    }

});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.services.IdentificationService_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.services.IdentificationService_API"] = true;
dojo.provide("com.ibm.mashups.enabler.services.IdentificationService_API");
dojo.provide("com.ibm.mashups.enabler.services.IdentificationService");


/**
 * Interface to work with client side ids.
 * @ibm-spi
 * @ibm-module Base
 * @since 3.0
 */
dojo.declare("com.ibm.mashups.enabler.services.IdentificationService", null, {
    /**
     * Returns a new client side ID.
     * @return {String} client side id; never <code>null</code>.
     */
    createClientID: function() {
    },
    /**
     * This method attaches a client side id to make it know to the service
     * @param {Object} clientID client side id as string or Identifiable object
     * @return {void}
     * @since 3.0.0.1
     */
    attachClientID: function(clientID) {
    },
    /**
     * Releases an earlier through <tt>getClientID</tt> loaded client id.
     * @param {String} id the id to release
     * @return {void}
     */
    releaseClientID: function(id) {
    },
    /**
     * Checks whether the specified id is a client id of this IdentificationService
     * @param {String} id the id to check for client id
     * @return {boolean} <tt>true</tt> if the specified id is a client id <tt>false</tt> otherwise.
     */
    isClientID: function(id) {
    },
    /**
     * Checks whether the specified id is a server id generated by the underling server implementation
     * @param {String} id the id to check for server id
     * @return {boolean} <tt>true</tt> if the specified id is a server id <tt>false</tt> otherwise.
     */
    isServerID: function(id) {
    },
    /**
     * Checks whether the specified id is neither an client id nor an server id but is specified outside the mashup framework.
     *
     * @param {String} id the id to check for alien id
     * @return {boolean} <tt>true</tt> if the specified id is a alien id <tt>false</tt> otherwise.
     */
    isAlienID: function(id) {
    },
    /**
     * This method attaches a server side id to an existing client side id.
     * @param {Object} clientID client side id as string or Identifiable object
     * @param {Object} serverID server side id as string or Identifiable object
     * @return {void}
     */
    attachServerID: function(clientID, serverID) {
    },

    /**
     * Returns the attached server side id for any given client side id. Returns the
     * specified id, if it cannot be resolved.
     * @param {String} id the id to resolve
     * @return {String} id the resolved id
     */
    resolveID: function(id) {
    },

    /**
     * Returns the attached server side id for any given client side id. Returns the
     * specified id, if it cannot be resolved.
     * @param {String} id the id to resolve
     * @return {com.ibm.mashups.enabler.Identifiable} id the resolved id
     */
    resolveIdentifiable: function(id) {
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.utils.Utils"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.utils.Utils"] = true;
/*WARNING: don't include this class in any  iWidget2 modules,it should be exclusively used by Model related api*/
dojo.provide("com.ibm.mm.enabler.utils.Utils");






dojo.declare("com.ibm.mm.enabler.utils.UtilsImpl", null, {
    constructor: function() {
        // we do a lazy init
        this.serviceJson = null;
    },
    _lazyInit: function() {
        if (this.serviceJson) {
            return;
        }
        this.xmlDom = com.ibm.mm.enabler.utils.Dom.createDocument();
        // service document and initialization
        this.serviceJson = com.ibm.mm.enabler.model.ServiceDocumentModel.getCollectionData(com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_NAVIGATION);
        this.prefix = this.serviceJson.idprefix;
        var nsf = com.ibm.mm.enabler.model.NameSpaceFactory;
        this.ns = dojo.delegate(this.serviceJson.namespaces, nsf.getNameSpaces([nsf.NS_ATOM]));
    },

    createNode: function(name, ns) {
        this._lazyInit();
        return com.ibm.mm.enabler.utils.Dom.createElement(this.xmlDom, name, ns);
    },

    createLinkNode: function(href, rel, ns) {
        var linkNode = this.createNode("atom:link", ns);
        linkNode.setAttribute("href", href);
        linkNode.setAttribute("rel", rel);
        return linkNode;
    },

    createExtLinkNode: function(href, rel, extrel) {
        this._lazyInit();
        var nsf = com.ibm.mm.enabler.model.NameSpaceFactory;
        var linkNode = this.createNode("atom:link", this.ns[nsf.NS_ATOM]);
        linkNode.setAttribute("href", href);
        if (rel) {
            linkNode.setAttribute("rel", rel);
        }
        com.ibm.mm.enabler.utils.Dom.setAttributeWithNS(this.xmlDom, linkNode, "ext:rel", "rel", this.ns.ext, extrel);
        return linkNode;
    },

    getIdFromExtUri: function(prefix, node) {
        this._lazyInit();
        var id = null;
        var uri = com.ibm.mm.enabler.utils.Dom.getAttributeWithNS(node, "ext:uri", "uri", this.ns.ext);
        // remove model scope from id
        if (uri) {
            // check for associative id
            var aPos = uri.indexOf("@");
            if (aPos != -1) {
                uri = uri.slice(0, aPos);
            }
            id = uri;
            // remove model scope from id
            var idPos = id.lastIndexOf(":");
            if (idPos != -1) {
                id = id.slice(idPos + 1);
            }
            idPos = id.toUpperCase().lastIndexOf("%3A");
            if (idPos != -1) {
                id = id.slice(idPos + 3);
            }
            idPos = id.lastIndexOf("/");
            if (idPos != -1) {
                id = id.slice(idPos + 1);
            }
        }
        return id;
    },


    getHrefFromIdentifiable: function(identifiable) {
        return (identifiable && (typeof identifiable._getParameters == "function")) ? identifiable._getParameters().href : null;
    },

    getIdFromIdentifiable: function(identifiable) {
        if(com.ibm.mm.enabler.utils.Misc.isInstanceOf(identifiable, com.ibm.mashups.enabler.Identifiable)) {
            return identifiable.getID();
        } else if(dojo.isString(identifiable)) {
            return dojo.string.trim(identifiable);
        } else {
            return identifiable;
        }
    },

    setAttributeWithNS: function(element, attName, nsUri, value) {
        this._lazyInit();
        com.ibm.mm.enabler.utils.Dom.setAttributeWithNS(this.xmlDom, element, attName, null, nsUri, value);
    },
    createFeed: function(id, title, entry, namespaces) {
        var ns = "";
        for (var prefix in namespaces) {
            if (Object.prototype.hasOwnProperty.call(namespaces,prefix)) {
                ns += "xmlns:" + prefix + "=\"" + namespaces[prefix] + "\" ";
            }
        }
        var time = new Date();
        var feed = '<?xml version="1.0" encoding="UTF-8"?>\n' +
        '<atom:feed ' +
        ns +
        ' >\n' +
        '<atom:title>' +
        title +
        '</atom:title>\n' +
        '<atom:id>' +
        id +
        '</atom:id>\n' +
        '<atom:updated>' +
        time.toGMTString() +
        '</atom:updated>\n' +
        entry +
        '</atom:feed>';
        return feed;
    }
});

com.ibm.mm.enabler.utils.Utils = new com.ibm.mm.enabler.utils.UtilsImpl();

}

if(!dojo._hasResource["com.ibm.mm.enabler.IdentifiableHelper"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.IdentifiableHelper"] = true;
dojo.provide("com.ibm.mm.enabler.IdentifiableHelper");

//com.ibm.mm.enabler.IdentifiableHelper.getID = function(id){
//    // check for associative id
//    var aPos = id.indexOf("@");
//    if (aPos != -1) {
//        id = id.slice(0, aPos);
//    }
//
//    // remove model scope from id
//    var idPos = id.lastIndexOf(":");
//    if (idPos != -1) {
//        id = id.slice(idPos + 1);
//    }
//    idPos = id.toUpperCase().lastIndexOf("%3A");
//    if (idPos != -1) {
//        id = id.slice(idPos + 3);
//    }
//    idPos = id.lastIndexOf("/");
//    if (idPos != -1) {
//        id = id.slice(idPos + 1);
//    }
//
//    return id;
//};
com.ibm.mm.enabler.IdentifiableHelper.ID_MATCHER = /^(.*?)(%3a)?([ \.\w_\-]*)(@.*?)?$/i;
com.ibm.mm.enabler.IdentifiableHelper.getID = function(id) {
    var matches = id.match(com.ibm.mm.enabler.IdentifiableHelper.ID_MATCHER);
    return matches ? matches[3] : "";
};

//com.ibm.mm.enabler.IdentifiableHelper.replaceID = function(currentId, prefix, newId){
//
//    // associative id (including '@')
//    var aPos = currentId.indexOf("@");
//    var association = (aPos != -1) ? currentId.slice(aPos) : "";
//
//    // model schema
//    var mPos = currentId.indexOf(prefix + ":");
//    var model = (mPos > 0) ? currentId.slice(0, mPos) : "";
//
//    // remove model scope and add 'newId:' from input newId if necessary
//    var idPos = newId.indexOf(prefix + ":");
//    var value = (idPos >= 0) ? newId.slice(idPos) : prefix + ":" + newId;
//
//    return model + value + association;
//};

com.ibm.mm.enabler.IdentifiableHelper.replaceID = function(currentId, prefix, newId) {
    var id = com.ibm.mm.enabler.IdentifiableHelper.getID(newId);
    var matches = currentId.match(com.ibm.mm.enabler.IdentifiableHelper.ID_MATCHER);
    return prefix + ":" + id + (matches ? (matches[4] || "") : "");
};

}

if(!dojo._hasResource["com.ibm.mm.enabler.utils.Atom"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.utils.Atom"] = true;
dojo.provide("com.ibm.mm.enabler.utils.Atom");








com.ibm.mm.enabler.utils.Atom = {

    // atom feed
    _FEED: "atom:feed",

    // atom entry
    _ENTRY: "atom:entry",

    // atom link
    _LINK: "atom:link",

    // atom id
    _ID: "atom:id",

    // next link
    _NEXT_LINK: "atom:link[@rel='next']",

    // edit link
    _EDIT_LINK: "atom:link[@rel='edit']",

    // replies link
    _REPLIES_LINK: "atom:link[@rel='replies']",

    // replies link href
    _REPLIES_LINK_HREF: "atom:link[@rel='replies']/@href",

    // in-reply-to link
    _IN_REPLY_TO_LINK: "thr:in-reply-to",

    // in-reply-to link href
    _IN_REPLY_TO_LINK_HREF: "thr:in-reply-to/@href",

    /**
     * Creates an atom:entry with a title and an optional element for a specific model artifact.
     *
     * Example usage:
     *
     *
     *
     * var res = com.ibm.mm.enabler.utils.Misc._createAtomEntry("new navigation node", "model:navigation-node", namespace);
     * var entry = res.entryElement; 	// reference to <atom:entry>
     * var id = res.idElement;			// reference to <atom:id>
     * var model = res.modelElement;  	// reference to <model:navigation-node>
     *
     * @param {String} title title of the atom:entry
     * @param {String} qname the qname of the model artifact to be created in the atom:content element
     * @param {String} namespace corresponding name space
     * @return {Object} object with properties "entryElement", "modelElement" (optional), and "idElement"
     */
    createEntry: function(title, qname, namespace){

        var result = {};

        // name spaces
        var nsf = com.ibm.mm.enabler.model.NameSpaceFactory;
        var ns = nsf.getNameSpaces([nsf.NS_ATOM]);

        // atom:entry
        var entry = com.ibm.mm.enabler.utils.Utils.createNode("atom:entry", ns.atom);

        // atom:id
        var idElem = com.ibm.mm.enabler.utils.Utils.createNode("atom:id", ns.atom);
        entry.appendChild(idElem);

        // atom:title
        var titleElem = com.ibm.mm.enabler.utils.Utils.createNode("atom:title", ns.atom);
        if (title) {
            com.ibm.mm.enabler.utils.Dom.textContent(titleElem, title);
        }
        entry.appendChild(titleElem);

        // atom:updated
        var updated = com.ibm.mm.enabler.utils.Utils.createNode("atom:updated", ns.atom);
        var time = new Date();
        com.ibm.mm.enabler.utils.Dom.textContent(updated, time.toGMTString());
        entry.appendChild(updated);

        // atom:content
        var content = com.ibm.mm.enabler.utils.Utils.createNode("atom:content", ns.atom);
        content.setAttribute("type", "application/xml");
        entry.appendChild(content);

        if (qname && namespace) {
            // add specified element
            var elem = com.ibm.mm.enabler.utils.Utils.createNode(qname, namespace);
            content.appendChild(elem);
            result.modelElement = elem;
        }

        result.entryElement = entry;
        result.idElement = idElem;
        return result;
    }
};

}

if(!dojo._hasResource["com.ibm.mm.enabler.persistence.xml.IdentifiableXmlImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.persistence.xml.IdentifiableXmlImpl"] = true;
dojo.provide("com.ibm.mm.enabler.persistence.xml.IdentifiableXmlImpl");












// i18n



dojo.declare("com.ibm.mm.enabler.persistence.xml.IdentifiableXmlImpl", [com.ibm.mashups.enabler.Identifiable, com.ibm.mm.enabler.DirtyFlagProviderImpl, com.ibm.mm.enabler.ServiceDocConsumer], {
    constructor: function(){
        // messages
        this.modelMessages = dojo.i18n.getLocalization("com.ibm.mm.enabler", "modelMessages");

        this._resetCachedRawID();
        this._addDirtyCallback(this, this._resetCachedRawID, null, true);
    },

    // class member - must NOT be an instance member
    _cachedRawIdToken: {},

    _resetCachedRawID: function(){
        this._cachedRawID = this._cachedRawIdToken;
    },

    _cachedRawID: null,

    _initServiceDoc: function(){
        this.inherited("_initServiceDoc", arguments);
        // service document and initialization
        var serviceJson = com.ibm.mm.enabler.model.ServiceDocumentModel.getCollectionData(com.ibm.mm.enabler.model.ServiceDocumentModel.SERVICE_NAVIGATION);
        var nsf = com.ibm.mm.enabler.model.NameSpaceFactory;
        this.id_ns = dojo.delegate(serviceJson.namespaces, nsf.getNameSpaces([nsf.NS_ATOM, nsf.NS_THR, nsf.NS_XML, nsf.NS_OPENSEARCH, nsf.NS_XHTML, nsf.NS_APP]));
        this.id_prefix = serviceJson.idprefix;
    },

    getID: function(){
        var id = this._getRawID();
        return id ? com.ibm.mm.enabler.IdentifiableHelper.getID(id) : id;
    },

    _getRawID: function(){
        this._initServiceDoc();
        if (this._cachedRawID === this._cachedRawIdToken) {
            var result = null;
            var node = com.ibm.mashups.enabler.xml.XPath.evaluateString(com.ibm.mm.enabler.utils.Atom._ID, this.xmlData, this.id_ns);
            if (node) {
                result = dojo.string.trim(node);
            }
            this._cachedRawID = result;
        }
        return this._cachedRawID;
    },

    equals: function(identifiable){
        return com.ibm.mm.enabler.utils.Utils.getIdFromIdentifiable(this) == com.ibm.mm.enabler.utils.Utils.getIdFromIdentifiable(identifiable);
    },

    setID: function(id){
        this._initServiceDoc();
        var rawID = this._getRawID();
        var newId = com.ibm.mm.enabler.IdentifiableHelper.replaceID(rawID || "", this.id_prefix, id);
        if (newId != rawID) {
            this._setRawID(newId);
        }
    },
    _setRawID: function(id){
        this._initServiceDoc();
        id = id || "";
        var node = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(com.ibm.mm.enabler.utils.Atom._ID, this.xmlData, this.id_ns);
        if (node) {
            var currentId = this._getRawID();

            if (id != currentId) {
                com.ibm.mm.enabler.utils.Dom.textContent(node, id);
                this._setDirty();

                // populate cache
                this._cachedRawID = dojo.string.trim(id);
            }
        }
        else {
            throw new Error(dojo.string.substitute(this.modelMessages.E_ELEMENT_NOT_FOUND_2, [com.ibm.mm.enabler.utils.Atom._ID, this.toString()]));
        }
    },

    getUniqueName: function(){
        this._initServiceDoc();
        var name = null;
        var res = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(com.ibm.mm.enabler.utils.Atom._ID, this.xmlData, this.id_ns);
        if (res) {
            name = com.ibm.mm.enabler.utils.Dom.getAttributeWithNS(res, "ext:uniquename", "uniquename", this.id_ns.ext);
        }
        return name || "";
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.IdentifierImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.IdentifierImpl"] = true;



dojo.provide("com.ibm.mm.enabler.IdentifierImpl");

// identifier
dojo.declare("com.ibm.mm.enabler.IdentifierImpl", com.ibm.mm.enabler.persistence.xml.IdentifiableXmlImpl, {
    _id: null,
    _params: null,

    constructor: function(id, params) {
        if (dojo.isString(id)) {
            this._id = id;
        }
        else {
            this.xmlData = id;
        }
        this._params = params;
    },

    setID: function(id) {
        if (this._id) {
            this._id = id;
        }
        else {
            this.inherited(arguments);
        }
    },

    getID: function() {
        return this._id ? com.ibm.mm.enabler.IdentifiableHelper.getID(this._id) : this.inherited(arguments);
    },

    _getParameters: function() {
        return this._params;
    },
    /**
     * This method returns the raw id like it is stored in the atom entry
     */
    _getRawID: function() {
        return this._id ? this._id : this.inherited(arguments);
    },

    _setRawID: function(id) {
        if (!this._id) {
            var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(com.ibm.mm.enabler.utils.Atom._ID, this.xmlData, this.id_ns);
            if (nodes) {
                com.ibm.mm.enabler.utils.Dom.textContent(nodes, id);
            }
        }
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.services.IdentificationServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.services.IdentificationServiceImpl"] = true;
dojo.provide("com.ibm.mm.enabler.services.IdentificationServiceImpl");






dojo.declare("com.ibm.mm.enabler.services.IdentificationServiceImpl", [com.ibm.mashups.enabler.services.IdentificationService], {
    constructor: function() {
        // client ids
        this.clientIds = {};

        // client id map
        this.clientServerMap = {};

        var regexString = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.SERVER_OBJECT_ID_FORMAT);

        if (!regexString) {
            regexString = "M[A-F0-9]+$";
        }

        // the regexp for the Server ID
        this.serverOidRegExp = new RegExp(regexString);
    },

    createClientID: function() {
        while (true) {
            var id = dojox.uuid.generateRandomUuid().replace(/-/g, "_");

            if (!(id in this.clientIds)) {
                this.clientIds[id] = null;
                return id;
            }
        }

        // unreachable code
        return null;
    },
    attachClientID: function(clientID) {
        this.clientIds[clientID] = null;
    },
    releaseClientID: function(id) {
        var cidString = com.ibm.mm.enabler.utils.Utils.getIdFromIdentifiable(id);

        if (this.isClientID(cidString)) {
            delete this.clientIds[cidString];
            delete this.clientServerMap[cidString];
        }
    },
    isClientID: function(id) {
        return (id in this.clientIds);
    },
    isServerID: function(id) {
        return this.serverOidRegExp.test(id);
    },
    isAlienID: function(id) {
        return !this.isServerID(id) && !this.isClientID(id);
    },
    attachServerID: function(cid, sid) {
        var cidString = com.ibm.mm.enabler.utils.Utils.getIdFromIdentifiable(cid);
        var sidString = com.ibm.mm.enabler.utils.Utils.getIdFromIdentifiable(sid);
        // create mapping
        this.clientServerMap[cidString] = sidString;
    },

    resolveID: function(id) {
        var cidString = com.ibm.mm.enabler.utils.Utils.getIdFromIdentifiable(id);
        return (cidString in this.clientServerMap) ? this.clientServerMap[cidString] : cidString;
    },

    resolveIdentifiable: function(id) {
        return new com.ibm.mm.enabler.IdentifierImpl(this.resolveID(id));
    }
});

com.ibm.mashups.enabler.services.IdentificationService = new com.ibm.mm.enabler.services.IdentificationServiceImpl();

}

if(!dojo._hasResource["com.ibm.mashups.enabler.services.IdentificationService"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.services.IdentificationService"] = true;
dojo.provide("com.ibm.mashups.enabler.services.IdentificationService");







}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateProcessor_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateProcessor_API"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateProcessor_API");
dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateProcessor");

/**
 * Interface representing NavigationStateProcessor.NavigationState is internally Represented as an JSON object.<br/>
 * Paramters are predefined.<br/>
 * <code>
 * {<br/>
 *  sid:{<br/>
 *  &nbsp;&nbsp;value: &lt;sid>,<br/>
 *  &nbsp;&nbsp;params:{}<br/>
 *  },<br/>
 *  pid:{<br/>
 *  &nbsp;&nbsp;value: &lt;pid>,<br/>
 *  &nbsp;&nbsp;params:{}<br/>
 *  },<br/>
 *  pageselection:{<br/>
 *  &nbsp;&nbsp;&lt;spaceid>:{<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;value: &lt;pageid>,<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
 *  &nbsp;&nbsp;},<br/>
 *  &nbsp;&nbsp;&lt;spaceid>:{<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;value: &lt;pageid>,<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
 *  &nbsp;&nbsp;}<br/>
 *  },<br/>
 *  wparams:{<br/>
 *  &nbsp;&nbsp;&lt;wid>:{<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rp:{w:&lt;"200">,h:&lt;"300">,st:&lt;"NORMAL">},<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cp:{&lt;page:"3">}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;},<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
 *  &nbsp;&nbsp;},<br/>
 *  &nbsp;&nbsp;&lt;wid>:{<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rp:{w:&lt;"300">,h:&lt;"400">,st:&lt;"MAX">},<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cp:{&lt;page:"4">}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;},<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
 *  &nbsp;&nbsp;}<br/>
 *  },<br/>
 *  lcparams:{<br/>
 *  &nbsp;&nbsp;&lt;pid>:{<br/>
 *  &nbsp;&nbsp;templateURL: "&lt;dav:filestore/layout-templates/2ColumnEqual>",{<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;lcid>:{<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rp:{w:&lt;"70%">}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;lcid>:{<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rp:{w:&lt;"30%">}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;},<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
 *  &nbsp;&nbsp;},<br/>
 *  &nbsp;&nbsp;&lt;pid>:{<br/>
 *  &nbsp;&nbsp;templateURL: "&lt;dav:filestore/layout-templates/3ColumnEqual>",{<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;lcid>:{<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rp:{w:&lt;"30%">}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;lcid>:{<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rp:{w:&lt;"30%">}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;lcid>:{<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rp:{w:&lt;"40%">}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;},<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
 *  &nbsp;&nbsp;}<br/>
 *  },<br/>
 *  sparams:{<br/>
 *  &nbsp;&nbsp;&lt;id>:{<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;global: {<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>},<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name>:{<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: &lt;value>,<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name>:{<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: &lt;value>,<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;},<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&lt;scope-id>: {<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>},<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: {<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name>:{<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: &lt;value>,<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name>:{<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: &lt;value>,<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;params:{lm:&lt;timestamp>}<br/>
 *  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
 *  &nbsp;&nbsp;}<br/>
 *  }<br/>
 * }<br/>
 * </code>
 * <br/>
 * Navigation State parameters will be written to url or persistence store upon configuration.<br/>
 * Here's the default configuration:<br>
 * <ul>
 * <li>navstate.persistence.url = pid,cp,sparams</li>
 * <li>persistence.pstore = w,h,st,pid,sid,pageselection</li>
 * </ul>
 * <br/>
 * Following is the list of parameters that are configurable:<br/>
 * <ul>
 * <li>pid: page id </li>
 * <li>sid: space id </li>
 * <li>pageselection: page selections </li>
 * <li>sparams: shareable parameter sets </li>
 * <li>h: widget height </li>
 * <li>w: widget width </li>
 * <li>st: widget window state </li>
 * <li>md: widget mode </li>
 * <li>cp: widget customized state </li>
 * </ul>
 *
 * Upon page loading or page refresh, navigationstatemodel is initialized with navigation state data from url or </br>
 * persistence. "decode" will be used to load data from url and "preprocess" will be used to load data from persistence.</br>
 * Upon commit on NavigationStateModel updates, navigation state data will be sent to url or sent to persistence.</br>
 * "postprocess" will send the updates to persistence and "encode" will generate the new url fragment based on latest navigation state.</br>
 *
 *
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare( "com.ibm.mashups.enabler.model.state.NavigationStateProcessor", null, {
	/**
    * Encodes the specified widget instance id.
    * @param {String} wid widget instance id; different page may have same widget instance id.
    * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navigationStateModel
    * @type String
    * @return {String} unique id, representing a widget instance on a page
    */
    encodeWidgetIdentifier: function(wid, navigationStateModel){
    },
   /**
    * Decodes a unique widget instance id.
    * @param {String} wid unique widget instance id.
    * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navigationStateModel
    * @type String
    * @return {String} widget instance id
    */
    decodeWidgetIdentifier: function(wid, navigationStateModel){
    },
	/**
     * Decode the url and store the state into a JSON Object. JSON object should be
     * pass into Callback. If no callback is defined, navigation state is returned.<br/>
     * <code>callback:function(state){};</code><br/>
     * @param {String} url url string
     * @param {Function} callback callback function
     * @type Object
     * @return {Object} navigation state object
     */
	decode:function(url,callback){
	},
	/**
     * Encode state object and generate fragment. Fragment should be passed into callback function.<br/>
     * <code>callback(fragment);</code>
     * If no callback is defined, url fragment is returned.<br/>
     * @param {Object} state JSON object representing Mashup state
     * @param {Function} callback callback function which takes the following parameters:
     * &nbsp;&nbsp;<b><code>additionalParams</code> (JSON)</b> - if the <code>additionalParams<code> was passed in to the encode
     * function, then it must be passed back into the callback function <br>
     * &nbsp;&nbsp;<b><code>responseParams</code> (JSON)</b> - <i>Optional</i> If <code>additionalParams.allowRedirect</code> is true and this is an asynchronous commit,
     * then the implementation of this function may pass <code>responseParams.doRedirect</code> set to true to refresh the page after the commit is completed <br>
     * @param {Object} oldState JSON object representing Mashup state before it gets updated
     * @param {Object} additionalParams <i>Optional</i> JSON object to control various aspects of encoding or the registered callback
     * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navigationStateModel
     * @type String
     * @return {String} the url fragment that contains navigation state
     */
	encode:function(state,callback,oldState, additionalParams, navigationStateModel){
	},
	/**
     * @deprecated Use generateURL instead.
     *
     * @param {Object} state
     * @param {Function} callback
     * @param {JSON} params
     * @type String
     */
	generateUrl:function(state,callback,params){
	},
	/**
     * Encode state object and generate full url. URL should be absolute URL. URL should be passed into callback function.
     * If no callback, full url is returned.<br/>
     * <code>callback:function(url){};</code><br/>
     * Sample parameter: {nohash:"true"}<br/>
     * if "nohash" is set to true,the returned url will not contain state in hash.<br/>
     * By default Lotus Mashups only supports url that contains navigation state in hash.  <br/>
     * Extensions can be added to support additional parameter by using extension registry.<br/>
     *
     * @param {Object} state JSON object representing Mashup state
     * @param {Function} callback callback function
     * @param {JSON} params additional parameter in json format
     * @type String
     * @return {String} full url that contains navigation state
     */
	generateURL:function(state,callback,params){
	},
	/**
     * Preprocess could be used to filter the original state. For example,
     * pulling more state information that's cached in cookie.<br/>
     * The final state should be passed into callback.<br/>
     *   <code>callback:function(state){};</code><br/>
     * If no callback, state object will be returned.<br/>
     * @param {Object} state JSON object representing Mashup state
     * @param {Function} callback callback function
     * @type Object
     * @return {Object} object contains navigation state
     */
	preprocess:function(state,callback){
	},
	/**
     * Dispose the any navigation state that's persisted. Callback is executed when dispose action is done. <br/>
     * <code>callback:function(){};</code>
     * @param {Function} callback callback function
     * @type void
     */
	dispose:function(callback){
	},
	/**
     * Postprocess could be used to filter the original state before url is generated.
     * For example,some state information should be persisted into cookie.<br/>
     * The final state should be passed into callback.<br/>
     *   <code>callback:function(state){};</code><br/>
     * If no callback, state object will be returned.<br/>
     * @param {Object} state JSON object representing Mashup state
     * @param {Function} callback callback function
     * @param {Object} oldState JSON object representing Mashup state before it gets updated
     * @param {Object} additionalParams <i>Optional</i> JSON object to control various aspects of encoding or the registered callback.
     * @type Object
     * @return {Object} object contains navigation state
     */
	postprocess:function(state,callback,oldState, additionalParams){
	}
});


}

if(!dojo._hasResource["com.ibm.mm.enabler.model.state.CookieManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.state.CookieManager"] = true;
dojo.provide("com.ibm.mm.enabler.model.state.CookieManager");


dojo.declare("com.ibm.mm.enabler.model.state.CookieManager", null, {
    //cookie limit is 4096byte(at least for IE)
    //cookie is persisted per user, cookiename uid+"_state"
    //need to split if we run into problems
    /* {sid:{value:<sid>,params:{}},
     *  pid:{value:<pid>,params:{}},
     *  pageselection:{
     *	<spaceid>:{value:<pageid>,params:{lm:<timestamp>}},
     *	<spaceid>:{value:<pageid>,params:{lm:<timestamp>}}
     *	},
     *  wparams:{
     *  	<wid>:{value:{rp:{w:<"200">,h:<"300">,st:<"NORMAL">}},params:{lm:<timestamp>}},
     *  	<wid>:{value:{rp:{w:<"300">,h:<"400">,st:<"MAX">}},params:{lm:<timestamp>}}
     *  }
     * }
     */
    constructor: function() {
        this._dirty = false;
        this.cookiePath = window.location.pathname;
    },
    COOKIE_PREFIX: "digest.ignore.state.",
    disposeState: function() {
        if (ibmConfig["com.ibm.mashups.embedding.isActive"]===true) {
            // in case of embedding we are not allowed to write out a cookie
            return;
        }
        var id = this._getCookieID();
        if (id && dojo.cookie(id)) {
            if (dojo.isIE) {
                dojo.cookie(id, null, {
                    expires: -1
                });
            }
            else {
                dojo.cookie(id, null, {
                    expires: -1,
                    path: this.cookiePath
                });
            }
        }
        if (this._state) {
            delete this._state;
        }
        this._dirty = false;
    },
    _getCookieID: function() {
        //get user id
        if (!this._cookieID) {
            var configSvr = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
            var uid = configSvr.getValue(com.ibm.mashups.enabler.services.ConfigConstants.USER);
            if (!uid || (uid && uid == "null")) {
                return null;
            }
            //this._cookieID = uid+"_state";
            this._cookieID = this.COOKIE_PREFIX + uid;
        }
        return this._cookieID;
    },
    _init: function() {
        if (!this._getCookieID()) {
            this._state = {};
            return;
        }
        if (dojo.cookie.isSupported()) {
            if (dojo.cookie(this._getCookieID()) && dojo.fromJson(dojo.cookie(this._getCookieID()))) {
                this._state = dojo.fromJson(dojo.cookie(this._getCookieID()));
            }
        }
        if (!this._state) {
            this._state = {};
        }
    },
    getState: function(id) {
        //if id is not defined, return the whole state object
        if (!this._state) {
            this._init();
        }
        if (!id) {
            return this._state;
        }
        if (this._state[id]) {
            return this._state[id];
        }
        return null;
    },
    setState: function(id,/*object*/ value) {
        //pid,sid,pageselection,wparams
        if (!this._state) {
            this._state = {};
        }
        this._state[id] = value; //create/overwrite
        this._dirty = true;
    },
    removeState: function(id) {
        if (this._state[id]) {
            delete this._state[id];
            this._dirty = true;
        }
    },
    commit: function() {
        if (ibmConfig["com.ibm.mashups.embedding.isActive"]===true) {
            // in case of embedding we are not allowed to write out a cookie
            return;
        }
        //cookie expiration?
        if (this._dirty) {
            if (!this._getCookieID()) {
                this._dirty = false;
                return;
            }
            if (dojo.cookie.isSupported()) {
                if (dojo.isIE) {
                    dojo.cookie(this._getCookieID(), dojo.toJson(this._state), {
                        expires: 3652
                    });
                }
                else {
                    dojo.cookie(this._getCookieID(), dojo.toJson(this._state), {
                        expires: 3652,
                        path: this.cookiePath
                    });
                }
            }
            this._dirty = false;
        }
    }
});
com.ibm.mashups.enabler.model.state.CookieManager = new com.ibm.mm.enabler.model.state.CookieManager();

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.model.Factory_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.model.Factory_API"] = true;
dojo.provide("com.ibm.mashups.iwidget.model.Factory_API");
dojo.provide("com.ibm.mashups.iwidget.model.Factory");

/**
 * Interface represents  iWidgetModelFactory
 * @ibm-spi
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.model.Factory", null, {
    /**
     * @private
     */
    constructor: function() {

    },
    /**
     Returns  global widget model.
     @type com.ibm.mashups.iwidget.model.WidgetModel
     @returns{com.ibm.mashups.iwidget.model.WidgetModel }  Interface for WidgetModel.
     */
    getGlobalWidgetModel: function() {
    }

});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.Constants"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.Constants"] = true;
dojo.provide("com.ibm.mm.iwidget.Constants");

dojo.declare("com.ibm.mm.iwidget.Constants", null, {
    constructor: function() {
    },
    WIDGETEVENT_PREFIX: "widgetevents.",
    WILDCARD_PREFIX: "*.",
    mode: {
        VIEW:/*String*/ "view",//The generated markup fragment(s) should reflect normal interaction with the iWidget
        EDIT:/*String*/ "edit",//The generated markup fragment(s) should reflect iWidget interactions for editing iWidget attributes scoped to this instance of iwidget, but applicable to all users
        PERSONALIZE:/*String*/ "personalize",//The generated markup fragment(s) should reflect iWidget interactions for personalizing iwidget attributes scoped to this instance on the iWidget for this user
        CONFIG:/*String*/ "config",//The generated markup fragment(s) should reflect iWidget interactions for editing iwidget attributes scoped to all instances of the iWidget for all users
        HELP:/*String*/ "help"//The iWidget should generate markup fragment(s) to assist the user with interacting with the iWidget
    },
	mode_view: "view",
    mode_edit: "edit",
    mode_help: "help",
    event: {
        TITLE:/*String*/ "title",//Name for the Attribute holding event title
        DESCRIPTION:/*String*/ "description"//Name for the Attribute holding event description
    },
    ATTRIBUTES:/*String*/ "attributes", //Name for the ManagedItemSet holding the customization attributes.
    IDESCRIPTOR:/*String*/ "idescriptor", //Name for the ManagedItemSet holding the items describing the iWidget
    USERPROFILE:/*String*/ "userprofile", //Name for the ManagedItemSet holding data about the user
    windowstate: {
        NORMAL:/*String*/ "normal",
        MINIMIZE:/*String*/ "minimize",
        MAXIMIZE:/*String*/ "maximize"
    },
    status: {
        SUCCESS:/*int*/ 200,
        TIMEOUT:/*int*/ 408,
        NOTFOUND:/*int*/ 404,
        INTERROR:/*int*/ 500,
        OTHER:/*int*/ 303
    },
    changeType: {
        CHANGEDVALUE:/*String*/ "changedValue",
        NEWITEM:/*String*/ "newItem",
        REMOVEDITEM:/*String*/ "removedItem"
    },
    iDescriptorItems: {
        title: "title",
        name: "name",
        description: "description",
        defaultHeight: "defaultHeight",
        defaultWidth: "defaultWidth",
        displayLocale: "displayLocale",
        mode: "mode",
        author: "author",
        email: "email",
        website: "website",
        version: "version",
        icon: "icon",
        windowState: "windowState",
		messageLocale:"messageLocale",
		availableMessageLocales:"availableMessageLocales",
		thumbnail:"thumbnail"
    },
    IW_PREFIX: "iw-",
    IW_DEFINITION_TYPE: "iwidget",
    OSGADGET_DEFINITION_TYPE: "os-gadget",
    CSSCLASS_INSTANCE: {
        iwWidget: "iWidget",
		iwOSGadget: "OSGadget",
		iwSandbox:"Sandbox",
        iwDefinition: "Definition",
		iwEventDescription:"EventDescription",
		iwPayloadType:"PayloadType",
        iwHandled: "Handled",
		iwPublished: "Published",
        iwDescription: "Description",
		iwTitle:"Title",
		iwEvent:"Event",
		iwDescRef:"DescRef",
		iwGlobalid:"Globalid",
		iwHandler: "Handler",
		iwNewWire: "NewWire",
		iwRemoveWire: "RemoveWire",
        iwReadOnly: "ReadOnly",
        iwItemSet: "ItemSet",
        iwItem: "Item",
        iwValue: "Value",
        iwContent: "Content",
        iwReceivedEvent: "ReceivedEvent",
        iwSourceEvent: "SourceEvent",
        iwTargetEvent: "TargetEvent",
        iwMappedName: "MappedName",
        iwStandalone: "Standalone"
    },

    CSSCLASS_PREFIXED_INSTANCE: { /* filled at runtime */},

    CSSCLASS_PERSONALIZED: "mm-Personalized",

    RESOURCE: {
        src: "src",
        id: "id",
        globalid: "globalid",
        mimeType: "mimeType",
        callback: "callback",
        version: "version",
		blockInit:"blockInit",
		skipLoad:"skipLoad"
    },
    EVENTS: {
        onLoad:/*String*/ "onLoad",
        onUnLoad:/*String*/ "onUnload",
        onModeChanged:/*String*/ "onModeChanged",
        onItemSetChanged:/*String*/ "onItemSetChanged",
        unloadWidget:/*String*/ "/enabler/unloadWidget",
        unSubscribeWire:/*String*/ "/enabler/unSubscribeWire",
        modeChanged:/*String*/ "modeChanged",
        onSizeChanged:/*String*/ "onSizeChanged",
        onNavStateChanged:/*String*/ "onNavStateChanged",
        onAttributeSaved:/*String*/ "com.ibm.mashups.iwidget.onAttributeSaved",
        onWindowStateChanged:/*String*/ "onWindowStateChanged",
		onIncompleteEventDescription:/*String*/"onIncompleteEventDescription"
    },
	eventservice:{
		type:{
			MAIN:"MAIN",
			IFRAME:"IFRAME"
		}
	}

});
com.ibm.mm.iwidget.Constants = new com.ibm.mm.iwidget.Constants();

(function() {
    for(var key in com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE) {
        if(Object.prototype.hasOwnProperty.call(com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE,key)) {
            com.ibm.mm.iwidget.Constants.CSSCLASS_PREFIXED_INSTANCE[key] = com.ibm.mm.iwidget.Constants.IW_PREFIX + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE[key];
        }
    }
})();


// TODO: move to legacy layer
iwConstants = com.ibm.mm.iwidget.Constants;

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.WireProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.widget.WireProvider"] = true;
dojo.provide("com.ibm.mashups.iwidget.widget.WireProvider");

/**
 * Interface defines functions to access handled or published event descriptions.
 * @ibm-spi
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.widget.WireProvider", null, {
    /**
     * @private
     */
    constructor: function(id) {

    },
    /**
     This method returns an array of supported wires.
     @type com.ibm.mashups.iwidget.widget.Wire[]
     @returns{com.ibm.mashups.iwidget.widget.Wire[] }  array of Wire this iWidget is wired as  target .
     */
    getWires: function() {
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.IEventDescription_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.IEventDescription_API"] = true;
dojo.provide("com.ibm.mashups.iwidget.IEventDescription_API");
dojo.provide("com.ibm.mashups.iwidget.IEventDescription");

/**
 * It contains various pieces of information describing an event.
 *
 * @ibm-api
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.IEventDescription", null, {


    constructor: function() {
        /**
         * @private
         */
    },
	/**
     The alias of the event.
     @type String
     */
    alias:/*String*/ "",
    /**
     The name of the event.
     @type String
     */
    name:/*String*/ "",
    /**
     The type of any payload. If this is set to null, no information is being provided.
     @type String
     */
    type:/*String*/ "",
    /**
     This provides the name of a callback function with the following signature and no return value.
     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>   function(ievent) </code>
     @type String
     */
    handlingFn:/*String*/ "",
    /**
     it returns a user-oriented description (markup allowed) of the event in the requested locale. If no locale is supplied, the default locale of the iWidget is used (with "en" being the default iWidget locale). The description is likely to be displayed when a user is wiring event flow between iWidgets.
     @param{String} locale  required locale. Can be NULL. If no locale is supplied, the default locale of the iWidget is used (with "en" being the default iWidget locale).
     @type String
     @returns{String}  Return the description of a given locale,if no locale is provided, then the default locale of the iWidget is used.
     @deprecated please use getAttribute("description",locale) instead
     @since Deprecated since Version 2.0
     */
    getDescription: function(/*String*/locale) {
        return null;
    },
    /**
     This provides the default language of all the localized attributes within this event description.
     @type String
     */
    lang:/*String*/ "",
    /**
     This indicates if an event is a handled event or not. Default value is false.
     @type Boolean
     */
    isHandled: false,
    /**
     This indicates if an event is a published event or not. Default value is false.
     @type Boolean
     */
    isPublished: false,
    /**
     This method returns the asking value of an attribute of the event description. Each event description should have title and description . Normally title and description should be globalized, default locale should be specified by using the iso language code, if missing, the value for the default locale will be en. <br/>
     @param{String} attributeName  name of attribute. Can  Not be NULL.
     @param{String} locale  required locale. Can be NULL. If no locale is supplied, the default locale of the iWidget is used (with "en" being the default iWidget locale).
     @type String
     @returns{String}  Return the value of the required attribute,if locale is provided, it returns locale specific value.
     */
    getAttribute: function(/*String*/attributeName,/*String*/ locale) {
        return null;
    },
    /**
     The method set the value for a given event description attribute.It returns a handle of this eventdescription, return null upon failure. If the locale parameter is absent, then the given attribute won't be locale specific.
     @param{String} attributeName  name of attribute. Can  Not be NULL.
     @param{String} attributeValue  value of attribute. Can  Not be NULL.
     @param{String} locale  optional, locale. Can be NULL.
     @type com.ibm.mashups.iwidget.IEventDescription
     @returns{com.ibm.mashups.iwidget.IEventDescription}  return a handle of this eventdescription, return null upon failure..
     */
    setAttribute: function(/*String*/attributeName, /* String*/ attributeValue, /*String*/ locale) {
    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.IEventDescriptionImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.IEventDescriptionImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.IEventDescriptionImpl");





dojo.declare("com.ibm.mm.iwidget.IEventDescriptionImpl", com.ibm.mashups.iwidget.IEventDescription, {

    constructor: function(/*String*/name,/*function*/ handlingFn,/*String*/ type,/*String*/ description,/*String[]*/ aliases, defaultLang,/*[]*/ descriptions) {
        if (dojo.isString(name)) {
            /*backward compatibility, some widget are still trying to create iEventDescription by using this constuctor as is!*/
            var obj = {};
            obj.name = name;
            handlingFn = handlingFn || null;
            if (handlingFn) {
                obj.handlingFn = handlingFn;
                obj.isHandled = true;
                obj.isPublished = false; //backward compatibility either isPublished or isHandled
            }
            else {
                obj.isPublished = true;
            }
            type = type || null;
            if (type) {
                obj.type = type;
            }
            defaultLang = defaultLang || null;
            if (defaultLang) {
                obj.lang = defaultLang;
            }
            else {
                obj.lang = "en";
            }
            //how to set isPublished? or set it later
            obj.attributes = {};
            obj.localizedAttributes = {};
            aliases = aliases || null;
            if (aliases) {
                obj.attributes.aliases = aliases;
            }
            descriptions = descriptions || null;
            if (descriptions) {
                obj.localizedAttributes = descriptions;
            }
            //backward compatibility
            if (description) {
                if (!obj.localizedAttributes[obj.lang]) {
                    obj.localizedAttributes[obj.lang] = {};
                }
                obj.localizedAttributes[obj.lang].description = description;
            }

            this._internalJsonObj = obj;
        }
        else {
            this._internalJsonObj = name;
        }
        this.initPredefinedFields(this._internalJsonObj);
    },
    initPredefinedFields: function(obj) {
        //initialize  fields
        this.name = obj.name;
        this.type = obj.type;
        this.lang = obj.lang;
        this.handlingFn = obj.handlingFn;

        this.isHandled = obj.isHandled;
        this.isPublished = obj.isPublished;

//        if (this.handlingFn) {
//            this.isHandled = true;
//        }
//        else {
//            this.isHandled = false;
//        }
//        // set isPublished to true only when both isHandled and isPublished is not defined
//        // this is required for backward compatiblity reason
//        if ((obj.isPublished && obj.isPublished == "true") || obj.isPublished) {
//            this.isPublished = true;
//        }
    },
    getDescription: function(locale) {
        return this._getLocalizedAttribute("description", locale);
    },
    getTitle: function(locale) {
        return this._getLocalizedAttribute("title", locale);
    },
    _getLocalizedAttribute: function(attributeName, locale) {
        var attValue = null, altAttValue = null;
        var lc = com.ibm.mashups.enabler.context.Factory.getLocalizedContext(locale, this.lang);
        var finalLocale = lc.getLocale(this);
        if (this.localemapping && this.localemapping[finalLocale]) {
            finalLocale = this.localemapping[finalLocale];
        }
        if (this._internalJsonObj.localizedAttributes) {
            altAttValue = this._internalJsonObj.localizedAttributes[finalLocale];
            if (altAttValue) {
                attValue = altAttValue[attributeName];
            }
        }
        if (!attValue) {
            attValue = this[attributeName];
        }

        if (typeof attValue == "undefined") {
            attValue = null;
        }
        return attValue;
    },
    setOnRemoveWire: function(/*String*/handler) {
        if (typeof handler == "undefined" || handler === null) {
            handler = "onRemoveWire";
        }
        //this.onRemoveWire = handler;
        if (typeof this._internalJsonObj.attributes == "undefined") {
            this._internalJsonObj.attributes = {};
        }
        this._internalJsonObj.attributes.onRemoveWire = handler;
        return this;
    },
    getOnRemoveWire: function() {
        //can remove?
        if (typeof this._internalJsonObj.attributes != "undefined" && this._internalJsonObj.attributes.onRemoveWire) {
            return this._internalJsonObj.attributes.onRemoveWire;
        }
        return null;
    },
    setOnNewWire: function(/*String*/handler) {
        if (typeof handler == "undefined" || handler === null) {
            handler = "onNewWire";
        }
        //this.onNewWire = handler;
        if (typeof this._internalJsonObj.attributes == "undefined") {
            this._internalJsonObj.attributes = {};
        }
        this._internalJsonObj.attributes.onNewWire = handler;
        return this;
    },
    getOnNewWire: function() {
        if (typeof this._internalJsonObj.attributes != "undefined" && this._internalJsonObj.attributes.onNewWire) {
            return this._internalJsonObj.attributes.onNewWire;
        }
        return null;
    },
    getLocales: function() {
        var locales = [];
        var mapping = {};
        if (this._internalJsonObj.localizedAttributes) {
            for (var i in this._internalJsonObj.localizedAttributes) {
                if (Object.prototype.hasOwnProperty.call(this._internalJsonObj.localizedAttributes,i)) {
                    locales.push(i);
                    var normalizedLocale = com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(i);
                    if (normalizedLocale != i) {
                        mapping[normalizedLocale] = i;
                    }
                }
            }
        }
        this.localemapping = mapping;

        return locales;
    },
    toString: function() {
        //return null or unserialized string, dojo will throw exception if it's not a valid Json obj
        var temp = this.toJson();
        return dojo.toJson(temp);
    },
    _getInternalJsonObj: function() {
        return this._internalJsonObj;
    },
    toJson: function() {
        var internalJson = {};
        for (var i in this._internalJsonObj) {
            if (Object.prototype.hasOwnProperty.call(this._internalJsonObj,i)) {
                if (i == "handlingFn") { //it could be functionpointer
                    if (dojo.isFunction(this._internalJsonObj[i])) {
                        internalJson[i] = "HANDLEFN";
                        continue;
                    }
                }
                internalJson[i] = dojo.clone(this._internalJsonObj[i]);
            }
        }

        return internalJson;
    },
    clone: function() {
        var temp = dojo.toJson(this._internalJsonObj);
        if (temp) {
            return new com.ibm.mm.iwidget.IEventDescriptionImpl(dojo.fromJson(temp));
        }
        else {
            return null;
        }
    },
    getAttribute: function(attName, locale) {
        if (!attName) {
            return null;
        }
        if (!locale) {
            if (this._internalJsonObj.attributes && typeof this._internalJsonObj.attributes[attName] != "undefined") {
                return this._internalJsonObj.attributes[attName];
            }
            //get value for default locale
            if (this._internalJsonObj.localizedAttributes && this._internalJsonObj.localizedAttributes[this.lang]) {
                var attValue = this._internalJsonObj.localizedAttributes[this.lang][attName];
                if (attValue) {
                    return attValue;
                }
            }
            return null; //if no such attributes or localized attributes
        }
        else {
            return this._getLocalizedAttribute(attName, locale);
        }
    },
    setAttribute: function(attName, attValue, locale) {
        //todo; if no locale defined and attributes is predefined such as "title","description", set the value on default locale
        //return a handle of this eventdescription, return null upon failure.
        if (!attName) {
            return null;
        }
        if (typeof attValue == "undefined") {
            return null; // allow value to be null
        }
        if (!locale) {
            if (typeof this._internalJsonObj.attributes == "undefined") {
                this._internalJsonObj.attributes = {};
            }
            this._internalJsonObj.attributes[attName] = attValue;
            if (attValue === null) {
                delete this._internalJsonObj.attributes[attName];
            }
            return this;
        }
        if (!this._internalJsonObj.localizedAttributes[locale]) {
            this._internalJsonObj.localizedAttributes[locale] = {};
        }
        this._internalJsonObj.localizedAttributes[locale][attName] = attValue;
        if (attValue === null) {
            delete this._internalJsonObj.localizedAttributes[locale][attName];
        }
        return this;
    },
    copyRuntimeProperties: function(eventDesc2Copy) {
        if ((!this.handlingFn) && (eventDesc2Copy.handlingFn)) {
            this.handlingFn = eventDesc2Copy.handlingFn;
        }
        if ((!this._internalJsonObj.handlingFn) && (eventDesc2Copy._internalJsonObj.handlingFn)) {
            this._internalJsonObj.handlingFn = eventDesc2Copy._internalJsonObj.handlingFn;
        }
        if (typeof this._internalJsonObj.attributes == "undefined") {
            this._internalJsonObj.attributes = {};
        }
        for (name in eventDesc2Copy._internalJsonObj.attributes) {
            if (!this._internalJsonObj.attributes[name]) {
                this._internalJsonObj.attributes[name] = eventDesc2Copy._internalJsonObj.attributes[name];
            }
        }
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.IEventDescription"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.IEventDescription"] = true;
dojo.provide("com.ibm.mashups.iwidget.IEventDescription");




}

if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.EventProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.widget.EventProvider"] = true;
dojo.provide("com.ibm.mashups.iwidget.widget.EventProvider");



/**
 * Interface defines functions to access handled or published event descriptions.
 * @ibm-spi
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.widget.EventProvider", null, {
    /**
     * @private
     */
    constructor: function() {

    },
    /**
     This method returns an array of event description. Only published event of this widget will be returned.
     @type {com.ibm.mashups.iwidget.IEventDescription}
     @returns{com.ibm.mashups.iwidget.IEventDescription[] }  array of event description
     */
    getWidgetPublishedEvents: function() {
    },

    /**
     This method returns an array of event description. Only handled event of this widget will be returned.
     @type {com.ibm.mashups.iwidget.IEventDescription[]}
     @returns{com.ibm.mashups.iwidget.IEventDescription[] }  array of event description
     */
    getWidgetHandledEvents: function() {
    },
    /**
     This method returns the required event.
     @param {String}name name of required public event
     @type {com.ibm.mashups.iwidget.IEventDescription}
     @returns{com.ibm.mashups.iwidget.IEventDescription }  an event description it returns NULL if event can't be found.
     */
    getPublicEvent: function(name) {
    }

});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.Properties_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.widget.Properties_API"] = true;
dojo.provide("com.ibm.mashups.iwidget.widget.Properties_API");
dojo.provide("com.ibm.mashups.iwidget.widget.Properties");

/**
 * Interface defines functions to iterates , updates and persist Properties.
 * @ibm-spi
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.widget.Properties", null, {
    /**
     * @private
     */
    constructor: function() {
    },
    /**
     * This method returns the value of the required item
     * @param{String} itemName name of the item.Must never be NULL.
     * @param{String} locale the locale of the value to fetch. if locale isn't defined, the
     *                <code>DEFAULT_LOCALE</code> will be used
     * @return{String}  return the  value of required item
     */
    getItemValue: function(/*String*/itemName, locale) {

    },
    /**
     * This method returns an array of Strings,providing the name of each item.
     * @return{String[]}  return an array of items names and return NULL if the set contains no item
     */
    getAllNames: function() {
        return null;
    },

    /**
     * This methods returns the locales for the item specified by <code>itemName</code>
     * @param{String} itemName the name of the item for which do get the locales.
     * @return{String[]} return an array of locales valid for the specified itemName, returns an empty array if no localized item values are available.
     */
    getItemLocales: function(itemName) {
    },
    /**
     * This method allows the caller to check whether a specific item is readOnly or not.
     * @param{String} itemName the item name of the item to check readOnly
     * @return{Boolean} <code>true</code> if the item exists and is read only, <code>false</code> otherwise.
     */
    isReadOnly: function(itemName) {
    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.widget.PropertiesImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.widget.PropertiesImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.widget.PropertiesImpl");





dojo.declare("com.ibm.mm.iwidget.widget.PropertiesImpl", com.ibm.mashups.iwidget.widget.Properties, {
    DELETE_TOKEN: "com.ibm.mm.iwidget.widget.DELETE_TOKEN",
    TYPE_NEW: "newItem",
    TYPE_UPDATE: "updatedValue",
    TYPE_REMOVE: "removedItem",
    /**
     * @param items {ItemSet JSON} the items this Properties class is based on
     * @param defaultProps {Properties} The default properties object
     **/
    constructor: function(items, defaultProps) {
        this._defaultProperties = defaultProps;

        // create the new object
        this._items = {};

        if (items) {
            this._items = items;
        }

        this._localizedItems = {};
        // define the default locale of this properties set
        this.DEFAULT_LOCALE = ibmConfig[com.ibm.mashups.enabler.services.ConfigConstants.DEFAULT_LOCALE];
        if (!this.DEFAULT_LOCALE) {
            this.DEFAULT_LOCALE = "en";
        }
    },
    /**
     * Internal method which can be used by ENABLER components for determining the default locale of an Properties Element
     */
    _getItemDefaultLocale: function(itemName) {
        var defLocale = null;

        if (this._items[itemName]) {
            if (this._items[itemName].defaultLocale) {
                defLocale = this._items[itemName].defaultLocale;
            }
        }
        if (!defLocale) {
            defLocale = null;
        }
        return defLocale;
    },
	getLocalizedItemValue:function(itemName,locale){
		//internal function, used by private ItemSet
		//no fallback to default locale
		if (!itemName || !locale) {
			return;
		}
		if (!(itemName in this._items) && !this._defaultProperties) {
            return null;
        }
		var item = this._items[itemName];
        var value = null;

        if (!item.values) {
            return null;
        }

        var matchLocales = [];
        for (var i in item.values) {
            if (Object.prototype.hasOwnProperty.call(item.values,i)) {
                matchLocales.push(i);
            }
        }

        var normalizedLocale;

        // check if we have a value for the specified locale
        normalizedLocale = com.ibm.mm.enabler.utils.LocaleHelper.matchLocale(locale, matchLocales);
		for (var i in item.values) {
			if (normalizedLocale == com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(i)) {
				value = item.values[i];
				break;
			}
		}
        if (value == this.DELETE_TOKEN) {
            return null;
        }
		return value;
	},
    getItemValue: function(itemName, locale) {
        // if we don't have an item and don't have default properties, we can exit right away
        if (!(itemName in this._items) && !this._defaultProperties) {
            return null;
        }

        // if we don't have the item we can delegate to default props (which we checked earlier)
        if (!(itemName in this._items)) {
            return this._defaultProperties.getItemValue(itemName, locale);
        }

        // seems we have an item, so let's do the magic
        var item = this._items[itemName];
        var value = null;

        if ((typeof locale == "undefined" || locale === null) && typeof item.value != "undefined" && item.value !== null) {
            if (item.value == this.DELETE_TOKEN) {
                return null;
            }
            return item.value;
        }
        if (!item.values) {
            return null;
        }

        var matchLocales = [];
        for (var i in item.values) {
            if (Object.prototype.hasOwnProperty.call(item.values,i)) {
                matchLocales.push(i);
            }
        }

        var normalizedLocale;

        // check if we have a value for the specified locale
        if (locale) {
            normalizedLocale = com.ibm.mm.enabler.utils.LocaleHelper.matchLocale(locale, matchLocales);
			for (var i in item.values) {
				if (normalizedLocale == com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(i)) {
					value = item.values[i];
					break;
				}
			}
        }

        // test the default locale of the item
        if (item.defaultLocale && value === null) {
            normalizedLocale = com.ibm.mm.enabler.utils.LocaleHelper.matchLocale(item.defaultLocale, matchLocales);
			for (var i in item.values) {
				if (normalizedLocale == com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(i)) {
					value = item.values[i];
					break;
				}
			}
        }

        // test the default of the sytem
        if (this.DEFAULT_LOCALE && value === null) {
            normalizedLocale = com.ibm.mm.enabler.utils.LocaleHelper.matchLocale(this.DEFAULT_LOCALE, matchLocales);
			for (var i in item.values) {
				if (normalizedLocale == com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(i)) {
					value = item.values[i];
					break;
				}
			}
        }

        // otherwise the first locale wins
        if (value === null) {
            for (var lang in item.values) {
                if (Object.prototype.hasOwnProperty.call(item.values,lang)) {
                    value = item.values[lang];
                    break;
                }
            }
        }

        if (value == this.DELETE_TOKEN) {
            return null;
        }

        return value;
    },
    getItemLocales: function(itemName) {
        var locales = [];

        if (itemName in this._items && this._items[itemName].values) {
            for (var locale in this._items[itemName].values) {
                if (Object.prototype.hasOwnProperty.call(this._items[itemName].values,locale)) {
                    locales.push(locale);
                }
            }
        }
        /*if (itemName in this._items && this._items[itemName].value) {
            locales.push("");
        }*/
        if (locales.length === 0) {
            return null;
        }
        return locales;
    },
    getAllNames: function() {
		//return empty array if there's no item
        var defaultNames = [];
        if (this._defaultProperties) {
            defaultNames = this._defaultProperties.getAllNames();
        }

        var mergedItems = {};

        for (var i = 0; i < defaultNames.length; i++) {
            mergedItems[defaultNames[i]] = null;
        }

        for (var itemName in this._items) {
            if (this._items[itemName] && this._items[itemName]._change && this._items[itemName]._change.changeType == this.TYPE_REMOVE) {
                if (itemName in mergedItems) {
                    delete mergedItems[itemName];
                }
            }
            else {
                mergedItems[itemName] = null;
            }
        }

        var names = [];

        for (var itemName2 in mergedItems) {
            if (Object.prototype.hasOwnProperty.call(mergedItems,itemName2)) {
                names.push(itemName2);
            }
        }

        return names;
    },
    isReadOnly: function(itemName) {
        var item = this._items[itemName];
        return (this._defaultProperties && this_defaultProperties.isReadOnly(itemName)) ||
            (item && item.readOnly);
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.Properties"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.widget.Properties"] = true;
dojo.provide("com.ibm.mashups.iwidget.widget.Properties");




}

if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.PropertiesProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.widget.PropertiesProvider"] = true;
dojo.provide("com.ibm.mashups.iwidget.widget.PropertiesProvider");


/**
 * Read-Only interface defines functions to access properties that's defined with iWidget.
 * @ibm-spi
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.widget.PropertiesProvider", null, {
    /**
     * @private
     */
    constructor: function() {
    },
    /**
     This method returns an object that contains iDescriptor items as defined by iWidget spec. It contains  default title and icon
     @type com.ibm.mashups.iwidget.widget.Properties
     @returns{com.ibm.mashups.iwidget.widget.Properties } object that contains iWidget  iDescriptor items information
     */
    getIDescriptorItems: function() {
    },
    /**
     This method returns an object that contains attributes as defined by iWidget spec.
     @type com.ibm.mashups.iwidget.widget.Properties
     @returns{com.ibm.mashups.iwidget.widget.Properties } object that contains iWidget  iDescriptor items information
     */
    getAttributes: function() {
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetDefinition_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetDefinition_API"] = true;
dojo.provide("com.ibm.mashups.iwidget.widget.IWidgetDefinition_API");
dojo.provide("com.ibm.mashups.iwidget.widget.IWidgetDefinition");

/**
 * Interface defines functions to access all the data object in widget definition. PropertiesProvider is not implemented.
 * @ibm-spi
 * @ibm-module iWidget2
  */
dojo.declare("com.ibm.mashups.iwidget.widget.IWidgetDefinition",[com.ibm.mashups.iwidget.widget.EventProvider,com.ibm.mashups.iwidget.widget.PropertiesProvider],{
  	/**
            * @private
            */
    constructor:function(){

	},
/**
This method returns an array of supported modes such as "view" and "edit".
@returns{String[] }  array of supported modes this iWidget supports.
*/
    getSupportedModes:function(){
    },

/**
This method returns a  JSON based spec compliant object that represents all the data that's defined in widget xml.<p/>
Rule to follow:<br/>
1. Element -- "iw:iwidget" is considered to be root Element and a root object is created from here.<p/>
2. Any  attribute of this element will be a field in the root object. '_' will be added as prefix to field names.<br/>
   ":" within any namespaced attribute will be replaced with "_".
<code>&lt;iw:iwidget id="map" xml:base="/root/test/" allowInstanceContent="false"......&gt;</code><br/>
{ _id:"map",_xml_base:"/root/test/",_allowInstanceContent:"false"......}<p/>
3. All repreatable elements, element name (append with "s") is used as a field name and an object is created to contain all the repeatable elements.
Within that object, value of "id" attribute is used as field name for an individual element if id attribute is available.<br/>
{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resources:{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"myId":{_id:"myId",_src:"my.js"},<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;		"myOtherId":{_id:"myOtherId",_src:"my2.js"}<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;		}<br/>
}<p/>
4. For "iw:content" elements, "contents" is used as the key in the parent object and an object is created to contain all the content elements.<br/>
For each "content" element, "mode" attribute is used  as the key and CDATA section is saved as the value.<br/>
{<br/>
&nbsp;&nbsp;&nbsp;contents:{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "view": {<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "_mode": "view",<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "value": "mycontent"<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/>
&nbsp;&nbsp;&nbsp; }<br/>
}<p/>
5. For "iw:alt" elements,"alts" is used as the key in parent object and an object is created to contain all the alt elements.<br/>
For each "alt" element, "lang" attribute is used  as the key and  all the attributes are saved per attributes convention.<br/>
eventDescname:{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_id:"eventDescnname",<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_payloadType:"payloadType",<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alts:{<br/>
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"en":{_lang:'en',_description:"description",_descriptionURI:"descriptionURI"},<br/>
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"zh":{_lang:'zh',_description:"description",_descriptionURI:"descriptionURI"}<br/>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>
}<p/>
An example of simple iWidget and  the return result.<br/>
<code>&lt;iw:iwidget id="stock" xmlns:iw="http://www.ibm.com/xmlns/prod/iWidget" iScope="stock" allowInstanceContent="true" supportedModes="view edit " mode="view" lang="en"></code><br/>
&nbsp;&nbsp;&nbsp;<code> &lt;iw:itemSet id="attributes" private="true" onItemSetChanged="changeItemSet"&gt;</code><br/>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> &lt;iw:item id="broker"  readOnly="false"    value="Etrade" /&gt;</code><br/>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> &lt;iw:item id="company"  value="IBM" /&gt;</code><br/>
 &nbsp;&nbsp;&nbsp;<code>&lt;/iw:itemSet&gt;</code><br/>
 &nbsp;&nbsp;&nbsp;<code> &lt;iw:event id="sendStockData" eventDescName="sendStockDataDesc"  published="true" onNewWire="sendData" /&gt; </code><br/>
 &nbsp;&nbsp;&nbsp;<code> &lt;iw:eventDescription  id="sendStockDataDesc"  payloadType="stockData" title="Send stock data"  lang="en"  &gt;</code><br/>
   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>&lt;iw:alt title="Send stock data"  lang="en" /&gt; </code><br/>
  &nbsp;&nbsp;&nbsp;<code>&lt;/iw:eventDescription&gt;</code><br/>
 &nbsp;&nbsp;&nbsp;<code>&lt;iw:resource src="stock.js" id="stock" /&gt;</code><br/>
  &nbsp;&nbsp;&nbsp;<code>&lt;iw:content mode="view"&gt;
        &lt;![CDATA[
          mycontent
            ]]&gt;
     &lt;/iw:content&gt;</code><br/>
  &nbsp;&nbsp;&nbsp;<code>&lt;/iw:iwidget&gt;</code><p/>

  Example of returnin json object. <br/>
  <code>
  {  _id:"map",_allowInstanceContent:"true",_iScope:"stock",_supportedModes:"view edit",_mode:"view",_lang:"en",<br/>
      &nbsp;&nbsp;&nbsp; itemSets:{<br/>
	       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"attributes":{  _id:"attributes", _private:"true",_onItemSetChanged:"changedItemSet",<br/>
	        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                  items:{ <br/>
		&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  			"broker":{  _id:"broker",_readOnly:"false", _value:"Etrade"},<br/>
		&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  			"company":{ _id:"company",_value;"IBM"} <br/>
		&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;		     }<br/>
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;	            }<br/>
     &nbsp;&nbsp;&nbsp;},<br/>
           &nbsp;&nbsp;&nbsp;events:{ <br/>
	        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"sendStockData":{  _id:"sendStockData", _eventDescName:"sendStockDataDesc", _published:"true",_onNewWire:"sendData"}<br/>
	 &nbsp;&nbsp;&nbsp;},<br/>
           &nbsp;&nbsp;&nbsp;eventDescriptions:{<br/>
	        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"sendStockDataDesc":{ _id:"sendStockDataDesc", _payloadType:"stockData",_title:"Send stock data",_lang:"en",<br/>
		&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  	                    alts:{<br/>
		&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;  			        "en":{ _lang:"en",_title:"Send stock data"}	<br/>
		&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  			      }	<br/>
		&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;			}<br/>
	&nbsp;&nbsp;&nbsp;		    },<br/>
         &nbsp;&nbsp;&nbsp; resources:{<br/>
		       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"stock":{ _id:"stock", _src:"stock.js"}<br/>
	&nbsp;&nbsp;&nbsp;},<br/>
           &nbsp;&nbsp;&nbsp;contents:{<br/>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "view": {<br/>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "_mode": "view",<br/>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "value": "mycontent"<br/>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/>
    &nbsp;&nbsp;&nbsp; }<br/>
  }<br/>
  </code>

@returns{object} a JSON based, spec compliant object that represents all the data that's defined in widget.xml
*/
    toSpecObject:function(){
    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetDefinitionDefaultImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetDefinitionDefaultImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.widget.IWidgetDefinitionDefaultImpl");





//no support on EventProvider,
//todo toSpecObject should just return the json object
dojo.declare("com.ibm.mm.iwidget.widget.IWidgetDefinitionDefaultImpl", com.ibm.mashups.iwidget.widget.IWidgetDefinition, {
    namespaces: {
        "iw": "http://www.ibm.com/xmlns/prod/iWidget"
    },
    reservedAttributes: {
        iScope: "iScope",
        supportedModes: "supportedModes",
        id: "id",
        allowInstanceContent: "allowInstanceContent",
        lang: "language",
		"xml_lang":"_xml_lang",
        "xmlns_iw": "_xmlns_iw",
        supportedWindowStates: "supportedWindowStates",
        "xml_base": "_xml_base",
		sandbox:"sandbox"
    },

    constructor: function(/*/object*/widgetDef, xmlStr, specObject) {
        this.widgetDef = widgetDef; //xmlStr is now widgetDef.xmlStr, xmlData is rarely used so only load when it's called in toSpec function.
        if (xmlStr) {
            this.xmlStr = xmlStr;
        }
        if (specObject) {
            this.specObject = specObject;
            this._specObjectToWidgetDef();
        }
    },
    getXmlBase: function() {
        if (this.widgetDef.xmlBase) {
            return this.widgetDef.xmlBase;
        }
        return null;
    },
    getAllowInstanceContent: function() {
        return this.widgetDef.allowInstanceContent;
    },
    getResources: function() {
        if (!this.resources) {
            this.resources = [];
        }
        return this.resources;
    },
    getIScope: function() {
        return this.widgetDef.iScope;
    },
    getWidgetEvents: function() {
        return this.widgetDef.widgetEvents;
    },
    getMarkupByMode: function(mode) {
        if (this.widgetDef.markup) {
            if (!mode) {
                mode = "view";
            }
            var temp = this.widgetDef.markup[mode];
            return temp;
        }
        else {
            return null;
        }
    },
    setMarkupByMode: function(mode, elem) {
        if (this.widgetDef.markup) {
            if (!mode) {
                mode = "view";
            }
            this.widgetDef.markup[mode] = elem; //simple replacement
            return this;
        }
        return null;
    },
    _getManagedItemSetListener: function(itemsetname) {
        if (!itemsetname) {
            return null;
        }
        if (itemsetname != iwConstants.ATTRIBUTES && itemsetname != iwConstants.IDESCRIPTOR) {
            return null;
        }
		if (this.widgetDef.itemSetsArr) {
			var defAttrItemSet = this.widgetDef.itemSetsArr[itemsetname];
			if (defAttrItemSet && defAttrItemSet.onItemSetChanged) {
				return defAttrItemSet.onItemSetChanged;
			}
		}
        return null;
    },
    _getManagedItemSetItems: function(itemsetname, simpleAttributes) {
        var properties = {};
		if (this.widgetDef.itemSetsArr) {
			var defAttrItemSet = this.widgetDef.itemSetsArr[itemsetname];
			if (defAttrItemSet) {
				for (var itemName in defAttrItemSet.items) {
					if (Object.prototype.hasOwnProperty.call(defAttrItemSet.items, itemName)) {
						properties[itemName] = defAttrItemSet.items[itemName]; // the new internal json itemset notation is compatible with the SPI
					}
				}
			}
		}
        // determine the default locale for fallback
        /*var lang = ibmConfig[com.ibm.mashups.enabler.services.ConfigConstants.DEFAULT_LOCALE];
         if (!lang)
         lang = "en";*/
        simpleAttributes = simpleAttributes || null;
        if (simpleAttributes) {
            for (var attName in simpleAttributes) {
                if (Object.prototype.hasOwnProperty.call(simpleAttributes,attName)) {
                    var value = simpleAttributes[attName];
                    if (typeof value != "undefined" && value !== null) {
                        var property = {};
                        //property.defaultLocale = lang;
                        property.readOnly = false;
                        //property.values = {};
                        //property.values[lang] = value;
                        property.value = value;
                        property.id = attName;
                        properties[attName] = property;
                    }
                }
            }
        }
        return new com.ibm.mm.iwidget.widget.PropertiesImpl(properties);
    },
    /**
     * PropertiesProvider Impl
     */
    getAttributes: function() {
        if (!this.attributeProperties) {
            this.attributeProperties = this._getManagedItemSetItems(iwConstants.ATTRIBUTES, this.widgetDef.simpleAttributes);
        }
        return this.attributeProperties;
    },
    /**
     * PropertiesProvider Impl
     */
    getIDescriptorItems: function() {
        if (!this.idescriptorProperties) {
            this.idescriptorProperties = this._getManagedItemSetItems(iwConstants.IDESCRIPTOR, this.widgetDef.iDescriptor);
        }
        return this.idescriptorProperties;
    },
    getAllItemSetNames: function() {
        var names = [];
        if (!this.widgetDef.itemSetsArr) {
            return names;
        }

        for (var itemName in this.widgetDef.itemSetsArr) {
            if (Object.prototype.hasOwnProperty.call(this.widgetDef.itemSetsArr,itemName)) {
                var itemSetWrapper = this.widgetDef.itemSetsArr[itemName];
                if (typeof(itemSetWrapper) != "undefined" && itemName != iwConstants.ATTRIBUTES && itemName != iwConstants.IDESCRIPTOR) {
                    names.push(itemSetWrapper.id);
                }
            }
        }
        return names;
    },
    getItemSet: function(/*String*/name) {
        if (name == "attributes") {
            return this.getAttributes();
        }
        var itemSetWrapper = this.widgetDef.itemSetsArr[name] || null;
        if (!itemSetWrapper) {
            return null;
        }
        return itemSetWrapper;
    },
    getWidgetId: function() {
        return this.widgetDef.id;
    },
    getWidgetName: function() {
        return this.widgetDef.id;
    },
    getPayloadDefs: function() {
        return null;
    },
    getPayloadDef: function(name) {
        return null;
    },
    getPayloadDefNames: function() {
        var arr = [];
        return arr;
    },
    getSupportedModes: function() {
        var temp = this.widgetDef.supportedModes;
        if (!temp) {
            return null;
        }
        var arr = temp.split(" ");
        return arr;
    },
    getSupportedWindowStates: function() {
        var temp = this.widgetDef.supportedWindowStates;
        if (!temp) {
            return null;
        }
        var arr = temp.split(" ");
        return arr;
    },
    getDefaultLanguage: function() {
        return this.widgetDef.lang;
    },
    getMarkup: function() {
        return this.widgetDef.markup;
    },
    _specObjectToWidgetDef: function() {
        this.widgetDef = {};
        if (null === this.specObject) {
            return;
        }
        // id
		var temp = this.specObject._id;
        if (!temp) {
            temp = this.specObject._name;
        }
		this.widgetDef.id = null;
		this.widgetDef.name = null;
		if (temp){
			this.widgetDef.id = temp;
			this.widgetDef.name = temp;
		}
        // allowInstanceContent
        this.widgetDef.allowInstanceContent = false;
        temp = this.specObject._allowInstanceContent;
        if (temp && temp == "true") {
            this.widgetDef.allowInstanceContent = true;
        }
        // iScope
        temp = this.specObject._iScope;
        this.widgetDef.iScope = null;
        if (temp) {
            this.widgetDef.iScope = temp;
        }
        // supportedModes
        temp = this.specObject._supportedModes;
        if (!temp) {
            temp = "view";
        }
        this.widgetDef.supportedModes = temp;

        // supportedWindowStates
        temp = this.specObject._supportedWindowStates;
        if (!temp) {
            temp = "normal";
        }
        this.widgetDef.supportedWindowStates = temp;

        // lang
        temp = this.specObject._lang;
        if (!temp) {
            temp = this.specObject._xml_lang;
        }
		if (!temp){
			temp = "en";
		}
        this.widgetDef.lang = temp;

		// xml:base
		temp = this.specObject._xml_base;
		if (temp){
			this.widgetDef.xmlBase = temp;
		}

        // iDescriptor
        var iDescriptorItems = iwConstants.iDescriptorItems;
        var iDescriptor = {};
        for (var i in iDescriptorItems) {
            if (Object.prototype.hasOwnProperty.call(iDescriptorItems,i)) {
                var name = iDescriptorItems[i];
                var value = this.specObject['_' + name];
				if (typeof value == "undefined") {
					value = null;
				}
                iDescriptor[name] = value;
            }
        }

        this.widgetDef.iDescriptor = iDescriptor;

        // simple attributes and widget events
        var simpleAttributes = {};
        var widgetEvents = {};
        for (var j in this.specObject) {
            if (Object.prototype.hasOwnProperty.call(this.specObject,j)) {
                // only root level attributes
                if (0 !== j.indexOf('_')) {
                    continue;
                }
                var attr = j;
                attr = attr.substr(1);
                if (attr.indexOf("on") !== 0 && !iwConstants.iDescriptorItems[attr] && !this.reservedAttributes[attr]) {
					simpleAttributes[attr] = this.specObject[j];
                }
                else if (attr.indexOf("on") === 0) {
                    widgetEvents[attr] = this.specObject[j];
                }
            }
        }
        this.widgetDef.simpleAttributes = simpleAttributes;
        this.widgetDef.widgetEvents = widgetEvents;

        // markup
        this.widgetDef.markup = this._extractMarkupFromSpecObject();

        // itemSets
        var itemSets = this._extractItemSetsFromSpecObject(this.widgetDef);
        if (null !== itemSets) {
            this.widgetDef.itemSetsArr = itemSets;
        }

        // public events
        this.widgetDef.publicEvents = this._extractEventsFromSpecObject();

        // resources
        this.widgetDef.resources = this._extractResourcesFromSpecObject();

        // payload defs
        // this.widgetDef.payloadDefs = this._extractPayloadDefsFromSpecObject();

        // event descriptions
        this.widgetDef.eventDescriptions = this._extractEventDescFromSpecObject();
    },
    // never used
	//    _extractEventsFromSpecObject: function() {
	//        // widget events
	//        var widgetEvents = {};
	//        for (var i in this.specObject) {
	//            var handler = this.specObject[i];
	//            if (typeof handler != "undefined" && handler != null) {
	//                widgetEvents[event.name] = handler;
	//            }
	//        }
	//        return widgetEvents;
	//    },
    _extractMarkupFromSpecObject: function() {
        var contents = this.specObject.contents;
        var widgetDefContents = {};
        for (var mode in contents) {
            if (Object.prototype.hasOwnProperty.call(contents,mode)) {
                if (contents[mode]) {
					widgetDefContents[mode] = {};
					if (contents[mode]._uri) {
						widgetDefContents[mode].uri = contents[mode]._uri;
					}
					if (contents[mode].value) {
						widgetDefContents[mode].content = contents[mode].value;
					}
				}
            }
        }
        return widgetDefContents;
    },
    _extractItemSetsFromSpecObject: function(widgetDef) {
        var itemSets = this.specObject.itemSets;
        if (itemSets) {
            var itemSetsArr = {};
            var shareableItemSetsArr = {};
            for (var i in itemSets) {
                if (Object.prototype.hasOwnProperty.call(itemSets,i)) {
                    var itemSet = itemSets[i];
                    var id = i;

                    var onItemSetChanged = itemSet._onItemSetChanged;
                    var temp = itemSet._private;
                    var isPrivate = true;
                    if (temp && temp == "false") {
                        isPrivate = false;
                    }
					var alias = itemSet._alias?itemSet._alias:null;

                    var descriptionRef = itemSet._description;

                    var itemSetWrapper = {
                        id: id,
                        onItemSetChanged: onItemSetChanged,
                        isPrivate: isPrivate
                    };

					if (alias){
						itemSetWrapper.alias = alias;
					}
                    itemSetWrapper.items = {};

                    var items = itemSet.items; // WARNING: this assumes that an itemset only contains items !
                    for (var j in items) {
                        if (Object.prototype.hasOwnProperty.call(items,j)) {
                            var item = items[j];
                            var readOnly = false;
                            var readOnlyAtt = item._readOnly;

                            if (readOnlyAtt && readOnlyAtt == "true") {
                                readOnly = true;
                            }

                            var id2 = item._id;
							var alias2 = item._alias?item._alias:null;

                            var value = item._value;
                            var lang = item._lang;
							if (!lang){
								lang = item._xml_lang;
							}

                            var anItem = {};
                            anItem.id = id2;

							if (alias2){
								anItem.alias = alias2;
							}
                            anItem.readOnly = readOnly;
                            if (lang) {
								anItem.defaultLocale = lang;
							}
							//value could be ""
							if (typeof value != "undefined" && value !== null && !lang) {
								anItem.value = value;
							}
							if (typeof value != "undefined" && value !== null  && lang){
								anItem.values = {};
								anItem.values[lang]=value;
							}

                            var values = item.alts;
                            for (var v in values) {
                                if (Object.prototype.hasOwnProperty.call(values,v)) {
                                    var valueNode = values[v];
                                    var locale = v;
                                    var localeValue = valueNode._value;
									if (!anItem.values) {
										anItem.values = {};
									}
                                    anItem.values[locale] = localeValue;
									// if default value for default locale is defined in alts, remove default value here so no duplicates
									if (lang && locale == lang && anItem.value){
										delete anItem.value;
									}

                                }
                            }

                            itemSetWrapper.items[id2] = anItem;
                        }
                    }

                    if (isPrivate === true) {
                        itemSetsArr[id] = itemSetWrapper;
                    }
                    else {
                        shareableItemSetsArr[id] = itemSetWrapper;
                    }
                }
            }
            widgetDef.shareableItemSetsArr = shareableItemSetsArr;
            return itemSetsArr;
        }
        return null;
    },
    _extractEventsFromSpecObject: function() {
        var events = this.specObject.events;
        var eventsArray = {};
        if (events && events.length !== 0) {
            for (var j in events) {
                if (Object.prototype.hasOwnProperty.call(events,j)) {
                    var event = events[j];
                    //todo. handler attributes
                    var iEvent = {};
                    for (var i in event) {
                        if (Object.prototype.hasOwnProperty.call(event,i)) {
                            var name = i;
                            if (0 === i.indexOf('_')) {
                                name = name.substr(1);
                            }
                            var value = event[i];
                            if (name == "eventDescName") {
                                name = "description"; //backward compatibility
                            }
                            if (name == "handled") {
                                name = "isHandled"; //align with js representation
                            }
                            if (name == "published") {
                                name = "isPublished"; //align with js representation
                            }
                            if (value) {
                                iEvent[name] = value;
                            }
                        }
                    }
                    eventsArray[iEvent.id] = iEvent;
                }
            }
        }
        return eventsArray;
    },
    _extractResourcesFromSpecObject: function() {
        var resources = [];
        var nodes = this.specObject.resources;
        var j = 0;
        if (nodes && nodes.length !== 0) {
            for (var i in nodes) {
                if (Object.prototype.hasOwnProperty.call(nodes,i)) {
                    var node = nodes[i];
                    var resource = {};
					var id = node._id;
					if (!id) {
						id = node._globalid;
					}

                    resource[iwConstants.RESOURCE.id] = id?id:null;
                    var src = node._src;
                    if (!src) {
                        src = node._uri;
                    }

                    resource[iwConstants.RESOURCE.src] = src;
                    resource[iwConstants.RESOURCE.version] = node._version?node._version:null;
                    resource[iwConstants.RESOURCE.callback] = node._callback?node._callback:null;
                    resource[iwConstants.RESOURCE.mimeType] = node._mimeType?node._mimeType:null;
					resource[iwConstants.RESOURCE.blockInit] = node._blockInit?node._blockInit:null;
					resource[iwConstants.RESOURCE.globalid] = node._globalid?node._globalid:null;
					resource[iwConstants.RESOURCE.skipLoad] = node._skipLoad?node._skipLoad:null;
				    resources[j] = resource;
                    j++;
                }
            }
        }
        return resources;
    },
    _extractPayloadDefsFromSpecObject: function() {
        var payloadDefsArr = {};
        var payloadDefs = this.specObject.payloadDefs;
        for (var i in payloadDefs) {
            if (Object.prototype.hasOwnProperty.call(payloadDefs,i)) {
                var aNode = payloadDef[i];
                // MDG to do fix!
                // var payloadDef = com.ibm.mm.iwidget.Utils.getPayloadDef(aNode);
                //payloadDefsArr[i]=payloadDef;
            }
        }
    },
	//todo!
    _extractEventDescFromSpecObject: function() {
        var eventDescriptions = {};
        var eventDescs = this.specObject.eventDescriptions;
        if (eventDescs && eventDescs.length !== 0) {
            for (var i in eventDescs) {
                if (Object.prototype.hasOwnProperty.call(eventDescs,i)) {
                    var node = eventDescs[i];
                    var eventDescription = {};
                    var id = i;
                    eventDescription.id = id;
                    eventDescription.payloadType = node._payloadType;
                    eventDescription.description = node._description;
                    eventDescription.title = node._title;
                    eventDescription.descriptionURI = node._descriptionURI?node._descriptionURI:null;
					//eventDescription.aliases = node._aliases?node._aliases:null;
					var lang = node._lang;
					if (!lang ){
						lang = node._xml_lang;
					}
                    if (lang) {
						eventDescription.lang = lang;
					}

                    var children = node.alts;
                    for (var j in children) {
                        if (Object.prototype.hasOwnProperty.call(children,j)) {
                            var aNode = children[j];
                            var temp = {};
                            temp.description = aNode._description;
                            temp.title = aNode._title;
                            temp.descriptionURI = aNode._descriptionURI?aNode_descriptionURI:null;
							if (!eventDescription.descriptions){
								eventDescription.descriptions = {};
							}
                            eventDescription.descriptions[j] = temp;
                        }
                    }
                    eventDescriptions[id] = eventDescription;
                }
            }
        }
        return eventDescriptions;
    },
    toSpecObject: function() {
        if (this.specObject) {
            return this.specObject;
        }
        var outputJSON = {};
        return outputJSON;
    }
});

com.ibm.mm.iwidget.widget.IWidgetDefinitionImpl = com.ibm.mm.iwidget.widget.IWidgetDefinitionDefaultImpl;

// IMPORTANT
// ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
// This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "iWidget") >= 0)) {
    dojo["require"]("com.ibm.mm.iwidget.widget.IWidgetDefinitionExtendedImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
}

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetDefinition"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetDefinition"] = true;
dojo.provide("com.ibm.mashups.iwidget.widget.IWidgetDefinition");






}

if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.ModifiableProperties_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.widget.ModifiableProperties_API"] = true;
dojo.provide("com.ibm.mashups.iwidget.widget.ModifiableProperties_API");
dojo.provide("com.ibm.mashups.iwidget.widget.ModifiableProperties");

/**
 * Modifiable interface defines functions to iterates , updates and persist Properties.
 * @ibm-spi
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.widget.ModifiableProperties", [com.ibm.mashups.iwidget.widget.Properties], {
    /**
     * @private
     */
    constructor: function() {
    },
    /**
     * This method creates or overwrites the value of the required item
     * @param{String}itemName name of the item. Must never be NULL.
     * @param{String} itemValue value of the item. Must never be NULL.
     * @param{Boolean} readOnly whether the item value is read only (on this level).
     * @param{String} locale the locale in which the item value is
     * @return{com.ibm.mashups.iwidget.widget.Properties} return an handle of InstanceProperties upon successful, NULL upon failure.
     */
    setItemValue: function(itemName, itemValue, readOnly, locale) {
    },
    /**
     * Removes the named item from the set.
     * @param{String} itemName name of the item that should be removed.Must never be NULL.
     * @return{com.ibm.mashups.iwidget.widget.Properties} return an handle of InstanceProperties upon successful, NULL upon failure..
     */
    removeItem: function(itemName) {
        //summary:This method sets an value of an iDescriptor item
    },
    /**
     * Removes the specified item value with the given locale.
     * @param{String} itemName the name of the item for which to remove the value.
     * @param{String} locale the locale of the value to remove. Must never be NULL
     * @return{void}
     */
    removeItemValue: function(itemName, locale) {
    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.widget.ModifiablePropertiesImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.widget.ModifiablePropertiesImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.widget.ModifiablePropertiesImpl");





dojo.declare("com.ibm.mm.iwidget.widget.ModifiablePropertiesImpl", [com.ibm.mashups.iwidget.widget.ModifiableProperties, com.ibm.mm.iwidget.widget.PropertiesImpl], {
    constructor: function(items, defaultProps) {
        this._dirty = false;
    },
    _buildChange: function(item, itemName, oldVal, newVal, isRemove) {
        var isDirty = item._dirty;
        if (!isDirty) {
            item._dirty = true;
        }
        var change = item._change ? item._change : {};
        change.id = itemName;

        if (isRemove) {
            //if it's remove action
            if (isDirty && change.changeType && change.changeType == this.TYPE_NEW) {
                item._dirty = false;
                delete item._change;
                return;
            }
            else if (isDirty) {
                change.changeType = this.TYPE_REMOVE;
                return;
            }
            item._change.changeType = this.TYPE_REMOVE;
            item._change.oldVal = oldVal;
            return;
        }

        if (isDirty && change.changeType) {
            if (change.changeType == this.TYPE_NEW) {
                change.newVal = newVal;
            }
            else {
                change.changeType = this.TYPE_UPDATE;
                change.newVal = newVal;
            }
        }
        else {
            if (oldVal) {
                change.oldVal = oldVal;
            }
            if (newVal) {
                change.newVal = newVal;
            }
            if (oldVal) {
                change.changeType = this.TYPE_UPDATE;
            }
            else {
                change.changeType = this.TYPE_NEW;
            }
        }
        item._change = change;
        return;
    },
    setItemValue: function(itemName, itemValue, readOnly, locale) {
        if (!itemName || !itemValue) {
            return null;
        }
        if (itemName in this._items) {
            if (this._defaultProperties && this._defaultProperties.isReadOnly(itemName)) {
                return null;
            }
        }
        var oldValue = {};
        var newValue = {};
        var isReadOnly;
        if (!locale || (locale && locale == "")) { //that means this is a nonlocalized item
            if (itemName in this._items) {
                oldValue = {};
                newValue = {};
                if (this._items[itemName].values) {
                    oldValue = dojo.clone(this._items[itemName].values);
                    if (this._items[itemName].value) {
                        oldValue[""] = this._items[itemName].value;
                    }
                    newValue = dojo.clone(this._items[itemName].values);
                    newValue[""] = itemValue;
                }
                else {
                    if (this._items[itemName].value) {
                        oldValue[""] = this._items[itemName].value;
                    }
                    newValue[""] = itemValue;
                }
                this._items[itemName].value = itemValue;
                this._buildChange(this._items[itemName], itemName, oldValue, newValue);
            }
            else {
                var anItem = {};
                anItem.id = itemName;
                //anItem.name = itemName;
                anItem.value = itemValue;
                isReadOnly = !!readOnly;
                anItem.readOnly = isReadOnly;
                this._items[itemName] = anItem;
                newValue = {};
                newValue[""] = itemValue;
                this._items[itemName] = this._items[itemName] ? this._items[itemName] : {};
                this._buildChange(this._items[itemName], itemName, null, newValue);
            }
            if (this._items[itemName]._dirty) {
                this._dirty = true;
            }
            return this;
        }

        var normalizedLocale = locale.replace(/-/g, "_"); // normalize the locale
        if (itemName in this._items) {
            oldValue = {};
            newValue = {};
            //this is update
            if (this._items[itemName].values) {
                oldValue = dojo.clone(this._items[itemName].values);
            }
            this._items[itemName].values[normalizedLocale] = itemValue;
            newValue = dojo.clone(this._items[itemName].values);
            if (this._items[itemName].value) {
                oldValue[""] = this._items[itemName].value;
                newValue[""] = this._items[itemName].value;
            }
            this._items[itemName].readOnly = readOnly;
            this._buildChange(this._items[itemName], itemName, oldValue, itemValue);
            if (this._items[itemName]._dirty) {
                this._dirty = true;
            }
            return this;
        }

        //if it's a new item
        var item = {};
        item.values = {};
        item.values[normalizedLocale] = itemValue;
        item.id = itemName;
        isReadOnly = !!readOnly;
        item.readOnly = isReadOnly;
        this._items[itemName] = item;
        newValue = dojo.clone(item.values);
        this._buildChange(this._items[itemName], itemName, null, newValue);

        if (this._items[itemName]._dirty) {
            this._dirty = true;
        }
        return this;
    },
    removeItem: function(itemName) {
        //remove all the values of the Item

        // check if this item is read-only on the parent level
        if (this._defaultProperties && this._defaultProperties.isReadOnly(itemName)) {
            throw "The specified item [" + itemName + "] is readOnly!";
        }

        var change = {};
        var deleted = false;
        if (itemName in this._items) {
            //delete this._items[itemName]; //this._items only keeps track of any change
            if (this._items[itemName]._dirty) {
                this._items[itemName].value = this.DELETE_TOKEN;
                this._items[itemName].values = this.DELETE_TOKEN;
                change = this._items[itemName]._change ? this._items[itemName]._change : {};
                if (change.changeType == this.TYPE_NEW) {
                    delete this._items[itemName];
                    return this;
                }
                else {
                    change.changeType = this.TYPE_REMOVE; //keep old value
                }
            }
            else {
                var oldValue = {};
                if (this._items[itemName].values) {
                    oldValue = dojo.clone(this._items[itemName].values);
                }
                if (this._items[itemName].value) {
                    oldValue[""] = this._items[itemName].value;
                }
                this._items[itemName].value = this.DELETE_TOKEN;
                this._items[itemName].values = this.DELETE_TOKEN;
                change = {};
                change.changeType = this.TYPE_REMOVE;
                change.itemName = itemName;
                change.oldVal = oldValue;
                this._items[itemName]._change = change;
                this._items[itemName]._dirty = true;
            }
            deleted = true;
        }
        if (deleted) {
            this._dirty = true;
            return this;
        }
        else {
            return null;
        }
    },
    removeItemValue: function(itemName, locale) {
        if (!locale) {
           //remove nonlocalized value
		   locale = "";
        }

        // check if this item is read-only on the parent level
        if (this._defaultProperties && this._defaultProperties.isReadOnly(itemName)) {
            throw "The specified item [" + itemName + "] is readOnly!";
        }

        var normalizedLocale = locale.replace(/-/g, "_"); // normalize the locale
        var deleted = false;
        var change = {};
        if (itemName in this._items) {
            if (this._items[itemName]._dirty) {
                change = this._items[itemName]._change ? this._items[itemName]._change : {};
                if (change.changeType == this.TYPE_REMOVE) {
                    return null; //item is already removed
                }
                else if (change.changeType == this.TYPE_NEW) { //don't change type
                    if (normalizedLocale == "" && this._items[itemName].value && this._items[itemName].value != this.DELETE_TOKEN) {
                        delete this._items[itemName].value;
                        if (this._items[itemName]._change.newVal[""]) {
                            delete this._items[itemName]._change.newVal[""];
                        }
                        deleted = true;
                    }
                    if (normalizedLocale != "") {
                        if (this._items[itemName].values[normalizedLocale]) {
                            delete this._items[itemName].values[normalizedLocale];
                            if (this._items[itemName]._change.newVal[normalizedLocale]) {
                                delete this._items[itemName]._change.newVal[normalizedLocale];
                            }
                            deleted = true;
                        }
                    }
                    if (this._isEmpty(this._items[itemName]._change.newVal)) {
                        delete this._items[itemName]._dirty;
                        delete this._items[itemName]._change;
                    }
                }
                else { //update
                    if (normalizedLocale == "" && this._items[itemName].value && this._items[itemName].value != this.DELETE_TOKEN) {
                        delete this._items[itemName].value;
                        if (this._items[itemName]._change.newVal[""]) {
                            delete this._items[itemName]._change.newVal[""];
                        }
                        deleted = true;
                    }
                    if (this._items[itemName].values[normalizedLocale]) {
                        delete this._items[itemName].values[normalizedLocale];
                        if (this._items[itemName]._change.newVal[normalizedLocale]) {
                            delete this._items[itemName]._change.newVal[normalizedLocale];
                        }
                        deleted = true;
                    }
                }
            }
            else {
                var oldValue = {};
                var newValue = {};
                if (normalizedLocale == "" && this._items[itemName].value) {
                    change = {};
                    change.id = itemName;
                    oldValue = {};
                    newValue = {};
                    if (this._items[itemName].values) {
                        change.changeType = this.TYPE_UPDATE;
                        oldValue = dojo.clone(this._items[itemName].values);
                        oldValue[""] = this._items[itemName][""];
                        change.oldVal = oldValue;
                        change.newVal = dojo.clone(this._items[itemName].values);
                        delete this._items[itemName].value;
                    }
                    else {
                        change.changeType = this.TYPE_REMOVE;
                        oldValue[""] = this._items[itemName][""];
                        change.oldVal = oldValue;
                        delete this._items[itemName].value;
                    }
                    this._items[itemName]._change = change;
                    this._items[itemName]._dirty = true;
                    deleted = true;
                }
                if (normalizedLocale in this._items[itemName].values) {
                    change = {};
                    change.id = itemName;
                    oldValue = {};
                    newValue = {};
                    if (this._items[itemName].value) {
                        change.changeType = this.TYPE_UPDATE;
                        oldValue = dojo.clone(this._items[itemName].values);
                        oldValue[""] = this._items[itemName][""];
                        change.oldVal = oldValue;
                        change.newVal = dojo.clone(this._items[itemName].values);
                        change.newVal[""] = this._items[itemName].value;
                        delete change.newVal[normalizedLocale];
                        delete this._items[itemName].value;
                    }
                    else {
                        oldValue = dojo.clone(this._items[itemName].values);
                        delete this._items[itemName].values[normalizedLocale];
                        if (this._isEmpty(this._items[itemName].values)) {
                            change.changeType = this.TYPE_REMOVE;
                        }
                        else {
                            change.changeType = this.TYPE_UPDATE;
                            change.newVal = dojo.clone(this._items[itemName].values);
                        }
                        change.oldVal = oldValue;
                    }
                    this._items[itemName]._change = change;
                    this._items[itemName]._dirty = true;
                    deleted = true;
                }
            }

        }

        if (deleted) {
            this._dirty = true;

            return this;
        }
        else {
            return null;
        }
    },
    _isDirty: function() {
        return this._dirty;
    },
    _setDirty: function(value) {
        this._dirty = value;
    },
    _isItemDirty: function(itemName) {
        if (!itemName) {
            return false;
        }
        var isDirty = false;
        if (this._items[itemName]) {
            isDirty = this._items[itemName]._dirty;
        }
        return isDirty;
    },
    _setItemDirty: function(itemName, value) {
        if (!itemName) {
            return;
        }
        if (this._items[itemName]) {
            this._items[itemName]._dirty = value;
            if (typeof value != "undefined" && !value) {
                delete this._items[itemName]._dirty;
                delete this._items[itemName]._change;
            }

            if (this._items[itemName].values && this._items[itemName].values == this.DELETE_TOKEN) {
                delete this._items[itemName].values;
            }
            if (this._items[itemName].value && this._items[itemName].value == this.DELETE_TOKEN) {
                delete this._items[itemName].value;
            }

            if (!this._items[itemName].value && !this._items[itemName].values) {
                delete this._items[itemName];
            }
        }
    },
    _getInternalItemValue: function(itemName) {
        if (this._items[itemName]) {
            return this._items[itemName];
        }
        return null;
    },
    _isEmpty: function(obj) {
    	return com.ibm.mm.enabler.utils.Misc.isEmpty(obj);
    },
    _getRequiredValue: function(obj, locale) {
        if (!obj) {
            return null;
        }
        if (dojo.isString(obj)) {
            return obj;
        }
        if (locale) {
            if (obj[locale]) {
                return obj[locale];
            }
            else {
                return null;
            }
        }
        var singleValue = null;
        var j = 0;
        for (var i in obj) {
            if (Object.prototype.hasOwnProperty.call(obj,i)) {
                if (i == "") {
                    singleValue = obj[i];
                }
                j++;
            }
        }
        if (singleValue && j == 1) {
            return singleValue;
        }
        return obj;
    },
	_updateProperties:function(updatedProperties){
		//used by sandboxed mode... updates is sent from wrapper to stub
		//merge the updates, latest one overwrites the old one
		var updatedItems = dojo.mixin(this._items,updatedProperties);
		this._items = updatedItems;
		this._dirty = true;
	},
	toJson:function(){
		return this._items;
	}
});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.ModifiableProperties"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.widget.ModifiableProperties"] = true;
dojo.provide("com.ibm.mashups.iwidget.widget.ModifiableProperties");





}

if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.ModifiablePropertiesProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.widget.ModifiablePropertiesProvider"] = true;
dojo.provide("com.ibm.mashups.iwidget.widget.ModifiablePropertiesProvider");



/**
 * Modifiable interface defines functions to access properties that's defined with iWidget.
 * @ibm-spi
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.widget.ModifiablePropertiesProvider", null, {
    /**
     * @private
     */
    constructor: function() {
    },
    /**
     This method returns an object that contains iDescriptor items as defined by iWidget spec. It contains  default title and icon
     @type com.ibm.mashups.iwidget.widget.ModifiableProperties
     @returns{com.ibm.mashups.iwidget.widget.ModifiableProperties } object that contains iWidget iDescriptor items information
     */
    getIDescriptorItems: function() {
    },

    /**
     This method returns an object that contains attributes as defined by iWidget spec.
     @type com.ibm.mashups.iwidget.widget.ModifiableProperties
     @returns{com.ibm.mashups.iwidget.widget.ModifiableProperties } object that contains iWidget iDescriptor items information
     */
    getAttributes: function() {
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.ModifiableWireProvider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.widget.ModifiableWireProvider"] = true;
dojo.provide("com.ibm.mashups.iwidget.widget.ModifiableWireProvider");



/**
 * Interface defines functions to access handled or published event descriptions.
 * @ibm-spi
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.widget.ModifiableWireProvider", com.ibm.mashups.iwidget.widget.WireProvider, {
    /**
     * @private
     */
    constructor: function(id) {

    },

    /**
     * @param {String}sourceWidgetId id of the widget that will publish the event
     * @param {String}sourceEventName  name of the event source widget will publish
     * @param {String}targetEventName   name of the event the receiving widget and this event will handle the event published by source widget
     * @type void
     */
    addWire: function(sourceWidgetId, sourceEventName, targetEventName) {
    },
    /**
     * @param {String}sourceWidgetId  id of the widget that will publish the event
     * @param {String}sourceEventName name of the event source widget will publish
     * @param {String}targetEventName name of the event the receiving widget and this event will handle the event published by source widget
     * @type void
     */
    removeWire: function(sourceWidgetId, sourceEventName, targetEventName) {
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetInstance_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetInstance_API"] = true;
dojo.provide("com.ibm.mashups.iwidget.widget.IWidgetInstance_API");
dojo.provide("com.ibm.mashups.iwidget.widget.IWidgetInstance");

/**
 * Interface defines functions to access all the instance level descriptive data.
 * @ibm-spi
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.widget.IWidgetInstance", [com.ibm.mashups.iwidget.widget.ModifiablePropertiesProvider, com.ibm.mashups.iwidget.widget.ModifiableWireProvider], {
    /**
     * @private
     */
    constructor: function() {

    }

});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.Utils"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.Utils"] = true;
dojo.provide("com.ibm.mm.iwidget.Utils");



dojo.declare("com.ibm.mm.iwidget.UtilsDefaultImpl", null, {
    constructor: function() {
    },

    widgetClassRE: new RegExp("(mm:|mm_|iw-)iWidget"),

    findElementByAttribute: function(/*String*/att,/*String*/ value,/*DOMElement*/ root,/*[]*/ element, hasMultiple){

        var aRoot = root;
        if (!root.childNodes) {
            return false;
        }
        if (att == "class") {
            dojo.query("." + value, root).forEach(function(ele){
                element.push(ele);
            });

            return element.length !== 0;
        }
        else if (att == "query") {
            dojo.query(value, root).forEach(function(ele){
                element.push(ele);
            });

            return element.length !== 0;
        }

        //other attributes
        if (root.getElementsByTagName) {

            var nodes = root.getElementsByTagName("*");
            for (var i = 0, l = nodes.length; i < l; i++) {
                var aNode = nodes[i];
                if (aNode && aNode.getAttribute) {
                    var childValue = aNode.getAttribute(att);
                    if (childValue == value) {
                        element.push(aNode);
                        if (!hasMultiple) {
                            return true;
                        }
                    }
                }
            }
        }

        // made this order change for 20459. The above code should fix 20459 for dojo test. If it fails 20403 and 20330, the following code will catch it
        // This is to avoid using the hacking code

        // made the change for 20403 and 20330 since IE7 returns wrong value with code in the other attributes section above
        if (att == "id") {
        	dojo.query("#" + value, root).forEach(function(ele){
                element.push(ele);
            });

            return element.length !== 0;
        }
        return false;
    },

    getClass: function(/*object*/node){
        var childValue = node.getAttribute("class");
        childValue = childValue ? childValue : node.getAttribute("className");
        return childValue;
    },

    checkParentElement: function(/*Node*/selfNode, /*RegExp*/ classToFind){
        if (selfNode) {
            var dadNode = selfNode.parentNode;
            if (dadNode) {
                if (dadNode.className) {
                    if (dadNode.className.match(classToFind)) {
                        return dadNode.id;
                    }
                }
                return this.checkParentElement(dadNode, classToFind);
            }
        }
        return null;
    },

    getWidgetParent: function(/*Domnode*/node, /*RegExp*/ classToFind){
        if (dojo.isString(node)) {
            node = dojo.byId(node);
        }
        if (!classToFind) {
            classToFind = this.widgetClassRE;
        }

        return this.checkParentElement(node, classToFind);
    },

    getParents: function(/*widget*/widget,/*array*/ arr){
        var parent = widget.getParent();
        if (parent) {
            arr.push(parent);
            this.getParents(parent, arr);
        }
        return;
    },

    /**
     * 	This utility method takes an id from the markup and returns
     *  an unprefixed id to pass into an enabler model (like Widget,
     *  Wire or Event.)  IE7 doesn't support ids that start with a
     *  number so the server may encode the ids with a prefix,
     *  like 'id_' to make an id valid.
     *
     *  If the markup id starts with the prefix from
     *  ibmConfig["com.ibm.mashups.iWidget.idPrefix"] this method
     *  will remove the prefix.
     *
     *  If the id does not start with the prefix no action will be
     *  taken.
     *
     * @param {String}  id from the markup
     * @return {String} the unprefixed id to pass to the enabler
     *                  models
     */
    getModelID: function(/*string*/id){
		var ret = id;
		var prefix = ibmConfig[com.ibm.mashups.enabler.services.ConfigConstants.ID_PREFIX];
		if (prefix && dojo.isString(ret)) {
			var indx = ret.indexOf(prefix);
			if (indx === 0) {
				ret = ret.substring(prefix.length);
			}
		}

		return ret;
    },

    /**
     * 	This utility method takes an id from an enabler (like Widget,
     *  Wire or Event) and returns a prefixed markup id. IE7 doesn't
     *  support ids that start with a number so the server may encode
     *  the ids with a prefix, like 'id_' to make an id valid.
     *
     *  If the model id starts with a number this method will take
     *  prefix from ibmConfig["com.ibm.mashups.iWidget.idPrefix"]
     *  and prepend it to the id passed in.
     *
     *
     * @param {String} id retrieved from an enabler model
     * @return {String} the prefixed id to match the markup returned
     *                  from the server
     */
    getMarkupID: function(/*string*/id) {
		var ret = id;
		var prefix = ibmConfig[com.ibm.mashups.enabler.services.ConfigConstants.ID_PREFIX];
		if (prefix && dojo.isString(ret)) {
			ret = prefix + ret;
		}

		return ret;
    },

    stripHashPrefix: function(str) {
        if (dojo.isString(str)) {
            var pos = str.indexOf('#');
            if (pos !== -1) { // not enough to just strip first character, because IE prepends the URL.
                return str.substr(1 + pos);
            }
        }
        return str;
    },
    /**
     * This method is internal only, it is mainly used for classes that use the "Model" type of instances
     */
    _getWidgetTitle: function(widgetId) {
        return null;
    }
});

// IMPORTANT
// ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
// This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "iWidget") >= 0)) {
    dojo["require"]("com.ibm.mm.iwidget.UtilsExtended"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
} else {
    com.ibm.mm.iwidget.Utils = new com.ibm.mm.iwidget.UtilsDefaultImpl();
}

}

if(!dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetInstanceDefaultImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetInstanceDefaultImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.widget.IWidgetInstanceDefaultImpl");










dojo.declare("com.ibm.mm.iwidget.widget.IWidgetInstanceDefaultImpl", com.ibm.mashups.iwidget.widget.IWidgetInstance, {
    constructor: function(wrapper, /*RootElement*/widgetSpan,/*String*/ id){
        this.wrapper = wrapper;
        this.rootElement = widgetSpan;
        this.id = id;
        this.ns = widgetSpan.className.substr(0, 3);

        var nodes = [];
        var className = this.ns + "Definition";
        com.ibm.mm.iwidget.Utils.findElementByAttribute("query", "> ."+className, this.rootElement, nodes, false);
        if (nodes && nodes.length > 0) {
            var node = nodes[0];
            var url = node.getAttribute("href");
            if (typeof(url) != "undefined" && url !== null) {
                this.widgetXMLUrl = url;
            }
        }
    },
    _destroy: function(){
        // #17713 one leak for widgetWrapper.rootElement (iw-iWidget DIV)
        if (this.rootElement) {
            this.rootElement = null;
        }
    },
    getDefaultViewContent: function(){
        if (this.defaultViewContent) {
            return this.defaultViewContent;
        }
        var className = this.ns + "Content";
        var node = null;
        var nodeList = dojo.query("> ." + className+"."+iwConstants.mode_view, this.rootElement);
        if (nodeList) {
            node = nodeList[0];
        }
        if (!node) {
            nodeList = dojo.query("> ." + className, this.rootElement);
            if (nodeList) {
                node = nodeList[0];
            }
        }
        if (node) {
            this.defaultViewContent = node.innerHTML;
            return this.defaultViewContent;
        }
        else {
            return null;
        }
    },
    getWidgetEvents: function(){
        //simple events including all the predefined events and onSth. event
        if (this.widgetEvents) {
            return this.widgetEvents;
        }
        var widgetEvents = {};
        var attributes = this.rootElement.attributes;
        for (var i = 0; i < attributes.length; i++) {
            var attribute = attributes[i];
            if (attribute.name !== null && attribute.name.indexOf("on") === 0) {
                var handler = this.rootElement.getAttribute(attribute.name);
                if (typeof handler != "undefined" && handler !== null) {
                    widgetEvents[attribute.name] = handler;
                }
            }
        }
        this.widgetEvents = widgetEvents;

        return this.widgetEvents;
    },
    _addWire: function(wire){
    },
    _removeWire: function(id){
    },
    addWire: function(sourceWidget, sourceEvent, targetEvent){
    },
    removeWire: function(sourceWidget, sourceEvent, targetEvent){
    },
    _getPublicEvents: function(){
        return null;
    },
    getWires: function(){
        return [];
    },
    getWireModel: function(){
        return null;
    },
    /**
     * ModifiablePropertiesProvider Impl
     */
    getAttributes: function(){
        if (!this.attributeProperties) {
            //return all the attributes as  JSON data
            var attributes = this.getItemSets()[iwConstants.ATTRIBUTES];
            var properties = {};
            if (attributes) {
                for (var itemName in attributes) {
                    if (Object.prototype.hasOwnProperty.call(attributes, itemName)) {
                        properties[itemName] = attributes[itemName]; // we are compatible with the new internal itemset format
                    }
                }
            }

            this.attributeProperties = new com.ibm.mm.iwidget.widget.ModifiablePropertiesImpl(properties);
        }

        return this.attributeProperties;
    },
    /**
     * ModifiablePropertiesProvider Impl
     */
    getIDescriptorItems: function(){
        if (!this.idescriptorProperties) {
            //return all the attributes as  JSON data
            var iDescriptor = this.getItemSets()[iwConstants.IDESCRIPTOR];

            var properties = {};

            if (iDescriptor) {
                for (var itemName in iDescriptor) {
                    if (Object.prototype.hasOwnProperty.call(iDescriptor, itemName)) {
                        properties[itemName] = iDescriptor[itemName]; // we are compatible with the new internal itemset format
                        // (this is working here, because on instance level we got the idescriptor from markup, not def)
                    }
                }
            }

            this.idescriptorProperties = new com.ibm.mm.iwidget.widget.ModifiablePropertiesImpl(properties);
        }

        return this.idescriptorProperties;
    },

    _getItemSets: function(){
        if (this.itemSets) {
            return this.itemSets;
        }
        this.loadItemSets();
        return this.itemSets;
    },
    getItemSets: function(){
        //returns a list of itemsets: each itemset is like following
        // { itemname1:object,itemname2;object}
        //
        return this._getItemSets();
    },
    getItemSet: function(itemSetName){
        //returns json object as indicated in _loadItem
        //{ itemName1:{},itemName2:{}}
        if (!itemSetName) {
            return null;
        }
        var itemSets = this._getItemSets();
        if (itemSets && itemSets[itemSetName]) {
            return itemSets[itemSetName];
        }
    },
    loadItemSets: function(){
        //this.itemSets = this._loadItemSets(this.rootElement, this.ns);
        this.itemSets = this._loadItemSetsOptimized(this.rootElement, this.ns);
    },

    _loadItemSetsOptimized: function(rootElement, ns){
        var itemSets = {};
        if (rootElement.childNodes.length) {

            dojo.query('> .'+ns+com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwItemSet+' > .'+ns+com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwItem, rootElement).forEach(function(item){
                var setName = dojo.attr(item.parentNode, 'title');
                if (setName) {
                    if (!itemSets[setName]) {
                        itemSets[setName] = {};
                    }
                    var anItem = this._loadItemOptimized(item, ns);
                    itemSets[setName][anItem.id] = anItem;
                }
            }, this);
        }

        return itemSets;
    },

    _loadItemOptimized: function(elem, ns){
        var css = com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE;

        var item = {
            id: com.ibm.mm.iwidget.Utils.stripHashPrefix(dojo.attr(elem, 'href')),
            readOnly: dojo.hasClass(elem, ns + css.iwReadOnly)
        };

        var lang = dojo.attr(elem, 'lang');
        if (lang) {
            item.defaultLocale = lang;
        }

        var value;
        var children = dojo.query('> .' + ns + css.iwValue, elem);
        if (children.length) {
            item.values = {};
            children.forEach(function(valElem){
                var locale = dojo.attr(valElem, 'lang') || lang;
                item.values[locale] = com.ibm.mm.enabler.utils.Dom.textContent(valElem);
            });
        }
        else {
            value = com.ibm.mm.enabler.utils.Dom.textContent(elem);
            if (dojo.isString(value)) {
                item.value = dojo.string.trim(value);
            }
        }

        return item;
    },

    // invalidate itemsets
    _invalidateItemSets: function(name){
        if (!name) {
            // invalidate all itemset
            this.itemSets = {};
        }
        else {
            // invalidate a single itemsets
            this.itemSets[name] = {};
        }
    },

    _getInstanceMarkup: function(){
        var node = dojo.clone(this.rootElement);
        //remove content div if it's available
        dojo.query("> ." + this.ns + "Content", node).forEach(function(contentNode){
            com.ibm.mm.enabler.utils.Dom.destroyNode(contentNode);
        });
        dojo.query("> ." + this.ns + "loading", node).forEach(function(contentNode){
            com.ibm.mm.enabler.utils.Dom.destroyNode(contentNode);
        });

        var tempEl = document.createElement("div");
        tempEl.appendChild(node);
        var html = tempEl.innerHTML;
        return html;
    }
});

com.ibm.mm.iwidget.widget.IWidgetInstanceImpl = com.ibm.mm.iwidget.widget.IWidgetInstanceDefaultImpl;

// IMPORTANT
// ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
// This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "iWidget") >= 0)) {
    dojo["require"]("com.ibm.mm.iwidget.widget.IWidgetInstanceExtendedImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
}

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetInstance"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetInstance"] = true;
dojo.provide("com.ibm.mashups.iwidget.widget.IWidgetInstance");






}

if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetWrapper_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetWrapper_API"] = true;
dojo.provide("com.ibm.mashups.iwidget.widget.IWidgetWrapper_API");
dojo.provide("com.ibm.mashups.iwidget.widget.IWidgetWrapper");

/**
 * IWidgetWrapper interface  represents a runtime instance of an iWidget on the page. Information provided by the IWidgetWrapper is an aggregation of definition level data and instance level data.
 * To get desriptive data that's specific to instance level and definition level. It should use Provider api that's implemented by IWidgetDefinition or IWidgetIstance.
 * @ibm-spi
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.widget.IWidgetWrapper", [com.ibm.mashups.iwidget.widget.WireProvider, com.ibm.mashups.iwidget.widget.EventProvider], {
    /**
     * @private
     */
    constructor: function() {

    },

    /**
     This method returns iWidgetDefinition of  this runtime instance.<br/>
     <code>var deferred = widgetWrapper.getIWidgetDefinition();</code><br/>
     <code>deferred.setFinishedCallback(callback,parameters);</code><br/>
     <code>deferred.start(true);</code><br/>
     here are the callback parameters that will be passed into callback function: <br/>
     &nbsp;&nbsp;&nbsp;&nbsp;<code>resource</code> -  IWidgetDefinition object <br>
     &nbsp;&nbsp;&nbsp;&nbsp;<code>statusCode</code> - the overall HTTP status,code of the action (the highest status code of the involved operations).<br>
     &nbsp;&nbsp;&nbsp;&nbsp;<code>params</code> - the parameters passed into the callback <br>
     @type com.ibm.mashups.enabler.Deferred
     @returns{com.ibm.mashups.enabler.Deferred}  a deferred object used to start this operation.
     @see com.ibm.mashups.iwidget.widget.IWidgetDefinition
     */
    getIWidgetDefinition: function() {
    },

    /**
     Sets the iWidgetDefinition for this runtime instance
     @param{com.ibm.mashups.iwidget.widget.IWidgetDefinition} widgetDefinition IWidgetDefinition to use for this runtime instance. Must not be null.
     @type{void}
     @return{void}
     */
    setIWidgetDefinition: function(widgetDefinition) {
    },
    /**
     This method returns iWidgetInstance which contains all the descriptive data for this iWidget instance
     @type com.ibm.mashups.iwidget.widget.IWidgetInstance
     @returns{com.ibm.mashups.iwidget.widget.IWidgetInstance }  iWidgetInstance object
     */
    getIWidgetInstance: function() {
    },
    /**
     * This method returns the a clone of the content of the widget as it is inside of the DOM.<br/>It removes automatically
     * any markup that was added to the DOM using microformats (given that the microformat implements the unProcess handler).<br/>
     * This method does not remove any additional DOM changes that where done by the widget itself and applies the unProcess only<br/>
     * to the subnodes of the actual widget node.<br/><br/>
     * If your widget needs to take special action to it's DOM nodes before the getMarkup is processing it, you can define the method<br/>
     * <code>_onGetMarkup</code> in your widgets JavaScript file. This method, as part of the iScope, will always be called before the actual<br/>
     * markup is processed.<br/><br/>
     * <b>The synchrounus mode of returned Deferred is not supported.</b>
     * @type com.ibm.mashups.enabler.Deferred
     * @returns {com.ibm.mashups.enabler.Deferred} a deferred object used to fetch the actual markup.
     */
    getMarkup: function() {
    },
    /**
     This method returns  true if an iwidget instance is already loaded on the page dom.
     @type Boolean
     @returns{Boolean }  true if widget is already completely rendered on the page.
     */
    isLoaded: function() {
    },
    /**
     * This method returns  true if an iwidget instance is standalone on the page.
     * @type Boolean
     * @returns{Boolean}  true if widget is standalone on the page.
     */
    isStandalone: function() {
    },
  /**
     This method displays the widgets on the page if widget has not been displayed yet.
     @type void
     */
    doRender: function() {
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.Filter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.Filter"] = true;
dojo.provide("com.ibm.mm.enabler.aggregation.javascript.Filter");




function com_ibm_enabler_aggregation_javascript_globalEvalNonIE( /*String*/javascript) {
    // summary: Evaluates a string of javascript in the global scope.
    // description: Calling eval.call( self, ... ); from within a JS object apparently makes "this" point to the object from which the
    // eval call was made even though the scope is set using the "call" function. Therefore we need to have this function
    // available in the global scope and not as a member variable on a JS object.
    eval.call(self, javascript);
}

dojo.declare("com.ibm.mm.enabler.aggregation.javascript.Filter", null, {
    // summary:    Base interface for a filter. Each implementation must implement
    //  the doFilter function.
    // description: Passes the given event through to give the implementation of
    //  this filter a chance to alter or handle the event in some way.
    constructor: function() {
    },

    doFilter: function( script) {
        // summary: Filter the given event.
        // description: Allows this filter to handle or alter the event. If this function
        //  returns true, processing is stopped and the event is considered "handled".
        // script: the script block (string or HTMLElement)
        //dojo.unimplemented( "com.ibm.mm.enabler.aggregation.JavascriptFilter.doFilter" );
    },
    evalGlobal: function( javascript) {
        // summary: Evaluates the given javascript in the global context.
        // javascript: a string of javascript to evaluate.
        if (window.execScript) { // JSLINT-IGNORE: We have to use eval here
            window.execScript(this._stripHTMLComments(javascript), "JavaScript"); // JSLINT-IGNORE: We have to use eval here
        }
        else {
            //Using eval.call( window, javascript ) was apparently not really eval'ing
            //in the global scope since 'this' was still referring to the Filter object
            //and not the window object as it should have (or I think it should have)...
            com_ibm_enabler_aggregation_javascript_globalEvalNonIE(javascript);
        }
    },
    _stripHTMLComments: function(str) {
        // summary: Strip all HTML comments from a script block.
        // description: Although HTML comments are allowed in a script block by the browser
        //  IE throws up whenever you try and eval a javascript string in the global context
        //  that has HTML comments in the string.
        var resultStr = str;
		resultStr = resultStr.replace(/<!--[^(-->)]+-->/g, '');
        return resultStr;
    },
    prepareDocumentWrite: function(buffer) {
        // summary: Prepares support for document.write() and document.writeln
        // description: Overrides the original document.write() and document.writeln()
        //       functions with functions writing to the buffer
        var me = this;
        document.write = function() { // JSLINT-IGNORE: We have to use eval here
            me._documentWrite(buffer, document.write.arguments); // JSLINT-IGNORE: We have to use eval here
        };
        document.writeln = function(str) { // JSLINT-IGNORE: We have to use eval here
            me._documentWrite(buffer, document.writeln.arguments); // JSLINT-IGNORE: We have to use eval here
        };
    },
    _documentWrite: function(buffer,  args) {
        // summary: Internal document.write() function writing to the given buffer
        // description: Just appends the given String arguments to our buffer
        for (var i = 0, l = args.length; i < l; i++) {
            buffer.content += args[i];
        }
    },

    applyDocumentWrite: function( script, buffer) {
        // summary: Injects the markup in the given buffer into the DOM
        // description: Looks up the script element in the original DOM
        //       and injects the markup before that element
        var cont = buffer.content || null;
        if (cont !== null && cont.length > 0) {
            var i = 0;
            if (dojo.isIE) {
				// Attention: IE needs the <br> tag available, otherwise <script> tags get stripped when using .innerHTML
                cont = '<br>' + cont;
                i++; // the <br> tag must not be copied, so stop iterating one earlier
            }

            var div = dojo.create("div",{
                innerHTML: cont
            });

			var execute = dojo.isIE || dojo.isWebKit || dojo.isOpera; // IE, WebKit and Opera don't execute the inserted scripts automatically, so do it for them.

            var children = div.childNodes || null;
            if (children !== null && children.length > 0) {
                // copy the nodes over into the DOM
                var pred = script;

                var l;
                var scripts = [];
                while (i < (l = children.length)) {
                    var node = children[l - 1];
                    // we need to inject the markup before the script element
                    // to properly handle table updates
                    dojo.place(node, pred, 'before');
                    if (execute && node.tagName && node.tagName.toLowerCase() == 'script') {
                        scripts.unshift(node);
                    }

                    pred = node;
                }

                if (execute) {
                    dojo.forEach(scripts, function(scr){
                        com.ibm.mm.enabler.aggregation.javascript.JAVASCRIPT_HANDLER.handle(scr);
                    });
                }
            }
            dojo.destroy(div);
        }
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.ExternalScriptFilter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.ExternalScriptFilter"] = true;
dojo.provide("com.ibm.mm.enabler.aggregation.javascript.ExternalScriptFilter");






dojo.declare("com.ibm.mm.enabler.aggregation.javascript.ExternalScriptFilter", com.ibm.mm.enabler.aggregation.javascript.Filter, {
    doFilter: function( /*HTMLElement*/script) {
        // summary: Filter the given event.
        // description: Allows this filter to handle or alter the event. If this function
        //        returns true, processing is stopped and the script is considered "handled".
        // script: the script block (HTMLElement)

        var url = this._getScriptUrl(script);

        var handled = false;

        if (url) {
            // check if the AJAX proxy is enabled
            var proxyURL = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.PROXY_URL);
            proxyURL = proxyURL || null;
            if (proxyURL !== null) {
                proxyURL += "/";
                url = this._rewriteURL(url, proxyURL);
            }
            // prepare buffer for document.write/ln
            var buffer = {
                content: ""
            };
            this.prepareDocumentWrite(buffer);
            this._loadExternalScript(url);
            // apply document.write/ln to DOM
            this.applyDocumentWrite(script, buffer);
            handled = true;
        }

        return handled;
    },
    _getScriptUrl: function( /*HTMLElement*/script) {
        // summary: Retrieve the src attribute value of a script tag if it exists.
        // returns: the url for the script tag or null if the script tag doesn't specify a URL
        var url = null;

        if (script.getAttribute) {
            url = script.getAttribute("src");
        }
        else {
            var start = script.toLowerCase().indexOf("<script");
            var end = script.toLowerCase().indexOf(">");

            var scriptTagSubstr = script.substring(start, end);
            var srcIndex = scriptTagSubstr.toLowerCase().indexOf("src");


            if (srcIndex != -1) {
                // figure out whether it's a src='blah' or src="blah"
                var quoteIndex = scriptTagSubstr.indexOf("'", srcIndex);
                var dblQuoteIndex = scriptTagSubstr.indexOf('"', srcIndex);
                var markerChar = '"';
                var markerIndex = dblQuoteIndex;
                if (dblQuoteIndex == -1 || (quoteIndex != -1 && quoteIndex < dblQuoteIndex)) {
                    markerChar = "'";
                    markerIndex = quoteIndex;
                }
                var markerIndex2 = scriptTagSubstr.indexOf(markerChar, markerIndex + 1);
                url = scriptTagSubstr.substring(markerIndex + 1, markerIndex2);
            }
        }

        return url;
    },

    /**
     * This is reused by space-extension remote script loading.
     */
    loadExternalScript: function( /*String*/url) {
        var proxyURL = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME).getValue(com.ibm.mashups.enabler.services.ConfigConstants.PROXY_URL);
        proxyURL = proxyURL || null;
        if (proxyURL !== null) {
            proxyURL += "/";
            url = this._rewriteURL(url, proxyURL);
        }

        this._loadExternalScript(url);
    },

    _loadExternalScript: function( /*String*/url) {
        var me = this;
        dojo.xhrGet({
            url: url,
            load: function(data, ioArgs) {
                me.evalGlobal(data);
            },
            sync: true,
            handleAs: "text"
        });
    },
    _rewriteURL: function(/*String*/targetUrl, /*String*/ proxyUrl) {
        var newURL = proxyUrl;
        var host = window.location.host;
        var protocol = window.location.protocol;

        // check if this is a proxy request:
        if (targetUrl.indexOf("://") < 0 || targetUrl.indexOf(protocol) === 0 && targetUrl.indexOf(host) == protocol.length + 2) {
            return targetUrl;
        }

        // rewrite
        if (targetUrl.indexOf("https") === 0) {
            newURL += "https/";
        }
        else {
            newURL += "http/";
        }

        newURL += targetUrl.substr(targetUrl.indexOf("://") + 3);
        return newURL;
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.FilterChain"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.FilterChain"] = true;
dojo.provide("com.ibm.mm.enabler.aggregation.javascript.FilterChain");

dojo.declare("com.ibm.mm.enabler.aggregation.javascript.FilterChain", null, {
    constructor: function() {
        this._filters = [];
    },
    // summary: Controls the registration and execution of the filters associated
    //        with this filter chain.

    addFilter: function(filter) {
        // summary: Register a filter at the end of the filter chain.
        // filter: the filter to append
        if (!this._filters) {
            this._filters = [];
        }
        this._filters.push(filter);
    },
    applyFilters: function(script) {
        // summary: Execute the filter chain.
        // description: Calls doFilter on every filter registered in this filter chain
        //        until all filters have been called or one of the filters returns true.
        // e: the event object
        // returns: true if the event was handled, false if it was not
        var returnValue = false;

        for(var i = 0, l = this._filters.length; i < l && !returnValue; i++) {
            returnValue = this._filters[i].doFilter(script);
        }

        return returnValue; //Boolean
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.InlineScriptFilter"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.InlineScriptFilter"] = true;
dojo.provide("com.ibm.mm.enabler.aggregation.javascript.InlineScriptFilter");



dojo.declare("com.ibm.mm.enabler.aggregation.javascript.InlineScriptFilter", com.ibm.mm.enabler.aggregation.javascript.Filter, {
    doFilter: function( /*HTMLElement*/script) {
        // summary: Filter the given event.
        // description: Allows this filter to handle or alter the script. If this function
        //        returns true, processing is stopped and the script is considered "handled".
        // script: the script block (HTMLElement)

        var handled = false, tokenContents = "";

        if (!dojo.isString(script)) {
            //Use innerHTML because IE doesn't correctly provide the textContent for a script tag.
            tokenContents = script.innerHTML;
        }
        else {
            var scriptStr = script;
            var firstIndex = scriptStr.indexOf(">");
            var lastIndex = scriptStr.lastIndexOf("<");
            tokenContents = scriptStr.substring(firstIndex + 1, lastIndex);
        }

        if (tokenContents) {
            // prepare buffer for document.write/ln
            var buffer = {
                content: ""
            };
            this.prepareDocumentWrite(buffer);
            // Eval the contents
            this.evalGlobal(tokenContents);
            handled = true;
            // apply document.write/ln to DOM
            this.applyDocumentWrite(script, buffer);
        }

        return handled;
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.WidgetJavascriptHandler"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript.WidgetJavascriptHandler"] = true;
dojo.provide("com.ibm.mm.enabler.aggregation.javascript.WidgetJavascriptHandler");





dojo.declare("com.ibm.mm.enabler.aggregation.javascript.WidgetJavascriptHandler", null, {
    constructor: function() {
        this.filterChain = new com.ibm.mm.enabler.aggregation.javascript.FilterChain();
    },
    // summary: Examines all javascript included by a widget, modifies it if
    //        necessary and evaluates it in the global context.
    // description: All script elements must be loaded manually since the widget
    //        markup is added asynchronously. This handler will evaluate a script
    //        element in the global context or load an external script file if necessary.

    handle: function(script) {
        // summary: Handles a script element added asynchronously.
        // script: the script element
        var val = this.filterChain.applyFilters(script);
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.aggregation.javascript"] = true;
dojo.provide("com.ibm.mm.enabler.aggregation.javascript");







com.ibm.mm.enabler.aggregation.javascript.JAVASCRIPT_HANDLER = new com.ibm.mm.enabler.aggregation.javascript.WidgetJavascriptHandler();

//Register the filters. The order registered is the order executed.
com.ibm.mm.enabler.aggregation.javascript.JAVASCRIPT_HANDLER.filterChain.addFilter(new com.ibm.mm.enabler.aggregation.javascript.ExternalScriptFilter());
com.ibm.mm.enabler.aggregation.javascript.JAVASCRIPT_HANDLER.filterChain.addFilter(new com.ibm.mm.enabler.aggregation.javascript.InlineScriptFilter());

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.Constants"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.Constants"] = true;
dojo.provide("com.ibm.mashups.iwidget.Constants");

/**
 * com.ibm.mashups.iwidget.Constants defines all the public iwidget framework constants.<br/>
 * Each constants should be referred to as : com.ibm.mashups.iwidget.Constants.WIDGET_LOADED...
 * @ibm-module iWidget2
 */

dojo.declare("com.ibm.mashups.iwidget.Constants", null, {

   /**
	*  Enabler would publish WIDGET_LOADED event when an iwidget is loaded. <br/>
  	* <b>Event</b>: com.ibm.mashups.iwidget.Constants.WIDGET_LOADED<br/>
	* <b>Value</b>:"com.ibm.mashups.iwidget.widgetloaded"<br/>
	* <b>Payload</b>: String -- widgetid<br/>
	* For example:
	* When event is published, a name convention is use: com.ibm.mashups.iwidget.Constants.WIDGET_LOADED+"."+widgetId
	* An widget could subscribe to this event by using following SPI:
	* var eventService = com.ibm.mashups.services.ServiceManager.getService("eventService");
	* eventService.subscribeEvent(com.ibm.mashups.iwidget.Constants.WIDGET_LOADED+"."+widgetId,scopeobject,"mycallbackfn");
	* @type String
	* @ibm-spi
	*/
	WIDGET_LOADED: "com.ibm.mashups.iwidget.widgetloaded",

  /**
    *  Enabler would subscribe this event and page components could publish RESIZE_WIDGET event to indicate an iwidget need to be resized.<br/>
    *  When event is published, a name convention is used: com.ibm.mashups.iwidget.Constants.RESIZE_WIDGET+"."+widgetId
	*  Page component should publish event by using following SPI:
	*  var eventService = com.ibm.mashups.services.ServiceManager.getService("eventService");
	*  eventService.publishEvent(com.ibm.mashups.iwidget.Constants.RESIZE_WIDGET+"."+widgetId,payload);
	* <b>Event</b>: com.ibm.mashups.iwidget.Constants.RESIZE_WIDGET<br/>
	* <b>Value</b>:"com.ibm.mashups.iwidget.resizewidget"<br/>
	* <b>Payload</b>: JSON object: {"newWidth": "","newHeight": ""}<br/>
	* @type String
	* @ibm-spi
	*/
   	RESIZE_WIDGET: "com.ibm.mashups.iwidget.resizewidget",


  /**
    *  Enabler would subscribe this event and page components could publish UNLOAD_WIDGETS event to unload certain widgets.<br/>
    *  For example: layout widget could publish this event to unload all the widgets on the page upon page switch<br/>
    *  When all the requested iwidgets are unloaded, enabler would publish event --com.ibm.mashups.iwidget.Constants.WIDGETS_UNLOADED <br/>
	* <b>Event</b>: com.ibm.mashups.iwidget.Constants.UNLOAD_WIDGETS<br/>
	* <b>Value</b>:"com.ibm.mashups.iwidget.unloadwidgets"<br/>
	* <b>Payload</b>: an array of widget id that need to be unloaded<br/>
	* @type String
	* @ibm-spi
	*/
   	UNLOAD_WIDGETS: "com.ibm.mashups.iwidget.unloadwidgets",

  /**
    *  Enabler would publish WIDGETS_UNLOADED event when requested iwidgets are  unloaded. This event is used together with com.ibm.mashups.iwidget.Constants.UNLOAD_WIDGETS.<br/>
    * <b>Event</b>: com.ibm.mashups.iwidget.Constants.WIDGETS_UNLOADED<br/>
    * <b>Value</b>:"com.ibm.mashups.iwidget.widgetsunloaded"<br/>
    * <b>Payload</b>: an array of widget id that are unloaded<br/>
    * @type String
    * @ibm-spi
    */
	WIDGETS_UNLOADED: "com.ibm.mashups.iwidget.widgetsunloaded",
 /**
    *  Enabler would publish WIDGET_MODECHANGED event when requested iwidget has switched from one mode to another mode. <br/>
    * <b>Event</b>: com.ibm.mashups.iwidget.Constants.WIDGET_MODECHANGED<br/>
    * <b>Value</b>:"com.ibm.mashups.iwidget.widgetmodechanged"<br/>
    * <b>Payload</b>: JSON object: {id:"",oldMode:"",newMode:""}<br/>
    * @type String
    * @ibm-api
    */
	WIDGET_MODECHANGED: "com.ibm.mashups.iwidget.widgetmodechanged",
	/**
	*  Enabler would subscribe this event and page components could publish CHANGE_WIDGETMODE event to change a mode of a widget.<br/>
	*  Page components should publish event as follows:
	*  var eventService = com.ibm.mashups.services.ServiceManager.getService("eventService");
	*  eventService.publishEvent(com.ibm.mashups.iwidget.Constants.CHANGE_WIDGETMODE,payload);
	*  following api is deprecated:
	*  com.ibm.mashups.services.ServiceManager.getService("eventService").fireEvent(this.iwidgetId, "onModeChanged", {
    *        newMode: mode,
    *        rootElementId: <DOMNode>
    *    });
	*  <b>Event</b>: com.ibm.mashups.iwidget.Constants.CHANGE_WIDGETMODE<br/>
    * <b>Value</b>:"com.ibm.mashups.iwidget.changeWidgetMode"<br/>
    * <b>Payload</b>: JSON object: {id:"",newMode:"",parentNode:<DOMNode>}<br/>
    * @type String
    * @ibm-api
    */
	CHANGE_WIDGETMODE: "com.ibm.mashups.iwidget.changewidgetmode",
	/**
    *  Enabler would subscribe WIDGET_WINDOWSTATECHANGED event when iwidget has been switched from one window state to another another. <br/>
    * <b>Event</b>: com.ibm.mashups.iwidget.Constants.WIDGET_WINDOWSTATECHANGED<br/>
    * <b>Value</b>:"com.ibm.mashups.iwidget.widgetwindowstatechanged"<br/>
    * <b>Payload</b>: JSON object: {id:"",oldWindowState:"",newWindowState:""}<br/>
    * @type String
    * @ibm-api
    */
	WIDGET_WINDOWSTATECHANGED: "com.ibm.mashups.iwidget.widgetwindowstatechanged",
	/**
	*  Enabler would publish this event when widget is tried to change window state.<br/>
	*  <b>Event</b>: com.ibm.mashups.iwidget.Constants.CHANGE_WIDGETWINDOWSTATE<br/>
    * <b>Value</b>:"com.ibm.mashups.iwidget.changeWidgetWindowState"<br/>
    * <b>Payload</b>: JSON object: {id:"",newWindowState:"",oldWindowState:""}<br/>
    * @type String
    * @ibm-api
    */
	CHANGE_WIDGETWINDOWSTATE: "com.ibm.mashups.iwidget.changewidgetwindowstate",
  /**
   * Event that will be published when navigation state is committed.
   * <b>Event</b>: com.ibm.mashups.iwidget.Constants.NAVSTATE_UPDATED<br/>
   * <b>Value</b>:"com.ibm.mashups.enabler.model.state.onNavStateUpdated"<br/>
   * For example: <br/>
   * An widget could subscribe to this event by using following SPI:<br/>
   * var eventService = com.ibm.mashups.services.ServiceManager.getService("eventService");<br/>
   * eventService.subscribeEvent("com.ibm.mashups.enabler.model.state.onNavStateUpdated",scope,"mycallbackfn");<br/>
   * In the callback function, an widget should use Accessor api to get the navstate they're interested </br>
   * Following example use PageAccessor as an example<br/>
   * 	var pageAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getPageAccessor(navigationStateModel);<br/>
   *	var pageId = pageAccessor.getPageID();		<br/>
   * @type String
   */
	NAVSTATE_UPDATED:"com.ibm.mashups.enabler.model.state.onNavStateUpdated"

});

com.ibm.mashups.iwidget.Constants = new com.ibm.mashups.iwidget.Constants();

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.iEvents_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.iEvents_API"] = true;
dojo.provide("com.ibm.mashups.iwidget.iEvents_API");
dojo.provide("com.ibm.mashups.iwidget.iEvents");

/**
 * This interface defines methods that's  used for event distribution and event management. Events service is accessible by using <b>"this.iContext"</b><p/>
 *  &nbsp;&nbsp;&nbsp; <code>this.iContext.iEvents</code><p/>
 *  To distribute an event:<p/>
 *  &nbsp;&nbsp;&nbsp; <code>this.iContext.iEvents.fireEvent("eventName");</code><p/>
 *
 * @ibm-api
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.iEvents",null,
{	/**
            * @private
            */
    constructor:function () {

    },
/**
This method informs the iContext to distribute an event with proper payload and payload type
@param{String} eventName name of the event that needs to be distributed.Must not be <code>null</code>.
@param{String} payloadType optional,type of the payload.
@param{object} payload optional,object of the payload that needs to be distributed together with the event
@type void
*/
    fireEvent:function(/*String*/eventName,/*String*/payloadType,/*object*/payload){
    },
/**
This method simply creates a new event definition or updates an existing event if the name already exists. <br/>
It returns true if new event is created successfully or existing event is updated successfully. It returns false if it fails to create new event or update existing event.<br/>
@param{com.ibm.mashups.iwidget.IEventDescription} eventDesc IEventDescription object. Must not be <code>null</code>.
@type Boolean
@returns{Boolean} returns true if new event is created successfully or existing event is updated successfully. It returns false if it fails to create new event or update existing event.
*/
    setEvent:function(/* iEventDescription*/ eventDesc){
	},
/**
Using this method will potentially allow optimizations to occur within the iContext. The returned boolean <br/>
indicates whether or not the request added all the described events to the iwidgets. <br/>
@param{com.ibm.mashups.iwidget.IEventDescription[]} eventDesc  array of IEventDescription object. Must not be <code>null</code>.
@type Boolean
@returns{Boolean} returns true if all the events are created successfully or existing events are updated successfully. It returns false if not all events are processed successfully.
*/
    setEvents:function(/* iEventDescription[]*/ eventDescs){
	},
/**
This method removes an existing event description.It returns true if event is removed successfully or event doesn't exist, otherwise it returns false. <br/>
@param{String} eventName event name. Must not be <code>null</code>.
@type Boolean
@returns{Boolean} returns true if event is removed successfully or event doesn't exist, otherwise it returns false.
*/
   removeEvent:function(/*String*/ eventName){
   },
/**
This method removes specified events.It returns true if all the events are removed successfully , otherwise it returns false. <br/>
@param{String[]} eventName event name. Must not be <code>null</code>.
@type Boolean
@returns{Boolean} returns true if all the events are removed successfully, otherwise it returns false.
*/
   removeEvents:function(/*String[]*/ eventNames){
   },
/**
The query method which takes a javascript object as condition, it returns a list of event descriptions which matches the given condition. <br/>
The scope of the events is limited to this iwidget instance. The returning result need to match all the conditions that's given. <br/>
For exampe, if a condition object looks like this: {type:'text', isHandled:true}<br/>
This method will return all the handled event description whose payload is text.<br/>
If no condition is provided, this method will return all the events. It returns null if no event is found for a given condition.Only predefined fields or non localized attributes should be used to define condition.
@param{Object} condition  JSON object that contains the condition. Must not be <code>null</code>.
@type com.ibm.mashups.iwidget.IEventDescription
@returns{com.ibm.mashups.iwidget.IEventDescription} returns an array of event description that matches the condition. It returns null if no event is found for a given condition.
*/
   getEvents:function(/*Object*/ condition){
   },
/**
This method allows to create a new IEventDescription object. All the data should be passed in as a JSON object.<br/>
Following rules applied to the JSON object:<br/>
1. Predefined fields: name,type,isHandled,isPublished,lang,handlingFn<br/>
2. Localized attributes: please see sample below<br/>
3. Non-localized attributes: please see sample below<br/>
4. Lotus Mashups provides a feature to allow a widget to register a private event so this event will not be exposed to other iwidgets by the wiring interface<br/>
&nbsp;&nbsp;&nbsp;private attribute is used to mark an event to be a private event. please see sample below<br/>
<code>
 &nbsp;&nbsp;&nbsp;var obj = {name:"sendData",  type:"text", isHandled:"true", lang:"en", handlingFn:"onSendData", <br/>
 &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;localizedAttributes:{  <br/>
  &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;"en":{"title":"mytitle_en","description":"mydescription_en"},<br/>
  &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;"fr":{"title":"mytitle_fr","description":"mydescription_fr"}  <br/>
  &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;} ,      <br/>
  &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;attributes:{  namespace:"com.ibm.mashups", onRemoveWire:"handleRemoveWire",private:"true"} <br/>
 &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;  };<br/>
 &nbsp;&nbsp;&nbsp;var event = this.iContext.iEvents.createEventDescription(obj);<br/>
 &nbsp;&nbsp;&nbsp;this.iContext.iEvents.setEvent(event);<br/>
</code>
@param{Object} object  JSON object that contains all the data to create an IEventDescription. Must not be <code>null</code>.
@type com.ibm.mashups.iwidget.IEventDescription
@returns{com.ibm.mashups.iwidget.IEventDescription} returns an  IEventDescription . It returns null if it fail to create the iEventDescription.
*/
  createEventDescription:function(/* Object */object){
  }

});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.IEvent_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.IEvent_API"] = true;
dojo.provide("com.ibm.mashups.iwidget.IEvent_API");
dojo.provide("com.ibm.mashups.iwidget.IEvent");

/**
 * it carries various pieces of information when an event flows at runtime
 *
 * @ibm-api
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.IEvent", null, {
    constructor: function() {
        /**
         * @private
         */
    },
    /**
     The name of the event.
     @type String
     */
    name:/*String*/ "",
    /**
     The type of any payload. If this is set to null, no information is being provided.
     @type String
     */
    type:/*String*/ "",
    /**
     The data, if any, being provided by the source of the event.
     @type Object
     */
    payload:/*object*/ null,
    /**
     The iWidget supplied id for the source iWidget.
     @type String
     */
    source:/*String*/ ""
});


}

if(!dojo._hasResource["com.ibm.mashups.iwidget.IEvent"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.IEvent"] = true;
dojo.provide("com.ibm.mashups.iwidget.IEvent");





}

if(!dojo._hasResource["com.ibm.mm.iwidget.IEventImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.IEventImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.IEventImpl");



dojo.declare("com.ibm.mm.iwidget.IEventImpl", com.ibm.mashups.iwidget.IEvent, {

    constructor: function(/*String*/name,/*String*/ type,/*Object*/ payload,/*String*/ source) {
        this.name = name;

        if (typeof type != "undefined") {
            this.type = type;
        }
        else {
            this.type = null;
        }

        if (typeof payload != "undefined") {
            this.payload = payload;
        }
        else {
            this.payload = null;
        }

        if (typeof source != "undefined") {
            this.source = source;
        }
        else {
            this.source = null;
        }
        this.source = source;
    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextIEventsImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextIEventsImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.icontext.IContextIEventsImpl");






dojo.declare("com.ibm.mm.iwidget.icontext.IContextIEventsImpl", com.ibm.mashups.iwidget.iEvents, {
    constructor: function(wrapper) {
        this.widget = wrapper;
        this.id = wrapper.id;
        this.svc = com.ibm.mashups.services.ServiceManager.getService("eventService");
		this.timer = null;
		this.timerEventQ = [];
		this.allTargetWidgetsLoaded = false;
    },
    createEventDescription: function(/*json*/object) {
        return new com.ibm.mm.iwidget.IEventDescriptionImpl(object);
    },
    getEvents: function(condition) {
        //always return a data copy of each iEventDescription
        //return null if no events is found
        var eventModel = this.widget._getPublicEvents(); //get the internal eventModel
        var events = eventModel.getEvents(condition);
        //now build a copy of iEventDescription
        if (!events) {
            return null;
        }
        var arr = [];
        for (var i in events) {
            if (Object.prototype.hasOwnProperty.call(events,i)) {
                arr.push(events[i].clone());
            }
        }
        return arr;
    },
    setEvent: function(eventDesc) {
        //create/update event
        //return true if event is successful

        // verify first whether the event is the same and no update is required
        var eventModel = this.widget._getPublicEvents(); //get the internal eventModel
        var rc = eventModel.eventExists(eventDesc.name);
        var updateRequired = false;
        if (rc) {
            updateRequired = eventModel.isUpdateEventRequired(eventDesc);
        }
        else {
            updateRequired = true;
        }
        if (updateRequired) {
            var cs = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME);
            if (cs) {
                cs.switchToModifiablePersistenceMode(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS);
            }
        }

        eventModel = this.widget._getPublicEvents(); //get the internal eventModel
        rc = eventModel.eventExists(eventDesc.name);
        if (rc) {
            if (this.widget._inIframe()) {
                this.svc._publishEvent(this.svc.WIDGETEVENT_PREFIX + "_stub_" + this.id, {
                    "scope": "eventmodel",
                    "methodname": "updateEvent",
                    "params": [eventDesc.toJson()]
                }, this.id);
            }
            rc = eventModel.updateEvent(eventDesc);
        }
        else {
            if (this.widget._inIframe()) {
                this.svc._publishEvent(this.svc.WIDGETEVENT_PREFIX + "_stub_" + this.id, {
                    "scope": "eventmodel",
                    "methodname": "createEvent",
                    "params": [eventDesc.toJson()] //turn iEventDescription into an json object
                }, this.id);
            }
            rc = eventModel.createEvent(eventDesc);
        }
        return rc;
    },
    removeEvent: function(eventName) {
        var cs = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME);
        if (cs) {
            cs.switchToModifiablePersistenceMode(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS);
        }

        //remove event
        //return true upon successful, if event doesn't exist or for other reason event can't be deleted, return false;
        if (this.widget._inIframe()) {
            this.svc._publishEvent(this.svc.WIDGETEVENT_PREFIX + "_stub_" + this.id, {
                "scope": "eventmodel",
                "methodname": "removeEvent",
                "params": [eventName]
            }, this.id);
        }
        var eventModel = this.widget._getPublicEvents(); //get the internal eventModel
        var rc = eventModel.removeEvent(eventName);
        return rc;
    },
    publishEvent: function(/*String*/eventName, payload, payloadType) {
        //internal, deprecated, todo remove
        return this.fireEvent(eventName, payloadType, payload);
    },
    fireEvent: function(/*String*/eventName, payloadType, payload) {
        // 18152: Make sure all target widgets are loaded before firing event. Since wires are stored with the
        // target widgets, the source widget could fireEvent before the target widgets, and therefore the wires,
        // are loaded. By waiting until the target widgets are loaded, we ensure the needed wires are loaded.
        if (this.allTargetWidgetsLoaded) {
        	this._fireEventFinish(eventName,payloadType,payload);
        } else {
        	// Multiple fireEvents could come in while the asynchronous this.timer is processing, so queue up all
        	// fireEvents that come in so they can all get processed in _fireEventContinue in the order received.
        	this.timerEventQ.push({"eventName":eventName,"payloadType":payloadType,"payload":payload});
        	if (!this.timer) {
        		var widgetModel = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel();
	            var all_wires = dojo.query("."+this.widget.ns+"ReceivedEvent", this.widget.rootElement);
	            var target_widgets = [];
	            for (var i = 0; i < all_wires.length; i++) {
	            	var sourceEvent = dojo.query("."+this.widget.ns+"SourceEvent", all_wires[i])[0];
	            	if (sourceEvent) {
	            		var href = sourceEvent.getAttribute("href");
	            		if (href.indexOf(this.widget.id) != -1) {
	            			var target_widget = widgetModel.find(all_wires[i].parentNode.id);
	            			if (target_widget) {
	            				target_widgets.push(target_widget);
	            			}
	            		}
	            	}
	            }
	            this.timer_tries = 0;
	            this.timer = setInterval(dojo.hitch(this, "_fireEventContinue", target_widgets), 5);
        	}
        }
     },
     _fireEventContinue:function(target_widgets){
        for (var i = 0; i < target_widgets.length; i++) {
        	if (!target_widgets[i].isLoaded() && (this.timer_tries < 20)) {  // should never reach 20, but just in case
        		this.timer_tries++;
        		return;
        	}
        }
        clearInterval(this.timer);
        this.timer_tries = 0;
        while (this.timerEventQ.length > 0) {
        	var event = this.timerEventQ.shift(); // first in, first out
        	this._fireEventFinish(event.eventName,event.payloadType,event.payload);
        }
        this.allTargetWidgetsLoaded = true;
        this.timer = null;
     },
      _fireEventFinish:function(/*String*/eventName,payloadType,payload){
        //event description here...
        var eventModel = this.widget._getPublicEvents();
        //var isHandled = widgetWrapper.handleEvent(eventName,aEvent);
        //handle internally only if it's not a handled event
        var isHandledEvent = false;
        var temp;
        if (eventModel) {
            temp = eventModel.find(eventName);
            //assign payload type
            if (temp) {
                payloadType = temp.type;
            }
            if (temp && temp.handlingFn) {
                isHandledEvent = true;
            }
        }
        var aEvent = new com.ibm.mm.iwidget.IEventImpl(eventName, payloadType, payload, null);
        if (!isHandledEvent) {
            this.widget.handleEvent(aEvent);
        }

        //publish wire if it's a published event
        if (eventModel) {
            temp = eventModel.find(eventName);
            if (temp && temp.isPublished) {
                this.svc.publishWire(this.id, eventName, payload, payloadType);
            }
        }
    },
    setEvents: function(eventDescs) {
        var eventModel = this.widget._getPublicEvents();
        if (this.widget._inIframe()) {
            var arr = [];
            for (var i = 0; i < eventDescs.length; i++) {
                arr.push(eventDescs[i].toJson());
            }
            this.svc._publishEvent(this.svc.WIDGETEVENT_PREFIX + "_stub_" + this.id, {
                "scope": "eventmodel",
                "methodname": "setEvents",
                "params": [arr]
            }, this.id);
        }
        rc = eventModel.setEvents(eventDescs);
        return rc;
    },
    removeEvents: function(eventNames) {
        //remove event
        //return true upon successful, if event doesn't exist or for other reason event can't be deleted, return false;
        if (this.widget._inIframe()) {
            this.svc._publishEvent(this.svc.WIDGETEVENT_PREFIX + "_stub_" + this.id, {
                "scope": "eventmodel",
                "methodname": "removeEvents",
                "params": [eventNames]
            }, this.id);
        }
        var eventModel = this.widget._getPublicEvents(); //get the internal eventModel
        var rc = eventModel.removeEvents(eventNames);
        return rc;
    }
});


}

if(!dojo._hasResource["com.ibm.mashups.iwidget.iEvents"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.iEvents"] = true;
dojo.provide("com.ibm.mashups.iwidget.iEvents");





}

if(!dojo._hasResource["com.ibm.mashups.iwidget.io_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.io_API"] = true;
dojo.provide("com.ibm.mashups.iwidget.io_API");
dojo.provide("com.ibm.mashups.iwidget.io");

/**
 * This interface defines support the iContext is supplying regarding IO operations.<p/>
 *  &nbsp;&nbsp;&nbsp; <code>this.iContext.io.rewriteURI(aUri);</code><p/>
 *
 * @ibm-api
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.io", null, {
    /**
     * @private
     */
    constructor: function() {

    },
    /**
     This object wraps the native XMLHttpRequest support to provide a consistent page in the face of asynchronous updates, especially those which may cause server-side coordination between the server-side components related to multiple iWidgets on the page.
     @type XMLHttpRequest
     @returns{XMLHttpRequest} returns  native XMLHttpRequest object.
     */
    XMLHttpRequest: function() {
    },

    /**
     This method takes a URI as a parameter and returns a URI which the browser can resolve for accessing the supplied URI.
     Examples of usage include resolving a relative URI against the source of the iWidget's definition and resolving other URIs to address any intermediate
     gateways, such as a proxy server. <p/>
     &nbsp;&nbsp;&nbsp;Sample usage that resolves URI to address a proxy server ,assume url to proxy server is "/mum/proxy".<br/>
     <code>
     &nbsp;&nbsp;&nbsp; var aUri = "http://yourco.com/mytest.js"; <br/>
     &nbsp;&nbsp;&nbsp; var rc = this.iContext.io.rewriteURI(aUri); <br/>
     </code>
     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the result will be "/mum/proxy/http/yourco.com/mytest.js"<br/>
     <br/>
     &nbsp;&nbsp;&nbsp;Sample usage that resolves a relative URI against the source of the iWidget's deinfition<br/>
     &nbsp;&nbsp;&nbsp; Assume iwidget is included on a page as follows:<br/>
     <code>
     &nbsp;&nbsp;&nbsp; &lt;span id="yourcoWidget" class="iw-iWidget"&gt;&lt;a class="iw-Definition" href="/mm/widget-catalog/yourcoWidget.xml"&gt;&lt;/a&gt;&lt;/span&gt;<br/><br/>
     &nbsp;&nbsp;&nbsp; var aUri = "mytest.js"; <br/>
     &nbsp;&nbsp;&nbsp; var rc = this.iContext.io.rewriteURI(aUri);  <br/>
     </code>
     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the result will be "/mm/widget-catalog/mytest.js" <br/>
     <br/>
     &nbsp;&nbsp;&nbsp;Sample usage that resolves a relative URI against the source of the iWidget's deinfition for an image resource.<br/>
     &nbsp;&nbsp;&nbsp; Assume iwidget is included on a page as follows:<br/>
     <code>
     &nbsp;&nbsp;&nbsp; &lt;span id="yourcoWidget" class="iw-iWidget"&gt;&lt;a class="iw-Definition" href="http://yourco.com/mm/widget-catalog/yourcoWidget.xml"&gt;&lt;/a&gt;&lt;/span&gt;<br/><br/>
     </code>
     &nbsp;&nbsp;&nbsp;the url for the img resource  of following code will be "http://yourco.com/mm/widget-catalog/mytest.gif" <br/>
     <code>
     &nbsp;&nbsp;&nbsp; var aUri = "mytest.gif"; <br/>
     &nbsp;&nbsp;&nbsp; var returnUri = this.iContext.io.rewriteURI(aUri,false);  <br/>
     &nbsp;&nbsp;&nbsp; var img = dojo.byId(id); <br/>
     &nbsp;&nbsp;&nbsp;  img.src = returnUri;<br/>
     </code>
     @param{String} uri URI that needs to be resolved. Must not be <code>null</code>.
     @param{Boolean} isXhr optional,boolean indicating the url is used as xhr. If no value is provided, the default is true.
     @type String
     @returns{String} return a URI which the browser can resolve for accessing the supplied URI. Must not be <code>null</code>.
     */
    rewriteURI: function(/*String*/uri,/*Boolean*/ isXhr) {
        return null;
    },
	/**
     This convenience method creates a new XMLHttpRequest and send the request with all supplied arguments on the XMLHttpRequest. <br/>
     The supported fields within the arguments object include: <br/>
     <code><br/>
     {<br/>
	   &nbsp;&nbsp;&nbsp; "requestVerb": {"get" | "post" | "put" | "delete"}, <br/>
	   &nbsp;&nbsp;&nbsp;"url": {url},<br/>
       &nbsp;&nbsp;&nbsp;"handleAs": {handleAs},<br/>
       &nbsp;&nbsp;&nbsp;"sync": {boolean},<br/>
       &nbsp;&nbsp;&nbsp;"preventCache": {boolean},<br/>
       &nbsp;&nbsp;&nbsp;"content": {content},<br/>
       &nbsp;&nbsp;&nbsp;"headers": {headers},<br/>
       &nbsp;&nbsp;&nbsp;"timeout": {int},<br/>
	   &nbsp;&nbsp;&nbsp;"user": {user},<br/>
       &nbsp;&nbsp;&nbsp;"password": {password},<br/>
       &nbsp;&nbsp;&nbsp;"form": {form},<br/>
       &nbsp;&nbsp;&nbsp;"msgData": {msgData},<br/>
       &nbsp;&nbsp;&nbsp;"load": {load},<br/>
       &nbsp;&nbsp;&nbsp;"error": {error},<br/>
       &nbsp;&nbsp;&nbsp;"handle": {handle}<br/>
	 }<br/>
	 </code><br/>
     @param{Object} args supported properties as listed above.
     @type void
     */
	xhrReq:function(/*Object*/ args){
		return;
	}

});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextIOImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextIOImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.icontext.IContextIOImpl");







dojo.declare("com.ibm.mm.iwidget.icontext.IContextIOImpl", com.ibm.mashups.iwidget.io, {
    constructor: function(wrapper) {
        this.id = wrapper.id;
        this.widget = wrapper;
    },
    XMLHttpRequest: function() {
        return dojo._xhrObj();
    },
    rewriteURI: function(/*String*/uri, isXhr) {
        var returnUri = this.widget._rewriteURI(uri, isXhr);
        return returnUri;
    },
    getWebAppRootPath: function() {
		//not all the widgets has context path, following are the examples:
		//a. "http://host:test/accuweather" --> absolute path
		//b. "/accuweather" --> full path
		if (this.rootPath) {
			return this.rootPath;
		}
	    var rawUri = this.widget.getIWidgetInstance().widgetXMLUrl;
		rawUri = this.widget._getRawBaseUri(rawUri); // resolve end point
		rawUri = this.widget._getResolvedPocUri(rawUri); //resolve Poc Uri

		var returnUri = null;
        if (rawUri && rawUri.indexOf("/")===0){
			var temp = rawUri.substring(1);
			if (temp.indexOf("/")>0) {
				returnUri = "/"+temp.substring(0,temp.indexOf("/"));
			}else{
				returnUri = rawUri;
			}
		}
		if (returnUri) {
			this.rootPath = returnUri;
			return returnUri;
		}
        if (rawUri && rawUri.indexOf("://") > 0) {
               var parts = rawUri.split("/");
               if (parts.length >= 4) {
                        returnUri = parts[0] + "//" + parts[2] + "/" + parts[3];
               }
        }
        if (returnUri) {
			this.rootPath = returnUri;
			return returnUri;
		}
		return null;
    },
    request: function(requestVerb, uri, callbackFn, message,/* [{headerName, value}] */ requestHeader) {
        //Sends an HTTP request with the given method
        //The method argument should be uppercase.
        //sample callback Fn
        /*function callbackFunction(){
         if (this.readyState != 4) return;
         var response = this.responseText;
         }
         */
        var xhr = dojo._xhrObj();
        var realUri = this.rewriteURI(uri);

        var async = false;
        if (callbackFn) {
            xhr.onreadystatechange = callbackFn;
            //sets it to asynchronous only if a callbackFn is provided, per xhr spec, user agent should consider default is true if it's omitted
            async = true;
        }
        var method = requestVerb || null;
        if (!requestVerb) {
            method = this.httpmethods.GET;
        }
        if (requestVerb) {
            if (!this.httpmethods[requestVerb]) {
                method = this.httpmethods.GET;
            }
        }

        //user/password    xhr.open(method,realUri,async,user,pwd);
        xhr.open(method, realUri, async);
        //xhr.send();
        //console.debug(method + " " + realUri);

        var contentType = null;
        var _defaultContentType = "application/x-www-form-urlencoded";
        if (requestHeader) {
            //Authors are strongly encouraged to ensure that they have specified the Content-Type header via setRequestHeader() before invoking send() with a non-null data argument.
            for (var i = 0; i < requestHeader.length; i++) {
                var anItem = requestHeader[i];
                var headerName = anItem[headerName];
                var value = anItem[value];
                if (headerName == "Content-Type") {
                    contentType = value;
                }
                else {
                    xhr.setRequestHeader(headerName, value);
                }
            }
        }
        xhr.setRequestHeader("Content-Type", (contentType || _defaultContentType));

        //user/password    xhr.open(method,realUri,async,user,pwd);
        if (method == this.httpmethods.PUT || method == this.httpmethods.POST) {
            if (message) {
                xhr.send(message);
            }
        }
        else {
            xhr.send(null);
        }
        return xhr;
    },
	xhrReq:function(args){
		if (!args) {
			return;
		}
		if (!args.requestVerb || !args.url || !args.handleAs){ return;}

		var requestVerb = args.requestVerb;
		if (requestVerb && !this.requestVerbs[requestVerb]){
			requestVerb = this.requestVerbs.get;
		}

		if (requestVerb && requestVerb == this.requestVerbs.get){
			var obj = args;
			delete obj.requestVerb;
			dojo.xhrGet(obj);
			return;
		}
		if (requestVerb && requestVerb == this.requestVerbs.put){
			var obj1 = args;
			delete obj1.requestVerb;
			if (obj1.msgData){
				obj1.putData = obj1.msgData;
				delete obj1.msgData;
			}
			dojo.xhrPut(obj1);
			return;
		}
		if (requestVerb && requestVerb == this.requestVerbs["delete"]){
			var obj2 = args;
			delete obj2.requestVerb;
			dojo.xhrDelete(obj2);
			return;
		}
		if (requestVerb && requestVerb == this.requestVerbs.post){
			var obj3 = args;
			delete obj3.requestVerb;
			if (obj3.msgData){
				obj3.postData = obj3.msgData;
				delete obj3.msgData;
			}
			dojo.xhrPost(obj3);
			return;
		}

	},
    httpmethods: {
        GET: "GET",
        PUT: "PUT",
        POST: "POST",
        DELETE: "DELETE"
    },
	requestVerbs:{
		get: "get",
        put: "put",
        post: "post",
        "delete": "delete"
	}
});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.io"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.io"] = true;
dojo.provide("com.ibm.mashups.iwidget.io");





}

if(!dojo._hasResource["com.ibm.mashups.iwidget.iContext_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.iContext_API"] = true;
dojo.provide("com.ibm.mashups.iwidget.iContext_API");
dojo.provide("com.ibm.mashups.iwidget.iContext");

/**
 * This interface defines methods that the iWidget can use to interact with the iContext.
 * An iContext instance is created specifically for each iWidget instance and a reference will be set in iWidget encapsulation object.
 * Thus within iWidget encapsulation class, iContext should be referred to by using <b>"this.iContext"</b><p/>
 *  &nbsp;&nbsp;&nbsp; <code>var root = this.iContext.getRootElement();</code><p/>
 *
 * @ibm-api
 */
dojo.declare("com.ibm.mashups.iwidget.iContext", null, {

    /**
     * @private
     */
    constructor: function() {
    },
    /**
     * Defines constants available in iContext.<br/>
     * Constants defined within iContext can be referred as follows:</p>
     *
     *  &nbsp;&nbsp;&nbsp; <code>this.iContext.constants.mode.VIEW</code><br/>
     *  &nbsp;&nbsp;&nbsp; <code>this.iContext.constants.mode.EDIT</code><br/>
     *  &nbsp;&nbsp;&nbsp; <code>this.iContext.constants.mode.PERSONALIZE</code><br/>
     *  &nbsp;&nbsp;&nbsp;<code>this.iContext.constants.mode.HELP</code><br/>
     *  &nbsp;&nbsp;&nbsp;<code>this.iContext.constants.ATTRIBUTES</code><br/>
     *  &nbsp;&nbsp;&nbsp;<code>this.iContext.constants.IDESCRIPTOR</code><br/>
     *  &nbsp;&nbsp;&nbsp;<code>this.iContext.constants.USERPROFILE</code><br/>
     * </code>
     * @type Object
     * @ibm-module iWidget2
     */
    constants: {
        /*@type object*/
        mode: {
            /*@type String*/
            VIEW:/*String*/ "view",//The generated markup fragment(s) should reflect normal interaction with the iWidget
            /*@type String*/
            EDIT:/*String*/ "edit",//The generated markup fragment(s) should reflect iWidget interactions for editing iWidget attributes scoped to this instance of iwidget, but applicable to all users
            /*@type String*/
            PERSONALIZE:/*String*/ "personalize",//The generated markup fragment(s) should reflect iWidget interactions for personalizing iwidget attributes scoped to this instance on the iWidget for this user
            /*@type String*/
            CONFIG:/*String*/ "config",//The generated markup fragment(s) should reflect iWidget interactions for editing iwidget attributes scoped to all instances of the iWidget for all users
            /*@type String*/
            HELP:/*String*/ "help"//The iWidget should generate markup fragment(s) to assist the user with interacting with the iWidget
        },
        event: {
            /*@type String*/
            TITLE:/*String*/ "title",//Name for the Attribute holding event title
            /*@type String*/
            DESCRIPTION:/*String*/ "description"//Name for the Attribute holding event description
        },
        /*@type String*/
        ATTRIBUTES:/*String*/ "attributes", //Name for the ManagedItemSet holding the customization attributes.
        /*@type String*/
        IDESCRIPTOR:/*String*/ "idescriptor", //Name for the ManagedItemSet holding the items describing the iWidget
        /*@type String*/
        USERPROFILE:/*String*/ "userprofile", //Name for the ManagedItemSet holding data about the user
        /*@type Object*/
        keys: {
            /*@type int*/
            SHIFT:/*int*/ 1,
            /*@type int*/
            ALT:/*int*/ 2,
            /*@type int*/
            CTRL:/*int*/ 4,
            /*@type int*/
            META:/*int*/ 8,
            /*@type int*/
            CAPSLOCK:/*int*/ 16
        },
        windowstate: {
            /*@type String*/
            NORMAL:/*String*/ "normal",
            /*@type String*/
            MINIMIZE:/*String*/ "minimize",
            /*@type String*/
            MAXIMIZE:/*String*/ "maximize"
        },
        status: {
            /*@type int*/
            SUCCESS:/*int*/ 200,
            /*@type int*/
            TIMEOUT:/*int*/ 408,
            /*@type int*/
            NOTFOUND:/*int*/ 404,
            /*@type int*/
            INTERROR:/*int*/ 500,
            /*@type int*/
            OTHER:/*int*/ 303
        },
        changeType: {
            /*@type String*/
            CHANGEDVALUE:/*String*/ "changedValue",
            /*@type String*/
            NEWITEM:/*String*/ "newItem",
            /*@type String*/
            REMOVEDITEM:/*String*/ "removedItem"

        }
    },
	/**
     * This method returns the unique identifier for this instance of the iWidget in the current evironment (usually a web page).
     * @type String
     * @return{String}  widgetId unique identifier of the iWidget. return <code>null</code> if element is not available.
     * @ibm-module iWidget2
     */
    getWidgetId: function() {
        return null;
    },
    /**
     * Returns the iContext supplied element containing the content for the current mode of the iwidget such that the iWidget can easily do things such as search its own markup.
     * @type DOMElement
     * @return{DOMElement}  rootElement of the iWidget. return <code>null</code> if element is not available.
     * @ibm-module iWidget2
     */
    getRootElement: function() {
        return null;
    },
    /**
     * This method provides the same semantics as the DOM method with the same name, but restricts the search to the iWidget's markup rather than the entire page
     * @param{String} id  element id. Must not be <code>null</code>.
     * @param{DOMElement} root  optional DOMElement to define a search scope, it will search in the scope of current active mode if root is not provided.
     * @type DOMElement
     * @return{DOMElement} return the element, or <code>null</code> if element is not found.
     * @ibm-module iWidget2
     */
    getElementById: function(/*String*/id,/*DOMNode*/ root) {
        return null;
    },
    /**
     * This method returns the ManagedItemSet that provides access to the iWidget's customization attributes.
     * If there is no ManagedItemSet  related to the iWidget's customization attributes, this method MUST create an empty set and return it.
     * @type com.ibm.mashups.iwidget.itemset.ManagedItemSet
     * @return{com.ibm.mashups.iwidget.itemset.ManagedItemSet } return the ManagedItemSet or empty ManagedItemSet if no customization attributes is found.
     * @ibm-module iWidget2
     */
    getiWidgetAttributes: function() {
        return {};
    },
    /**
     * This method returns an ItemSet corresponding to the requested name. If it does not already exist, an ItemSet will be created and associated with the supplied name.
     * @param{String}name name of ItemSet. Must not be <code>null</code>.
     * @param{Boolean}isPrivate deprecated,please use getShareableItemSet()if it's a ShareableItemSet.
     * @type com.ibm.mashups.iwidget.itemset.ItemSet
     * @return{com.ibm.mashups.iwidget.itemset.ItemSet} return the requested ItemSet or <code> null</code> if access is denied.
     * @ibm-module iWidget2
     */
    getItemSet: function(/*String*/name,/*Boolean*/ isPrivate) {
        return null;
    },
	  /**
     * This method returns an ShareableItemSet corresponding to the requested name. If it does not already exist, an ItemSet will be created and associated with the supplied name.
     * @param{String}name name of ItemSet. Must not be <code>null</code>.
     * @type com.ibm.mashups.iwidget.itemset.ItemSet
     * @return{com.ibm.mashups.iwidget.itemset.ShareableItemSet} return the requested ItemSet or <code> null</code> if access is denied.
     * @ibm-module iWidget2
     */
    getShareableItemSet: function(/*String*/name) {
        return null;
    },
    /**
     * Provides means for iWidget to declare dependency on set of shared resource support dynamic loads in asynchronous manner. JS and CSS resources are supported.
     * @param{String} globalid  globalid of the Item that needs to be loaded. Must not be <code>null</code>.
     * @param{String}version  optional
     * @param{String}uri uri of the resource. Must not be <code>null</code>.
     * @param{Object}cb optional
     * @param{String}mimeType  optional
     * @type void
     * @ibm-module iWidget2
     */
    requires: function(/*String*/globalid,/*String*/ version,/*String*/ uri,/*function*/ cb,/*String*/ mimeType) {
    },
    /**
     * This method returns an instance of type Object which was initialized prior to the loading of the iWidget (either as a generic Object or an instance of the encapsulation Object ) . Its purpose is to support proper
     * encapsulation of the iWidget's assets (variables and methods) such that multiple instances of the iWidget can be loaded into a
     * single page's DOM without stepping on each other.
     * So iWidget resources can refer to any functions that's defined within iWidget encapsulation object by using iContext.iScope().fn();
     * @type Object
     * @return{Object} return an instance of the encapsulation class or return a generic object
     * @ibm-module iWidget2
     */
    iScope: function() {
        return null;
    },
    /**
     * This method requests the iContext to process the markup such that it can be inserted into the iWidget's markup and properly interact with the page.
     * (i.e. all the iContext reference in the markup needs to be properly namespaced). Where, when and how the markup is inserted into the page
     * is the responsibility of the iWidget.
     * @param{String}markup  markupString that needs to be processed. Must not be <code>null</code>.
     * @type String
     * @return  On success this method MUST return the processed markup while on failure it MUST return null
     * @ibm-module iWidget2
     */
    processMarkup: function(/*String*/markup) {
        return null;
    },
    /**
     * This method requests the iContext to process the subtree under the supplied node for the purpose of resolving and instantiating any referenced iWidgets.
     * @param{DOMNode}root root element of the subtree. Must not be <code>null</code>.
     * @type void
     * @ibm-module iWidget2
     */
    processiWidgets: function(/*DOMNode*/root) {
        //summary: This method requests the iContext to process the subtree under the supplied node for the purpose of resolving and instantiating any referenced iWidgets.
        //root: root element of the subtree
    },
    /**
     * This method returns an array of Elements within the iWidget's markup which have the supplied value as one of those specified by the Element's "class" attribute.
     * @param{String}classname  name of class attribute. Must not be <code>null</code>.
     * @param{DOMElement}root root element of the subtree. Must not be <code>null</code>
     * @type DOMElement[]
     * @return{DOMElement[]} return an array of elements
     * @ibm-module iWidget2
     */
    getElementByClass: function(/*String*/classname,/*DOMElement*/ root) {
        return null;
    },
    /**
     * This method returns the ManagedItemSet that provides access to the user's profile data.
     * @type com.ibm.mashups.iwidget.itemset.ManagedItemSet
     * @return{com.ibm.mashups.iwidget.itemset.ManagedItemSet } if there is no ManagedItemSet related to the user's profile, this method creates an empty set and returns it. If access to the user's profile is denied, this method returns null.
     * @ibm-module iWidget
     */
    getUserProfile: function() {
        return null;
    },
    /**
     * This method returns the ManagedItemSet that provides access to iWidget's descriptive items.
     * @type com.ibm.mashups.iwidget.itemset.ManagedItemSet
     * @return {com.ibm.mashups.iwidget.itemset.ManagedItemSet } If there is no ManagedItemSet  related to the iWidget's descriptive items this method creates an empty set and returns it..
     * @ibm-module iWidget2
ja     */
    getiDescriptor: function() {
        return null;
    },
    /**
     * This object provides access to io service. io service is accessible by using "this.iContext.io".<p/>
     * @type com.ibm.mashups.iwidget.io
     * @ibm-module iWidget2
     */
    io: {},
    /**
     * This object provides access to events service. event service is accessible by using "this.iContext.iEvents".<p/>
     * @type com.ibm.mashups.iwidget.iEvents
     * @ibm-module iWidget
     */
    iEvents: {}
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextDefaultImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextDefaultImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.icontext.IContextDefaultImpl");






dojo.declare("com.ibm.mm.iwidget.icontext.IContextDefaultImpl", com.ibm.mashups.iwidget.iContext, {

    constructor: function(wrapper){
        //information accessible from iwidget
        this.widgetwrapper = wrapper;
        this.widgetId = wrapper.id;
        this.scope = {};

        //todo: root is associated with mode
        //this.rootElement = wrapper.rootElement;
        //keep this.rootElement and this.ns since this will break some widget code
        this.rootElement = dojo.byId(this.widgetId);
        this.ns = this.rootElement.className.substr(0, 3);
        this._initEvents();
        this._initIO();
        this._initMMExtension();

    },
    _destroy: function(){
        // # 17713, leak for one iw-iWidget DIV
        if (this.rootElement) {
            this.rootElement = null;
        }
    },
    getWidgetId: function(){
        if (this.widgetId) {
            return this.widgetId;
        }
        return null;
    },
    _initEvents: function(){
        this.iEvents = null;
    },
    _initMMExtension: function(){
        this._mm = null;
    },
    getRootElement: function(){
        //summary: returns the root element of the iWidget such that iWidget can easily do things such as
        // searching its own markup. RootElement can also be a convenient place to place items which iWidget wishes
        // to access later.
        //we generate it dynamically so it can work for sandboxed iwidget
        return dojo.byId(this.widgetId);
    },
    getElementById: function(/*String*/id, root){

        //summary: this method provides the same semantics as the DOM method by the same name with the distinction that
        //  this method will restrict the search to the iWidget's markup rather than entire page
        if (!root) {
            root = this._getContentRoot();
        }

        //following dojo.query will query by id however it doesn't work, so use our legacy stuff instead
        /*
         var nodeList = dojo.query("#"+id,root);
         if (nodeList.length >= 1){
         return nodeList[0];
         }
         return null;
         */
        var element = [];
        var rc = com.ibm.mm.iwidget.Utils.findElementByAttribute("id", id, root, element, false);

        if (rc) {
            return element[0];
        }
        else {
            return null;
        }
    },
    getiWidgetAttributes: function(){
        //Summary: returns an ManagedItemSet which provides access to the iWidget's customization attributes.
        //          The returned ManagedItemSet will be the same as getItemSet(iContext.constants.itemset.ATTRIBUTES).
        //          returns empty set if there's no ItemSet.
        var attrs = this.widgetwrapper.getAttributes();
        return attrs;
    },
    getItemSet: function(/*String*/name,/*boolean*/ isPrivate){

        if (typeof name == "undefined" || name === null) {
            return null;
        }
        if (name == iwConstants.ATTRIBUTES) {
            return this.getiWidgetAttributes();
        }
        if (name == iwConstants.USERPROFILE) {
            return this.getUserProfile();
        }
        if (name == iwConstants.IDESCRIPTOR) {
            return this.getiDescriptor();
        }

        var itemSet = this.widgetwrapper.getWidgetItemSet(name);
        return itemSet;
    },
    iScope: function(){
        return this.scope;
    },
    processMarkup: function(/*string*/markup){
        //return null upon failure
        var oldMarkup = markup.replace(/_IWID_/g, "_" + this.widgetId + "_");
        var finalMarkup = oldMarkup.replace(/iContext(?=\.|\s|\(|\))/g, "_" + this.widgetId + "_iContext");
        return finalMarkup;
    },
    getElementByClass: function(classname, root){
        if (!root) {
            root = this._getContentRoot();
        }

        //todo: use dojo.query
        var nodeList = dojo.query("." + classname, root);
        if (typeof nodeList != "undefined" && nodeList !== null) {
            if (nodeList.length === 0) {
                return null;
            }
            else {
                var elements = [];
                for (var i = 0; i < nodeList.length; i++) {
                    elements.push(nodeList[i]);
                }
                return elements;
            }
        }
        return null;
    },
    getWidgetXMLPath: function(){
        var url = this.widgetwrapper.getIWidgetInstance().widgetXMLUrl;
        var queryStart = url.indexOf("?");
        if (0 < queryStart) {
            url = url.substring(0, queryStart);
        }

        var url2 = com.ibm.mm.enabler.EndpointUtils.checkForEndpoints(url);
        if (url2) {
            url = url2;
        }

        return url;
    },
    _getWidgetBaseUri: function(){

        var widgetBaseUri = this.widgetwrapper.getIWidgetInstance().widgetXMLUrl;
        var queryStart = widgetBaseUri.indexOf("?");
        if (0 < queryStart) {
            widgetBaseUri = widgetBaseUri.substring(0, queryStart);
        }

        return widgetBaseUri.substring(0, widgetBaseUri.lastIndexOf("/") + 1);
    },
    _getContentRoot: function(){

        var contentRoot = this.getRootElement();
        var currentMode = this.widgetwrapper.currentMode;
        if (!currentMode) {
            currentMode = "view";
        }
        var currentWindow = this.widgetwrapper.windowManager[currentMode];
        if (currentWindow) {
            var temp = currentWindow.root;
            if (temp) {
                contentRoot = temp;
            }
        }

        return contentRoot;
    },
    getiDescriptor: function(){
        var iDescriptor = this.widgetwrapper.getIDescriptorItems();
        return iDescriptor;
    },

    // simply stubbed out for minimal
    _initIO: function(){
        this.io = new com.ibm.mm.iwidget.icontext.IContextIOImpl(this.widgetwrapper);
    },
    getUserProfile: function(){
        //todo: warning
        return null;
    },
    requires: function(/*String*/requiredItem,/*String*/ version,/*String*/ uri,/*function*/ cb, mimeType){
        //todo: warning
        return;
    },
    processiWidgets: function(/*domnode*/root){
        //todo: warning
        return;
    }
});

com.ibm.mm.iwidget.icontext.IContextImpl = com.ibm.mm.iwidget.icontext.IContextDefaultImpl;

// IMPORTANT
// ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
// This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "iWidget") >= 0)) {
    dojo["require"]("com.ibm.mm.iwidget.icontext.IContextExtendedImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
}

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.iContext"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.iContext"] = true;
dojo.provide("com.ibm.mashups.iwidget.iContext");








}

if(!dojo._hasResource["com.ibm.mashups.iwidget.itemset.ManagedItemSetCallbackModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.itemset.ManagedItemSetCallbackModel"] = true;
dojo.provide("com.ibm.mashups.iwidget.itemset.ManagedItemSetCallbackModel");


/**
 * This API defines the callback functions for ManagedItemSet.
 * @ibm-api
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.itemset.ManagedItemSetCallbackModel", null, {
    /**
     @private
     */
    constructor: function() {
    },
    /**
     This method defines the callback function after save operation.  IWidget may provide this function when invoke <code> managedItemSet.save(callbackfn)</code>.
     The iContext will invoke callbackfn upon save completion.
     @param{String}managedItemSetName  name of ManagedItemSet: attributes,idescriptor,userprofile. Must never be <code>null</code>.
     @param{Boolean}success boolean indicates if save operation is successful or not.
     @type void
     */
    postSaveCallbackFn: function(/*String*/managedItemSetName,/*Boolean*/ success) {
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.itemset.ManagedItemSet_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.itemset.ManagedItemSet_API"] = true;
dojo.provide("com.ibm.mashups.iwidget.itemset.ManagedItemSet_API");
dojo.provide("com.ibm.mashups.iwidget.itemset.ManagedItemSet");

/**
 Interface to a simple abstraction of a datamodel. This provides a base from which more sofisticated datamodel can be built.
 There're 3 default ManagedItemSet provided in Lotus Mashups. They are attributes, userprofile and  idescriptor.<p/>
 @ibm-api
 @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.itemset.ManagedItemSet",null, {
    /**
     @private
     */
    constructor: function() {
    },
    /**
     This method requests the iContext save the current state of the ManagedItemSet.
     The iContext MAY also choose to save the ManagedItemSet at times other than when iWidgets request a save.
     This method MAY operate asynchronously.  The iContext  MUST invoke any supplied callbackFn upon completion of the save attempt.
     It need to be implemented by each subclass...signiture of callback function is as follows</br>
     &nbsp;&nbsp;&nbsp;<code>function(in String managedItemSetName, in Boolean success);</code>
     @param{com.ibm.mashups.iwidget.itemset.ManagedItemSetCallbackModel.postSaveCallbackFn}callbackfn optional callback function
     @type void
     @deprecated use commit(callbackfn) instead
     */
    save: function(callbackfn) {
    },
	 /**
     This method requests the queued change be processed. This includes simultaneous changes to multiple items and any persistence or other propagation of the values.
     This method MAY operate asynchronously.  The iContext  MUST invoke any supplied callbackFn upon completion of the commit attempt.
     It need to be implemented by each subclass...signiture of callback function is as follows</br>
     &nbsp;&nbsp;&nbsp;<code>function(in String managedItemSetName, in Boolean success);</code>
     @param{com.ibm.mashups.iwidget.itemset.ManagedItemSetCallbackModel.postSaveCallbackFn}callbackfn optional callback function
     @type void
     */
    commit: function(callbackfn) {
    },
	  /**
     This method sets an item within the ItemSet, creates or replaces an existing entry as needed.
     To append a value to any existing item, suggest to get the current value of this item and append
     the new value to the list and supply the result to this method.
     Marking an item as ReadOnly indicates to the iContext that while this item maybe shared with other components
     on the page, the access of those components should not include changing or removing item.
     @param{String}itemName name of the item. Must never be <code>null</code>.
     @param{String}value value of the item. Must never be <code>null</code>.
     @param{Boolean}readOnly optional Boolean attribute to indicate this item is readOnly or not.Default value is false if this parameter is not provided.
     @return{ItemSet} return an handle of ItemSet upon successful, <code>null</code> upon failure.
     @deprecated use setItemValue(itemName,value) instead
     */
    setItemValue: function( /*String*/itemName, /*Object*/ value,/*boolean*/ readOnly) {
        return this;
    },
	 /**
     This method sets an item within the ItemSet, creates or replaces an existing entry as needed.
     With the actual setting/processing of the change happening when commit() is invoked.As ManagedItemSet are controlled by
     the iContext, some items may be read only to the iwidget.
     @param{String}itemName name of the item. Must never be <code>null</code>.
     @param{String}value value of the item. Must never be <code>null</code>.
     @return{ItemSet} return an handle of ItemSet upon successful, <code>null</code> upon failure.
     */
    setItemValue: function( /*String*/itemName, /*Object*/ value) { // JSLINT-IGNORE: in Java functions with the same name but different signatures are allowed - this is only used for generating JavaDoc
        return this;
    },
    /**
     This method returns the value for the named item from the set.
     @param{String}itemName name of the item. Must never be <code>null</code>.
     @return{String} return value of the named item for the set, <code>null</code> upon failure.
     */
    getItemValue: function( /*String*/itemName) {
        return null;
    },
    /**
     This method returns an array of Strings, providing the name of each item.
     @return{String[]}  return an array of items names and return <code>null</code> if the set contains no item
     */
    getAllNames: function() {
        return null;
    },
    /**
     Removes the named item from the set.
     @param{String}itemName name of the item that needs to be removed. Must never be <code>null</code>.
     @return{ItemSet} return the handle to the ManagedItemSet upon successful, <code>null</code> upon failure.
     */
    removeItem: function(/*String*/itemName) {
        return null;
    },
    /**
     This method returns a new ItemSet which is a duplicate of the current ItemSet.
     @return{ItemSet}  return a new ItemSet which contains all the data item in the current ItemSet
     @deprecated not used
     */
    clone: function() {
        return null;
    },
    /**
     This method returns a Boolean indicating whether or not the item specified by the supplied name can be modified by the user.
     @param{String}itemName name of the required Item. Must never be <code>null</code>.
     @return{Boolean} return a Boolean indicating whether or not the item specified by the supplied name can be modified by the user. Never <code>null</code>.
     */
    isReadOnly: function(/*String*/itemName) {
        return null;
    },
    /**
     As a limitation in Lotus Mashups, this method returns <code>null</code>.
     @return{Object} return As a limitation in Lotus Mashups, this method returns <code>null</code>.
     @deprecated not used
     */
    getItemSetDescription: function() {
        return null;
    },
	/**
     This function adds listener to this ShareableItemSet. So it will gets notified when this ShareableItemSet is updated.
     @param{Function}listener js function that should already be properly scoped. Must never be <code>null</code>.
     @return{String} return listener id if listener is registered successfully, return null if it's not.
     */
    addListener: function(/*Function*/listener) {
        return null;
    },
    /**
     This function removes the  listener from this ShareableItemSet.
     @param{String}listenerId  listener id that's returned by the system when listener is added. Must never be <code>null</code>.
     @return{Boolean} return true if listener is removed successfully.
     */
    removeListener: function(/*String*/listenerId) {
        return true;
    } //return true if listener is removed successfully
});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.services.EventService"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.services.EventService"] = true;
dojo.provide("com.ibm.mashups.iwidget.services.EventService");

/**
 * This interface defines iWidget EventService which provides  a topic driven subscribe/publish mechanism.
 * "fireEvent" and "broadcastEvent"  are provided as convenience functions on top of this basic model.
 * The service can be retrieved using the following code: <br>
 * <code>var eventService = com.ibm.mashups.services.ServiceManager.getService(<br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;com.ibm.mashups.iwidget.services.EventService.SERVICE_NAME);</code><br/>
 * @ibm-spi
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.services.EventService",null,  {
    /**
     * The service name to be used to fetch the service from the ServiceManager
     * @type String
     */
    SERVICE_NAME: "eventService",

  	/**
     * @private
     */
    constructor:function(){
    },

/**
Allows page component to invoke a handled event that's defined in an iWidget.<br/>
For example,  in Lotus Mashups, user can click "save" to save the attributes when user finished editing a widget .<br/>
Then the component that renders the "save" button could use this api to distribute an onModeChanged event to the widget.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>com.ibm.mashups.services.ServiceManager.getService("eventService").fireEvent(this.iwidgetId,"onModeChanged", {newMode:"view"});	 </code><br/>
So the widget could get notified and go back to "view"mode.<br/>
Same function can also be achieved by using "publishEvent"<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>com.ibm.mashups.services.ServiceManager.getService("eventService").publishEvent("widgetevents."+this.iwidgetId+"."+"onModeChanged", {newMode:"view"}); </code><br/>
@param{String } targetWidget  id of target iWidget. Must never be NULL.
@param{String } targetEvent  event name of target Event .Must never be NULL.
@param{Object } payload  optional. data object that's distributed with an event. May be NULL.
@param{String } payloadType  optional. type of the payload
@param{String } sourceid  optional. id of source component that triggers this event
@type void
*/
      fireEvent: function(targetWidget,targetEvent,payload,payloadType,sourceid){
      },
/**
Allows page components to broadcast  an event to all the widgets/components on the page. There's no need for widgets to subscribe that topic first.<br/>
For example,  mode selector iWidget may broadcast a "pageModeChanged" event when page mode is changed from view mode to edit mode.<br/>
Then all the widgets/components  will get notified and all widgets/components that  can handle "pageModeChanged" event will update accordingly.<br/>
A widget that can handle this event must have this event defined. <br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> &lt;iw:event id="pageModechanged"  eventDescName="pageModeChanged_desc" handled="true"  onEvent="handlePageModeChange" /&gt; </code><br/>
A component that can handle this event must subscribe this event by using:<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <code>serviceManager.getService("eventService").subscribeEvent ("pageModechanged",handlerFn,scope,sourceid)</code><br/>
Code example:<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>com.ibm.mashups.services.ServiceManager.getService("eventService").broadcastEvent("pageModeChanged", payload,payloadtype,,sourceid); </code><br/>
Same function can also be achieved by using "publishEvent"<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>com.ibm.mashups.services.ServiceManager.getService("eventService").publishEvent("*"+"."+"onModeChanged", {newMode:"view"}); </code><br/>
@param{String } targetEvent  event name of target Event .Must never be NULL.
@param{Object } payload  optional.  data object that's distributed with an event. May be NULL.
@param{String } payloadType  optional.  type of the payload
@param{String } sourceid  optional. id of client component that triggers this event.
@type void
*/
      broadcastEvent: function(targetEvent,payload,payloadType,sourceid){
      },
/**
Allows page components to switch to a different page and broadcast an event to all the widgets/components on that page.<br/>
@param{String } targetEvent  event name of target Event .Must never be NULL.
@param{Object } payload  optional.  data object that's distributed with an event. May be NULL.
@param{String } payloadType  optional.  type of the payload
@param{String } sourceid  optional. id of client component that triggers this event.
@param{String } pageid  optional. id of page to switch to and receive the event. If none is provided, no page switch will occur and event will broadcast to current page.
@type void
*/
      broadcastEvent: function(targetEvent,payload,payloadType,sourceid,pageid){ // JSLINT-IGNORE: cannot change public API
      },
/**
Allows page components to switch to a different page and space and broadcast an event to all the widgets/components on that page.<br/>
@param{String } targetEvent  event name of target Event .Must never be NULL.
@param{Object } payload  optional.  data object that's distributed with an event. May be NULL.
@param{String } payloadType  optional.  type of the payload
@param{String } sourceid  optional. id of client component that triggers this event.
@param{String } pageid  optional. id of page to switch to and receive the event. If none is provided, no page switch will occur and event will broadcast to current page.
@param{String } spaceid  optional. id of space containing the page to switch to and receive the event. If none is provided, current space is assumed.
@type void
*/
      broadcastEvent: function(targetEvent,payload,payloadType,sourceid,pageid,spaceid){ // JSLINT-IGNORE: cannot change public API
      },
/**
Allows page components to broadcast more than one event to all the widgets/components on the page.<br/>
@param{Array } eventsArray   Array of objects each containing the following event information: &#123; "targetEvent": targetEvent, "payload": payload, "payloadType": payloadType &#125;. Must never be NULL.
@param{String } sourceid  optional. id of client component that triggers this event.
@type void
*/
      broadcastEvents: function(eventsArray,sourceid){
      },
/**
Allows page components to switch to a different page and broadcast more than one event to all the widgets/components on that page.<br/>
@param{Array } eventsArray   Array of objects each containing the following event information: &#123; "targetEvent": targetEvent, "payload": payload, "payloadType": payloadType &#125;. Must never be NULL.
@param{String } sourceid  optional. id of client component that triggers this event.
@param{String } pageid  optional. id of page to switch to and receive the events. If none is provided, no page switch will occur and events will broadcast to current page.
@type void
*/
      broadcastEvents: function(eventsArray,sourceid,pageid){ // JSLINT-IGNORE: cannot change public API
      },
/**
Allows page components to switch to a different page and space and broadcast more than one event to all the widgets/components on that page.<br/>
@param{Array } eventsArray   Array of objects each containing the following event information: &#123; "targetEvent": targetEvent, "payload": payload, "payloadType": payloadType &#125;. Must never be NULL.
@param{String } sourceid  optional. id of client component that triggers this event.
@param{String } pageid  optional. id of page to switch to and receive the events. If none is provided, no page switch will occur and events will broadcast to current page.
@param{String } spaceid  optional. id of space containing the page to switch to and receive the events. If none is provided, current space is assumed.
@type void
*/
      broadcastEvents: function(eventsArray,sourceid,pageid,spaceid){ // JSLINT-IGNORE: cannot change public API
      },
/**
Allows page component to publish a global event that's available to all the other page components.<br/>
Event service supports global topics. For these topics all the page components could subscribe to it.<br/>
For example. when an iWidget is removed from page, a global event -"/enabler/unloadWidget" will be published by the skin component.<br/>
iWidget container is a subscriber of this topic, thus it can clean up the resource related to this iWidget accordingly.<br/>
@param{String } topic  topic that's published.Must never be NULL.
@param{Object } payload  optional. payload object.
@param{String } payloadType optional.  type of the payload
@param{String } sourceid  optional. id of client component that triggers this event.
@type void
*/
      publishEvent: function(topic,payload,payloadType,sourceid){
      },
/**
Allows page component to subscribe  a global event that's available to all the other page components.<br/>
Event service supports global topic. for these topics all the page listeners could subscribe to it.<br/>
For example. when an iWidget is removed from page, a global event -"/enabler/unloadWidget" will be published by the skin component.<br/>
iWidget container is a subscriber of this topic, thus it can clean up the resource related to this iWidget accordingly.
@param{String } event  event name
@param{Object } object  optional. scope object of the handlerFn. default scope is global scope.
@param{String} eventCallback optional. eventCallback that will be invoked when event is published
@param{String} subscribeCallback optional. callback  to tell is subscription is good
@param{String } sourceid  optional. id of client component that subscribes this event
@type void
*/
      subscribeEvent:function(event,object,eventCallback,subscribeCallback,sourceid){
      },
/**
Allows page component to unsubscribe  a global event that's available to all the other page components.<br/>
@param{Object } subscriptionHandler   subscriptionHandler
@param{String } sourceid  optional. id of client component that subscribes this event
@type void
*/
	  unsubscribeEvent:function(subscriptionHandler,sourceid){
	  }
});
// make sure we can reference this globally
com.ibm.mashups.iwidget.services.EventService.SERVICE_NAME = "eventService";

}

if(!dojo._hasResource["com.ibm.mm.iwidget.manageditemset.IDescriptorDefaultImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.manageditemset.IDescriptorDefaultImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.manageditemset.IDescriptorDefaultImpl");










dojo.declare("com.ibm.mm.iwidget.manageditemset.IDescriptorDefaultImpl", com.ibm.mashups.iwidget.itemset.ManagedItemSet, {
    constructor: function(widget, defiDescriptor, instanceiDescriptor) {
        this.widget = widget;
        this.defiDescriptorItems = defiDescriptor; //associative array
        this.instanceiDescriptorItems = instanceiDescriptor; //associative array
        this.navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
        this._updatedItems = {}; // only manages mode and windowstate here
    },
    readOnlyItems: {
        defaultHeight: "defaultHeight",
        defaultWidth: "defaultWidth",
        displayLocale: "displayLocale",
        messageLocale: "messageLocale",
        author: "author",
        email: "email",
        website: "website",
        version: "version",
        icon: "icon"
    },
    writableItems: {
        title: "title",
        name: "name",
        description: "description",
        availableMessageLocales: "availableMessageLocales",
        mode: "mode",
        windowState: "windowState"
    },
    localizedItems: {
        title: "title",
        name: "name",
        description: "description"
    },
    getItemValue: function(/*string*/name) {

        if (typeof name == "undefined" || name === null) {
            return null;
        }
        var value = null;
        if (name == iwConstants.iDescriptorItems.mode) {
            var widgetWrapper = this.widget;
            if (widgetWrapper) {
                value = widgetWrapper.currentMode;
            }
        }
        else if (name == iwConstants.iDescriptorItems.displayLocale) {
            var aLocale = ibmConfig.locale;
            var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
            var temp = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.DISPLAY_LOCALE);
            if (temp) {
                aLocale = temp;
            }
            value = aLocale;
        }
        else if (name == iwConstants.iDescriptorItems.messageLocale) {
            value = this._getMessageLocale();
        }
        else if (name == iwConstants.iDescriptorItems.windowState) {
            value = this._getWindowState();
        }
        else {
            value = this._getItemValue(/*String*/name);
        }
        return value;
    },
    _getWindowState: function() {
        return "normal";
    },
    _getItemValue: function(/*String*/itemName) {

        var defItem = null;
        var instanceItem = null;

        var locale = null;
        if (this.localizedItems[itemName]) {
            locale = this._getMessageLocale(); //replace with mesage locale
        }

        if (itemName == iwConstants.iDescriptorItems.title) {
            // seems we have a title, so let's first try to get it from dyna content
            instanceItem = this._getDynamicTitle();
        }

        if (instanceItem === null && this.instanceiDescriptorItems) {
            instanceItem = this.instanceiDescriptorItems.getItemValue(itemName, locale);
        }

        if (instanceItem === null && this.defiDescriptorItems) {
            defItem = this.defiDescriptorItems.getItemValue(itemName, locale);
            if (typeof defItem == "undefined") {
                defItem = null;
            }
        }

        if (instanceItem !== null ) {
            return instanceItem;
        }

        return defItem;
    },
    _getDynamicTitle: function() {
        // noop in default
        return null;
    },
    _setDynamicTitleOrIcon: function(name, value) {
        // noop
    },
    setItemValue: function(name, value) {
        if (typeof name == "undefined" || name === null) {
            return null;
        }
        if (typeof value == "undefined" || value === null) {
            return null;
        }
        if (this.readOnlyItems[name]) {
            return null;
        }

        if (name == iwConstants.iDescriptorItems.mode) {
            var supportedModes = this._getWidgetDef().getSupportedModes();
            if (this._contains(supportedModes, value)) {
                this._updatedItems[name] = value;
            }
            else {
                return null;
            }
        }
        if (name == iwConstants.iDescriptorItems.windowState) {
            var supportedWindowStates = this._getWidgetDef().getSupportedWindowStates();
            if (this._contains(supportedWindowStates, value)) {
                this._updatedItems[name] = value;
            }
            else {
                return null;
            }
        }

        // dynamic title or icon
        if (this.widget.id && ( name == iwConstants.iDescriptorItems.title || name == iwConstants.iDescriptorItems.icon)) {
            this._setDynamicTitleOrIcon(name, value);
        }

        var locale = null;
        if (this.localizedItems[name]) {
            locale = this._getMessageLocale();
        }
        //save to instance level because this is the level next to view
        //such as title/desription/icon, iContext always use the current locale
        if (name == this.writableItems.title || name == this.writableItems.name || name == this.writableItems.description) {
            this.instanceiDescriptorItems.setItemValue(name, value, false, locale);
        }
        if (name == iwConstants.iDescriptorItems.availableMessageLocales) {
            this.instanceiDescriptorItems.setItemValue(name, value, false);
        }
        return this;
    },
    isReadOnly: function(name) {
        if (typeof name == "undefined" || name === null) {
            return false;
        }
        if (this.readOnlyItems[name]) {
            return true;
        }
        else {
            return false;
        }
    },
    removeItem: function(name) {
        //can't remove idescriptor items
        return null;
    },
    getAllNames: function() {
        var arr = {};
        if (this.defiDescriptorItems) {
            var defNames = this.defiDescriptorItems.getAllNames();
            for (var i in defNames) {
                if (Object.prototype.hasOwnProperty.call(defNames,i)) {
                    arr[defNames[i]] = true;
                }
            }
        }
        if (this.instanceiDescriptorItems) {
            var instanceNames = this.instanceiDescriptorItems.getAllNames();
            for (var j in instanceNames) {
                if (Object.prototype.hasOwnProperty.call(instanceNames,j)) {
                    arr[instanceNames[j]] = true;
                }
            }
        }
        var nameArr = [];
        for (var name in arr) {
            if (Object.prototype.hasOwnProperty.call(arr,name)) {
                nameArr.push(name);
            }
        }
        return nameArr;
    },
    save: function(cb) {
        return this.commit(cb);
    },
    commit: function(callbackfn) {
        //todo, what if change mode,windowstate? each are different
        if (this.serverless) {
            this._saveMicroformat();
        }

        //need to process event one by one, mode first
        if (this._updatedItems[iwConstants.iDescriptorItems.mode]) {
            var newMode = this._updatedItems[iwConstants.iDescriptorItems.mode];
            this.widget._handleOnModeChange(newMode);
        }
        if (this._updatedItems[iwConstants.iDescriptorItems.windowState]) {
            var newWindowState = this._updatedItems[iwConstants.iDescriptorItems.windowState];
            var oldWindowState = this._getWindowState();
            var eventService = com.ibm.mashups.services.ServiceManager.getService("eventService");
            eventService.publishEvent(com.ibm.mashups.iwidget.Constants.CHANGE_WIDGETWINDOWSTATE, {
                id: this.widget.id,
                newWindowState: newWindowState,
                oldWindowState: oldWindowState
            });
        }

        if (callbackfn) {
            callbackfn(iwConstants.IDESCRIPTOR, true);
        }

    },
    _saveMicroformat: function() { //for title/description/icon
        this.widget.commit();
        var payloadObj = {};
        payloadObj.wid = this.widget.id;
        this.widget.eventSvr._publishEvent(iwConstants.EVENTS.onAttributeSaved, payloadObj, this.widget.hubId);
    },
    addListener: function(/*obj*/fn) {
        var widgetWrapper = this.widget;
        var listenerId = widgetWrapper._registerListener(iwConstants.IDESCRIPTOR, fn);
        return listenerId;
    },
    removeListener: function(/*String*/listenerId) {
        var widgetWrapper = this.widget;
        return widgetWrapper._removeListener(iwConstants.IDESCRIPTOR, listenerId);
    },
    _getWidgetDef: function() {
        return this.widget.widgetDef;
    },
    _contains: function(arr, attribute) {
        var rc = false;
        for (var i = 0; i < arr.length; i++) {
            if (attribute == arr[i]) {
                rc = true;
                break;
            }
        }
        return rc;

    },
    _getMessageLocale: function() {
        if (this.messageLocale) {
            return this.messageLocale;
        }
        var aLocale = null;
        var availableMessageLocales = this._getItemValue(iwConstants.iDescriptorItems.messageLocale);
        if (availableMessageLocales) {
            var locales = availableMessageLocales.split(" ");
            var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
            var temp = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.DISPLAY_LOCALE);
            if (temp) {
                aLocale = this._getLocale(locales, temp, ibmConfig.locale);
            }
        }
        if (!aLocale) {
            aLocale = ibmConfig.locale;//most of our widgets use this today
        }
        this.messageLocale = aLocale;
        return this.messageLocale;
    },
    _getLocale: function(localesArray, preferredLocale, defaultLocale) {

        switch (localesArray.length) {
            case 0:
                // there is no localization
                return null;
                //break; // not necessary after return
            case 1:
                // there is only one localization, so use that
                return com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(localesArray[0]);
                //break; // not necessary after return
            default:
                var preferredMatch = com.ibm.mm.enabler.utils.LocaleHelper.matchLocale(preferredLocale, localesArray);
                if (preferredMatch) {
                    // yep, preferred was matched
                    return preferredMatch;
                }
                var defaultMatch = com.ibm.mm.enabler.utils.LocaleHelper.matchLocale(defaultLocale, localesArray);
                if (defaultMatch) {
                    // default was matched
                    return defaultMatch;
                }

                // nothing was matched, return first (as defaultLocale is not available)
                return com.ibm.mm.enabler.utils.LocaleHelper.normalizeLocale(localesArray[0]);
                //break; // not necessary after return
        }

    }

});

com.ibm.mm.iwidget.manageditemset.IDescriptorImpl = com.ibm.mm.iwidget.manageditemset.IDescriptorDefaultImpl;

// IMPORTANT
// ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
// This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "iWidget") >= 0)) {
    dojo["require"]("com.ibm.mm.iwidget.manageditemset.IDescriptorExtendedImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
}

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.itemset.ManagedItemSet"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.itemset.ManagedItemSet"] = true;
dojo.provide("com.ibm.mashups.iwidget.itemset.ManagedItemSet");







}

if(!dojo._hasResource["com.ibm.mm.iwidget.manageditemset.PersistentAttributes"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.manageditemset.PersistentAttributes"] = true;
dojo.provide("com.ibm.mm.iwidget.manageditemset.PersistentAttributes");




// INTERNAL PRIVATE CLASS - do NOT use directly
// Use PersistentAttributes instead
dojo.declare("com.ibm.mm.iwidget.manageditemset.InternalPersistentAttributesToPreferenceModelAdapter", com.ibm.mashups.iwidget.itemset.ManagedItemSet, {
    //Provides an the ItemSet interface to to the preference subsystem
    constructor: function(widget, serverless, parent) {
        if (serverless) {
            this.serverless = true;
        }
        else {
            this.serverless = false;
        }
        this.modes = iwConstants.mode;
        this.widget = widget;
        this.widgetInstance = this.widget.getIWidgetInstance();
        this.instanceAttributes = this.widgetInstance.getAttributes();
        this.defAttributes = this.widget.widgetDef.getAttributes();
        this.parent = parent;

        this.mode = this._getMode(null);
    },
    setItemValue: function(itemName, value, _merge) {
        if (!itemName) {
            return null;
        }
        if (!value) {
            return null;
        }
        if (this.isReadOnly(itemName)) {
            return null;
        }
        if (this.serverless) {
            if (this.mode == this.modes.EDIT) {
                //todo: replace with user preferred messagelocale
                this.instanceAttributes.setItemValue(itemName, value);
                //save to other level add more here
                if (this.parent) {
                    return this.parent;
                }
            }
        }
        return null;
    },
    getItemValue: function(itemName, _merge) {
        if (!itemName) {
            return null;
        }
        var value;
        if (this.serverless) {
            if (typeof _merge === "undefined") {
                _merge = true;
            }
            if (this.mode == this.modes.CONFIG) {
                value = this.defAttributes.getItemValue(itemName);
                if (typeof value === "undefined") {
                    value = null;
                }
                return value;
            }
            if (this.mode == this.modes.EDIT && !_merge) {
                value = this.instanceAttributes.getItemValue(itemName);
                if (typeof value === "undefined") {
                    value = null;
                }
                return value;
            }
            if (_merge) {
                value = this.instanceAttributes.getItemValue(itemName);
                if (!value) {
                    value = this.defAttributes.getItemValue(itemName);
                }
                if (typeof value === "undefined") {
                    value = null;
                }
                return value;
            }
        }
        return null;
    },
    getAllNames: function(_merge) {
        if (this.serverless) {
            if (typeof _merge === "undefined") {
                _merge = true;
            }
            var names;
            if (this.mode == this.modes.CONFIG) {
                names = this.defAttributes.getAllNames();
                if (names && names.length && names.length === 0) {
                    return null;
                }
                return names;
            }
            if (this.mode == this.modes.EDIT && !_merge) {
                names = this.instanceAttributes.getAllNames();
                if (names && names.length && names.length === 0) {
                    return null;
                }
                return names;
            }
            var name;
            if (_merge) {
                names = this.instanceAttributes.getAllNames();
                var obj = {};
                if (names && names.length && names.length > 0) {
                    for (var i in names) {
                        if (Object.prototype.hasOwnProperty.call(names,i)) {
                            name = names[i];
                            obj[name] = name;
                        }
                    }
                }
                names = this.defAttributes.getAllNames();
                if (names && names.length && names.length > 0) {
                    for (var j in names) {
                        if (Object.prototype.hasOwnProperty.call(names,j)) {
                            name = names[j];
                            obj[name] = name;
                        }
                    }
                }
                return this._getNamesArray(obj);
            }
        }
        return null;
    },
    removeItem: function(itemName) {
        if (!itemName) {
            return null;
        }
        if (this.isReadOnly(itemName)) {
            return null;
        }
        if (this.serverless) {
            if (this.mode == this.modes.EDIT) {
                this.instanceAttributes.removeItem(itemName);
                if (this.parent) {
                    return this.parent;
                }
            }
        }
        return null;
    },
    isReadOnly: function(/*String*/itemName, _merge) {
        //readOnly is set on definition level, per spec we only overwrite value in editmode
        //however to keep things backward compatible, we allow define value in microformat as well.
        if (!itemName) {
            return false;
        }

        if (this.serverless) {
            if (typeof _merge === "undefined") {
                _merge = true;
            }
            if (this.mode == this.modes.CONFIG) {
                return this.defAttributes.isReadOnly(itemName);
            }
            if (this.mode == this.modes.EDIT && _merge) {
                var isReadOnly = this.defAttributes.isReadOnly(itemName);
                if (!isReadOnly) {
                    isReadOnly = this.instanceAttributes.isReadOnly(itemName);
                }
                return isReadOnly;
            }
            if (this.mode == this.modes.EDIT) {
                return this.instanceAttributes.isReadOnly(itemName);
            }

        }

        return false;
    },
    commit: function(callbackfn) {
        //should persist on all the mode level. however config is not supported in runtime model
        //only edit mode needs to persist
        if (this.serverless) {
            this._saveMicroformat();
        }
        else {
            return null;
        }
        if (callbackfn) {
            callbackfn(iwConstants.ATTRIBUTES, true);
        }
        return (this);
    },
    _getNamesArray: function(items) {
        var i = 0;
        var names = [];
        var name;

        for (name in items) {
            if (Object.prototype.hasOwnProperty.call(items,name)) {
                names.push(name);
                i++;
            }
        }
        if (i === 0) {
            return null;
        }
        return names;
    },
    _saveMicroformat: function() {
        this.widget.commit();
        var payloadObj = {};
        payloadObj.wid = this.widget.id;
        this.widget.eventSvr._publishEvent(iwConstants.EVENTS.onAttributeSaved, payloadObj, this.widget.hubId);
    },
    _getMode: function(_mode) {
        var mode = this.modes.EDIT;
        if (_mode) {
            mode = _mode;
        }
        else {
            mode = this.widget.currentMode;
        }
        //todo: we need to define all the systemmodes supported by the framework
        //for runtime model, we only support edit
        if (mode == this.modes.VIEW) {
            mode = this.modes.EDIT;
        }
        return mode;
    },
    addListener: function(/*obj*/fn) {
        var listenerId = this.widget._registerListener(iwConstants.ATTRIBUTES, fn);
        return listenerId;
    },
    removeListener: function(/*String*/listenerId) {
        return this.widget._removeListener(iwConstants.ATTRIBUTES, listenerId);
    }
});

dojo.declare("com.ibm.mm.iwidget.manageditemset.PersistentAttributes", com.ibm.mashups.iwidget.itemset.ManagedItemSet, {
    constructor: function(widgetWrapper, serverless) {
        this._internalPersistentAttributesToPreferenceModelAdapter =
            new com.ibm.mm.iwidget.manageditemset.InternalPersistentAttributesToPreferenceModelAdapter(widgetWrapper, serverless, this);
    },
    setItemValue: function(itemName, value) {
        return this._internal().setItemValue(itemName, value, true);
    },
    getItemValue: function(itemName) {
        return this._internal().getItemValue(itemName, true);
    },
    getAllNames: function() {
        return this._internal().getAllNames(true);
    },
    removeItem: function(itemName) {
        return this._internal().removeItem(itemName);
    },
    isReadOnly: function(itemName) {
        return this._internal().isReadOnly(itemName, true);
    },
    save: function(callbackfn) {
        return this.commit(callbackfn);
    },
    commit: function(callbackfn) {
        return this._internal().commit(callbackfn);
    },
    _internal: function() { //todo: cleanup
        return this._internalPersistentAttributesToPreferenceModelAdapter;
    },
    addListener: function(/*obj*/fn) {
        return this._internal().addListener(fn);
    },
    removeListener: function(/*String*/listenerId) {
        return this._internal().removeListener(listenerId);
    }

});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.itemset.ItemSet"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.itemset.ItemSet"] = true;
dojo.provide("com.ibm.mashups.iwidget.itemset.ItemSet");

/**
 * Interface to a simple abstraction of a datamodel. This provides a base from which more sofisticated data models can be built.
 * @ibm-api
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.itemset.ItemSet", null, {
    /**
     @private
     */
    constructor: function() {
    },
    /**
     This method sets an item within the ItemSet, creates or replaces an existing entry as needed.
     Since only one value is allowed for any one name/locale combination, the supplied value replaces any existing value for the supplied name/locale.
	 When successful, this method MUST return a handle to the ItemSet while on failure it must return null.
     @param{String}itemName name of the item. Must never be <code>null</code>.
     @param{Object}value value of the item. Must never be <code>null</code>.
     @param{String}locale specified locale. Must never be <code>null</code>.
     @return{ItemSet} return an handle of ItemSet upon successful, <code>null</code> upon failure.
     */
    setLocalizedItemValue: function( /*String*/itemName, /*Object*/ value,/*String*/ locale) {
        return this;
    },
    /**
     This method sets an item within the ItemSet, creates or replaces an existing entry as needed.
     To append a value to any existing item, suggest to get the current value of this item and append
     the new value to the list and supply the result to this method.
     Marking an item as ReadOnly indicates to the iContext that while this item maybe shared with other components
     on the page, the access of those components should not include changing or removing item.
     @param{String}itemName name of the item. Must never be <code>null</code>.
     @param{Object}value value of the item. Must never be <code>null</code>.
     @param{Boolean}readOnly optional Boolean attribute to indicate this item is readOnly or not.Default value is false if this parameter is not provided.
     @return{ItemSet} return an handle of ItemSet upon successful, <code>null</code> upon failure.
     @deprecated please use setItemValue(itemName,value) readOnly is always false
     */
    setItemValue: function( /*String*/itemName, /*Object*/ value,/*boolean*/ readOnly) {// JSLINT-IGNORE: in Java functions with the same name but different signatures are allowed - this is only used for generating JavaDoc
        return this;
    },
	/**
     This method sets a nonlocalized value of an item within the ItemSet, creates or replaces an existing entry as needed.
     @param{String}itemName name of the item. Must never be <code>null</code>.
     @param{Object}value value of the item. Must never be <code>null</code>.
     @return{ItemSet} return an handle of ItemSet upon successful, <code>null</code> upon failure.
     */
    setItemValue: function( /*String*/itemName, /*Object*/ value) {// JSLINT-IGNORE: in Java functions with the same name but different signatures are allowed - this is only used for generating JavaDoc
        return this;
    },
	/**
     This method returns the value for the named item in the specified locale. On failure this method MUST return null.
     @param{String}itemName name of the item. Must never be <code>null</code>.
     @param{String}locale specified locale. Must never be <code>null</code>.
     @return{Object} return value of the item, <code>null</code> upon failure.
     */
    getLocalizedItemValue: function( /*String*/itemName,/*String*/locale) {
        return null;
    },
    /**
     This method returns the nonlocalized value for the named item from the set.
     @param{String}itemName name of the item. Must never be <code>null</code>.
     @return{ItemSet} return the named item for the set, <code>null</code> upon failure.
     */
    getItemValue: function( /*String*/itemName) {
        return null;
    },
    /**
     This method returns an array of Strings, providing the name of each item.
     @return{String[]}  return an array of items names and return <code>null</code> if the set contains no item
     */
    getAllNames: function() {
        return null;
    },
    /**
     Removes the named item from the set.
     @param{String}itemName name of the item that needs to be removed. Must never be <code>null</code>.
     @return{ItemSet} return the handle to the ItemSet upon successful, <code>null</code> upon failure.
     */
    removeItem: function(/*String*/itemName) {
        return null;
    },
	 /**
     Removes the non localized value of the item from the set.
     @param{String}itemName name of the item that needs to be removed. Must never be <code>null</code>.
     @return{ItemSet} return the handle to the ItemSet upon successful, <code>null</code> upon failure.
     */
    removeItemValue: function(/*String*/itemName) {
        return null;
    },
	 /**
     Removes the  value of the item from the set for a specified locale.
     @param{String}itemName name of the item that needs to be removed. Must never be <code>null</code>.
     @param{String}locale a specified locale. Must never be <code>null</code>.
     @return{ItemSet} return the handle to the ItemSet upon successful, <code>null</code> upon failure.
     */
    removeLocalizedItemValue: function(/*String*/itemName,/*String*/locale) {
        return null;
    },
   /**
     The method returns an array of strings, each providing a locale where a value is defined. The empty string"" is
     returned for a value without a locale. if the set does not contain the names item, this method must return null.
     @param{String}itemName name of the item.  Must never be <code>null</code>.
     @return{String[]} return an array each providing  a locale where a value is defined.
     */
    getLocalesWithValues: function(/*String*/itemName) {
        return null;
    },
    /**
     This method returns a new ItemSet which is a duplicate of the current ItemSet.
     @return{ItemSet}  return a new ItemSet which contains all the data item in the current ItemSet
     @deprecated not used
     */
    clone: function() {
        return null;
    },
    /**
     This method returns a Boolean indicating whether or not the item specified by the supplied name can be modified by the user.
     @param{String}itemName name of the required Item. Must never be <code>null</code>.
     @return{Boolean} return a Boolean indicating whether or not the item specified by the supplied name can be modified by the user. Never <code>null</code>.
     @deprecated always return false
     */
    isReadOnly: function(/*String*/itemName) {
        return false;
    },
    /**
     As a limitation in Lotus Mashups, this method returns <code>null</code>.
     @return{Object} return As a limitation in Lotus Mashups, this method returns <code>null</code>.
     @deprecated not used
     */
    getItemSetDescription: function() {
        return null;
    },
		/**
     This function adds listener to this ShareableItemSet. So it will gets notified when this ShareableItemSet is updated.
     @param{Function}listener js function that should already be properly scoped. Must never be <code>null</code>.
     @return{String} return listener id if listener is registered successfully, return null if it's not.
     @deprecated not used
     */
    addListener: function(/*Function*/listener) {
        return null;
    },
    /**
     This function removes the  listener from this ShareableItemSet.
     @param{String}listenerId  listener id that's returned by the system when listener is added. Must never be <code>null</code>.
     @return{Boolean} return true if listener is removed successfully.
     @deprecated not used
     */
    removeListener: function(/*String*/listenerId) {
        return true;
    } //return true if listener is removed successfully
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.itemset.ItemsetDefaultImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.itemset.ItemsetDefaultImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.itemset.ItemsetDefaultImpl");





dojo.declare("com.ibm.mm.iwidget.itemset.ItemSetDefaultImpl", com.ibm.mashups.iwidget.itemset.ItemSet, {
    constructor: function(parent, defData, name) {

        this.widget = parent; //widget wrapper;
        this.name = name;
        //no persistence is needed thus we have only one merged data layer at runtime
        var instance = this.widget.getIWidgetInstance();
        var instanceProperties = null;
        if (instance) {
            instanceProperties = instance.getItemSet(name);
        }
        var properties = {};
        if (defData) {
            if (defData) {
                for (var itemName1 in defData.items) {
                    if (Object.prototype.hasOwnProperty.call(defData.items,itemName1)) {
                        properties[itemName1] = dojo.clone(defData.items[itemName1]); // the new internal json itemset notation is compatible with the SPI
                    }
                }
            }
            this.properties = new com.ibm.mm.iwidget.widget.ModifiablePropertiesImpl(properties);
        }
        if (!this.properties) {
            this.properties = new com.ibm.mm.iwidget.widget.ModifiablePropertiesImpl(properties);
        }

        if (instanceProperties) {
            for (var itemName in instanceProperties) { //overwrite only
                //if (defData.items[itemName]) {
			   if (Object.prototype.hasOwnProperty.call(instanceProperties,itemName)) {

                    var anItem = instanceProperties[itemName];
                    if (anItem.values) {
                        for (var j in anItem.values) {
                            if (Object.prototype.hasOwnProperty.call(anItem.values,j)) {
                                //always readOnly
                                this.properties.setItemValue(itemName, anItem.values[j], false, j);
                            }
                        }
                    }
                    if (anItem.value) {
                        this.properties.setItemValue(itemName, anItem.value);
                    }
              }
            }
        }
    },
	_getResourceBundle: function() {
        if (!this.iwMessages) {
            this.iwMessages = dojo.i18n.getLocalization("com.ibm.mm.enabler", "iwMessages");
        }
        return this.iwMessages;
    },
	_logDeprecated:function(methodName,fn1,fn2){
		this._getResourceBundle();
        var warning = dojo.string.substitute(this.iwMessages.W_DEPRECATE_2, [fn1,fn2]);
	},
    getLocalesWithValues: function(/*String*/itemName) {
        return this.properties.getItemLocales(itemName);
    },
	setLocalizedItemValue:function(itemName,value,locale){
		if (!itemName || !locale) {
			return null;
		}
		if (!(typeof value != "undefined" && value !== null)){
			return null;
		}
		rc = this.properties.setItemValue(itemName,value,false,locale);
		if (rc){
			return this;
		}
		return null;
	},
	setItemValue: function( /*String*/itemName, /*Object*/ value,/*String*/ locale) {
		if (!itemName ) {
			return null;
		}
		if (!(typeof value != "undefined" && value !== null)){
			return null;
		}

		//locale should be deprecated,use setLocalizedItemValue instead
		if (!locale){
			rc = this.properties.setItemValue(itemName,value,false);
		}else if (locale && !dojo.isString(locale)){
			this._logDeprecated("setItemValue","ItemSet.setItemValue(itemName,value,readOnly)","ItemSet.setItemValue(item,value)");
			rc = this.properties.setItemValue(itemName,value,false);
		}else{
			this._logDeprecated("setItemValue","ItemSet.setItemValue(itemName,value,locale)","ItemSet.setLocalizedItemValue(item,value,locale)");
			return this.setLocalizedItemValue(itemName,value,locale);
		}
        if (rc) {
            return this;
        }
        return null;
    },
	getLocalizedItemValue: function( /*String*/itemName, locale) {
		if (!itemName || !locale) {
			return null;
		}
        return this.properties.getLocalizedItemValue(itemName, locale);
    },
    getItemValue: function( /*String*/itemName, locale) {
		if (!itemName ) {
			return null;
		}
		if (locale){
			this._logDeprecated("getItemValue","ItemSet.getItemValue(itemName,locale)","ItemSet.getLocalizedItemValue(item,locale)");
			return this.getLocalizedItemValue(itemName,locale);
		}
        return this.properties.getItemValue(itemName);
    },
    getAllNames: function() {
        rc =  this.properties.getAllNames();
		if (rc && rc.length === 0) {
			return null;
		}
		return rc;
    },
    removeItem: function(/*String*/itemName, locale) {
		if (!itemName ) {
			return null;
		}
		if (locale){
			this._logDeprecated("removeItem","ItemSet.removeItem(itemName,locale)","ItemSet.removeLocalizedItemValue(itemName,locale)");
			return this.removeLocalizedItemValue(itemName,locale);
		}
        rc = this.properties.removeItem(itemName);
        if (rc) {
            return this;
        }
        return null;
    },
	removeLocalizedItemValue:function(itemName,locale){
		if (!itemName || !locale) { return null;}
		rc = this.properties.removeItemValue(itemName,locale);
		 if (rc) {
            return this;
        }
        return null;
	},
	removeItemValue:function(itemName){
		if (!itemName ) { return null;}
		rc = this.properties.removeItemValue(itemName);
		if (rc) {
            return this;
        }
        return null;

	}
});


}

if(!dojo._hasResource["com.ibm.mm.iwidget.DeferredLiveTextUnprocessStubImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.DeferredLiveTextUnprocessStubImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.DeferredLiveTextUnprocessStubImpl");



dojo.declare("com.ibm.mm.iwidget.DeferredLiveTextUnprocessStubImpl", com.ibm.mm.enabler.DeferredImpl, {
    constructor: function(wrapper) {
        this.wrapper = wrapper;
    },
    start: function(sync) {
        // defaults to false
        if (sync) {
            return;
        }
        //todo, what should we return if widget is sandboxed?
        var widgetInstance = this.wrapper.getIWidgetInstance();
        var tempMarkup = dojo.clone(this.wrapper.rootElement);
        this._unchangeCompleteCallback(tempMarkup);
    },
    setIncludeParent: function(value) {
        this.includeParent = value;
    },
    getIncludeParent: function() {
        return this.includeParent;
    },
    _unchangeCompleteCallback: function(node) {
        if (dojo.isFunction(this.getFinishedCallback())) {
            this.finish(node, 200);
        }
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.services.ContainerService_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.services.ContainerService_API"] = true;
dojo.provide("com.ibm.mashups.iwidget.services.ContainerService_API");
dojo.provide("com.ibm.mashups.iwidget.services.ContainerService");

/**
 * @ibm-spi
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.services.ContainerService",null,  {
    /**
     * The service name to be used to fetch the service from the ServiceManager
     * @type String
     */
    SERVICE_NAME: "iWidgetContainerService",

    /**
     * Constant defining the provider for event information
     * @type String
     */
    PROVIDER_EVENTS: "events",

    /**
     * Constant defining the provider for wire information
     * @type String
     */
    PROVIDER_WIRES: "wires",

    /**
     * Constant defining the provider for attribute information
     * @type String
     */
    PROVIDER_ATTRIBUTES: "attributes",

    registerOnChangeListener:function(provider, contextAndCallback) {
    },

    /**
     * Sets the persistence mode for the given type to the given new mode.
     *
     * @param {String} provider  One of the PROVIDER_* constants defined in this service. Must never be NULL.
     * @return {String} the current persistence mode for the given provider. May be NULL.
     */
    getPersistenceMode:function(provider, newMode) {
    },

    /**
     * Sets the persistence mode for all providers into their respective modifiable mode.
     *
     * @type void
     */
    switchToModifiablePersistenceMode:function() {
    }

});

// make sure we can reference this globally
com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME = "iWidgetContainerService";
com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS = "events";
com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES = "wires";
com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES = "attributes";


}

if(!dojo._hasResource["com.ibm.mm.iwidget.services.ContainerServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.services.ContainerServiceImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.services.ContainerServiceImpl");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget2
 *
 * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
 * Any number that is smaller causes this class to be written out before any other with a higher number
 * @ibm-dojo-profile-level 40
 */
// inject this service into the ServiceManager at the end. Therefore we have to require the implementation




dojo.declare("com.ibm.mm.iwidget.services.ContainerServiceImpl", com.ibm.mashups.iwidget.services.ContainerService, {
    constructor: function(){
        this._modes = null;
        this._modModes = null;
        this.TOPIC_BASE = "/"+("com.ibm.mm.iwidget.services.ContainerServiceImpl".replace(/\./ig,'/'))+"/";
        this.TOPIC_CHANGE = this.TOPIC_BASE + "change";
        this.TOPIC_CHANGE_EVENTS = this.TOPIC_CHANGE + "/events";
        this.TOPIC_CHANGE_WIRES = this.TOPIC_CHANGE + "/wires";
        this.TOPIC_CHANGE_ATTRIBUTES = this.TOPIC_CHANGE + "/attributes";

        this._topics = {};
        this._topics[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS] = this.TOPIC_CHANGE_EVENTS;
        this._topics[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES] = this.TOPIC_CHANGE_WIRES;
        this._topics[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES] = this.TOPIC_CHANGE_ATTRIBUTES;
    },

    _invalidate: function() {
        this._modes = null;
        this._modModes = null;
    },

    _init:function() {
        if (this._modes) {
            return;
        }
        var cs = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
        var genericPersistenceMode = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.PERSISTENCE_MODE);
        var eventPersistenceMode = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.PERSISTENCE_MODE_EVENTS);
        var wirePersistenceMode = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.PERSISTENCE_MODE_WIRES);
        var attributePersistenceMode = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.PERSISTENCE_MODE_ATTRIBUTES);
        this._modes = {};
        this._modes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS] = (eventPersistenceMode) ? eventPersistenceMode : genericPersistenceMode;
        this._modes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES] = (wirePersistenceMode) ? wirePersistenceMode :  genericPersistenceMode;
        this._modes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES] = (attributePersistenceMode) ? attributePersistenceMode : genericPersistenceMode;

        eventPersistenceMode = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.PERSISTENCE_MODE_EVENTS_MODIFIABLE);
        wirePersistenceMode = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.PERSISTENCE_MODE_WIRES_MODIFIABLE);
        attributePersistenceMode = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.PERSISTENCE_MODE_ATTRIBUTES_MODIFIABLE);
        this._modModes = {};
        this._modModes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS] = (eventPersistenceMode) ? eventPersistenceMode : genericPersistenceMode;
        this._modModes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES] = (wirePersistenceMode) ? wirePersistenceMode :  genericPersistenceMode;
        this._modModes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES] = (attributePersistenceMode) ? attributePersistenceMode : genericPersistenceMode;
    },

    registerOnChangeListener:function(provider, contextAndCallback) {
        this._init();
        var handle = dojo.subscribe(this._topics[provider], contextAndCallback.context, contextAndCallback.callback);
        if (dojo.isFunction(contextAndCallback.unregister)) {
            dojo.hitch(contextAndCallback.context, contextAndCallback.unregister)(handle);
        }
    },

    getPersistenceMode:function(provider, newMode) {
        this._init();
        return this._modes[provider];
    },

    switchToModifiablePersistenceMode:function(provider) {
        this._init();
        var oldModeEvents = this._modes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS];
        var newModeEvents = this._modModes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS];
        var oldModeWires = this._modes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES];
        var newModeWires = this._modModes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES];
        var oldModeAttributes = this._modes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES];
        var newModeAttributes = this._modModes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES];

        this._modes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS] = newModeEvents;
        this._modes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES] = newModeWires;
        this._modes[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES] = newModeAttributes;

        if (oldModeEvents != newModeEvents) {
            dojo.publish(this._topics[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS],
                [com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS, oldModeEvents, newModeEvents]);
            dojo.publish(this._topics[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES],
                [com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES, oldModeWires, newModeWires]);
            dojo.publish(this._topics[com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES],
                [com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES, oldModeAttributes, newModeAttributes]);
        }
    }

});

com.ibm.mashups.services.ServiceManager.setService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME, new com.ibm.mm.iwidget.services.ContainerServiceImpl());


}

if(!dojo._hasResource["com.ibm.mashups.iwidget.services.ContainerService"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.services.ContainerService"] = true;
dojo.provide("com.ibm.mashups.iwidget.services.ContainerService");





}

if(!dojo._hasResource["com.ibm.mm.iwidget.manageditemset.AttributesModeDelegate"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.manageditemset.AttributesModeDelegate"] = true;
dojo.provide("com.ibm.mm.iwidget.manageditemset.AttributesModeDelegate");







dojo.declare("com.ibm.mm.iwidget.manageditemset.AttributesModeDelegate", com.ibm.mashups.iwidget.itemset.ManagedItemSet, {
    constructor: function(persistentAttributesFactoryService, wrapper) {
        this.persistentAttributesFactoryService = persistentAttributesFactoryService;
        this.wrapper = wrapper;
        this.callbackHandle = {context:this, callback:"_attributesProviderModeChange",
            unregister: function(handle) {
                this.wrapper.unregisterArray.push(handle);
            }
        };
        this.widgetAttributes = [];
        this.widgetAttributesReplay = [];
        this._skipRecord = false;
        // init
        this._getAttributes();
    },
    _attributesProviderModeChange: function(provider, oldMode, newMode) {
        this.widgetAttributes = [];
        this._getAttributes();
        // replay here into the new persistence mode
        var modeSelector = this._getModeSelector();
        var replayArray = this.widgetAttributesReplay[modeSelector];
        if (replayArray) {
            this._skipRecord = true;
            for (var i=0; i<replayArray.length; i++) {
                var replay = replayArray[i];
                if (replay[0] == "set") {
                    this.setItemValue(replay[1], replay[2]);
                }
                else if (replay[0] == "remove") {
                    this.removeItem(replay[1]);
                }
            }
            this._skipRecord = false;
        }
        this.widgetAttributesReplay = [];
        this.widgetAttributesReplay[modeSelector] = [];
    },
    _getModeSelector: function() {
        // the rules for the modes are:
        // config -> config
        // edit -> edit
        // personalize -> personalize
        // view --> personalize
        // "else" --> personalize

        var currentMode = this.wrapper._getCurrentMode();
        var modeSelector = iwConstants.mode.PERSONALIZE;
        if (currentMode == iwConstants.mode.CONFIG || currentMode == iwConstants.mode.EDIT) {
            modeSelector = currentMode;
        }
        return modeSelector;
    },
    _getAttributes:function() {
        var modeSelector = this._getModeSelector();

        this.widgetAttributes[modeSelector] = this.widgetAttributes[modeSelector] || null;
        if (this.widgetAttributes[modeSelector] === null) {
            this.widgetAttributes[modeSelector] = this.persistentAttributesFactoryService.createPersistentAttributes(this.wrapper, this.callbackHandle);
            // we only want to register one callback handler to clean out all modes
            this.callbackHandle = null;
        }
        return this.widgetAttributes[modeSelector];
    },
    _record: function(array) {
        if (!this._skipRecord) {
            // first element is function name, everything after that parameters
            var modeSelector = this._getModeSelector();
            this.widgetAttributesReplay[modeSelector] = this.widgetAttributesReplay[modeSelector] || null;
            if (this.widgetAttributesReplay[modeSelector] === null) {
                this.widgetAttributesReplay[modeSelector] = [];
            }
            this.widgetAttributesReplay[modeSelector].push(array);
            //console.log("recorded ",array);
        }
    },
    _clearReplay: function()
    {
        var modeSelector = this._getModeSelector();
        this.widgetAttributesReplay[modeSelector] = [];
    },
    setItemValue: function(itemName, value) {
        this._record(["set",itemName, value]);
        return this._getAttributes().setItemValue(itemName, value);
    },
    getItemValue: function(itemName) {
        return this._getAttributes().getItemValue(itemName, true);
    },
    getAllNames: function() {
        return this._getAttributes().getAllNames(true);
    },
    removeItem: function(itemName) {
        this._record(["remove",itemName]);
        return this._getAttributes().removeItem(itemName);
    },
    isReadOnly: function(itemName) {
        return this._getAttributes().isReadOnly(itemName, true);
    },
    save: function(callbackfn) {
        var cs = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME);
        if (cs) {
            cs.switchToModifiablePersistenceMode(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES);
        }
        this._clearReplay();
        return this._getAttributes().save(callbackfn);
    },
    commit: function(callbackfn) {
        var cs = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME);
        if (cs) {
            cs.switchToModifiablePersistenceMode(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES);
        }
        this._clearReplay();
        return this._getAttributes().commit(callbackfn);
    },
    addListener: function(/*obj*/fn) {
        return this._getAttributes().addListener(fn);
    },
    removeListener: function(/*String*/listenerId) {
        return this._getAttributes().removeListener(listenerId);
    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.DeferredLoadImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.DeferredLoadImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.DeferredLoadImpl");




// deferred Load
dojo.declare("com.ibm.mm.iwidget.DeferredLoadImpl", com.ibm.mm.enabler.DeferredImpl, {
    constructor: function(uri, id, widgetDef) {
        this.uri = uri;
        if (typeof id == "undefined") {
            id = null;
        }
        this.id = id;
        if (typeof widgetDef == "undefined") {
            widgetDef = null;
        }
        this.widgetDef = widgetDef;
    },
    // defaults to synchronous
    start: function(sync) {
        if (this.widgetDef) {
            this._handleCallback(this.widgetDef, 200); //resource first, status code second
            return this.widgetDef;
        }
        var mode = (typeof(sync) == 'undefined') ? true : sync;
        var widgetLoadService = com.ibm.mashups.services.ServiceManager.getService("widgetLoadService");
        widgetLoadService.getWidgetXML(this.uri, mode, dojo.hitch(this, "_handleLoad"), this.id);
        if (sync) {
            return this.widgetDef;
        }
        return null;
    },
    _handleLoad: function(data, statuscode, xhr) {
        if (xhr) {
            statuscode = xhr.status;
        }
        if (statuscode != 200) {
            data = null; //set to null value
        }
        this.widgetDef = data;
        this._handleCallback(data, status);
    },
    _handleCallback: function(widgetDef, status) {
        this.finish(widgetDef, status);
    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetWrapperDefaultImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetWrapperDefaultImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.widget.IWidgetWrapperDefaultImpl");

/*
 * TODO
 * @ibm-module iWidget2
 */






















dojo.declare("com.ibm.mm.iwidget.widget.IWidgetWrapperDefaultImpl", com.ibm.mashups.iwidget.widget.IWidgetWrapper, {
    constructor: function(widgetSpan, id) {
        this._internalIbmModes = iwConstants._INTERNALIBMMODES;

        //parsing microformat
        this.rootElement = widgetSpan;
        this.id = id || dojo.attr(widgetSpan,'id');
        this.hubId = this.id; //hubClientId -- used for communication with openajax hub, for main view, it's the same as instanceid
        this.simpleWidgetEvents = {};
        this.loaded = false;
        this.standalone = null;
        this.widgetAttributes = null; // defer creation
        this.widgetItemSets = null; // defer creation to getWidgetItemSet or getItemSets
        this.ns = widgetSpan.className.substr(0, 3);
        this.windowManager = {}; // an associative array of window entities, key is windowid(for release1,it's mode);
        // value is simple json object: {id:"edit",root:rootElement,active:false}
        this.iwMessages = null;
        this.eventSvr = com.ibm.mashups.services.ServiceManager.getService("eventService");
        this._jsHandler = com.ibm.mm.enabler.aggregation.javascript.JAVASCRIPT_HANDLER;
        this.eventHandlers = [];
        this.unregisterArray = [];

        //backward compatibility
        this.publishedEvents = {};
        this.handledEvents = {};
    },
    getID: function() {
        return this.id;
    },
    getIWidgetInstance: function() {
        if (this.widgetInstance) {
            return this.widgetInstance;
        }
        this.widgetInstance = new com.ibm.mm.iwidget.widget.IWidgetInstanceImpl(this, this.rootElement, this.id);
        return this.widgetInstance;
    },
    setIWidgetDefinition: function(widgetDef) {
        this.widgetDef = widgetDef;
    },
    getIWidgetDefinition: function() {
        if (this.loaded) {
            return new com.ibm.mm.iwidget.DeferredLoadImpl(this.getIWidgetInstance().widgetXMLUrl, this.id, this.widgetDef);
        }
        else {
            return new com.ibm.mm.iwidget.DeferredLoadImpl(this.getIWidgetInstance().widgetXMLUrl, this.id);
        }
    },
    getMarkup: function() {
        return new com.ibm.mm.iwidget.DeferredLiveTextUnprocessStubImpl(this);
    },
    doRender: function() {
        try {
            this.prepare();
            this.execute();
        }
        catch (e) {
			//throw e;
        }
    },
    prepare: function() {
        var variableName = "_" + this.id + "_" + "iContext";
        if (!this.isModal()) {
            dojo.global[variableName] = new com.ibm.mm.iwidget.icontext.IContextImpl(this, this.ns);
        }
        else {
					var mainframeId = this._mainframeId;
			var iContextInstance = parent[mainframeId][variableName];
			dojo.global[variableName] = iContextInstance;
        }

        //subscribe event handler so event can be handled
        //if (this._inIframe())  console.log("subscribe hubClient:"+this.eventSvr.WIDGETEVENT_PREFIX + this.hubId);
        var eventServiceHandler = this.eventSvr._subscribeEvent(this.eventSvr.WIDGETEVENT_PREFIX + this.hubId, this, "handleEvent", null, this.hubId);

        if (!this._inIframe()) {
            this.eventHandlers.push(eventServiceHandler);
        }
    },
    execute: function() {
        this._initialize(dojo.hitch(this, function(){
            this._doRender();
        }));
    },

    _initialize: function(callback) {

        var lang = this.widgetDef.getDefaultLanguage();
        if (typeof lang != "undefined" && lang !== null) {
            this.defaultLanguage = lang;
        }
        else {
            this.defaultLanguage = "en";
        }

        var aMode = this._getInitDefaultMode();
        if (aMode === null) {
            aMode = iwConstants.mode_view;
        }
        this.currentMode = aMode;
        if (this._handleSaveMode) {
            this._handleSaveMode();
        }

        this._initManagedItemSet();

        if (callback) {
            callback();
        }
    },

    _getResourceBundle: function() {
        return null;
    },

    _logUpdateMarkupError: function(mode) {
    },
    _getMarkupByMode: function(mode) {
        var wInfo = this.widgetDef;
        var elem = wInfo.getMarkupByMode(mode);
        if (elem && elem.uri) {
            var uri = this._rewriteURI(elem.uri);
            dojo.xhrGet({
                url: uri,
                handleAs: "text",
                sync: true,
                load: function(result) {
                    if (result) {
                        var newElem = {};
                        newElem.content = result;
                        wInfo.setMarkupByMode(mode, newElem);
                    }
                },
                error: function(data, ioArgs) {
                    delete elem.uri;
                }
            });
        }
        var markup = null;
        if (wInfo.getMarkupByMode(mode)) {
            markup = wInfo.getMarkupByMode(mode).content;
        }
        return markup;
    },
	_updateTitle: function() {
    	// noop
	},
    _updateMarkup: function(mode, contentDiv) {
        var markup = this._getMarkupByMode(mode);

        if (mode == iwConstants.mode_view) {
            if (this.widgetDef.getAllowInstanceContent()) {
                var temp = this.getIWidgetInstance().getDefaultViewContent();
                if (temp && temp !== null) {
                    markup = temp;
                }
            }
        }
        if (typeof markup == "undefined" || markup === null) {
            this._logUpdateMarkupError(mode);
            return true;
        }
        //parse the mark and replace iContext with _widgetid_iContext
        var updatedMarkup = this._prepareMarkup(markup);
        updatedMarkup = updatedMarkup.replace(/^\s+|\s+$/, '');
        if (updatedMarkup.indexOf("<script") === 0) {
            updatedMarkup = "&nbsp;" + updatedMarkup;
        }

        //append all the nodes to a temporary div element
        var tempDIV = document.createElement("DIV");
        tempDIV.innerHTML = updatedMarkup;

        // find the script elements
        var scriptElems = tempDIV.getElementsByTagName("script");
        if (scriptElems !== null) {
            // iterate over script elements and attach an id attribute ,
            // this is necessary so if there's document.write, it got over written
            // otherwise you will get a blank page!
            for (var i = 0, l = scriptElems.length; i < l; i++) {
                var scriptElem = scriptElems[i];

                // include an id if there is none so far
                // (needed to lookup script in original DOM later on)
                var id = scriptElem.getAttribute("id");
                if (id === null || id == "") {
                    scriptElem.setAttribute("id", "_scr#" + i);
                }
            }
        }
        // update the DOM before executing the scripts
        // (the scripts might rely on elements in the DOM)
        //var contentDiv = this.rootElement.lastChild;
        contentDiv.innerHTML = tempDIV.innerHTML;
        //destroy tempDiv
        com.ibm.mm.enabler.utils.Dom.destroyNode(tempDIV);
        return true;
    },
    _prepareMarkup: function(markup) {
        var oldMarkup = markup.replace(/_IWID_/g, "_" + this.id + "_");
        //?= is javascript 1.5 feature
        var finalMarkup = oldMarkup.replace(/iContext(?=\.|\s|\(|\))/g, "_" + this.id + "_iContext");
        return finalMarkup;
    },
    destroy: function() {
        if (this.loaded && !this.isModal()) {
            this._handleEventInternal(iwConstants.EVENTS.onUnLoad);
        }
        if (!this._inIframe()) {
            var wireModel = this.getIWidgetInstance().getWireModel();
			//remove any wires coming into this widget (any wires that this widget is a target of)
			if (wireModel) {
				var myWires = wireModel.getWires();
				if (myWires) {
					var j = myWires.length;
					for (var k = j - 1; k >= 0; k--) {
						var wireSourceID = myWires[k].getSourceWidgetID();
						wireModel.removeWire(wireSourceID);
						this.commit();
					}
				}
			}
			//remove any wires going out of this widget (any wires that this widget is a source of)
            var targets = null;
            if (wireModel) {
                targets = wireModel.getTargets();
            }
            if (targets) {
				var widgetModel = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel();
                for (var i in targets) {
                    if (Object.prototype.hasOwnProperty.call(targets,i)) {
                        var widget = widgetModel.find(i);
                        if (widget) {
                            var wires = widget.getIWidgetInstance().getWireModel();
                            wires.removeWire(this.id); // remove all the wires that contains "this.id" as source
                            widget.commit();
                        }
                    }
                }
            }
            for (var x in this.eventHandlers) {
                if (Object.prototype.hasOwnProperty.call(this.eventHandlers,x)) {
                    this.eventSvr._unsubscribeEvent(this.eventHandlers[x], this.hubId);
                }
            }
            this.eventSvr._getHubAdapter(this.hubId).removeInlineHubClient(this.hubId);
            if (dojo.global["_" + this.id + "_" + "iContext"])//when iframe is removed,this could be null
            {
				dojo.global["_" + this.id + "_" + "iContext"]._destroy();
                dojo.global["_" + this.id + "_" + "iContext"] = null;
            }
        }
        else {
            //delete dojo.global["_"+this.id+"_"+"iContext"];   //doesn't work on IE7, can't delete from global context
            if (!this.isModal()) {
                this.eventSvr.disconnectHubClient();
                if (dojo.global["_" + this.id + "_" + "iContext"])//when iframe is removed,this could be null
                {
                    dojo.global["_" + this.id + "_" + "iContext"] = null;
                }
            }
        }
        if (this.rootElement) {
            this.rootElement = null;
        }
        if (this.windowManager) {
            this.windowManager = null;
        }
        //notify target widget to removeWire
    	// #17713 destroy the widgetInstance
		this.widgetInstance._destroy();
    },
    _doRender: function() {
		//update the title
        if (!this._inIframe()) {
			this._updateTitle();
		}
        var tempDiv = document.createElement("div");
        tempDiv.className = this.ns + "Content";
        this.rootElement.appendChild(tempDiv);
        var contentDiv = this.rootElement.lastChild;
        dojo.addClass(contentDiv, this.currentMode);
        contentDiv.style.visibility = "hidden";
        if (this._inIframe()) {
            dojo.style(contentDiv, "height", "100%");
        }
        //need to render default mode for modal dialog since some widgets will create dom in onload etc...
        var defIDescriptor = this.widgetDef.getIDescriptorItems();
        var defaultMode = defIDescriptor.getItemValue(iwConstants.iDescriptorItems.mode);
        if (this.isModal() && this.currentMode != defaultMode) {
            //create a div tag for main view
            var tempDiv1 = document.createElement("div");
            tempDiv1.className = this.ns + "Content";
            this.rootElement.appendChild(tempDiv1);
            contentDiv1 = this.rootElement.lastChild;
            dojo.addClass(contentDiv1, defaultMode);
            contentDiv1.style.visibility = "hidden";
            contentDiv1.style.display = "none";
            this._updateMarkup(defaultMode, contentDiv1);
        }

        this._updateMarkup(this.currentMode, contentDiv);
        this._loadWidgetSharedResource(dojo.partial(this._finishRender, contentDiv, this));
    },
    _finishRender: function(contentDiv, wrapper) {
        // Important for timing to subscribe to this event before loading widget
		try {
			var eventHandler = wrapper.eventSvr._subscribeEvent(com.ibm.mashups.iwidget.Constants.RESIZE_WIDGET + "." + wrapper.id, wrapper, "handleSizeChanged", null, wrapper.id);
			wrapper.eventHandlers.push(eventHandler);

			wrapper._createiScope();
			//contentDiv = wrapper.rootElement?
			wrapper._evalScripts(contentDiv);
			wrapper.windowManager[wrapper.currentMode] = {
				id: wrapper.currentMode,
				root: contentDiv,
				active: true,
				external: false
			};

            // remove the iw-loading div
            dojo.query("> ." + wrapper.ns + "loading", wrapper.rootElement).forEach(function(elem) {
                com.ibm.mm.enabler.utils.Dom.destroyNode(elem);
            });

			wrapper.onLoad();

			//now handle queued events if there's any
			if (typeof wrapper._eventqueue != "undefined" && wrapper._eventqueue !== null) {
				for (var event in wrapper._eventqueue) {
					if (Object.prototype.hasOwnProperty.call(wrapper._eventqueue, event)) {
						wrapper.handleEvent(wrapper._eventqueue[event]);
					}
				}
			}
		}catch(e){
			 return;
		}

        dojo.query("." + wrapper.currentMode, wrapper.rootElement).style({
            "visibility": "" //display:"none" will make mode selector not displaying properly
            //set visible will work funny in FF, the node will be visible even parent node is set to be invisible
        });
    },
    _evalScripts: function(contentDiv) {
        dojo.query("script",contentDiv).forEach(function(script) {
            this._jsHandler.handle(script);
        },this);
    },
    onLoad: function() {
        if (!this.isModal()) { //no need to call onload anymore since it should already be initialized
            this._handleEventInternal(iwConstants.EVENTS.onLoad);
        }
        //update state like onNavStateChanged
        this.updateState();
        //tell the stub widget is loaded
		var iEvent = new com.ibm.mm.iwidget.IEventImpl("on" + this.currentMode,null,{oldMode:null});
        this._handleEventInternal("on" + this.currentMode,iEvent);
        this.loaded = true;
        try {
            //tell builder widget is loaded
            dojo.publish(com.ibm.mashups.iwidget.Constants.WIDGET_LOADED + "." + this.id, [this.id]);
        }
        catch (e) {
            //workaround
            throw e;
        }
        this.eventSvr._publishEvent(com.ibm.mashups.iwidget.Constants.WIDGET_LOADED + "." + this.hubId, this.hubId);

    },
    updateState: function() {
        return;
    },
    _getSimpleEventHandler: function(/*String*/eventName) {
        if (this.simpleWidgetEvents && typeof this.simpleWidgetEvents[eventName] != "undefined") {
            return this.simpleWidgetEvents[eventName];
        }
        var handler = this.widgetDef.getWidgetEvents()[eventName];
        if (!handler) {
            handler = eventName;
        }
        var scope = this._getHandlerScope(handler);
        var handlerObj = null;
        if (scope) {
            handlerObj = dojo.hitch(scope, handler);
            this.simpleWidgetEvents[eventName] = handlerObj;
        }
        else if (handler.indexOf("on") === 0) {
            //get Uppercase event like onedit --> onEdit
            var newhandler = "on" + handler.substr(2, 1).toUpperCase() + handler.substr(3);
            if (newhandler != handler) {
                scope = this._getHandlerScope(newhandler);
                if (scope) {
                    handlerObj = dojo.hitch(scope, newhandler);
                    this.simpleWidgetEvents[eventName] = handlerObj;
                }
            }
        }
        return handlerObj;
    },
    _getHandlerScope: function(/*String*/handler) {

        //returns a global function or scope object
        var fn = dojo.global["_" + this.id + "_" + handler];
        if (typeof(fn) == "undefined") {
            var widgetScope = dojo.global["_" + this.id + "_iContext"].iScope();
            if (widgetScope && widgetScope[handler]) {
                fn = widgetScope;
            }
        }
        if (typeof fn == "undefined" || fn === null) {
            fn = dojo.global[handler];
        }
        if (typeof fn == "undefined" || fn === null) {
            return null;
        }
        else {
            return fn;
        }
    },
    handleEvent: function(payload) {
        //event handler that subscribes to event handler
        var declaredClass = payload.declaredClass;
        if (declaredClass == "com.ibm.mm.iwidget.IEventImpl") {
            var eventName = payload.name;
            return this._handleEvent(eventName, payload);
        }
    },
    _handleEvent: function(eventName, iEvent) {
        iEvent = this._deserializePayload(iEvent);

        //check here. it's just one payload with {eventName,iEvent}
        if (typeof eventName == "undefined" || eventName === null) {
            return false;
        }
        if (!this.loaded) {
            if (!this._eventqueue) {
                this._eventqueue = {};
            }
            this._eventqueue[eventName] = iEvent;
            return;
        }
        //handle onModeChanged event
        try {
            /*	if (eventName == iwConstants.EVENTS.onNavStateChanged) {
             return this._handleOnNavStateChanged(iEvent);
             }	*/
            if (eventName == iwConstants.EVENTS.onModeChanged) {
                if (this._inIframe()) {
                    //publish event to stub widget
                    var payloadObj = {};
                    payloadObj.methodname = "_handleOnModeChange";
                    payloadObj.hubclient = this.hubId;
                    payloadObj.params = [iEvent.payload];
                    //var id = "_stub_"+this.id.slice(0,this.id.lastIndexOf("_"));
                    var id = "_stub_" + this.id;
                    this.eventSvr._publishEvent(iwConstants.WIDGETEVENT_PREFIX + id, payloadObj, this.hubId);
                    return;
                }

                return this._handleModeChange(iEvent);
            }

            return this._handleEventInternal(eventName, iEvent);
        }
        catch (e) {
			throw e;
        }
    },
    _deserializePayload: function(iEvent) {
        // complex payload objects must be deserialized from json for case when widgets are sandboxed
        // to be serializable, complex payload objects must implement toJson method that returns json in format {"className":"x","json":"y"}
        // to be deserializable, complex payload objects must have a constructor with an argument that accepts the "y" json value returned from toJson
        if (typeof iEvent.payload == 'string' && iEvent.payload.indexOf("className") != -1 && iEvent.payload.indexOf("json") != -1) {
            try {
                var deserialized = dojo.fromJson(iEvent.payload);
                if (deserialized.className && typeof deserialized.className == 'string' && deserialized.className.length > 0 && deserialized.json && typeof deserialized.json == 'string') {
   				    var deserialized_payload = deserialized.json;
					// check if this is a table object that requires an additional deserialization of its payload before it is instanciated as a table - 15594
					if (deserialized.className=="com.ibm.mm.data.table" && deserialized_payload.indexOf("data") != -1) {
						 deserialized_payload = dojo.fromJson(deserialized_payload);
					}
                    iEvent.payload = new (dojo.getObject(deserialized.className))(deserialized_payload);
                }
            }
            catch (e) {
				throw e;
            }
        }
        return iEvent;
    },
    _handleOnModeChange: function(newMode) {
        var aEvent = new com.ibm.mm.iwidget.IEventImpl("onModeChanged", null, {
            newMode: newMode
        }, null);
        this._handleModeChange(aEvent);
    },
    _handleModeChange: function(iEvent) {
        var isHandled = false;
        var oldMode = this.currentMode;

        var payload = iEvent.payload;
        if (typeof payload == "undefined" || payload === null) {
            return false;
        }
        if (dojo.isString(payload)) {
            payload = dojo.fromJson(payload);
        }
        if (typeof payload == "undefined" || payload === null) {
            return false;
        }
        var newMode = payload.newMode || null;
        var newRoot = payload.rootElementId || null;

        // support one active mode only, thus don't support this operation
        if (newMode !== null && newMode == this.currentMode) {
            return false;
        }
        if (newMode === null) {
            return false;
        }

        var external = newRoot !== null;
        var updatedNewRoot = newRoot;

        var defaultMode = this._getDefaultMode();
        if (!defaultMode) {
            defaultMode = "view";
        }

        var oldWindow = this.windowManager[newMode] || null;

        // make sure that we only make default logic if the widget was launched with default mode
        if (this._inIframe() && oldWindow !== null && defaultMode == newMode) {
            //swtich back to view mode
            this.currentMode = newMode;

            if (this._handleSaveMode) {
                this._handleSaveMode();
            }
            // update newMode window state
            this.windowManager[newMode].active = true;
			if (updatedNewRoot !== null) {
			   this.windowManager[newMode].root = updatedNewRoot;
			}
            dojo.style(this.windowManager[newMode].root, "display", "");
			// update oldMode window state
			var oldModeWindow = this.windowManager[oldMode];
			oldModeWindow.active = false;
			if (oldModeWindow.root) {
               dojo.style(oldModeWindow.root, "display", "none");
			}
            this._handleOnModeEvent(newMode,oldMode);
            return;
        }
        //change:e

        var isWindowAvailable = false;
        if (typeof oldWindow != "undefined" && oldWindow !== null) {
            var oldRoot = oldWindow.root;
            if (!oldWindow.external && oldRoot !== null && newRoot === null) {
                updatedNewRoot = oldRoot;
                isWindowAvailable = true;
                isHandled = true;
                //how to verify a node doesn't exist anymore?
                // turn on this window
                dojo.style(oldRoot, "display", "");

            }
        }

        //create new window and update markup
        if (!isWindowAvailable) {
            if (updatedNewRoot === null) {
                var tempDiv = document.createElement("div");
                tempDiv.className = this.ns + "Content";
                this.rootElement.appendChild(tempDiv);
                updatedNewRoot = this.rootElement.lastChild;
                dojo.addClass(updatedNewRoot, newMode);
            }
            isHandled = this._updateMarkup(newMode, updatedNewRoot);
        }
        if (isHandled) {
            //hide current view
            var currentWindow = this.windowManager[this.currentMode];
            var currentRoot = currentWindow.root;
            if (currentWindow.external) {
                dojo.style(currentRoot, "display", "none");//todo, destroy external window?
                this.windowManager[this.currentMode] = null;
            }
            else if (newRoot !== null) { //if the newRoot is provided, don't hide current window. leave builder to do this.
                currentWindow.active = false;
            }
            else {
                currentWindow.active = false;
                dojo.style(currentRoot, "display", "none");
            }

            //change current mode
			oldMode = this.currentMode;
            this.currentMode = newMode;
            if (this._handleSaveMode) {
                this._handleSaveMode();
            }

            //  save/reset new window
            this.windowManager[newMode] = {
                id: newMode,
                root: updatedNewRoot,
                active: true,
                external: external
            };

            if (!isWindowAvailable) {
                this._evalScripts(updatedNewRoot);
            }
            this._handleOnModeEvent(newMode,oldMode);
        }
        if (isHandled && !this._inIframe()) {
            dojo.publish(iwConstants.EVENTS.modeChanged, [this.id, oldMode, newMode]);
            payload = {};
            payload.id = this.id;
            payload.oldMode = oldMode;
            payload.newMode = newMode;
            this.eventSvr._publishEvent(com.ibm.mashups.iwidget.Constants.WIDGET_MODECHANGED, payload, this.hubId);
        }

        if (this._inIframe()) {
            //switch from view -->edit  very rare use case since mode switch are triggered from skin
            //just tell stub mode is updated
            var payloadObj = {};
            payloadObj.methodname = "_handleOnModeUpdated";
            payloadObj.hubclient = this.hubId;
            payloadObj.params = [iEvent.payload];
            //var id = "_stub_"+this.id.slice(0,this.id.lastIndexOf("_"));
            var id = "_stub_" + this.id;
            this.eventSvr._publishEvent(iwConstants.WIDGETEVENT_PREFIX + id, payloadObj, this.hubId);
        }

        return isHandled;
    },
    _handleOnModeUpdated: function(mode) {
        var newMode = mode.newMode || mode;

        // in case we get the update for the mode we are already in, don't switch
        if (newMode == this.currentMode) {
            return;
        }

        this.currentMode = newMode;

        if (this._handleSaveMode) {
            this._handleSaveMode();
        }
        this.windowManager[newMode] = {
            id: this.id,
            active: true,
            external: true
        };
    },
    _handleOnModeEvent: function(mode,oldMode) {
        if (this._inIframe()) {
            dojo.setContext(com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().global, com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().doc);
            if (dojo.isIE) {
                if (document._mmcreateElement) {
                    document.createElement = document._mmcreateElement;
                }
                if (document._mmgetElementsByTagName) {
                    document.getElementsByTagName = document._mmgetElementsByTagName;
                }
            }
        }
        var isHandled = false;
        //handle event
        var eventName = "on" + mode;
		if (!oldMode) {
			oldMode = null;
		}
		var iEvent = new com.ibm.mm.iwidget.IEventImpl(eventName,null,{oldMode:oldMode});
		isHandled = this._handleEventInternal(eventName,iEvent);
        return isHandled;
    },
    _handleEventInternal: function(/*String*/eventName, iEvent) {
        if (typeof eventName == "undefined" || eventName === null) {
            return false;
        }

        var isHandled = false;
        var handlerFn = null;

        if (eventName.indexOf("on") === 0) {
            var eventHandler = this._getSimpleEventHandler(eventName);
            if (eventHandler !== null) {
                handlerFn = eventHandler;
            }
        }
        if (handlerFn === null) {
            handlerFn = this.getPublicEventHandler(eventName);
        }
        if (dojo.isFunction(handlerFn)) {
            try {
                if (iEvent) {
                    //transform data if necessary
                    if (this._transform) {
                        iEvent = this._transform(eventName, iEvent);
                    }
                    dojo.partial(handlerFn)(iEvent);
                }
                else {
                    dojo.partial(handlerFn)();
                }
            }
            catch (e) {
				throw e;
            }
            isHandled = true;
        }
        return isHandled;
    },
    getPublicEventHandler: function(/*String|Function*/eventName) {
        return null;
    },
    _getParent: function() {
        if (!this.parent) {
            this.parent = com.ibm.mm.iwidget.Utils.getWidgetParent(this.rootElement);
        }
        this.parent = this.parent || null;
        return this.parent;
    },
    _setParent: function(parent) {
        this.parent = parent;
    },
    getAttributes: function() {
        //Summary: returns an ManagedItemSet which provides access to the iWidget's customization attributes.
        //          The returned ManagedItemSet will be teh same as getItemSet(iContext.constants.itemset.ATTRIBUTES).
        //          returns empty set if there's no ItemSet.Return null if iWidget customization attributes is not
        //          supported
        if (!this.widgetAttributes) {
            var service = com.ibm.mashups.services.ServiceManager.getService("persistentAttributesFactoryService");
            this.widgetAttributes = new com.ibm.mm.iwidget.manageditemset.AttributesModeDelegate(service, this);
        }
        return this.widgetAttributes;
    },
    getWidgetItemSets: function() {
        if (this.widgetItemSets) {
            return this.widgetItemSets;
        }
        this.widgetItemSets = {};

        if (this.widgetDef) {
            var names = this.widgetDef.getAllItemSetNames();
            for (var i = 0, l = names.length; i < l; i++) {
                var id = names[i];
                var itemSetWrapper = this.widgetDef.getItemSet(id);
                var anItemSet = new com.ibm.mm.iwidget.itemset.ItemSetDefaultImpl(this, itemSetWrapper, id);
                this.widgetItemSets[id] = anItemSet;
            }
        }
        return this.widgetItemSets;
    },
    getWidgetItemSet: function(/*String*/name) {
        var widgetItemSets = this.getWidgetItemSets();
        var rtnVal = null;
        if (widgetItemSets) {
            rtnVal = widgetItemSets[name];
            if (!rtnVal) {
                rtnVal = new com.ibm.mm.iwidget.itemset.ItemSetDefaultImpl(this, null, name);
                this.widgetItemSets[name] = rtnVal;
            }
        }
        return rtnVal;
    },
    _loadWidgetSharedResource: function(cb2) {
        if (cb2) {
            cb2();
        }
    },
    _createiScope: function() {
        if (!this.isModal()) {
            var iScope = this.widgetDef.getIScope();
            var iScopeInstance = null;
            if (typeof iScope != "undefined" && iScope !== null) {
                try {
                    iScopeInstance = new (dojo.getObject(iScope))();
                }
                catch (err) {
                }
            }
            this.iScope = iScopeInstance ||
            {};

            dojo.global["_" + this.id + "_iContext"].scope = this.iScope;
            this._executeCallbackQueue();
        }
        else {
            this.iScope = dojo.global["_" + this.id + "_iContext"].scope;
        }
        this.iScope.iContext = dojo.global["_" + this.id + "_iContext"];
    },
    getIDescriptorItems: function() {
        if (this.iDescriptor) {
            return this.iDescriptor;
        }
        //read only for now
        this.iDescriptor = new com.ibm.mm.iwidget.manageditemset.IDescriptorImpl(this, this.widgetDef.getIDescriptorItems(), this.getIWidgetInstance().getIDescriptorItems());
        return this.iDescriptor;
    },
	_getInitDefaultMode:function(){
		if (this._getModeFromNavStateModel) {
            var aMode = this._getModeFromNavStateModel();
            if (typeof aMode != "undefined" && aMode !== null) {
                return aMode;
            }
        }
		return this._getDefaultMode();
	},
    _getDefaultMode: function() {

        var instanceIDescriptor = this.getIWidgetInstance().getIDescriptorItems();
        if (typeof instanceIDescriptor != "undefined" && instanceIDescriptor !== null) {
            var instanceItem = instanceIDescriptor.getItemValue(iwConstants.iDescriptorItems.mode);
            if (instanceItem) {
                return instanceItem;
            }
        }
        var defIDescriptor = this.widgetDef.getIDescriptorItems();
        var defItem = null;
        if (typeof defIDescriptor != "undefined" && defIDescriptor !== null) {
            defItem = defIDescriptor.getItemValue(iwConstants.iDescriptorItems.mode);
        }
        return defItem || null;
    },
    _getMarkup: function(includeParent) {
        //returning Markup to proxy widget stub
        var that = this;
        var cb = function(node, status) {
            that.eventSvr._publishEvent(that.eventSvr.WIDGETEVENT_PREFIX + that.id + ".onMarkupReturned", node);
        };
        var deferred = this.getMarkup();
        deferred.setIncludeParent(includeParent);
        deferred.setFinishedCallback(cb);
        deferred.start();
    },
    _inIframe: function() {
        return false;
    },
    commit: function(noSync) {
        var widgetInstance = this.getIWidgetInstance();
        var instanceAttributes = null;
        if (this._inIframe() && !noSync) { //if it's within iframe, synchronize all the data change...
            //send attributes/wiremodel  to the stub for now...

            var dataObj = {};
            instanceAttributes = widgetInstance.getAttributes();
            if (instanceAttributes && instanceAttributes._isDirty()) {
                dataObj.attributes = dojo.clone(instanceAttributes.toJson());
            }
            var wireModel = widgetInstance.getWireModel();
            if (wireModel && wireModel.isDirty()) {
                dataObj.wiremodel = wireModel.toJson();
            }

            var payloadObj = {};
            payloadObj.methodname = "_handleDataSync";
            payloadObj.hubclient = this.hubId;
            payloadObj.params = [dataObj];
            //send any updates to stub widget first

            var id = "_stub_" + this.id;
            this.eventSvr._publishEvent(iwConstants.WIDGETEVENT_PREFIX + id, payloadObj, this.hubId);
            //here's the flow main dialog -- stub
            return;

        }
        // need to check attribute properties and idescriptor attributes
        instanceAttributes = widgetInstance.getAttributes();

        if (instanceAttributes && instanceAttributes._isDirty()) {
            //source onItemSetChanged to the widget
            this._notifyWidget(this, "attributes", instanceAttributes);
            this._writePropertiesToDOM(this, "attributes", instanceAttributes);
            instanceAttributes._setDirty(false);
        }

        var instanceIDescriptor = widgetInstance.getIDescriptorItems();

        if (instanceIDescriptor && instanceIDescriptor._isDirty()) {
            //source onItemSetChanged to the widget
            this._notifyWidget(this, "idescriptor", instanceIDescriptor);
            this._writePropertiesToDOM(this, "idescriptor", instanceIDescriptor);
            instanceIDescriptor._setDirty(false);
        }

        //check wires
        var wiremodel = widgetInstance.getWireModel();
        if (wiremodel && wiremodel.isDirty()) {
            wiremodel.commit();
        }
    },
    _writePropertiesToDOM: function(widgetWrapper, itemSetName, properties) {
        var ns = widgetWrapper.ns;
        var root = widgetWrapper.rootElement;

        // query the markup for the given itemSetName
        var itemSets = dojo.query('span.' + ns + 'ItemSet[title="' + itemSetName + '"]', root);

        // iterate through the itemsets and delete those that are already inside of the markup
        for (var i = 0, l = itemSets.length; i < l; i++) {
            var itemSet = itemSets[i];
            if (root == itemSet.parentNode) {
                root.removeChild(itemSet);
            }
        }

        // create the new ItemSet span
        var newItemSet = document.createElement("span");
        newItemSet.className = ns + 'ItemSet';
        newItemSet.title = itemSetName;
        newItemSet.style.display = "none";
        newItemSet.style.visibility = "hidden";

        // append it to the DOM
        root.appendChild(newItemSet);

        var names = properties.getAllNames();

        if (!names) {
            return;
        }

        // iterate through all the items in the itemset
        for (var k = 0, l2 = names.length; k < l2; k++) {
            var itemName = names[k];
            var newItem = document.createElement("a");
            newItem.className = ns + 'Item';
            newItem.style.visibility = "hidden";
            newItem.style.display = "none";
            newItem.href = "#" + itemName;
            // read only ? --todo, not spec compliant
            if (properties.isReadOnly(itemName)) {
                dojo.addClass(newItem, ns + "ReadOnly");
            }
            var locales = properties.getItemLocales(itemName);
            if (!locales || (locales !== null && locales.length == 1 && locales[0] == "")) {
                var value = properties.getItemValue(itemName);
                if (value) {
                    newItem.appendChild(document.createTextNode(value));
                }
                newItemSet.appendChild(newItem);
            }
            else if (locales !== null) {
                var defaultLocale = properties._getItemDefaultLocale(itemName);
                if (!defaultLocale) {
                    defaultLocale = properties.DEFAULT_LOCALE; // this is not as nice as it should be
                }
                // create the new Element

                newItem.setAttribute("lang", defaultLocale);

                for (var j = 0; j < locales.length; j++) {
                    var langSpan = document.createElement("span");
                    langSpan.setAttribute("class", ns + "Value");
                    langSpan.setAttribute("lang", locales[j]);
                    var langValue = properties.getItemValue(itemName, locales[j]);
                    langSpan.appendChild(document.createTextNode(langValue));
                    newItem.appendChild(langSpan);
                }

                // append it to the itemset Span
                newItemSet.appendChild(newItem);
            }
        }
    },
    _notifyWidget: function(widgetwrapper, itemsetname, properties) {
        var names = properties.getAllNames();
        if (!names) {
            return;
        }
        var payload = {};
        payload.itemSetName = itemsetname;
        payload.changes = [];

        // iterate through all the items in the itemset
        for (var i = 0, l = names.length; i < l; i++) {
            var itemName = names[i];
            if (properties._isItemDirty && properties._isItemDirty(itemName)) {
                var value = properties._getInternalItemValue(itemName);

                if (value && value._change) {
                    var _change = dojo.clone(value._change);
                    if (_change.newVal) {
                        _change.newVal = properties._getRequiredValue(_change.newVal);
                    }
                    if (_change.oldVal) {
                        _change.oldVal = properties._getRequiredValue(_change.oldVal);
                    }
                    payload.changes.push(_change);
                }
                properties._setItemDirty(itemName, false);
            }
        }

        var listeners = this._getListeners(itemsetname);
        for (var x in listeners) {
            if (Object.prototype.hasOwnProperty.call(listeners,x)) {
                listeners[x](payload);
            }
        }
    },
    isModal: function() {
        //indicate if this is an iframe rendered in a modal dialog
        //return this._isModal? this._isModal:false;
        return false;
    },
    isLoaded: function() {
        return this.loaded;
    },
    isStandalone: function() {
        if (this.standalone === null) {
            this.standalone = dojo.hasClass(this.rootElement,
                    com.ibm.mm.iwidget.Constants.CSSCLASS_PREFIXED_INSTANCE.iwStandalone);
        }
        return this.standalone;
    },
    handleSizeChanged: function(payload) {
        if (payload.newWidth) {
            this.width = payload.newWidth;
        }
        if (payload.newHeight) {
            this.height = payload.newHeight;
        }
        var aEvent = new com.ibm.mm.iwidget.IEventImpl(iwConstants.EVENTS.onSizeChanged, null, payload, null);
        this._handleEvent(iwConstants.EVENTS.onSizeChanged, aEvent);
    },
    _isEmpty: function(obj) {
    	return com.ibm.mm.enabler.utils.Misc.isEmpty(obj);
    },
    _getListeners: function(itemSetName) {
        //only iwConstants.ATTRIBUTES && iwConstants.IDESCRIPTOR
        if (!this.listenerManager) {
            return null;
        }
        if (!this.listenerManager[itemSetName]) {
            return null;
        }
        return this.listenerManager[itemSetName];
    },
    _registerListener: function(itemSetName, fn) {
        if (!this.listenerManager) {
            this.listenerManager = {};
        }
        this.listenerManager[itemSetName] = this.listenerManager[itemSetName] ? this.listenerManager[itemSetName] : {};
        var listenerId = this._generateListenerId();
        var me = this;
        var listener = function(payload) {
            var changes = payload.changes ? payload.changes : null;
            if (changes.length > 0) {
                var iEvent = new com.ibm.mm.iwidget.IEventImpl("onItemSetChanged", null, payload);
                if (dojo.isString(fn)) {
                    var scope = me._getHandlerScope(fn);
                    if (scope) {
                        fn = dojo.hitch(scope, fn);
                    }
                }
                if (dojo.isFunction(fn)) {
                    dojo.partial(fn)(iEvent);
                }
            }
        };
        this.listenerManager[itemSetName][listenerId] = listener;
        return listenerId;
    },
    _removeListener: function(itemSetName, id) {
        if (!itemSetName || typeof id == "undefined" || id === null) {
            return false;
        }
        if (!this.listenerManager) {
            return false;
        }
        if (!this.listenerManager[itemSetName]) {
            return false;
        }
        if (this.listenerManager[itemSetName][id]) {
            delete this.listenerManager[itemSetName][id];
            return true;
        }
        return false;
    },
    _generateListenerId: function() {
        if (typeof this._listenerCt == "undefined") {
            this._listenerCt = 0;
        }
        else {
            this._listenerCt++;
        }
        return this._listenerCt;
    },
    _initManagedItemSet: function() { //register listener for idescriptor and attributes
        var listener = null;
        if (typeof(this.widgetDef) != "undefined") {
            listener = this.widgetDef._getManagedItemSetListener(iwConstants.ATTRIBUTES);
            if (listener !== null) {
                this._registerListener(iwConstants.ATTRIBUTES, listener);
            }
            listener = this.widgetDef._getManagedItemSetListener(iwConstants.IDESCRIPTOR);
            if (listener !== null) {
                this._registerListener(iwConstants.IDESCRIPTOR, listener);
            }
        }
    },
	_getRawUri:function(){
			var rawUri = this.getIWidgetInstance().widgetXMLUrl;
            if (this.widgetDef.getXmlBase()) {
                rawUri = this.widgetDef.getXmlBase();
            }
			return rawUri;
	},
	_initBaseUri:function(rawUri){
		if (!rawUri) {
			return;
		}
		this.rawBaseUri = this._getRawBaseUri(rawUri);
        this.widgetBaseUri = this._getResolvedPocUri(this.rawBaseUri);
		this.widgetBaseUriXhr = this._getXhrUri(this.widgetBaseUri);

		if (this.rawBaseUri.indexOf(":/") != -1) {
				var serverRoot = this._getServerRoot(this.rawBaseUri);
				if (serverRoot) {
					this.serverRoot = this._getResolvedPocUri(serverRoot);
					this.serverRootXhr = this._getXhrUri(this.serverRoot);
				}
		}
	},
    _rewriteURI: function(/*String*/uri, isXhr) {

        if (!this.widgetBaseUri) {
            var rawUri = this._getRawUri();
			this._initBaseUri(rawUri);
        }

		return this._rewriteURIWithContext(uri,isXhr,this.widgetBaseUri,this.widgetBaseUriXhr,this.serverRoot,this.serverRootXhr);
     },
	 _rewriteURIWithContext:function(uri,isXhr,widgetBaseUri,widgetBaseUriXhr,serverRoot,serverRootXhr)	{

	 	if (typeof isXhr == "undefined") {
			isXhr = true;
		}

        var uri2 = com.ibm.mm.enabler.EndpointUtils.checkForEndpoints(uri);
        if (uri2) {
            uri = uri2;
        }

        var returnUri = uri;
        var pathQuery, encPath;
        if (isXhr) {
            if (uri.indexOf(":/") != -1) { //valid schema is defined. absolute url
                returnUri = com.ibm.mm.enabler.utils.URLHelper.rewriteURL(uri);
            }
            else if (serverRootXhr !== null && uri.indexOf(serverRootXhr) === 0) {
                // seems the uri is already rewritten, so reuse it
                returnUri = uri;
            }
            else {
                pathQuery = uri.split("?"); // split the query
                encPath = com.ibm.mm.enabler.utils.Misc.encodePath(pathQuery[0]);
				returnUri = encPath;
                if (uri.indexOf("/") === 0) { //fullpath eg. /accuWeather/accuWeather.js
                    if (serverRootXhr) {
                        returnUri = serverRootXhr + encPath.substring(1);
                    }
                }
                else {
					if (widgetBaseUriXhr){
						 returnUri =  widgetBaseUriXhr + encPath;
					}
                }

                if (pathQuery.length == 2) {
                    returnUri += "?" + pathQuery[1];
                }
            }
        }
        else {
            if (uri.indexOf(":/") === -1) { //not absolute path
                pathQuery = uri.split("?"); // split the query
                encPath = com.ibm.mm.enabler.utils.Misc.encodePath(pathQuery[0]);
                if (uri.indexOf("/") === 0) { //fullpath
                    if (serverRoot) {
                        returnUri = serverRoot + encPath.substring(1);
                    }
                }
                else { //relative path
                    if (widgetBaseUri) {
                        returnUri = widgetBaseUri + encPath;
                    }
                }
                if (pathQuery.length === 2) {
                    returnUri += "?" + pathQuery[1];
                }
            }
        }
        return returnUri;
    },
	_getRawBaseUri:function(rawUri){
		if (!rawUri) {
			return null;
		}
		//don't solve res:/ here so server root can be figured out correctly
			var queryStart = rawUri.indexOf("?");
            if (0 < queryStart) {
                rawUri = rawUri.substring(0, queryStart);
            }

            var uri2 = com.ibm.mm.enabler.EndpointUtils.checkForEndpoints(rawUri);
            if (uri2) {
                rawUri = uri2;
            }
        	var rc = rawUri.substring(0, rawUri.lastIndexOf("/") + 1);
			return rc;
	},
	_getResolvedPocUri:function(rawUri){
		//solve res:/ to be the correct one
		if (!rawUri) {
			return null;
		}
		    var rc = rawUri;
		 	if (com.ibm.mm.enabler.utils.Misc.isPocUrl(rawUri) === true){
		  		rc = com.ibm.mm.enabler.utils.URLHelper.rewriteURL(rawUri);
		  	}
			return rc;
	},
	_getXhrUri:function(baseUri){
		if (!baseUri) {
			return null;
		}
		  var rc = baseUri;
		  if (baseUri.indexOf("/") !== 0) {
              rc =  com.ibm.mm.enabler.utils.URLHelper.rewriteURL(baseUri);
          }
		  return rc;
	},
	_getServerRoot:function(rawUri){
		if (!rawUri) {
			return null;
		}
		if (rawUri.indexOf(":/") == -1) {
			return null;
		}
			var serverRoot = null;

            	var indexOfScheme = rawUri.indexOf(":/");
            	serverRoot = rawUri.substring(0, indexOfScheme + 2); // value is "http:/" or "res:/"
            	if (rawUri.indexOf(":///") !== -1) {
                	serverRoot = rawUri.substring(0, indexOfScheme + 4); // "res:///" or "file:///"
            	}
            	else if (rawUri.indexOf("://") !== -1) { //http://www.ibm.com/
                	var indexOfRoot = rawUri.indexOf("/", indexOfScheme + 4);
                	serverRoot = rawUri.substring(0, indexOfRoot + 1); // "http://myhost/"
            	}

        	return serverRoot;
	},
	_executeCallbackQueue: function() {
        return;
    },
    // used by other classes within implementation
    _getCurrentMode: function() {
        return this.currentMode;
    }
});

com.ibm.mm.iwidget.widget.IWidgetWrapperImpl = com.ibm.mm.iwidget.widget.IWidgetWrapperDefaultImpl;

// IMPORTANT
// ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
// This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "iWidget") >= 0)) {
    dojo["require"]("com.ibm.mm.iwidget.widget.IWidgetWrapperExtendedImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
}

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetWrapper"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.widget.IWidgetWrapper"] = true;
dojo.provide("com.ibm.mashups.iwidget.widget.IWidgetWrapper");









}

if(!dojo._hasResource["com.ibm.mashups.iwidget.model.WidgetModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.model.WidgetModel"] = true;
dojo.provide("com.ibm.mashups.iwidget.model.WidgetModel");

/**
 * WidgetModel interface defines functions that expose information of a widget model.<br/>
 * Global model available to all the page components.<br/>
 * <code>var widgetModel = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel();</code>
 * @ibm-spi
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.model.WidgetModel",null,{
/**
 * @private
 */
	constructor:function(id){

	},

/**
Returns  an iWidgetWrapper object which represents a runtime instance of an iWidget object. <br/>
Id is the  "id" attribute that's defined in  microformat. It's used to uniquely identify an iWidget instance on the page.<br/>
<code> &lt;span class="iw-iWidget" id="{id}"&gt;  </code>
@param{String} id  unique id of an iWidget wrapper. Must not be NULL.
@type com.ibm.mashups.iwidget.widget. IWidgetWrapper
@returns{com.ibm.mashups.iwidget.widget. IWidgetWrapper }  an  iWidget Wrapper of the required iWidget . iWidget Wrapper represents a runtime instance of an iWidget.
*/
	find:function(id){
	},
/**
Returns  whether or not the given node has children. NOT Implemented.
@param{com.ibm.mashups.iwidget.iWidgetWrapper} iWidgetWrapper  parent iWidgetWrapper object. Must not be NULL.
@type Boolean
@returns{Boolean }  returns TRUE if the given node has children.
*/
	hasChildren:function(iWidgetWrapper){
	},
/**
Returns  an array of iWidgetWrapper object. NOT Implemented.<br/>
@param{com.ibm.mashups.iwidget.widget.IWidgetWrapper} iWidgetWrapper  parent object .Must not be NULL.
@param{Boolean} isNested  optional. the default  value is TRUE. It returns all the nested iWidgets if it's true. It returns only direct children if it's false.
@type  com.ibm.mashups.iwidget.widget. IWidgetWrapper[]
@returns{com.ibm.mashups.iwidget.widget. IWidgetWrapper[]}  return an array of iWidgetWrapper object .
*/
	getChildren:function(iWidgetWrapper,isNested){
	},
/**
Returns  the parent object of the specified iWidgetWrapper object . <br/>
@param{com.ibm.mashups.iwidget.widget. IWidgetWrapper} iWidgetWrapper  iWidgetWrapper object. Must not be NULL.
@type com.ibm.mashups.iwidget.widget. IWidgetWrapper
@returns{com.ibm.mashups.iwidget.widget. IWidgetWrapper } returns parent node or NULL if the node has no parent.
*/
	getParent:function(iWidgetWrapper){
	},

/**
Returns the deferred object used to start this operation and an IWidgetDefinition object is returned when deferred object is executed.<br/>
<code>var deferred = widgetModel.getWidgetDefinitionByUrl(url)</code><br/>
<code>deferred.setFinishedCallback(callback,parameters);</code><br/>
<code>deferred.start(false);</code><br/>
here are the callback parameters that will be passed into callback function: <br/>
 &nbsp;&nbsp;&nbsp;&nbsp;<code>resource</code> -  IWidgetDefinition object <br>
&nbsp;&nbsp;&nbsp;&nbsp;<code>statuscode</code> - the HTTP status,code of the action .<br>
&nbsp;&nbsp;&nbsp;&nbsp;<code>params</code> - optional.  may use this to pass additional parameters  into the callback .<br>
here is a sample implementation of callbackfunction:<br/>
 &nbsp;&nbsp;&nbsp;&nbsp;<code>function callback(resource, statuscode, params) { </code><br/>
 &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<code>  if (statuscode == 200) {   </code><br/>
 &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<code>  var defObj = resource;</code><br/>
 &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<code> ... }</code><br/>
 &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<code> } </code><br/>
@param{String} url  url to load widget definition. Must not be NULL.
@type com.ibm.mashups.enabler.Deferred
@returns{com.ibm.mashups.enabler.Deferred}  a deferred object used to start this operation.
@see com.ibm.mashups.iwidget.widget.IWidgetDefinition
@deprecated Use getWidgetDefinitionByURL instead.
*/
	getWidgetDefinitionByUrl:function(url){
	},
/**
Returns the deferred object used to start this operation and an IWidgetDefinition object is returned when deferred object is executed.<br/>
<code>var deferred = widgetModel.getWidgetDefinitionByUrl(url)</code><br/>
<code>deferred.setFinishedCallback(callback,parameters);</code><br/>
<code>deferred.start(false);</code><br/>
here are the callback parameters that will be passed into callback function: <br/>
 &nbsp;&nbsp;&nbsp;&nbsp;<code>resource</code> -  IWidgetDefinition object <br>
&nbsp;&nbsp;&nbsp;&nbsp;<code>statuscode</code> - the HTTP status,code of the action .<br>
&nbsp;&nbsp;&nbsp;&nbsp;<code>params</code> - optional.  may use this to pass additional parameters  into the callback .<br>
here is a sample implementation of callbackfunction:<br/>
 &nbsp;&nbsp;&nbsp;&nbsp;<code>function callback(resource, statuscode, params) { </code><br/>
 &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<code>  if (statuscode == 200) {   </code><br/>
 &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<code>  var defObj = resource;</code><br/>
 &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<code> ... }</code><br/>
 &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<code> } </code><br/>
@param{String} url  url to load widget definition. Must not be NULL.
@type com.ibm.mashups.enabler.Deferred
@returns{com.ibm.mashups.enabler.Deferred}  a deferred object used to start this operation.
@see com.ibm.mashups.iwidget.widget.IWidgetDefinition
*/
	getWidgetDefinitionByURL:function(url){
	},

    /**
    * Commits the modifications applied to this model and all dependent models.<br>
    * @return {DeferredOperation} a deferred object used to start this operation.
    * The return value when executed through the deferred object is <code>null</null>
    */
    commit:function(){
        //summary: This method persists the data
    },

	/**
Returns iWidgetDefinition object for the specified JSON object. <br/>
@param{Object} json  JSON object. Must not be NULL.
@type com.ibm.mashups.iwidget.widget. IWidgetWrapper
@return{com.ibm.mashups.iwidget.widget.IWidgetDefinition} returns the IWidgetDefinition representation of the JSON object.
@see com.ibm.mashups.iwidget.widget.IWidgetDefinition
	 */
	createIWidgetDefinition:function(json) {
        //create WidgetDefinition based on JSON object
	},

	/**
Creates a widget and associates it with a span element on the page <br/>
@param{Object} span  DOMElement to associate the widget with.  Must not be NULL.
@return{com.ibm.mashups.iwidget.widget.IWidgetWrapper} returns the IWidgetWrapper representation of the JSON object. May be NULL.
	 */
	createWidget:function(span) {
	}
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.hub.ManagedHubImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.hub.ManagedHubImpl"] = true;
dojo.provide("com.ibm.mm.enabler.hub.ManagedHubImpl");



dojo.declare("com.ibm.mm.enabler.hub.ManagedHubImpl", null, {
    constructor: function() {
        //implement singleton
        //allow any products to use enabler extensionregistry to plugin their own publishMgr and subscribeMgr,security manager
        //sample code
        /*var extensions = [];
         extensions.push({
         "com.ibm.mm.enabler.hub.ManagedHubImpl.publishMgr": {
         type: "around",
         handler: function ( executor, fnArgs ) { //executor is the default impl. function
         var topic = fnArgs[0];
         var data = fnArgs[1];
         var pubClientID = fnArgs[2];
         var subClientID = fnArgs[3];
         //do logic here...
         return;
         }
         }
         });
         */
    },
    publishMgr: function(topic, data, pubClient, subClient) {
        var pubClientID = pubClient ? pubClient.getClientID() : "manager";
        var subClientID = subClient ? subClient.getClientID() : "manager";
        var that = com.ibm.mm.enabler.hub.ManagedHubImpl._instance;
        return true;
    },
    subscribeMgr: function(topic, client) {
        var clientID = client ? client.getClientID() : "manager";
        var that = com.ibm.mm.enabler.hub.ManagedHubImpl._instance;
        return true;
    },
    securityMgr: function(source, alertType) {
        var that = com.ibm.mm.enabler.hub.ManagedHubImpl._instance;
    },
    getInstance: function() {
        //Hub api doc and sample is out of sync,need to confirm parameters
        var hub = com.ibm.mm.enabler.hub.ManagedHubImpl._instance;
        if (!hub) {
            com.ibm.mm.enabler.hub.ManagedHubImpl._instance = new OpenAjax.hub.ManagedHub({
                onPublish: this.publishMgr,
                onSubscribe: this.subscribeMgr,
                onSecurityAlert: this.securityMgr
            });
            hub = com.ibm.mm.enabler.hub.ManagedHubImpl._instance;
        }
        return hub;
    }
});

com.ibm.mm.enabler.hub.ManagedHubImpl = new com.ibm.mm.enabler.hub.ManagedHubImpl();

}

if(!dojo._hasResource["com.ibm.mm.enabler.hub.SubDomainPoolImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.hub.SubDomainPoolImpl"] = true;
dojo.provide("com.ibm.mm.enabler.hub.SubDomainPoolImpl");






dojo.declare("com.ibm.mm.enabler.hub.SubDomainPoolImpl", null, {
    constructor: function(arr) {
        if (arr) {
            this._pool = arr;
            this._internalPool = dojo.clone(this._pool);
        }
        else {
            this._counter = 0;
            this._reusedSubDomain = [];
        }
        this.configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
        this.reuseSubDomain = this.configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.SUBDOMAINREUSE);
    },
    getSize: function() {
        if (this._internalPool) {
            return this._internalPool.length;
        }
        return -1; //unlimited
    },
    //get next available
    get: function() {
        if (this._pool) {
            return this._getFromPool();
        }

        var cnt = this._counter;
        if (this.reuseSubDomain) {
            if (this._reusedSubDomain.length > 0) {
                cnt = this._reusedSubDomain.shift();
                return cnt;
            }
            else {
                this._counter++;
            }
        }
        else {
            this._counter++;
        }
        return "w" + cnt;

    },
    //add old one back to pool for use eg. widget is deleted from the page
    add: function(subDomain) {
        if (!this.reuseSubDomain) {
            return;
        }
        if (this._pool) {
            return this._addToPool(subDomain);
        }
        else {
            this._reusedSubDomain.push(subDomain);
        }
        return;
    },
    _getFromPool: function() {
        if (this._pool.length === 0) {
            return null;
        }
        return this._pool.shift();
    },
    _addToPool: function(subDomain) {
        this._pool.push(subDomain);
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.hub.XHRHeaderExtensionImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.hub.XHRHeaderExtensionImpl"] = true;
dojo.provide("com.ibm.mm.enabler.hub.XHRHeaderExtensionImpl");



dojo.declare("com.ibm.mm.enabler.hub.XHRHeaderExtensionImpl", null, {
    constructor: function() {
        this.originalDojoXHR = dojo.xhr;

        dojo.xhr = dojo.hitch(this, function(/* String */method, /* dojo.__XhrArgs */ args, /* Boolean */ hasBody) {
            if (!args.headers) {
                args.headers = {};
            }
            args.headers["com.ibm.lotus.openajax.virtualhost"] = document.location.hostname;
            args.headers["com.ibm.lotus.openajax.virtualport"] = document.location.port;
            var ret = this.originalDojoXHR(method, args, hasBody);
            return ret;
        });
    }
});

com.ibm.mm.enabler.hub.XHRHeaderExtension = new com.ibm.mm.enabler.hub.XHRHeaderExtensionImpl();

}

if(!dojo._hasResource["com.ibm.mm.enabler.hub.MainHubAdapterImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.hub.MainHubAdapterImpl"] = true;
dojo.provide("com.ibm.mm.enabler.hub.MainHubAdapterImpl");









dojo.declare("com.ibm.mm.enabler.hub.MainHubAdapterImpl", null, {
    constructor: function(managedhub) {
        this._managedhub = managedhub;
        //this._inlineContainerArr = {};
        //this._iframeContainerArr = {};
        this._inlineHubClients = {};
    },
    PREFIX_INLINE: "_inline_",
    PREFIX_IFRAME: "_iframe_",
    createInlineHubContainer: function(id) {
        var fullId = this.PREFIX_INLINE + id;
        var me = this;

        function onClientConnect(container) {
        }
        function onClientDisconnect(container) {
        }
        function onClientSecurityAlert(container, securityAlert) {
        }
        function onClientError(container, error) {
        }

        var params = {
            Container: {
                onConnect: onClientConnect,
                onDisconnect: onClientDisconnect,
                onSecurityAlert: onClientSecurityAlert,
                onError: onClientError
            }
        };
        var client = new OpenAjax.hub.InlineContainer(this._managedhub, fullId, params);
        return client;
    },
		createIframeHubContainer:function(id,/*domNode*/widget,/*uri*/uri,isModal,width,height, myOnClientSecurityAlert){

        var fullId = this.PREFIX_IFRAME + id;

        var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
        var enablerContext = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT_ENABLER);
        var tunnelPath = enablerContext + "/js/openajaxhub/rpc_relay.html";

        var schema = window.location.protocol;
        var host = window.location.hostname;
        var port = window.location.port;
        var tunnelUri = schema + "//" + host + ":" + port + tunnelPath;
        if (port == "") {
            tunnelUri = schema + "//" + host + tunnelPath;
        }
        var me = this;
        function onClientConnect(container) {
        }
        function onClientDisconnect(container) {
        }
        function onClientSecurityAlert(container, securityAlert) {
        }
        try {
            var w,h;
            this.removeIframeHubContainer(id); // remove any that already exists so there is never duplicate
            if (isModal && isModal == "true") {
                w = "600px";
                h = "400px";
            }
            else {
                w = "100%";
                h = "100%";
            }
            if (width) {
                w = width;
            }
            if (height) {
                h = height;
            }

			if (myOnClientSecurityAlert) {
				onClientSecurityAlert = myOnClientSecurityAlert;
			}

            var client = new OpenAjax.hub.IframeContainer(this._managedhub, fullId, {
                Container: {
                    onConnect: onClientConnect,
                    onDisconnect: onClientDisconnect,
                    //	      log:function(msg){
                    //	   	console.log("!!!!!!"+msg);
                    //	   },
                    onSecurityAlert: onClientSecurityAlert

                },
                IframeContainer: {
                    //uri: "http://c" + i + ".foo.bar.com/hub11/samples/plain_hub/widgetSender.html",
                    uri: uri,
                    tunnelURI: tunnelUri,
                    //    timeout:1000000000,
                    parent: widget,
                    //	iframeAttrs:{ style: { width: "100%", height: "100%" },scrolling:"no" }
                    iframeAttrs: {
                        title: "iframe",
                        style: {
                            width: w,//need to set default size since IE7/6 either have wierd or no default size at all
                            height: h,
                            border: "0px",
                            overflow: "auto"
                        }/*,
                        id: "iframe_" + id,
                        name: id*/
                    },
                    timeout: 1200000
                }
            });
        }
        catch (e) {
        }
    },
    createInlineHubClient: function(id) {
        //create hub client and connect to hub
        var fullId = this.PREFIX_INLINE + id;
        var me = this;

        var container = this._managedhub.getContainer(fullId);
        function onHubClientSecurityAlert(source, alertType) {
        }
        var hubClient1 = new OpenAjax.hub.InlineHubClient({
            HubClient: {
                onSecurityAlert: onHubClientSecurityAlert
            },
            InlineHubClient: {
                container: container
            }
        });
        function onHubClientConnect(client, success, error) {
        }
        hubClient1.connect(onHubClientConnect);
        this._inlineHubClients[fullId] = hubClient1;
        return hubClient1;
    },
    _getInlineHubClient: function(id) {
        if (!id) {
            return null;
        }
        var fullId = this.PREFIX_INLINE + id;
        var client = this._inlineHubClients[fullId];
        if (typeof client == "undefined") {
            client = null;
        }
        return client;
    },
    getInlineHubClient: function(id) {
        if (!id) {
            return this._managedhub;
        }
        var client = this._getInlineHubClient(id);
        return client ? client : this._managedhub;
    },
    isInlineClient: function(id) {
        var rc = false;
        var hubClient = this._getInlineHubClient(id);
        if (hubClient) {
            rc = true;
        }
        return rc;
    },
    removeInlineHubClient: function(id) {
        //eg. widget is removed from the page
        var hubClient = this._getInlineHubClient(id);
        var fullId = this.PREFIX_INLINE + id;
        if (hubClient) {
            var me = this;
            var onHubClientDisconnect = function (client, success, error) {
            };
            hubClient.disconnect(onHubClientDisconnect);

            delete this._inlineHubClients[fullId];
            //var inlineContainer = this._inlineContainerArr[fullId];
            var inlineContainer = this._managedhub.getContainer(fullId);
            if (inlineContainer) {
                this._managedhub.removeContainer(inlineContainer);
            }
            return;
        }
    },
	getContainer:function(id,isIframe){
		isIframe = isIframe || false;
		if (isIframe === true) {
			id = this.PREFIX_IFRAME + id;
		}
		return this._managedhub.getContainer(id);
	},
    removeIframeHubContainer: function(id) {
        var fullId = this.PREFIX_IFRAME + id;
        var iframeContainer = this._managedhub.getContainer(fullId);
        if (iframeContainer) {
            this._managedhub.removeContainer(iframeContainer);
        }
    },
    returnSubDomain: function(subDomain) {
        this.getSubDomainPool().add(subDomain);
    },
    getSubDomainSize: function() {
        return this.getSubDomainPool().getSize();
    },
    getSubDomain: function() {
        return this.getSubDomainPool().get();
    },
    getSubDomainPool: function() {
        if (!this.subDomainPool) {
            var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
            var subDomains = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.SUBDOMAINS);
            if (subDomains) {
                if (dojo.isArray(subDomains) && subDomains.length !== 0) {
                    this.subDomainPool = new com.ibm.mm.enabler.hub.SubDomainPoolImpl(subDomains);
                }
            }
            if (!this.subDomainPool) {
                this.subDomainPool = new com.ibm.mm.enabler.hub.SubDomainPoolImpl();
            }
        }
        return this.subDomainPool;
    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.services.EventService"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.services.EventService"] = true;
dojo.provide("com.ibm.mm.iwidget.services.EventService");




// inject this service into the ServiceManager at the end. Therefore we have to require the implementation








dojo.declare("com.ibm.mm.iwidget.services.EventServiceDefaultImpl", com.ibm.mashups.iwidget.services.EventService, {
    constructor: function(){
        this.subMgr = {};
        this.managedhub = com.ibm.mm.enabler.hub.ManagedHubImpl.getInstance();
        this.hubAdapter = new com.ibm.mm.enabler.hub.MainHubAdapterImpl(this.managedhub);
        this._subscribeEventService();
        if (this.registerServices) {
            this.registerServices();
        }
        if (this.registerExtServices) {
            this.registerExtServices();
        }
    },
    getType: function(){
        return com.ibm.mm.iwidget.Constants.eventservice.type.MAIN;
    },
    registerServices: function(){
        //listen to request to change widget mode
        var event = com.ibm.mashups.iwidget.Constants.CHANGE_WIDGETMODE;
        var me = this;
        var eventCallback = function(payload){
            var widgetId = payload.id;
            var newMode = payload.newMode;
            var parentNode = payload.parentNode;
            me.fireEvent(widgetId, "onModeChanged", {
                newMode: newMode,
                rootElementId: parentNode
            });
        };
        this.subscribeEvent(event, null, eventCallback, null, null);
    },
    setId: function(id){
        this.id = id;
    },
    getId: function(){
        return "main";
    },
    _subscribeEventService: function(){
        //dispatch event to each method....for now, just fireEvent
        //in future, broadcastEvent... has security concern though
        var that = this;
        // message should contain
        // methodname:fireEvent
        // params:{}
        // hubclient:hubclientid
        function eventCallback(topic, message, subscribeData){
            //(targetWidget,targetEvent,message.payload,message.payloadType,sourceWidget)
            var methodname = message.methodname;
            if (methodname) {
                var fn = that[message.methodname];
                if (fn) {
                    that[methodname].apply(that, message.params);
                }
            }
        }
        this.managedhub.subscribe("eventservice." + this.getId(), eventCallback, that, that._subscribeCallback);
    },
    _subscribeCallback: function(subHandle, success,/*OpenAjax.hub.Error*/ error){
        //common _subscribeCallback function
        if (!success) {
            console.log("subscribe failed " + subHandle);
        }
    },
    _getHubAdapter: function(){
        return this.hubAdapter;
    },
    _getManagedHub: function(){
        return this.managedhub;
    },
    WIDGETEVENT_PREFIX: iwConstants.WIDGETEVENT_PREFIX,
    WILDCARD_PREFIX: iwConstants.WILDCARD_PREFIX,
    subscribeWire: function(/*String*/sourceWidget,/*String*/ sourceEvent,/*String*/ targetWidget,/*String*/ targetEvent){
        return false;
    },
    publishWire: function(/*String*/sourceWidget,/*String*/ sourceEvent,/*object*/ payload,/*String*/ payloadType){
        return false;
    },
    unSubscribeWire: function(sourceWidget, sourceEvent, targetWidget, targetEvent){
        return false;
    },
    addWire: function(sourceWidget, sourceEvent, targetWidget, targetEvent){
        return false;
    },
    removeWire: function(sourceWidget, sourceEvent, targetWidget, targetEvent){
        return false;
    },
    fireEvent: function(targetWidget, targetEvent, payload, payloadType, sourceWidget){
        //allows a third party to fire a event in a target widget
        var aEvent = new com.ibm.mm.iwidget.IEventImpl(targetEvent, payloadType, payload, sourceWidget);
        //need to make sure  the widget is loaded
        var widgetModel = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel();
        var widget = widgetModel.find(targetWidget);

        var cb = function(eventSvr, targetWWrapper, aEvent, subscribeID){
            var isInlineClient = eventSvr.hubAdapter.isInlineClient(targetWWrapper.id);
            if (isInlineClient) {
                eventSvr._publishEvent(eventSvr.WIDGETEVENT_PREFIX + targetWWrapper.id, aEvent, aEvent.source);
            }
            else {
                var payloadObj = {};
                if (aEvent.name == iwConstants.EVENTS.onModeChanged) {
                    payloadObj.methodname = "_handleOnModeChange";
                    payloadObj.params = [payload];
                    targetWWrapper.handleEvent(payloadObj);
                    return;
                }

                payloadObj.methodname = "fireEvent";
                payloadObj.hubclient = eventSvr.getId();
                payloadObj.params = [targetWWrapper.id, aEvent.name, aEvent.payload, aEvent.type];
                eventSvr._publishEvent("eventservice." + targetWWrapper.id, payloadObj);
            }
            if (subscribeID) { //delete subscriber
                var subHandle = eventSvr.subMgr[subscribeID];
                if (subHandle) {
                    eventSvr.unsubscribeEvent(subHandle);
                }
                delete eventSvr.subMgr[subscribeID];
            }
        };
        if (widget && widget.isLoaded()) {
            cb(this, widget, aEvent);
        }
        else {
            var that = this;
            //subscribe widgetloaded event with callback
            //var subscribeID = com.ibm.mashups.iwidget.Constants.WIDGET_LOADED + "." + targetWidget;
            var subscribeID = dojox.uuid.generateRandomUuid();
            var subHandle = this.subscribeEvent(com.ibm.mashups.iwidget.Constants.WIDGET_LOADED + "." + targetWidget, null, function(){
                var widget = widgetModel.find(targetWidget);
                cb(that, widget, aEvent, subscribeID);
            });
            this.subMgr[subscribeID] = subHandle;
        }
    },
    //support pagechanged event and widget deleted event
    publishEvent: function(sourceEvent, payload, payloadType, sourceid){
        // dojo dojo.publish(topic: String, args: Array);
        if (typeof sourceEvent == "undefined" || sourceEvent === null) {
            return;
        }
        var temp;
        if (sourceEvent.indexOf(this.WILDCARD_PREFIX) === 0) {
            temp = this.WILDCARD_PREFIX;
            return this.broadcastEvent(sourceEvent.substring(temp.length), payload, payloadType, sourceid);
        }
        else
            if (sourceEvent.indexOf(this.WIDGETEVENT_PREFIX) === 0) {
                temp = sourceEvent.substring(this.WIDGETEVENT_PREFIX.length);
                var widget = temp.substring(0, temp.indexOf("."));
                var event = temp.substring(temp.indexOf(".") + 1);
                return this.fireEvent(widget, event, payload, payloadType, sourceid);
            }
        this._publishEvent(sourceEvent, payload, sourceid);
    },
    _publishEvent: function(event, payload, sourceid){
        //internal use
        /*payload; need to be json object if it's openajax hub, for now, it's dojo, so it need to be array*/
        var client = this.hubAdapter.getInlineHubClient(sourceid);
        if (typeof payload == "undefined" || payload === null) {
            client.publish(event);
        }
        else {
            client.publish(event, payload);
        }
    },
    broadcastEvent: function(targetEvent, payload, payloadType, sourceid, pageid, spaceid){
        var eventObj = {};
        eventObj.targetEvent = targetEvent;
        eventObj.payload = payload;
        eventObj.payloadType = payloadType;
        this.broadcastEvents([eventObj], sourceid, pageid, spaceid);
        return;
    },

    broadcastEvents: function(eventsArray, sourceid, pageid, spaceid){
        if ((eventsArray === null) || !dojo.isArray(eventsArray)) {
            return;
        }
        var navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
        var spaceAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getSpaceAccessor(navStateModel);
        var currentSpaceID = spaceAccessor.getSpaceID();
        var pageAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getPageAccessor(navStateModel, currentSpaceID);
        var currentPageID = pageAccessor.getPageID();

        var switchPage = ((pageid) && (typeof pageid == "string") && (pageid != currentPageID));
        if (switchPage) {
        	this._switchPageForBroadcastEvents(eventsArray, sourceid, pageid, spaceid, navStateModel, spaceAccessor, currentSpaceID);
        }
        else {
            var subscribeID;
            var subHandle;
            // no switch page - stay on current page
            var widgetModel = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel();
            var widgets = widgetModel.getAllWidgets();
            var that = this;
            var checkHandledEvents = function(widget, eventsArray, subscribeID){
                var handledEvents = widget.getWidgetHandledEvents();
                if (handledEvents === null) {
                    // This is a hack for 15760
                    // In some instances the handled events aren't initialized on the IWidgetWrapper.
                    // If handledEvents comes back null get the events off the IWidgetDefinition.
                    var widgetDefinition = widget.getIWidgetDefinition().start();
                    if (widgetDefinition) {
                        handledEvents = widgetDefinition.getWidgetHandledEvents();
                    }
                }

                if (handledEvents) {
                    for (var i = 0; i < eventsArray.length; i++) {
                        for (var j = 0; j < handledEvents.length; j++) {
                            if (eventsArray[i].targetEvent == handledEvents[j].name) {
                                that.fireEvent(widget.getID(), eventsArray[i].targetEvent, eventsArray[i].payload, eventsArray[i].payloadType, sourceid);
                                break;
                            }
                        }
                    }
                }
                if (subscribeID) {
                    var subHandle = that.subMgr[subscribeID];
                    if (subHandle) {
                        that.unsubscribeEvent(subHandle);
                    }
                    delete that.subMgr[subscribeID];
                }
            };
            var isSubscribed = false;
            for (var i in widgets) {
                if (Object.prototype.hasOwnProperty.call(widgets, i)) {
                    var aWidget = widgets[i];
                    if (aWidget.isLoaded()) {
                        checkHandledEvents(aWidget, eventsArray);
                    }
                    else {
                        if (!aWidget.lazyLoad) {
                            isSubscribed = true;
                            subscribeID = dojox.uuid.generateRandomUuid();
                            subHandle = this.subscribeEvent(com.ibm.mashups.iwidget.Constants.WIDGET_LOADED + "." + aWidget.getID(), null, dojo.partial(checkHandledEvents, aWidget, eventsArray, subscribeID));
                            this.subMgr[subscribeID] = subHandle;
                        }
                    }
                }
            }
            // we are not allowed to verify for subscription anymore as the target widget is not yet in the global widget model after page switch. This happens later
            if ((eventsArray.length > 0) && (eventsArray[0].targetEvent === "com.ibm.mashups.builder.skinLoaded")) {
                subscribeID = dojox.uuid.generateRandomUuid();
                subHandle = this.subscribeEvent(com.ibm.mashups.iwidget.Constants.WIDGET_LOADED + "." + eventsArray[0].payload.widgetId, null, function(){
                    that._handleBroadcastEventsCache();
                    var subHandle = that.subMgr[subscribeID];
                    if (subHandle) {
                        that.unsubscribeEvent(subHandle);
                    }
                });
                this.subMgr[subscribeID] = subHandle;
            }
            for (var j = 0; j < eventsArray.length; j++) {
                this._publishEvent(eventsArray[j].targetEvent, eventsArray[j].payload, sourceid);
            }
        }
        return;
    },
	_switchPageForBroadcastEvents: function(eventsArray, sourceid, pageid, spaceid, navStateModel, spaceAccessor, currentSpaceID) {
    	// noop - implemented by subclass
    	// no pages in core or minimal layer, so only switch page in model layer
    },
    _handleBroadcastEventsCache: function(){
    	// noop - implemented by subclass
    	// no pages in core or minimal layer, so only switch page in model layer
    },
    _subscribeEvent: function(event, object, eventCallback, subscribeCallback, sourceid){
        var client = this._getHubAdapter().getInlineHubClient(sourceid);
        //return dojo.subscribe(event,object,eventCallback);
        //return subscription id for openajax hub

        var subHandle1 = client.subscribe(event, function(topic, data, subscriberData){ /*onData*/
            var ec = eventCallback;
            if (object && eventCallback) {
                ec = dojo.hitch(object, eventCallback);
            }

            //Deserialize data,not necessary

            if (ec) {
                ec(data);
            }
        }, null /* scope */, function(subID, success, error){ /*onComplete*/
            if (object && subscribeCallback) {
                subscribeCallback = dojo.hitch(object, subscribeCallback);
            }
            if (subscribeCallback) {
                subscribeCallback.apply(this, [subID, success, error]);
            }
            if (!success) {
                console.log("subscription for " + subID + " failed");
                return;
            }
        });
        return subHandle1;
    },
    subscribeEvent: function(event, object, eventCallback, subscribeCallback, sourceid){
        return this._subscribeEvent(event, object, eventCallback, subscribeCallback, sourceid);
    },
    _unsubscribeEvent: function(subscriptionHandler, sourceid){
        var client = this._getHubAdapter().getInlineHubClient(sourceid);
        try {
            if (client) {
                client.unsubscribe(subscriptionHandler);
            }
        }
        catch (e) {//workaround for hub bug
            console.log("unsubscribe failure:" + e);
        }
    },
    unsubscribeEvent: function(subscriptionHandler, sourceid){
        if (!subscriptionHandler) {
            return;
        }
        this._unsubscribeEvent(subscriptionHandler, sourceid);
    },
    _generateWireId: function(sourceWidget, sourceEvent, targetWidget, targetEvent){
        return sourceWidget + "_" + sourceEvent + "_" + targetWidget + "_" + targetEvent;
    }
});

if (!ibmConfig.insideSandbox) {
    com.ibm.mashups.services.ServiceManager.setService("eventService", "com.ibm.mm.iwidget.services.EventServiceDefaultImpl");
}
// IMPORTANT
// ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
// This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "iWidget") >= 0)) {
    dojo["require"]("com.ibm.mm.iwidget.services.EventServiceExtended"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
    dojo["require"]("com.ibm.mm.iwidget.services.IFrameEventServiceImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
}

}

if(!dojo._hasResource["com.ibm.mm.iwidget.model.WidgetModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.model.WidgetModel"] = true;
dojo.provide("com.ibm.mm.iwidget.model.WidgetModel");










dojo.declare("com.ibm.mm.iwidget.model.WidgetModelDefaultImpl", com.ibm.mashups.iwidget.model.WidgetModel, {
    constructor: function() {
        this.widgetArr = {}; //associate array since it provides direct access
        this.parentMap = {}; // maps from widget id to parent widget id
        this.eventService = com.ibm.mashups.services.ServiceManager.getService("eventService");
        this.eventService.subscribeEvent(com.ibm.mashups.iwidget.Constants.UNLOAD_WIDGETS, this, "_unloadWidgets");

        if (!ibmConfig || (ibmConfig && typeof ibmConfig.loadingHTML != "string")) { // only preload anim gif if loadingHTML is not set
            if (ibmConfig["loadingHTML.imageURL"]) {
                this.processAnim = com.ibm.mm.enabler.utils.Misc.preloadImage(ibmConfig["loadingHTML.imageURL"], 20, 20);
            }
            else {
                var url = new dojo.moduleUrl("com.ibm.mm.iwidget", "image/");
                url = url + "progress-anim.gif";
                this.processAnim = com.ibm.mm.enabler.utils.Misc.preloadImage(url, 20, 20);
            }
        }
        dojo.addOnWindowUnload(this, "_onWindowUnload");
        this.global = dojo.global;
        this.doc = dojo.doc;
    },
    _onWindowUnload: function() {
        try {
            var arr = [];
            for (var i in this.widgetArr) {
                if (Object.prototype.hasOwnProperty.call(this.widgetArr,i)) {
                    this._unloadWidget(i); //use _unloadWidget to avoid pulish event com.ibm.mashups.iwidget.Constants.WIDGETS_UNLOADED
                }
            }
        }
        catch (e) {
            console.log("_onWindowUnload " + e.message);
        }
    },
    createWidget: function(/*DomElment*/widgetSpan) {
        // for now by design id is required attribute for each widget
        var id = widgetSpan.getAttribute("id");
        if (typeof(id) == "undefined") {
            return null;
        }

        // each fragment is uniquely identified by the widget id, thus we don't
        // support different fragment that shares the same id the old one will
        //be deleted
        var oldWidget = this.widgetArr[id];
        if (typeof oldWidget != "undefined" && oldWidget !== null) {
            var oldfragment = oldWidget.rootElement;
            if (oldfragment == widgetSpan) { //eg. switch skin if it's the same dom node
                return oldWidget;
            }
            else {
                this._unloadWidget(id);
            }
        }

        var aWidget = new com.ibm.mm.iwidget.widget.IWidgetWrapperImpl(widgetSpan, id);
        this.widgetArr[id] = aWidget;
        //this.parentMap[id] = aWidget._getParent();
        this.parentMap[id] = "DEFER_TOKEN";
        return aWidget;
    },
    createIWidgetDefinition: function(/*Object*/json) {
        return new com.ibm.mm.iwidget.widget.IWidgetDefinitionImpl(null, null, json);
    },

    find: function(/*String*/id) {
        var widget = this.widgetArr[id];
        if (typeof widget != "undefined") {
            if (widget.lazyLoad && !widget.loaded) {
                this.renderWidget(widget);
                delete widget.lazyLoad;
            }
            return widget;
        }
        return null;
    },
    getWidgetById: function(/*String*/id) { //deprecated
        return this.find(id);
    },
    commit: function() {
        return new com.ibm.mm.enabler.DeferredOperationImpl(this, this._commit);
    },
    _commit: function(deferred, sync) {
        // iterate through my widgets and see whether any itemset is dirty or not.
        for (var widgetId in this.widgetArr) {
            if (Object.prototype.hasOwnProperty.call(this.widgetArr,widgetId)) {
                var widgetWrapper = this.widgetArr[widgetId];
                var widgetInstance = widgetWrapper.getIWidgetInstance();

                if (!widgetInstance) {
                    continue;
                }
                widgetWrapper.commit();
            }
        }
    },
    _unloadWidgets: function(/*[]*/arr) {
        var aWidget;
        if (typeof arr != "undefined" || arr !== null) {
            if (dojo.isArray(arr)) {
                for (var i in arr) {
                    if (Object.prototype.hasOwnProperty.call(arr,i)) {
                        aWidget = arr[i];
                        this._unloadWidget(aWidget);
                    }
                }
                dojo.publish(com.ibm.mashups.iwidget.Constants.WIDGETS_UNLOADED, [arr]);
                this.eventService.publishEvent(com.ibm.mashups.iwidget.Constants.WIDGETS_UNLOADED, arr);
            }
            else if (dojo.isString(arr)) {
                this._unloadWidget(arr);
            }
        }
    },
    _unloadWidget: function(aWidget) {
        if (typeof this.widgetArr[aWidget] != "undefined" && this.widgetArr[aWidget] !== null) {

            var widgetwrapper = this.widgetArr[aWidget];
            try {
                widgetwrapper.destroy();
            }
            catch (e) {
            }
            delete this.widgetArr[aWidget];
            if (this.parentMap[aWidget]) {
                delete this.parentMap[aWidget];
            }
        }
    },
    getParent: function(widget) {
        var parentId = this.parentMap[widget.getID()];
        if (parentId && parentId == "DEFER_TOKEN") {
            parentId = widget._getParent();
            this.parentMap[widget.getID()] = parentId;
        }
        if (parentId) {
            parent = this.find(parentId);
        }
        return parent || null;
    },
    hasChildren: function(widget) {
        return (this.getChildren(widget, false).length === 0) ? false : true;
    },
    getChildren: function(widget, isNested) {
        this._checkParentMap();
        var children = [];
        var nested = (typeof isNested == "undefined") ? true : isNested;
        this._getChildren(widget, nested, children);
        return children;
    },
    _checkParentMap: function() {
        //make sure parent map is built
        for (var id in this.widgetArr) {
            if (Object.prototype.hasOwnProperty.call(this.widgetArr,id)) {
                var parentId = this.parentMap[id];
                if (parentId && parentId == "DEFER_TOKEN") {
                    var aWidget = this.widgetArr[id];
                    parentId = aWidget._getParent();
                    this.parentMap[id] = parentId;
                }
            }
        }
    },
    _getChildren: function(parent, nested, children) {
        // iterate parent map
        for (var id in this.parentMap) {
            // collect children
            if (this.parentMap[id] == parent.getID()) {
                var widget = this.find(id);
                if (widget) {
                    children.push(widget);
                    if (nested) {
                        // collect nested children
                        this._getChildren(widget, nested, children);
                    }
                }
            }
        }
    },
    // @deprecated
    getWidgetDefinitionByUrl: function(url) {
        return this.getWidgetDefinitionByURL(url);
    },
    getWidgetDefinitionByURL: function(url) {
        return new com.ibm.mm.iwidget.DeferredLoadImpl(url);
    },
    getAllWidgets: function() {
        return this.widgetArr;
    },

    renderWidget: function(/*Object*/iWidget) {
        if (typeof iWidget == "undefined") {
            return;
        }
        if (iWidget.loaded) {
            return;
        }
        iWidget.doRender();
    }


});

com.ibm.mm.iwidget.model.WidgetModelImpl = com.ibm.mm.iwidget.model.WidgetModelDefaultImpl;

// IMPORTANT
// ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
// This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "iWidget") >= 0)) {
    dojo["require"]("com.ibm.mm.iwidget.model.WidgetModelExtended"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
}

}

if(!dojo._hasResource["com.ibm.mm.iwidget.model.FactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.model.FactoryImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.model.FactoryImpl");




dojo.declare("com.ibm.mm.iwidget.model.FactoryImpl", com.ibm.mashups.iwidget.model.Factory, {
    constructor: function() {

    },
    getGlobalWidgetModel: function() {
        if (!this._globalWidgetModel) {
            this._globalWidgetModel = new com.ibm.mm.iwidget.model.WidgetModelImpl();
        }
        return this._globalWidgetModel;
    }
});
com.ibm.mashups.iwidget.model.Factory = new com.ibm.mm.iwidget.model.FactoryImpl();

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.model.Factory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.model.Factory"] = true;
dojo.provide("com.ibm.mashups.iwidget.model.Factory");




}

if(!dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateProcessorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateProcessorImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.state.NavigationStateProcessorImpl");
















dojo.declare("com.ibm.mm.enabler.model.state.NavigationStateProcessorImpl", com.ibm.mashups.enabler.model.state.NavigationStateProcessor, {

    constructor: function(){
        this.configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
        var persistenceURL = this.configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.NAVSTATE_PERSISTENCE_URL);
        if (persistenceURL) {
            this.persistenceURL = this._getAssociativeArray(persistenceURL);
        }
        var persistencePSTORE = this.configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.NAVSTATE_PERSISTENCE_PSTORE);
        if (persistencePSTORE) {
            this.persistencePSTORE = this._getAssociativeArray(persistencePSTORE);
        }
        var limit = this.configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.NAVSTATE_PERSISTENCE_URL_LIMIT);
        var index = 10;
        if (limit) {
            index = parseInt(limit, 10);
        }
        this.urlpersistenceLIMIT = index;
        var splimit = this.configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.NAVSTATE_PERSISTENCE_URL_SPLIMIT);
        index = 2;
        if (splimit) {
            index = parseInt(splimit, 10);
        }
        this.urlpersistenceSPLIMIT = index;
        this.isHuffmannEnabled = this.configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.NAVSTATE_HUFFMANNENCODE_ENABLED);
    },
    PID: "pid",
    SHAREDPARAMETERSETS: "sps",
    SID: "sid",
    HUFFMANN_PREFIX: "mashup:huffman/",
    encodeWidgetIdentifier: function(wid, nsm){
        return wid;
    },
    decodeWidgetIdentifier: function(wid, nsm){
        return wid;
    },
    dispose: function(callback){
        var cookieManager = com.ibm.mashups.enabler.model.state.CookieManager;
        var temp = cookieManager.disposeState();

        if (callback) {
            callback();
        }
    },
    _getAssociativeArray: function(array){
        var obj = {};
        if (dojo.isString(array)) {
            obj[array] = array;
            return obj;
        }
        for (var i in array) {
            if (Object.prototype.hasOwnProperty.call(array, i)) {
                var value = array[i];
                obj[value] = value;
            }
        }
        return obj;
    },
    decode: function(url, callback){
        if (url.indexOf(this.HUFFMANN_PREFIX) != -1) {
            var arr = url.split(this.HUFFMANN_PREFIX);
            var result = com.ibm.mm.enabler.encode.huffman.HuffmanURL.getDataFromHuffmanTree(arr[1]) || null;
            if (result) {
                url = arr[0] + result;
            }
        }

        var hash = this._getHash(url) || null; //this is the alrerady uri encoded url
        if (hash) {
            if (url.indexOf("#") != -1) {
                if (url.lastIndexOf("&") == (url.length - 1)) {
                    url = url.concat(hash);
                }
                else {
                    url = url.concat("#");
                    url = url.concat(hash);
                }
            }
            else {
                url = url.concat("#");
                url = url.concat(hash);
            }
        }

        var state = {};

        var httpUrl = new com.ibm.mm.enabler.utils.HttpUrl(url);
        var fragment = httpUrl.anchor;
        fragment = decodeURIComponent(fragment);
        if (fragment && fragment != "") {
            /*This string:
             "sid=testspace&pid=test&w0=testwidget&w0cp=%20spaces%20=blah"
             results in this object structure:
             {
             sid: "testspace",
             pid:"test",
             w0:"testwidget",
             w0cp: " spaces =blah"
             }
             */
            var parameters = dojo.queryToObject(fragment);
            var timestamp = new Date().getTime();
            if (parameters.pid) {
                state.pid = {};
                state.pid.value = decodeURIComponent(parameters.pid);
                state.pid.params = {};
                state.pid.params.lm = timestamp;
            }
            if (parameters.sid) {
                state.sid = {};
                state.sid.value = decodeURIComponent(parameters.sid);
                state.sid.params = {};
                state.sid.params.lm = timestamp;
            }
            if (parameters.sps) {
                state.sparams = {};
                rawValue = dojo.fromJson(decodeURIComponent(parameters.sps));
                //json object looks like this:
                // { name1:{value:<>,params:{lm:<>}},
                //   name2:{value:<>,params:{lm:<>}}
                // }
                state.sparams = rawValue;
            }

            state.wparams = {};

            //collect all the widget state parameters from url
            //10 should be the default
            //for example: w0,w1,w2...
            for (var i in parameters) {
                if (i.indexOf("w") === 0 && i.indexOf("cp") == -1 && i.indexOf("rp") == -1) {
                    var widgetData = {};
                    var index = i.substr(1) * 1 + timestamp;
                    var wID = parameters[i];
                    var wIndexCP = i + "cp";
                    var wIndexRP = i + "rp";
                    if (parameters[wIndexCP]) {
                        widgetData.value = widgetData.value ? widgetData.value : {};
                        try {
                            widgetData.value.cp = dojo.fromJson(decodeURIComponent(parameters[wIndexCP]));
                        }
                        catch (e) {
                            widgetData.value.cp = decodeURIComponent(parameters[wIndexCP]);
                        }
                        widgetData.params = widgetData.params ? widgetData.params : {};
                        widgetData.params.lm = index;
                    }
                    if (parameters[wIndexRP]) {
                        widgetData.value = widgetData.value ? widgetData.value : {};
                        try {
                            widgetData.value.rp = dojo.fromJson(decodeURIComponent(parameters[wIndexRP]));
                        }
                        catch (e2) {
                            widgetData.value.rp = decodeURIComponent(parameters[wIndexRP]);
                        }
                        widgetData.params = widgetData.params ? widgetData.params : {};
                        widgetData.params.lm = index;
                    }
                    state.wparams[wID] = widgetData;
                }
                else
                    if (i.indexOf("w") !== 0 && i != "pid" && i != "sid" && i != "sps" && i != "pageselection") {
                        //anything other than reserved parameters are state.params
                        var value = parameters[i];
                        state.params = state.params ? state.params : {};
                        state.params[i] = decodeURIComponent(value);
                    }
            }
        }
        if (callback) {
            callback(state);
        }
        if (!callback) {
            return state;
        }
    },
    _getFragmentFromData: function(obj, contains, notContains){
        var urlData;
        if (dojo.isString(obj)) {
            urlData = obj;
        }
        else {
            //var urlData = this._filterData(obj, contains, notContains);
            urlData = dojo.clone(obj);
            if (contains || notContains) {
                urlData = this._filterData(obj, contains, notContains);
            }
        }
        var realData = urlData;
        if (!dojo.isString(realData)) {
            if (this._isEmpty(realData)) {
                realData = null;
            }
            else {
                try {
                    realData = dojo.toJson(realData);
                }
                catch (e) {
                    realData = null;
                }
            }
        }
        return realData;
    },
    encode: function(state, callback, oldState, params, nsm){
        //change above state into url fragment as defined in CDD and url encoded
        var fragment = "";

        // params overrides config setting:
        // cp.noWidgets = "true" |
        // cp.widgetsOnCurrentPage = "true" |
        // cp.allWidgets = "true"
        var urlCp = {};
        var wm;
        if (params && params.cp) {
            urlCp = params.cp;
            if (urlCp.widgetsOnCurrentPage == "true") {
                wm = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel();
            }
        }
        var data;
        var pid;
        var sid;
        //pid
        if (state.pid && state.pid.value) {
            pid = state.pid.value;
        }
        if (!pid && state.sid && state.sid.value) {
            sid = state.sid.value;
            if (state.pageselection && state.pageselection[sid]) {
                pid = state.pageselection[sid].value;
            }
        }
        if (pid && this._contains("pid", this.persistenceURL)) {
            fragment = fragment + "pid" + "=" + encodeURIComponent(pid) + "&";
        }

        //sid
        if (!sid && state.sid && state.sid.value) {
            sid = state.sid.value;
        }
        if (sid && this._contains("sid", this.persistenceURL)) {
            fragment = fragment + "sid" + "=" + encodeURIComponent(sid) + "&";
        }

        for (var i in state) {
            if (Object.prototype.hasOwnProperty.call(state, i)) {
                if (i == "sparams") {
                    //json object looks like this:
                    // id: {
                    //   global:{ name1:{value:<>,params:{lm:<>,_listener:[]}},
                    //   		name2:{value:<>,params:{lm:<>}},
                    //	 <scope>:{ name1:{value:<>,params:{lm:<>,_listener:[]}},
                    //   		name2:{value:<>,params:{lm:<>}}
                    // }
                    if (state[i]) {
                        var sparamsData = dojo.clone(state[i]) || null;
                        this._removeHiddenParameters(sparamsData);
                        this._removeEmptyObj(sparamsData);
                        if (sparamsData && this._contains("sparams", this.persistenceURL)) {
                            fragment = fragment + "sps" + "=" + encodeURIComponent(dojo.toJson(sparamsData)) + "&";
                        }
                    }
                }
                if (i == "pageselection" && state[i]) {
                    data = dojo.clone(state[i]) || null;
                    if (data && this._contains("pageselection", this.persistenceURL)) {
                        fragment = fragment + "pageselection" + "=" + encodeURIComponent(dojo.toJson(data)) + "&";
                    }
                }
                // widgets! -- only save widget customized state to url and parameters defined in this.persistenceURL
                if (i == "wparams" && state[i] && !(urlCp.noWidgets == "true")) {
                    //it's a realarray after sorting
                    var widgetsData = this._sortData(dojo.clone(state[i]));//work with a clone copy...
                    if (widgetsData.length > this.urlpersistenceLIMIT) {
                        widgetsData = widgetsData.slice(widgetsData.length - this.urlpersistenceLIMIT);
                    }
                    var index = 0;
                    var realDataCp;
                    var realDataRp;
                    var allWidgets = urlCp.allWidgets == "true" || this._contains("cp", this.persistenceURL);
                    var widgetsOnPage = urlCp.widgetsOnCurrentPage == "true";
                    for (var j in widgetsData) {
                        if (Object.prototype.hasOwnProperty.call(widgetsData, j)) {
                            var widgetData = widgetsData[j] || null;
                            // add widget state only for widgets on the current page
                            if (widgetsOnPage && wm) {
                                if (widgetData && widgetData.wid) {
                                    var wid = dojo.isFunction(this.decodeWidgetIdentifier) ? this.decodeWidgetIdentifier(widgetData.wid, nsm) : widgetData.wid;
                                    if (wm.find(wid) === null) {
                                        continue;
                                    }
                                }
                            }
                            if (widgetData && widgetData.value) {
                                realDataCp = null;
                                realDataRp = null;
                                if (widgetData.value.cp && (allWidgets || widgetsOnPage)) {
                                    realDataCp = this._getFragmentFromData(widgetData.value.cp) || null;
                                }
                                if (widgetData.value.rp) {
                                    realDataRp = this._getFragmentFromData(widgetData.value.rp, this.persistenceURL) || null;
                                }
                                if (realDataCp || realDataRp) {
                                    //always persist widget customized data
                                    fragment = fragment + "w" + index + "=" + widgetData.wid + "&";
                                    if (realDataCp) {
                                        fragment = fragment + "w" + index + "cp=" + encodeURIComponent(realDataCp) + "&";
                                    }
                                    if (realDataRp) {
                                        fragment = fragment + "w" + index + "rp=" + encodeURIComponent(realDataRp) + "&";
                                    }
                                    index++;
                                    if (index >= this.urlpersistenceLIMIT) {
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }

                //any params will be in the url
                if (i == "params" && state[i]) {
                    var data1 = state[i];
                    for (var k in data1) {
                        if (Object.prototype.hasOwnProperty.call(data1, k)) {
                            fragment = fragment + k + "=" + encodeURIComponent(data1[k]) + "&";
                        }
                    }
                }
            }
        }

        if (this.isHuffmannEnabled) {
            //need to generate url that's huffmann encoding enabled, don't encode pid for now... #pid
            if (fragment.indexOf("&") != -1) {
                data = fragment.substr(fragment.indexOf("&") + 1);
                if (data.length > 0) {
                    data = com.ibm.mm.enabler.encode.huffman.HuffmanURL.createRawSchemeSpecificPartFromRegex(data, "[%&c=]");
                    fragment = fragment.substring(0, fragment.indexOf("&") + 1); //include "&"
                    fragment = fragment.concat(this.HUFFMANN_PREFIX);
                    fragment = fragment.concat(data);
                }
            }
        }

        //huffman encoding if required
        if (callback) {
            callback(fragment, params);
        }
        if (!callback) {
            return fragment;
        }
    },
    _removeHiddenParameters: function(obj){
        for (var i in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, i)) {
                if (i.indexOf("_") === 0) {
                    obj[i] = null;
                    delete obj[i];
                }
                else {
                    if (!dojo.isString(obj[i])) {
                        this._removeHiddenParameters(obj[i]);
                    }
                }
            }
        }
    },
    _removeEmptyObj: function(obj){
        // if the object is empty, we can exit right away
        if (com.ibm.mm.enabler.utils.Misc.isEmpty(obj)) {
            return;
        }

        for (var childName in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, childName)) {
                // if the child is not an object (e.g. it is a string, we must not try to delte it
                if (!dojo.isObject(obj[childName])) {
                    continue;
                }

                var childObj = obj[childName];
                this._removeEmptyObj(childObj);

                // now we can check whether the object is empty after we recursively removed empty childs
                if (com.ibm.mm.enabler.utils.Misc.isEmpty(childObj)) {
                    obj[childName] = null;
                    delete obj[childName];
                }
            }
        }
    },
    _removeQueryState: function(wru){
        if (wru.indexOf("?") == -1) {
            return wru;
        }
        var queryParams = wru.substring(wru.indexOf("?") + 1); //? is not included
        if (queryParams && queryParams.indexOf("#") != -1) {
            queryParams = queryParams.substring(0, queryParams.indexOf("#"));
        }
        var prefix = wru.substr(0, wru.indexOf("?")); //prefix before query parameter,"?" is not included
        var st = null;
        var newqueryParams = "";
        if (queryParams && (queryParams.indexOf("nst=") === 0 || queryParams.indexOf("&nst=") >= 0)) {
            var temp = queryParams.substr(queryParams.indexOf("nst=") + 3); //mystate&other=test
            var postSt = "";
            if (temp.indexOf("&") > 0) { //?nst=mystate&other=test
                st = temp.substring(0, temp.indexOf("&")); //mystate
                postSt = temp.substring(temp.indexOf("&")); //&other=test
            }
            else {
                st = temp;
            }

            if (queryParams.indexOf("&nst=") != -1) {
                //?other=test&nst=mystate --> other=test
                newqueryParams = queryParams.substring(0, queryParams.indexOf("&nst="));
            }
            if (newqueryParams.length === 0 && postSt.length !== 0) {
                newqueryParams = newqueryParams.concat(postSt.substring(1)); //remove "&" here
            }
            else {
                newqueryParams = newqueryParams.concat(postSt);
            }
        }
        else {
            return wru; //if there's no state information encoded in params.
        }

        //add hash
        var hash = wru.substr(wru.indexOf("#") + 1);

        //remove "nst=" as query parameter
        var newWru = prefix;
        if (newqueryParams.length > 0) {
            newWru = newWru.concat("?").concat(newqueryParams);
        }
        if (hash.length > 0) {
            newWru = newWru.concat("#").concat(hash);
        }
        return newWru;

    },
    // @deprecated
    generateUrl: function(state, callback, params, nsm){
        return this.generateURL(state, callback, params);
    },
    generateURL: function(state, callback, params, nsm){
        var additionalParams;
        if (params && params.cp) {
            additionalParams = {
                cp: params.cp
            };
        }
        var encodedFragment = additionalParams ? this.encode(state, null, null, additionalParams, nsm) : this.encode(state, null, null, null, nsm);
        var href = window.location.href;
        //remove "?nst=" here
        href = this._removeQueryState(href);
        var preHref = href;
        if (href.indexOf("#") != -1) {
            preHref = href.substr(0, href.indexOf("#"));
        }
        var url = preHref.concat("#");
        url = url.concat(encodedFragment);
        //{nohash:"true"}
        if (params && params.nohash && params.nohash == "true") {
            //now need to generate a url without hash, by default we use query "?nst=b"
            //there could be =,& in the encodedFragment, need ot escape
            encodedFragment = encodeURIComponent(encodedFragment);

            if (preHref.indexOf("?") == -1) {
                url = preHref.concat("?");
                url = url.concat("nst=");
                url = url.concat(encodedFragment);
            }
            else {
                if (preHref.lastIndexOf("&") == (preHref.length - 1)) {
                    url = preHref.concat("nst=");
                    url = url.concat(encodedFragment);
                }
                else {
                    url = preHref.concat("&");
                    url = url.concat("nst=");
                    url = url.concat(encodedFragment);
                }
            }
        }

        if (callback) {
            callback(url);
        }
        return url;
    },
    _getHash: function(wru){
        if (wru.indexOf("?") == -1) {
            return null;
        }
        if (wru.indexOf("#") != -1) {
            var hashValue = wru.substr(wru.indexOf("#") + 1);
            if (wru.indexOf("pid") != -1 || wru.indexOf("sid") != -1) {
                return null;
            }
        }
        var queryParams = wru.substring(wru.indexOf("?") + 1); //? is not included
        if (queryParams && queryParams.indexOf("#") != -1) {
            queryParams = queryParams.substring(0, queryParams.indexOf("#"));
        }
        //var prefix = wru.substr(0,wru.indexOf("?")); //prefix before query parameter,"?" is not included

        var st = null;
        //var newqueryParams = "";
        if (queryParams && (queryParams.indexOf("nst=") === 0 || queryParams.indexOf("&nst=") >= 0)) {
            var temp = queryParams.substr(queryParams.indexOf("nst=") + 4); //mystate&other=test
            var postSt = "";
            if (temp.indexOf("&") > 0) { //?nst=mystate&other=test
                st = temp.substring(0, temp.indexOf("&")); //mystate
            }
            else {
                st = temp;
            }

            st = decodeURIComponent(st); //returned state is still URIencoded
        }
        else {
            return null; //if there's no state information encoded in params.
        }
        return st;
    },
    _sortData: function(widgetsData){
        //sort data based on "lm" -- pass in an associative array
        var arr = [];
        for (var i in widgetsData) {
            if (Object.prototype.hasOwnProperty.call(widgetsData, i)) {
                widgetsData[i].wid = i;
                var widgetData = widgetsData[i]; //i is widgetid
                if (widgetData.params && widgetData.params.lm) {
                    arr.push(widgetData);
                }
            }
        }
        var sortby = function(a, b){
            return (a.params.lm - b.params.lm);
        };
        arr.sort(sortby);
        return arr; //an array sorted in accending order
    },
    _getLength: function(obj){
        var length = 0;
        for (var i in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, i)) {
                length++;
            }
        }
        return length;
    },
    _isEmpty: function(obj){
        return com.ibm.mm.enabler.utils.Misc.isEmpty(obj);
    },
    _contains: function(value, obj){
        if (!obj) {
            return false;
        }
        if (obj[value]) {
            return true;
        }
        return false;
    },
    _filterData: function(data, containsObj, notContainsObj){
        //removes data fields that's not in the containsObj if notContainsObject is not provided
        //removes data fields that's in notContainsObj and it's not in containsObj --> url
        if (!containsObj && !notContainsObj) {
            return data;
        }
        if (!notContainsObj) {
            for (var i in data) {
                if (Object.prototype.hasOwnProperty.call(data, i)) {
                    if (!this._contains(i, containsObj)) {
                        delete data[i];
                    }
                }
            }
            return data;
        }
        for (var j in data) {
            if (Object.prototype.hasOwnProperty.call(data, j)) {
                if (!this._contains(j, containsObj) && this._contains(j, notContainsObj)) {
                    delete data[j];
                }
            }
        }
        return data;
    },
    preprocess: function(state, callback){
        //call cookie preprocessor to process data
        //collect data from cookie
        var cookieManager = com.ibm.mashups.enabler.model.state.CookieManager;
        var temp = cookieManager.getState();

        //need to merge data
        //pid/sid first
        //if state already contains sid and even pid is null, don't load it
        if (!state.pid && temp.pid && !state.sid) {
            state.pid = temp.pid;
        }
        if (!state.sid && temp.sid) {
            state.sid = temp.sid;
        }

        if (!state.pageselection && temp.pageselection) {
            state.pageselection = temp.pageselection;
        }

        // this is only to support lc params
        // which are only stored in the cookie
        // and are only used by base Mashups
        // to get layout template for the page
        // which is used to determine
        // if the width and height of widgets are still valid
        state.lcparams = temp.lcparams || {};

        //widget data collection
        if (!state.wparams) {
            state.wparams = {};
        }
        var widgetsStateData = state.wparams;

        var widgetData = temp.wparams; //values in cookie
        for (var i in widgetData) {
            if (Object.prototype.hasOwnProperty.call(widgetData, i)) {
                var widget = i;
                var value = widgetData[i]; //data in cookie
                var widgetStateData = widgetsStateData[widget];//data in state object
                if (widgetStateData) {
                    value = dojo.mixin(value, dojo.clone(widgetStateData)); //merge data for widget,data in memory wins if duplicate, for example: "lm"
                    widgetsStateData[widget] = value; //set new dta in memory
                }
                else {
                    widgetsStateData[widget] = value;
                }
            }
        }
        if (callback) {
            callback(state);
        }
        if (!callback) {
            return state;
        }
    },
    postprocess: function(state, callback, oldState, additionalParams){
        //persist into cookie
        var cookieManager = com.ibm.mashups.enabler.model.state.CookieManager;

        for (var i in state) {
            if (Object.prototype.hasOwnProperty.call(state, i)) {
                if (i == "pid" || i == "sid" || i == "pageselection" || i == "sparams") {
                    if (this._contains(i, this.persistencePSTORE)) {
                        cookieManager.setState(i, state[i]);
                    }
                }

                // lcparams -- needed in case w,h are stored since this contains
                // the name of the layout template for the page which is used to determine
                // if the width and height of widgets are still valid
                // specifically, if the page instance template is different from the navstate layout template
                // then widgets' width and height on the relevant page are invalid
                if (i == "lcparams" && state[i] && this.persistencePSTORE && (this.persistencePSTORE.w || this.persistencePSTORE.h)) {
                    var lcparamsState = {};
                    var lcparamsData = state[i];
                    for (var page in lcparamsData) {
                        if (Object.prototype.hasOwnProperty.call(lcparamsData, page)) { // it's really a page, not some inherited property
                            var layoutState = {};
                            var layoutData = lcparamsData[page];
                            layoutState.templateURL = layoutData.templateURL;
                            layoutState.params = layoutData.params;
                            lcparamsState[page] = layoutState;
                            // don't need any other data because mashups does not support saving/restore of layout containerd (column widths)
                        }
                    }
                    cookieManager.setState("lcparams", lcparamsState);
                }

                // widgets!
                if (i == "wparams" && state[i]) {
                    var widgetsstate = {};
                    var widgetsData = state[i];
                    for (var j in widgetsData) {
                        if (Object.prototype.hasOwnProperty.call(widgetsData, j)) {
                            var widgetData = widgetsData[j] || null;
                            var wID = j;//wid
                            var pstoreData = {};
                            if (widgetData && widgetData.value) {
                                if (widgetData.value.rp) {
                                    var rpData = this._filterData(dojo.clone(widgetData.value.rp), this.persistencePSTORE);
                                    if (!this._isEmpty(rpData)) {
                                        pstoreData.value = pstoreData.value ? pstoreData.value : {};
                                        pstoreData.value.rp = rpData;
                                    }
                                }
                                if (widgetData.value.cp && this._contains("cp", this.persistencePSTORE)) {
                                    var cpData = this._filterData(dojo.clone(widgetData.value.cp), this.persistencePSTORE);
                                    if (!this._isEmpty(cpData)) {
                                        pstoreData.value = pstoreData.value ? pstoreData.value : {};
                                        pstoreData.value.cp = cpData;
                                    }
                                }
                                if (!this._isEmpty(pstoreData)) {
                                    //if there's no value, no reason to save empty params. at least for now.
                                    if (widgetData.params) {
                                        pstoreData.params = widgetData.params;
                                    }
                                    widgetsstate[wID] = pstoreData;
                                }
                            }
                        }
                    }
                    cookieManager.setState("wparams", widgetsstate);
                }
            }
        }
        cookieManager.commit();

        if (callback) {
            callback(state, additionalParams);
        }
        if (!callback) {
            return state;
        }
    }

});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateProcessor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateProcessor"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateProcessor");





}

if(!dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateProcessorFactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateProcessorFactoryImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.state.NavigationStateProcessorFactoryImpl");



dojo.declare("com.ibm.mm.enabler.model.state.NavigationStateProcessorFactoryImpl", null, {

    constructor: function(){
    },
    getProcessor: function(){
        if (!this._nsp) {
            this._nsp = new com.ibm.mm.enabler.model.state.NavigationStateProcessorImpl();
        }
        return this._nsp;
    }
});
com.ibm.mashups.enabler.model.state.NavigationStateProcessorFactory = new com.ibm.mm.enabler.model.state.NavigationStateProcessorFactoryImpl();

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateNode_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateNode_API"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateNode_API");
dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateNode");


/**
 * Interface representing a NavigationStateNode.
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.model.state.NavigationStateNode", com.ibm.mashups.enabler.Identifiable, {

    /**
     * Returns the value of this NavigationNode
     * @return {Object} The value of the navigation node
     */
    get: function(){
    },

    /**
     * Sets the value of navigation state node
     * @param {Object} value The value of the navigation state node
     * @type void
     */
    set: function(/*Object*/value){
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateNode"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateNode"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateNode");





}

if(!dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateNodeImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateNodeImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.state.NavigationStateNodeImpl");



dojo.declare("com.ibm.mm.enabler.model.state.NavigationStateNodeImpl", [com.ibm.mashups.enabler.model.state.NavigationStateNode], {

    constructor: function(navStateModel, key, value, id, ref) {
        this.model = navStateModel;
        this.key = key; //like pid
        this.value = value;//real pid
        if (id) {
            this.id = id;
        }
        if (ref) {
            this.ref = ref;
        }
    },
    setID: function(id) {
        this.id = id; //pointer to the position in jso object. wparams#widgetid#cp
    },
    setRef: function(ref) { //ref to the data in state json object: this._state["pid"]
        this.ref = ref;
    },
    getID: function() {
        return this.id;
    },
    getRef: function() {
        return this.ref; //return the ref in state json object
    },
    getKey: function() {
        return this.key;
    },
    getValue: function() {
        return this.value;
    },
    get: function() { //return value only,not reference
        return dojo.clone(this._ref);
    },
    set: function(value) {
        this.ref = value; //overwrite
        this.model.setDirty(true);
    }
});


}

if(!dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateModelImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateModelImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.state.NavigationStateModelImpl");















dojo.declare("com.ibm.mm.enabler.model.state.NavigationStateModelImpl", [com.ibm.mashups.enabler.model.state.NavigationStateModel], {

    DELIMITER: "#",
    ROOT: "ROOT",
    DELETE_TOKEN: "DELETE_TOKEN",
    VALUE: "value",
    PARAMS: "params",
    constructor: function(state){
        this.processor = com.ibm.mashups.enabler.model.state.NavigationStateProcessorFactory.getProcessor();

        if (state) {
            this._state = state;
            this._rootNode = new com.ibm.mm.enabler.model.state.NavigationStateNodeImpl(this, this.ROOT, this._state, this.ROOT, this._state);
            this._loaded = true;
        }
        else {
            dojo.back.setInitialState({
                back: this._loadCurrentPage,
                forward: this._loadCurrentPage
            });

            this._loaded = false;
            this.processor.decode(window.location.href, dojo.hitch(this, "_preprocess"));
        }

        this._sync = true;
    },
    _getUniqueWid: function(wid){
        return dojo.isFunction(this.processor.encodeWidgetIdentifier) ? this.processor.encodeWidgetIdentifier(wid, this) : wid;
    },
    _refreshPage: function(){
        //get full page refresh redirect url
        var cb = function(url){
            if (url) {
                top.location.href = url;
            }
        };
        var navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
        com.ibm.mashups.enabler.model.state.UrlGeneratorFactory.getURLGenerator().getUrl(navStateModel, cb, {
            nohash: "true"
        });
    },
    _getFullUrl: function(cb, params){
        return this.processor.generateURL(this._state, cb, params, this);
    },
    clone: function(){
        var clone = dojo.clone(this._state);
        return new com.ibm.mm.enabler.model.state.NavigationStateModelImpl(clone);
    },
    _preprocess: function(/*json*/state){
        this.processor.preprocess(state, dojo.hitch(this, "_initializeState"));
    },
    _initialize: function(){
        this.processor.decode(window.location.href, dojo.hitch(this, "_preprocess"));
    },
    _initializeState: function(/*json*/state){
        this._state = state;
        this._stateInternal = dojo.clone(state);
        this._rootNode = new com.ibm.mm.enabler.model.state.NavigationStateNodeImpl(this, this.ROOT, this._state, this.ROOT, this._state);
        this._isDirty = false;
        this._isTransactionDirty = false;
        //this._dirtyProperties = {};
        this._isTransaction = false;
        this._loaded = true;
    },
    _postprocess: function(/*json*/state, additionalParams){
        //don't call encode if page is already unloaded
        if (this._isDirty && (!this._pagemode || (this._pagemode && this._pagemode != "unload" && this._pagemode != "edit"))) {
            this.processor.encode(state, dojo.hitch(this, "_finishCommit"), this._stateInternal, additionalParams, this);
        }
        else { //call callback
            if (this._deferred) {
                this._deferred.finish(null, com.ibm.mm.enabler.model.HttpStatusCodes.HTTP_OK);
                delete this._deferred;
            }
        }
    },
    _loadCurrentPage: function(){
        // this is a helper function for loading the current page, it is not bound to this context.
        // it is used by the dojo.back mechanism
        var nsm = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();

        nsm._initialize();
        var eventService = com.ibm.mashups.services.ServiceManager.getService("eventService");
        eventService.publishEvent(nsm.ONNAVSTATEUPDATED);
    },
    _finishCommit: function(fragment, additionalParams, responseParams){
        //update url fragment identifier accordingly
        //todo
        //update url
        //var oldUrl = window.location.hash;
        //var other = "";
        //if (oldUrl && oldUrl != null){
        //	other = this._getDifference(oldUrl);
        //}
        //need to keep things that's in fragment already such as "pageContext".

        //window.location.hash = "#"+fragment+other;
        try {
            var currentFragment = window.location.hash.substring(1);

            if (additionalParams && additionalParams.addToHistory) {
                if (fragment && currentFragment != fragment) {
                    dojo.back.addToHistory({
                        back: this._loadCurrentPage,
                        forward: this._loadCurrentPage,
                        changeUrl: fragment
                    });
                }
            }
        }
        catch (e) {
            //defect 14585 IE has a maximum url length at 2083 character, catch the exception so widgets can continue rendering process
        }

        //broadcast page Navigation updated event
        if (this._isDirty) {
            var eventService = com.ibm.mashups.services.ServiceManager.getService("eventService");
            eventService.publishEvent(this.ONNAVSTATEUPDATED);
        }


        //just call dojo.backbutton...
        this._isDirty = false;
        //cleanup set all the _isDirty flag into false
        this._removeDirty(this._state);
        //
        this._stateInternal = dojo.clone(this._state);

        //not used anymore?
        //delete this._dirtyProperties;
        //this._dirtyProperties = {};

        // see if we should refresh or handle the callback
        if (additionalParams && additionalParams.allowRedirect &&
        responseParams &&
        responseParams.doRedirect &&
        !this._sync) {
            this._refreshPage();
        }
        else
            if (this._deferred) {
                //handle callback
                this._deferred.finish(null, com.ibm.mm.enabler.model.HttpStatusCodes.HTTP_OK);
                delete this._deferred;
            }
    },
    _removeDirty: function(obj){
        for (var i in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, i)) {
                if (i.params && i.params._isDirty) {
                    i.params._isDirty = false;
                    if (i.value && i.value == this.DELETE_TOKEN) {
                        obj[i] = null;
                        delete obj[i];
                    }
                }
                if (obj[i] && !dojo.isString(obj[i])) {
                    this._removeDirty(obj[i]);
                }
            }
        }
    },
    setDirty: function(isDirty){
        this._isDirty = isDirty;
    },
    isDirty: function(){
        return this._isDirty;
    },
    _find: function(id){//id
        //return the NavigationStateNode by id or return null
        id = id || null;
        if (!id) {
            return null;
        }
        if (id == this.ROOT) {
            return this._rootNode;
        }
        else {
            var aNode = this._findReference(id) || null; //return the ref in this._state
            if (aNode) {
                var returnNode = new com.ibm.mm.enabler.model.state.NavigationStateNodeImpl(this);
                returnNode.setID(id);
                returnNode.setRef(aNode);
                return returnNode;
            }
        }
        return null;
    },
    create: function(context){
        //{key:id,value:data}
        //{key:"pid",value:pid}
        //{key:"mywidgetid",value:json}
        var key = context.key ? context.key : null;
        var value = context.value ? context.value : null;
        var aNode = new com.ibm.mm.enabler.model.state.NavigationStateNodeImpl(this, key, value);
        return aNode;
    },
    insert: function(aNode, parentNode){
        //For example, pid node should be inserted under rootnode
        var parentData = parentNode.getRef();
        var key = aNode.getKey();
        var value = aNode.getValue() || null;
        if (!value) {
            value = {};
        }

        //if parentNode is wparams, then aNode is widget node, widget node need to have an index in value
        var parentKey = parentNode.getID();
        /*if (parentKey && parentKey != null && parentKey == "wparams") {
         value.i = this._getIndex(parentData);
         }*/
        parentData[key] = value;//insert the node into JSON
        return;
    },
    _getIndex: function(parentData){
        var index = 0;
        for (var i in parentData) {
            if (Object.prototype.hasOwnProperty.call(parentData, i)) {
                index++;
            }
        }
        return index;
    },
    remove: function(aNode){
        //get id
        var id = aNode.getID();
        var arr = id.split("#");
        if (arr.length == 1) {
            //remove from root
            if (this._state[id]) {
                delete this._state[id];
            }
        }
        if (arr.length > 1) {
            var key = id.substring(id.lastIndexOf("#") + 1);
            var parentId = id.substring(0, id.lastIndexOf("#"));
            var parentNode = this._find(parentId);
            if (parentNode) {
                var ref = parentNode.getRef();
                if (ref[key]) {
                    delete ref[key];
                }
            }
        }
        return;
    },
    _getRoot: function(){
        return this._rootNode;
    },
    _findReference: function(id){
        if (id == this.ROOT) {
            return this._state;
        }
        var found = false;
        var arr = id.split("#");
        var node = this._state;
        if (!node) {
            return null;
        }
        for (var i in arr) {
            if (Object.prototype.hasOwnProperty.call(arr, i)) {
                var j = arr[i];
                found = false;
                if (this._findMatch(node, j)) {
                    node = node[j];
                    found = true;
                }
                else {
                    break;
                }
            }
        }
        if (!found) {
            return null;
        }
        return node;
    },
    _findMatch: function(node, key){
        if (node[key]) {
            return true;
        }
        return false;
    },
    commit: function(additionalParams){
        return new com.ibm.mm.enabler.DeferredImpl(this, this._commit, additionalParams);
    },
    _commit: function(deferred, sync, additionalParams){ //default is synchronous
        this._deferred = deferred;
        this._sync = sync;
        if (additionalParams && additionalParams.allowRedirect && this._sync) {
        }
        //commit all the itemset changed.
        this._processShareableParameters();
        //don't commit if it's edit mode...
        if (this._isDirty && (!this._pagemode || (this._pagemode && this._pagemode != "edit"))) {
            //persist to cookie
            this._isTransactionDirty = true;
            this.processor.postprocess(this._state, dojo.hitch(this, this._postprocess), this._stateInternal, additionalParams);
        }
    },
    _processShareableParameters: function(){
        var sparams = this._state.sparams;
        if (!sparams) {
            return;
        }
        var paramset = null;
        for (var i in sparams) {
            if (Object.prototype.hasOwnProperty.call(sparams, i)) {
                //i is itemset name
                var payload = {};
                payload.itemSetName = i;
                var changes = [];

                for (var scope in sparams[i]) {
                    if (Object.prototype.hasOwnProperty.call(sparams[i], scope)) {
                        var itemValues = sparams[i][scope].value;
                        for (var j in itemValues) {
                            if (Object.prototype.hasOwnProperty.call(itemValues, j)) {
                                //j is itemName
                                var itemParams = itemValues[j].params;
                                if (itemParams && itemParams._isDirty) {
                                    changes.push(itemParams._change);
                                    if (itemValues[j].value == this.DELETE_TOKEN) {
                                        itemValues[j] = null;
                                        delete itemValues[j];
                                    }
                                    else {
                                        itemValues[j].params = null;
                                        delete itemValues[j].params;
                                    }
                                }
                            }
                        }


                        if (changes.length > 0) {
                            payload.changes = changes;
                            if (sparams[i][scope].params && sparams[i][scope].params._listeners) {
                                var listeners = sparams[i][scope].params._listeners;
                                for (var t in listeners) {
                                    if (Object.prototype.hasOwnProperty.call(listeners, t)) {
                                        listeners[t](payload);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    discard: function(){
        this._state = dojo.clone(this._stateInternal);
        this._rootNode = new com.ibm.mm.enabler.model.state.NavigationStateNodeImpl(this, this.ROOT, this._state, this.ROOT, this._state);
        this._isDirty = false;
    },
    _getPageMode: function(){
        if (!this._pagemode) {
            return null;
        }
        return this._pagemode;
    },
    _setPageMode: function(pageMode){
        if (pageMode) {
            this._pagemode = pageMode;
        }
    },
    dispose: function(){
        this._state = {};
        this._stateInternal = {};
        this._rootNode = new com.ibm.mm.enabler.model.state.NavigationStateNodeImpl(this, this.ROOT, this._state, this.ROOT, this._state);
        this._isDirty = false;
        this._loaded = true;
        this.processor.dispose();
    },
    startTransaction: function(){
        // If _isTransaction is already true, do nothing.
        if (this.isTransaction())
            return;

        // Otherwise set _isDirty false and _isTransaction true
        // and save a clone of the NavState in case rollback is necessary
        this.discard();  // just in case
        this._isTransaction = true;
        this._isTransactionDirty = false;
        this._transactionRollbackState = dojo.clone(this._state);

        // This is a fix for defect 19201
        // Temporary widget ids such as 0 and 1
        // are assigned to new widgets before the page is saved
        // when the page is saved, real server ids are assigned
        // and the wparams navstate is copied from the temporary ids.
        // This is done in _copyWidgetStateInfo()
        // in com.ibm.mm.enabler.widget.WidgetModelImpl
        // but _copyWidgetStateInfo() does not delete the temporary ids.
        // The temporary widget ids are reused when another page creates a new widget
        // so the navstate from the new widget on the previous page
        // ends up being applied to new widget on this other page -- which is wrong.
        // Since it was not obvious to me that it was always safe
        // to delete the temporary ids _copyWidgetStateInfo()
        // and since the WidgetAccessor does not have a method to delete a widget
        // the code below simply makes sure the navstate data
        // associated with the temporary ids
        // is deleted before the page edit begins (startTransaction is called)
        // This is not ideal because it ties startTransaction() to Edit Page.
        // But it is not terrible.
        // We can evaluate this during knowledge transfer.
        // -dosofsky, 28-mar-2011
        var wparams = null;
        if (this._state)
            wparams = this._state.wparams;
        if (wparams) {
            var idService = com.ibm.mashups.enabler.services.IdentificationService;
            var id;
            for (id in wparams) {
                if (!idService.isServerID(id))
                    delete wparams[id];
            }
        }
    },
    commitTransaction: function(){
        // If _isTransaction  is false, do nothing.  Otherwise set  _isTransaction false, and if isDirty is true call postprocess()
        if (this.isTransaction()) {
            this._isTransaction = false;
            if (this._isTransactionDirty) {
                this.discard();
                this._stateInternal = this._transactionRollbackState;
                this._transactionRollbackState = null; // discard copy of navstatemodel
                this._isDirty = true;
                // call postprocess()
                this.processor.postprocess(this._state, dojo.hitch(this, this._postprocess), this._stateInternal);
                this._isTransactionDirty = false;
            }
        }
        return;
    },
    discardTransaction: function(){
        // If _isTransaction  is false, do nothing.  Otherwise if _isTransactionDirty is true  reset the NavState to the clone and call postprocess().  Regardless of the state of _isDirty, set _isTransaction false.
        if (this.isTransaction()) {
            if (this._isTransactionDirty) {
                this.discard();
                if (!(typeof this._transactionRollbackState == "undefined")) {

                    // when a page edit is discarded the pid, sid, and pageselection for
                    // the _transactionRollbackState should be the same as the _state
                    // but in a couple of cases, when a page is in edit mode,
                    // and the user selects another page tab or the "new page" page tab
                    // the page is switched to the other page or "new page"
                    // but then discardTransaction() is called
                    // and could roll back the the pid, sid, and/or pageselection
                    // to their values before the page was switched
                    // the code below prevents that problem; it fixes defects:
                    // 18785, 19150, and probably 19236
                    //  -dosofsky, 21-mar-2011
                    var trs = this._transactionRollbackState;
                    var s = this._state;
                    if (s) {
                        if(s.pid)
                            trs.pid = dojo.clone(s.pid);
                        if(s.sid)
                            trs.sid = dojo.clone(s.sid);
                        if(s.pageselection)
                            trs.pageselection = dojo.clone(s.pageselection);
                    }

                    this._state = this._transactionRollbackState; // reset NavState to the clone state
                    this._rootNode = new com.ibm.mm.enabler.model.state.NavigationStateNodeImpl(this, this.ROOT, this._state, this.ROOT, this._state);
                    this._transactionRollbackState = null; // discard copy of navstatemodel
                    this._isDirty = true;
                    // call postprocess()
                    this.processor.postprocess(this._state, dojo.hitch(this, this._postprocess), this._stateInternal);
                }
                this._isTransactionDirty = false;
            }
            this._isTransaction = false;
        }
        return;
    },
    isTransaction: function(){
        if (typeof this._isTransaction == "undefined") { // check if isTransaction flag exists
            this._isTransaction = false;
        }
        return this._isTransaction;
    },
    _generateListenerId: function(){
        if (!this._listenerCounter) {
            this._listenerCounter = 1;
        }
        else {
            this._listenerCounter++;
        }
        return this._listenerCounter;
    }
});

// init the backbutton functionality, this is mandatory for having back button support working on IE !!!
//dojo.back.init();

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateModel"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateModel");






}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateModelFactory_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateModelFactory_API"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateModelFactory_API");
dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateModelFactory");


/**
 * Interface for a NavigationStateModelFactory.<br/>
 * <code>var navigationStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();</code><br/>
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare( "com.ibm.mashups.enabler.model.state.NavigationStateModelFactory", null, {
    /**
     * Returns  the NavigationStateModel of Mashup Server.
     * @return {com.ibm.mashups.enabler.model.state.NavigationStateModel} The NavigationStateModel, never <code>null</code>.
     */
	getNavigationStateModel:function() {
	}
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateModelFactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.state.NavigationStateModelFactoryImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.state.NavigationStateModelFactoryImpl");




dojo.declare("com.ibm.mm.enabler.model.state.NavigationStateModelFactoryImpl", [com.ibm.mashups.enabler.model.state.NavigationStateModelFactory], {
    constructor: function() {

    },
    getNavigationStateModel: function(state) {
        // STATE is internal and may not be used as public API. It was introduced for sandboxing to initialize the NavState within the sandbox
        if (!this.navigationstatemodel) {
            this.navigationstatemodel = new com.ibm.mm.enabler.model.state.NavigationStateModelImpl(state);
        }
        return this.navigationstatemodel;
    }
});
com.ibm.mashups.enabler.model.state.NavigationStateModelFactory = new com.ibm.mm.enabler.model.state.NavigationStateModelFactoryImpl();

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateModelFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.NavigationStateModelFactory"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.NavigationStateModelFactory");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.UrlGenerator_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.UrlGenerator_API"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.UrlGenerator_API");
dojo.provide("com.ibm.mashups.enabler.model.state.UrlGenerator");

/**
 * Interface representing an UrlGenerator.
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare( "com.ibm.mashups.enabler.model.state.UrlGenerator", null, {
    /**
     * Returns the URL based on navigation state model and additional parameters.
     * Sample parameter: {nohash:"true"}
     * if "nohash" is set to "true",the returned URL will not contain state in hash.
     *
     * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navStateModel NavigationStateModel to generate URL
     * @param {Function} callback callback funtion is invoked when URL is generated, URL will be passed into callback
     * @param {JSON} params additional parameter in json format
     * @type String
     * @return {String} The URL that's generated based on navigationStateModel
     * @deprecated Use getURL instead.
     */
	getUrl:function(navStateModel,callback,params) {
	},
    /**
     * Returns the URL based on navigation state model and additional parameters.
     * Sample parameter: {nohash:"true"}
     * if "nohash" is set to "true",the returned URL will not contain state in hash.
     *
     * @param {com.ibm.mashups.enabler.model.state.NavigationStateModel} navStateModel NavigationStateModel to generate URL
     * @param {Function} callback callback funtion is invoked when URL is generated, URL will be passed into callback
     * @param {JSON} params additional parameter in json format
     * @type String
     * @return {String} The URL that's generated based on navigationStateModel
     */
	getURL:function(navStateModel,callback,params) {
	}
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.model.state.UrlGeneratorImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.state.UrlGeneratorImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.state.UrlGeneratorImpl");



dojo.declare("com.ibm.mm.enabler.model.state.UrlGeneratorImpl", com.ibm.mashups.enabler.model.state.UrlGenerator, {

    constructor: function() {
    },
    getUrl: function(navStateModel, callback, params) {
        return this.getURL(navStateModel, callback, params);
    },
    getURL: function(navStateModel, callback, params) {
        if (!navStateModel) {
            return null;
        }
        var clone = navStateModel.clone(); //get a clone so it doesn't affect the original navStateModel
        return clone._getFullUrl(callback, params);
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.UrlGenerator"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.UrlGenerator"] = true;
dojo.provide( "com.ibm.mashups.enabler.model.state.UrlGenerator" );




}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.UrlGeneratorFactory_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.UrlGeneratorFactory_API"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.UrlGeneratorFactory_API");
dojo.provide("com.ibm.mashups.enabler.model.state.UrlGeneratorFactory");

/**
 * Interface representing an UrlGeneratorFactory.
 * @ibm-spi
 * @ibm-module Base
 */
dojo.declare( "com.ibm.mashups.enabler.model.state.UrlGeneratorFactory", null, {
    /**
     * Returns the url generator to get the url based on navigationstatemodel
     * @type com.ibm.mashups.enabler.model.state.UrlGenerator
     * @return {com.ibm.mashups.enabler.model.state.UrlGenerator} The url generator based on navigation state model
     * @deprecated Use getURLGenerator instead.
     */
	getUrlGenerator:function() {
	},

	/**
     * Returns the url generator to get the url based on navigationstatemodel
     * @type com.ibm.mashups.enabler.model.state.UrlGenerator
     * @return {com.ibm.mashups.enabler.model.state.UrlGenerator} The url generator based on navigation state model
     */
	getURLGenerator:function() {
	}
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.model.state.UrlGeneratorFactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.model.state.UrlGeneratorFactoryImpl"] = true;
dojo.provide("com.ibm.mm.enabler.model.state.UrlGeneratorFactoryImpl");




dojo.declare("com.ibm.mm.enabler.model.state.UrlGeneratorFactoryImpl", com.ibm.mashups.enabler.model.state.UrlGeneratorFactory, {

    constructor: function() {
        this._urlGenerator = new com.ibm.mm.enabler.model.state.UrlGeneratorImpl();
    },

    // @deprecated
    getUrlGenerator: function() {
        return this.getURLGenerator();
    },
    getURLGenerator: function() {
        return this._urlGenerator;
    }
});
com.ibm.mashups.enabler.model.state.UrlGeneratorFactory = new com.ibm.mm.enabler.model.state.UrlGeneratorFactoryImpl();

}

if(!dojo._hasResource["com.ibm.mashups.enabler.model.state.UrlGeneratorFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.model.state.UrlGeneratorFactory"] = true;
dojo.provide("com.ibm.mashups.enabler.model.state.UrlGeneratorFactory" );




}

if(!dojo._hasResource["com.ibm.mashups.enabler.strategy.HiddenMetaDataLoadingStrategy"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.strategy.HiddenMetaDataLoadingStrategy"] = true;
dojo.provide("com.ibm.mashups.enabler.strategy.HiddenMetaDataLoadingStrategy");



/**
 * Interface to control, if hidden meta data are loaded with the MetaData
 * interface or not.<br>
 *
 * @since 2.4
 *
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.strategy.HiddenMetaDataLoadingStrategy", com.ibm.mashups.enabler.strategy.Strategy, {
    /**
     * @param {String[]} names Array of hidden meta data names to load;
     * must not be <code>null</code>
     */
    constructor: function(names){
        this.names = names;
    },

    /**
     * Indicates hidden meta data to load.
     * @return {Boolean} <code>true</code> if to expose hidden meta data
     */
    getHiddenMetaDataToLoad: function(){
        return this.names;
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.strategy.ListLoadAheadStrategy"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.strategy.ListLoadAheadStrategy"] = true;
dojo.provide("com.ibm.mashups.enabler.strategy.ListLoadAheadStrategy");



/**
 * Interface that defines a load ahead strategy for loading elements of a list.
 * When applied to a list model it will load the given number of elements at a
 * time from the backend.<br>
 * Example; A ListLoadAheadStrategy with interval = 10 will cause the model to
 * load new data from the backend with every 10th call of the method next() when
 * using the iterator of the list.
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.strategy.ListLoadAheadStrategy", com.ibm.mashups.enabler.strategy.Strategy, {
    /**
     * @param {int} interval number of elements to be loaded ahead from the
     * backend. must not be <code>null</code> or less than one.
     */
    constructor: function(interval){
        this.interval = interval;
    },

    /**
     * Returns the number of elements to load ahead
     * @type int
     * @return number of elements to load ahead
     */
    getInterval: function(){
        return this.interval;
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.strategy.SyncMetaDataStrategy"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.strategy.SyncMetaDataStrategy"] = true;
dojo.provide("com.ibm.mashups.enabler.strategy.SyncMetaDataStrategy");



/**
 * Interface to control, if a meta data set/deleted on a content node is synchronized to the respective navigation node and vice versa.
 *
 * @since 2.4
 *
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.strategy.SyncMetaDataStrategy", com.ibm.mashups.enabler.strategy.Strategy, {
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.strategy.TreeLoadAheadStrategy"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.strategy.TreeLoadAheadStrategy"] = true;
dojo.provide("com.ibm.mashups.enabler.strategy.TreeLoadAheadStrategy");



/**
 * Interface that defines a load ahead strategy for loading elements wihin a
 * tree hierarchy. When applied to a tree model it will load the given number
 * of elements at a time from the backend.<br>
 * Example; A TreeLoadAheadStrategy with parentLevel = 2 and childrenLevel = 2 will<br>
 * <ul><li>load the parent as well as all the parents of the parent when calling
 * getParent on a given node and</li>
 * <li>load the children as well as all the children of the child when calling
 * getChildren on a given node.</li></ul>
 * @ibm-api
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.strategy.TreeLoadAheadStrategy", com.ibm.mashups.enabler.strategy.Strategy, {
    /**
     * @param {int} parentLevel number of parent levels to be loaded ahead from
     * the backend. must not be <code>null</code> or less than one.
     * @param {int} childrenLevel number of children levels to be loaded ahead
     * from the backend. must not be <code>null</code> or less than one.
     */
    constructor: function(parentLevel, childrenLevel){
        this.parentLevel = parentLevel;
        this.childrenLevel = childrenLevel;
    },

    /**
     * Returns the number of children levels in the hierarchy to load ahead
     * @return {int} number of children levels to load ahead
     */
    getChildrenLevel: function(){
        return this.childrenLevel;
    },

    /**
     * Returns the number of parent levels in the hierarchy to load ahead
     * @return {int} number of parent levels to load ahead
     */
    getParentLevel: function(){
        return this.parentLevel;
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.utils.EventTransformer_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.utils.EventTransformer_API"] = true;
dojo.provide("com.ibm.mashups.enabler.utils.EventTransformer_API");
dojo.provide("com.ibm.mashups.enabler.utils.EventTransformer");

/**
 * Event Transformer that checks compatibility between events.
 * Compatibility checks work bi-directionally, for example a source event with payload type time can
 * be checked against a target event with payload xsd:time. The reverse direction can also be checked, i.e
 * a source event with xsd:time checked against a target event with payload time. The compatibility check is
 * applicable for xsd primitive data types and Mashup simple types.
 *
 * @ibm-module Base
 */
dojo.declare("com.ibm.mashups.enabler.utils.EventTransformer", null, {
    /**
     * Checks the compatibility of sourceEvent and  targetEvent.
     *
     * @ibm-api
     *
     * @param {com.ibm.mashups.iwidget.event} sourceEvent the event to be checked
     * @param {com.ibm.mashups.iwidget.event} targetEvent the event that sourceEvent is checked against.
     * @param {Boolean} relaxed If relaxed is true, then the checking of the type matches are flexible,
     * if false then only direct type matches are checked
     * @return {Boolean} true if events are compatible, false otherwise.
     */
    isTransformable: function(sourceEvent, targetEvent, relaxed){
    }
});

}

if(!dojo._hasResource["com.ibm.mm.data.datatypes"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.data.datatypes"] = true;
dojo.provide("com.ibm.mm.data.datatypes");

/**
 @author <a href="mailto:litong01@us.ibm.com">Tong Li</a>
 @author <a href="mailto:bizheng@cn.ibm.com">Zheng Bi</a>
 @class com.ibm.mm.data.datatypes
 @name com.ibm.mm.data.datatypes
 */



dojo.declare("com.ibm.mm.data.datatypes", null, /** @lends com.ibm.mm.data.datatypes */ {

    _alltypes: {
        'text': 1,
        'url': 1,
        'html': 1,
        'image': 1,
        'number': 1,
        'countrycode': 1,
        'languagecode': 1,
        'currency': 1,
        'boolean': 1,
        'date': 1,
        'time': 1,
        'timestamp': 1,
        'email': 1,
        'postalcode': 1,
        'phone': 1,
        'address': 1,
        'person': 1,
        'table': 1,
        'atom': 1,
        'xml': 1,
        'json': 1,
        'modeldata': 1,
        'xsd:string': 1,
        'xsd:boolean': 1,
        'xsd:decimal': 1,
        'xsd:float': 1,
        'xsd:double': 1,
        'xsd:duration': 1,
        'xsd:datetime': 1,
        'xsd:time': 1,
        'xsd:date': 1,
        'xsd:gyearmonth': 1,
        'xsd:gyear': 1,
        'xsd:gmonthday': 1,
        'xsd:gday': 1,
        'xsd:gmonth': 1,
        'xsd:hexbinary': 1,
        'xsd:base64binary': 1,
        'xsd:anyuri': 1,
        'xsd:qname': 1,
        'xsd:notation': 1,
		'js:string': 1,
        'js:number': 1,
        'js:date': 1,
        'js:boolean': 1
    },

    _simpleTypes: {
        'text': 1,
        'url': 1,
        'html': 1,
        'image': 1,
        'number': 1,
        'countrycode': 1,
        'languagecode': 1,
        'currency': 1,
        'boolean': 1,
        'date': 1,
        'time': 1,
        'timestamp': 1,
        'email': 1,
        'postalcode': 1,
        'phone': 1,
        'address': 1,
        'person': 1,
        'xsd:string': 1,
        'xsd:boolean': 1,
        'xsd:decimal': 1,
        'xsd:float': 1,
        'xsd:double': 1,
        'xsd:duration': 1,
        'xsd:datetime': 1,
        'xsd:time': 1,
        'xsd:date': 1,
        'xsd:gyearmonth': 1,
        'xsd:gyear': 1,
        'xsd:gmonthday': 1,
        'xsd:gday': 1,
        'xsd:gmonth': 1,
        'xsd:hexbinary': 1,
        'xsd:base64binary': 1,
        'xsd:anyuri': 1,
        'xsd:qname': 1,
        'xsd:notation': 1,
		'js:string': 1,
        'js:number': 1,
        'js:date': 1,
        'js:boolean': 1
    },

    _complexTypes: {
        'table': 1,
        'atom': 1,
        'xml': 1,
        'json': 1,
        'modeldata': 1
    },

    specialTypes: {
        'mashupdata': 1
    },

    _mappings: {
		//mashup types
        text: {
            'url': 1,
            'html': 1,
            'number': 1,
            'countrycode': 1,
            'languagecode': 1,
            'currency': 1,
            'boolean': 1,
            'date': 1,
            'time': 1,
            'timestamp': 1,
            'email': 1,
            'postalcode': 1,
            'phone': 1,
            'address': 1,
            'person': 1,
            'xsd:string': 1,
            'xsd:boolean': 1,
            'xsd:decimal': 1,
            'xsd:float': 1,
            'xsd:double': 1,
            'xsd:duration': 1,
            'xsd:datetime': 1,
            'xsd:time': 1,
            'xsd:date': 1,
            'xsd:gyearmonth': 1,
            'xsd:gyear': 1,
            'xsd:gmonthday': 1,
            'xsd:gday': 1,
            'xsd:gmonth': 1,
            'xsd:hexbinary': 1,
            'xsd:base64binary': 1,
            'xsd:anyuri': 1,
            'xsd:qname': 1,
            'xsd:notation': 1,
			'js:string': 1,
        	'js:number': 1,
        	'js:date': 1,
       		'js:boolean': 1
        },
        'url': {
            'xsd:anyuri': 1,
			'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'html': {
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'image': {},
        'number': {
            'xsd:decimal': 1,
            'xsd:float': 1,
            'xsd:double': 1,
			'js:number': 1,
			'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'countrycode': {
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'languagecode': {
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'currency': {
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'boolean': {
            'xsd:boolean': 1,
			'js:boolean': 1,
			'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'date': {
            'timestamp': 1,
            'xsd:date': 1,
			'js:date': 1,
			'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'time': {
            'timestamp': 1,
            'xsd:time': 1,
			'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'timestamp': {
            'date': 1,
            'time': 1,
            'xsd:datetime': 1,
			'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'email': {
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'postalcode': {
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'phone': {
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'address': {
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'person': {
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'json': {},
		//xsd types
        'xsd:string': {
            'text': 1,
            'url': 1,
            'html': 1,
            'number': 1,
            'countrycode': 1,
            'languagecode': 1,
            'currency': 1,
            'boolean': 1,
            'date': 1,
            'time': 1,
            'timestamp': 1,
            'email': 1,
            'postalcode': 1,
            'phone': 1,
            'address': 1,
            'person': 1,
            'xsd:boolean': 1,
            'xsd:decimal': 1,
            'xsd:float': 1,
            'xsd:double': 1,
            'xsd:duration': 1,
            'xsd:datetime': 1,
            'xsd:time': 1,
            'xsd:date': 1,
            'xsd:gyearmonth': 1,
            'xsd:gyear': 1,
            'xsd:gmonthday': 1,
            'xsd:gday': 1,
            'xsd:gmonth': 1,
            'xsd:hexbinary': 1,
            'xsd:base64binary': 1,
            'xsd:anyuri': 1,
            'xsd:qname': 1,
            'xsd:notation': 1,
			'js:string': 1,
        	'js:number': 1,
        	'js:date': 1,
        	'js:boolean': 1
        },
        'xsd:boolean': {
            'boolean': 1,
			'js:boolean': 1,
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'xsd:decimal': {
            'number': 1,
			'js:number': 1,
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'xsd:float': {
            'number': 1,
			'js:number': 1,
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'xsd:double': {
            'number': 1,
			'js:number': 1,
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'xsd:duration': {
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'xsd:gmonthday': {
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'xsd:gday': {
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'xsd:gmonth': {
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'xsd:hexbinary': {
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'xsd:base64binary': {
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'xsd:qname': {
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'xsd:notation': {
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'xsd:anyuri': {
            'url': 1,
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'xsd:time': {
            'time': 1,
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'xsd:date': {
            'date': 1,
			'js:date': 1,
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'xsd:datetime': {
            'timestamp': 1,
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'xsd:gyear': {
            'date': 1,
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'xsd:gyearmonth': {
            'date': 1,
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
		//js types
        'js:string': {
            'text': 1,
            'url': 1,
            'html': 1,
            'number': 1,
            'countrycode': 1,
            'languagecode': 1,
            'currency': 1,
            'boolean': 1,
            'date': 1,
            'time': 1,
            'timestamp': 1,
            'email': 1,
            'postalcode': 1,
            'phone': 1,
            'address': 1,
            'person': 1,
            'xsd:string': 1,
            'xsd:boolean': 1,
            'xsd:decimal': 1,
            'xsd:float': 1,
            'xsd:double': 1,
            'xsd:duration': 1,
            'xsd:datetime': 1,
            'xsd:time': 1,
            'xsd:date': 1,
            'xsd:gyearmonth': 1,
            'xsd:gyear': 1,
            'xsd:gmonthday': 1,
            'xsd:gday': 1,
            'xsd:gmonth': 1,
            'xsd:hexbinary': 1,
            'xsd:base64binary': 1,
            'xsd:anyuri': 1,
            'xsd:qname': 1,
            'xsd:notation': 1,
            'js:number': 1,
            'js:date': 1,
            'js:boolean': 1
        },
        'js:date': {
            'date': 1,
            'xsd:date': 1,
            'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'js:number': {
            'xsd:decimal': 1,
            'xsd:float': 1,
            'xsd:double': 1,
            'number': 1,
			'text': 1,
			'xsd:string': 1,
			'js:string': 1
        },
        'js:boolean': {
            'xsd:boolean': 1,
            'boolean': 1,
			'text': 1,
			'xsd:string': 1,
			'js:string': 1
        }
    },

    _semanticMappings: {
        text: {
            'xsd:string': 1,
			'js:string': 1
        },
        'url': {
            'xsd:anyuri': 1
        },
        'html': {},
        'image': {},
        'number': {
            'xsd:decimal': 1,
            'xsd:float': 1,
            'xsd:double': 1,
			'js:number': 1
        },
        'countrycode': {},
        'languagecode': {},
        'currency': {},
        'boolean': {
            'xsd:boolean': 1,
			'js:boolean': 1
        },
        'date': {
            'xsd:date': 1,
			'js:date': 1
        },
        'time': {
            'xsd:time': 1
        },
        'timestamp': {
            'xsd:datetime': 1
        },
        'email': {},
        'postalcode': {},
        'phone': {},
        'address': {},
        'person': {},
        'json': {},
        'xsd:string': {
            'text': 1,
			'js:string': 1
        },
        'xsd:boolean': {
            'boolean': 1,
			'js:boolean': 1
        },
        'xsd:decimal': {
            'number': 1,
			'js:number': 1
        },
        'xsd:float': {
            'number': 1,
			'js:number': 1
        },
        'xsd:double': {
            'number': 1,
			'js:number': 1
        },
        'xsd:duration': {},
        'xsd:gmonthday': {},
        'xsd:gday': {},
        'xsd:gmonth': {},
        'xsd:hexbinary': {},
        'xsd:base64binary': {},
        'xsd:qname': {},
        'xsd:notation': {},
        'xsd:anyuri': {
            'url': 1
        },
        'xsd:time': {
            'time': 1
        },
        'xsd:date': {
            'date': 1,
			'js:date': 1
        },
        'xsd:datetime': {
            'timestamp': 1
        },
        'xsd:gyear': {
            'date': 1
        },
        'xsd:gyearmonth': {
            'date': 1
        },
		 'js:string': {
            'text': 1,
            'xsd:string': 1
        },
		 'js:date': {
            'date': 1,
            'xsd:date': 1
        },
        'js:number': {
            'xsd:decimal': 1,
            'xsd:float': 1,
            'xsd:double': 1,
            'number': 1
        },
        'js:boolean': {
            'xsd:boolean': 1,
            'boolean': 1
        }
    },


    _SIMPLE_DATA_TYPE: 1,
    _COMBINED_DATA_TYPE: 2,
    _COMPLEX_DATA_TYPE: 3,

    resourceBundle: null,


    constructor: function(/* String */datatypecfg) {
        this.resourceBundle = dojo.i18n.getLocalization("com.ibm.mm.data", "dataTypeStrings");
		this.xsdNS = com.ibm.mm.enabler.model.NameSpaceFactory.getNameSpaceUri(com.ibm.mm.enabler.model.NameSpaceFactory.NS_XSD);
		this.nsNS = com.ibm.mm.enabler.model.NameSpaceFactory.getNameSpaceUri(com.ibm.mm.enabler.model.NameSpaceFactory.NS_EVENT_DATATYPES);
		this.jsNS = com.ibm.mm.enabler.model.NameSpaceFactory.getNameSpaceUri(com.ibm.mm.enabler.model.NameSpaceFactory.NS_JS);
		this.xsdPrefix = "xsd:";
		this.nsPrefix = "";
		this.jsPrefix = "js:";
    },

    addDataType: function(/* String */typename, /* String */ typeCat) {
        //Check type name
        if (!typename) {
            return;
        }
        this._alltypes.typename = 1;
        //Check the type category
        if (!typeCat || typeCat == this._SIMPLE_DATA_TYPE) {
            this._simpleTypes.typename = 1;
        }
        else {
            this._complexTypes.typename = 1;
        }
    },

    removeDataType: function(/* String */typename) {
        delete this._alltypes[typename];
    },

    addDataMapping: function(/* String */typename1, /* String */ typename2) {
        if (this._mappings.typename1 === null) {
            this._mappings.typename1 = {};
        }
        this._mappings[typename1][typename2] = 1;
    },

    removeDataMapping: function(/* String */typename1, /* String */ typename2) {
        if (this._mappings[typename1] !== null) {
            if (this._mappings[typename1][typename2] !== null) {
                delete this._mappings[typename1][typename2];
            }
        }
    },

    getAllTypes: function() {
        return dojo.clone(this._alltypes);
    },

    /**
     * The method to return if two types should be considered as a match.
     * It may need more work to include the combined data type mapping mechanism.
     *
     * @param {String} typename1 The first data type name(handle event)
     * @param {String} typename2 The second data type name.(publish event)<b>
     * @returns {Boolean}
     */
    doesTypeMatch: function(/* String */typename1, /* String */ typename2) {
        var doesItMatch = false;
        //null type does not match to any thing.
        if (!typename1 || !typename2 ) {
            return doesItMatch;
        }
        //date type is case-insensitive
        typename1 = typename1.toLowerCase();
        typename2 = typename2.toLowerCase();
        //if two types are same or either type is any, then they are considered as a match.
        if (typename1 == typename2 || typename1 == 'any' || typename2 == 'any') {
            doesItMatch = true;
        }
        else {
            //check the type of the "payload type"
            var typeOfName1 = this.checkDataType(typename1);
            switch (typeOfName1) {
                //typename1 is simple data type
                case this._SIMPLE_DATA_TYPE:
                    var typeOfName2 = this.checkDataType(typename2);
                    switch (typeOfName2) {
                        //Two simple data types, use the mapping to decide whether they match or not
                        case this._SIMPLE_DATA_TYPE:
                            if (this._mappings[typename1][typename2] == 1) {
                                doesItMatch = true;
                            }
                            break;
                        //Simple data type VS combine data type, compare the main type. (url.text's main type is :url)
                        case this._COMBINED_DATA_TYPE:
                            var mainTypeOfType2 = this.getMainType(typename2);
                            if (typename1 == mainTypeOfType2 || this._mappings[typename1][mainTypeOfType2] == 1) { //url can handle url.text
                                doesItMatch = true;
                            }
                            break;
                        default:
                            break;
                    }//end of switch(typeOfName2) {
                    break;
                //For comebined type and complex data type as received data type, currently, consider match only when type names are exactly same
                //we can add more logic here in future
                case this._COMBINED_DATA_TYPE:
                    break;
                case this._COMPLEX_DATA_TYPE:
                    break;
                default:
                    break;
            }// enf of switch(typeOfName1)
        }
        return doesItMatch;
    },

    /**
     * The method to return if two types should be considered as a match with a much more flex rule
     * on combined type: only cares about the main type
     *
     * @param {String} typename1 The first data type name(handle event)
     * @param {String} typename2 The second data type name.(publish event)
     * @param {Boolean} relaxed If relaxed is true, then the checking of the type matches are flexible,
     * if false then only direct type matches are checked<b>
     * @returns {Boolean}
     */
    doesTypeFlexMatch: function(/* String */typename1, /* String */ typename2, relaxed) {
        var doesItMatch = false;
        //null type does not match to any thing.
        if (typename1 === null || typename2 === null) {
            return doesItMatch;
        }
        if ((relaxed === null) || (typeof relaxed == "undefined")) {
            //default to true
            relaxed = true;
        }

		// get valid data type
		typename1 = this.getNormalizedPayload(typename1);
		typename2 = this.getNormalizedPayload(typename2);

        //date type is case-insensitive
        typename1 = typename1.toLowerCase();
        typename2 = typename2.toLowerCase();
        //if two types are same or either type is any, then they are considered as a match.
        if (typename1 == typename2 || typename1 == 'any' || typename2 == 'any') {
            doesItMatch = true;
        }
        else {
            //check the type of the "payload type"
            var typeOfName1 = this.checkDataType(typename1);
            var typeOfName2, mainTypeOfType2;
            switch (typeOfName1) {
                //typename1 is simple data type
                case this._SIMPLE_DATA_TYPE:
                    typeOfName2 = this.checkDataType(typename2);
                    switch (typeOfName2) {
                        //Two simple data types, use the mapping to decide whether they match or not
                        case this._SIMPLE_DATA_TYPE:
                            if (relaxed) {
                                if (this._mappings[typename1][typename2] == 1) {
                                    doesItMatch = true;
                                }
                            }
                            else {
                                if (this._semanticMappings[typename1][typename2] == 1) {
                                    doesItMatch = true;
                                }
                            }
                            break;
                        //Simple data type VS combine data type, compare the main type. (url.text's main type is :url)
                        case this._COMBINED_DATA_TYPE:
                            mainTypeOfType2 = this.getMainType(typename2);
                            if (relaxed) {
                                if (typename1 == mainTypeOfType2 || this._mappings[typename1][mainTypeOfType2] == 1) { //url can handle url.text
                                    doesItMatch = true;
                                }
                            }
                            else {
                                if (typename1 == mainTypeOfType2 || this._semanticMappings[typename1][mainTypeOfType2] == 1) { //url can handle url.text
                                    doesItMatch = true;
                                }
                            }
                            break;
                        default:
                            break;
                    }//end of switch(typeOfName2) {
                    break;
                //For comebined type and complex data type as received data type, currently, consider match when they have the same mail(prefix) type
                case this._COMBINED_DATA_TYPE:
                    typeOfName2 = this.checkDataType(typename2);
                    var mainTypeOfType1 = this.getMainType(typename1);
                    switch (typeOfName2) {
                        //Two simple data types, use the mapping to decide whether they match or not
                        case this._SIMPLE_DATA_TYPE:
                            if (relaxed) {
                                if (mainTypeOfType1 == typename2 || this._mappings[mainTypeOfType1][typename2] == 1) {
                                    doesItMatch = true;
                                }
                            }
                            else {
                                if (mainTypeOfType1 == typename2 || this._semanticMappings[mainTypeOfType1][typename2] == 1) {
                                    doesItMatch = true;
                                }
                            }
                            break;
                        //Simple data type VS combine data type, compare the main type. (url.text's main type is :url)
                        case this._COMBINED_DATA_TYPE:
                            mainTypeOfType2 = this.getMainType(typename2);
                            if (mainTypeOfType1 == mainTypeOfType2 || this._mappings[mainTypeOfType1][mainTypeOfType2] == 1) { //url can handle url.text
                                doesItMatch = true;
                            }
                            break;
                        default:
                            break;
                    }//end of switch(typeOfName2) {
                    break;
                //case this._COMPLEX_DATA_TYPE:
                default:
                    break;
            }// end of switch(typeOfName1)
        }
        return doesItMatch;
    },

    /**
     * The method to return the mail type of a combined data type. If it's not combined data type,
     * For example:
     * url.text will return url
     *
     * @param {String} typename
     */
    getMainType: function(/* String */typename) {
        var dotPosition = typename.indexOf('.');
        if (dotPosition < 0) {
            return typename;
        }
        else {
            return typename.substring(0, dotPosition);
        }
    },

    checkDataType: function(/* String */typename) {
        //Check if the type name is the format like url.text
        typename = typename.toLowerCase();
        var types = typename.split('.');
        if (types.length == 1) { // Not combine data type
            if (this._simpleTypes[typename] == 1) {
                return this._SIMPLE_DATA_TYPE;
            }
            else {
                return this._COMPLEX_DATA_TYPE;
            }
        }
        else if (types.length == 2 || types.length == 3) { // type like: url.text || text.countrycode || url.text.countrycode
            var prefixType = types[0];
            var suffixType = types[types.length - 1];
            //In v1.1, only support url as prefix and
            //if (this._alltypes[prefixType] == 1 && this._alltypes[suffixType] == 1)
            if (prefixType == "url" || suffixType == "languagecode" || suffixType == "countrycode") {
                return this._COMBINED_DATA_TYPE;
            }
            else {
                return this._COMPLEX_DATA_TYPE;
            }
        }
        else {
            return this._COMPLEX_DATA_TYPE;
        }
    },

    getTypeLabel: function(/* String */typename, /* String */ locale) {
        typename = typename.toLowerCase();
        var shownType = typename;
        var result = this.checkDataType(typename);

        if (result == this._COMBINED_DATA_TYPE) {
            var dotPosition = typename.indexOf('.');
            var main = typename.substring(0, dotPosition);
            var mainType = this.getSimpleTypeLabel(main, locale);
            var sub = typename.substring(dotPosition + 1, typename.length);
            var subType = this.getSimpleTypeLabel(sub, locale);
            shownType = mainType + ' (' + subType + ')';
        }
        else {
            shownType = this.getSimpleTypeLabel(typename, locale);
        }
        return shownType;
    },

    /**
     * Get the usable version of the payload
     *  If there is a namespace prefix, normalize
     * @param {String} payload
     */
	   getNormalizedPayload: function(/* String */ payload) {

		var payloadType = payload;
		var result = payload;

        var elipsePosition = payload.indexOf('{');
		var endElipsePosition = payload.indexOf('}');
		var prefix = "";
        if (endElipsePosition > elipsePosition) {
			payloadType = payload.substring(elipsePosition + 1, endElipsePosition);
			result = payload.substring(endElipsePosition + 1, payload.length);
			if (payloadType === this.xsdNS) {
				prefix = this.xsdPrefix;
			}
			else
				if (payloadType === this.jsNS) {
					prefix = this.jsPrefix;
				}
				else
					if (payloadType === this.nsNS) {
						prefix = this.nsPrefix;
					}
			result = prefix + result;
		}

        return result;
    },

    /**
     * Get the display name of the simple or complex data type. The rule here is
     * 1. For the simple type predefined, return the display name for this locale
     * 2. For user defined or complex data type, if it's composed with English characters, return the date type with first letter capitalized
     * 3. Otherwise, return the original data type
     * @param {String} typename
     * @param {String} locale
     */
    getSimpleTypeLabel: function(/* String */typename, /* String */ locale) {
        var label;
        if (this.resourceBundle[typename]) {
            label = this.resourceBundle[typename];
        }
        else {
            label = typename.charAt(0).toUpperCase() + typename.substring(1);
        }
        return label;
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.utils.EventTransformerImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.utils.EventTransformerImpl"] = true;
dojo.provide("com.ibm.mm.enabler.utils.EventTransformerImpl");





// EventTransformer implementation
dojo.declare("com.ibm.mm.enabler.utils.EventTransformerImpl", [com.ibm.mashups.enabler.utils.EventTransformer], {

    constructor: function(){
        this.dataTypes = new com.ibm.mm.data.datatypes();
    },

    _transform: function(sourceEvent, targetEvent, relaxed){
        var transformedEvent = null;
        if (sourceEvent.type == targetEvent.type || sourceEvent.type == 'any' || targetEvent.type == 'any') {
            transformedEvent = new com.ibm.mm.iwidget.IEventImpl(sourceEvent.name, sourceEvent.type, sourceEvent.payload, sourceEvent.source);
        }
        else {
            var validMatch = this.isTransformable(sourceEvent, targetEvent, relaxed);
            if (validMatch) {
                var transformedPayload = null;
                switch (targetEvent.type.toLowerCase()) {
                    case "time":
                        if (sourceEvent.type.toLowerCase() == "xsd:time") {
                            transformedPayload = this._xsdTimeToMmTime(sourceEvent.payload);
                        }
                        break;
                    case "date":
                        switch (sourceEvent.type.toLowerCase()) {
                            case "xsd:date":
                                transformedPayload = this._xsdDateToMmDate(sourceEvent.payload);
                                break;
                            case "js:date":
                                transformedPayload = this._jsDateToMmDate(sourceEvent.payload);
                                break;
                        }
                        break;
                    case "timestamp":
                        if (sourceEvent.type.toLowerCase() == "xsd:datetime") {
                            transformedPayload = this._xsdDateTimeToMmTimestamp(sourceEvent.payload);
                        }
                        break;
                    case "xsd:time":
                        if (sourceEvent.type.toLowerCase() == "time") {
                            transformedPayload = this._mmTimeToXsdTime(sourceEvent.payload);
                        }
                        break;
                    case "xsd:date":
                        switch (sourceEvent.type.toLowerCase()) {
                            case "date":
                                transformedPayload = this._mmDateToXsdDate(sourceEvent.payload);
                                break;
                            case "js:date":
                                transformedPayload = this._jsDateToXsdDate(sourceEvent.payload);
                                break;
                        }
                        break;
                    case "xsd:datetime":
                        if (sourceEvent.type.toLowerCase() == "timestamp") {
                            transformedPayload = this._mmTimestampToXsdDatetime(sourceEvent.payload);
                        }
                        break;
                    case "js:date":
                        switch (sourceEvent.type.toLowerCase()) {
                            case "xsd:date":
                                transformedPayload = this._xsdDateToJsDate(sourceEvent.payload);
                                break;
                            case "date":
                                transformedPayload = this._mmDateToJsDate(sourceEvent.payload);
                                break;
                        }
                        break;
                }
                if (transformedPayload !== null) {
                    transformedEvent = new com.ibm.mm.iwidget.IEventImpl(sourceEvent.name, targetEvent.type, transformedPayload, sourceEvent.source);
                }
                else {
                    // they are compatible and no payload transformation needed
                    transformedEvent = new com.ibm.mm.iwidget.IEventImpl(sourceEvent.name, targetEvent.type, sourceEvent.payload, sourceEvent.source);
                }
            }
        }
        return transformedEvent;

    },


    isTransformable: function(sourceEvent, targetEvent, relaxed){
        return this.dataTypes.doesTypeFlexMatch(sourceEvent.type, targetEvent.type, relaxed);
    },

    _mmTimestampToXsdDatetime: function(timestamp){
        var timestampDelimiter = "T";
        var dateDelimiter = "-";
        var timeDelimiter = ":";
        var defaultFormat = /^([\d]{4})-([\d]{2})-([\d]{2})\s([\d]{2}):([\d]{2}):([\d]{2})$/; //YYYY-MM-DD hh:mm:ss
        var longFormat = /^([\d]{4})-([\d]{2})-([\d]{2})\s([\d]{2}):([\d]{2}):([\d]{2})\.([\d]{4})$/; //YYYY-MM-DD hh:mm:ss.mmmm
        var shortFormat = /^([\d]{4})([\d]{2})([\d]{2})\s([\d]{2})([\d]{2})([\d]{2})$/; //YYYYMMDD hhmmss
        var isValidFormat = false;

        //check YYYY-MM-DD hh:mm:ss.mmmm
        isValidFormat = longFormat.test(timestamp);
        if (isValidFormat) {
            var newTimeStamp = timestamp.split(new RegExp("[.]{1}"))[0];
            return newTimeStamp.replace(/\s/, timestampDelimiter);
        }
        else {
            //check YYYY-MM-DD hh:mm:ss
            isValidFormat = defaultFormat.test(timestamp);
            if (isValidFormat) {
                return timestamp.replace(/\s/, timestampDelimiter);
            }
            else {
                //check YYYYMMDD hhmmss
                isValidFormat = shortFormat.test(timestamp);
                if (isValidFormat) {
					var parts = shortFormat.exec(timestamp);
                    var yyyy = parts[1];
                    var months = parts[2];
                    var dd = parts[3];
                    var hh = parts[4];
                    var minutes = parts[5];
                    var ss = parts[6];
                    return yyyy + dateDelimiter + months + dateDelimiter + dd + timestampDelimiter + hh + timeDelimiter + minutes + timeDelimiter + ss;
                }
                else {
                    //not valid format
                    return null;
                }
            }
        }
    },

    _mmDateToXsdDate: function(date){
        //defaults
        var delimiter = "-";
        var defaultmm = "01";
        var defaultdd = "01";
        var defaultFormat = /^([\d]{4})-([\d]{2})-([\d]{2})$/; //YYYY-MM-DD
        var yyyymmddFormat = /^([\d]{4})([\d]{2})([\d]{2})$/; //YYYYMMDD
        var yyyymmFormat = /^([\d]{4})([\d]{2})$/; //YYYYMM
        var yyyyFormat = /^([\d]{4})$/; //YYYY
        var isValidFormat = false;
        // split(new RegExp("[./]{1}"))

        isValidFormat = defaultFormat.test(date);
        if (isValidFormat) {
            //already in correct format
            return date;
        }
        else {
            //check YYYYMMDD
            isValidFormat = yyyymmddFormat.test(date);
            var yyyy, mm, parts;
            if (isValidFormat) {
				parts  = yyyymmddFormat.exec(date);
                yyyy = parts[1];
                mm = parts[2];
                var dd = parts[3];
                return yyyy + delimiter + mm + delimiter + dd;
            }
            else {
                //check YYYYMM
                isValidFormat = yyyymmFormat.test(date);
                if (isValidFormat) {
					parts = yyyymmFormat.exec(date);
                    yyyy = parts[1];
                    mm = parts[2];
                    return yyyy + delimiter + mm + delimiter + defaultdd;
                }
                else {
                    //check YYYY
                    isValidFormat = yyyyFormat.test(date);
                    if (isValidFormat) {
						parts = yyyyFormat.exec(date);
                        yyyy = parts[1];
                        return yyyy + delimiter + defaultmm + delimiter + defaultdd;
                    }
                    else {
                        //not valid format
                        return null;
                    }
                }
            }
        }
    },

    _mmTimeToXsdTime: function(time){
        var delimiter = ":";
        var defaultmm = "00";
        var defaultss = "00";
        var hhmmssmmmmFormat = /^\d{2}\:\d{2}\:\d{2}\.\d{4}$/; //hh:mm:ss.mmmm
        var hhmmssFormat = /^\d{2}\:\d{2}\:\d{2}$/; //hh:mm:ss
        var hhmmFormat = /^\d{2}\:\d{2}$/; //hh:mm
        var hhFormat = /^\d{2}$/; //hh
        var isValidFormat = false;

        //check hh:mm:ss.mmmm
        isValidFormat = hhmmssmmmmFormat.test(time);
        if (isValidFormat) {
            return time.split(new RegExp("[.]{1}"))[0];
        }
        else {
            //check hh:mm:ss
            isValidFormat = hhmmssFormat.test(time);
            if (isValidFormat) {
                //already in valid format
                return time;
            }
            else {
                //check hh:mm
                isValidFormat = hhmmFormat.test(time);
                if (isValidFormat) {
                    //already in valid format
                    return time + delimiter + defaultss;
                }
                else {
                    //check hh
                    isValidFormat = hhFormat.test(time);
                    if (isValidFormat) {
                        //already in valid format
                        return time + delimiter + defaultmm + delimiter + defaultss;
                    }
                    else {
                        //not in valid format
                        return null;
                    }
                }
            }
        }
    },

    _xsdDateTimeToMmTimestamp: function(datetime){
        var datetimeDelimiter = " ";
        var defaultFormat = /^\d{4}\-\d{2}\-\d{2}\T\d{2}\:\d{2}\:\d{2}/; //YYYY-MM-DD hh:mm:ss
        var isValidFormat = false;

        isValidFormat = defaultFormat.test(datetime);
        if (isValidFormat) {
            var newDateTime = datetime.match(defaultFormat)[0];
            return newDateTime.replace(/T/, datetimeDelimiter);
        }
        else {
            //not in valid format
            return null;
        }
    },

    _xsdDateToMmDate: function(date){
        var defaultFormat = /^\d{4}\-\d{2}\-\d{2}/; //YYYY-MM-DD
        var isValidFormat = false;

        isValidFormat = defaultFormat.test(date);
        if (isValidFormat) {
            return date.match(defaultFormat)[0];
        }
        else {
            //not in valid format
            return null;
        }
    },

    _xsdTimeToMmTime: function(time){
        var defaultFormat = /^\d{2}\:\d{2}\:\d{2}/; //HH-MM-SS
        var isValidFormat = false;

        isValidFormat = defaultFormat.test(time);
        if (isValidFormat) {
            return time.match(defaultFormat)[0];
        }
        else {
            //not in valid format
            return null;
        }
    },

    _jsDateToMmDate: function(date){
        //YYYY-MM-DD
        if (date) {
            var year = date.getFullYear();
            var month = date.getMonth();
            var day = date.getDate();
            month = this._format(month.toString());
            day = this._format(day.toString());
            return year + "-" + month + "-" + day;
        }
        else {
            return null;
        }
    },

    _jsDateToXsdDate: function(date){
        var xsdDate = null;
        if (date) {
            var year = date.getFullYear();
            var month = date.getMonth();
            var day = date.getDate();
            var timezoneOffset = date.getTimezoneOffset();
            month = this._format(month.toString());
            day = this._format(day.toString());
            xsdDate = year + "-" + month + "-" + day;
            if (timezoneOffset !== 0) {
                var timezone;
                var hours;
                var minutes;
                if (timezoneOffset < 0) {
                    hours = Math.ceil(timezoneOffset / 60);
                    minutes = (timezoneOffset * -1) % 60;
                    if (minutes === 0) {
                        timezone = "-" + this._format((hours * -1).toString()) + ":00";
                    }
                    else {
                        timezone = "-" + this._format((hours * -1).toString()) + this._format(minutes);
                    }
                    xsdDate = xsdDate + timezone;
                }
                else {
                    hours = Math.floor(timezoneOffset / 60);
                    minutes = timezoneOffset % 60;
                    if (minutes === 0) {
                        timezone = "+" + this._format((hours).toString()) + ":00";
                    }
                    else {
                        timezone = "+" + this._format((hours).toString()) + this._format(minutes);
                    }
                    xsdDate = xsdDate + timezone;
                }
            }
        }
        return xsdDate;
    },

    _xsdDateToJsDate: function(date){
        var defaultFormat = /^([\d]{4})-(\d\d)-(\d\d)/;
        var isValidFormat = false;

        isValidFormat = defaultFormat.test(date);
        if (isValidFormat) {
            var newDate = new Date(NaN);
            var month;
            var parts = defaultFormat.exec(date);
            if (parts) {
                month = parts[2];
                newDate.setFullYear(parts[1], month - 1, parts[3]);
                if (month != newDate.getMonth() + 1) {
                    newDate.setTime(NaN);
                }
            }
            return newDate;
        }
        else {
            //not in valid format
            return null;
        }
    },

    _mmDateToJsDate: function(date){
        return this._xsdDateToJsDate(this._mmDateToXsdDate(date));
    },

    _format: function(value){
        if (value.length == 1) {
            //add preceding 0
            value = "0" + value;
        }
        return value;
    }

});

}

if(!dojo._hasResource["com.ibm.mashups.enabler.utils.EventTransformer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.utils.EventTransformer"] = true;
dojo.provide("com.ibm.mashups.enabler.utils.EventTransformer");





}

if(!dojo._hasResource["com.ibm.mashups.enabler.widget.Constants_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.widget.Constants_API"] = true;
dojo.provide("com.ibm.mashups.enabler.widget.Constants_API");
dojo.provide("com.ibm.mashups.enabler.widget.Constants");

dojo.declare("com.ibm.mashups.enabler.widget.Constants", null, {

    /**
     * Handled events
     * @type {String}
     */
    FILTER_HANDLED_EVENTS: "HandledEvents",

    /**
     * Published events
     * @type {String}
     */
    FILTER_PUBLISHED_EVENTS: "PublishedEvents"
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.widget.Constants"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.widget.Constants"] = true;
dojo.provide("com.ibm.mm.enabler.widget.Constants");



dojo.declare("com.ibm.mm.enabler.widget.Constants", com.ibm.mashups.enabler.widget.Constants, {

    constructor: function() {

    },

    PERSISTENCE_MODE_MODEL: "Model",
    PERSISTENCE_MODE_MODEL_PREFERENCES: "ModelPreferences",
    PERSISTENCE_MODE_DOM: "DOM"
});

com.ibm.mashups.enabler.widget.Constants = new com.ibm.mm.enabler.widget.Constants();

}

if(!dojo._hasResource["com.ibm.mashups.enabler.widget.Constants"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.enabler.widget.Constants"] = true;
dojo.provide("com.ibm.mashups.enabler.widget.Constants");

/**
 * Constants for the widget model.
 * @ibm-api
 * @ibm-module iWidget2
 * @since 2.4
 */




}

if(!dojo._hasResource["com.ibm.mashups.iwidget.itemset.PersistentAttributesFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.itemset.PersistentAttributesFactory"] = true;
dojo.provide("com.ibm.mashups.iwidget.itemset.PersistentAttributesFactory");

/**
 * @private
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.itemset.PersistentAttributesFactory",null,  {
    /**
     * Creates persistent attributes for the specified widget and persistence mode.
     *
     * @param {com.ibm.mashups.iwidget.widget.IWidgetWrapper} widget the widget for which to create the persistent attributes
     * @param {String} persistenceMode the persistence mode for which to create the attributes
     * @return {ManagedItemSet} the persistent attributes for the given widget / mode.
     * If the specified mode is not supported by this method <tt>null</tt> will be returned.
     */
    createPersistentAttributes: function(widgetWrapper, persistenceMode) {

    },
    /**
     * Returns the persistence modes that are supported by this factory.
     * @return {String[]} the supported persistence modes.
     */
    getSupportedPersistenceMode: function() {

    }
});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService_API"] = true;
dojo.provide("com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService_API");
dojo.provide("com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService");

/**
 * @private
 * @ibm-module iWidget2
 */
dojo.declare("com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService",null,  {

	/**
	 * TODO make this public at some point, ServiceManager documentation says it should be there
	 *
	 * @private
	 */
	SERVICE_NAME : "persistentAttributesFactoryService",

    /**
     * Creates persistent attributes for the specified widget by honoring the current persistence mode (e.g. DOM vs. WidgetModel).
     * The factory for the current persistence mode needs to be added to this service by using the <tt>addFactory</tt> method of this class.
     *
     * @param {com.ibm.mashups.iwidget.widget.IWidgetWrapper} widget the widget for which to create the persistent attributes
     * @return {ManagedItemSet} an itemset for the specified widget using the according factory or <tt>null</tt> if no factory is available for the current mode.
     */
    createPersistentAttributes: function(widgetWrapper, contextAndCallback) {

    },
    /**
     * Sets the factory for the specified persistenceMode to this service.
     * @param {String} persistenceMode the mode that is supported by the specified factory
     * @param {com.ibm.mashups.iwidget.services.PersistentAttributesFactory} factory the factory that creates the attributes.
     * @return {void}
     */
    setFactory: function(persistenceMode, factory) {

    },

    /**
    * Removes a factory for a specified persistence mode.
    *
    * @param {String} persistenceMode the mode to remove
    *
    * TODO make this public at some time
    * @private
    */
   removeFactory: function(persistenceMode) {

   }
});

com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService.SERVICE_NAME = com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService.prototype.SERVICE_NAME;

}

if(!dojo._hasResource["com.ibm.mm.iwidget.manageditemset.DOMPersistentAttributesFactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.manageditemset.DOMPersistentAttributesFactoryImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.manageditemset.DOMPersistentAttributesFactoryImpl");




dojo.declare("com.ibm.mm.iwidget.manageditemset.DOMPersistentAttributesFactoryImpl",com.ibm.mashups.iwidget.itemset.PersistentAttributesFactory, {
    constructor: function() {
        this.modes = ["DOM"];
    },
    createPersistentAttributes: function(widgetWrapper, persistenceMode) {
        return new com.ibm.mm.iwidget.manageditemset.PersistentAttributes(widgetWrapper, true/*serverless*/);
    },
    getSupportedPersistenceMode: function() {
        return this.modes;
    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget2
 */

// inject this service into the ServiceManager at the end. Therefore we have to require the implementation










dojo.declare("com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl", com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService, {
    constructor: function(){
        this._factories = {};
    },
    createPersistentAttributes: function(widgetWrapper, contextAndCallback){
        if (contextAndCallback) {
            // register callback
            com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME).registerOnChangeListener(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES, contextAndCallback);
        }
        var persistenceMode;
        var wID = widgetWrapper.id;

        var persistenceMode = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME).getPersistenceMode(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_ATTRIBUTES);

        var widgetDomNode = widgetWrapper.rootElement;

        if (dojo.hasClass(widgetDomNode, com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl.STANDALONE_CLASS) || !persistenceMode) {
            persistenceMode = com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl.DEFAULT_PERSISTENCE;
        }

        if (typeof persistenceMode !== "undefined" && persistenceMode == com.ibm.mashups.enabler.widget.Constants.PERSISTENCE_MODE_MODEL) {
            var widgetModel = com.ibm.mashups.enabler.widget.Factory.getWidgetModel();
            var navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
            var spaceAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getSpaceAccessor(navStateModel);
            var pageAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getPageAccessor(navStateModel, currentSpaceID);

            var currentSpaceID = spaceAccessor.getSpaceID();
            var currentPageID = pageAccessor.getPageID();

            var modelID = com.ibm.mm.iwidget.Utils.getModelID(wID);

            var wnd = widgetModel.findWidgetWindow(modelID, currentPageID).start();

            if (!wnd) {
                // we put a failsafe here to verify if the given ID is a client side ID, and if this is the case we are switching to DEFAULT PERSISTENCE
                // the reason resides in a chicken and egg problem in that a not yet live preview widget may try to get the attributes
                // in its onunload function, but it has already been discarded from the WidgetModel. This means that it would show an error that
                // iw-Standalone is required
                if (!com.ibm.mashups.enabler.services.IdentificationService.isClientID(modelID)) {
                    if (dojo.isFunction(widgetWrapper._getResourceBundle)) {
                        widgetWrapper._getResourceBundle();
                    }
                }
                persistenceMode = com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl.DEFAULT_PERSISTENCE;
            }
        }

        if (!(persistenceMode in this._factories)) {
            return null;
        }

        return this._factories[persistenceMode].createPersistentAttributes(widgetWrapper, persistenceMode);
    },
    setFactory: function(persistenceMode, factory){
        this._factories[persistenceMode] = factory;
    },

    removeFactory: function(persistenceMode) {
    	if(persistenceMode in this._factories) {
    		delete this._factories[persistenceMode];
    	}
    }
});


com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl.DEFAULT_PERSISTENCE = com.ibm.mashups.enabler.widget.Constants.PERSISTENCE_MODE_DOM;
com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl.STANDALONE_CLASS = com.ibm.mm.iwidget.Constants.CSSCLASS_PREFIXED_INSTANCE.iwStandalone;

com.ibm.mashups.services.ServiceManager.setService(com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService.SERVICE_NAME, new com.ibm.mm.iwidget.services.PersistentAttributesFactoryServiceImpl());

com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService.SERVICE_NAME).setFactory(com.ibm.mashups.enabler.widget.Constants.PERSISTENCE_MODE_DOM, new com.ibm.mm.iwidget.manageditemset.DOMPersistentAttributesFactoryImpl());

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService"] = true;
dojo.provide("com.ibm.mashups.iwidget.services.PersistentAttributesFactoryService");





}

if(!dojo._hasResource["com.ibm.mm.iwidget.services.IWidgetFragmentServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.services.IWidgetFragmentServiceImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.services.IWidgetFragmentServiceImpl");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget2
 */
// inject this service into the ServiceManager at the end. Therefore we have to require the implementation



dojo.declare("com.ibm.mm.iwidget.services.IWidgetFragmentServiceImpl", null, {
    /**
     This function creates an Item in microformat as defined by iWidget spec.<p/>
     If defaultValue is provided and no defaultLanguage is provided, following element will be created.<br/>
     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> &lt;a class="iw-Item" href="#{itemName}" &gt;{defaultValue} &lt;/a&gt; </code><br/>
     If defaultLanguage is provided, following element will be created.</br>
     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> &lt;a class="iw-Item" href="#{itemName}" lang="{defaultLang}"&gt; &lt;/a&gt; </code><br/>
     @param{String } itemName name of the item. Must never be NULL.
     @param{String } defaultValue  default value of the item. May be NULL.
     @param{String } defaultLang  default language of a localized item .May be NULL.
     @param{String } prefix  optional. namespace of the class, default is "iw-".
     @type DOMElement
     @returns{DOMElement }  DOMElement of the new item.
     */
    createItem: function(itemName, defaultValue, defaultLang, ns) {
        if (!ns) {
            ns = "iw-";
        }
        var item = document.createElement("a");
        dojo.addClass(item, ns + iwConstants.CSSCLASS_INSTANCE.iwItem);
        dojo.style(item, "visibility", "hidden");
        dojo.style(item, "display", "none");

        item.setAttribute("href", "#" + itemName);
        if (defaultLang) {
            item.setAttribute("lang", defaultLang);
        }
        if (defaultValue && !defaultLang) {
            item.innerHTML = defaultValue;
        }
        return item;
    },
    /**
     This function creates an ItemSet in microformat as defined by iWidget spec.<p/>
     Following element will be created.<br/>
     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> &lt;span class="iw-ItemSet"  title="{setName}"&gt;&lt;/span&gt;</code><br/>
     @param{String } itemSetName name of the itemset. Must never be NULL.
     @param{String } prefix  optional. namespace of the class, default is "iw-".
     @type DOMElement
     @returns{DOMElement }  DOMElement of the new itemset.
     */
    createItemSet: function(itemSetName, ns) {
        if (!ns) {
            ns = "iw-";
        }
        var param = document.createElement("span");
        dojo.addClass(param, ns + iwConstants.CSSCLASS_INSTANCE.iwItemSet);
        param.setAttribute("title", itemSetName);
        dojo.style(param, "visibility", "hidden");
        dojo.style(param, "display", "none");
        return param;
    },
    /**
     This function creates an  anchor link that points to url to load widget definition.<p/>
     Following element will be created.<br/>
     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> &lt;a class="iw-Definition" href="{uri}" /&gt;&lt;/code&gt;<br/>
     @param{String } widgetDefUrl  url to load widget definition xml. Must never be NULL.
     @param{String } prefix  optional. namespace of the class, default is "iw-".
     @type DOMElement
     @returns{DOMElement }  DOMElement of the new anchor link.
     */
    createWidgetDefRef: function(widgetDefUrl, ns) {
        if (!ns) {
            ns = "iw-";
        }
        var aTag = document.createElement("a");
        dojo.addClass(aTag, ns + iwConstants.CSSCLASS_INSTANCE.iwDefinition);
        aTag.setAttribute("href", widgetDefUrl);
        dojo.style(aTag, "visibility", "hidden");
        dojo.style(aTag, "display", "none");
        return aTag;
    },
    /**
     This function returns the required itemset with the given iwidget id.<br/>
     @param{String } iwidgetId  iwidget id. Must never be NULL.
     @param{String } name  name of the required ItemSet. Must never be NULL.
     @param{String } prefix  optional. namespace of the class, default is "iw-".
     @type DOMElement
     @returns{DOMElement }  DOMElement of the itemset.
     */
    getItemSet: function(iwidgetId, name, ns) {
        if (!ns) {
            ns = "iw-";
        }
        var rc = null;
        var widgetSpan = dojo.byId(iwidgetId);
        var itemsets = dojo.query("." + ns + iwConstants.CSSCLASS_INSTANCE.iwItemSet, widgetSpan);
        for (var i = 0; i < itemsets.length; i++) {
            var anItemSet = itemsets[i];
            var title = anItemSet.getAttribute("title");
            if (name == title) {
                rc = anItemSet;
                break;
            }

        }
        return rc;
    },
    /**
     This function returns the required item with the given parent.<br/>
     item element is a nested element within itemset element.<br/>
     @param{DOMElement } parent  parent element. Must never be NULL.
     @param{String } name  name of the required item. Must never be NULL.
     @param{String } prefix  optional. namespace of the class, default is "iw-".
     @type DOMElement
     @returns{DOMElement }  DOMElement of the item.
     */
    getItem: function(parent, name, ns) {
        if (!ns) {
            ns = "iw-";
        }
        var rc = null;
        var items = dojo.query("." + ns + iwConstants.CSSCLASS_INSTANCE.iwItem, parent);
        for (var i = 0; i < items.length; i++) {
            var anItem = items[i];
            var title = this.getKeyFromHref(anItem);
            if (title && title == name) {
                rc = anItem;
                break;
            }
        }
        return rc;
    },
    /**
     This function returns the all the items within the given parent itemset.<br/>
     item element is a nested element within itemset element.<br/>
     @param{DOMElement } parent  parent element. Must never be NULL.
     @param{String } prefix  optional. namespace of the class, default is "iw-".
     @type DOMElement[]
     @returns{DOMElement []}   list of DOMElements.
     */
    getItems: function(parent, ns) {
        if (!ns) {
            ns = "iw-";
        }
        var items = dojo.query("." + ns + iwConstants.CSSCLASS_INSTANCE.iwItem, parent);
        if (typeof items == "undefined" || items === null || items.length === 0) {
            items = null;
        }
        return items;
    },
    /**
     This function returns the reference to the widget definition.<br/>
     Widget definition reference is defined within anchor link.<br/>
     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> &lt;a class="iw-Definition" href="{uri}" /&gt;&lt;/code&gt;<br/>
     @param{String } iwidgetId  id of the iWidget. Must never be NULL.
     @param{String } prefix  optional. namespace of the class, default is "iw-".
     @type String
     @returns{ String }   uri to download the iWidget definition.
     */
    getWidgetDefRef: function(iwidgetId, ns) {
        if (!ns) {
            ns = "iw-";
        }
        var rc = null;
        var widgetSpan = dojo.byId(iwidgetId);
        var def = dojo.query("." + ns + iwConstants.CSSCLASS_INSTANCE.iwDefinition, widgetSpan)[0];
        var ref = def.getAttribute("href");
        if (ref) {
            rc = ref;
        }
        return rc;
    },
    /**
     This function provides a convenience function to get  the real value defined with an "href" attribute.<br/>
     Per iWidget spec, several items are defined by using anchor link. <br/>
     For example,  item element or sourceEvent within a ReceivedEvent.<br/>
     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code> &lt;a class="iw-Item" href="#{itemName}" &gt;{value} &lt;/a&gt; </code><br/>
     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<code>&lt;a class="iw-SourceEvent" href="#{sourceWidgetID}"&gt;{sourceEventName} &lt;/a &gt;</code><br/>
     This function will return itemname if it's an item node.<br/>
     This function will return id of source iWidget if it's an sourceevent node within a ReceivedEvent.<br/>
     @param{DOMNode } node  DOMNode which is an item. Must never be NULL.
     @type String
     @returns{ String }   .
     */
    getKeyFromHref: function(node) {
        var hrefValue = node.getAttribute("href");
        if (!hrefValue) {
            return null;
        }
        var pos = hrefValue.indexOf("#");
        if (pos < 0) {
            return null;
        }
        return hrefValue.substring(pos + 1);
    }
});


com.ibm.mashups.services.ServiceManager.setService("iwidgetFragmentService", new com.ibm.mm.iwidget.services.IWidgetFragmentServiceImpl());

}

if(!dojo._hasResource["com.ibm.mm.enabler.EndpointUtilsExtendedImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.EndpointUtilsExtendedImpl"] = true;
dojo.provide("com.ibm.mm.enabler.EndpointUtilsExtendedImpl");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget
 *
 * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
 * Any number that is smaller causes this class to be written out before any other with a higher number
 * @ibm-dojo-profile-level 40
 */






dojo.declare("com.ibm.mm.enabler.EndpointUtilsExtendedImpl", com.ibm.mm.enabler.EndpointUtilsDefaultImpl, {
    constructor: function(){
    },

    checkForEndpoints: function(/*String*/url){
        if (!url) {
            return null;
        }

        var result = url.toString();
        if (result) {
            var index = result.indexOf("endpoint://", 0);
            if (index === 0) {
                var relativeIndex = result.indexOf("/", 11);
                if (relativeIndex > 0) {
                    var endpoint = result.substring(11, relativeIndex);
                    var relativeURL = result.substring(relativeIndex + 1);
                    var resolvedEndpoint = this._resolveEndpoint(endpoint);
                    if (resolvedEndpoint) {
                        if (resolvedEndpoint.charAt(resolvedEndpoint.length - 1) == '/') {
                            result = resolvedEndpoint + relativeURL;
                        }
                        else {
                            result = resolvedEndpoint + '/' + relativeURL;
                        }
                        return result;
                    }
                    else {
                        return null;
                    }
                }
            }
            else
                if (index > 0) {
                    var origUrl = result.substring(0, index);
                    var endpointPortion = result.substring(index);
                    var endpointPortion2 = this.checkForEndpoints(endpointPortion);
                    if (endpointPortion2) {
                        //return origUrl + endpointPortion2.substring(1);
                        return endpointPortion2.substring(0);
                    }
                }
        }

        return url;
    },

    _resolveEndpoint: function(/*String*/endpoint){
        if (!this.co) {
            this._init();
        }

        var decodedEndpoint = decodeURIComponent(endpoint);

        var url = this.co.getValue(decodedEndpoint + ".url");

        if (!url) {
            if (decodedEndpoint == "{contenthandler}") {
                url = this.urlContentHandler;
            }
            else
                if (decodedEndpoint == "{webdavroot}") {
                    url = this.urlWebDavRoot;
                }
                else {
                    return null;
                }
        }

        if ((url) && (url.charAt(0) != "/") && (url.substr(0, 4) != "http")) {
            url = "/" + url;
        }

        return url;
    },

    _init: function(){
        this.cs = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);

        this.co = this.cs.getConfigObject(com.ibm.mashups.enabler.services.ConfigConstants.ENDPOINT_CONFIG_PROVIDER);

        this.urlContentHandler = "";

        // add the contextroot
        this.urlContentHandler += this.cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT);

        // add the public contenthandler url
        var anonymousUser = this.cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.ANONYMOUS_USER);

        var contenthandlerPath;

        if (anonymousUser) {
            contenthandlerPath = this.cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PUBLIC);
        }
        else {
            contenthandlerPath = this.cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTENTHANDLER_PRIVATE);
        }

        this.urlContentHandler += contenthandlerPath;

        if (com.ibm.mm.enabler.remote && com.ibm.mm.enabler.remote.WebDavUrlFactory) {
            this.urlWebDavRoot = com.ibm.mm.enabler.remote.WebDavUrlFactory.createUrl() + "/";
        }
        else {
            this.urlWebDavRoot = null;
        }

    }
});
com.ibm.mm.enabler.EndpointUtils = new com.ibm.mm.enabler.EndpointUtilsExtendedImpl();

}

if(!dojo._hasResource["com.ibm.mm.iwidget.payloadDef"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.payloadDef"] = true;
dojo.provide("com.ibm.mm.iwidget.payloadDef");



dojo.declare("com.ibm.mm.iwidget.payloadDef", null, {
    constructor: function(name, type, defaultValue, description, attributes) {
        this.name = name;
        this.attributes = attributes || null;
        if (!this.attributes) {
            this.attributes = {};
        }

        if (typeof type != "undefined" && type !== null) {
            this.attributes.type = type;
        }
        if (typeof defaultValue != "undefined" && defaultValue !== null) {
            this.attributes.defaultValue = defaultValue;
        }
        if (typeof description != "undefined" && description !== null) {
            this.attributes.description = description;
        }

        this.attributeNames = [];
        this.attributeNames.push("type");
        this.attributeNames.push("defaultValue");
        this.attributeNames.push("description");

        var aName;
        for (aName in attributes) {
            if (Object.prototype.hasOwnProperty.call(attributes,aName)) {
                this.attributeNames.push(aName);
            }
        }
        this.children = new com.ibm.mm.enabler.ArrayMap();/*an array of payloadDef*/
    },
    setAttribute: function(name, defaultValue) {
        this.attributes[name] = defaultValue;
        if (typeof(this.attributeNames[name]) != "undefined") {
            this.attributeNames.push(name);
        }
    },
    getAttribute: function(name) {
        var defaultValue = this.attributes[name];
        if (typeof defaultValue == "undefined") {
            defaultValue = null;
        }
        return defaultValue;
    },
    getAttributeNames: function() {
        return this.attributeNames;
    },
    getChildren: function() {
        return this.children.values();
    },
    getChild: function(name) {
        return this.children.get(name);
    },
    setChild: function(name,/*object*/ payloadDef) {
        this.children.put(name, payloadDef);
    },
    getChildrenNames: function() {
        this.children.keySet();
    },
    getName: function() {
        return this.name;
    },
    getType: function() {
        return this.attributes.type;
    },
    getDefaultValue: function() {
        return this.attributes.defaultValue;
    },
    getDescription: function() {
        return this.attributes.description;
    }
});


}

if(!dojo._hasResource["com.ibm.mm.iwidget.UtilsExtended"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.UtilsExtended"] = true;
dojo.provide("com.ibm.mm.iwidget.UtilsExtended");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget
 *
 * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
 * Any number that is smaller causes this class to be written out before any other with a higher number
 * @ibm-dojo-profile-level 40
 */



dojo.declare("com.ibm.mm.iwidget.UtilsExtendedImpl", com.ibm.mm.iwidget.UtilsDefaultImpl, {

    getPayloadDef: function(aNode) {
        var name = aNode.getAttribute("name");
        var payloadDef = new com.ibm.mm.iwidget.payloadDef(name);
        var attributes = aNode.attributes;
        //var attributesArr = [];
        for (var i = 0; i < attributes.length; i++) {
            var anAttribute = attributes[i];
            if (anAttribute.name != "name") {
                payloadDef.setAttribute(anAttribute.name, anAttribute.value);
            }
        }
        var children = aNode.childNodes;
        for (var j = 0; j < children.length; j++) {
            var child = children[j];
            if (child.nodeType == 1) {
                var aChildPayloadDef = this.getPayloadDef(child);
                payloadDef.setChild(aChildPayloadDef.name, aChildPayloadDef);
            }
        }
        return payloadDef;
    }
});

//IMPORTANT
//ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
//This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "CoreModel") >= 0)) {
    dojo["require"]("com.ibm.mm.enabler.iwidget.UtilsModelImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the layers
} else {
    com.ibm.mm.iwidget.Utils = new com.ibm.mm.iwidget.UtilsExtendedImpl();
}

}

if(!dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextMMExtensionImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextMMExtensionImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.icontext.IContextMMExtensionImpl");

dojo.declare("com.ibm.mm.iwidget.icontext.IContextMMExtensionImpl", null, {

    constructor: function(wrapper) {
        //information accessible from iwidget
        this.widget = wrapper;
        this.widgetId = wrapper.id;
    },
    getSupportedModes: function() {
        var supportedModes = this.widgetwrapper.widgetDef.getSupportedModes();
        return supportedModes;
    },
    getPayloadDef: function(name) {
        var payloadDefs = this.widget.widgetDef.payloadDefs;
        var payloadDef = payloadDefs[name];
        if (typeof payloadDef == "undefined") {
            return null;
        }
        return payloadDef;
    },
    getPayloadDefNames: function() {
        var payloadDefs = this.widget.widgetDef.payloadDefs;
        var arr = [];
        for (var a in payloadDefs) {
            if (Object.prototype.hasOwnProperty.call(payloadDefs,a)) {
                arr.push(a);
            }
        }
        return arr;
    }
});


}

if(!dojo._hasResource["com.ibm.mm.iwidget.manageditemset.UserProfileImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.manageditemset.UserProfileImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.manageditemset.UserProfileImpl");



dojo.declare("com.ibm.mm.iwidget.manageditemset.UserProfileImpl", com.ibm.mashups.iwidget.itemset.ManagedItemSet, {
    constructor: function(widgetId, user) {
        this.widgetId = widgetId;
        this.user = user;
    },
    getItemValue: function(/*string*/name) {
        if (!name) {
            return null;
        }
        var value = this.user.getAttribute(name);
        if (typeof value == "undefined") {
            value = null;
        }
        return value;
    },
    setItemValue: function(name, value) {
        //readonly
        if (!name || !value) {
            return null;
        }
        if (this.isReadOnly(name)) {
            return null;
        }
        this.user.setAttribute(name, value);
        return this;
    },
    isReadOnly: function(name) {
        if (typeof name == "undefined" || name === null) {
            return false;
        }
        var readOnlyAttributes = this.user.getReadOnlyAttributeNames();
        var rc = this._contains(readOnlyAttributes, name);
        return rc;
    },
    _contains: function(array, attribute) {
        if (!attribute) {
            return false;
        }
        if (!array) {
            return false;
        }
        if (array && !dojo.isArray(array)) {
            return false;
        }
        for (var i = 0; i < array.length; i++) {
            if (array[i] && array[i] == attribute) {
                return true;
            }
        }
        return false;
    },
    removeItem: function(name) {
        if (!name) {
            return null;
        }
        if (this.isReadOnly(name)) {
            return null;
        }
        this.user.removeAttribute(name);
        return this;
    },
    getAllNames: function() {
        var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
        var hideLookaside = configService.getValue("com.ibm.mashups.hideLookaside");

        if (dojo.isString(hideLookaside) && hideLookaside.toLowerCase() == "true") {
            return this.user.getReadOnlyAttributeNames();
        }

        return this.user.getAttributeNames();
    },
    save: function(cb) {
        return this.commit(cb);
    },
    commit: function(cb) {
        var userModel = null;
        if (com.ibm.mashups.enabler.user.Factory.getUserModel) {
        	userModel = com.ibm.mashups.enabler.user.Factory.getUserModel();
        }
        if (userModel) {
	        var deferred = userModel.commit();

	        var fn = function(resource, statusCode, param) {
	            if (cb) {
	                var rc = false;
	                var itemName = iwConstants.USERPROFILE;
	                if (statusCode && statusCode == iwConstants.status.SUCCESS) {
	                    rc = true;
	                }
	                cb(itemName, rc);
	            }
	        };
	        deferred.setFinishedCallback(fn);
	        deferred.start();
        }
    },
    addListener: function(/*obj*/fn) {
        var widget = this._getWidget();
        if (!widget) {
            return null;
        }
        var listenerId = widget._registerListener(iwConstants.USERPROFILE, fn);
        return listenerId;
    },
    removeListener: function(/*String*/listenerId) {
        var widget = this._getWidget();
        if (!widget) {
            return null;
        }
        return widget._removeListener(iwConstants.USERPROFILE, listenerId);
    },
    _getWidget: function() {
        var widgetModel = com.ibm.mashups.iwidget.model.Factory.getGlobalModel();
        return widgetModel.find(this.widget) || null;
    }

});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.widget.ResourceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.widget.ResourceImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.widget.ResourceImpl");

dojo.declare("com.ibm.mm.iwidget.widget.ResourceImpl", null, {
    constructor: function(/*JSON object*/obj) {
        if (obj) {
            for (var i in obj) {
                if (Object.prototype.hasOwnProperty.call(obj,i)) {
                    this[i] = obj[i];
                }
            }
        }
    },
    IMAGE: {
        "bmp": "bmp",
        "cod": "cod",
        "gif": "gif",
        "ief": "ief",
        "jpe": "jpe",
        "jpeg": "jpeg",
        "jpg": "jpg",
        "jfif": "jfif",
        "svg": "svg",
        "tif": "tif",
        "tiff": "tiff",
        "ras": "ras",
        "cmx": "cmx",
        "ico": "ico",
        "pnm": "pnm",
        "pbm": "pbm",
        "pgm": "pgm",
        "ppm": "ppm",
        "rgb": "rgb",
        "xbm": "xbm",
        "xpm": "xpm",
        "xwd": "xwd"

    },
    isCSS: function() {
        var rc = false;
        var extension = this._getExtension();
        if (extension && extension == "css") {
            rc = true;
        }
        if (!rc && this.getMimeType()) {
            if (this.getMimeType() == "text/stylesheet" || this.getMimeType() == "text/css") {
                rc = true;
            }
        }
        return rc;
    },
    isImage: function() {
        var rc = false;
        var extension = this._getExtension();
        if (extension && extension in this.IMAGE) {
            rc = true;
        }
        if (!rc && this.getMimeType()) {
            if (this.getMimeType().indexOf("image/") === 0) {
                rc = true;
            }
        }
        return rc;
    },
    isJS: function() {
        var rc = false;
        var extension = this._getExtension();
        if (extension && extension == "js") {
            rc = true;
        }
        if (!rc && this.getMimeType()) {
            var mimetype = this.getMimeType();
            if (mimetype == "text/javascript" || mimetype == "application/x-javascript" || mimetype == "application/javascript") {
                rc = true;
            }
        }
        return rc;
    },
    getGlobalId: function() {
		var id = this[iwConstants.RESOURCE.globalid];
        if (!id) {
            id= this[iwConstants.RESOURCE.id];
        }
		if (!id) {
			id = null;
		}
        return id;
    },
    getSrc: function() {
        return this[iwConstants.RESOURCE.src];
    },
    getMimeType: function() {
        var mimeType = this[iwConstants.RESOURCE.mimeType];
        if (!mimeType) {
            mimeType = null;
        }
        return mimeType;
    },
    _getExtension: function() {
        var uri = this.getSrc();
        if (!uri) {
            return null;
        }

        var extension = uri.substring(uri.lastIndexOf(".") + 1, uri.length);
        if (!extension) {
            return null;
        }
        return extension;
    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextExtendedImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.icontext.IContextExtendedImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.icontext.IContextExtendedImpl");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget
 *
 * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
 * Any number that is smaller causes this class to be written out before any other with a higher number
 * @ibm-dojo-profile-level 40
 */







dojo.declare("com.ibm.mm.iwidget.icontext.IContextExtendedImpl", com.ibm.mm.iwidget.icontext.IContextDefaultImpl, {
    _initEvents: function() {
        this.iEvents = new com.ibm.mm.iwidget.icontext.IContextIEventsImpl(this.widgetwrapper);
    },
    _initIO: function() {
        this.io = new com.ibm.mm.iwidget.icontext.IContextIOImpl(this.widgetwrapper);
    },
    _initMMExtension: function() {
        this._mm = new com.ibm.mm.iwidget.icontext.IContextMMExtensionImpl(this.widgetwrapper);
    },
    getUserProfile: function() {
        var userModel = null;
        if (com.ibm.mashups.enabler.user.Factory.getUserModel) {
        	userModel = com.ibm.mashups.enabler.user.Factory.getUserModel();
        }
        var user = null;
        if (userModel) {
            user = userModel.findCurrentUser().start();
        }
        var userProfile = null;
        if (user) {
            userProfile = new com.ibm.mm.iwidget.manageditemset.UserProfileImpl(this.widgetId, user);
        }
        return userProfile;
    },
    requires: function(/*String*/requiredItem,/*String*/ version,/*String*/ uri,/*function*/ cb, mimeType) {
        //Summery: provides means for iWidget to declare dependency on set of non-required items:
        //         "io"...
        //         no uri should be specified for above
        // shared resources can be loaded just once for all iwidgets like dojo.js
        // version support?
        // support dynamic loads in asynchronous manner
        mimeType = mimeType || null;
        if (!mimeType) {
            mimeType = "text/plain";
        }
        uri = uri || null;
        if (uri) {
            var obj = {};
            obj[iwConstants.RESOURCE.mimeType] = mimeType;
            obj[iwConstants.RESOURCE.id] = requiredItem;
            obj[iwConstants.RESOURCE.version] = version;
            obj[iwConstants.RESOURCE.src] = uri;
            obj[iwConstants.RESOURCE.callback] = cb;
            var resource = new com.ibm.mm.iwidget.widget.ResourceImpl(obj);

            com.ibm.mashups.services.ServiceManager.getService("resourceLoadService").loadResource(resource, this.widgetId);
        }
    },
    processiWidgets: function(/*domnode*/root) {
        dojo.publish("/com/ibm/mashups/livetext/livetextchanged", [root, true]);
    },
    getShareableItemSet: function(/*String*/name) {
        name = name || null;
        if (!name) {
            return null;
        }
        var itemSet = this.widgetwrapper._getShareableItemSet(name);
        return itemSet;
    }
});

com.ibm.mm.iwidget.icontext.IContextImpl = com.ibm.mm.iwidget.icontext.IContextExtendedImpl;

}

if(!dojo._hasResource["com.ibm.mm.iwidget.manageditemset.IDescriptorExtendedImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.manageditemset.IDescriptorExtendedImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.manageditemset.IDescriptorExtendedImpl");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget
 *
 * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
 * Any number that is smaller causes this class to be written out before any other with a higher number
 * @ibm-dojo-profile-level 40
 */





dojo.declare("com.ibm.mm.iwidget.manageditemset.IDescriptorExtendedImpl",com.ibm.mm.iwidget.manageditemset.IDescriptorDefaultImpl,{

	_getWindowState:function(){
		if (this.widget) {
		     var accessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getWidgetAccessor(this.navStateModel,this.widget.id);
			 value = accessor.getWindowState();
		 } else {
			 value = 'normal';
		 }
		 return value;
	}
});

com.ibm.mm.iwidget.manageditemset.IDescriptorImpl = com.ibm.mm.iwidget.manageditemset.IDescriptorExtendedImpl;

}

if(!dojo._hasResource["com.ibm.mm.iwidget.services.ResourceLoadServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.services.ResourceLoadServiceImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.services.ResourceLoadServiceImpl");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget
 */
// inject this service into the ServiceManager at the end. Therefore we have to require the implementation






dojo.declare("com.ibm.mm.iwidget.services.ResourceLoadServiceImpl", null, {
    constructor: function() {
        //loadModelus to keep track that if a resource has been loaded already
        this.modules = {};
        this.LOADING_TOKEN = 0;
        this.LOADING_ERROR_TOKEN = 1;
        this.LOADED_TOKEN = 2;
        this.waitingqueue = {};// resource is under loading,however callback might be different, waiting to be loaded
        this.evalqueue = {}; // js loaded within one resource will be evaluated in order
        this.callbackQueue = {};
        var cs = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
        if (cs) {
            var registeredLoadedResources = cs.getValue(com.ibm.mashups.enabler.services.ConfigConstants.REGISTER_LOADEDRESOURCES);
            if (registeredLoadedResources) {
                if (dojo.isString(registeredLoadedResources)) {
                    try {
                        registeredLoadedResources = dojo.fromJson(registeredLoadedResources);
                    }
                    catch (e) {
                        //invalid configuration
                    }
                }
                if (dojo.isArray(registeredLoadedResources)) {
                    this.registeredLoadedResources = registeredLoadedResources;
                }
            }
        }
    },
    executeCallbackQueue: function(widgetId) {
        if (this.callbackQueue[widgetId]) {
            var cbElems = this.callbackQueue[widgetId];
            var widget = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().find(widgetId);
            if (widget) {
                for (var i = 0; i < cbElems.length; i++) {
                    if (cbElems[i]) {
                        var scope = widget._getHandlerScope(cbElems[i].cb);
                        if (scope) {
                            var cb = dojo.hitch(scope, cbElems[i].cb);
                            cb(cbElems[i].id, cbElems[i].src, cbElems[i].status);
                            cbElems[i] = null;
                        }
                    }
                }
            }
        }

    },
    loadResource: function(resourceElem, widgetId, cb2) {
        var internalId = resourceElem.getGlobalId(); //could be globalid or path
        var uri = resourceElem.getSrc();
        var path = null;
        if (resourceElem.isJS()) {
            path = this._rewriteUrl(uri, widgetId, true);
        }
        else {
            path = this._rewriteUrl(uri, widgetId, false);
        }
        if (!internalId) {
            internalId = path;
        }
        if (!internalId) {
            return; //if there's no id and no path, invalid request
        }

        //add each resource to eval queue so it will be evaluated based on order
        this.evalqueue[widgetId] = this.evalqueue[widgetId] ? this.evalqueue[widgetId] : [];
        this.evalqueue[widgetId].push({
            _id: internalId, // used to check if resource is loaded
            resourceElem: resourceElem,
            cb2: cb2,
            widgetId: widgetId,
            isReady: false
        });

        //check skipLoad if available
        var skipLoad = resourceElem[iwConstants.RESOURCE.skipLoad];

        if (skipLoad) {
            var rc = false;
            try {
                // we cannot use the internal eval function here as the IE eval does not return a value. We have to have it here though
                rc = dojo.eval(skipLoad); // JSLINT-IGNORE: Its ok here
            }
            catch (e) {
                rc = false;
            }
            if (rc) {
                this._handleLoadedResource(internalId, widgetId, null, status.OTHER);
                return;
            }
        }
        //check if it's already loaded
        var registeredLoadedResources = this.registeredLoadedResources;
        if (dojo.isArray(registeredLoadedResources)) {
            for (var j = 0; j < registeredLoadedResources.length; j++) {
                if (registeredLoadedResources[j].globalid && registeredLoadedResources[j].globalid == internalId) {
                    if (registeredLoadedResources[j].version) {
                        var version = resourceElem[iwConstants.RESOURCE.version];
                        //don't load if specific version is not required or specific version matches the loaded version
                        if (!version || (version && version == registeredLoadedResources[j].version)) {
                            this._handleLoadedResource(internalId, widgetId, null, status.OTHER);
                            return;
                        }
                    }
                    else {
                        this._handleLoadedResource(internalId, widgetId, null, status.OTHER);
                        return;
                    }
                }
            }
        }

        var resourceData = this.modules[internalId]; //two widgets may have same globalid but different path
        var me = this;
        if (resourceData && resourceData !== null) {
            var type = resourceData.type;
            switch (type) {
                case 0: //loading
                    this.waitingqueue[resourceData._id] = (this.waitingqueue[resourceData._id]) ? this.waitingqueue[resourceData._id] : [];
                    this.waitingqueue[resourceData._id].push({
                        resourceElem: resourceElem,
                        widgetId: widgetId,
                        cb2: cb2
                    });
                    return;                //break; // not needed after return
                case 1: //error
                    this._handleLoadedResource(internalId, widgetId, null, resourceData.status, resourceData.data);
                    return;                //break; // not needed after return
                case 2: //loaded
                    this._handleLoadedResource(internalId, widgetId, null, resourceData.status);
                    return;                //break; // not needed after return
            }
        }

        resourceData = {};
        resourceData.type = this.LOADING_TOKEN;
        resourceData._id = internalId;
        resourceData._path = path;
        this.modules[internalId] = resourceData;
        if (internalId != path) {
            this.modules[path] = this.modules[internalId];
        }
        var retVal = null;
        if (resourceElem.isCSS()) {
            retVal = this._loadCSS(path);
            this.modules[internalId].type = this.LOADED_TOKEN;
            this.modules[internalId].status = iwConstants.status.OTHER;
            this._handleLoadedResource(internalId, widgetId, null, iwConstants.status.OTHER);
            return;
        }
        if (resourceElem.isImage()) {
            retVal = this._loadImage(path);
            this.modules[internalId].type = this.LOADED_TOKEN;
            this.modules[internalId].status = iwConstants.status.OTHER;
            this._handleLoadedResource(internalId, widgetId, null, iwConstants.status.OTHER);
            return;
        }

        var jsPath = path;
        if (dojo.isIE == 6 && path.indexOf("/") === 0) { //ie6 doesn't like "/mum/proxy", it will throw obj error.
            var schema = window.location.protocol;
            var host = window.location.hostname;
            var port = window.location.port;
            jsPath = schema + "//" + host + ":" + port + path;
        }

        var mpHandler1 = com.ibm.mashups.enabler.io.XHRMultipartFactory.create();
        var isSync = !mpHandler1.isTransaction();
        // Required to make dojotest run synchronously
        if (ibmConfig.dojotest) {
            isSync = true;
        }
        var args = {
            url: jsPath,
            sync: isSync,
            load: function(data, ioArgs) {
                //status is 0 if it's a local file system resource
                var contents = null;
                if (ioArgs.xhr.status == 200 || ioArgs.xhr.status === 0) {
                    var oldContents = ioArgs.xhr.responseText;
                    contents = oldContents.replace(/_IWID_/g, "_" + widgetId + "_");
                }

                me.modules[internalId].type = me.LOADED_TOKEN;
                me.modules[internalId].status = iwConstants.status.SUCCESS;
                me._handleLoadedResource(internalId, widgetId, contents, iwConstants.status.SUCCESS);

                var queue = me.waitingqueue[internalId];
                if (queue) {
                    for (var j = 0; j < queue.length; j++) {
                        var req = queue[j];
                        me._handleLoadedResource(internalId, req.widgetId, null, iwConstants.status.SUCCESS);
                    }
                }
                me.waitingqueue[internalId] = null;
            },
            error: function(data, ioArgs) {

                me.modules[internalId].type = me.LOADING_ERROR_TOKEN;
                me.modules[internalId].data = data;
                me.modules[internalId].status = ioArgs.xhr.status;
                me._handleLoadedResource(internalId, widgetId, null, ioArgs.xhr.status, data);

                var queue = me.waitingqueue[internalId];
                if (queue) {
                    for (var h = 0; h < queue.length; h++) {
                        var req = queue[h];
                        me._handleLoadedResource(internalId, req.widgetId, null, ioArgs.xhr.status, data);
                    }
                }
                me.waitingqueue[internalId] = null;
            }
        };

        dojo.xhrGet(args);
    },

    _rewriteUrl: function(uri, id, isXhr) {
        var widget = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().find(id);
        return widget._rewriteURI(uri, isXhr);
    },
    _getExtension: function(uri) {
        return uri.substring(uri.lastIndexOf(".") + 1, uri.length);
    },
    _loadCSS: function(path) {
        var link = document.createElement("link");
        link.setAttribute("rel", "stylesheet");
        link.setAttribute("type", "text/css");
        link.setAttribute("href", path);
        document.getElementsByTagName("head")[0].appendChild(link);
    },
    _loadImage: function(path) {
        com.ibm.mm.enabler.utils.Misc.preloadImage(url);
    },
    _evalCallback: function(cb, widgetId, resourceElem, status) {
        //now call the callback for this resource

        if (cb) {
            //need to resolve as other event function
            if (dojo.isString(cb)) {
                var widget = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().find(widgetId);
                if (widget) {
                    var scope = widget._getHandlerScope(cb);
                    if (scope) {
                        cb = dojo.hitch(scope, cb);
                    }
                }
            }
            var id = resourceElem.getGlobalId();
            var src = resourceElem.getSrc();
            if (!status) {
                status = iwConstants.status.SUCCESS;
            }
            if (dojo.isFunction(cb)) {
                dojo.partial(cb)(id, src, status);

            }
            else {
                this.callbackQueue[widgetId] = this.callbackQueue[widgetId] ? this.callbackQueue[widgetId] : [];
                var cbElem = {
                    cb: cb,
                    id: id,
                    src: src,
                    status: status
                };
                this.callbackQueue[widgetId].push(cbElem);
            }
        }
    },
    _evalFn: function(contents) {
        if (window.execScript) { // JSLINT-IGNORE: We have to use eval here
            window.execScript(contents, "JavaScript"); // JSLINT-IGNORE: We have to use eval here
        }
        else {
           dojo.eval(contents); // JSLINT-IGNORE: Its ok here
        }
    },
    _loadedFC: function(resourceElem, widgetId, cb2, data, status) {
        var cb = resourceElem[iwConstants.RESOURCE.callback];
        if (cb) {
            this._evalCallback(cb, widgetId, resourceElem, status);
        }
        if (cb2) {
            // suspend the transaction in order to avoid feeds/other sensitive data
            // from being part of the MP transaction
            var mpHandler = com.ibm.mashups.enabler.io.XHRMultipartFactory.create();
            mpHandler.suspendTransaction();
            if (data && status) {
                cb2(data, status);
            }
            else {
                cb2();
            }
            mpHandler.resumeTransaction();
        }
    },
    _handleLoadedResource: function(internalId, widgetId, contents, status, statusData) {
        var anEntry;
        var queue = this.evalqueue[widgetId];
        if (queue) {
            if (queue[0] && queue[0]._id && queue[0]._id == internalId) {
                if (contents) {
                    this._evalFn(contents);
                }
                //invoke callback
                anEntry = queue.shift();//remove that resource from that queue
                this._loadedFC(anEntry.resourceElem, widgetId, anEntry.cb2, statusData, status);
                //if will never be here if this is the last resource in the widget loading list
                var arr = queue;
                var continueExec = true;
                while (continueExec && queue.length > 0) {
                    if (queue[0].isReady) {
                        var theContents = queue[0].contents;
                        if (contents) {
                            this._evalFn(contents);
                        }
                        this._loadedFC(queue[0].resourceElem, widgetId, queue[0].cb2, queue[0].statusData, queue[0].status);
                        queue.shift();
                    }
                    else {
                        continueExec = false;
                    }
                }
            }
            else if (queue[0] && queue[0]._id && queue[0]._id != internalId) {
                for (var i = 0; i < queue.length; i++) {
                    anEntry = queue[i];
                    if (anEntry._id && anEntry._id == internalId) {
                        queue[i].contents = contents;
                        queue[i].isReady = true;
                        queue[i].status = status;
                        queue[i].statusData = statusData;
                    }
                }
            }
        }
    }
});

com.ibm.mashups.services.ServiceManager.setService("resourceLoadService", new com.ibm.mm.iwidget.services.ResourceLoadServiceImpl());

}

if(!dojo._hasResource["com.ibm.mm.iwidget.parser.WidgetParser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.parser.WidgetParser"] = true;
dojo.provide("com.ibm.mm.iwidget.parser.WidgetParser");

dojo.declare("com.ibm.mm.iwidget.parser.WidgetParser", null, {
    parseWidgetDefinition: function() {
        return null;
    }
});

}

if(!dojo._hasResource["com.ibm.mm.enabler.xslt"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.xslt"] = true;
dojo.provide("com.ibm.mm.enabler.xslt");





//---------------------------------------------------------------------- xml related utility methods
/*
 * loadXml(sUrl) - returns oDomDoc. parses xml from the url into DOM document object.
 * loadXmlString() - returns oDomDoc. parses xml from the contents of the string into DOM document object.
 * loadXsl()
 * transform()
 */
com.ibm.mm.enabler.xslt.ie = {};
com.ibm.mm.enabler.xslt.gecko = {};

com.ibm.mm.enabler.xslt.getXmlHttpRequest = function() {
    var oXml = null;
    if (typeof window.ActiveXObject != "undefined" || dojo.isIE == 11 || dojo.isIE == 10) {
        oXml = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else {
        oXml = new XMLHttpRequest();
    }
    return oXml;
};

com.ibm.mm.enabler.xslt.loadXml = function(sUrl) {
    if (typeof window.ActiveXObject != "undefined" || dojo.isIE == 11 || dojo.isIE == 10) {
        return com.ibm.mm.enabler.xslt.ie.loadXml(sUrl);
    }
    else {
        return com.ibm.mm.enabler.xslt.gecko.loadXml(sUrl);
    }
};

com.ibm.mm.enabler.xslt.loadXmlString = function(sXml) {
    if (typeof window.ActiveXObject != "undefined" || dojo.isIE == 11 || dojo.isIE == 10) {
        return com.ibm.mm.enabler.xslt.ie.loadXmlString(sXml);
    }
    else {
        var parser = new DOMParser();
        return com.ibm.mm.enabler.xslt.gecko.loadXmlString(sXml);
    }
};

com.ibm.mm.enabler.xslt.loadXsl = function(sUrl) {
    if (typeof window.ActiveXObject != "undefined" || dojo.isIE == 11 || dojo.isIE == 10) {
        return com.ibm.mm.enabler.xslt.ie.loadXsl(sUrl);
    }
    else {
        return com.ibm.mm.enabler.xslt.gecko.loadXsl(sUrl);
    }
};

com.ibm.mm.enabler.xslt.transform = function(xml, xsl, sXslMode, aXslParams, bReturnString) {
    if (typeof window.ActiveXObject != "undefined" || dojo.isIE == 11 || dojo.isIE == 10) {
        return com.ibm.mm.enabler.xslt.ie.transform(xml, xsl, sXslMode, aXslParams, bReturnString);
    }
    else {
        return com.ibm.mm.enabler.xslt.gecko.transform(xml, xsl, sXslMode, aXslParams, bReturnString);
    }
};

com.ibm.mm.enabler.xslt.transformAndUpdate = function(/*HTMLElement*/nodeToUpdate, /*XMLDocument*/ xml, /*XMLDocument*/ xsl, /*String?*/ sXslMode, /*Map*/ aXslParams) {
    var results;
    if (typeof window.ActiveXObject != "undefined" || dojo.isIE == 11 || dojo.isIE == 10) {
        results = com.ibm.mm.enabler.xslt.ie.transform(xml, xsl, sXslMode, aXslParams, true);
        //Don't really want to use innerHTML here, but seems to be the only way IE will
        //take the update.
        nodeToUpdate.innerHTML += results;
    }
    else {
        results = com.ibm.mm.enabler.xslt.gecko.transform(xml, xsl, sXslMode, aXslParams, false);
        var toAppend = results.documentElement;

        if (results.documentElement.tagName == "transformiix:result") {
            toAppend = results.documentElement.childNodes;
            com.ibm.mm.enabler.utils.Dom.copyChildren(results.documentElement, nodeToUpdate, true);
        }
        else {
            nodeToUpdate.appendChild(toAppend);
        }
    }
};

//---------------------------------------------------------------------- IE xml related utility methods

com.ibm.mm.enabler.xslt.ie.loadXml = function(sUrl) {
    var oXmlDoc = new ActiveXObject("MSXML2.DOMDocument");
    oXmlDoc.async = 0;
    oXmlDoc.resolveExternals = 0;
    if (!oXmlDoc.load(sUrl)) {
        //Callers should catch this and can substitute their own error message
        throw new Error("Error loading xml file " + sUrl);
    }
    return oXmlDoc;
};

com.ibm.mm.enabler.xslt.ie.loadXmlString = function(sXml) {
    var oXmlDoc = new ActiveXObject("MSXML2.DOMDocument");
    oXmlDoc.async = 0;
    oXmlDoc.resolveExternals = 0;
    if (!oXmlDoc.loadXML(sXml)) {
        //Callers should catch this and can substitute their own error message
        throw new Error("Error loading xml string " + sXml);
    }
    return oXmlDoc;
};

com.ibm.mm.enabler.xslt.ie.loadXsl = function(sUrl) {
    //we need to use MSXML2.FreeThreadedDOMDocument interface in order to support
    //mode and parameters in XSL transformation.
    var oXslDoc = new ActiveXObject("MSXML2.FreeThreadedDOMDocument");
    oXslDoc.async = 0;
    oXslDoc.resolveExternals = 0;
    if (!oXslDoc.load(sUrl)) {
        //Callers should catch this and can substitute their own error message
        throw new Error("Error loading xsl file " + sUrl);
    }
    return oXslDoc;
};

com.ibm.mm.enabler.xslt.ie.transform = function(xmlDoc, xsl, sXslMode, aXslParams, bReturnString) {
    var oXml = xmlDoc;
    var oXsl = xsl;

    try {
        if (!oXsl.documentElement) {
            oXsl = this.loadXsl(xsl);
        }
    }
    catch (e) {
        var sMsg = e.message;
        throw new Error("" + sMsg, "" + sMsg);
    }
    //create the xsl processor and apply the transformation
    var oXslt = new ActiveXObject("Msxml2.XSLTemplate");
    oXslt.stylesheet = oXsl;
    var oXslProc = oXslt.createProcessor();
    oXslProc.input = oXml;

    //set paramaters if any
    if (aXslParams) {
        com.ibm.mm.enabler.utils.Misc.forIn(aXslParams, function(value,key,obj) {
            this.addParameter(key,value);
        },oXslProc);
    }
    if (sXslMode) {
        oXslProc.addParameter("mode", sXslMode);
    }

    if (bReturnString) {
        if (!oXslProc.transform()) {
            //Callers should catch this and can substitute their own error message
            throw new Error("Error transforming xml doc " + oXml);
        }
        return oXslProc.output;
    }
    else {
        var oHtmlDoc = new ActiveXObject("MSXML2.DOMDocument");
        oHtmlDoc.async = 0;
        oHtmlDoc.validateOnParse = 1;
        oXml.transformNodeToObject(oXsl, oHtmlDoc);
        return oHtmlDoc;
    }
};

//---------------------------------------------------------------------- GECKO xml related utility methods

com.ibm.mm.enabler.xslt.gecko.loadXml = function(sUrl) {
    //var oXmlResponse = NG.ServerRequest.postRequest(sUrl);
    //    if (oXmlResponse) return xmlLoadString(oXmlResponse.responseText);
    //    else return null;
};

com.ibm.mm.enabler.xslt.gecko.loadXmlString = function(sXml) {
    var parser = new DOMParser();
    var oXmlDoc;
    try {
        oXmlDoc = parser.parseFromString(sXml, "text/xml");
    }
    catch (exc) {
        //Callers should catch this and can substitute their own error message
        throw new Error("Error loading xml string " + sXml);
    }
    return oXmlDoc;
};

com.ibm.mm.enabler.xslt.gecko.loadXsl = function(sUrl) {
    //This is done through createDocument because of anchor(#) we have in portal url.
    //Do not change the code without testing the case.
    var oDomDoc = document.implementation.createDocument('', '', null);
    oDomDoc.async = 0; // this is the important part
    oDomDoc.load(sUrl);

    return oDomDoc;
};

com.ibm.mm.enabler.xslt.gecko.transform = function(xmlDoc, xsl, sXslMode, aXslParams, bReturnString) {
    try {
        var xslDoc = xsl;
        if (!xslDoc.documentElement) {
            xslDoc = this.loadXsl(xsl);
        }
        var proc = new XSLTProcessor();
        proc.importStylesheet(xslDoc);

        //set parameters if any
        if (aXslParams) {
            com.ibm.mm.enabler.utils.Misc.forIn(aXslParams, function(value,key,obj) {
                this.setParameter(null, key,value);
            },proc);
        }
        if (sXslMode) {
            proc.setParameter(null, "mode", sXslMode);
        }

        var resultDoc = proc.transformToDocument(xmlDoc);
        if (!bReturnString) {
            return resultDoc;
        }
        resultStr = resultDoc.documentElement.childNodes[0].textContent;
    }
    catch (exc) {
        //Callers should catch this and can substitute their own error message
        throw new Error("Error transforming xml doc " + exc);
    }
    return resultStr;
};

/* This method sets the content of a layer within the HTML page
 * to the result of transforming the xml parameter by the xsl
 * parameter. The xml and xsl parameters may be of any form
 * supported by the transformXml() method. The layer parameter
 * may be either a DOM object or the name of a DOM object that
 * can be found using the findObject() method.
 */
com.ibm.mm.enabler.xslt.setLayerContentByXml = function(layer, xml, xsl, xslparam, bReturnString) {
    var result = com.ibm.mm.enabler.xslt.transform(xml, xsl, null, xslparam, bReturnString);
    if (layer.innerHTML) {
        layer.innerHTML = result;
    }
    else {
        var obj = document.getElementById(layer);
        obj.innerHTML = result;
    }
};


}

if(!dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetDefinitionLegacyImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetDefinitionLegacyImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.widget.IWidgetDefinitionLegacyImpl");





dojo.declare("com.ibm.mm.iwidget.widget.IWidgetDefinitionLegacyImpl", com.ibm.mashups.iwidget.widget.IWidgetDefinition, {
    //unfortunately sametime iwidget is still not spec 1.0 compliant
    constructor: function( /*object*/name, /*String*/ markup,/*String*/ iScope,/*object[]*/ itemSetsArr,/*object*/ widgetEvents,/*String*/ uri,/*[]*/ supportedModes,/*[]*/ publishedEvents,/*[]*/ handledEvents,/*[]*/ resources,/*[]*/ payloadDefs, iDescriptor) {
        var arg1 = name;
        //todo:fix me
        if (dojo.isString(arg1)) {
            this.name = name;
            this.markup = markup;
            this.iScope = iScope;
            this.itemSetsArr = itemSetsArr;
            this.uri = uri;
            this.widgetEvents = widgetEvents;
            this.publishedEvents = publishedEvents;
            this.handledEvents = handledEvents;
            this.supportedModes = supportedModes;
            this.resources = resources;
            this.payloadDefs = payloadDefs;
            this.iDescriptor = iDescriptor;
        }
        else {
            this.name = arg1.name;
            this.markup = arg1.markup;

            this.metaData = arg1.metaData;
            this.events = arg1.events;
            this.itemSets = arg1.itemSets;
            this.resources = arg1.resources;
            this.payloadDefs = arg1.payloadDefs;
            this.iScope = this.metaData.iScope;
            this.supportedModes = this.metaData.supportedModes;
            this.uri = this.metaData.contentURI;

            var anEvent;
            this.widgetEvents = {};
            for (anEvent in this.metaData) {
                if (anEvent.indexOf("on") === 0) {
                    this.widgetEvents[anEvent] = this.metaData[anEvent];
                }
            }
            var publishedEventsData = arg1.events.publishedEvents;
            this.publishedEvents = {};
            this.handledEvents = {};
            var anEventName;
            var iEventDescription;
            for (anEventName in publishedEventsData) {
                if (Object.prototype.hasOwnProperty.call(publishedEventsData,anEventName)) {
                    anEvent = publishedEventsData[anEventName];
                    iEventDescription = new com.ibm.mm.iwidget.IEventDescriptionImpl(anEvent.eventName, anEvent.payloadType, anEvent.description, anEvent.onEvent);
                    if (!this.publishedEvents[anEventName]) {
                        this.publishedEvents[anEventName] = [];
                    }
                    this.publishedEvents[anEventName].push(iEventDescription);
                }
            }

            var handledEventsData = arg1.events.handledEvents;
            for (anEventName in handledEventsData) {
                if (Object.prototype.hasOwnProperty.call(handledEventsData,anEventName)) {
                    anEvent = handledEventsData[anEventName];
                    iEventDescription = new com.ibm.mm.iwidget.IEventDescriptionImpl(anEvent.eventName, anEvent.payloadType, anEvent.description, anEvent.onEvent);
                    if (!this.handledEvents[anEventName]) {
                        this.handledEvents[anEventName] = [];
                    }
                    this.handledEvents[anEventName].push(iEventDescription);
                }
            }

            var anItemSetName;
            this.itemSetsArr = {};
            for (anItemSetName in arg1.itemSets) {
                if (Object.prototype.hasOwnProperty.call(arg1.itemSets,anItemSetName)) {
                    var anItemSetData = arg1.itemSets[anItemSetName];
                    var anItemSet;
                    if (anItemSetName == "attributes") {
                        anItemSet = new com.ibm.mm.iwidget.itemset.ItemSetDefaultImpl(anItemSetData.name, anItemSetData.onItemSetChanged);
                    }
                    else {
                        anItemSet = new com.ibm.mm.iwidget.itemset.ItemSetDefaultImpl(anItemSetData.name, anItemSetData.onItemSetChanged);
                    }
                    //set data to the internal data field("items") in ItemSet
                    anItemSet.itemLists.items = anItemSetData.itemLists;
                    this.itemSetsArr[anItemSetName] = anItemSet;
                }
            }
        }
    },
    _getPublishedEvents: function() {
        return this.publishedEvents; // an associative array
    },
    _getHandledEvents: function() {
        return this.handledEvents;
    },
    getPublishedEvents: function() {
        //return a real array
        var arr = [];
        for (var i in this.publishedEvents) {
            if (Object.prototype.hasOwnProperty.call(this.publishedEvents,i)) {
                arr.push(this.publishedEvents[i]);
            }
        }
        return arr;
    },
    getHandledEvents: function() {
        //return a real array
        var arr = [];
        for (var i in this.handledEvents) {
            if (Object.prototype.hasOwnProperty.call(this.handledEvents,i)) {
                arr.push(this.handledEvents[i]);
            }
        }
        return arr;
    },
    getAttributes: function() { // need to implement SPI
        //var itemSetWrapper = {name:name,onItemSetChanged:onItemSetChanged,isPrivate:isPrivate};
        //      itemSetWrapper.items = [];
        //var anItem = {id:id,value:value,readOnly:isReadOnly};
        var attributes = this.itemSetsArr.attributes;
        if (!attributes) {
            attributes = {
                name: "attributes",
                items: {}
            };
        }

        if (typeof(this.uri) != "undefined" && attributes) {
            attributes.items.contentURI = {
                id: "contentURI",
                value: this.uri,
                readOnly: false
            };
        }
        if (typeof(this.supportedModes) != "undefined" && attributes) {
            attributes.items.supportedModes = {
                id: "supportedModes",
                value: this.uri,
                readOnly: false
            };
        }
        return attributes;
    },
    getAllItemSetNames: function() {
        var names = [];
        if (!this.itemSetsArr) {
            return names;
        }
        var i = 0;
        for (var itemName in this.itemSetsArr) {
            if (Object.prototype.hasOwnProperty.call(this.itemSetsArr,itemName)) {
                var itemSetWrapper = this.itemSetsArr[itemName];
                if (typeof(itemSetWrapper) != "undefined") {
                    names[i] = itemSetWrapper.name;
                }
                i++;
            }
        }
        return names;
    },
    getItemSet: function(/*String*/name) {
        if (name == "attributes") {
            return this.getAttributes();
        }
        var itemSetWrapper = this.itemSetsArr[name];
        if (typeof(itemSetWrapper) != "undefined") {
            return itemSetWrapper;
        }
        return null;
    },
    getPublishedEventsNames: function() {
        if (!this.publishedEvents) {
            return null;
        }
        var eventNames = [];
        var aEventName;
        for (aEventName in this.publishedEvents) {
            if (Object.prototype.hasOwnProperty.call(this.publishedEvents,aEventName)) {
                eventNames.push(aEventName);
            }
        }
        return eventNames;
    },
    getHandledEventsNames: function() {
        if (!this.handledEvents) {
            return null;
        }
        var eventNames = [];
        var aEventName;
        for (aEventName in this.handledEvents) {
            if (Object.prototype.hasOwnProperty.call(this.handledEvents,aEventName)) {
                eventNames.push(aEventName);
            }
        }
        return eventNames;
    },
    getPublishedEvent: function(/*String*/eventName) {
        if (!this.publishedEvents) {
            return null;
        }
        //return an instance of iEventDescription
        return this.publishedEvents[eventName];
    },
    getHandledEvent: function(/*String*/eventName) {
        if (!this.handledEvents) {
            return null;
        }
        //return an instance of iEventDescription
        return this.handledEvents[eventName];
    },
    getWidgetName: function() {
        return this.name;
    },
    getPayloadDefs: function() {
        return this.payloadDefs;
    },
    getPayloadDef: function(name) {
        var payloadDef = this.payloadDefs[name];
        if (typeof payloadDef == "undefined") {
            return null;
        }
        return payloadDef;
    },
    getPayloadDefNames: function() {
        var arr = [];
        var a;
        for (a in this.payloadDefs) {
            if (Object.prototype.hasOwnProperty.call(this.payloadDefs,a)) {
                arr.push(a);
            }
        }
        return arr;
    },
    getSupportedModes: function() {
        var temp = this.supportedModes;
        if (!temp) {
            return null;
        }
        var arr = temp.split(" ");
        return arr;
    },
    getIDescriptorItems: function() {
        return null;
    },
    getMarkupByMode: function(mode) {
        return this.markup;
    },
    getWidgetEvents: function() {
        return this.widgetEvents;
    },
    getIScope: function() {
        return this.iScope;
    },
    getResources: function() {
        return this.resources;
    },
    getDefaultLanguage: function() {
        return "en";
    },
    getMarkup: function() {
        return this.markup;
    },
    getAllowInstanceContent: function() {
        return false;
    },
    _getShareableItemSets: function() {
        return null;
    },
    _getManagedItemSetListener: function(itemsetname) {
        return null;
    },
    getXmlBase: function() {
        return null;
    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.parser.LegacyXMLParser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.parser.LegacyXMLParser"] = true;
dojo.provide("com.ibm.mm.iwidget.parser.LegacyXMLParser");









dojo.declare("com.ibm.mm.iwidget.parser.LegacyXMLParser", com.ibm.mm.iwidget.parser.WidgetParser, {
    constructor: function(responseText) {
        this.xmlStr = responseText;
    },
    namespaces: {
        "iw": "http://www.ibm.com/iWidget"
    },
    parseWidgetDefinition: function() {
        var xmlData = com.ibm.mm.enabler.xslt.loadXmlString(this.xmlStr);
        var markup = this.readMarkup(xmlData);
        var itemSetsArr = this.readItemSets(xmlData);
        var uri = this.readContentURI(xmlData);
        var widgetEvents = this.readWidgetEvents(xmlData);
        var name = this.readName(xmlData);
        var iScope = this.readiScope(xmlData);
        var supportedModes = this.readSupportedModes(xmlData);
        var handledEvents = this.readPublicEvents(xmlData, "iw:handledEvents");
        var publishedEvents = this.readPublicEvents(xmlData, "iw:publishedEvents");
        var resources = this.readResources(xmlData);
        var payloadDefs = this.readPayloadDefs(xmlData);
        var iDescriptor = this.readIDescriptor(xmlData);
        return new com.ibm.mm.iwidget.widget.IWidgetDefinitionLegacyImpl(name, markup, iScope, itemSetsArr, widgetEvents, uri, supportedModes, publishedEvents, handledEvents, resources, payloadDefs, iDescriptor);
    },
    readMarkup: function( /*XMLDocument*/xmlData) {
        var contentsXPath = "/iw:iwidget/iw:content";
        //we support html fragment only in iw:content
        var rootNode = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(contentsXPath, xmlData, this.namespaces);
        var defaultContent = "";
        if (rootNode) {
            var child = rootNode.childNodes;

            for (var j = 0, l = child.length; j < l; j++) {
                var aNode = child[j];

                //if this is CDATAsection
                if (aNode.nodeType == 4) {
                    defaultContent = defaultContent.concat(aNode.nodeValue);
                }
                else if (aNode.nodeType == 3) {//textNode
                    defaultContent = defaultContent.concat(aNode.nodeValue);
                }
            }
        }
        // exit trace
        return defaultContent;
    },
    readSupportedModes: function(/*XMLDocument*/xmlData) {
        // read the iwidget's "supportedModes" attribute and store
        // the string (no further parding here)
        var root = xmlData.documentElement;
        var modes = root.getAttribute("supportedModes");
        // return null if not found
        if (typeof modes == "undefined" || modes === null) {
            return null;
        }
        return modes;
    },
    readItemSets: function( /*XMLDocument*/xmlData) {
        var itemSetsArr = {};
        var contentsXPath = "/iw:iwidget/iw:itemSet";
        var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(contentsXPath, xmlData, this.namespaces);
        for (var i = 0, l = nodes.length; i < l; i++) {
            var aNode = nodes[i];
            var id = aNode.getAttribute("name");
            var onItemSetChanged = aNode.getAttribute("onItemSetChanged");

            var itemSetWrapper = {
                id: id,
                onItemSetChanged: onItemSetChanged
            };
            itemSetWrapper.items = {};
            var child = aNode.childNodes;
            for (var j = 0, l2 = child.length; j < l2; j++) {
                var aItemNode = child[j];
                if (aItemNode.nodeType == 1) {
                    var isReadOnly = aItemNode.getAttribute("readOnly");
                    var anItem = {
                        id: aItemNode.getAttribute("name"),
                        value: aItemNode.getAttribute("value"),
                        readOnly: isReadOnly
                    };
                    itemSetWrapper.items[anItem.id] = anItem;
                }
            }
            itemSetsArr[id] = itemSetWrapper;
        }
        // exit trace
        return itemSetsArr;
    },
    readPayloadDefs: function( /*XMLDocument*/xmlData) {
        var payloadDefsArr = {};
        var contentsXPath = "/iw:iwidget/iw:payloadDef";
        var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(contentsXPath, xmlData, this.namespaces);
        for (var i = 0, l = nodes.length; i < l; i++) {
            var aNode = nodes[i];
            var payloadDef = com.ibm.mm.iwidget.Utils.getPayloadDef(aNode);
            payloadDefsArr[payloadDef.name] = payloadDef;
        }
        // exit trace
        return payloadDefsArr;
    },
    readName: function(/*XMLDocument*/xmlData) {
        var root = xmlData.documentElement;
        var name = root.getAttribute("name");
        if (typeof name == "undefined" || name === null) {
            return null;
        }
        return name;
    },
    //this attribute is a convenience for an extremely common iwidget attribute, if specifies a URI which the iwidget will use to fetch data or markup which it will present to the user
    readContentURI: function(/*XMLDocument*/xmlData) {
        var root = xmlData.documentElement;
        var uri = root.getAttribute("contentURI");
        if (typeof uri == "undefined" || uri === null) {
            return null;
        }
        return uri;
    },
    readiScope: function(/*XMLDocument*/xmlData) {
        var root = xmlData.documentElement;
        var iScope = root.getAttribute("iScope");
        if (typeof iScope == "undefined" || iScope === null) {
            return null;
        }
        return iScope;
    },
    readWidgetEvents: function(/*XMLDocument*/xmlData) {
        //read all teh onSth event
        var root = xmlData.documentElement;
        var widgetEvents = {};
        var attributes = root.attributes;
        for (var i = 0; i < attributes.length; i++) {
            var event = attributes[i];

            if (event.name.indexOf("on") === 0) {
                var handler = event.value;
                if (typeof handler != "undefined" && handler !== null) {
                    widgetEvents[event.name] = handler;
                }
            }
        }
        return widgetEvents;
    },
    readPublicEvents: function(/*XMLDocument*/xmlData,/*String*/ eventType) {
        //returns iEventDescriptionImpl(name,onEvent,payloadType,description)
        var contentsXPath = "/iw:iwidget/" + eventType;
        var node = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(contentsXPath, xmlData, this.namespaces);
        var events = {};
        if (node) {
        	dojo.forEach(node.childNodes, function(eventNode) {
                if (eventNode.nodeType == 1) {
                    //todo. handle aliases
                    var iEventDescription = new com.ibm.mm.iwidget.IEventDescriptionImpl(eventNode.getAttribute("eventName"), eventNode.getAttribute("onEvent"), eventNode.getAttribute("payloadType"), eventNode.getAttribute("description"));
                    events[eventNode.getAttribute("eventName")] = iEventDescription;
                }
            },this);
        }
        if (!events) {
            return null;
        }
        return events;
    },
    readResources: function(/*XMLDocument*/xmlData) {
        var resourcePath = "/iw:iwidget/iw:resource";
        var resources = [];
        var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(resourcePath, xmlData, this.namespaces);
        if (nodes && nodes.length > 0) {
            dojo.forEach(nodes,function(node) {
                var resource = {};
                resource.name = node.getAttribute("resourceName");
                resource.src = node.getAttribute("uri");
                resource.version = node.getAttribute("version");
                resource.callback = node.getAttribute("callback");
                resource.mimetype = node.getAttribute("mimetype");
                resources[i] = resource;
            },this);
        }
        return resources;
    },
    readIDescriptor: function(/*XMLDocument*/xmlData) {
        //don't support this in legacy
        return null;
    }

});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.parser.StandardXMLParser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.parser.StandardXMLParser"] = true;
dojo.provide("com.ibm.mm.iwidget.parser.StandardXMLParser");











dojo.declare("com.ibm.mm.iwidget.parser.StandardXMLParser", com.ibm.mm.iwidget.parser.WidgetParser, {
    constructor: function(responseText) {
        this.xmlStr = responseText;
    },
    namespaces: {
        "iw": "http://www.ibm.com/xmlns/prod/iWidget"
    },
    reservedAttributes: {
        iScope: "iScope",
        supportedModes: "supportedModes",
        id: "id",
        allowInstanceContent: "allowInstanceContent",
        lang: "lang",
        "xmlns:iw": "xmlns:iw",
        supportedWindowStates: "supportedWindowStates",
        "xml:lang": "xml:lang",
        "xml:base":"xml:base"
    },
    parseWidgetDefinition: function() {
        var xmlData = com.ibm.mm.enabler.xslt.loadXmlString(this.xmlStr);
        var widgetDef = this.readRootElement(xmlData);
        widgetDef.markup = this.readMarkup(xmlData);
        widgetDef.itemSetsArr = this.readItemSets(xmlData, widgetDef); // it also sets the  .shareableItemSetsArr
        //widgetDef.handledEvents = this.readPublicEvents(xmlData,"handled");
        //widgetDef.publishedEvents = this.readPublicEvents(xmlData,"published");
        widgetDef.publicEvents = this.readPublicEvents(xmlData);
        widgetDef.resources = this.readResources(xmlData);
		var payloadDefs = this.readPayloadDefs(xmlData);
        if (payloadDefs) {
			widgetDef.payloadDefs = payloadDefs;
		}
        widgetDef.eventDescriptions = this.readEventDescriptions(xmlData);
        widgetDef.xmlStr = this.xmlStr;
        return new com.ibm.mm.iwidget.widget.IWidgetDefinitionImpl(widgetDef, this.xmlStr);
    },
    readRootElement: function( /*XMLDocument*/xmlData) {
        var widgetDef = {};
        var root = xmlData.documentElement;
        var modes = root.getAttribute("supportedModes");
        // return null if not found
        if (!modes) {
            modes = "view";
        }
        widgetDef.supportedModes = modes;

        var value;
        var name = root.getAttribute("id");
        if (!name) {
            name = null;
        }
        widgetDef.id = name;
        widgetDef.name = name;

        var temp = root.getAttribute("allowInstanceContent");
        var allowInstanceContent = false;
        if (temp && temp == "true") {
            allowInstanceContent = true;
        }
        widgetDef.allowInstanceContent = allowInstanceContent;

        var lang = root.getAttribute("lang");
        if (!lang) {
            lang = root.getAttribute("xml:lang");
        }
        if (!lang) {
            lang = "en";
        }
        widgetDef.lang = lang;

        var widgetEvents = {};
        var attributes = root.attributes;
        var i;
        for (i = 0; i < attributes.length; i++) {
            var event = attributes[i];
            if (event.name.indexOf("on") === 0) {
                var handler = event.value;
                if (handler) {
                    widgetEvents[event.name] = handler;
                }
            }
        }
        widgetDef.widgetEvents = widgetEvents;

        var iScope = root.getAttribute("iScope");
        if (!iScope) {
            iScope = null;
        }
        widgetDef.iScope = iScope;

        var iDescriptorItems = iwConstants.iDescriptorItems;
        var iDescriptor = {};
        for (var j in iDescriptorItems) {
            if (Object.prototype.hasOwnProperty.call(iDescriptorItems,j)) {
                name = iDescriptorItems[j];
                value = root.getAttribute(name);
                iDescriptor[name] = value;
            }
        }
        widgetDef.iDescriptor = iDescriptor;

        var simpleAttributes = {};
        attributes = root.attributes;
        for (i = 0; i < attributes.length; i++) {
            var att = attributes[i];
            if (att.name.indexOf("on") !== 0 && !iwConstants.iDescriptorItems[att.name] && !this.reservedAttributes[att.name]) {
                value = att.value;
                if (typeof value != "undefined" && value !== null) {
                    simpleAttributes[att.name] = value;
                }
            }
        }
        widgetDef.simpleAttributes = simpleAttributes;

        var windowStates = root.getAttribute("supportedWindowStates");
        // return null if not found
        if (!windowStates) {
            windowStates = "normal";
        }
        widgetDef.supportedWindowStates = windowStates;

        var xmlBase = root.getAttribute("xml:base");
        if (xmlBase) {
            widgetDef.xmlBase = xmlBase;
        }
        return widgetDef;
    },
    readMarkup: function( /*XMLDocument*/xmlData) {
        var contentsXPath = "/iw:iwidget/iw:content";
        //we support html fragment only in iw:content
        var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(contentsXPath, xmlData, this.namespaces);
        var contents = {};
        var defaultContent = "";
        var mode = null;
        if (nodes && nodes.length > 0) {
            for (var i = 0, l = nodes.length; i < l; i++) {
                var rootNode = nodes[i];
                var child = rootNode.childNodes;

                for (var j = 0, l2 = child.length; j < l2; j++) {
                    var aNode = child[j];

                    //if this is CDATAsection
                    if (aNode.nodeType == 4) {
                        defaultContent = defaultContent.concat(aNode.nodeValue);
                    }
                    else if (aNode.nodeType == 3) {//textNode
                        defaultContent = defaultContent.concat(aNode.nodeValue);
                    }
                }
                mode = rootNode.getAttribute("mode");
                if (!mode) {
                    mode = "view"; //assign default mode
                    break;
                }
                uri = rootNode.getAttribute("uri");
                contents[mode] = {};
                if (uri) {
                    contents[mode].uri = uri;
                }
                contents[mode].content = defaultContent;
                defaultContent = "";
            }
        }
        // exit trace
        return contents;
    },
    /**
     * Return json object, each itemset
     * {
     * 	id:{id},
     * 	items:{}, --> for each item: {id:{id},name:{name},readOnly:{readOnly},value:{value},defaultLocale:{defaultLocale},values:{}}
     * 	onItemSetChanged:{handler}
     * }
     */
    readItemSets: function( /*XMLDocument*/xmlData, widgetDef) {
        var shareableItemSetsArr = {};
        var itemSetsArr = {};
        var contentsXPath = "/iw:iwidget/iw:itemSet";
        var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(contentsXPath, xmlData, this.namespaces);
        for (var i = 0, l = nodes.length; i < l; i++) {
            var aNode = nodes[i];
            var itemSetId = aNode.getAttribute("id");
            //alias if optiontal
            var alias = aNode.getAttribute("alias")?aNode.getAttribute("alias"):null;
			if (!alias){
				alias = aNode.getAttribute("globalid") ? aNode.getAttribute("globalid") : null;
			}
            var onItemSetChanged = aNode.getAttribute("onItemSetChanged");
            var temp = aNode.getAttribute("private");
            var isPrivate = true;
            if (temp && temp == "false") {
                isPrivate = false;
            }

            var descriptionRef = aNode.getAttribute("description");

            var itemSetWrapper = {
                id: itemSetId,
                onItemSetChanged: onItemSetChanged,
                isPrivate: isPrivate
            };
            if (alias) {
                itemSetWrapper.alias = alias;
            }
            itemSetWrapper.items = {};

            var itemNodes = aNode.childNodes; // WARNING: this assumes that an itemset only contains items !
            for (var j = 0, jL = itemNodes.length; j < jL; j++) {
                var aItemNode = itemNodes[j];
                if (aItemNode.nodeType == 1) {
                    var readOnly = false;
                    var readOnlyAtt = aItemNode.getAttribute("readOnly");
                    if (readOnlyAtt && readOnlyAtt == "true") {
                        readOnly = true;
                    }

                    var id = aItemNode.getAttribute("id");
					var alias1 = aItemNode.getAttribute("alias")?aItemNode.getAttribute("alias"):null;
					if (!alias1){
						alias1 = aItemNode.getAttribute("globalid") ? aItemNode.getAttribute("globalid") : null;
					}

                    var value = aItemNode.getAttribute("value");
                    var lang = aItemNode.getAttribute("lang");
                    if (!lang) {
                        lang = aItemNode.getAttribute("xml:lang");
                    }

                    var anItem = {};
                    anItem.id = id;
                    if (alias1) {
                    	anItem.alias = alias1;
                    }
                    anItem.readOnly = readOnly;

                    if (!lang && (typeof value != "undefined" && value !== null)) { // "" is also allowed
                        anItem.value = value; //a value without locale
                    }
                    if (lang) {
                        anItem.defaultLocale = lang;
                    }
					if (lang && (typeof value != "undefined" && value !== null)){
						anItem.values = {};
						anItem.values[lang] = value;
					}

                    //value with locale
                    var valueNodes = aItemNode.childNodes;
                    if (valueNodes.length > 0 || (lang && value)) {

                        for (var v = 0, vL = valueNodes.length; v < vL; v++) {
                            var valueNode = valueNodes[v];
                            if (valueNode.nodeType == 1) {
                                var locale = valueNode.getAttribute("lang");
                                if (!locale) {
                                    locale = valueNode.getAttribute("xml:lang");
                                }
                                if (!locale) {
                                    locale = "en";
                                }
                                var localeValue = valueNode.getAttribute("value");
								anItem.values = anItem.values?anItem.values:{};
                                anItem.values[locale] = localeValue;
                            }
                        }
                    }
                    itemSetWrapper.items[id] = anItem;
                }
            }

            if (isPrivate) {
                itemSetsArr[itemSetId] = itemSetWrapper;
            }
            else {
                shareableItemSetsArr[itemSetId] = itemSetWrapper;
            }
        }
        widgetDef.shareableItemSetsArr = shareableItemSetsArr;
        // exit trace
        return itemSetsArr;
    },
    readPayloadDefs: function( /*XMLDocument*/xmlData) {
        var payloadDefsArr = {};
        var contentsXPath = "/iw:iwidget/iw:payloadDef";
        var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(contentsXPath, xmlData, this.namespaces);
        for (var i = 0, l = nodes.length; i < l; i++) {
            var aNode = nodes[i];
            var payloadDef = com.ibm.mm.iwidget.Utils.getPayloadDef(aNode);
            payloadDefsArr[payloadDef.name] = payloadDef;
        }
		if (com.ibm.mm.enabler.utils.Misc.isEmpty(payloadDefsArr) === true) {
			payloadDefsArr = null;
		}
        // exit trace
        return payloadDefsArr;
    },
    readPublicEvents: function(/*XMLDocument*/xmlData,/*String*/ eventType) {
        //return empty object if no events is defined
        //var contentsXPath = "/iw:iwidget/iw:event[@"+eventType+"]";
        var events = {};
        var contentsXPath = "/iw:iwidget/iw:event";
        var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(contentsXPath, xmlData, this.namespaces);
        if (nodes && nodes.length !== 0) {
            for (var j = 0, l = nodes.length; j < l; j++) {
                var eventNode = nodes[j];
                if (eventNode.nodeType == 1) {
                    //todo. handler attributes
                    var iEvent = {};
                    var attributes = eventNode.attributes;
                    for (var i = 0; i < attributes.length; i++) {
                        var att = attributes[i];
                        var name = att.name;
                        var value = att.value;
                        if (name == "eventDescName") {
                            name = "description"; //backward compatibility
                        }
                        if (name == "handled") {
                            name = "isHandled"; //align with js representation
                        }
                        if (name == "published") {
                            name = "isPublished"; //align with js representation
                        }
                        if (value) {
                            iEvent[name] = value;
                        }
                    }
                    events[iEvent.id] = iEvent;
                }
            }
        }
        return events;
    },
    readResources: function(/*XMLDocument*/xmlData) {
        var resourcePath = "/iw:iwidget/iw:resource";
        var resources = [];
        var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(resourcePath, xmlData, this.namespaces);
        if (nodes && nodes.length !== 0) {
            for (var i = 0, l = nodes.length; i < l; i++) {
                var node = nodes[i];
                var resource = {};

                var id = node.getAttribute("id");
                if (!id) {
                    id = node.getAttribute("globalid");
                }
                resource[iwConstants.RESOURCE.id] = id;
                resource[iwConstants.RESOURCE.globalid] = node.getAttribute("globalid")?node.getAttribute("globalid"):null;
                var src = node.getAttribute("src");
                if (!src) {
                    src = node.getAttribute("uri");
                    //todo warning
                }

                resource[iwConstants.RESOURCE.src] = src;
                resource[iwConstants.RESOURCE.version] = node.getAttribute("version");
                resource[iwConstants.RESOURCE.blockInit] = node.getAttribute("blockInit");
                resource[iwConstants.RESOURCE.callback] = node.getAttribute("callback");
                resource[iwConstants.RESOURCE.mimeType] = node.getAttribute("mimeType");
                resource[iwConstants.RESOURCE.skipLoad] = node.getAttribute("skipLoad");

                if (!resource[iwConstants.RESOURCE.skipLoad]) {
                    var childNodes = node.childNodes;
                    var aNode = null;
                    for (var j = 0; j < childNodes.length; j++) {
                        aNode = childNodes[j];
                        if (aNode.nodeType == 1) {//skipLoad section //CDATA section
                            break;
                        }
                    }
                    if (aNode) {
                        childNodes = aNode.childNodes;
                        for (var h = 0; h < childNodes.length; h++) {
                            if (childNodes[h].nodeType == 4) {//skipLoad section //CDATA section
                                resource[iwConstants.RESOURCE.skipLoad] = childNodes[h].nodeValue;
                            }
                        }
                    }
                }
                resources[i] = resource;
            }
        }
        return resources;
    },
    readEventDescriptions: function(/*XMLDocument*/xmlData) {
        var eventDescriptionpath = "iw:iwidget/iw:eventDescription";
        var eventDescriptions = {};
        var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath(eventDescriptionpath, xmlData, this.namespaces);
        if (nodes && nodes.length !== 0) {
            for (var i = 0, l = nodes.length; i < l; i++) {
                var node = nodes[i];
                var eventDescription = {};
                var id = node.getAttribute("id");
                eventDescription.id = id;
                eventDescription.payloadType = node.getAttribute("payloadType");
                eventDescription.description = node.getAttribute("description");
                eventDescription.title = node.getAttribute("title");
                eventDescription.descriptionURI = node.getAttribute("descriptionURI");
                var lang = node.getAttribute("lang");
                if (!lang) {
                    lang = node.getAttribute("xml:lang");
                }
                eventDescription.lang = lang;
                eventDescription.aliases = node.getAttribute("aliases");
                eventDescription.descriptions = {};
                var children = node.childNodes;
                for (var j = 0, jL = children.length; j < jL; j++) {
                    var aNode = children[j];
                    if (aNode.nodeType == 1) {
                        var temp = {};
                        var lang2 = aNode.getAttribute("lang");
                        if (!lang2) {
                            lang2 = aNode.getAttribute("xml:lang");
                        }
                        temp.description = aNode.getAttribute("description");
                        temp.title = aNode.getAttribute("title");
                        temp.descriptionURI = aNode.getAttribute("descriptionURI");
                        eventDescription.descriptions[lang2] = temp;
                    }
                }
                eventDescriptions[id] = eventDescription;
            }
        }
        return eventDescriptions;
    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.parser.OpenSocialXMLParser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.parser.OpenSocialXMLParser"] = true;
dojo.provide("com.ibm.mm.iwidget.parser.OpenSocialXMLParser");










dojo.declare("com.ibm.mm.iwidget.parser.OpenSocialXMLParser", com.ibm.mm.iwidget.parser.WidgetParser, {
    constructor: function(responseText) {
        this.xmlStr = responseText;
    },
    namespaces: {},
    reservedAttributes: {
        iScope: "iScope",
        supportedModes: "supportedModes",
        id: "id",
        allowInstanceContent: "allowInstanceContent",
        lang: "lang",
        "xmlns:iw": "xmlns:iw",
        supportedWindowStates: "supportedWindowStates",
        "xml:lang": "xml:lang",
        "xml:base": "xml:base"
    },
    parseWidgetDefinition: function() {
        var xmlData = com.ibm.mm.enabler.xslt.loadXmlString(this.xmlStr);
        var widgetDef = this.readRootElement(xmlData);
        this.readAllChildNodes(xmlData, widgetDef); // sets shareableItemSetsArr and itemSetsArr
        widgetDef.publicEvents = this.readPublicEvents(xmlData);
        widgetDef.resources = this.readResources(xmlData);
        var payloadDefs = this.readPayloadDefs(xmlData);
        if (payloadDefs) {
            widgetDef.payloadDefs = payloadDefs;
        }
        widgetDef.eventDescriptions = this.readEventDescriptions(xmlData);
        widgetDef.xmlStr = this.xmlStr;
        return new com.ibm.mm.iwidget.widget.IWidgetDefinitionImpl(widgetDef, this.xmlStr);
    },
    readRootElement: function( /*XMLDocument*/xmlData) {
        var widgetDef = {};
        var root = xmlData.documentElement;

        // TBD in gadgets, read mode as part of the Content tag
        var modes = "view";
        widgetDef.supportedModes = modes;

        var value;
        var name = null;

        widgetDef.id = name; // TBD widget id needs to be set up with something else?
        widgetDef.name = name; // // TBD widget name needs to be set up with something else?
        var temp = null;
        var allowInstanceContent = false; // TBD is this the right value for gadgets?
        widgetDef.allowInstanceContent = allowInstanceContent;

        var lang = "en"; // TBD how to determine the default language for the gadget?  read Locale nodes?
        widgetDef.lang = lang;

		widgetDef.getType = dojo.hitch(widgetDef, function () { return com.ibm.mm.iwidget.Constants.OSGADGET_DEFINITION_TYPE; });

        var widgetEvents = {};
        widgetDef.widgetEvents = widgetEvents; // OS gadgets 1.0 do not have any "on" Events in its spec
        var iScope = null;
        widgetDef.iScope = iScope;

        var iDescriptor = {};
        widgetDef.iDescriptor = iDescriptor;

        var simpleAttributes = {};
        widgetDef.simpleAttributes = simpleAttributes;

        var windowStates = "normal";
        widgetDef.supportedWindowStates = windowStates;

        return widgetDef;
    },
    readAllChildNodes: function( /*XMLDocument*/xmlData, widgetDef) {
        var root = xmlData.documentElement;

        if (root.children) {
            var childrenNodes = root.children;

            for (var j = 0; j < childrenNodes.length; j++) {

                if (childrenNodes[j].nodeName) {

                    if (childrenNodes[j].nodeName === "ModulePrefs") {
                        this.readModulePrefs(childrenNodes[j], widgetDef);


                    }
                    else if (childrenNodes[j].nodeName === "UserPref") {

                    }
                    else if (childrenNodes[j].nodeName === "Content") {
                        widgetDef.markup = this.readContent(childrenNodes[j]);
                    }
                }
            }
        }
    },
    readContent: function( /*XMLDocument*/documentElement) {
        var contents = {};
        var nodes = documentElement.childNodes;
        var defaultContent = "";
        var mode = "view";
        for (var j = 0; j < nodes.length; j++) {
            var aNode = nodes[j];

            //if this is CDATAsection
            if (aNode.nodeType == 4) {
                defaultContent = defaultContent.concat(aNode.nodeValue);
            }
            else if (aNode.nodeType == 3) {//textNode
                defaultContent = defaultContent.concat(aNode.nodeValue);
            }
        }
        contents[mode] = {};
        contents[mode].content = defaultContent;
        return contents;
    },
    readMarkup: function( /*XMLDocument*/xmlData) {
        return {};
    },
    readItemSets: function( /*XMLDocument*/xmlData, widgetDef) {
        return {};
    },
    readModulePrefs: function( /*XMLDocument*/documentElement, widgetDef) {

        // iterate through attributes to get title and then parse it with Locale info
        var iDescriptor = {};
        iDescriptor.mode = "view";
        iDescriptor.name = ""; // TBD how to get the gadget name or id here?
        widgetDef.iDescriptor = iDescriptor;
        var itemSetsArr = {};
        var shareableItemSetsArr = {};

        var itemSetId = "idescriptor";

        if (documentElement.attributes && documentElement.attributes !== null) {
            var modAttributes = documentElement.attributes;

            for (var j = 0; j < modAttributes.length; j++) {

                if (modAttributes[j]) {

                    var isPrivate = true;

                    if (modAttributes[j].name && modAttributes[j].name === "title") { // parses only title item
                        var title = modAttributes[j].name;
                        var isTitleTranslatable = false;

                        var itemSetWrapper = {
                            id: itemSetId,
                            onItemSetChanged: null,
                            isPrivate: isPrivate
                        };
                        itemSetWrapper.items = {};


                        var readOnly = false;
                        var id = modAttributes[j].name;
                        var alias1 = null;
                        var value = modAttributes[j].value;
                        var lang = "en"; // TBD get default language from the browser
                        var anItem = {};
                        anItem.id = id;
                        if (alias1) {
                            anItem.alias = alias1;
                        }
                        anItem.readOnly = readOnly;

                        if (title.indexOf("__MSG_") >= 0) {
                            isTitleTranslatable = true;
                            anItem.defaultLocale = lang;
                            //	anItem.values = {};
                            //	anItem.values[lang] = value;

                        }
                        else {
                            anItem.value = value; //a value without locale
                        }


                        itemSetWrapper.items[id] = anItem;

                        if (isPrivate) {
                            itemSetsArr[itemSetId] = itemSetWrapper;
                        }
                        else {
                            shareableItemSetsArr[itemSetId] = itemSetWrapper;
                        }
                    }
                }
            }
        }

        // TBD - iterate through children nodes
        // TBD - ignore Require elements for the moment(in opensocial 1.1 parse events metadata)
        // TBD - parse Locale nodes and add to Items values (parse title)
        widgetDef.shareableItemSetsArr = shareableItemSetsArr;
        widgetDef.itemSetsArr = itemSetsArr;
    },

    readPayloadDefs: function( /*XMLDocument*/xmlData) {
        return {};
    },
    readPublicEvents: function(/*XMLDocument*/xmlData,/*String*/ eventType) {
        return {};
    },
    readResources: function(/*XMLDocument*/xmlData) {
        return [];
    },
    readEventDescriptions: function(/*XMLDocument*/xmlData) {
        return {};
    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.parser.WidgetParserFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.parser.WidgetParserFactory"] = true;
dojo.provide("com.ibm.mm.iwidget.parser.WidgetParserFactory");






dojo.declare("com.ibm.mm.iwidget.parser.WidgetParserFactory",null,  {
     getWidgetParser: function(responseText){
         var xmlStr = responseText.replace(/^\s+/, "").replace(/\s+$/, "");
         var isXML = this._isXML(xmlStr);
         var isLegacy = this._isLegacy(xmlStr);
		 var isOpenSocialGadget = this._isOpenSocialGadget(xmlStr);

         if ( isXML && isLegacy && !isOpenSocialGadget) {
             return  new com.ibm.mm.iwidget.parser.LegacyXMLParser(xmlStr);
         } else if ( isXML && !isLegacy && !isOpenSocialGadget) {
             return new com.ibm.mm.iwidget.parser.StandardXMLParser(xmlStr);
         } else if ( isXML && isOpenSocialGadget) {
             return new com.ibm.mm.iwidget.parser.OpenSocialXMLParser(xmlStr);
         }
		 return null;

     },
     _isOpenSocialGadget: function(responseText) {
          var isGadget = true;
          var index = responseText.indexOf("<Module>");
          if (index === -1) {
               isGadget = false;
          }
          return isGadget;
	 },
	 _isXML: function(responseText){
          var isXML = true;
          var index = responseText.indexOf("=\"http://www.w3.org/1999/xhtml\"");
          if (index != -1) {
               isXML = false;
          }
          return isXML;
     },
     _isLegacy: function(responseText){
          var isLegacy = true;
          var index = responseText.indexOf("=\"http://www.ibm.com/xmlns/prod/iWidget\"");
         if (index != -1) {
              isLegacy = false;
         }
         return isLegacy;
     }
});

com.ibm.mm.iwidget.parser.WidgetParserFactory = new com.ibm.mm.iwidget.parser.WidgetParserFactory();

}

if(!dojo._hasResource["com.ibm.mm.iwidget.services.WidgetLoadServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.services.WidgetLoadServiceImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.services.WidgetLoadServiceImpl");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget
 * TODO: Why not for sandbox ?
 */
dojo.provide("com.ibm.mm.iwidget.services.WidgetLoadServiceImpl");

// inject this service into the ServiceManager at the end. Therefore we have to require the implementation





dojo.declare("com.ibm.mm.iwidget.services.WidgetLoadServiceImpl", null, {
    constructor: function() {
        //loadModelus to keep track that if a resource has been loaded already
        this.widgetDef = {}; //cached as url-widgetdefinition
        this.LOADING_TOKEN = "LOADING_TOKEN";
        this.LOADING_ERROR_TOKEN = "LOADING_ERROR_TOKEN";
        this.waitingqueue = {};
    },
    getWidgetXML: function( /*String*/widgetUrl,/*boolean*/ sync, callbackfn,/*String*/ widgetId) {
        // summary: Retrieves the WidgetInfo for the given widget url.
        // widgetUrl: a widget URL, should come directly from the microformat or from alias

        // Required to make dojotest run synchronously
        if (ibmConfig.dojotest) {
            sync = true;
        }

        var wInfo = this.widgetDef[widgetUrl];
        if (wInfo && wInfo == this.LOADING_TOKEN) {
            if (!this.waitingqueue[widgetUrl]) {
                this.waitingqueue[widgetUrl] = [];
            }
            var entry = {
                id: widgetId,
                cb: callbackfn
            };
            this.waitingqueue[widgetUrl].push(entry);
            return;
        }
        else if (wInfo && wInfo.error && wInfo.error == this.LOADING_ERROR_TOKEN) {
            return this.handleCallback(callbackfn, wInfo.data, wInfo.status);
        }
        else if (wInfo) {
            return this.handleCallback(callbackfn, wInfo, "200");
        }

        this.widgetDef[widgetUrl] = this.LOADING_TOKEN;
        var me = this;
        var contentUrl = widgetUrl;
        if ((contentUrl.indexOf("http") === 0) || (contentUrl.indexOf("https") === 0)  || (contentUrl.indexOf("endpoint") === 0)) {
            contentUrl = com.ibm.mm.enabler.utils.URLHelper.rewriteURL(contentUrl);
        }
        var args = {
            url: contentUrl,
            load: function(data, ioArgs) {
                var xhr = ioArgs.xhr;
                var parser = com.ibm.mm.iwidget.parser.WidgetParserFactory.getWidgetParser(xhr.responseText);
                var wInfo = parser.parseWidgetDefinition();
                me.widgetDef[widgetUrl] = wInfo;

                me.handleCallback(callbackfn, wInfo, xhr.status, xhr);
                //check waiting queue
                var queue = me.waitingqueue[widgetUrl];
                if (queue) {
                    for (var i in queue) {
                        if (Object.prototype.hasOwnProperty.call(queue,i)) {
                            me.handleCallback(queue[i].cb, wInfo, xhr.status, xhr);
                        }
                    }
                    me.waitingqueue[widgetUrl] = null;
                }
            },
            error: function(data, ioArgs) {
                var xhr = ioArgs.xhr;
                me.widgetDef[widgetUrl] = {
                    error: me.LOADING_ERROR_TOKEN,
                    data: data,
                    status: xhr.status
                };
                me.handleCallback(callbackfn, data, xhr.status, xhr);
                var queue = me.waitingqueue[widgetUrl];
                if (queue) {
                    for (var i in queue) {
                        if (Object.prototype.hasOwnProperty.call(queue,i)) {
                            me.handleCallback(queue[i].cb, data, xhr.status, xhr);
                        }
                    }
                    me.waitingqueue[widgetUrl] = null;
                }
            },
            handleAs: "text", //tells framework this is an text document
            sync: sync //default is false, set to true if it's a blocking synchronous request
        };
        dojo.xhrGet(args);
        return;
    },

    handleCallback: function(callbackfn, data, statuscode, xhr) {
        if (callbackfn) {
            callbackfn(data, statuscode, xhr);
        }
    }
});


com.ibm.mashups.services.ServiceManager.setService("widgetLoadService", new com.ibm.mm.iwidget.services.WidgetLoadServiceImpl());

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.Wire_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.widget.Wire_API"] = true;
dojo.provide("com.ibm.mashups.iwidget.widget.Wire_API");
dojo.provide("com.ibm.mashups.iwidget.widget.Wire");

/**
 * Wire interface defines functions that expose information of a Wire
 * @ibm-spi
 * @ibm-module iWidget
 */
dojo.declare("com.ibm.mashups.iwidget.widget.Wire", null, {
    /**
     * @private
     */
    constructor: function() {

    },
    /**
     This method returns id of the source iWidget that's  connected to.
     @type String
     @returns{String }  id of the source iWidget
     */
    getSourceWidgetID: function() {

    },
    /**
     This method returns name of the event in the source iWidget.
     @type String
     @returns{String }  name of the source event
     */
    getSourceEventName: function() {
        //summary: This method returns an object that contains instance level attribute items
    },
    /**
     This method returns id of the source iWidget that's  connected to.
     @type String
     @returns{String }  id of the source iWidget
     */
    getTargetWidgetID: function() {

    },
    /**
     This method returns name of the event in the source iWidget
     @type String
     @returns{String }  name of the source event
     */
    getTargetEventName: function() {
        //summary: This method returns an object that contains instance level attribute items
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.Wire"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.widget.Wire"] = true;
dojo.provide("com.ibm.mashups.iwidget.widget.Wire");




}

if(!dojo._hasResource["com.ibm.mm.iwidget.widget.WireImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.widget.WireImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.widget.WireImpl");



dojo.declare("com.ibm.mm.iwidget.widget.WireImpl",com.ibm.mashups.iwidget.widget.Wire,{

		constructor:function(widgetid,/*JSON object*/obj){
			//"SourceWidget","SourceEvent","TargetEvent"
			if(obj){
			this.SourceWidget = obj.SourceWidget;
			this.SourceEvent = obj.SourceEvent;
			this.TargetEvent = obj.TargetEvent;
			}
			this.TargetWidget = widgetid;
			this._isDirty = false;
			this._type = null;
		},
		TYPE_NEW:"NEW",
		TYPE_DELETE:"DELETE",
		getID:function() {
			return this.SourceWidget +"_"+ this.SourceEvent +"_"+ this.TargetWidget+"_"+this.TargetEvent;
		},
		getSourceWidgetID:function(){
			return this.SourceWidget;
		},
		getSourceEventName:function(){
			return this.SourceEvent;
		},
		getTargetWidgetID:function(){
			return this.TargetWidget;
		},
		getTargetEventName:function(){
			return this.TargetEvent;
		},
		setDirty:function(isDirty){
			this._isDirty = isDirty;
		},
		isDirty:function(){
			return this._isDirty;
		},
		setType:function(type){
			this._type = type;
		},
		getType:function(){
			return this._type;
		},
		setSubHandler:function(subHandle){
			this._subHandle = subHandle;
		},
		getSubHandler:function(){
			return this._subHandle;
		},
        toString: function(){
            return this.getID();
        }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetWrapperStubImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetWrapperStubImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.widget.IWidgetWrapperStubImpl");









dojo.declare("com.ibm.mm.iwidget.widget.IWidgetWrapperStubImpl", null, {
    // available from IWidgetWrapperDefaultImpl:
    // this.rootElement,this.id,this.loaded,this.ns,this.iwMessages
    // RenderController will set this.widgetDef
    PREFIX_STUB: "_stub_",
    getID: function() {
        return this.id; //need to implement all the method defined by IWidgetWrapper otherwise mixin will take the default impl in the interface!
    },
    getIWidgetInstance: function() {
        if (this.widgetInstance) {
            return this.widgetInstance;
        }
        this.widgetInstance = new com.ibm.mm.iwidget.widget.IWidgetInstanceImpl(this, this.rootElement, this.id);
        return this.widgetInstance;
    },
    setIWidgetDefinition: function(widgetDef) {
        this.widgetDef = widgetDef;
    },
    getIWidgetDefinition: function() {
        if (this.loaded) {
            return new com.ibm.mm.iwidget.DeferredLoadImpl(this.getIWidgetInstance().widgetXMLUrl, this.id, this.widgetDef);
        }
        else {
            return new com.ibm.mm.iwidget.DeferredLoadImpl(this.getIWidgetInstance().widgetXMLUrl, this.id);
        }
    },
    getMarkup: function() {
        //return new com.ibm.mm.iwidget.DeferredLiveTextUnprocessImpl(this);
        //to do need to fix this...
        return new com.ibm.mm.iwidget.DeferredLiveTextUnprocessStubImpl(this);
    },
    _getInstanceMarkupFromDOM: function() {
        return this.getIWidgetInstance()._getInstanceMarkup();
    },
    _deepFind: function(widgetModel, layoutModel, container, id) {
        ret = null;
        var children = layoutModel.getChildren(container);
        while(children.hasNext()) {
            var child = children.next();
            if (layoutModel.hasChildren(child)) {
                ret = this._deepFind(widgetModel, layoutModel, child, id);
            }
            else if (child.getLayoutNodeType() == com.ibm.mashups.enabler.layout.Constants.LAYOUT_CONTROL) {
                var window = widgetModel.getWidgetWindow(child).start();
                if (window && window.getID() == id) {
                    return child;
                }
            }
        }
        return ret;
    },
    _getInstanceMarkup: function(callback) {
        var isAlienID = com.ibm.mashups.enabler.services.IdentificationService.isAlienID(this.id);

        // if the id is neither client side, nor backend
        if (isAlienID) {
            // now we assume that we can use the DOM to render the widget
            callback(this._getInstanceMarkupFromDOM());
            return;
        }

       var isClientID = com.ibm.mashups.enabler.services.IdentificationService.isClientID(this.id);

        // at this point we know that we are a widget in the page canvas area and can rely on using models to retrieve the content
        var widgetModel = com.ibm.mashups.enabler.widget.Factory.getWidgetModel();
        var navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
        var spaceAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getSpaceAccessor(navStateModel);
        var currentSpaceID = spaceAccessor.getSpaceID();
        var pageAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getPageAccessor(navStateModel, currentSpaceID);
        var currentPageID = pageAccessor.getPageID();
        var navModel = com.ibm.mashups.enabler.navigation.Factory.getNavigationModel();
        var navNode = navModel.find(currentPageID).start();
        var layoutModel = navModel.getLayoutModel(navNode);
        var control = null;
        //var wnd = widgetModel.findWidgetWindow(this.id, currentPageID).start();
        // we are doing a performance optimization here for normal rendering
        if (isClientID) {
            // if it is a client id then we need to walk the whole model
            control = this._deepFind(widgetModel, layoutModel, layoutModel.getRoot().start(), this.id);
        }
        else {
            // else we can assume that the window id is the same as the layout id and a find is sufficient
            control = layoutModel.find(this.id).start();
        }
        if (control) {
            var dfr = control.getWidgetBody();
            dfr.setFinishedCallback(callback);
            dfr.start(false);
        }
    },
    doRender: function() {
        try {
			//update the title
			this._updateTitle();

            // initialize wires so that the callback handlers are registered
            this.getWires();

            this.subHandler = {};
            this.eventSvr = com.ibm.mashups.services.ServiceManager.getService("eventService");
            //subscribe general event channel for the wrapper stub, this channel could be used to accept events distributed to stub
            //should be used for stub -- impl communication
            //widgetevents._stub_myrealid
            //console.info("subscribe #2",this.eventSvr.WIDGETEVENT_PREFIX + this.PREFIX_STUB + this.id, this, "handleEvent");
            var subHandler2 = this.eventSvr.subscribeEvent(this.eventSvr.WIDGETEVENT_PREFIX + this.PREFIX_STUB + this.id, this, "handleEvent"); //subscribe eventHandler for _stub_realwidgetid
            this.subHandler[this.PREFIX_STUB + this.id] = [];
            this.subHandler[this.PREFIX_STUB + this.id].push(subHandler2);

            this._getInstanceMarkup(dojo.hitch(this,"doRenderContinue"));
        }
        catch (e) {
        }
    },
    doRenderContinue: function(instancedata) {
		if (instancedata === null || instancedata === undefined) {
			return;
		}
        //get default mode
        var aMode = this._getDefaultMode();
        if (!aMode) {
            aMode = iwConstants.mode_view;
        }
        this.currentMode = aMode;
        if (this._handleSaveMode) {
            this._handleSaveMode();
        }
        //get root to render iframe
        var tempDiv = document.createElement("div");
        tempDiv.className = this.ns + "Content";
        this.rootElement.appendChild(tempDiv);
        var contentDiv = this.rootElement.lastChild;
        dojo.addClass(contentDiv, this.currentMode);
        contentDiv.visibility = "hidden";

        //use instance id to create iframe for default view
        this.windowManager[this.currentMode] = {
            id: this.id,
            root: contentDiv,
            active: true,
            main: true
        };
        var navigationStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
        var widgetAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getWidgetAccessor(navigationStateModel, this.id);
        var customParams = null;
        if (widgetAccessor) {
            customParams = widgetAccessor.getWidgetState("cp");
        }
        this._createIframe(instancedata, contentDiv, this.id, "false", this, customParams);
    },
    destroy: function() {
        //return subdomain
        this.eventSvr._getHubAdapter(this.id).returnSubDomain(this._getSubDomain());

        var wireModel = this.getIWidgetInstance().getWireModel();
		//remove any wires coming into this widget (any wires that this widget is a target of)
		if (wireModel) {
			var myWires = wireModel.getWires();
			while (myWires.length > 0) {
				var wireSourceID = myWires[0].getSourceWidgetID();
                wireModel.removeWire(wireSourceID);
                this.commit();
				myWires = wireModel.getWires();
			}
		}
		//remove any wires going out of this widget (any wires that this widget is a source of)
        var targets = null;
        if (wireModel) {
            targets = wireModel.getTargets();
        }
        if (targets) {
			var widgetModel = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel();
            for (var i in targets) {
                if (Object.prototype.hasOwnProperty.call(targets,i)) {
                    var widget = widgetModel.find(i);
                    if (widget) {
                        var wires = widget.getIWidgetInstance().getWireModel();
                        wires.removeWire(this.id); // remove all the wires that contains "this.id" as source
                        widget.commit();
                    }
                }
            }
        }
        //this.eventSvr.unsubscribeEvent(this.eventServiceHandler);
        for (var i2 in this.subHandler) {
            if (Object.prototype.hasOwnProperty.call(this.subHandler,i2)) {
                for (var j in this.subHandler[i2]) {
                    if (Object.prototype.hasOwnProperty.call(this.subHandler[i2],j)) {
                        this.eventSvr.unsubscribeEvent(this.subHandler[i2][j]);
                    }
                }
            }
        }

        //this will remove hubclient and container and destroy all the subscription on the client--remove the window for default view
        this.eventSvr._getHubAdapter(this.id).removeIframeHubContainer(this.id);


        if (this.windowManager) {
            this.windowManager = null;
        }

    },
    update2: function(span) {
        return;
    },
    _getParent: function() {
        if (!this.parent) {
            this.parent = com.ibm.mm.iwidget.Utils.getWidgetParent(this.rootElement);
        }
        this.parent = this.parent || null;
        return this.parent;
    },
    _setParent: function(parent) {
        this.parent = parent;
    },
    _getPublishedEvents: function() {
        //Todo:should remove once widgetstub is removed,backward compatibility as part of queryservice
        //return an associative array, with reference
        var publishedEvents = this.getWidgetPublishedEvents();
        var arr = {};
        if (dojo.isArray(publishedEvents)) {
            for (var i = 0, l = publishedEvents.length; i < l; i++) {
                arr[publishedEvents[i].name] = publishedEvents[i];
            }
        }
        return arr;
    },
    _getHandledEvents: function() {
        //Todo: should remove once widgetStub is removed,backward compatibility as part of queryservice
        var handledEvents = this.getWidgetHandledEvents();
        var arr = {};
        if (dojo.isArray(handledEvents)) {
            for (var i = 0, l = handledEvents.length; i < l; i++) {
                arr[handledEvents[i].name] = handledEvents[i];
            }
        }
        return arr;
    },
    getWidgetPublishedEvents: function() {
        //return a reference of event description for backward compatibility so it won't break the use case below
        var eventModel = this._getPublicEvents();
        if (eventModel) {
            var condition = {};
            condition.isPublished = "true";
            return eventModel.getEvents(condition);
        }
        return null;
    },
    getWidgetHandledEvents: function() {
        //return a reference of events array
        var eventModel = this._getPublicEvents();
        if (eventModel) {
            var condition = {};
            condition.isHandled = "true";
            return eventModel.getEvents(condition);
        }
        return null;
    },
    getWires: function() {
        return this.getIWidgetInstance().getWires();
    },
    handleEvent: function(payload) {
        var scope = payload.scope;
        if (scope) {
            if (scope == "instance") {
                scope = this.getIWidgetInstance();
            }
            else if (scope == "eventmodel") {
                scope = this._getPublicEvents();
            }
        }
        else {
            scope = this;
        }
        var methodname = payload.methodname;
        if (methodname && scope[methodname] && dojo.isFunction(scope[methodname])) {
            scope[methodname].apply(scope, payload.params);
        }
    },
    _handleOnModeChange: function(payload) {
        //change the mode to the new mode and create dialog in mode
        var isHandled = false;
        var oldMode = this.currentMode;
        if (!payload) {
            return false;
        }
        if (dojo.isString(payload)) {
            payload = dojo.fromJson(payload);
        }
        if (!payload) {
            return false;
        }

        var newMode = payload.newMode || null;
        var newRoot = payload.rootElementId || null;

        // support one active mode only, thus don't support this operation
        if (newMode !== null && newMode == this.currentMode) {
            return false;
        }
        if (newMode === null) {
            return false;
        }
        var payloadObj = {};

        var currentModeWindow = this.windowManager[this.currentMode];
        if (currentModeWindow && currentModeWindow.main  && newRoot === null) {
            //sendover to iframe and switch mode there, not popular usecase
            payloadObj.methodname = "_handleOnModeChange";//refresh
            //var aEvent = new com.ibm.mm.iwidget.IEventImpl(iwConstants.EVENTS.onModeChanged,null,{newMode:newMode});
            payloadObj.params = [newMode];
            this.eventSvr._publishEvent("widgetevents." + this.id, payloadObj);
	         // an extra widget mode change event is also required so theme updates contextual menu options appropriately (16928)
            var payload2 = {};
            payload2.id = this.id;
            payload2.oldMode = oldMode;
            payload2.newMode = newMode;
            this.eventSvr._publishEvent(com.ibm.mashups.iwidget.Constants.WIDGET_MODECHANGED, payload2, this.hubId);
            return;
        }

        //switch from default mode  to custom mode like edit mode
        if (currentModeWindow && currentModeWindow.main  && newRoot !== null) {
            //create iframe
            this._getInstanceMarkup(dojo.hitch(this, function(instancedata) {
                //add custom mode as iDescriptor
                instancedata = this._getInstanceMarkupForMode(instancedata, newMode);
                //get state data from main frame and create new iframe with id  realwidgetid_newmode
                this._createIframe(instancedata, newRoot, this.id + "_" + newMode, "true", this);
                oldMode = this.currentMode;
                this.currentMode = newMode;
                if (this._handleSaveMode) {
                    this._handleSaveMode();
                }
                this.windowManager[this.currentMode] = {
                    id: this.id + "_" + newMode,
                    root: newRoot,
                    active: true,
                    main: false
                };

                //tell the default mode wrapper the new mode
                payloadObj.methodname = "_handleOnModeUpdated";
                payloadObj.params = [newMode];

                this.eventSvr._publishEvent("widgetevents." + this.id, payloadObj);

                dojo.publish(iwConstants.EVENTS.modeChanged, [this.id, oldMode, newMode]);
                payload = {};
                payload.id = this.id;
                payload.oldMode = oldMode;
                payload.newMode = newMode;
                this.eventSvr._publishEvent(com.ibm.mashups.iwidget.Constants.WIDGET_MODECHANGED, payload, this.hubId);
            }));
            return;
        }

        //switch from custom mode to default mode (like view mode)
        var newModeOldWindow = this.windowManager[newMode];
        if (newModeOldWindow && newModeOldWindow.main ) {
            //call onView

            payloadObj = {};
            payloadObj.methodname = "_handleOnModeChange";//refresh
            //var aEvent = new com.ibm.mm.iwidget.IEventImpl(iwConstants.EVENTS.onModeChanged,null,{newMode:newMode});
            payloadObj.params = [newMode];
            try {
                this.eventSvr._publishEvent("widgetevents." + this.id, payloadObj);
            }
            catch (e1) {
                console.log("catching exception!!!" + e1);
            }

            //remove the hubcontainer for edit mode
            this.eventSvr._getHubAdapter(this.id).removeIframeHubContainer(this.id + "_" + this.currentMode);
            //unsubscribe any event related to edit dialog
            try {
                var x = this.id + "_" + this.currentMode;
                for (var j in this.subHandler[x]) {
                    if (Object.prototype.hasOwnProperty.call(this.subHandler[x],j)) {
                        this.eventSvr.unsubscribeEvent(this.subHandler[x][j]);
                    }
                }
            }
            catch (e2) {
                console.log("IWidgetWrapperStub:_handleOnModeChange unsubscribe exception:" + e2);
            }

            delete this.windowManager[this.currentMode]; //delete any window that's not main window
            oldMode = this.currentMode;
            this.currentMode = newMode;
            if (this._handleSaveMode) {
                this._handleSaveMode();
            }
            //todo, verify how it's used with builder
            dojo.publish(iwConstants.EVENTS.modeChanged, [this.id, oldMode, newMode]);
            payload = {};
            payload.id = this.id;
            payload.oldMode = oldMode;
            payload.newMode = newMode;
            this.eventSvr._publishEvent(com.ibm.mashups.iwidget.Constants.WIDGET_MODECHANGED, payload, this.hubId);

        }
        return;
    },
    commit: function(noSync) {
        //need to commit any change in iframe
        var widgetInstance = this.getIWidgetInstance();
        // need to check attribute properties and idescriptor attributes
        var instanceAttributes = widgetInstance.getAttributes();
        var instanceIDescriptor = widgetInstance.getIDescriptorItems();
        var wiremodel = widgetInstance.getWireModel();
        var params = {};
        if (instanceAttributes && instanceAttributes._isDirty()) {
            params.attributes = instanceAttributes;
        }
        if (instanceIDescriptor && instanceIDescriptor._isDirty()) {
            params.idescriptors = instanceIDescriptor;
        }
        if (wiremodel && wiremodel.isDirty()) {
            params.wiremodel = wiremodel.toJson();
        }
        // send events to widget  main view to handle data Sync ...
        if (!noSync) {
            this.eventSvr._publishEvent(this.eventSvr.WIDGETEVENT_PREFIX + this.id, {
                "methodname": "_handleDataSync",
                "params": [params]
            }, this.id);
        }
        if (instanceAttributes && instanceAttributes._isDirty()) {
            this._writePropertiesToDOM(this, "attributes", instanceAttributes);
            instanceAttributes._setDirty(false);
        }
        if (instanceIDescriptor && instanceIDescriptor._isDirty()) {
            this._writePropertiesToDOM(this, "idescriptor", instanceIDescriptor);
            instanceIDescriptor._setDirty(false);
        }
        //check wires
        if (wiremodel && wiremodel.isDirty()) {
            wiremodel.commit();
        }
    },
    getPublicEvent: function(name) {
        var eventModel = this._getPublicEvents();
        return eventModel.find(name);
    },
    _getInstanceMarkupForMode: function(markup, mode) {
        var newDiv = document.createElement("div");
        newDiv.innerHTML = markup;
        var root = newDiv.firstChild;
        root.id = this.id;
        //root.id = this.id+"_"+mode; //don't change widget id , keep it in sync so less widgets will break,widgets do cache id
        // query the markup for the given itemSetName
        var iDescriptors = dojo.query('span.' + this.ns + 'ItemSet[title="' + iwConstants.IDESCRIPTOR + '"]', root);
        var newItemSet = null;
        if (iDescriptors.length === 0) {
            newItemSet = document.createElement("span");
            newItemSet.className = this.ns + 'ItemSet';
            newItemSet.title = iwConstants.IDESCRIPTOR;
            newItemSet.style.display = "none";
            newItemSet.style.visibility = "hidden";

            // append it to the newDiv
            root.appendChild(newItemSet);
        }
        else {
            newItemSet = iDescriptors[0];
        }

        var items = dojo.query('.' + this.ns + 'Item[href="#' + 'mode' + '"]', newItemSet);
        for (var i = 0, l = items.length; i < l; i++) {
            var item = items[i];
            if (newItemSet == item.parentNode) {
                newItemSet.removeChild(item);
            }
        }
        //create new one
        var newItem = document.createElement("a");
        newItem.className = this.ns + 'Item';
        newItem.style.visibility = "hidden";
        newItem.style.display = "none";
        newItem.href = "#" + "mode";
        newItem.appendChild(document.createTextNode(mode));

        newItemSet.appendChild(newItem);
        //console.log("MarkupWithMode:"+newDiv.innerHTML);
        return newDiv.innerHTML;
    },
    _createIframe: function(instancedata, root, id, isModal, wrapper, stateData) {
        //console.log(instancedata);
        //render iframe here
        var that = wrapper;
        var cssUrl = wrapper.getCSSUrl();
        wrapper.subHandler[id] = [];
        function eventCallback(payload) {
            function eventCallbackContinue(instancedata) {
                var navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
                var obj = {"html": instancedata,
                        "xml": that.widgetDef.widgetDef,//original parsed data
                        "isModal": isModal,
                        "hubId": id,
                        "cssUrl": cssUrl,
                        "navState": navStateModel._state};
                if (stateData) {
                    obj.stateData = stateData;
                }

                if ( !(isModal && isModal == "false")){
                    var mainframeId = id.slice(0,id.lastIndexOf("_"));
                    var mainIframeContainer = that.eventSvr._getHubAdapter().getContainer(mainframeId,true);
                    mainframeId = mainIframeContainer.getIframe().id;
                    obj.mainframeId = mainframeId;
                }
                that.eventSvr._publishEvent(that.eventSvr.WIDGETEVENT_PREFIX + id + "." + "onWidgetLoading",obj );


                var subHandler3 = that.eventSvr.subscribeEvent(com.ibm.mashups.iwidget.Constants.WIDGET_LOADED + "." + id, null, function(payload) { /*onData*/
                    if (isModal == "false") {
                        that.loaded = true;
                        dojo.query("> ." + that.ns + "loading", that.rootElement).forEach(function(elem) {
                            com.ibm.mm.enabler.utils.Dom.destroyNode(elem);
                        });
                        dojo.query("." + that.currentMode, that.rootElement).style({
                            "visibility": "" //display:"none" will make mode selector not displaying properly
                            //set visible will work funny in FF, the node will be visible even parent node is set to be invisible
                        });
                    }
                });
                that.subHandler[id].push(subHandler3);
                var eventHandler = that.eventSvr.subscribeEvent(com.ibm.mashups.iwidget.Constants.RESIZE_WIDGET + "." + that.id, that, "handleSizeChanged");
                that.subHandler[id].push(eventHandler);
            }
            //sometime, iframe will automatically reloaded, in these paricular cases, we need to update instance markup so we don't lose any updates after widget is loaded eg. wires, attributes
            if (wrapper.isLoaded()  && isModal && isModal == "false") {
                wrapper.loaded = false;
                wrapper._getInstanceMarkup(eventCallbackContinue);
            }
            else {
                eventCallbackContinue(instancedata);
            }
        }
        var subHandler1 = wrapper.eventSvr.subscribeEvent(wrapper.eventSvr.WIDGETEVENT_PREFIX + id + "." + "onFrameLoaded", null, eventCallback);
        wrapper.subHandler[id].push(subHandler1);


        var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);

        var url = window.location.protocol;
        var host = window.location.hostname;
        var serverdomain = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.SERVERDOMAIN);
        if (serverdomain && serverdomain != "null") {
            host = serverdomain;
        }
        var port = window.location.port;
        var path = window.location.pathname; // for example "/mum/enabler"
        var startOfRealUrl = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT);//get Mashup context root.. "/mum"
        var junction = null;
        if (path.indexOf(startOfRealUrl) > 0) { //there's junciton point like http://host:8080/jp/mum/enabler
            junction = path.slice(0, path.indexOf(startOfRealUrl)); //it will be "/jp"
        }

        if (wrapper._getSubDomain()) {
            var subdomain = wrapper._getSubDomain() + "." + host;
            // support for tomcat developer mode. Disable subdomains in case the system has no SSO
            if (configService.getValue("sandbox.disable.subdomains")) {
                subdomain = host;
            }
            if (port != "") {
                url += "//" + subdomain + ":" + port;
            }
            else {
                url += "//" + subdomain;
            }
            if (junction) {
                url += junction;
            }
            url += configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.CONTEXT_ROOT_ENABLER);
            url += "/widgetsandbox";
                wrapper.eventSvr._getHubAdapter().createIframeHubContainer(id, root, url,isModal,null,null,dojo.hitch(this,"_onSecurityAlert"));

        }
        else {
            //throw error message
            var subDomainSize = wrapper.eventSvr._getHubAdapter().getSubDomainSize();
            var wTitle = unescape(wrapper.getIWidgetInstance().getIDescriptorItems().getItemValue("title", dojo.locale));
            if (!wTitle) {
                wTitle = wrapper.getID();
            }
            var reuseSubDomain = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.SUBDOMAINREUSE);
            var fmt = wrapper.iwMessages.E_SUBDOMAIN_NOTAVAILABLE1_2;
            if (reuseSubDomain) {
                fmt = wrapper.iwMessages.E_SUBDOMAIN_NOTAVAILABLE_2;
            }
            var message = dojo.string.substitute(fmt, [wTitle, subDomainSize]);
            var nodes = [];
            com.ibm.mm.iwidget.Utils.findElementByAttribute("query", "> ."+wrapper.ns + "loading", wrapper.rootElement, nodes, false);
            if (nodes.length > 0) {
                aNode = nodes[0];
                aNode.innerHTML = "";
            }
        }
    },
    _onSecurityAlert:function(container,securityAlert){
        //handle unexpected iframe unload here
        if (securityAlert&& securityAlert == "OpenAjax.hub.SecurityAlert.FramePhish" ){
            var me=this;
             setTimeout( function () {
                    me._handleIframeMove( container );
              }, 0 );
        }
    },
    _handleIframeMove:function(container){
            //unsubscribe
            this.eventSvr._getHubAdapter(this.id).returnSubDomain(this._getSubDomain());

            var currentWindowState= this.windowManager[this.currentMode];
            var id = currentWindowState.id;
            var root = currentWindowState.root || null;

            // if root is not specified try loading the default root
            // this is needed in case that the mode was switched inside the widget but not on the stub
            if (root === null) {
                var aMode = this._getDefaultMode() || iwConstants.mode_view;
                var mainWindowState = this.windowManager[aMode] || null;

                if (mainWindowState !== null) {
                    root = mainWindowState.root || null;
                }
            }
                //unsubscribe any event
            try{
                for (var j in this.subHandler[id]) {
                    if (Object.prototype.hasOwnProperty.call(this.subHandler[id], j)) {
                        this.eventSvr.unsubscribeEvent(this.subHandler[id][j]);
                    }
                }
            }catch(e){
            }
            this.eventSvr._getHubAdapter(id).removeIframeHubContainer(id);

            //need to create a new one, main iframe only
            this._getInstanceMarkup(dojo.hitch(this, function(instancedata) {
                this._createIframe(instancedata,root,id,"false",this);
            }));
    },
    _getSubDomain: function() {
        if (!this.subDomain) {
            this.subDomain = this.eventSvr._getHubAdapter().getSubDomain();
        }
        return this.subDomain;
    },
    _handleDataSync: function(payload) {
        //for now it's just attributes, handle any received data....
        //any sub window may have changed data these updates need to be sent to stub widget
        if (payload && payload.attributes) {
            var attributes = payload.attributes;
            // we leave that line here for backwards compatibility
            this._syncModifiableProperties(attributes, this.getIWidgetInstance().getAttributes());
            // now we use our common abstraction layer to write it as well, this will cause the model to be used if enabled
            this._syncAttributes(attributes, this.getAttributes());
        }
        if (payload && payload.wiremodel) {
            var wiremodel = payload.wiremodel;
            this._syncWireModel(wiremodel, this.getIWidgetInstance().getWireModel());
        }

        this.commit(true); //commit any change in the stub
    },
    _syncWireModel: function(wiremodel, instanceWireModel) {
        var wires = wiremodel._wires;
        for (var i in wires) {
            if (Object.prototype.hasOwnProperty.call(wires,i)) {
                var aWire = wires[i];
                if (aWire._isDirty && aWire._type && aWire._type == "NEW") {
                    instanceWireModel.addWire(aWire.SourceWidget, aWire.SourceEvent, aWire.TargetEvent);
                } else if (aWire._isDirty && aWire._type && aWire._type == "DELETE") {
                    instanceWireModel.removeWire(aWire.SourceWidget, aWire.SourceEvent, aWire.TargetEvent);
                }
            }
        }

        var targets = wiremodel._targets;
        instanceWireModel._targets = targets;//simple replacement of array.
    },
    _syncModifiableProperties: function(properties, instanceProperties) {
        instanceProperties._updateProperties(properties);
    },
    _syncAttributes: function(sandboxAttributes, mainAttributes) {
        var TYPE_NEW = "newItem";
        var TYPE_UPDATE = "updatedValue";
        var TYPE_REMOVE = "removedItem";
        for (var att in sandboxAttributes) {
            if (Object.prototype.hasOwnProperty.call(sandboxAttributes,att)) {
                var item = sandboxAttributes[att];
                if (item._dirty) {
                    if (item._change.changeType == TYPE_REMOVE) {
                        mainAttributes.removeItem(item.id);
                    }
                    else {
                        mainAttributes.setItemValue(item.id, item.value, item.readOnly);
                    }
                }
                /*
                att._change.changeType
                att.id
                att.value
                att.values
                att.readOnly
                att._dirty
                */
            }
        }
        mainAttributes.commit();
    },
    handleSizeChanged: function(payload) {
        var currentModeWindow = this.windowManager[this.currentMode];
        var id = this.id;
        if (!currentModeWindow.main) {
            id = this.id + "_" + this.currentMode;
        }

        var root = currentModeWindow.root;
        var iframeNode = root.childNodes[0];
        if (payload.newWidth) {
            var width = parseInt(payload.newWidth,10);
            width = width - 5;
            dojo.style(iframeNode, "width", width + "px");
        }
        if (payload.newHeight) {
            var height = parseInt(payload.newHeight,10);
            height = height - 5;
            dojo.style(iframeNode, "height", height + "px");
        }

        //publish event to current active iframe, either view iframe or edit iframe
        this.eventSvr._publishEvent(com.ibm.mashups.iwidget.Constants.RESIZE_WIDGET + id, payload);
    },
    getCSSUrl: function() {
        var that = this;
        if (this.themeCSS) {
            return this.themeCSS;
        }
        //gather all the css link elements and find theme.css or theme_rtl.css
        dojo.forEach(document.getElementsByTagName("link"), function(cssNode) {
            if (cssNode.href && cssNode.href.indexOf("theme.css") != -1) {
                var index1 = cssNode.href.length - 9;
                if (cssNode.href.indexOf("theme.css") == index1) {
                    that.themeCSS = cssNode.href;
                }
            }
            else if (cssNode.href && cssNode.href.indexOf("theme_rtl.css") != -1) {
                var index2 = cssNode.href.length - 13;
                if (cssNode.href.indexOf("theme_rtl.css") == index2) {
                    that.themeCSS = cssNode.href;
                }
            }
        });
        return this.themeCSS;
    },
    _handleOnNavStateChanged: function(iEvent) {
        var state = iEvent.payload;
        if (state) {
            //call navstate api
            var navigationStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
            var widgetAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getWidgetAccessor(navigationStateModel, this.id);
            widgetAccessor.setWidgetState("cp", state);
            var deferred = navigationStateModel.commit();
            deferred.start();
        }
    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.RenderController"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.RenderController"] = true;
dojo.provide("com.ibm.mm.iwidget.RenderController");









dojo.declare("com.ibm.mm.iwidget.RenderController", null, {
    constructor: function(widgetwrapper) {
        this.widgetwrapper = widgetwrapper;
        this.widgetXMLUrl = this.widgetwrapper.getIWidgetInstance().widgetXMLUrl;
        this.iwStr = dojo.i18n.getLocalization("com.ibm.mm.enabler", "iwStr");
		this.iwMessages = dojo.i18n.getLocalization("com.ibm.mm.enabler", "iwMessages");
    },
    render: function() {
        this._loadWidgetDefinition();
    },
    _resourceBaseURL: new dojo.moduleUrl("com.ibm.mm.iwidget", "image/"),
    _setLoading: function() {
        //create div tag and set image
        var tempDiv = document.createElement("div");
        tempDiv.className = this.widgetwrapper.ns + "loading";
        if (ibmConfig && ibmConfig.loadingHTML) {
            tempDiv.innerHTML = ibmConfig.loadingHTML;
        }
        else if (ibmConfig && ibmConfig["loadingHTML.imageURL"]) {
            tempDiv.innerHTML = "<img alt='" + this.iwStr.LOAD + "' src='" + ibmConfig["loadingHTML.imageURL"] + "' />&nbsp;" + this.iwStr.LOAD;
        }
        else {
            tempDiv.innerHTML = "<img alt='" + this.iwStr.LOAD + "' src='" + this._resourceBaseURL + "progress-anim.gif' />&nbsp;" + this.iwStr.LOAD;
        }
        this.widgetwrapper.rootElement.appendChild(tempDiv);
    },
    _loadWidgetDefinition: function() {
        var widgetSpan = this.widgetwrapper.rootElement;
        if (this.widgetwrapper.loaded) {
            return false;
        }
        this._setLoading();
        if (this.widgetXMLUrl !== null) {
            var iWidgetService = com.ibm.mashups.services.ServiceManager.getService("widgetLoadService");
            iWidgetService.getWidgetXML(this.widgetXMLUrl, false, dojo.hitch(this, "handleWidgetInfoRetrieved"), this.widgetwrapper.id);
        }
        else {
            return false;
        } // no io is involved
        return true;
    },
    handleWidgetInfoRetrieved: function(data, statuscode, xhr) {
        var wTitle;
        if (statuscode == "200" || statuscode == "0") {
            this.widgetwrapper.setIWidgetDefinition(data); //save widget definition
            this.widgetDef = data;
        }
        else {
            if (!this._isWidgetInstalled()) {
                //handle widget not installed
                this._handleInlineWidgetNotInstalledMessage(this.iwStr.WIDGET_NOT_INSTALLED, this.iwStr.WIDGET_NOT_INSTALLED_SUB, data.message);
            }
            else {
                //handle error
                wTitle = unescape(this.widgetwrapper.getIWidgetInstance().getIDescriptorItems().getItemValue("title", dojo.locale));
                if (!wTitle) {
                    wTitle = this.widgetXMLUrl;
                }
                this._handleInlineMessage("error", dojo.string.substitute(this.iwMessages.E_IWIDGETDEF_NOTAVAILABLE_1, [wTitle]), data.message);
            }
            return;
        }
        var isSandboxed = this.isSandboxed();
        if (dojo.isIE < 7 && isSandboxed) {
            wTitle = unescape(this.widgetwrapper.getIWidgetInstance().getIDescriptorItems().getItemValue("title", dojo.locale));
            if (!wTitle) {
                wTitle = this.widgetXMLUrl;
            }
            this._handleInlineMessage("error", dojo.string.substitute(this.iwMessages.E_NODISPLAY_UNSECUREWIDGET_1, [wTitle]));
            return;
        }
        this._doRender(isSandboxed);
    },
    _isWidgetInstalled: function() {
        try {
            var catalogData = com.ibm.mashups.enabler.catalog.Factory.getCatalogCategoryModel();
            catalogData.setStrategy(new com.ibm.mashups.enabler.strategy.ListLoadAheadStrategy(25));
            var entryModel = null;
            var entryURL = null;
            // root category
            var rootNode = catalogData.getRoot().start();
            var catIterator = catalogData.getChildren(rootNode);
            // iterate through categories
            while (catIterator.hasNext()) {
                var category = catIterator.next();
                entryModel = catalogData.getCatalogEntryModel(category);
                // catalog entries iterator
                var elemIterator = entryModel.iterator();
                elemIterator.setCursorPosition(0);
                while (elemIterator.hasNext()) {
                    var entry = elemIterator.next();
                    var widgetIWidgetDefinition = decodeURIComponent(this.widgetXMLUrl);
                    if (widgetIWidgetDefinition.indexOf(entry.getDefinitionURL(false)) >= 0) {
                        return true;
                    }
                }
            }
        }
        catch (e) {
            // if no access to the palette such as with enabler core or something unexpected goes wrong,
            // then assume the widget is installed so the user will get more detail on the error
            return true;
        }
        return false;
    },
    isSandboxed: function() {
        var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
        var isSandboxed = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.SANDBOXENABLED);
        if (!isSandboxed) {
            return false;
        }
        var myLocation = document.location + "";
        // check if it's embedding usecase, no sandbox needed if it's embedding
        /*if (myLocation.indexOf("widget:html") > -1) {
         return false;
         }*/
        isSandboxed = false;
        var attributes = this.widgetDef.getAttributes() || null;
        if (attributes) {
            var value = attributes.getItemValue("sandbox");
            if (typeof value != "undefined" && value !== null) {
                if (value == "true") {
                    isSandboxed = true;
                }
            }
        }
        if (!isSandboxed) {
            //check attribute at instance level, deprecated
            if (this.widgetwrapper.rootElement.getAttribute("sandbox") !== null && this.widgetwrapper.rootElement.getAttribute("sandbox") == "true") {
                isSandboxed = true;
            }
        }
        //check if there's iw-sandbox defined
        if (!isSandboxed) {
            //check attribute at instance level, deprecated
            if (this.widgetwrapper.rootElement.className.indexOf(iwConstants.CSSCLASS_INSTANCE.iwSandbox) > 0) {
                isSandboxed = true;
            }
        }
        //check disable flag
        if (isSandboxed) {
            if (this._isSandboxDisabledWidget(this.widgetXMLUrl)) {
                isSandboxed = false;
            }
        }
        return isSandboxed;
    },
    _isSandboxDisabledWidget: function(widgetDefUrl) {
        var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
        var temp = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.WIDGETDEFID_SANDBOX_DISABLED);
        var disabledWidgetsList = temp;
        if (dojo.isString(disabledWidgetsList)) {
            disabledWidgetsList = [temp];
        }
        if (disabledWidgetsList.length === 0) {
            return false;
        }
        for (var i = 0; i < disabledWidgetsList.length; i++) {
            if (dojo.string.trim(widgetDefUrl) === dojo.string.trim(disabledWidgetsList[i])) {
                return true;
            }
            else if (dojo.string.trim(widgetDefUrl).indexOf(dojo.string.trim(disabledWidgetsList[i])) != -1 && dojo.string.trim(disabledWidgetsList[i]).indexOf("/") !== 0) {//check relative path like dataEditor/dataEditor.xml
                return true;
            }
            else if (dojo.string.trim(widgetDefUrl).indexOf(dojo.string.trim(disabledWidgetsList[i])) != -1 && dojo.string.trim(disabledWidgetsList[i]).indexOf("/") === 0 && dojo.string.trim(widgetDefUrl).indexOf(":") != -1) { //check absolute path like /dataEditor/dataEditor.xml
                //make sure protocol, hostname,port match to window.location.
                var buf = widgetDefUrl.split("//");
                var protocol = buf[0];
                var buf2 = buf[1].split("/");
                var host = buf2[0];
                if (protocol == window.location.protocol && window.location.host == host) {
                    return true;
                }
                else if (protocol == window.location.protocol && protocol == "http:" && host.indexOf(window.location.host) === 0) {
                    if (host.substr(host.indexOf(":") + 1) == "80") {
                        return true;
                    }
                }
                else if (protocol == window.location.protocol && protocol == "https:" && host.indexOf(window.location.host) === 0) {
                    if (host.substr(host.indexOf(":") + 1) == "443") {
                        return true;
                    }
                }
            }
        }
        return false;
    },
    _handleInlineMessage: function(type, message, details) {
        var nodes = [];
        com.ibm.mm.iwidget.Utils.findElementByAttribute("query", "> ."+this.widgetwrapper.ns + "loading", this.widgetwrapper.rootElement, nodes, false);
        var aNode = nodes[0];
        aNode.innerHTML = "";
    },
    _handleInlineWidgetNotInstalledMessage: function(message, submessage, details) {
        var nodes = [];
        com.ibm.mm.iwidget.Utils.findElementByAttribute("query", "> ."+this.widgetwrapper.ns + "loading", this.widgetwrapper.rootElement, nodes, false);
        var aNode = nodes[0];
        var msg = [];
        msg[msg.length] = "<div style=\"margin:15px\">";
        msg[msg.length] = "<div class=\"widgetNotInstalledImage\">";
        msg[msg.length] = "</div>";
        msg[msg.length] = "<div class=\"widgetNotInstalledText\">";
        msg[msg.length] = message;
        msg[msg.length] = "</div>";
        if (submessage && submessage.length > 0) {
            msg[msg.length] = "<div class=\"widgetNotInstalledSubText\">";
            msg[msg.length] = submessage;
            msg[msg.length] = "</div>";
        }
        msg[msg.length] = "</div>";
        aNode.innerHTML = msg.join("");
    },
    _doRender: function(isSandboxed) {
        var eventSvr = com.ibm.mashups.services.ServiceManager.getService("eventService");

        if (isSandboxed) {
            dojo.mixin(this.widgetwrapper, new com.ibm.mm.iwidget.widget.IWidgetWrapperStubImpl());
        }
        else {
            eventSvr._getHubAdapter().createInlineHubContainer(this.widgetwrapper.id);
            eventSvr._getHubAdapter().createInlineHubClient(this.widgetwrapper.id);
        }
        this.widgetwrapper.doRender();
    }
});


}

if(!dojo._hasResource["com.ibm.mm.iwidget.model.WidgetModelExtended"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.model.WidgetModelExtended"] = true;
dojo.provide("com.ibm.mm.iwidget.model.WidgetModelExtended");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget
 *
 * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
 * Any number that is smaller causes this class to be written out before any other with a higher number
 * @ibm-dojo-profile-level 40
 */

//moved here from ServiceManagerImpl:














dojo.declare("com.ibm.mm.iwidget.model.WidgetModelExtendedImpl",com.ibm.mm.iwidget.model.WidgetModelDefaultImpl,{

	_onWindowUnload:function(){
	    //set pagemode to be "unload"
	    var navigationStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
		if (navigationStateModel){
			var pageModeAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getPageModeAccessor(navigationStateModel);
			pageModeAccessor.setPageMode("unload");
		}

		try {
			var arr = [];
			for (var i in this.widgetArr){
                if (Object.prototype.hasOwnProperty.call(this.widgetArr,i)) {
                    this._unloadWidget(i); //use _unloadWidget to avoid publish event com.ibm.mashups.iwidget.Constants.WIDGETS_UNLOADED
                }
			}
		}
		catch(e){
  			console.log("_onWindowUnload "+ e.message);
		}
	},
	renderWidget: function(/*Object*/iWidget)
	{
        if (typeof iWidget == "undefined") {
			return;
		}
        if (iWidget.loaded || iWidget.loading) {
            return;
        }
        iWidget.loading = true;
        var renderController = new com.ibm.mm.iwidget.RenderController(iWidget);
		renderController.render();
	},
    getWidgetById: function(/*String*/id)
    {    //deprecated
        return this.find(id);
    }
});

com.ibm.mm.iwidget.model.WidgetModelImpl = com.ibm.mm.iwidget.model.WidgetModelExtendedImpl;

}

if(!dojo._hasResource["com.ibm.mm.iwidget.services.EventServiceExtended"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.services.EventServiceExtended"] = true;
dojo.provide("com.ibm.mm.iwidget.services.EventServiceExtended");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget
 *
 * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
 * Any number that is smaller causes this class to be written out before any other with a higher number
 * @ibm-dojo-profile-level 40
 */
// inject this service into the ServiceManager at the end. Therefore we have to require the implementation



dojo.declare("com.ibm.mm.iwidget.services.EventServiceExtendedImpl", com.ibm.mm.iwidget.services.EventServiceDefaultImpl, {
    registerExtServices: function(){
        var event = com.ibm.mashups.iwidget.Constants.WIDGET_WINDOWSTATECHANGED;
        var me = this;
        var eventCallback = function(payload){

            var widgetId = payload.id;
            var newWindowState = payload.newWindowState;
            var oldWindowState = payload.oldWindowState;
            me.fireEvent(widgetId, "onWindowStateChanged", {
                newWindowState: newWindowState,
                oldWindowState: oldWindowState
            });
        };

        this.subscribeEvent(event, null, eventCallback, null, null);
    },
    subscribeWire: function(/*String*/sourceWidget,/*String*/ sourceEvent,/*String*/ targetWidget,/*String*/ targetEvent){
        if (typeof sourceWidget == "undefined" || sourceWidget === null) {
            return false;
        }
        if (typeof sourceEvent == "undefined" || sourceEvent === null) {
            return false;
        }
        if (typeof targetWidget == "undefined" || targetWidget === null) {
            return false;
        }
        if (typeof targetEvent == "undefined" || targetEvent === null) {
            return false;
        }

        var rc = true;
        var that = this;

        // should be subHandle, topic, payload ( as defined in publishWire...)
        function eventCallback(topic, message, subscribeData){
            that.fireEvent(targetWidget, targetEvent, message.payload, message.payloadType, sourceWidget);
        }
        function callback(item, success, error){
            if (!success) {
                console.log("eventService.subscribeWire subscribe failed " + "source:" + sourceWidget + " sourceEvent:" + sourceEvent + " targetWidget:" + targetWidget + " targetEvent:" + targetEvent);
            }
        }
        // do real subscription only if it's an inline iwidget
        var payload;
        var hubClient = this.hubAdapter._getInlineHubClient(targetWidget);
        if (hubClient) {
            var wireId = this._generateWireId(sourceWidget, sourceEvent, targetWidget, targetEvent);
            // failsafe implementation. In case the same wire has already been created we will not create it again
            if (this.subMgr[wireId]) {
                return true;
            }

            var subHandler = hubClient.subscribe(this.WIDGETEVENT_PREFIX + sourceWidget + "." + sourceEvent, eventCallback, null, callback);
            this.subMgr[wireId] = subHandler;

            //notify source iWidget  -- onNewWire
            payload = {};
            payload.targetWidget = targetWidget;
            payload.sourceEvent = sourceEvent;
            payload.sourceWidget = sourceWidget;
            payload.targetEvent = targetEvent;
            this.fireEvent(sourceWidget, "onNewWire", payload);
        }
        //if target widget is an iframe widget, we need to delegate the job to iframed widget
        var isInlineClient = this.hubAdapter.isInlineClient(targetWidget);
        //send message to
        if (!isInlineClient) {
            // Eventname:eventservice.widgetid
            // methodname:subscribeWire
            // params:{}
            // hubclient:hubclientid
            var eventname = "eventservice." + targetWidget;
            payload = {};
            payload.methodname = "subscribeWire";
            payload.sourceWidget = sourceWidget;
            payload.sourceEvent = sourceEvent;
            payload.targetWidget = targetWidget;
            payload.targetEvent = targetEvent;
            payload.hubclient = "main";
            this._publishEvent(eventname, payload);
            rc = true;
        }
        return rc;
    },
    publishWire: function(/*String*/sourceWidget,/*String*/ sourceEvent,/*object*/ payload,/*String*/ payloadType){
        payload = this._serializePayload(payload);

        //allow widget to fire a event
        if (typeof sourceWidget == "undefined" || sourceWidget === null) {
            return false;
        }
        if (typeof sourceEvent == "undefined" || sourceEvent === null) {
            return false;
        }
        var hubClient = this.hubAdapter._getInlineHubClient(sourceWidget);
        //publish wire only if it's an inline iwidget
        if (hubClient) {
            hubClient.publish(this.WIDGETEVENT_PREFIX + sourceWidget + "." + sourceEvent, {
                "payload": payload,
                "payloadType": payloadType
            });
        }
        return true;
    },
    _serializePayload: function(payload){
        // complex payload objects must be serialized to json for case when widgets are sandboxed
        // to be serializable, complex payload objects must implement toJson method that returns json in format {"className":"x","json":"y"}
        // to be deserializable, complex payload objects must have a constructor with an argument that accepts the "y" json value returned from toJson
        if (typeof payload == 'object' && payload.toJson) {
            payload = payload.toJson();
        }
        return payload;
    },
    unSubscribeWire: function(sourceWidget, sourceEvent, targetWidget, targetEvent){
        if (typeof sourceWidget == "undefined" || sourceWidget === null) {
            return false;
        }
        if (typeof sourceEvent == "undefined" || sourceEvent === null) {
            return false;
        }
        if (typeof targetWidget == "undefined" || targetWidget === null) {
            return false;
        }
        if (typeof targetEvent == "undefined" || targetEvent === null) {
            return false;
        }
        var payload;
        var hubClient = this.hubAdapter._getInlineHubClient(targetWidget);
        if (hubClient) {
            //unsubscribe only if it's an inline widget
            var wireId = this._generateWireId(sourceWidget, sourceEvent, targetWidget, targetEvent);
            var subHandler = this.subMgr[wireId];
            if (subHandler) {
                this.unsubscribeEvent(subHandler, targetWidget);
                delete this.subMgr[wireId];
            }

            //onRemoveWire-- notify target widget
            payload = {};
            payload.targetWidget = targetWidget;
            payload.targetEvent = targetEvent;
            payload.sourceWidget = sourceWidget;
            payload.sourceEvent = sourceEvent;
            this.fireEvent(targetWidget, "onRemoveWire", payload);
            this.fireEvent(sourceWidget, "onRemoveWire", payload);
            //todo:remove
            this.publishEvent(iwConstants.EVENTS.unSubscribeWire, {
                wires: [payload]
            });

            //notify source widget
        }
        //if target widget is an iframe widget, we need to delegate the job to iframed widget
        var isInlineClient = this.hubAdapter.isInlineClient(targetWidget);
        //send message to
        if (!isInlineClient) {
            // Eventname:eventservice.widgetid
            // methodname:subscribeWire
            // params:{}
            // hubclient:hubclientid
            var eventname = "eventservice." + targetWidget;
            payload = {};
            payload.methodname = "unSubscribeWire";
            payload.sourceWidget = sourceWidget;
            payload.sourceEvent = sourceEvent;
            payload.targetWidget = targetWidget;
            payload.targetEvent = targetEvent;
            payload.hubclient = "main";
            this._publishEvent(eventname, payload);
            rc = true;
        }
        return true;
    },
    addWire: function(sourceWidget, sourceEvent, targetWidget, targetEvent){
        //SPI support, deprecated, should remove, no sandboxed support
        if (typeof sourceWidget == "undefined" || sourceWidget === null) {
            return false;
        }
        if (typeof sourceEvent == "undefined" || sourceEvent === null) {
            return false;
        }
        if (typeof targetWidget == "undefined" || targetWidget === null) {
            return false;
        }
        if (typeof targetEvent == "undefined" || targetEvent === null) {
            return false;
        }

        var rc = false;
        //if target widget is an iframe widget, we need to delegate the job to iframed widget
        var isInlineClient = this.hubAdapter.isInlineClient(targetWidget);
        //send message to
        if (!isInlineClient) {
            // Eventname:eventservice.widgetid
            // methodname:addWire
            // params:{}
            // hubclient:hubclientid
            var eventname = "eventservice." + targetWidget;
            var payload = {};
            payload.methodname = "addWire";
            payload.params = arguments;
            payload.hubclient = "main";
            this._publishEvent(eventname, payload);
            rc = true;
        }
        else {
            //update js object and subscribe wire
            rc = this.subscribeWire(sourceWidget, sourceEvent, targetWidget, targetEvent);
            if (rc) {
                var widget = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().getWidgetById(targetWidget);
                if (typeof widget != "undefined" && widget !== null) {
                    var aWire = {};
                    aWire.SourceWidget = sourceWidget;
                    aWire.SourceEvent = sourceEvent;
                    aWire.TargetEvent = targetEvent;
                    var instance = widget.getIWidgetInstance();
                    var wireObj = new com.ibm.mm.iwidget.widget.WireImpl(targetWidget, aWire);
                    instance._addWire(wireObj);
                }
            }
        }
        return rc;
    },
    removeWire: function(sourceWidget, sourceEvent, targetWidget, targetEvent){
        //SPI support, deprecated, remove , no sandboxed support
        if (typeof sourceWidget == "undefined" || sourceWidget === null) {
            return false;
        }
        if (typeof sourceEvent == "undefined" || sourceEvent === null) {
            return false;
        }
        if (typeof targetWidget == "undefined" || targetWidget === null) {
            return false;
        }
        if (typeof targetEvent == "undefined" || targetEvent === null) {
            return false;
        }
        var rc = false;
        //if target widget is an iframe widget, we need to delegate the job to iframed widget
        var isInlineClient = this.hubAdapter.isInlineClient(targetWidget);
        //send message to
        if (!isInlineClient) {
            // Eventname:eventservice.widgetid
            // methodname:addWire
            // params:{}
            // hubclient:hubclientid
            var eventname = "eventservice." + targetWidget;
            var payload = {};
            payload.methodname = "removeWire";
            payload.params = arguments;
            payload.hubclient = "main";
            this._publishEvent(eventname, payload);
            rc = true;
        }
        else {
            rc = this.unSubscribeWire(sourceWidget, sourceEvent, targetWidget, targetEvent);
            if (rc) {
                var widget = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().getWidgetById(targetWidget);
                if (typeof widget != "undefined" && widget !== null) {
                    var aWire = {};
                    aWire.SourceWidget = sourceWidget;
                    aWire.SourceEvent = sourceEvent;
                    aWire.TargetEvent = targetEvent;
                    var instance = widget.getIWidgetInstance();
                    var wireObj = new com.ibm.mm.iwidget.widget.WireImpl(targetWidget, aWire);
                    instance._removeWire(wireObj.getID());
                }
            }
        }
        return rc;
    }
});

if (!ibmConfig.insideSandbox) {
    com.ibm.mashups.services.ServiceManager.setService("eventService", "com.ibm.mm.iwidget.services.EventServiceExtendedImpl");
}
//IMPORTANT
//ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
//This section dynamically loads the Model representation when the variable enablerLayerModules contains the given module
if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "CoreModel") >= 0)) {
 dojo["require"]("com.ibm.mm.enabler.iwidget.services.EventServiceModel"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the layers
}

}

if(!dojo._hasResource["com.ibm.mm.iwidget.services.IFrameEventServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.services.IFrameEventServiceImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.services.IFrameEventServiceImpl");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget
 *
 * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
 * Any number that is smaller causes this class to be written out before any other with a higher number
 * @ibm-dojo-profile-level 40
 */



// inject this service into the ServiceManager at the end. Therefore we have to require the implementation

// make sure extended loaded before this one







dojo.declare("com.ibm.mm.iwidget.services.IFrameEventServiceImpl", com.ibm.mashups.iwidget.services.EventService, {
    constructor: function() {
        this.subMgr = {}; //save all the subscription on this widget
        this.eventQueue = [];
        this._hubClient = null;
        this.getHubClient();//initialize connection
    },
    getType: function() {
        return com.ibm.mm.iwidget.Constants.eventservice.type.IFRAME;
    },
    PREFIX_IFRAME: "_iframe_",
    getHubClient: function() {
        //console.log("getHubClient");
        if (this._hubClient) {
            return this._hubClient;
        }
        var that = this;
        //create hub client and connect to hub
        function onHubClientSecurityAlert(source, alertType) {
        }
        var hubClient = new OpenAjax.hub.IframeHubClient({
            HubClient: {
                onSecurityAlert: onHubClientSecurityAlert
            }
        });
        function onHubClientConnect2(client, success, error) {
            var id = client.getClientID();
            id = id.slice(8);
            that.setId(id);
            that._hubClient = client;
            that._subscribeEventService();
            for (var i in that.eventQueue) {
                if (Object.prototype.hasOwnProperty.call(that.eventQueue,i)) {
                    var args = that.eventQueue[i];
                    args[0] = "widgetevents." + id + args[0];
                    that._subscribeEvent.apply(that, args);
                }
            }
        }

        function onHubClientDisconnect(client, success, error) {
            client.connect(onHubClientConnect2);
        }

        hubClient.connect(onHubClientConnect2);

        return null;
    },
    disconnectHubClient: function() {
        if (!this._hubClient) {
            return;
        }
        this._hubClient.disconnect();
        this._hubClient = null;
    },
    setId: function(id) {
        this.id = id;
    },
    getId: function() {
        return this.id;
    },
    _subscribeEventService: function() {
        //dispatch event to each method....for now, just fireEvent
        //in future, broadcastEvent... has security concern though
        var that = this;
        // message should contain
        // methodname:fireEvent
        // params:{}
        // hubclient:hubclientid
        function eventCallback(topic, message, subscribeData) {
            //(targetWidget,targetEvent,message.payload,message.payloadType,sourceWidget)
            var methodname = message.methodname;
            if ((methodname == "subscribeWire") || (methodname == "unSubscribeWire")) {
                var fn = that[message.methodname];
                if (fn) {
                    fn.apply(that, [message.sourceWidget, message.sourceEvent, message.targetWidget, message.targetEvent]);
                }
            }
            else if (methodname) {
                var fn = that[message.methodname];
                if (fn) {
                    fn.apply(that, message.params);
                }
            }
        }
        this._hubClient.subscribe("eventservice." + this.getId(), eventCallback, this, this._subscribeCallback);
    },
    _subscribeCallback: function(subHandle, success,/*OpenAjax.hub.Error*/ error) {
        if (!success) {
            //console.log("subscribe failed "+subHandle);
        }
    },
    WIDGETEVENT_PREFIX: iwConstants.WIDGETEVENT_PREFIX,
    WILDCARD_PREFIX: iwConstants.WILDCARD_PREFIX,
    subscribeWire: function(/*String*/sourceWidget,/*String*/ sourceEvent,/*String*/ targetWidget,/*String*/ targetEvent) {
        //called within iframe, target widget is the sandboxed iwidget
        if (typeof sourceWidget == "undefined" || sourceWidget === null) {
            return false;
        }
        if (typeof sourceEvent == "undefined" || sourceEvent === null) {
            return false;
        }
        if (typeof targetWidget == "undefined" || targetWidget === null) {
            return false;
        }
        if (typeof targetEvent == "undefined" || targetEvent === null) {
            return false;
        }

        var rc = true;
        var that = this;

        // should be subHandle, topic, payload ( as defined in publishWire...)
        function eventCallback(topic, message, subscribeData) {
            //that.fireEvent(targetWidget, targetEvent, message.payload, message.payloadType, sourceWidget);
            //distribute event directly to iwidgetwrapper
            that.fireEvent(targetWidget, targetEvent, message.payload, message.payloadType, sourceWidget);
        }
        function callback(item, success, error) {
        }
        var subHandler = this._hubClient.subscribe(this.WIDGETEVENT_PREFIX + sourceWidget + "." + sourceEvent, eventCallback, null, callback);
        var wireId = this._generateWireId(sourceWidget, sourceEvent, targetWidget, targetEvent);
        this.subMgr[wireId] = subHandler;

        //notify source iWidget  -- onNewWire
        var payload = {};
        payload.targetWidget = targetWidget;
        payload.sourceEvent = sourceEvent;
        payload.sourceWidget = sourceWidget;
        payload.targetEvent = targetEvent;
        this.fireEvent(sourceWidget, "onNewWire", payload);
        return rc;
    },
    publishWire: function(/*String*/sourceWidget,/*String*/ sourceEvent,/*object*/ payload,/*String*/ payloadType) {
        payload = this._serializePayload(payload);

        //allow widget to fire a event
        if (typeof sourceWidget == "undefined" || sourceWidget === null) {
            return false;
        }
        if (typeof sourceEvent == "undefined" || sourceEvent === null) {
            return false;
        }
        this._hubClient.publish(this.WIDGETEVENT_PREFIX + sourceWidget + "." + sourceEvent, {
            "payload": payload,
            "payloadType": payloadType
        });
        return true;
    },
    _serializePayload: function(payload) {
        // complex payload objects must be serialized to json for case when widgets are sandboxed
        // to be serializable, complex payload objects must implement toJson method that returns json in format {"className":"x","json":"y"}
        // to be deserializable, complex payload objects must have a constructor with an argument that accepts the "y" json value returned from toJson
        if (typeof payload == 'object' && payload.toJson) {
            payload = payload.toJson();
        }
        return payload;
    },
    unSubscribeWire: function(sourceWidget, sourceEvent, targetWidget, targetEvent) {
        if (typeof sourceWidget == "undefined" || sourceWidget === null) {
            return false;
        }
        if (typeof sourceEvent == "undefined" || sourceEvent === null) {
            return false;
        }
        if (typeof targetWidget == "undefined" || targetWidget === null) {
            return false;
        }
        if (typeof targetEvent == "undefined" || targetEvent === null) {
            return false;
        }

        //unsubscribe from OAHub
        var wireId = this._generateWireId(sourceWidget, sourceEvent, targetWidget, targetEvent);
        var subHandler = this.subMgr[wireId];
        if (subHandler) {
            this._unsubscribeEvent(subHandler, targetEvent);
            delete this.subMgr[wireId];
        }

        //onRemoveWire-- notify target widget
        var payload = {};
        payload.targetWidget = targetWidget;
        payload.targetEvent = targetEvent;
        payload.sourceWidget = sourceWidget;
        payload.sourceEvent = sourceEvent;
        this.fireEvent(targetWidget, "onRemoveWire", payload);
        this.fireEvent(sourceWidget, "onRemoveWire", payload);
        //builder is listening on this event
        this._publishEvent(iwConstants.EVENTS.unSubscribeWire, {
            wires: [payload]
        });
    },
    fireEvent: function(targetWidget, targetEvent, payload, payloadType, sourceWidget) {
        var aEvent = new com.ibm.mm.iwidget.IEventImpl(targetEvent, payloadType, payload, sourceWidget);
        // this._publishEvent(this.WIDGETEVENT_PREFIX+targetWidget,aEvent,sourceWidget);
        var widgetModel = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel();
        var widget = widgetModel.find(targetWidget);
        if (typeof widget != "undefined" && widget !== null) {
            if (widget.isLoaded()) {
                //if widget isEventsReady
                widget.handleEvent(aEvent);
            }
            else {
                var subID = dojox.uuid.generateRandomUuid();
                var cb = function(eventSvr, wrapper, aEvent) {
                    wrapper.handleEvent(aEvent);
                    var subHandler = eventSvr.subMgr[subID];
                    if (subHandler) {
                        eventSvr._unsubscribeEvent(subHandler);
                    }
                };
                var subHandle = this._subscribeEvent(com.ibm.mashups.iwidget.Constants.WIDGET_LOADED + "." + widget.id, null, dojo.partial(cb, this, widget, aEvent));
                this.subMgr[subID] = subHandle;
            }
        }
        else { //if widget doesn't belong to iframe delegate the job to main eventservice since it can check if widget is loaded or not
            //build payload methodname:fireEvent params:[] hubclient:hubclientid
            var payloadObj = {};
            payloadObj.methodname = "fireEvent";
            payloadObj.hubclient = this.getId();
            payloadObj.params = [targetWidget, targetEvent, payload, payloadType];
            this._publishEvent("eventservice.main", payloadObj);
        }
    },
    //support pagechanged event and widget deleted event
    publishEvent: function(sourceEvent, payload, payloadType, sourceid) {
        return;
    },
    _publishEvent: function(event, payload, sourceid) {
        /*payload; need to be json object if it's openajax hub, for now, it's dojo, so it need to be array*/
        if (typeof payload == "undefined" || payload === null) {
            this._hubClient.publish(event, "");
        }
        else {
            this._hubClient.publish(event, payload);
        }
    },
    broadcastEvent: function(targetEvent, payload, payloadType, sourceid, pageid, spaceid) {
        // untrusted widgets are not trusted to broadcast events
        return;
    },
    broadcastEvents: function(eventsArray, sourceid, pageid, spaceid) {
        // untrusted widgets are not trusted to broadcast events
        return;
    },
    _handleBroadcastEventsCache: function() {
        // pass to main event service
        var payloadObj = {};
        payloadObj.methodname = "_handleBroadcastEventsCache";
        payloadObj.hubclient = this.getId();
        payloadObj.params = [];
        this._publishEvent("eventservice.main", payloadObj);
    },
    subscribeEvent: function(event, object, eventCallback, subscribeCallback, sourceid) {
        return;
    },
    _subscribeEvent: function(event, object, eventCallback, subscribeCallback, sourceid) {
        //internal use only for subscription managed by container
        //widgets should not use this at all.
        if (!this._hubClient) {
            this.eventQueue.push(arguments);
            return;
        }

        var subHandle1 = this._hubClient.subscribe(event, function(topic, data, subscriberData) { /*onData*/
            if (object && eventCallback) {
                eventCallback = dojo.hitch(object, eventCallback);
            }

            //Deserialize data,not necessary

            if (eventCallback) {
                eventCallback.apply(this, [data]);
            }
        }, null /* scope */, function(subID, success, error) { /*onComplete*/
            if (object && subscribeCallback ) {
                subscribeCallback = dojo.hitch(object, subscribeCallback);
            }
            if (subscribeCallback) {
                subscribeCallback.apply(this, [subID, success, error]);
            }
            if (!success) {
                return;
            }
        });
        return subHandle1;
    },
    _unsubscribeEvent: function(subscriptionHandler, sourceid) {
        if (!subscriptionHandler) {
            return;
        }
        this._hubClient.unsubscribe(subscriptionHandler);
    },
    unsubscribeEvent: function(subscriptionHandler, sourceid) {
        return;
    },
    _generateWireId: function(sourceWidget, sourceEvent, targetWidget, targetEvent) {
        return sourceWidget + "_" + sourceEvent + "_" + targetWidget + "_" + targetEvent;
    }
});

if (ibmConfig.insideSandbox) {
    com.ibm.mashups.services.ServiceManager.setService("eventService", "com.ibm.mm.iwidget.services.IFrameEventServiceImpl");
}


}

if(!dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetDefinitionExtendedImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetDefinitionExtendedImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.widget.IWidgetDefinitionExtendedImpl");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget
 *
 * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
 * Any number that is smaller causes this class to be written out before any other with a higher number
 * @ibm-dojo-profile-level 40
 */






dojo.declare("com.ibm.mm.iwidget.widget.IWidgetDefinitionExtendedImpl", com.ibm.mm.iwidget.widget.IWidgetDefinitionDefaultImpl, {
    getResources: function() {
        if (!this.resources) {
            this.resources = dojo.map(this.widgetDef.resources, function(resource) {
                return new com.ibm.mm.iwidget.widget.ResourceImpl(resource);
            });
        }
        return this.resources;
    },
    getPublishedEventsNames: function() {
        var eventNames = [];
        if (this.widgetDef.publicEvents) {
            com.ibm.mm.enabler.utils.Misc.forIn(this.widgetDef.publicEvents, function(temp, aEventName) {
                if (!temp.isPublished || (temp.isPublished && temp.isPublished == "true")) {
                    eventNames.push(aEventName);
                }
            });
        }
        return eventNames;
    },
    getHandledEventsNames: function() {
        var eventNames = [];
        if (this.widgetDef.publicEvents) {
            com.ibm.mm.enabler.utils.Misc.forIn(this.widgetDef.publicEvents, function(temp, aEventName) {
                if (temp.onEvent) {
                    // it's a valid handledEvent only when onEvent is defined
                    eventNames.push(aEventName);
                }
            });
        }
        return eventNames;
    },
    getPublishedEvent: function(/*String*/eventName) {
        //generate a copy of ieventDescription object
        if (!this.widgetDef.publicEvents) {
            return null;
        }
        var event = this.getPublicEvent(eventName) || null;
        if (event) {
            if (!event.isPublished || (event.isPublished && event.isPublished == "false")) {
                event = null;
            }
        }
        return event;
    },
    getHandledEvent: function(/*String*/eventName) {
        //generate a copy of iEventDescription object
        if (!this.widgetDef.publicEvents) {
            return null;
        }
        var event = this.getPublicEvent(eventName) || null;
        if (event) {
            if (!event.onEvent) {
                event = null;
            }
        }
        return event;
    },
    getPublicEvent: function(eventName) {
        //generate a copy of iEventDescription object , following json object should be created passinto iEventDescription
        if (!this.widgetDef.publicEvents) {
            return null;
        }
        if (this.eventsCache && this.eventsCache[eventName]) {
            return new com.ibm.mm.iwidget.IEventDescriptionImpl(this.eventsCache[eventName]);
        }
        var data = this.widgetDef.publicEvents[eventName];
        var event = null;
        var obj = {};
        if (data) {
            //mapping into json format defined by iwidget spec.
            obj.name = data.id;
            if (data.onEvent) {
                obj.handlingFn = data.onEvent; //"String"-pass by value
                obj.isHandled = true;
            }
            else {
                obj.isHandled = false;
            }

            obj.isPublished = !!data.isPublished;

            obj.attributes = {};
            obj.localizedAttributes = {};

            var descriptionId = null;
            com.ibm.mm.enabler.utils.Misc.forIn(data, function(d, i) {
                if (i == "description") {
                    descriptionId = d;
                }
                else if (i != "id" && i != "onEvent") {
                    obj.attributes[i] = d; // save onNewWire/onRemoveWire, potentially other attributes, all are string
                }
            });

            var description = null;
            if (descriptionId) {
                description = this._getEventDescription(descriptionId) || null;
                if (description) {
                    var defaultLang = description.lang;
                    if (!defaultLang) {
                        defaultLang = this.getDefaultLanguage();
                        if (!defaultLang) {
                            defaultLang = "en";
                        }
                    }
                    obj.lang = defaultLang;
                    if (description.payloadType) {
                        obj.type = description.payloadType;
                    }

                    //todo: save more attributes && localized attributes.
                    if (description.aliases) {
                        obj.attributes.aliases = description.aliases;
                    }

                    var localizedAttributes = description.descriptions;
                    /*if (typeof localizedAttributes != "undefined" && localizedAttributes != null){
                     obj.localizedAttributes= dojo.clone(description.descriptions);
                     }*/
                    if (localizedAttributes) { //performance improvement
                        obj.localizedAttributes = description.descriptions;
                    }
                    if (typeof(obj.localizedAttributes[defaultLang]) == "undefined") {
                        obj.localizedAttributes[defaultLang] = {};
                    }
                    //backward compatibility
                    if (description.title) {
                        obj.localizedAttributes[defaultLang].title = description.title;
                    }
                    if (description.description) {
                        obj.localizedAttributes[defaultLang].description = description.description;
                    }
                    if (description.descriptionURI) {
                        obj.localizedAttributes[defaultLang].descriptionURI = description.descriptionURI;
                    }
                }
            }
            if (!this.eventsCache) {
                this.eventsCache = {};
            }
            this.eventsCache[eventName] = obj;
            event = new com.ibm.mm.iwidget.IEventDescriptionImpl(obj);
        }
        return event;
    },
    _getEventDescription: function(id) {
        var eventDescription = null;
        if (this.widgetDef.eventDescriptions) {
            eventDescription = this.widgetDef.eventDescriptions[id];
        }
        return eventDescription;
    },
    _getPublicEvents: function() {
        //return associative array, each eventdescription is identified by it's name
        //return an empty object if there's no public Events;
        //pass by data
        var publicEvents = {};
        com.ibm.mm.enabler.utils.Misc.forIn(this.widgetDef.publicEvents, function(k, aEventName) {
            var eventDescription = this.getPublicEvent(aEventName) || null;
            if (eventDescription) {
                publicEvents[aEventName] = eventDescription;
            }
        }, this);
        return publicEvents;
    },
    getWidgetPublishedEvents: function() {
        return this.getPublishedEvents();
    },
    getWidgetHandledEvents: function() {
        return this.getHandledEvents();
    },
    getPublishedEvents: function() {
        //return an array of new generated eventDescription
        //pass by data
        var publishedEvents = [];

        dojo.forEach(this.getPublishedEventsNames(), function(publishedEventName) {
            var eventDescription = this.getPublicEvent(publishedEventName) || null;
            if (eventDescription) {
                publishedEvents.push(eventDescription); //todo, remove array
            }
        }, this);

        return publishedEvents;
    },
    getHandledEvents: function() {
        //save as above
        var handledEvents = [];

        dojo.forEach(this.getHandledEventsNames(), function(handledEventName) {
            var eventDescription = this.getPublicEvent(handledEventName) || null;
            if (eventDescription) {
                handledEvents.push(eventDescription); //todo, remove array
            }
        }, this);

        return handledEvents;
    },
    getPayloadDefs: function() {
        return this.widgetDef.payloadDefs;
    },
    getPayloadDef: function(name) {
        var payloadDef = this.widgetDef.payloadDefs[name];
        return (typeof payloadDef == "undefined") ? null : payloadDef;
    },
    getPayloadDefNames: function() {
        var arr = [];
        com.ibm.mm.enabler.utils.Misc.forIn(this.widgetDef.payloadDefs, function(a) {
            arr.push(a);
        });
        return arr;
    },
    _getShareableItemSets: function() {
        // return Shareable ItemSets that's saved, based on old widgetDef format
        // returns an Objectof sharedItemSet or return null
        var shareableItemSetsArr = this.widgetDef.shareableItemSetsArr;
        if (shareableItemSetsArr) {
            for (var i in shareableItemSetsArr) {
                if (Object.prototype.hasOwnProperty.call(shareableItemSetsArr, i)) {
                    return shareableItemSetsArr;
                }
            }
        }
        return null;
    },
    toSpecObject: function() {
        if (this.specObject) {
            return this.specObject;
        }
        var outputJSON = {};
        //no support within sandbox
        if (!this.xmlStr) {
            return outputJSON;
        }
        var xmlData = com.ibm.mm.enabler.xslt.loadXmlString(this.xmlStr);

        var expr = "/iw:iwidget";
        var rootNode = com.ibm.mashups.enabler.xml.XPath.evaluateEntry(expr, xmlData, this.namespaces);

        if (rootNode) {
            this._addAttributesToJson(rootNode, outputJSON);

            var conditionArray = [];
            conditionArray.push({
                elementName: "eventDescription",
                keyNames: ["id"]
            });
            conditionArray.push({
                elementName: "alt",
                keyNames: ["lang", "xml:lang"]
            });
            this._addElements(rootNode, conditionArray, outputJSON);

            conditionArray = [];
            conditionArray.push({
                elementName: "event",
                keyNames: ["id"]
            });
            this._addElements(rootNode, conditionArray, outputJSON);

            //this._addElements(rootNode, "itemSetDescription", ["id"], "alt", ["lang","xml:lang"], outputJSON);

            //this._addElements(rootNode, "itemDescription", ["id"], "alt", ["lang","xml:lang"], outputJSON);
            conditionArray = [];
            conditionArray.push({
                elementName: "itemSet",
                keyNames: ["id"]
            });
            conditionArray.push({
                elementName: "item",
                keyNames: ["id"]
            });
            conditionArray.push({
                elementName: "alt",
                keyNames: ["lang", "xml:lang"]
            });
            this._addElements(rootNode, conditionArray, outputJSON);

            conditionArray = [];
            //if no skipLoad attribute, check if there's skipLoad element
            conditionArray.push({
                elementName: "resource",
                keyNames: ["uri", "src"],
                elemsAsAtt: ["skipLoad"]
            });
            this._addElements(rootNode, conditionArray, outputJSON);
            conditionArray = [];
            conditionArray.push({
                elementName: "content",
                keyNames: ["mode"]
            });
            this._addElements(rootNode, conditionArray, outputJSON, true);
        }

        this.specObject = outputJSON;
        return outputJSON;
    },
    _addAttributesToJson: function(node, jsonNode) {
        dojo.forEach(node.attributes, function(att) {
            jsonNode["_" + att.nodeName.replace(":", "_")] = att.nodeValue;
        });
    },
    _addElements: function(node, conditionArray,/*elementName, keyNames, subElement, subElementKeyNames,*/ jsonNode, isContentNode) {
        if (!dojo.isArray(conditionArray) || conditionArray.length === 0) {
            return;
        }
        var elementName = conditionArray[0].elementName;
        var keyNames = conditionArray[0].keyNames;
        var elemsAsAtt = conditionArray[0].elemsAsAtt;
        var subElement = null;
        var subElementKeyNames = null;
        if (conditionArray.length > 1) {
            subElement = conditionArray[1].elementName;
            subElementKeyNames = conditionArray[1].keyNames;
        }

        var elements = jsonNode[elementName + "s"] = {}; // do plural notation
        var nodes = com.ibm.mashups.enabler.xml.XPath.evaluateXPath("iw:" + elementName, node, this.namespaces);

        if (nodes) {
            dojo.forEach(nodes, function(node) {
                var keyValue;
                for (var j = 0, kL = keyNames.length; j < kL; j++) {
                    // first match wins
                    keyValue = node.getAttribute(keyNames[j]);
                    if (keyValue) {
                        break;
                    }
                }
                if (keyValue) {
                    var subNode = elements[keyValue] = {};
                    this._addAttributesToJson(node, subNode);
                    if (elemsAsAtt) {
                        dojo.forEach(elemsAsAtt, function(elemAsAtt) {
                            var elemAsAttKey = "_" + elemAsAtt;
                            if (!(elemAsAttKey in subNode) || !subNode[elemAsAttKey]) {
                                var node2 = com.ibm.mashups.enabler.xml.XPath.evaluateEntry("iw:" + elemAsAtt, node, this.namespaces);
                                if (node2) {
                                    dojo.forEach(node2.childNodes, function(child) {
                                        if (child.nodeType == 4 && child.nodeValue) {
                                            subNode[elemAsAttKey] = child.nodeValue;
                                        }
                                    });
                                }
                            }
                        }, this);
                    }

                    // if there is also a subelement do one recursion
                    if (subElement) {
                        var nextLevelArr = conditionArray.slice(1);
                        this._addElements(node, nextLevelArr, subNode);
                    }

                    // if this is a content node also add the content as "value"
                    if (isContentNode) {
                        subNode.value = dojo.map(node.childNodes || [], function(child) {
                            return (child.nodeType === 4 || child.nodeType === 3) ? child.nodeValue : "";
                        }).join("");
                    }
                }
            }, this);
        }
    }
});

com.ibm.mm.iwidget.widget.IWidgetDefinitionImpl = com.ibm.mm.iwidget.widget.IWidgetDefinitionExtendedImpl;

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.services.WireProviderFactoryService_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.services.WireProviderFactoryService_API"] = true;
dojo.provide("com.ibm.mashups.iwidget.services.WireProviderFactoryService_API");
dojo.provide("com.ibm.mashups.iwidget.services.WireProviderFactoryService");

/**
 * @private
 * @ibm-module iWidget
 */
dojo.declare("com.ibm.mashups.iwidget.services.WireProviderFactoryService",null,  {

	/**
	 * TODO make this public at some point, ServiceManager documentation says it should be there
	 *
	 * @private
	 */
	SERVICE_NAME : "WireProviderFactoryService",

    /**
     * Creates event model for the specified widget by honoring the current persistence mode (e.g. DOM vs. Model).
     * The factory for the current persistence mode needs to be added to this service by using the <tt>addFactory</tt> method of this class.
     *
     * @param {com.ibm.mashups.iwidget.widget.IWidgetInstance} widgetInstance the widget for which to create the wire provider
     * @param {Object} contextAndCallback an optional JSON object with a context and callback property to provide as a callback
     * @return {com.ibm.mashups.iwidget.widget.WireProvider} an event model for the specified widget using the according factory or <tt>null</tt> if no factory is available for the current mode.
     */
    createWireProvider: function(widgetWrapper, contextAndCallback) {

    },
    /**
     * Sets the factory for the specified persistenceMode to this service.
     * @param {String} persistenceMode the mode that is supported by the specified factory
     * @param {com.ibm.mashups.iwidget.services.WireProviderFactory} factory the factory that creates the provider.
     * @return {void}
     */
    setFactory: function(persistenceMode, factory) {

    },

    /**
     * Removes a factory for a specified persistence mode.
     *
     * @param {String} persistenceMode the mode to remove
     *
     * TODO make this public at some time
     * @private
     */
    removeFactory: function(persistenceMode) {

    }
});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.services.WireProviderFactoryService"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.services.WireProviderFactoryService"] = true;
dojo.provide("com.ibm.mashups.iwidget.services.WireProviderFactoryService");


com.ibm.mashups.iwidget.services.WireProviderFactoryService.SERVICE_NAME = com.ibm.mashups.iwidget.services.WireProviderFactoryService.prototype.SERVICE_NAME;


}

if(!dojo._hasResource["com.ibm.mashups.iwidget.widget.WireProviderFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.widget.WireProviderFactory"] = true;
dojo.provide("com.ibm.mashups.iwidget.widget.WireProviderFactory");

/**
 * @private
 * @ibm-module iWidget
 */
dojo.declare("com.ibm.mashups.iwidget.widget.WireProviderFactory",null,  {
    /**
     * Creates wire provider for the specified widget and persistence mode.
     *
     * @param {com.ibm.mashups.iwidget.widget.IWidgetInstance} widgetInstance the widget for which to create the persistent attributes
     * @param {String} persistenceMode the persistence mode for which to create the attributes
     * @return {com.ibm.mashups.iwidget.widget.WireProvider} wire provider the given widget / mode.
     * If the specified mode is not supported by this method <tt>null</tt> will be returned.
     */
    createWireProvider: function(widgetInstance, persistenceMode) {

    },
    /**
     * Returns the persistence modes that are supported by this factory.
     * @return {String[]} the supported persistence modes.
     */
    getSupportedPersistenceMode: function() {

    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.widget.ModifiableWireModelImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.widget.ModifiableWireModelImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.widget.ModifiableWireModelImpl");





dojo.declare("com.ibm.mm.iwidget.widget.ModifiableWireModelImpl", null, {
    constructor: function(widgetInstance) {
        this._dirty = false;
		this._instance = widgetInstance;
		this.svc = com.ibm.mashups.services.ServiceManager.getService("eventService");

    },
	toJson:function(){
		var returnObj = {};
		returnObj._dirty = this._dirty;
		if(this._wires) {
			returnObj._wires = dojo.clone(this._wires);
		}
		if(this._targets) {
			returnObj._targets = dojo.clone(this._targets );
		}
		return returnObj;
	},
    isDirty: function() {
        return this._dirty;
    },
	setDirty: function(isDirty) {
      this._dirty = isDirty;
    },
	registerTargets:function(tw,te,se){
	 if (!this._targets) {
		 this._targets = {};
	 }
	 if (!this._targets[tw]) {
		 this._targets[tw] = [];
	 }
	 var wire = {tw:tw,te:te,sw:this._instance.id,se:se};
	 this._targets[tw].push(wire);
	 this._dirty = true;
	},
	getTargets:function(){
		if(! this._targets) {
			return null;
		}
		return this._targets;
	},
	removeTargets:function(tw,te,se){
		if(this._targets){
			if (this._targets[tw]) {
				if(!te && !se){
					delete(this._targets[tw]);
					this._dirty = true;
				}
				//todo,very rare case te,se will be available
			}
		}
	},
	_addWire:function(wire,loadFromDom) {
		var wire2 = this._findWire(wire.getID()) || null;
		if (wire2 === null) {
			if (!this._wires) {
				this._wires = [];
			}
			if (!(loadFromDom && loadFromDom === true)) {
				wire.setDirty(true);
				wire.setType(wire.TYPE_NEW);
				this._dirty = true;
			}
			this._wires.push(wire);
			this.svc.subscribeWire(wire.SourceWidget, wire.SourceEvent, this._instance.id, wire.TargetEvent);

		}
	},
	_removeWire:function(id) {
		var wire = this._findWire(id) || null;
		if (wire !== null) {
			// unsubscribe wire
			for ( var i in this._wires) {				
				if (typeof this._wires[i].getID === "function" && this._wires[i].getID() == id) {
						// remove wire from wire array
						//this._wires.splice(j-1,1);
						if(this._wires[i].setDirty === "function" ){
							this._wires[i].setDirty(true);
						}
						if(typeof this._wires[i].setType === "function"){
							this._wires[i].setType(this._wires[i].TYPE_DELETE);
						}
						this.svc.unSubscribeWire(wire.SourceWidget, wire.SourceEvent, this._instance.id, wire.TargetEvent);
						this._dirty=true;
						break;
				}
			}
		}
	},
	addWire:function(sourceWidget,sourceEvent,targetEvent) {
		var aWire = {};
		aWire.SourceWidget = sourceWidget;
		aWire.SourceEvent = sourceEvent;
		aWire.TargetEvent = targetEvent;
		var wire = new com.ibm.mm.iwidget.widget.WireImpl(this._instance.id, aWire);
		this._addWire(wire);
	},
	removeWire:function(sourceWidget,sourceEvent,targetEvent) {
		var aWire = {};
		sourceWidget = sourceWidget || null;
		sourceEvent = sourceEvent || null;
		targetEvent = targetEvent || null;
		if (sourceWidget !== null&& sourceEvent !== null  && targetEvent !== null) {
			aWire.SourceWidget = sourceWidget;
			aWire.SourceEvent = sourceEvent;
			aWire.TargetEvent = targetEvent;
			var wireObj = new com.ibm.mm.iwidget.widget.WireImpl(this._instance.id, aWire);
			this._removeWire(wireObj.getID());
		}else if (sourceWidget !== null){
			//delete all the wires that has this widget as source
			for (var w in this._wires) {				
					if (typeof this._wires[w].getSourceWidgetID === "function" && this._wires[w].getSourceWidgetID() == sourceWidget) {
						if(typeof this._wires[w].setDirty === "function"){
							this._wires[w].setDirty(true);
						}
						if(typeof this._wires[w].setType === "function"){
							this._wires[w].setType(this._wires[w].TYPE_DELETE);
						}
					}
				var wire = this._wires[w];
				this.svc.unSubscribeWire(sourceWidget, wire.SourceEvent, wire.TargetWidget, wire.TargetEvent);
				this._dirty=true;
			}			
		}
	},
	// find Wire by id
	_findWire: function(id) {
		this._wires = this._wires || null;
        var wire = null;
		if (this._wires !== null) {
			for (var w in this._wires) {
				if (typeof this._wires[w].getID === "function" && this._wires[w].getID() == id) {
					wire = this._wires[w]; //commit the change
					if (wire.isDirty() && wire.getType() !== null && wire.getType() == wire.TYPE_DELETE) {
						this._removeFromDOM(wire);
						delete this._wires[w];
						wire = null;
					}
					else {
						break;
					}
				}
			}
		}
		return wire || null;
	},
	getWires:function(){
		if (!this._wires) {
			this._loadWires();
		}
		var arr = [];
		for (var i in this._wires){
			if (Object.prototype.hasOwnProperty.call(this._wires,i)) {
				var aWire = this._wires[i];
				if (!(aWire.isDirty() === true && (aWire.getType() !== null && aWire.getType() == aWire.TYPE_DELETE))) {
					arr.push(aWire);
				}
			}
		}
		//if (arr.length == 0 ) return null;
		return arr;
	},
	_loadWires:function(){
          this._wires = [];
          var ns = this._instance.ns;
          var className="ReceivedEvent";
          var nodes=[];
          com.ibm.mm.iwidget.Utils.findElementByAttribute("query","> ."+ns+className,this._instance.rootElement,nodes,true);
          var names = ["SourceWidget","SourceEvent","TargetEvent"];
          var classes = ["SourceEvent","TargetEvent"];
          for (var i=0;i<nodes.length;i++){
               var aNode = nodes[i];
               var aWire = {};
               var isValid = true;
               for (var j=0;j<2;j++){
                   var element=[];
                   com.ibm.mm.iwidget.Utils.findElementByAttribute("query","> ."+ns+classes[j],aNode,element,false);
                   if (element.length === 0 ){ isValid = false; }
                   else{
                       if ( j===0 ) {
                           var temp = element[0].getAttribute("href") || null;
                           if (temp !== null) {
                             var index = temp.indexOf ("#");
                             if (index != -1) {
                                 temp=temp.substring(index+1);
                             }
                             aWire[names[0]] = temp;
                             aWire[names[1]] = element[0].innerHTML;
                            }
                       }
                       else{
                           aWire[names[2]] = element[0].innerHTML;
                       }
                   }
               }
               if (isValid) {
			   	  this._addWire(new com.ibm.mm.iwidget.widget.WireImpl(this._instance.id,aWire),true);
				//  com.ibm.mashups.services.ServiceManager.getService("eventService").subscribeWire(aWire.SourceWidget,aWire.SourceEvent,this._instance.id,aWire.TargetEvent);
			   }
           }
	},
	commit:function(){
		//update dom for ADD and Delete
		if (this.isDirty() === true){
			for (var i in this._wires){
				if (Object.prototype.hasOwnProperty.call(this._wires,i)) {
					var aWire = this._wires[i];
					if (aWire.isDirty() && aWire.getType() !== null && aWire.getType() == aWire.TYPE_NEW) {
						this._addToDOM(aWire);
						aWire.setDirty(false);
						aWire.setType(null);
					}
					else
						if (aWire.isDirty() && aWire.getType() !== null && aWire.getType() == aWire.TYPE_DELETE) {
							this._removeFromDOM(aWire);
							//delete this._wires[i];
							this._wires.splice(i, 1);
						}
				}
			}
			this.setDirty(false);
		}
	},
	_addToDOM:function(aWire){
		var sourceId = aWire.getSourceWidgetID();
		var sourceEvent = aWire.getSourceEventName();
		var targetEvent = aWire.getTargetEventName();

		var recEvent = document.createElement("span");
    	recEvent.className = this._instance.ns+"ReceivedEvent";
        var srcWidget = document.createElement("a");
    	srcWidget.className = this._instance.ns+"SourceEvent";
    	srcWidget.setAttribute("href", "#" + sourceId);
    	srcWidget.innerHTML = sourceEvent;

    	var tarEvent = document.createElement("span");
    	tarEvent.className = this._instance.ns+"TargetEvent";
    	tarEvent.innerHTML = targetEvent;

    	recEvent.appendChild(srcWidget);
    	recEvent.appendChild(tarEvent);

		this._instance.rootElement.appendChild(recEvent);

	},
	_removeFromDOM:function(aWire){
		var sourceId = aWire.getSourceWidgetID();
		var sourceEvent = aWire.getSourceEventName();
		var targetEvent = aWire.getTargetEventName();

		var widgetSpan = this._instance.rootElement;
    	var allWireSpans = dojo.query("." + this._instance.ns+"ReceivedEvent", widgetSpan);
		var fragmentService = com.ibm.mashups.services.ServiceManager.getService("iwidgetFragmentService");
    	for (var i = 0; i < allWireSpans.length; i++) {
        	var wireSpan = allWireSpans[i];
        	var srcWidgetSpan = dojo.query("."+this._instance.ns+"SourceEvent", wireSpan)[0];
        	var srcEvent = srcWidgetSpan.innerHTML;
        	var tarEventSpan = dojo.query("."+this._instance.ns+"TargetEvent", wireSpan)[0];

        	if (fragmentService.getKeyFromHref(srcWidgetSpan) == sourceId && srcEvent == sourceEvent && tarEventSpan.innerHTML == targetEvent) {
				//widgetSpan.removeChild(wireSpan);
				// use dojo.destroy() instead to avoid orphan nodes
				dojo.destroy(wireSpan);
				break;
			}
        }
    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.widget.DOMWireProviderFactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.widget.DOMWireProviderFactoryImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.widget.DOMWireProviderFactoryImpl");

// TODO



dojo.declare("com.ibm.mm.iwidget.widget.DOMWireProviderFactoryImpl", com.ibm.mashups.iwidget.widget.WireProviderFactory, {
    constructor: function() {
        this.modes = ["DOM"]; //just make it consistent with other model like attributes model
    },
 	createWireProvider: function(widgetInstance, persistenceMode) {
        return new com.ibm.mm.iwidget.widget.ModifiableWireModelImpl(widgetInstance);
    },
    getSupportedPersistenceMode: function() {
        return this.modes;
    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget
 */

// inject this service into the ServiceManager at the end. Therefore we have to require the implementation







dojo.declare("com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl", com.ibm.mashups.iwidget.services.WireProviderFactoryService, {
    constructor: function(){
        this._factories = {};
    },
    createWireProvider: function(widgetInstance, contextAndCallback) {
        if (contextAndCallback) {
            // register callback
            com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME).registerOnChangeListener(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES, contextAndCallback);
        }
        var persistenceMode;
        var wID = widgetInstance.id;

        persistenceMode = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME).getPersistenceMode(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_WIRES);

        var widgetDomNode = widgetInstance.rootElement;

        if (dojo.hasClass(widgetDomNode, com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl.STANDALONE_CLASS) || !persistenceMode) {
            persistenceMode = com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl.DEFAULT_PERSISTENCE;
        }

        if (typeof persistenceMode !== "undefined" && persistenceMode == com.ibm.mashups.enabler.widget.Constants.PERSISTENCE_MODE_MODEL) {
            var widgetModel = com.ibm.mashups.enabler.widget.Factory.getWidgetModel();
            var navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
            var spaceAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getSpaceAccessor(navStateModel);
            var pageAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getPageAccessor(navStateModel, currentSpaceID);

            var currentSpaceID = spaceAccessor.getSpaceID();
            var currentPageID = pageAccessor.getPageID();

            var modelID = com.ibm.mm.iwidget.Utils.getModelID(wID);

            var wnd = widgetModel.findWidgetWindow(modelID, currentPageID).start();

            if (!wnd) {
                persistenceMode = com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl.DEFAULT_PERSISTENCE;
                if (this.widgetWrapper && dojo.isFunction(this.widgetWrapper._getResourceBundle)) {
                    this.widgetWrapper._getResourceBundle();
                }
            }
		}

        if (!(persistenceMode in this._factories)) {
            return null;
        }
        return this._factories[persistenceMode].createWireProvider(widgetInstance, persistenceMode);
    },
    setFactory: function(persistenceMode, factory){
        this._factories[persistenceMode] = factory;
    },

    removeFactory: function(persistenceMode) {
    	if(persistenceMode in this._factories) {
    		delete this._factories[persistenceMode];
    	}
    }
});

com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl.DEFAULT_PERSISTENCE = com.ibm.mashups.enabler.widget.Constants.PERSISTENCE_MODE_DOM;
com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl.STANDALONE_CLASS = com.ibm.mm.iwidget.Constants.CSSCLASS_PREFIXED_INSTANCE.iwStandalone;

com.ibm.mashups.services.ServiceManager.setService(com.ibm.mashups.iwidget.services.WireProviderFactoryService.SERVICE_NAME, new com.ibm.mm.iwidget.services.WireProviderFactoryServiceImpl());

com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.WireProviderFactoryService.SERVICE_NAME).setFactory(com.ibm.mashups.enabler.widget.Constants.PERSISTENCE_MODE_DOM, new com.ibm.mm.iwidget.widget.DOMWireProviderFactoryImpl());


}

if(!dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetInstanceExtendedImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetInstanceExtendedImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.widget.IWidgetInstanceExtendedImpl");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget
 *
 * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
 * Any number that is smaller causes this class to be written out before any other with a higher number
 * @ibm-dojo-profile-level 40
 */





dojo.declare("com.ibm.mm.iwidget.widget.IWidgetInstanceExtendedImpl", com.ibm.mm.iwidget.widget.IWidgetInstanceDefaultImpl, {
    _addWire: function(wire) {
        return this.getWireModel()._addWire(wire);
    },
    _removeWire: function(id) {
        return this.getWireModel()._removeWire(id);
    },
    addWire: function(sourceWidget, sourceEvent, targetEvent) {
        return this.getWireModel().addWire(sourceWidget, sourceEvent, targetEvent);
    },
    removeWire: function(sourceWidget, sourceEvent, targetEvent) {
        return this.getWireModel().removeWire(sourceWidget, sourceEvent, targetEvent);
    },
    getWires: function() {
        return this.getWireModel().getWires();
    },
    getWireModel: function() {
        if (!this.wiremodel) {
            this.wiremodel = com.ibm.mashups.services.ServiceManager.getService("WireProviderFactoryService").createWireProvider(this, {context: this, callback: "_wireProviderModeChange",
                unregister: function(handle) {
                    this.wrapper.unregisterArray.push(handle);
                }
            });
        }
        return this.wiremodel;
    },
    _wireProviderModeChange: function(provider, oldMode, newMode) {
		// D18935: Store the wire model targets to transfer to the new wire model
        var targets = null;
        if (this.wiremodel) {
            targets = this.wiremodel.getTargets();
		}

		this.wiremodel = com.ibm.mashups.services.ServiceManager.getService("WireProviderFactoryService").createWireProvider(this);

		// D18935: Transfer the wire model targets to the new wire model
		if (targets) {
			for (var id in targets) {
				var value=targets[id];
				for (var i=0, l=value.length;i<l;i++) {
					this.wiremodel.registerTargets(value[i].tw, value[i].te, value[i].se);
				}
            }
        }

        this.getWires(); // we need to initialize the model here
    },
    _getPublicEvents: function() {

        if (!this.events) {
            this.events = {};
            var events = [];
            com.ibm.mm.iwidget.Utils.findElementByAttribute("query", "> ."+this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwEvent, this.rootElement, events, true);
            var eventDescs = [];
            com.ibm.mm.iwidget.Utils.findElementByAttribute("query", "> ."+this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwEventDescription, this.rootElement, eventDescs, true);

            if (events.length > 0) {
                for (var i = 0; i < events.length; i++) {
                    var elem = events[i];
                    var anEvent = this._getEventDescription(elem, eventDescs);
                    var id = elem.getAttribute("title");
                    this.events[id] = anEvent;
                }
            }

        }
        return this.events;
    },
    _getEventDescription: function(elem, eventDescs) {
        var id = elem.getAttribute("title");
        var nodeList = dojo.query("> ." + this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwDescRef, elem);
        var descRefNode = null;
        if (nodeList) {
            descRefNode = nodeList[0];
        }
        var eventDescName = null;
        if (descRefNode) {
            eventDescName = descRefNode.getAttribute("href");
            if (eventDescName.indexOf("#") === 0) {
                eventDescName = eventDescName.slice(1);
                // some browser actually escape the href that comes back so that we have to decode it so that we compare apples with apples
                eventDescName = unescape(eventDescName);
            }
        }
        var descNode = null;
        for (var j = 0; j < eventDescs.length; j++) {
            var temp = eventDescs[j];
            if (temp.getAttribute("title") == eventDescName) {
                descNode = temp;
                break;
            }
        }
        //build IEventDescriptionImpl object
        var obj = {};
        /*{
         name: "",
         alias: "",
         type: "",
         lang: "",
         handlingFn: "" | Function,
         isHandled: true | false,
         isPublished: true | false,
         localizedAttributes: [<locale>: {<attName>: <attValue>}, ...],
         attributes: {<attName>: <attValue>, ... }
         }*/
        obj.name = id;
        var alias = descRefNode.innerHTML;
        alias = alias.replace(/^\s*/, "").replace(/\s*$/, "");
        if (alias) {
            obj.alias = alias;
        }
        var className = elem.className;
        if (className.indexOf(this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwPublished) > 0) {
            obj.isPublished = true;
        }
        if (className.indexOf(this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwHandled) > 0) {
            obj.isHandled = true;
        }

        var list = [];
        list.push(this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwHandler);
        list.push(this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwNewWire);
        list.push(this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwRemoveWire);
        for (var s = 0; s < list.length; s++) {
            var nodesList = dojo.query("> ." + list[s], elem);
            if (nodesList) {
                var aNode = nodesList[0];
                if (aNode) {
                    switch (s) {
                        case 0:
                            obj.handlingFn = aNode.innerHTML;
                            break;
                        case 1:
                            obj.attributes = obj.attributes ? obj.attributes : {};
                            obj.attributes.onNewWire = aNode.innerHTML;
                            break;
                        case 2:
                            obj.attributes = obj.attributes ? obj.attributes : {};
                            obj.attributes.onRemoveWire = aNode.innerHTML;
                            break;
                        default:
                            break;
                    }
                }
            }
        }

        //payloadtype && localizedAttributes
        if (descNode) {
            var payloadTypeCSS = this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwPayloadType;
            var list = dojo.query("> ." + payloadTypeCSS, descNode);
            if (list && list[0]) {
                obj.type = list[0].innerHTML.replace(/^\s*/, "").replace(/\s*$/, "");
            }

            obj.localizedAttributes = {};
            var titleCSS = this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwTitle;
            var valueCSS = this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwValue;
            var titleList = dojo.query("> ." + titleCSS, descNode);
            if (titleList && titleList[0]) {
                dojo.query("> ." + valueCSS, titleList[0]).forEach(function(elem) {
                    var lang = elem.getAttribute("lang");
                    var value = elem.innerHTML.replace(/^\s*/, "").replace(/\s*$/, "");
                    if (!obj.localizedAttributes[lang]) {
                        obj.localizedAttributes[lang] = {};
                    }
                    obj.localizedAttributes[lang].title = value;
                });
            }
            var descCSS = this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwDescription;
            var valueCSS = this.ns + com.ibm.mm.iwidget.Constants.CSSCLASS_INSTANCE.iwValue;
            var descList = dojo.query("> ." + descCSS, descNode);
            if (descList && descList[0]) {
                dojo.query("> ." + valueCSS, descList[0]).forEach(function(elem) {
                    var lang = elem.getAttribute("lang");
                    var value = elem.innerHTML.replace(/^\s*/, "").replace(/\s*$/, "");
                    if (!obj.localizedAttributes[lang]) {
                        obj.localizedAttributes[lang] = {};
                    }
                    obj.localizedAttributes[lang].description = value;
                });
            }

        }

        return new com.ibm.mm.iwidget.IEventDescriptionImpl(obj);


    }

});
com.ibm.mm.iwidget.widget.IWidgetInstanceImpl = com.ibm.mm.iwidget.widget.IWidgetInstanceExtendedImpl;

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService_API"] = true;
dojo.provide("com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService_API");
dojo.provide("com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService");

/**
 * @private
 * @ibm-module iWidget
 */
dojo.declare("com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService",null,  {

	/**
	 * TODO make this public at some point, ServiceManager documentation says it should be there
	 *
	 * @private
	 */
	SERVICE_NAME : "WidgetEventModelFactoryService",

    /**
     * Creates event model for the specified widget by honoring the current persistence mode (e.g. DOM vs. Model).
     * The factory for the current persistence mode needs to be added to this service by using the <tt>addFactory</tt> method of this class.
     *
     * @param {com.ibm.mashups.iwidget.widget.IWidgetWrapper} widget the widget for which to create the event model
     * @return {com.ibm.mashups.Deferred} an event model (com.ibm.mashups.iwidget.model.EventModel) for the specified widget using the according factory or <tt>null</tt> if no factory is available for the current mode.
     */
    createEventModel: function(widgetWrapper,contextAndCallback) {

    },
    /**
     * Sets the factory for the specified persistenceMode to this service.
     * @param {String} persistenceMode the mode that is supported by the specified factory
     * @param {com.ibm.mashups.iwidget.services.WidgetEventModelFactory} factory the factory that creates the attributes.
     * @return {void}
     */
    setFactory: function(persistenceMode, factory) {

    },

    /**
    * Removes a factory for a specified persistence mode.
    *
    * @param {String} persistenceMode the mode to remove
    *
    * TODO make this public at some time
    * @private
    */
   removeFactory: function(persistenceMode) {

   }
});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService"] = true;
dojo.provide("com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService");



// make sure we can reference this globally
com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService.SERVICE_NAME = com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService.prototype.SERVICE_NAME;



}

if(!dojo._hasResource["com.ibm.mashups.iwidget.model.EventModelFactory"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.model.EventModelFactory"] = true;
dojo.provide("com.ibm.mashups.iwidget.model.EventModelFactory");

/**
 * @private
 * @ibm-module iWidget
 */
dojo.declare("com.ibm.mashups.iwidget.model.EventModelFactory",null,  {
    /**
     * Creates widget events model for the specified widget and persistence mode.
     *
     * @param {com.ibm.mashups.iwidget.widget.IWidgetWrapper} widget the widget for which to create the persistent attributes
     * @param {String} persistenceMode the persistence mode for which to create the attributes
     * @return {ManagedItemSet} the persistent attributes for the given widget / mode.
     * If the specified mode is not supported by this method <tt>null</tt> will be returned.
     */
    createEventModel: function(widgetWrapper, persistenceMode) {

    },
    /**
     * Returns the persistence modes that are supported by this factory.
     * @return {String[]} the supported persistence modes.
     */
    getSupportedPersistenceMode: function() {

    }
});

}

if(!dojo._hasResource["com.ibm.mashups.iwidget.model.EventModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.model.EventModel"] = true;
dojo.provide("com.ibm.mashups.iwidget.model.EventModel");


/**
 * @private
 * @ibm-module iWidget
 */
dojo.declare("com.ibm.mashups.iwidget.model.EventModel",null,{

	// FIXME What the heck is this doing in the API?
 constructor:function (wrapper) {
	  this.wrapper = wrapper;
 },
/**
It returns event specified by given id. It returns null if event is not found.<br/>
@param{String} id event id. Must not be <code>null</code>.
@returns{com.ibm.mashups.iwidget.IEventDescription} returns an event description that matches event id.
*/
 find:function(id){
     return null;
 },
/**
It returns true if event exists. It returns false if event doesn't exist.<br/>
@param{String} id event id. Must not be <code>null</code>.
@type Boolean
@returns{Boolean} returns true if event exists. It returns false if event doesn't exist.
*/
 eventExists:function(id){
     return false;
 },
/**
This method simply creates a new event definition. <br/>
It returns true if new event is created successfully. It returns false if it fails to create new event.<br/>
@param{com.ibm.mashups.iwidget.IEventDescription} eventDesc IEventDescription object. Must not be <code>null</code>.
@type Boolean
@returns{Boolean} returns true if new event is created successfully. It returns false if it fails to create new event.
*/
 createEvent:function(eventDesc){
 	 return null;
 },
/**
This method removes an existing event description.It returns true if event is removed successfully or event doesn't exist, otherwise it returns false. <br/>
@param{String} eventName event name. Must not be <code>null</code>.
@type Boolean
@returns{Boolean} returns true if event is removed successfully or event doesn't exist, otherwise it returns false.
*/
 removeEvent:function(eventName){

 },
/**
This method verifies if an update on an event is really required as it may be the same that is getting set again.<br/>
It returns true if the event is different and an update is required, otherwise false.<br/>
@param{com.ibm.mashups.iwidget.IEventDescription} eventDesc IEventDescription object. Must not be <code>null</code>.
@type Boolean
@returns{Boolean} returns true if the event is different and an update is required, otherwise false.
*/
 isUpdateEventRequired:function(eventDesc){

 },
/**
This method updates an existing event definition. <br/>
It returns true if event is updated successfully. It returns false if it fails to update existing event.<br/>
@param{com.ibm.mashups.iwidget.IEventDescription} eventDesc IEventDescription object. Must not be <code>null</code>.
@type Boolean
@returns{Boolean} returns true if event is updated successfully. It returns false if it fails to update existing event.
*/
 updateEvent:function(eventDesc){

 },
/**
The query method which takes a javascript object as condition, it returns a list of event descriptions which matches the given condition. <br/>
The scope of the events is limited to this iwidget instance. The returning result need to match all the conditions that's given. <br/>
For exampe, if a condition object looks like this: {type:'text', isHandled:true}<br/>
This method will return all the handled event description whose payload is text.<br/>
If no condition is provided, this method will return all the events. It returns null if no event is found for a given condition.Only predefined fields or non localized attributes should be used to define condition.
@param{Object} condition  JSON object that contains the condition. Must not be <code>null</code>.
@type com.ibm.mashups.iwidget.IEventDescription
@returns{com.ibm.mashups.iwidget.IEventDescription} returns an array of event description that matches the condition. It returns null if no event is found for a given condition.
*/
 getEvents:function(condition){

 }

});



}

if(!dojo._hasResource["com.ibm.mm.enabler.utils.EventModelHelperImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.enabler.utils.EventModelHelperImpl"] = true;
dojo.provide("com.ibm.mm.enabler.utils.EventModelHelperImpl");
dojo.declare("com.ibm.mm.enabler.utils.EventModelHelperImpl", null, {
    _PredefinedFields: {
        alias: "alias",
        name: "name",
        type: "type",
        lang: "lang",
        isPublished: "isPublished",
        isHandled: "isHandled",
        handlingFn: "handlingFn"
    },
    checkMatch: function(eventDesc, condition) {
        var rc = true;
        var conditionArr = [];
        var isPublished;
        for (var i in condition) {
            if (Object.prototype.hasOwnProperty.call(condition,i)) {
                if (!condition[i]) {
                    continue; //check next condition if current condition is null
                }
                if (typeof(this._PredefinedFields[i]) != "undefined") {
                    //for predefined fields

                    if (i == this._PredefinedFields.isPublished && (condition[i] === true || condition[i] == "true")) {
                        //check if isPublished is true
                        //break if !(isPublished is defined and isPublished = true)
                        //eventDesc.isPublished returns undefined if eventDesc.isPublished = true!

                        isPublished = eventDesc.isPublished;
                        if (!(isPublished && (isPublished === true || isPublished == "true"))) {
                            rc = false;
                            break;
                        }
                    }
                    else if (i == this._PredefinedFields.isPublished && (condition[i] == "false" || condition[i] === false)) {
                        //check if isPublished is false
                        //break if isPublished is defined and isPublished is not "false"
                        isPublished = eventDesc.isPublished;
                        if (!(isPublished && (isPublished === false || isPublished == "false"))) {
                            rc = false;
                            break;
                        }
                    }
                    else if (i == this._PredefinedFields.isPublished && (condition[i] == "false" || condition[i] === false)) {
                        //check if isPublished is false
                        //break if isPublished is defined and isPublished is not "false"
                        if (!this._checkBoolean(dojo.toJson(eventDesc), i, "false")) {
                            rc = false;
                            break;
                        }
                    }
                    else if (i == this._PredefinedFields.isHandled && (condition[i] === true || condition[i] == "true")) {
                        //break if handlingFn is not defined or it's null
                        if (!eventDesc[this._PredefinedFields.handlingFn]) {
                            rc = false;
                            break;
                        }
                    }
                    else if (i == this._PredefinedFields.isHandled && (condition[i] == "false" || condition[i] === false)) {
                        //break if handlingFn is defined and it's not null
                        if (eventDesc[this._PredefinedFields.handlingFn]) {
                            rc = false;
                            break;
                        }
                    }
                    else if (!(eventDesc[i] && eventDesc[i] == condition[i])) {
                        //break if !(condition exists and condition match)
                        rc = false;
                        break;
                    }
                } //for attributes
                else if (!(eventDesc.attributes && eventDesc.attributes[i] && eventDesc.attributes[i] == condition[i])) {
                    rc = false;
                    break;
                }
                //continue with next condition, break if condition doesn't meet
            }
        }
        return rc;
    },
    _checkBoolean: function(str, name, value) {
        var rc = false;
        var temp = "\"" + name + "\"" + ":" + value;
        if (str.indexOf(temp) != -1) {
            return true;
        }
        temp = "\"" + name + "\"" + ":\"" + value + "\"";
        if (str.indexOf(temp) != -1) {
            return true;
        }
        return false;
    }

});
dojo.declare("com.ibm.mashups.enabler.utils.EventModelHelper", null, {});
com.ibm.mashups.enabler.utils.EventModelHelper = new com.ibm.mm.enabler.utils.EventModelHelperImpl();


}

if(!dojo._hasResource["com.ibm.mm.iwidget.model.DOMEventModelImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.model.DOMEventModelImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.model.DOMEventModelImpl");




/*provide Locator and Iterator,query by condition and other convenience function*/
/*internal model for widget wrapper */
dojo.declare("com.ibm.mm.iwidget.model.DOMEventModelImpl", com.ibm.mashups.iwidget.model.EventModel, {
    constructor: function(wrapper) {
        //widget wrapper id
        this.wrapper = wrapper;
        //an associative array of eventDescription object
        this.eventDescriptionPool = {};
        var defEvents = wrapper.widgetDef._getPublicEvents();
		var instanceEvents = wrapper.getIWidgetInstance()._getPublicEvents();
		var events = defEvents?defEvents:null;
		if (instanceEvents) {
			for (var j in instanceEvents) {
				if (Object.prototype.hasOwnProperty.call(instanceEvents, j)) {
					events[j] = instanceEvents[j];
				}
			}
		}
        if (events) {
            var wrapperevents = {};
            for (var i in events) {
                if (Object.prototype.hasOwnProperty.call(events,i)) {
                    wrapperevents[i] = events[i];
                }
            }
            this.eventDescriptionPool = wrapperevents;
        }

    },
    /*id is eventName*/
    find: function(id) {
        var event = this.eventDescriptionPool[id];
        if (event) {
            return event;
        }
        if (this.wrapper.handledEvents) {
            if (this.wrapper.handledEvents[id]) {
                return this.wrapper.handledEvents[id][0];
            }
        }
        if (this.wrapper.publishedEvents) {
            if (this.wrapper.publishedEvents[id]) {
                return this.wrapper.publishedEvents[id][0];
            }
        }
        return null;
    },
    eventExists: function(eventName) {
        var temp = this.eventDescriptionPool[eventName];
        if (temp) {
            return true;
        }
        else {
            return false;
        }
    },
    _getEventDescObj: function(eventDesc) {
        var obj = eventDesc;
        var declaredClass = eventDesc.declaredClass;
        if (typeof declaredClass == "undefined" || declaredClass === null) {
            obj = new com.ibm.mm.iwidget.IEventDescriptionImpl(eventDesc);
        }
        return obj;
    },
    createEvent: function(eventDescData) {
        var eventDesc = this._getEventDescObj(eventDescData);
        var eventExists = this.eventExists(eventDesc.name);
        if (eventExists) {
            return false;
        }
        else {
            this.eventDescriptionPool[eventDesc.name] = eventDesc;
            return true;
        }
    },
    removeEvent: function(eventName) {
        var eventExists = this.eventExists(eventName);
        if (eventExists) {
            delete this.eventDescriptionPool[eventName];
            return true;
        }
        else {
            return true;
        }
    },
	removeEvents: function(eventNames){
		for (var i=0;i<eventNames.length;i++){
			 this.removeEvent(eventNames[i]);
		}
		//return true when deleted or event doesn't exist
		return true;
	},
    isUpdateEventRequired:function(eventDescData) {
        var eventDesc = this._getEventDescObj(eventDescData);
        var eventExists = this.eventExists(eventDesc.name);
        if (eventExists) {
            var oldEventDesc = this.eventDescriptionPool[eventDesc.name];
            // strip off namespace
            var oldType = oldEventDesc.type || "";
            oldType = (oldType.indexOf("}")==-1) ? oldType : oldType.substring(oldType.indexOf("}")+1);
            var newType = eventDesc.type || "";
            newType = (newType.indexOf("}")==-1) ? newType : newType.substring(newType.indexOf("}")+1);

            if ((oldEventDesc.alias != eventDesc.alias) ||
                (oldEventDesc.name != eventDesc.name) ||
                (oldType != newType) ||
                //(oldEventDesc.handlingFn != eventDesc.handlingFn) ||
                //(oldEventDesc.lang != eventDesc.lang) ||
                (oldEventDesc.isHandled != eventDesc.isHandled) ||
                (oldEventDesc.isPublished != eventDesc.isPublished)) {
               return true;
            }
            return false;
        }
        else {
            return true;
        }
    },
    updateEvent: function(eventDescData) {
        var eventDesc = this._getEventDescObj(eventDescData);
        var eventExists = this.eventExists(eventDesc.name);
        if (eventExists) {
            this.eventDescriptionPool[eventDesc.name] = eventDesc;
        }
        else {
            return false;
        }
        return true;
    },
	setEvents:function(eventDescDatas){
		var rc = true;
		for (var i=0;i<eventDescDatas.length;i++){
			var anEvent = eventDescDatas[i];
			var result = this.createEvent(anEvent);
			result = result || false;
			if (result === false) {
				result = this.updateEvent(anEvent);
			}
			result = result ||false;
			if (rc === true) {
				rc = result;
			}
		}
		return rc;
	},
    getEvents: function(condition) {
        //return  an array of iEventDescription ( by reference)
        //return null if no events is found

        if (typeof condition == "undefined" || condition === null) {
            return this._getEventsInArray(this.eventDescriptionPool);
        }
        //check any events from previous session
        var array = [];

        if (condition.isHandled && condition.isHandled == "true") {
            //check if we have any events in the wrapper array
            //backward compatibility
            if (this.wrapper.handledEvents) {
                this._addEvents(array, this.wrapper.handledEvents);
            }
        }

        if (condition.isPublished && condition.isPublished == "true") {
            //check if we have any events in the wrapper array
            //backward compatibility
            if (this.wrapper.publishedEvents) {
                this._addEvents(array, this.wrapper.publishedEvents);
            }
        }
        if (dojo.isString(condition)) {
            try {
                condition = dojo.fromJson(condition);
            }
            catch (e) {
                return null; // invalid condition
            }
        }


        for (var j in this.eventDescriptionPool) {
            if (Object.prototype.hasOwnProperty.call(this.eventDescriptionPool,j)) {
                var eventDesc = this.eventDescriptionPool[j];
                var rc = com.ibm.mashups.enabler.utils.EventModelHelper.checkMatch(eventDesc._getInternalJsonObj(), condition);
                if (rc) {
                    array.push(eventDesc);
                }
            }
        }
        if (array.length === 0) {
            return null;
        }
        else {
            return array;
        }
    },
    /*turn associative array into real array, return null if empty*/
    _getEventsInArray: function(arr) {
        var returnArr = [];
        for (var j in arr) {
            if (Object.prototype.hasOwnProperty.call(arr,j)) {
                returnArr.push(arr[j]);
            }
        }
        if (returnArr.length === 0) {
            return null;
        }
        else {
            return returnArr;
        }
    },
    _addEvents: function(arr, associativeArr) {
        for (var i in associativeArr) {
            if (Object.prototype.hasOwnProperty.call(associativeArr,i)) {
                var eventDescArr = associativeArr[i];
                for (var j in eventDescArr) {
                    if (Object.prototype.hasOwnProperty.call(eventDescArr,j)) {
                        arr.push(eventDescArr[j]);
                    }
                }
            }
        }
    }

});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.model.DOMEventModelFactoryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.model.DOMEventModelFactoryImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.model.DOMEventModelFactoryImpl");

// TODO



dojo.declare("com.ibm.mm.iwidget.model.DOMEventModelFactoryImpl", com.ibm.mashups.iwidget.model.EventModelFactory, {
    constructor: function() {
        this.modes = ["DOM"]; //just make it consistent with other model like attributes model
    },
 	createEventModel: function(widgetWrapper, persistenceMode) {
        return new com.ibm.mm.iwidget.model.DOMEventModelImpl(widgetWrapper);
    },
    getSupportedPersistenceMode: function() {
        return this.modes;
    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget
 */

// inject this service into the ServiceManager at the end. Therefore we have to require the implementation










dojo.declare("com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl", com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService, {
    constructor: function() {
        this._factories = {};
    },
    // returns a deferred
    createEventModel: function(widgetWrapper, contextAndCallback) {
        if (contextAndCallback) {
            // register callback
            com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME).registerOnChangeListener(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS, contextAndCallback);
        }
        return new com.ibm.mm.enabler.DeferredImpl(this, function(dfr, sync){
            var wID = widgetWrapper.id;

            var persistenceMode = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.ContainerService.SERVICE_NAME).getPersistenceMode(com.ibm.mashups.iwidget.services.ContainerService.PROVIDER_EVENTS);

            var widgetDomNode = widgetWrapper.rootElement;
            if (dojo.hasClass(widgetDomNode, com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl.STANDALONE_CLASS) || !persistenceMode) {
                persistenceMode = com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl.DEFAULT_PERSISTENCE;
            }

            var retVal;
            if (typeof persistenceMode !== "undefined" && persistenceMode == com.ibm.mashups.enabler.widget.Constants.PERSISTENCE_MODE_MODEL) {
                var widgetModel = com.ibm.mashups.enabler.widget.Factory.getWidgetModel();
                var navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();

                var spaceAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getSpaceAccessor(navStateModel);
                var currentSpaceID = spaceAccessor.getSpaceID();

                var pageAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getPageAccessor(navStateModel, currentSpaceID);
                var currentPageID = pageAccessor.getPageID();

                var modelID = com.ibm.mm.iwidget.Utils.getModelID(wID);

                var deferred = widgetModel.findWidgetWindow(modelID, currentPageID);
                deferred.setFinishedCallback(dojo.hitch(this, function(wnd, status){
                    if (!wnd) {
                        persistenceMode = com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl.DEFAULT_PERSISTENCE;
                        if (dojo.isFunction(widgetWrapper._getResourceBundle)) {
                            widgetWrapper._getResourceBundle();
                        }
                    }
                    if (!(persistenceMode in this._factories)) {
                        retVal = null;
                    }
                    else {
                        retVal = this._factories[persistenceMode].createEventModel(widgetWrapper, persistenceMode);
                    }
                    dfr.finish(retVal, status);
                }));
                deferred.start(sync);
            }
            else {
                if (!retVal) {
                    if (!(persistenceMode in this._factories)) {
                        retVal = null;
                    }
                    else {
                        retVal = this._factories[persistenceMode].createEventModel(widgetWrapper, persistenceMode);
                    }
                }
                dfr.finish(retVal, 200);
            }
            return retVal;
        });
    },
    setFactory: function(persistenceMode, factory) {
        this._factories[persistenceMode] = factory;
    },

    removeFactory: function(persistenceMode) {
        if (persistenceMode in this._factories) {
            delete this._factories[persistenceMode];
        }
    }
});

com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl.DEFAULT_PERSISTENCE = com.ibm.mashups.enabler.widget.Constants.PERSISTENCE_MODE_DOM;
com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl.STANDALONE_CLASS = com.ibm.mm.iwidget.Constants.CSSCLASS_PREFIXED_INSTANCE.iwStandalone;

com.ibm.mashups.services.ServiceManager.setService(com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService.SERVICE_NAME, new com.ibm.mm.iwidget.services.WidgetEventModelFactoryServiceImpl());

com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.iwidget.services.WidgetEventModelFactoryService.SERVICE_NAME).setFactory(com.ibm.mashups.enabler.widget.Constants.PERSISTENCE_MODE_DOM, new com.ibm.mm.iwidget.model.DOMEventModelFactoryImpl());


}

if(!dojo._hasResource["com.ibm.mashups.iwidget.itemset.ShareableItemSet"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.iwidget.itemset.ShareableItemSet"] = true;
dojo.provide("com.ibm.mashups.iwidget.itemset.ShareableItemSet");


/**
 * Interface to a simple abstraction of a datamodel which is shared across different components.
 * @ibm-api
 * @ibm-module iWidget
 */
dojo.declare("com.ibm.mashups.iwidget.itemset.ShareableItemSet", null, {
    /**
     @private
     */
    constructor: function() {
    },
    /**
     This method sets an item within the ShareableItemSet, creates or replaces an existing entry as needed.
     To add an additional value to any existing item, suggest to get the current value of this item and append
     the new value to the list and supply the result to this method.
     @param{String}itemName name of the item. Must never be <code>null</code>.
     @param{String}value value of the item. Must never be <code>null</code>.
     @return{com.ibm.mashups.iwidget.itemset.ShareableItemSet} return an handle of ShareableItemSet upon successful, <code>null</code> upon failure.
     */
    setItemValue: function( /*String*/itemName, /*String*/ value) {
        return this;
    },
    /**
     This method returns the value for the named item from the set.
     @param{String}itemName name of the item. Must never be <code>null</code>.
     @return{String} return the named item for the set, <code>null</code> upon failure.
     */
    getItemValue: function( /*String*/itemName) {
        return null;
    },
    /**
     This method returns an array of Strings, providing the name of each item.
     @return{String[]}  return an array of items names and return <code>null</code> if the set contains no item
     */
    getAllNames: function() {
        return null;
    },
    /**
     Removes the named item from the set.
     @param{String}itemName name of the item that needs to be removed. Must never be <code>null</code>.
     @return{com.ibm.mashups.iwidget.itemset.ShareableItemSet} return the handle to the ShareableItemSet upon successful, <code>null</code> upon failure.
     */
    removeItem: function(/*String*/itemName) {
        return null;
    },
    /**
     This funtions commits all the changes that's applied to ShareableItemSet. Any udpates should be distributed to client side  components that has registered listener on this ShareableItemSet.
     @type void
     */
    commit: function() {
        return null;
    },
    /**
     This function adds listener to this ShareableItemSet. So it will gets notified when this ShareableItemSet is updated.
     @param{Function}listener js function that should already be properly scoped. Must never be <code>null</code>.
     @return{String} return listener id if listener is registered successfully, return null if it's not.
     */
    addListener: function(/*Function*/listener) {
        return null;
    },
    /**
     This function removes the  listener from this ShareableItemSet.
     @param{String}listenerId  listener id that's returned by the system when listener is added. Must never be <code>null</code>.
     @return{Boolean} return true if listener is removed successfully.
     */
    removeListener: function(/*String*/listenerId) {
        return true;
    } //return true if listener is removed successfully
});





}

if(!dojo._hasResource["com.ibm.mm.iwidget.itemset.ShareableItemSetImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.itemset.ShareableItemSetImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.itemset.ShareableItemSetImpl");








dojo.declare("com.ibm.mm.iwidget.itemset.ShareableItemSetImpl", com.ibm.mashups.iwidget.itemset.ShareableItemSet, {
    constructor: function(parent, defData, name) {
        //items needs to be key/value pair
        this.DELETE_TOKEN = "DELETE_TOKEN";
        this.parent = parent;
        /* def is a json object. other localized syntax can be ignored here
         * { id:localId,
         *   alias:alias,//optional
         *   isPrivate:false,
         *   items:{
         *   	<id>:{id:<id>,alias:<alias>},
         *      <id>:{id:<id>,alias:<alias>}
         *   }
         * }
         */
        if (name) {
            this.id = name; //localId for new ShareableItemSet
        }
        if (defData) {
            this.id = defData.id;
            this.alias = defData.alias ? defData.alias : null;
            this.defData = defData; //save the reference to the data in widgetDef
        }
        this.mapping = {}; //name-id mapping globalid-id
        this.items = {};//id-value mapping {id:<id>,globalid:<globalid>,value:<value>}
        if (defData) {
            var _items = defData.items;
            for (var i in _items) {
                if (Object.prototype.hasOwnProperty.call(_items, i)) {
                    var id = i;
                    var alias = _items[i].alias ? _items[i].alias : null;
                    this.items[i] = {
                        id: id
                    };
                    if (alias) {
                        this.mapping[alias] = id;
                        this.items[i].alias = alias;
                    }
                }
            }
        }

        this.navigationStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();

        var psid = this.alias;
        if (!psid) {
            psid = this.id;
        }

        this.shareableAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getShareableParameterSetAccessor(this.navigationStateModel, psid, "global");
        this._isDirty = false;
    },
    addListener: function(/*obj*/fn) {
        var id = this.alias;
        if (!id) {
            id = this.id;
        }

        var me = this;
        var listener = function(payload) {
            //in future, we could apply filter here if necessary, right now, we always distribute event as is
            //wrap up as iEvent
            if (me._isSender) {
                return;
            }
            //resolve qname into local mapping
            var changes = payload.changes ? payload.changes : null;
            if (changes) {
                for (var i = 0; i < changes.length; i++) {
                    var alias = changes[i].alias; //this is globalid
                    if (me.mapping) {
                        if (me.mapping[alias]) {
                            var localId = me.mapping[alias];
                            changes[i].id = localId;
                        }
                    }
                }
            }
            if (changes.length > 0) {
                var iEvent = new com.ibm.mm.iwidget.IEventImpl("onItemSetChanged", null, payload);
                if (dojo.isString(fn)) {
                    var scope = me.parent._getHandlerScope(fn);
                    if (scope) {
                        fn = dojo.hitch(scope, fn);
                    }
                }
                fn(iEvent);
            }
        };
        var listenerId = this.shareableAccessor.registerListener(listener);
        return listenerId;
    },
    removeListener: function(/*String*/listenerId) {
        return this.shareableAccessor.removeListener(listenerId);
    },
    setItemValue: function( /*String*/itemName, /*String*/ value) {
        if (!itemName) {
            return null;
        }
        if (!value) {
            return null;
        }
        if (typeof(this._isDirty) != "undefined" && !this._isDirty) {
            this._isDirty = true;
            this._changedItems = {};
        }
        var alias = this._resolveMapping(itemName); //localId
        if (!alias) {
            alias = itemName;
        }
        this._changedItems = this._changedItems ? this._changedItems : {};
        this._changedItems[alias] = value;
        return this;
    },
    getItemValue: function( /*String*/itemName) {
        var id = this._resolveMapping(itemName);
        if (!id) {
            id = itemName;
        }
        if (this._isDirty && this._changedItems) {
            if (this._changedItems[id] && this._changedItems[id] != this.DELETE_TOKEN) {
                return this._changedItems[id];
            } else if (this._changedItems[id] && this._changedItems[id] == this.DELETE_TOKEN) {
                return null;
            }
        }
        //call navstate api to get  value
        var itemSetId = this.alias;
        if (!itemSetId) {
            itemSetId = this.id;
        }

        var value = this.shareableAccessor.getItemValue(id);
        if (!value) {
            value = null;
        }
        return value;
    },
    getAllNames: function() {
        var itemSetId = this.alias;
        if (!itemSetId) {
            itemSetId = this.id;
        }

        var names = this.shareableAccessor.getAllNames();

        if (this._isDirty) {
            var obj = {};
            for (var i = 0; i < names.length; i++) {
                var aName = names[i];
                obj[aName] = aName; //globalids
            }
            if (this._changedItems) {
                for (var j in this._changedItems) {
                    if (this._changedItems[j] && this._changedItems[j] == this.DELETE_TOKEN && obj[j]) {
                        obj[j] = null;
                    } else if (this._changedItems[j] && !obj[j]) {
                        obj[j] = j; //globalids
                    }
                }
            }
            var arr = [];
            for (var k in obj) {
                if (Object.prototype.hasOwnProperty.call(obj, k)) {
                    arr.push(k);
                }
            }
            names = arr;
        }
        for (var s = 0; s < names.length; s++) {
            var id = names[s];//globalid
            if (this.mapping[id]) {
                names[s] = this.mapping[id]; //replace with local id if available
            }
        }
        if (names.length === 0) {
            return null;
        }
        return names;
    },
    removeItem: function(/*String*/itemName) {
        if (typeof(this._isDirty) != "undefined" && !this._isDirty) {
            this._isDirty = true;
            this._changedItems = {};
        }

        var names = this.getAllNames();

        if (names === null) {
            return null;
        }

        var contains = false;
        for (var i = 0; i < names.length; i++) {
            if (names[i] == itemName) {
                contains = true;
            }
        }
        if (!contains) {
            return null; //item doesn't exist
        }
        var id = this._resolveMapping(itemName);
        if (!id) {
            id = itemName;
        }
        this._changedItems = this._changedItems ? this._changedItems : {};
        this._changedItems[id] = this.DELETE_TOKEN;
        return this;
    },
    getItemSetDescription: function() {
        return null;
    },
    commit: function() {
        //call navstate api to send _changedItems to navigation state
        if (this._isDirty) {
            this._isSender = true; //synchronous code below
            var itemSetId = this.alias;
            if (!itemSetId) {
                itemSetId = this.id;
            }
            this.shareableAccessor._setItems(this._changedItems);
            var deferred = this.navigationStateModel.commit(); //commit the data distribution or this will trigger data persistence to url
            deferred.start();
            this._isSender = false;
        }
        this._changedItems = null;
        this._isDirty = false;
    },
    _resolveMapping: function(name) {
        if (!name) {
            return null;
        }
        if (!this.items) {
            return null;
        }
        if (this.items[name] && this.items[name].alias) {
            return this.items[name].alias;
        }
        return null;
    }

});

com.ibm.mm.iwidget.itemset.ShareableItemSetFactory = com.ibm.mm.iwidget.itemset.ShareableItemSetImpl;

// IMPORTANT
// ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
// This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "CoreModel") >= 0)) {
    dojo["require"]("com.ibm.mm.iwidget.itemset.ShareableItemSetExtendedModelImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the minimal layer
}

}

if(!dojo._hasResource["com.ibm.mm.iwidget.DeferredLiveTextUnprocessImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.DeferredLiveTextUnprocessImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.DeferredLiveTextUnprocessImpl");



dojo.declare("com.ibm.mm.iwidget.DeferredLiveTextUnprocessImpl", com.ibm.mm.enabler.DeferredImpl, {
    constructor: function(wrapper) {
        this.wrapper = wrapper;
    },
    start: function(sync) {
        // defaults to false
        if (sync) {
            return;
        }

        var widgetInstance = this.wrapper.getIWidgetInstance();

        if (dojo.isFunction(this.wrapper.iScope._onGetMarkup)) {
            this.wrapper.iScope._onGetMarkup();
        }

        var tempMarkup = dojo.clone(this.wrapper.rootElement);

        dojo.publish("/com/ibm/mashups/livetext/livetextunchange", [tempMarkup, true, null, null, dojo.hitch(this, this._unchangeCompleteCallback), this.includeParent]);
    },
    setIncludeParent: function(value) {
        this.includeParent = value;
    },
    getIncludeParent: function() {
        return this.includeParent;
    },
    _unchangeCompleteCallback: function(node) {
        if (dojo.isFunction(this.getFinishedCallback())) {
            this.finish(node, 200);
        }
    }
});

}

if(!dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetWrapperExtendedImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.iwidget.widget.IWidgetWrapperExtendedImpl"] = true;
dojo.provide("com.ibm.mm.iwidget.widget.IWidgetWrapperExtendedImpl");

/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget
 *
 * This value defines the order in which the packages should be printed out into the dojo profile. Default is 100.
 * Any number that is smaller causes this class to be written out before any other with a higher number
 * @ibm-dojo-profile-level 40
 */






// TODO remove the following four requires as soon as the meta packages have been modularized
//dojo.require("com.ibm.mm.iwidget.model.eventmodel");
// END TODO

//dojo.require("com.ibm.mm.iwidget.model.EventModelImpl");
















dojo.declare("com.ibm.mm.iwidget.widget.IWidgetWrapperExtendedImpl", com.ibm.mm.iwidget.widget.IWidgetWrapperDefaultImpl, {

    getMarkup: function() {
        return new com.ibm.mm.iwidget.DeferredLiveTextUnprocessImpl(this);
    },
    destroy: function() {
        if (this.widgetDef) {
            var itemsets = this.widgetDef._getShareableItemSets();
            if (itemsets) {
                var anItemSet = null;
                for (var i in itemsets) {
                    if (Object.prototype.hasOwnProperty.call(itemsets, i)) {
                        // add default listener if there's any
                        if (this.shareableItemSets.listeners[i]) {
                            for (var j = 0, l = this.shareableItemSets.listeners[i].length; j < l; ++j) {
                                var listenerID = this.shareableItemSets.listeners[i][j];
                                anItemSet = this.shareableItemSets.itemsets[i];
                                anItemSet.removeListener(listenerID);
                            }
                        }
                    }
                }
            }
        }

        this.inherited(arguments);

        // perform the unregistration
        for (var m = 0, total = this.unregisterArray.length; m < total; m++) {
            dojo.unsubscribe(this.unregisterArray[m]);
        }
    },
    _getResourceBundle: function() {
        if (!this.iwMessages) {
            this.iwMessages = dojo.i18n.getLocalization("com.ibm.mm.enabler", "iwMessages");
        }
        return this.iwMessages;
    },
    _logUpdateMarkupError: function(mode) {
        this._getResourceBundle();
        var error = dojo.string.substitute(this.iwMessages.E_IWIDGETDEF_CONTENTNOTAVAILABLE_1, [mode]);
    },

    _loadWidgetSharedResource: function(cb2) {

        var resources = this.widgetDef.getResources();
        this._getResourceBundle();
        if (typeof resources != "undefined" && resources !== null) {
            var size = resources.length - 1;
            if (size == -1) {
                cb2();
            }

            // css and images must be grouped together for multipart support
            // js must be loaded first since css callback may have dependency js files
            var sortedResources = [];
            var temp = [];
            for (var x in resources) {
                if (Object.prototype.hasOwnProperty.call(resources, x)) {
                    var resource = resources[x];
                    if (resource.isImage() || resource.isCSS()) {
                        //   sortedResources.unshift(resource);//add to beginning of array
                        temp.push(resource);
                    }
                    else {
                        sortedResources.push(resource); //we still need the order to js resources
                    }
                }
            }
            for (var y = 0; y < temp.length; y++) {
                sortedResources.push(temp[y]);
            }
            var me = this;
            var mycb = function(i, resourceData, data, status) {
                if (data && status && resourceData.isJS()) {
                    me.error = "true";
                    if (!me.data) {
                        me.data = [];
                    }
                    var msg = dojo.string.substitute(me.iwMessages.E_RESOURCE_LOAD_FAIL_2, [resourceData.src, data.message]);
                    me.data.push({
                        data: msg,
                        status: status
                    });
                }
                if (size == i) {
                    if (me.error && me.error == "true") {
                        dojo.query("> ." + me.ns + "loading", me.rootElement).forEach(function(elem) {
                            elem.innerHTML = "";
                            var wTitle = me.getIWidgetInstance().getIDescriptorItems().getItemValue("title", dojo.locale);
                            if (!wTitle) {
                                wTitle = "'"+me.getIWidgetInstance().widgetXMLUrl+"'";
                            }
                            else {
                                wTitle = "'"+unescape(wTitle)+"'";
                            }
                            if (me.widgetDef) {
                                var _id = me.widgetDef.getWidgetId();
                                if (_id) {
                                    wTitle = "'"+_id+"' (" + wTitle + ")";
                                }
                            }
                            var message = "";
                            var _data = (dojo.isArray(me.data))?me.data[0]:me.data;
                            message = "";
                            for (var j in _data) {
                              if (Object.prototype.hasOwnProperty.call(_data, j)) {
                                if (j=="data") { // we only copy the details
                                    message = message.concat("'"+_data[j]+"'").concat("\n");
                                }
                              }
                            }
                        });
                        me.error = null;
                        me.data = null;
                    }
                    else {
                        if (cb2) {
                            cb2(); //iContext blockInit for all the resources rather than support blockInit
                        }
                    }
                }
            };

            for (var i = 0; i < sortedResources.length; i++) {
                var resourceData = sortedResources[i];
                if (typeof resourceData != "undefined" && resourceData !== null) {
                    com.ibm.mashups.services.ServiceManager.getService("resourceLoadService").loadResource(resourceData, this.id, dojo.partial(mycb, i, resourceData));
                }
            }
        }
    },
    handleEvent: function(payload) {
        //event handler that subscribes to event handler
        var declaredClass = payload.declaredClass;
        if (typeof declaredClass != "undefined" && declaredClass !== null && declaredClass == "com.ibm.mm.iwidget.IEventImpl") {
            var eventName = payload.name;
            return this._handleEvent(eventName, payload);
        }
        //if it's a payload other than iEvent --used for internal communication between wrapper and wrapper stub
        //for example: _getMarkup(includeParent);
        var scope = payload.scope;
        if (typeof scope != "undefined" && scope !== null) {
            if (scope == "instance") {
                scope = this.getIWidgetInstance();
            }
            else if (scope == "eventmodel") {
                scope = this._getPublicEvents();
            }
        }
        else {
            scope = this;
        }
        var methodname = payload.methodname;
        if (typeof methodname != "undefined" && methodname !== null) {
            if (scope[methodname] && dojo.isFunction(scope[methodname])) {
                scope[methodname].apply(scope, payload.params);
            }
        }
    },
    _handleEvent: function(eventName, iEvent) {
        iEvent = this._deserializePayload(iEvent);

        //check here. it's just one payload with {eventName,iEvent}
        if (typeof eventName == "undefined" || eventName === null) {
            return false;
        }
        if (!this.loaded) {
            if (!this._eventqueue) {
                this._eventqueue = {};
            }
            this._eventqueue[eventName] = iEvent;
            return;
        }
        //handle onModeChanged event
        try {
            if (eventName == iwConstants.EVENTS.onNavStateChanged) {
                return this._handleOnNavStateChanged(iEvent);
            }

            if (eventName == iwConstants.EVENTS.onWindowStateChanged) {
                //update widget and pass event to widget
                var navStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
                var accessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getWidgetAccessor(navStateModel, this.id);
                var value = iEvent.payload.newWindowState;
                accessor.setWindowState(value);
         		var widgetBox = dojo.contentBox(this.rootElement.parentNode);    // .lotusWidgetBody
                this.handleSizeChanged({"newWidth":Math.max(0, widgetBox.w), "newHeight":Math.max(0, widgetBox.h)});
                return this._handleEventInternal(eventName, iEvent);
            }
            if (eventName == iwConstants.EVENTS.onModeChanged) {
                if (this._inIframe()) {
                    //publish event to stub widget
                    var payloadObj = {};
                    payloadObj.methodname = "_handleOnModeChange";
                    payloadObj.hubclient = this.hubId;
                    payloadObj.params = [iEvent.payload];
                    //var id = "_stub_"+this.id.slice(0,this.id.lastIndexOf("_"));
                    var id = "_stub_" + this.id;
                    this.eventSvr._publishEvent(iwConstants.WIDGETEVENT_PREFIX + id, payloadObj, this.hubId);
                    return;
                }

                return this._handleModeChange(iEvent);
            }
            if (eventName == "onNewWire") {
                return this._handleNewWire(iEvent);
            }
            if (eventName == "onRemoveWire") {
                return this._handleRemoveWire(iEvent);
            }
            return this._handleEventInternal(eventName, iEvent);
        }
        catch (e) {
        }
    },
    getPublicEventHandler: function(/*String|Function*/eventName) {

        //var eventDesc = this._getHandledEvents()[eventName];
        var eventModel = this._getPublicEvents() || null;
        if (!eventModel) {
            return null;
        }
        var eventDesc = eventModel.find(eventName) || null;
        if (!eventDesc) {
            return null;
        }

        var handlerFn = eventDesc.handlingFn || null;

        if (!handlerFn) {
            var isComplete = eventDesc.getAttribute("isComplete");
            if (typeof isComplete !== "undefined" && isComplete === false) {
                //distribute an iEvent to widget
                var eventName1 = iwConstants.EVENTS.onIncompleteEventDescription;
                var payload = {
                    eventDescription: eventDesc
                };
                var iEvent = new com.ibm.mm.iwidget.IEventImpl(eventName1, null, payload);//json format
                this._handleEventInternal(eventName1, iEvent);
                eventDesc = eventModel.find(eventName);
                handlerFn = eventDesc.handlingFn;
            }
        }
        var handlerObj = null;
        if (handlerFn) {
            if (dojo.isFunction(handlerFn)) {
                handlerObj = handlerFn;
            }
            else {
                var scope = this._getHandlerScope(handlerFn) || null;
                if (scope) {
                    handlerObj = dojo.hitch(scope, handlerFn);
                }
            }
        }
        return handlerObj;
    },
    getPublishedEvents: function() {
        //backwardcompatibility
        if (!this.publishedEvents) {
            this.publishedEvents = {};
        }
        return this.publishedEvents;
    },
    getHandledEvents: function() {
        //backwardcompatibility
        if (!this.handledEvents) {
            this.handledEvents = {};
        }
        return this.handledEvents;
    },
    _inIframe: function() {
        if (this._isInIframe) {
            return this._isInIframe;
        }
        var inIframe = false;
        var type = this.eventSvr.getType();
        if (typeof type != "undefined" && type == com.ibm.mm.iwidget.Constants.eventservice.type.IFRAME) {
            inIframe = true;
        }
        this._isInIframe = inIframe;
        return this._isInIframe;
    },
    setMainframeId: function(mainframeId) {
        this._mainframeId = mainframeId;
    },
    setModal: function(isModal) {
        this._isModal = isModal;
    },
    isModal: function() {
        //indicate if this is an iframe rendered in a modal dialog
        return this._isModal ? this._isModal : false;
    },
    _handleDataSync: function(payload) {
        //for now it's just attributes
        //any sub window may have changed data these updates need to be sent to stub widget
        if (typeof payload.attributes != "undefined" && payload.attributes !== null) {
            var attributes = payload.attributes;
            this._syncModifiableProperties(attributes, this.getIWidgetInstance().getAttributes());
        }
        if (typeof payload.idescriptors != "undefined" && payload.idescriptors !== null) {
            var idescriptors = payload.idescriptors;
            this._syncModifiableProperties(idescriptors, this.getIWidgetInstance().getIDescriptorItems());
        }
        if (typeof payload.wiremodel != "undefined" && payload.wiremodel !== null) {
            var wiremodel = payload.wiremodel;
            this._syncWireModel(wiremodel, this.getIWidgetInstance().getWireModel());
        }
        this.commit(true); //commit any data change in instance
    },
    _syncModifiableProperties: function(properties, instanceProperties) {
        var items = properties._items;
        /* for each item following json object is used
         {readOnly:false,
         values:{ <locale>:<value>}
         }
         if the whole item is removed. _items["itemname"] = deletetoken;
         if only value for a particular locale is removed,  _items["itemname"] [<locale>]	=deletetoken;
         */
        if (properties._dirty) {
            for (var i in items) {
                if (Object.prototype.hasOwnProperty.call(items, i)) {
                    var name = i;
                    var temp = items[i];
                    if (dojo.isString(temp)) {
                        if (temp && temp == instanceProperties.DELETE_TOKEN) {
                            instanceProperties.removeItem(name);
                        }
                    }
                    else {
                        var readOnly = (items[i].readOnly) ? items[i].readOnly : false;
                        var values = items[i].values;
                        if (typeof values != "undefined" && values !== null) {
                            for (var j in values) {
                                if (Object.prototype.hasOwnProperty.call(values, j)) {
                                    var value = values[j];
                                    if (value && value == instanceProperties.DELETE_TOKEN) {
                                        instanceProperties.removeItemValue(name, j);
                                    }
                                    else if (value) {
                                        instanceProperties.setItemValue(name, value, readOnly, j);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    _syncWireModel: function(wiremodel, instanceWireModel) {
        var wires = wiremodel._wires;
        for (var i in wires) {
            if (Object.prototype.hasOwnProperty.call(wires, i)) {
                var aWire = wires[i];
                if (aWire._isDirty && aWire._type && aWire._type == "NEW") {
                    instanceWireModel.addWire(aWire.SourceWidget, aWire.SourceEvent, aWire.TargetEvent);
                }
                else if (aWire._isDirty && aWire._type && aWire._type == "DELETE") {
                    instanceWireModel.removeWire(aWire.SourceWidget, aWire.SourceEvent, aWire.TargetEvent);
                }
            }
        }
        var targets = wiremodel._targets;
        instanceWireModel._targets = targets;//simple replacement of array.
    },
    setStateData: function(stateData) {
        this.stateData = stateData;
        //StateData includes: widgetNavigationState
    },
    updateState: function() {
        //frameworks distribute onNavStateChanged event
        //handle onNavStateChanged Event here...
        //distribute onNavStateChanged event to iWidget
        var iEvent;
        if (!this._inIframe()) {//do this when it's not iframed
            var navigationStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
            var widgetAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getWidgetAccessor(navigationStateModel, this.id) || null;
            if (widgetAccessor) {
                var customParams = widgetAccessor.getWidgetState("cp");
                if (customParams) {
                    //send json object to widget
                    iEvent = new com.ibm.mm.iwidget.IEventImpl(iwConstants.EVENTS.onNavStateChanged, "json", customParams);//json format
                    this._handleEventInternal(iwConstants.EVENTS.onNavStateChanged, iEvent);
                }
            }
        }
        else {
            if (this.stateData) {
                //find onNavStateChanged in iScope and pass data
                iEvent = new com.ibm.mm.iwidget.IEventImpl(iwConstants.EVENTS.onNavStateChanged, null, this.stateData);//json format/string
                this._handleEventInternal(iwConstants.EVENTS.onNavStateChanged, iEvent);
            }
        }
    },
    _handleOnNavStateChanged: function(iEvent) {
        //widget fire onNavStateChanged event
        if (!this._inIframe()) {
            var state = iEvent.payload;
            if (state) {
                //call navstate api
                var navigationStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
                var widgetAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getWidgetAccessor(navigationStateModel, this.id);
                widgetAccessor.setWidgetState("cp", state); //payload should be string
                var deferred = navigationStateModel.commit();
                deferred.start();
            }
        }
        else {
            var payloadObj = {};
            payloadObj.methodname = "_handleOnNavStateChanged";
            payloadObj.params = [iEvent];
            this.eventSvr._publishEvent(this.eventSvr.WIDGETEVENT_PREFIX + "_stub_" + this.id, payloadObj);
        }
    },
    _initialize: function(callback) {
        var lang = this.widgetDef.getDefaultLanguage() || null;
        if (lang) {
            this.defaultLanguage = lang;
        }
        else {
            this.defaultLanguage = "en";
        }

        var aMode = this._getInitDefaultMode() || null;
        if (!aMode) {
            aMode = iwConstants.mode_view;
        }
        this.currentMode = aMode;
        this._handleSaveMode();
        this._initManagedItemSet();
        this._getShareableItemSets();

        //initialize publishedEvents and handledEvents
        this._getPublicEvents(dojo.hitch(this, function(publicEvents) {
            //register wires
            this.getWires();

            if (callback) {
                callback();
            }
        }));
    },
    getPublicEvent: function(name) {
        var eventModel = this._getPublicEvents();
        return eventModel.find(name);
    },
    _getPublicEvents: function(callback) {
        //Initialize internal eventmodel for iWidgetWrapper, events data are loaded in event model
        //An associative array is passed from widget definition to widgetwrapper
        if (!this.publicEvents) {
            var factory = com.ibm.mashups.services.ServiceManager.getService("WidgetEventModelFactoryService");
            var dfr = factory.createEventModel(this, {context: this, callback: "_eventProviderModeChange",
                unregister: function(handle) {
                    this.unregisterArray.push(handle);
                }
            });

            dfr.setFinishedCallback(dojo.hitch(this, function(eventModel, status){
                this.publicEvents = eventModel;
                if (callback) {
                    callback(this.publicEvents);
                }
            }));
            var sync = (callback)?false:true;
            // Required to make dojotest run synchronously
            if (ibmConfig.dojotest) {
                sync = true;
            }
            dfr.start(sync);
        }
        return this.publicEvents;
    },
    _eventProviderModeChange: function(provider, oldMode, newMode) {
        var oldEventModel = this.publicEvents;
        var factory = com.ibm.mashups.services.ServiceManager.getService("WidgetEventModelFactoryService");
        var dfr = factory.createEventModel(this, {context: this, callback: "_eventProviderModeChange",
            unregister: function(handle) {
                this.unregisterArray.push(handle);
            }
        });

        dfr.setFinishedCallback(dojo.hitch(this, function(eventModel, status){
            this.publicEvents = eventModel;
        }));
        dfr.start(true);

        // now we need to copy all runtime information from the previous persistence layer over. e.g. handlingFunctions
        var condition = {};
        condition.isHandled = "true";
        var oldEvents = oldEventModel.getEvents(condition);
        if (oldEvents) {
            for (var i=0; i < oldEvents.length; i++) {
                var oldEventDesc = oldEvents[i];
                var newEventDesc = this.getPublicEvent(oldEventDesc.name);
                if (oldEventDesc && newEventDesc) {
                    newEventDesc.copyRuntimeProperties(oldEventDesc);
                }
            }
        }
    },
    _getPublishedEvents: function() {
        //Todo:should remove once widgetstub is removed,backward compatibility as part of queryservice
        //return an associative array, with reference
        var publishedEvents = this.getWidgetPublishedEvents() || null;
        var arr = {};
        if (publishedEvents) {
            var i = 0;
            for (i; i < publishedEvents.length; i++) {
                arr[publishedEvents[i].name] = publishedEvents[i];
            }
        }
        return arr;
    },
    _getHandledEvents: function() {
        //Todo: should remove once widgetStub is removed,backward compatibility as part of queryservice
        var handledEvents = this.getWidgetHandledEvents() || null;
        var arr = {};
        if (handledEvents) {
            var i = 0;
            for (i; i < handledEvents.length; i++) {
                arr[handledEvents[i].name] = handledEvents[i];
            }
        }
        return arr;
    },
    getWidgetPublishedEvents: function() {
        //return a reference of event description for backward compatibility so it won't break the use case below
        var eventModel = this._getPublicEvents();
        if (eventModel) {
            var condition = {};
            condition.isPublished = "true";
            return eventModel.getEvents(condition);
        }
        return null;
    },
    getWidgetHandledEvents: function() {
        //return a reference of events array
        var eventModel = this._getPublicEvents();
        if (eventModel) {
            var condition = {};
            condition.isHandled = "true";
            return eventModel.getEvents(condition);
        }
        return null;
    },
    getWires: function() {
        return this.getIWidgetInstance().getWires();
    },
    _handleNewWire: function(iEvent) {
        var payload = iEvent.payload;
        //registerTargets
        var wireModel = this.getIWidgetInstance().getWireModel();
        wireModel.registerTargets(payload.targetWidget, payload.targetEvent, payload.sourceEvent);
        this.commit(); //need to send updates to stub, if it's iframe
        var eventName = payload.sourceEvent; //check if there's onNewWire defined in iEventDescription
        //var event = this.publishedEvents[eventName];
        var eventModel = this._getPublicEvents();
        if (!eventModel) {
            return false;
        }

        var eventDesc = eventModel.find(eventName);
        //need to get original event....
        if (eventDesc) {
            var handler = eventDesc.getOnNewWire();
            if (handler) {
                var scope = this._getHandlerScope(handler);
                if (scope && dojo.isFunction(scope)) {
                    scope(iEvent);
                }
                else if (scope && dojo.isObject(scope)) {
                    scope[handler](iEvent);
                }
                return true;
            }
        }
        return false;
    },
    _handleRemoveWire: function(iEvent) {
        var payload = iEvent.payload;
        var eventName = payload.targetEvent; // check if there's onRemoveWire defined in iEventDescription
        if (this.id == payload.sourceWidget) { //since it could be provided by publish event as well
            eventName = payload.sourceEvent;
        }

        var eventModel = this._getPublicEvents() || null;
        if (!eventModel) {
            return false;
        }

        var eventDesc = eventModel.find(eventName) || null;
        if (eventDesc) {
            var handler = eventDesc.getOnRemoveWire();
            if (handler) {
                var scope = this._getHandlerScope(handler);
                if (scope && dojo.isFunction(scope)) {
                    scope(iEvent);
                }
                else if (scope && dojo.isObject(scope)) {
                    scope[handler](iEvent);
                }
                return true;
            }
        }
        return false;
    },
    _getShareableItemSets: function() {
        if (this.shareableItemSets) {
            return this.shareableItemSets;
        }
        this.shareableItemSets = {};
        this.shareableItemSets.mapping = {};
        this.shareableItemSets.itemsets = {};
        this.shareableItemSets.listeners = {};

        var itemsets = this.widgetDef._getShareableItemSets();
        if (itemsets) {
            var anItemSet = null;
            for (var i in itemsets) {
                if (Object.prototype.hasOwnProperty.call(itemsets, i)) {
                    anItemSet = new com.ibm.mm.iwidget.itemset.ShareableItemSetFactory(this, itemsets[i]);
                    // add default listener if there's any
                    var onItemSetChanged = itemsets[i].onItemSetChanged || null;
                    if (onItemSetChanged) {
                        // if there are no listeners for this itemset yet, let's add them
                        if (!this.shareableItemSets.listeners[i]) {
                            this.shareableItemSets.listeners[i] = [];
                        }
                        this.shareableItemSets.listeners[i].push(anItemSet.addListener(onItemSetChanged));
                    }
                    this.shareableItemSets.itemsets[i] = anItemSet;
                    //alias is optional
                    var alias = itemsets[i].alias || null;
                    if (alias) {
                        this.shareableItemSets.mapping[alias] = alias;
                    }
                }
            }
        }
        return this.shareableItemSets;
    },
    //it could be either local name or real id
    _getShareableItemSet: function(id) {
        var shareableItemSets = this._getShareableItemSets();
        if (shareableItemSets && shareableItemSets.mapping[id]) { //checking alias first
            var realId = shareableItemSets.mapping[id];
            return shareableItemSets.itemsets[realId];
        }
        else if (shareableItemSets && shareableItemSets.itemsets[id]) { //check realid -- local id
            return shareableItemSets.itemsets[id];
        }
        var itemSet = new com.ibm.mm.iwidget.itemset.ShareableItemSetFactory(this.widgetwrapper, null, name);
        shareableItemSets.itemsets[id] = itemSet; //there's no global mapping
        return shareableItemSets.itemsets[id];
    },
    _executeCallbackQueue: function() {
        com.ibm.mashups.services.ServiceManager.getService("resourceLoadService").executeCallbackQueue(this.id);
    },
    _handleSaveMode: function() {
        var navigationStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
        var widgetAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getWidgetAccessor(navigationStateModel, this.id);
        var oldMode = widgetAccessor.getWidgetMode();
        if (oldMode != this.currentMode) {
            // check special case
            if (!((oldMode === null) && (this.currentMode == com.ibm.mm.iwidget.Constants.mode.VIEW))) {
                widgetAccessor.setWidgetMode(this.currentMode); //payload should be string
                var deferred = navigationStateModel.commit();
                deferred.start();
            }
        }
    },
    _transform: function(eventName, iEvent) {
        var event = this.getPublicEvent(eventName);
        if (!(!event || !event.type || !iEvent.type)) {
            var targetEvent = new com.ibm.mm.iwidget.IEventImpl(event.name, event.type, iEvent.payload, null);
            var transformer = new com.ibm.mm.enabler.utils.EventTransformerImpl();
            var newIEvent = transformer._transform(iEvent, targetEvent) || null;
            if (newIEvent) {
                iEvent = newIEvent;
            }
        }
        return iEvent;
    },
    _getModeFromNavStateModel: function() {
        var navigationStateModel = com.ibm.mashups.enabler.model.state.NavigationStateModelFactory.getNavigationStateModel();
        var widgetAccessor = com.ibm.mashups.enabler.model.state.AccessorFactory.getWidgetAccessor(navigationStateModel, this.id);
        return widgetAccessor.getWidgetMode();
    }
});

com.ibm.mm.iwidget.widget.IWidgetWrapperImpl = com.ibm.mm.iwidget.widget.IWidgetWrapperExtendedImpl;

//IMPORTANT
//ibmConfig.enablerLayerModules is a comma separated string of all supported modules at runtime
//This section dynamically loads the Extended representation when the variable enablerLayerModules contains the given module
if ((ibmConfig.enablerLayerModules) && (dojo.indexOf(ibmConfig.enablerLayerModules, "CoreModel") >= 0)) {
 dojo["require"]("com.ibm.mm.enabler.iwidget.widget.IWidgetWrapperModelImpl"); // JSLINT-IGNORE: This needs to be done to allow modularization and to support the layers
}

}

if(!dojo._hasResource["com.ibm.mashups.livetext.CallbackModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.livetext.CallbackModel"] = true;
dojo.provide("com.ibm.mashups.livetext.CallbackModel");

/**
  * This API defines the various callback functions for livetext services. These callback functions should be provided by
  * event publisher.
  *
  * @ibm-api
  * @ibm-module iWidget
  */
dojo.declare("com.ibm.mashups.livetext.CallbackModel", null,
{
	/**
	* The callback function which should be provided to livetext service by the event publisher. This
	* callback function provides a means by the event publisher and for the event publisher to run some code before
	* the HTML fragment is processed. <p />
 	* @param {DOMNode} domNode The DOM node whose decendent nodes to be parsed and processed. May be <code>null</code>.
 	* @param {Object[]} livetextList The list of the live text which will be processed. May be <code>null</code>.
 	* @param {Object} tagEntry The JSON object of the current tag entry used to match and process the returned nodes. Is never <code>null</code>.
 	* @type void
 	*/
	preProcessCallbackFunc: function(/* DOMNode */ domNode, /* Object[] */livetextList, /* Object */ tagEntry) {
	},
	/**
	* The callback function which should be provided to livetext service by the event publisher. This
	* callback function provides a means by the event publisher and for the event publisher to run some code
	* after HTML fragment has been processed. <p />
 	* @param {DOMNode} domNode The DOM node whose decendent nodes to be parsed and processed. May be <code>null</code>.
	* @param {Object[]} livetextList The list of the live text which will be processed. May be <code>null</code>.
 	* @param {Object[]} errors The list of the exceptions occurred during the parsing and node handling process. If
 	* there is no error, an empty array should be provided. May be <code>null</code>.
 	* @param {Object} tagEntry The JSON object of the current tag entry used to match and process the returned nodes. Is never <code>null</code>.
 	* @type void
 	*/
	postProcessCallbackFunc: function(/* DOMNode */ domNode, /* Object[] */livetextList, /* Object[] */ errors, /* Object */ tagEntry) {
	}
});

}

if(!dojo._hasResource["com.ibm.mashups.livetext.ConfigEntry_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.livetext.ConfigEntry_API"] = true;
dojo.provide("com.ibm.mashups.livetext.ConfigEntry_API");
dojo.provide("com.ibm.mashups.livetext.ConfigEntry");

/**
 * This API defines the service model configuration entry
 *
 * @ibm-api
 * @ibm-module iWidget
 */
dojo.declare("com.ibm.mashups.livetext.ConfigEntry", null, {

	/**
	 * Creates a new instance of livetext config entry.
	 *
	 * @param {String} match the CSS3 Selection expression to match a live text. Must not be <code>null</code>.
	 * @param {Boolean} processEnclosedTags should all the nested live text be processed in this request. If true, then all the live text will be processed. If false,
	 * only the out most live text of this type will be processed. May be <code>null</code>.
	 * @param {String} module the module to register the implementation livetextModel under. Must not be <code>null</code>.
	 * @param {String} path the url to load the livetextModel implementation resource file. Must not be <code>null</code>.
	 * @param {String} baseClass the JavaScript class which implement the livetextModel. Must not be <code>null</code>.
	 * @param {Boolean} waitOnPreTag The value of true or false to determine if the service should process this entry defined tags before the process of the previous
     *                  entry defined tags have been completed. The default value is true. <br /> Must not be <code>null</code>.
	 * @param {String} configId a unique id to identify the entry. This is useful in case we have same baseClass as different handlers. configId will be used to find nodes are for which matching criteria.Must not be <code>null</code>.
	 */
	constructor : function(/* String */match, /* Boolean */
			processEnclosedTags, /* String */module,
			/* String */path, /* String */baseClass ,/*Boolean*/ waitOnPreTag,/* String */id) {
	},

	/**
	 * Compare if this configuration entry is same as the given entry.
	 *
	 * @param {com.ibm.mashups.livetext.ConfigEntry} entry The entry to be compared with this entry. Must not be <code>null</code>.
	 * @returns {Boolean} The value indicats if the two entries are the same.
	 */
	isEqual : function(/* ConfigEntry */entry) {
	}
});

}

if(!dojo._hasResource["com.ibm.mm.livetext.ConfigEntryImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.livetext.ConfigEntryImpl"] = true;
dojo.provide("com.ibm.mm.livetext.ConfigEntryImpl");




dojo.declare("com.ibm.mm.livetext.ConfigEntryImpl", com.ibm.mashups.livetext.ConfigEntry, {
    constructor: function(/* String */match, /* Boolean */ processEnclosedTags, /* String */ module,    /* String */
    path, /* String */ baseClass, /*Boolean*/ waitOnPreTag, /* String */id) {
        this.match = match;
        this.wait = waitOnPreTag;
        this.procEnc = processEnclosedTags;
        this.mod = module;
        this.path = path;
        this.baseCls = baseClass;
        this.id = id;
    },
    isEqual: function(/* ConfigEntry */entry) { // Should not we just use configId to check if configentry are equal or not??
        return entry &&
            entry.match == this.match &&
            entry.wait == this.wait &&
            entry.procEnc == this.procEnc &&
            entry.mod == this.mod &&
            entry.path == this.path &&
            entry.baseCls == this.baseCls &&
            entry.id == this.id ;
    }
});

com.ibm.mashups.livetext.ConfigEntry = com.ibm.mm.livetext.ConfigEntryImpl;

}

if(!dojo._hasResource["com.ibm.mashups.livetext.ConfigEntry"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.livetext.ConfigEntry"] = true;
dojo.provide("com.ibm.mashups.livetext.ConfigEntry");





}

if(!dojo._hasResource["com.ibm.mashups.livetext.Exception"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.livetext.Exception"] = true;
dojo.provide("com.ibm.mashups.livetext.Exception");

/**
  * This API defines the exception which can be thrown by the semantic services during the parsing and processing
  *
  * An exceptionId should identify the current exception. It is a 7 character long string which uniquely identifies the
  * current abnormal condition of the parsing and processing. <p />
  *
  * @ibm-api
  * @ibm-module iWidget
  */
dojo.declare("com.ibm.mashups.livetext.Exception", null,
{

	/**
    * Create new instance of livetext service exception. <p />
    *
    * @param {String} exceptionId The exception identifier. Must not be <code>null</code>.
 	* @param {Object} variable The list of the parameters to describe this error condition. May be <code>null</code>. This object must hold all the necessary
 	* values to populate the exception message.  For example, a message may be defined as the following: <p />
 	*
 	* &nbsp;&nbsp;&nbsp;&nbsp;"The node ${id} does not have the necessary attribute ${attribute} or the attribute has unrecongnized values." <p/>
 	* When an exception is throw, the variable object should have members namded "id" and "attribute" respectively. Here is an example of such object <p />
 	*
 	* &nbsp;&nbsp;&nbsp;&nbsp;throw new com.ibm.mashups.livetext.exception('E000001', {'id':100, 'attribute':'DeJaWu'});
	*/
	constructor: function(/* String */exceptionId, /* Object */ variable) {
	},

	/**
	* Retrieve locale specific description by using the status code. This method should not cause any exception. If
	* no locale specific message is found, then an empty string will be returned.
 	* @param {String[]} locales The list of the locales which the locale specific error should be looked up. May be <code>null</code>.
 	* @returns {String} The locale specific exception message.
 	*/
	getMessage: function(/* String[] */ locales) {
	}
});

}

if(!dojo._hasResource["com.ibm.mashups.livetext.LivetextBatchModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.livetext.LivetextBatchModel"] = true;
dojo.provide("com.ibm.mashups.livetext.LivetextBatchModel");

/**
   This is the tag processor API. When a match tag is found by the livetext service according to the configuration, the service
   will hand the all DOM nodes to the tag processor which matches the criteria. Each tag processor must implement this interface. Each processor must also provide a
   non-parameter constructor in addition to the processTag method. The non-parameter constructor is to ensure that the livetext service
   can create an instance of the implementation class without providing any more information. <p />

   @ibm-api
   @ibm-module iWidget
  */
dojo.declare("com.ibm.mashups.livetext.LivetextBatchModel", null,
{
	/**
	* The entry point of a tag processor. When a tag is found, the service will dynamically load the module which was designed to process
	* that type of tags, then create an instance of that tag module class if it has not been created, then call this method and hand the
	* control to the tag module.
 	* @param {DOMNode[]} nodes The livetext DOM nodes to be processed. Must not be <code>null</code>.
 	* @param {com.ibm.mashups.livetext.ConfigEntry} configEntry The configuration enrty for the handler. This will be required in case we have one hanlder for multiple matching criteria <code>null</code>.
 	* @type void
 	*/
	processTag: function(/*DOMNode[]*/nodes, configEntry) {
	},
    /**
    * The entry point of a tag processor (unchanging). When a tag is found, the service will dynamically load the module which was designed to process
    * that type of tags, then create an instance of that tag module class if it has not been created, then call this method and hand the
    * control to the tag module.
    * @param {DOMNode[]} nodes The livetext DOM node to be &quot;unprocessed&quot;. Must not be <code>null</code>.
    * @type void
    */
    unprocessTag: function(/*DOMNode[]*/nodes) {
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.livetext.LivetextModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.livetext.LivetextModel"] = true;
dojo.provide("com.ibm.mashups.livetext.LivetextModel");

/**
   This is the tag processor API. When a match tag is found by the livetext service according to the configuration, the service
   will hand the DOM node to the tag processor. Each tag processor must implement this interface. Each processor must also provide a
   non-parameter constructor in addition to the processTag method. The non-parameter constructor is to ensure that the livetext service
   can create an instance of the implementation class without providing any more information. <p />

   @ibm-api
   @ibm-module iWidget
  */
dojo.declare("com.ibm.mashups.livetext.LivetextModel", null,
{
	/**
	* The entry point of a tag processor. When a tag is found, the service will dynamically load the module which was designed to process
	* that type of tags, then create an instance of that tag module class if it has not been created, then call this method and hand the
	* control to the tag module.
 	* @param {DOMNode} node The livetext DOM node to be processed. Must not be <code>null</code>.
 	* @type void
 	*/
	processTag: function(/*DOMNode*/node) {
	},
    /**
    * The entry point of a tag processor (unchanging). When a tag is found, the service will dynamically load the module which was designed to process
    * that type of tags, then create an instance of that tag module class if it has not been created, then call this method and hand the
    * control to the tag module.
    * @param {DOMNode} node The livetext DOM node to be &quot;unprocessed&quot;. Must not be <code>null</code>.
    * @type void
    */
    unprocessTag: function(/*DOMNode*/node) {
    }
});

}

if(!dojo._hasResource["com.ibm.mashups.livetext.ServiceModel_API"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.livetext.ServiceModel_API"] = true;
dojo.provide("com.ibm.mashups.livetext.ServiceModel_API");
dojo.provide("com.ibm.mashups.livetext.ServiceModel");






/**
   The livetext (formally known as semantic tag) service API. The implementation class of this API provides the livetext parsing services
   so that tags on a page can be recognized and processed according to the tagservice.entries.cfg
   configuration file. An instance of this API implementation class should be created after a page is fully loaded.
   Once the instance is created, the init method should be called so that the tags will be parsed. Each tag processor
   will be invoked to process the tags in order of the tags defined in the tagservices.entries.cfg file. There should be no more
   than 1 instance of this class on each page.

   The implementation of this API should subscribe to one of the following two event topics.<p/>

   &nbsp;&nbsp;&nbsp;"/com/ibm/mashups/livetext/livetextchanged" <p />

   &nbsp;&nbsp;&nbsp;"/com/ibm/mashups/livetext/livetextcontentchanged" <p />

   Once an event is published to that topic, the implementation of this API should start using the given DOM node and processing all the
   decendant DOM nodes of that given node. That given node itself will not be processed. Event livetextchanged will cause the passed node and
   all its children to be parsed. Event livetextcontentchanged will cause only the passed node children to be parsed. <p />

   If a component wishes for a piece of markup fragment being processed, that component should publish an event to that topic, that event
   should also come with the DOM node which holds that piece of the markup fragment, callback functions and a flag to indicate how to proceed
   when an exception is thrown. The DOM node, flag and the callback functions are referred to event data below.<p />

   The event data must be an array of objects in the following format.<p />

   &nbsp;&nbsp;&nbsp;[domNode, continueAfterException, preProcessCallbackFunc, postProcessCallbackFunc] <p/>

   The first object in the event data array is the root node of the HTML markup fragment. If that object is not a valid DOM node, then no action
   will be taken. The second object in the array is a flag to indicate if the parsing should continue when an exception is caught. The third and
   the last object in the array are two callback functions. The preProcessCallbackFunc will be invoked before the parsing process starts, the
   postProcessCallbackFunc will be invoked after the parsing process finished. If none callback function is provided by the array, then no function
   will be invoked. The default value for continueAfterException flag is false. <p/>

   If the node needs to be processed and the both pre and post process callback exist, then the call should look like this.<br /> <br />
   &nbsp;&nbsp;&nbsp;dojo.publish("/com/ibm/mashups/livetext/livetextchanged", <br />
   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[aDOMNode, false, callbackFunc1, callbackFunc2]); <br /><br />

   If all the nodes on the page need to be processed, and no callback functions are needed, then the call should look like this.<br/><br/>
   &nbsp;&nbsp;&nbsp;dojo.publish("/com/ibm/mashups/livetext/livetextchanged", <br />
   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[document, true]); <br /><br />

   If the node in the event data is not a valid node, then the event will be ignored. Before a given DOM node being processed,
   The preProcesCallbackFunc will be called. After the given DOM node has been processed, the postProcessCallbackFunc will be called.
   If preProcessCallbackFunc or postProcessCallbackFunc is not null, then the callback function is guaranteed to be invoked regardless
   the status of the tag parsing process. The given DOM node is considered as the root node of given HTML fragment. All its decendent
   child DOM nodes will be parsed. To make the process effecient, components should avoid passing the entire Document as the given DOM
   node unless it is the very first time.<p />

   Tag service configuration. <p/>
   This section describes the specific implementation of the IBM Lotus Mashups livetext services implementation.  The tag matching
   method is not defined, it is up to the tag service implementation to define their own match method and tag processing invoke sequence.<p />

   Tags can be nested, this tag service can be configured to process nested tags or leave the nested tags to the container to
   process. <p />

   This service is configurable by providing a configuration file. The configuration file should be located at the same location
   where the tag service API implementation class is. The configuration file is simply a JSON type of code. It defines tags that this service can process. The
   following is an example of this file. <p />

   &nbsp;&nbsp;&nbsp;[<br/>
   &nbsp;&nbsp;&nbsp;{"match":"*.iWidgetSkin[skin]","processEnclosedTags":true,'waitOnPreTag':true,<br/>
   &nbsp;&nbsp;&nbsp;&nbsp;"module":"tagservices", "path":"../../tagservices", "baseClass":"tagservices.skins"},<br/>
   &nbsp;&nbsp;&nbsp;{"match":"*.iw-iWidget","processEnclosedTags":false,'waitOnPreTag':false,<br/>
   &nbsp;&nbsp;&nbsp;&nbsp;"module":"tagservices", "path":"../../tagservices", "baseClass":"tagservices.widgets"}<br/>
   &nbsp;&nbsp;&nbsp;] <p />

   Each entry in this file presents a type of tags that this service can process. The order of these entries in the configuration
   file is important because the service will process the tags in this order. <p />

   Each entry should have the following element. <p />
   "match":  The CSS3 format for tag attribute match value. The value of this element determines if a tag should be processed by the services. This can now be a comma seperated values. In case comma seperated values are specified, nodes matching each of them will be merged<br/>
   "processEnclosedTags":  The value of true or false to determine if the service should process the nested tag. The default value is false.<br />
   "waitOnPreTag":  The value of true or false to determine if the service should process this entry defined tags before the process of the previous
   entry defined tags have been completed. The default value is true. <br />
   "module":  The implementation JavaScript module. This is required. <br />
   "path":  The path to the JavaScript implementation of the tag processor. This should be a URI to the JavaScript resource. This is required. <br />
   "baseClass":  The class which implement the tag processor API. <br />
   "id" a unique id to identify the entry. This is useful in case we have same baseClass as different handlers. id will be used to find nodes are for which matching criteria.Can be <code>null</code><br />

   Livetext service also provide a way for other components to dynamically add or remove a configuration entry. The addition or removal of the entries
   will not be persisted. It will only affect the current session. <br />

   If an entry needs to be added, then a component should publish to this topic with
   an entry.<br>

	&nbsp;&nbsp;&nbsp;"/com/ibm/mashups/livetext/configentryadded" <p />

   If an entry needs to be removed, then a component should publish to this topic with
   an entry.<br>

	&nbsp;&nbsp;&nbsp;"/com/ibm/mashups/livetext/configentryremoved" <p />

   @ibm-api
   @ibm-module iWidget
  */
dojo.declare("com.ibm.mashups.livetext.ServiceModel", null,
{
	/**
     * The service name to be used to fetch the service from the ServiceManager
     * @type String
     */
    SERVICE_NAME: "livetextService",

	/**
    * Initiate the tag service. This should be only called once after a page is completely loaded.
    * Normally it should be added to the document onload method. This method should initialize the
    * tag service which includes load the tag configuration and start parsing tags for the entire page.
    * @param {Object} initArgs Optional JSON object that defines initialization properties for the live text service.
    * May be <code>null</code>.  Currently supports these properties on the JSON object:</br>
	* { <br/>
	* &nbsp;&nbsp;&nbsp;&nbsp;<code>node</code>: The DOM node whose decendent nodes will be parsed and processed. Applies only to the initial parse. May be <code>null</code>.<br/>
	* &nbsp;&nbsp;&nbsp;&nbsp;<code>continueAfterException</code>: The flag to indicate if the service should continue the parsing and processing after an exception is caught. Applies only to the initial parse. May be <code>null</code>.<br/>
	* &nbsp;&nbsp;&nbsp;&nbsp;<code>preProcessCallbackFunc</code>: The callback function being called before nodes are processed for a particular tag. Applies only to the initial parse. May be <code>null</code>.<br/>
	* &nbsp;&nbsp;&nbsp;&nbsp;<code>postProcessCallbackFunc</code>: The callback function being called after nodes are processed for a particular tag. Applies only to the initial parse. May be <code>null</code>.<br/>
	* }<br/>
    * @type void
 	*/
	init: function(/* Object */ initArgs) {
	},

	/**
	* Tag changed event handler.  This handler will parse the passed in tag and all its children to be parsed.
 	* @param {DOMNode} domNode The DOM node whose decendent nodes to be parsed and processed. May be <code>null</code>.
 	* @param {boolean} continueAfterException The flag to indicate if the service should continue the parsing and processing after an exception is caught.
 		If this parameter is missing, the default is false. May be <code>null</code>.
 	* @param {com.ibm.mashups.livetext.CallbackModel.preProcessCallbackFunc} preProcessCallbackFunc The callback function being called before a node being processed. May be <code>null</code>.
 	* @param {com.ibm.mashups.livetext.CallbackModel.postProcessCallbackFunc} postProcessCallbackFunc The callback function being called after the a node being processed. May be <code>null</code>.
 	* @type void
 	*/
	onTagChanged: function(/* DOMNode */ domNode,
						   /* boolean */ continueAfterException,
						   /* com.ibm.mashups.livetext.CallbackModel.preProcessCallbackFunc */ preProcessCallbackFunc,
						   /* com.ibm.mashups.livetext.CallbackModel.postProcessCallbackFunc */ postProcessCallbackFunc) {

	},
    /**
    The event handler when a tag and/or its content should be removed.
    @param {DOMNode} node the root node which will be parsed.
    @param {Boolean} continueAfterException a flag indicate if the process should continue when error occurrs.
    @param {Function} preProcessCallback the callback function which will be called before nodes being processed.
    @param {Function} postProcessCallback the callback function which will be called after nodes being processed.
    @param {Function} postUnProcessCallbcak the callback function which will be called after the content is unchanged.
    @type void
    */
    onUnchangeTag: function(node, continueAfterException, preUnProcessCallback, postUnProcessCallback, unchangeCompleteCallback) {
    },
	/**
	* Tag content changed event handler. This handle will parsed all the passed in tag content to be parsed.
 	* @param {DOMNode} domNode The DOM node whose decendent nodes to be parsed and processed. May be <code>null</code>.
 	* @param {boolean} continueAfterException The flag to indicate if the service should continue the parsing and processing after an exception is caught.
 		If this parameter is missing, the default is false. May be <code>null</code>.
 	* @param {com.ibm.mashups.livetext.CallbackModel.preProcessCallbackFunc} preProcessCallbackFunc The callback function being called before a node being processed. May be <code>null</code>.
 	* @param {com.ibm.mashups.livetext.CallbackModel.postProcessCallbackFunc} postProcessCallbackFunc The callback function being called after the a node being processed. May be <code>null</code>.
 	* @type void
 	*/
	onTagContentChanged: function(/* DOMNode */ domNode,
						   /* boolean */ continueAfterException,
						   /* com.ibm.mashups.livetext.CallbackModel.preProcessCallbackFunc */ preProcessCallbackFunc,
						   /* com.ibm.mashups.livetext.CallbackModel.postProcessCallbackFunc */ postProcessCallbackFunc) {

	},

	/**
	* The method allows component dynamically add a new configuration entry so that the service can start process the tags presented
	* by the entry.
	* @param {com.ibm.mashups.livetext.ConfigEntry} entry The entry that should be added to the configuration. Must not be <code>null</code>.
	* @param {boolean} bFront The flag to indicate if the entry should be added to the front of the configuration array or not. true for front, false for end. Default is false for end.
	* @type void
	*/
	onAddConfigEntry: function(/* com.ibm.mashups.livetext.ConfigEntry */ entry, bFront) {
	},

	/**
	* This method allows components dynamically remove a configuration entry so that the service will not process that type of tags which
	* are presented by the configuration entry.
	* @param {com.ibm.mashups.livetext.ConfigEntry} entry The entry that should be removed from the configuration. Must not be <code>null</code>.
	* @type void
	*/
	onRemoveConfigEntry: function(/* com.ibm.mashups.livetext.ConfigEntry */ entry) {
	}
});

com.ibm.mashups.livetext.ServiceModel.SERVICE_NAME = com.ibm.mashups.livetext.ServiceModel.prototype.SERVICE_NAME;


}

if(!dojo._hasResource["com.ibm.mm.livetext.ServiceModelImpl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mm.livetext.ServiceModelImpl"] = true;
dojo.provide("com.ibm.mm.livetext.ServiceModelImpl");



// inject this service into the ServiceManager at the end. Therefore we have to require the implementation


dojo.declare("com.ibm.mm.livetext.ServiceModelImpl", com.ibm.mashups.livetext.ServiceModel,
{
    _initialized:false,
    _tagTypes:null,
    _rootContainer: null,
    tagChanged:"/com/ibm/mashups/livetext/livetextchanged",
    unchangeTag: "/com/ibm/mashups/livetext/livetextunchange",
    tagStatusChange: "/com/ibm/mashups/livetext/livetextchanged",
    tagContentChanged: "/com/ibm/mashups/livetext/livetextcontentchanged",
    entryAdded: "/com/ibm/mashups/livetext/configentryadded",
    entryRemoved: "/com/ibm/mashups/livetext/configentryremoved",

    constructor:function(){
        if (com.ibm.mm.livetext.ServiceModelStatic) {
            console.warn("WARNING: Do not create the LiveText Framework multiple times!");
            return;
        }
        com.ibm.mm.livetext.ServiceModelStatic = true;
        dojo.subscribe(this.entryAdded, this, "onAddConfigEntry");
        dojo.subscribe(this.entryRemoved, this, "onRemoveConfigEntry");
    },

    /**
    Initiate the tag service. This should be only called once after a page is completed loaded.
    Load the livetext configuration by calling loadTags method.<b>
    Subscribe to two event topics and prepare to catch events fired by other components.
    Publish the content changed event and start the entire document parsing.
    @returns
    */
    init: function(initArgs) {
        if (this._initialized) {
            console.warn("WARNING: Do not initialize the LiveText Framework multiple times!");
            return;
        }
        this._initialized = true;
    	if(!initArgs) {
    		initArgs = {};
    	}
        this._loadTags(initArgs);
        dojo.subscribe(this.tagChanged, this, "onTagChanged");
        dojo.subscribe(this.unchangeTag, this, "onUnchangeTag");
        dojo.subscribe(this.tagContentChanged, this, "onTagContentChanged");
        dojo.publish(this.tagContentChanged, [initArgs.node || document, ("continueAfterException" in initArgs) ? initArgs.continueAfterException : true, initArgs.preProcessCallbackFunc, initArgs.postProcessCallbackFunc]);
    },

    /**
    The core method to query the match tags according to the matching condition defined as CSS3 selection expression.
    If the type of the tag is defined to query the enclosed tag, then simply do one dojo query and return all the nodes.<b>
    If the type of the tag is defined to query tags excluding the enclosed tags, then two query will be performed, the offset
    of the two query results will be returned. The first query gets all the tags, the second query gets the tags which has nested
    tag inside, then the difference of the two results will be returned.
    @param {DOMNode} node the root node which will be parsed.
    @param {Object} tagType a tag type which maps to one of the configuration entries.
    @returns {Array} list of the matching tags.
    */
    _getNodes: function(node, tagType) {
	    var k = [];
	    if ( tagType == "undfined" || !tagType) {
	       console.error("Why are we having tagType undefined ::::");
	       return k;
	    }
	    // handle for tagType.match having multiple option

        var aNodeList;
        var a;
		var matchEntry = 0;
        if (tagType.processEnclosedTags != "undefined" && tagType.processEnclosedTags) {
			var tagTypeMatch = tagType.match;
            a = [];
            aNodeList = dojo.query(tagTypeMatch, node);
	        aNodeList.forEach(function(node, index, nodeList){
	            a.push(node);
	        });// JSLINT-IGNORE: Enabler Team decided to keep this paradigma from dojo in tact

            return a;
        }
        else {
			var tagTypeMatchArray = tagType.match.split(",");
            a = [];
            var b = [];
            for ( matchEntry = 0, l = tagTypeMatchArray.length; matchEntry < l ; matchEntry++ ) {
                aNodeList = dojo.query(tagTypeMatchArray[matchEntry] +' ' + tagTypeMatchArray[matchEntry], node);
                aNodeList.forEach(function(node, index, nodeList){
                        a.push(node);
                });// JSLINT-IGNORE: Enabler Team decided to keep this paradigma from dojo in tact
                var bNodeList = dojo.query(tagTypeMatchArray[matchEntry], node);
                bNodeList.forEach(function(node, index, nodeList){
                b.push(node);
                });// JSLINT-IGNORE: Enabler Team decided to keep this paradigma from dojo in tact
            }
            var anItem, bIndex;
            while (a.length > 0) {
                anItem = a[0]; bIndex = 0;
                while (bIndex < b.length) {
                    if (anItem == b[bIndex]) {
                        a.splice(0,1); b.splice(bIndex, 1);
                        break;
                    }
                    else {
                        bIndex++;
                    }
                }
            }
            return b;
        }
    },

    /**
    The event handler when a tag and/or its content get changed.
    @param {DOMNode} node the root node which will be parsed.
    @param {Boolean} continueAfterException a flag indicate if the process should continue when error occurrs.
    @param {Function} preProcessCallback the callback function which will be called before nodes being processed.
    @param {Function} postProcessCallback the callback function which will be called after nodes being processed.
    @returns
    */
    onTagChanged: function(node, continueAfterException, preProcessCallback, postProcessCallback) {
        var tag = null;
        for (var index=0, l = this._tagTypes.length; index<l;index++) {
            tag = this._tagTypes[index];
            this._processTypeTag(node,tag, continueAfterException, preProcessCallback, postProcessCallback, true);
        }
    },
    /**
    The event handler when a tag and/or its content should be removed.
    @param {DOMNode} node the root node which will be parsed.
    @param {Boolean} continueAfterException a flag indicate if the process should continue when error occurrs.
    @param {Function} preProcessCallback the callback function which will be called before nodes being processed.
    @param {Function} postProcessCallback the callback function which will be called after nodes being processed.
    @param {Function} postUnProcessCallbcak the callback function which will be called after the content is unchanged.
    @returns
    */
    onUnchangeTag: function(node, continueAfterException, preUnProcessCallback, postUnProcessCallback, unchangeCompleteCallback) {
        var tag = null;
        for (var index=0, l = this._tagTypes.length; index<l;index++) {
            tag = this._tagTypes[index];
            this._unprocessTypeTag(node,tag, continueAfterException, preUnProcessCallback, postUnProcessCallback, false);
        }

        if (dojo.isFunction(unchangeCompleteCallback)) {
            unchangeCompleteCallback(node);
        }
    },

    /**
    The event handler when a tag content gets changed. The passed in DOM node will not be processed. Only its child nodes
    will be processed.
    @param {DOMNode} node the root node which will be parsed.
    @param {Boolean} continueAfterException a flag indicate if the process should continue when error occurrs.
    @param {Function} preProcessCallback the callback function which will be called before nodes being processed.
    @param {Function} postProcessCallback the callback function which will be called after nodes being processed.
    @returns
    */
    onTagContentChanged: function(node, continueAfterException, preProcessCallback, postProcessCallback){
        var tag = null;
        for (var index=0, l = this._tagTypes.length; index<l;index++) {
            tag = this._tagTypes[index];
            this._processTypeTag(node,tag, continueAfterException, preProcessCallback, postProcessCallback, false);
        }
    },

    /**
    Once a type of tags have been found, each of the same type of tags will be processed by that type of the tag processor
    class defined in the configuration. If that type of the tag processor class has not been loaded, then the tag processor will
    be loaded and a new instance of that class will be created.
    After tag processor is created, this method will check if the passed in node should be included according to the includeRoot parameter.<b>
    If the passed in node should be included, then the check the node against the matching condition. If condition is met, then the node will
    be included in the list of the tags being processed individually. Otherwise, only the matching tags will be processed.<b>
    Before each tag is being processed, the preProcessCallBack function will be called. All the tags found will be passed into this callback function
    The loop in the middle of the method go through each tag in the list, using the tag processor to process each individual tag.<b>
    After entire tags in the list get processed, the postProcessCallback function get called with exceptions which might have occurred.<b>
    @param {DOMNode} node the root node which will be parsed.
    @param {Object} tag the tag type entry object from the configration.
    @param {Boolean} continueAfterException a flag indicate if the process should continue when error occurrs.
    @param {Function} preProcessCallback the callback function which will be called before nodes being processed.
    @param {Function} postProcessCallback the callback function which will be called after nodes being processed.
    @param {Boolean} includeRoot the flag indicate if the passed in node should be included in the process. This flag is used to differiate
    the event tag changed from tag content changed.
    @returns
    */
    _processTypeTag:function(node, tag, continueAfterException, preProcessCallback, postProcessCallback, includeRoot) {
    // if tag does not have baseClass there is no point going forward.
        tag = tag || null;
        if (tag === null) {
			return;
		}
        var nodes = [];
        if (includeRoot && this._checkRoot(node, tag)) {
            nodes[0] = node;
        }

        nodes = nodes.concat(this._getNodes(node, tag));
        var id = tag.id || null;
        if (id === null) {
			id = "";
		}
        var tagsforcallbackfunc = [];
        tagsforcallbackfunc = tagsforcallbackfunc.concat(nodes);

        if (tagsforcallbackfunc.length > 0) {
            tag.loaded = tag.loaded || null;
            if (tag.loaded === null){
                this._loadTagHandler(tag);
            }
            var errors = [];
            if (dojo.isFunction(preProcessCallback)) {
                try {
                    preProcessCallback(node, tagsforcallbackfunc, tag);
                } catch (error1) {
                    console.debug(error1);
                }
            }

            if ( tag.tagHandler instanceof  com.ibm.mashups.livetext.LivetextBatchModel ) {
				try {
					tag.tagHandler.processTag(nodes, tag);
				} catch(error){
                    errors[errors.length] = error;
                }
			} else {
                for (var index0=0, l = nodes.length; index0<l;index0++) {
                    try {
                        tag.tagHandler.processTag(nodes[index0]);
                    } catch (error2) {
                        errors[errors.length] = error2;
                        if (continueAfterException) {
                            break;
                        }
                    }
                }
            }
            if (dojo.isFunction(postProcessCallback)) {
                try {
                    postProcessCallback(node, tagsforcallbackfunc, errors, tag);
                } catch (error3) {
                    console.debug(error3);
                }
            }
        }
    },
    _unprocessTypeTag: function (node, tag, continueAfterException, preUnProcessCallback, postUnProcessCallback, includeRoot) {
        var tags = [];
        if (includeRoot && this._checkRoot(node, tag)) {
            tags[0] = node;
        }

        tags = tags.concat(this._getNodes(node, tag));

        var tagsforcallbackfunc = [];
        tagsforcallbackfunc = tagsforcallbackfunc.concat(tags);

        var errors = [];
        if (dojo.isFunction(preUnProcessCallback)) {
            try {
                preUnProcessCallback(node, tagsforcallbackfunc, tag);
            } catch (error1) {
                console.debug(error1);
            }
        }

        if (tagsforcallbackfunc.length > 0) {
            tag.loaded = tag.loaded || null;
            if (tag.loaded === null){
                this._loadTagHandler(tag);
            }

            if (tag.tagHandler instanceof com.ibm.mashups.livetext.LivetextBatchModel) {
                try {
                    tag.tagHandler.unprocessTag(nodes, tag);
                }
                catch (error2) {
                    errors[errors.length] = error2;
                 }
            } else {
                for (var index0=0, l = tags.length; index0<l;index0++) {
                    try {
                        tag.tagHandler.unprocessTag(tags[index0]);
                    } catch(error3) {
                        errors[errors.length] = error3;
                        if (continueAfterException) {
                            break;
                        }
                    }
                }
            }
        }

        if (dojo.isFunction(postUnProcessCallback)) {
            try {
                postUnProcessCallback(node, tagsforcallbackfunc, errors, tag);
            } catch (error4) {
                console.debug(error4);
            }
        }
    },
    /**
    The method to check individual node to see if the passed in node meet a given tag matching condition. If it does, then
    a value of true will be returned, otherwise a value of false will be returned.
    @param {DOMNode} node the DOM node to check with
    @param {Object} tag the tag type object
    @returns {Boolean} the value which indicate if the node meet the matching condition.
    */
    _checkRoot:function(node, tag) {
        var shouldInclude = false;
        node = node || null;
        if (node !== null && node.nodeType) {
            var copy = {};
            if(!this._rootContainer) {
                this._rootContainer = dojo.create("div", {
                    style: {
                        display: "none"
                    }
                }, dojo.body());
            }
            copy.copyNodeParent = document.createElement("div");
            this._rootContainer.appendChild(copy.copyNodeParent);
            copy.copyOfNode = node.cloneNode(false);
            copy.copyNodeParent.appendChild(copy.copyOfNode);
            copy.result = this._getNodes(copy.copyNodeParent, tag);
            copy.result = copy.result || null;
            if (copy.result !== null && copy.result.length > 0) {
                shouldInclude = true;
            }
            dojo.destroy(copy.copyOfNode);
            dojo.destroy(copy.copyNodeParent);
            delete copy.copyOfNode;
            delete copy.copyNodeParent;
            delete copy.result;
        }
        return shouldInclude;
    },

    /**
    This method will load the livetext framework configuration. It will first check if a livetextCfg global variable exists,
    if it does, then it assume that the global variable is the list of the tag configuration entries. This is to improve the performance
    and assume that the bootstrap will create a such javascript object.<b>
    If it does not exist, then it will load from a configuration file. The configuration file is assumed at the same location where
    this file is located. The format of this file is defined as the following

      &nbsp;&nbsp;&nbsp;[<br/>
    &nbsp;&nbsp;&nbsp;{"match":"*.iWidgetSkin[skin]","processEnclosedTags":true,'waitOnPreTag':true,<br/>
    &nbsp;&nbsp;&nbsp;&nbsp;"module":"tagservices", "path":"../../tagservices", "baseClass":"tagservices.skins"},<br/>
    &nbsp;&nbsp;&nbsp;{"match":"*.iw-iWidget","processEnclosedTags":false,'waitOnPreTag':false,<br/>
    &nbsp;&nbsp;&nbsp;&nbsp;"module":"tagservices", "path":"../../tagservices", "baseClass":"tagservices.widgets"}<br/>
    &nbsp;&nbsp;&nbsp;] <p />

     match, the value of the match is the CSS3 selection expression which presents a tag (livetext) matching condition.<b>
     processEnclosedTags, the boolean value to indicate if the enclosed same tag should be presented in this query. a value of true will cause
     all the tags to be processed. a value of false will make the outmost tags to be processed.<b>
    waitOnPreTag, this is not used for 1.1, it is for the future release.
    module, the string value to indicate a javascript module which the tag processor should be loaded against.
    path, the string value to indicate the processor javascript resources.<b>
    baseClass, the javascript class for the tag processor.
     @returns
    */
    _loadTags:function() {
        this._tagTypes = this._tagTypes || null;
        if (this._tagTypes === null) {
            var thisObj = this;
            if (ibmConfig.livetextService) {
                //if we have the livetext configuration exists as a global variable which is loaded by the bootstrap,
                //then we will simply use it. otherwise, we load from the configuration file.
                this._tagTypes = ibmConfig.livetextService;
            }
            else {
                dojo.xhrGet({
                    url: dojo.moduleUrl("com.ibm.mm.livetext", "tagservice.entries.cfg"),
                    handleAs: "text",
                    sync: true,
                    load:function(result) {
                        thisObj._tagTypes = dojo.fromJson(result);
                    },
                    error:function(data) {
                        console.dir(data);
                    }
                });
            }
        }
    },

    /**
    * @param {com.ibm.mashups.livetext.ConfigEntry} entry The entry that should be added to the configuration.
	* @param {boolean} bFront The flag to indicate if the entry should be added to the front of the configuration array or not. true for front, false for end. Default is false for end.
    * @returns
     * @throws The sermantic tag service exception.
    */
    onAddConfigEntry: function(/* com.ibm.mashups.livetext.ConfigEntry */ cfgEntry, bFront) {
        this._loadTags();
        if(!dojo.some(this._tagTypes,
            function(entry){
                return cfgEntry.isEqual(entry);
            })) {
        	if (bFront) {
	            this._tagTypes.unshift({
	                "match":cfgEntry.match,
	                "processEnclosedTags":cfgEntry.procEnc,
	                'waitOnPreTag':cfgEntry.wait,
                    "module":cfgEntry.mod,
	                "path":cfgEntry.path,
	                "baseClass":cfgEntry.baseCls,
	                "id":cfgEntry.id}
              );
        	} else {
	            this._tagTypes.push({
	                "match":cfgEntry.match,
	                "processEnclosedTags":cfgEntry.procEnc,
	                'waitOnPreTag':cfgEntry.wait,
	                "module":cfgEntry.mod,
	                "path":cfgEntry.path,
	                "baseClass":cfgEntry.baseCls,
	                "id":cfgEntry.id}
              );
        	}
        }
    },

    /**
    * @param {com.ibm.mashups.livetext.ConfigEntry} entry The entry that should be removed from the configuration.
    * @returns
     * @throws The sermantic tag service exception.
    */
    onRemoveConfigEntry: function(/* com.ibm.mashups.livetext.ConfigEntry */ entry) {
        this._loadTags();
        for(var i=0; ; i<this._tagTypes.length) {
            if (entry.isEqual(this._tagTypes[i])) {
                this._tagTypes[i].splice(i, 1);
            }
            else {
                i++;
            }
        }
    },

    /**
    This method is to provide a fall back for backfoward compatibility. If a component is still using the SemTagSvc.parseDom method,
    this method will still ensure the correctness of that component but it is strongly recommended to use the event model.
     * @param {Object} event Not used.
     * @param {DOMNode} node The dom node to be processed.
       @deprecated this methid has been deprecated. Use the publish event to invoke the process of the tags.
       @returns
     */
    parseDom:function(aEvent, node) {
        dojo.publish(this.tagChanged, [node]);
    },

    /**
    This method will register the tag processor module, then load the processor module and create an instance of base class.<b>
    After the tag processor is created, the flag on the tag type object will be set to true. This ensures that each tag processor will
    only have one instance and the module will be loaded only once.
    @param {Object} tag, the tag configuration entry.<b>
    @returns
    */
    _loadTagHandler:function(tag) {
         try {
             dojo.registerModulePath(tag.module, tag.path);
             dojo["require"](tag.baseClass); // JSLINT-IGNORE: array notation needed because otherwise gets stripped by shrinksafe
             var jsonStr = "{create:function(){return new " + tag.baseClass + "()}}";
             var classCreator = dojo.fromJson(jsonStr);
             tag.tagHandler = classCreator.create();
             tag.loaded = true;
         } catch(e)  {
         }
    }
});

com.ibm.mashups.services.ServiceManager.setService(com.ibm.mashups.livetext.ServiceModel.SERVICE_NAME, "com.ibm.mm.livetext.ServiceModelImpl");

}

if(!dojo._hasResource["com.ibm.mashups.livetext.ServiceModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.mashups.livetext.ServiceModel"] = true;
dojo.provide("com.ibm.mashups.livetext.ServiceModel");





}

if(!dojo._hasResource["tagservices.skins"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["tagservices.skins"] = true;
dojo.provide("tagservices.skins");

dojo.provide("com.ibm.mm.livetext.skins");
/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget
 */





/*
 Each skin should have a skin.html and skin.js file.
 skin.html file serves as a template with desirable variables. As a skin developer, you may
 define any number of variables for you to use as long as you setup the variable correctly
 in the process function which is defined in skin.js
 skin.js file is a json string file, it defines all the variables in the skin.html and how they should be created.
 In this file, function process can be defined as follows:
 process:function(skinId,tagId) {
 }
 this function will be called to form all the variables which are used in the skin.html.
 you may have variables in skin.html file like this
 ${var01}
 ${var02}
 When you have these, you will have to define these two variables with correct values. Of course,
 in process function, you have chance to set these variables to other values. Since function process
 will be given two objects, one is the skinId and the other is the tagId (widget id normally), so
 a lot of action can be taken to set up all necessary variables.
 There are two variable that you can use in the skin.html file, but you must not provide the value for,
 these two variables are
 ${widgetBody}
 ${skinId}
 Even if you provide values for these two variables, they will be overwritten;
 */
dojo.declare("tagservices.skins", null, {
    skinIdPrefix: "mm_ibm_skin_",
    allSkins: [],
    allVars: [],
    tempSkinHtmlObj: null,
    tempSkinJsObj: null,

    isProcessing: 0,
    waitingList: [],
    subscribeHandler: null,
    skinAttachEvent: "/skinservice/attachEnd",

    processTag: function(tag) {
        this.tempSkinHtmlObj = {};
        this.tempSkinJsObj = {};
        if (!tag) {
            return;
        }
        var skinId = tag.getAttribute("skin");
        this._getSkinTemplate(skinId, tag);
    },
    unprocessTag: function(tag) {
        var skinNode = this._findSkinNode(tag);
        var contentNode = skinNode.parentNode;

        contentNode.insertBefore(tag, skinNode);
        com.ibm.mm.enabler.utils.Dom.destroyNode(skinNode);
    },
    _findSkinNode: function(node) {
        var tempNode = node;
        while (tempNode && tempNode.id != this.skinIdPrefix + node.id) {
            tempNode = tempNode.parentNode;
        }

        return tempNode;
    },
    _getSkinTemplate: function(skinId, tag) {
        var aSkin = this.allSkins[skinId];
        if (!aSkin) {
            var thisObj = this;
            var skinMarkupURL = this._getSkinResourceUrl(skinId, "skin.html");
            var skinVarURL = this._getSkinResourceUrl(skinId, "skin.js");
            dojo.xhrGet({
                url: skinMarkupURL,
                handleAs: "text",
                sync: true,
                load: function(htmlData) {
                    dojo.xhrGet({
                        url: skinVarURL,
                        handleAs: "json",
                        sync: true,
                        load: function(jsData) {
                            // remove the copyright in the skin.html
                            htmlData = htmlData.replace(/<!--.*-->\s*/, "");
                            thisObj.allSkins[skinId] = htmlData;
                            thisObj.allVars[skinId] = jsData;
                            thisObj.startAttatchSkin(skinId, tag);
                        },
                        error: function(data) {
                            thisObj.allSkins[skinId] = htmlData;
                            thisObj.startAttatchSkin(skinId, tag);
                        }
                    });
                },
                error: function(data) {
                }
            });
        }
        else {
            this.startAttatchSkin(skinId, tag);
        }
    },

    startAttatchSkin: function(skinId, tag) {
        if (this.isProcessing === 0) {
            this.executeReplaceSkin(skinId, tag);
        }
        else {
            this.addToWaitingList(skinId, tag);
        }
    },

    chooseNext: function() {
        if (this.waitingList.length !== 0) {
            var theObject = this.waitingList.pop();
            this.executeReplaceSkin(theObject.skin, theObject.tag);
        }
    },

    addToWaitingList: function(skinId, tag) {
        if (!this.subscribeHandler) {
            this.subscribeHandler = dojo.subscribe(this.skinAttachEvent, this, "chooseNext");
        }
        var waitObj = {};
        waitObj.skin = skinId;
        waitObj.tag = tag;
        this.waitingList.push(waitObj);
    },

    executeReplaceSkin: function(skinId, tag) {
        this.isProcessing = 1;
        var temp = this.allSkins[skinId];

        if (temp) {
            var nodeToReplace = this._getNodeToReplace(tag);
            var parentNode = nodeToReplace.parentNode;
            var anId = dojox.uuid.generateRandomUuid().replace(/\-/g, "");
            var args = this._getArgs(skinId, tag, anId);

            if (!args) {
                return;
            }

            var skinCssURL = this._getSkinResourceUrl(skinId, "skin.css");
            com.ibm.mm.builder.utils.htmlUtil.loadCss(skinCssURL);

            if (builderConfig.isBidi) { //if language is rtl, load the rtl css
                var skinRtlCssURL = this._getSkinResourceUrl(skinId, "skin_rtl.css");
                com.ibm.mm.builder.utils.htmlUtil.loadCss(skinRtlCssURL);
            }

            var newMarkup = dojo.string.substitute(temp, args);
            newMarkup = newMarkup.replace(/\/>/g, "><\/div>");

            var newNode = this._getNodeFromMarkup(newMarkup);
            dojo.addClass(newNode, "mumWidgetTitleBar");

            parentNode.replaceChild(newNode, nodeToReplace);
            var tNode = dojo.byId(anId);
            tNode.parentNode.replaceChild(tag, tNode);

            // fix ie6 performance defect 6909
            if (!(dojo.hasClass(nodeToReplace, "iw-iWidget") || dojo.hasClass(nodeToReplace, "mm_iWidget"))) {
                //dojo.destroy(nodeToReplace);
            }
            // end fix

            var para = {};
            para.widgetId = tag.id;
            para.skinNodeId = newNode.id;
            para.skinParam = args;

            // NOTE: use enabler new SPI to getParent() can't help here, since the widget instance is created after skin creation.
            com.ibm.mashups.services.ServiceManager.getService("eventService").broadcastEvent("com.ibm.mashups.builder.skinLoaded", para);
        }

        this.isProcessing = 0;
        dojo.publish(this.skinAttachEvent, [null]);
    },

    _getSkinResourceUrl: function(skinId, resource) {
        try {
            var skinModel = com.ibm.mm.builder.utils.skinUtil._getSkinModel();
            var skin = com.ibm.mm.builder.utils.skinUtil.getSkinNode(skinId) ||
            com.ibm.mm.builder.utils.skinUtil.getDefaultSkin();
            var url = skinModel.findResourceURL(skin, resource);
            return url;
        }
        catch (ex) {
        }
        return null;
    },

    _getArgs: function(skinId, tag, anId) {
        var args = {};
        //fixme. use the skin substitution to do this.
        //here we will allow users to do things.
        var skinVar = this.allVars[skinId];
        if (skinVar) {
            dojo.mixin(args, skinVar);
        }
        //in case, skin defines the widgetBody and skinId, we need to overwrite.
        args.widgetBody = "<div id='" + anId + "'/>";
        args.skinId = this.skinIdPrefix + tag.id;

        if (!args.process) {
            args.process = function(skinId, tagId) {
            };
        }
        args.process(skinId, tag.id);
        return args;
    },

    _getNodeMarkup: function(tag) {
        var newNode = document.createElement("div");
        newNode.appendChild(tag.cloneNode(true));
        var markup = newNode.innerHTML;
        newNode.removeChild(newNode.firstChild);
        return markup;
    },

    _getNodeFromMarkup: function(markup) {
        var newNode = document.createElement("div");
        newNode.innerHTML = markup;
        return newNode.removeChild(newNode.firstChild);
    },

    _getNodeToReplace: function(tag) {
        var node = dojo.byId(this.skinIdPrefix + tag.id);
        if (!node) {
            node = tag;
        }
        return node;
    },

    _showParent: function(node) {
        var parent = node.parentNode;
        while (parent) {
            parent = parent.parentNode;
        }
    }
});

}

if(!dojo._hasResource["tagservices.widgets"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["tagservices.widgets"] = true;
dojo.provide("tagservices.widgets");

dojo.provide("com.ibm.mm.livetext.widgets");
/*
 * This is injected on the fly and not fetched through an API. Therefore we need to define the @ibm-module so that the build process is picking it up
 * @ibm-module iWidget
 */





dojo.declare("tagservices.widgets", null, {
	//20349
	queue: [],
	queueHandle: null,
	queueRendering: true,

    constructor: function() {
        //20349. Load the config property to determine if perform queued rendering
        var configService = com.ibm.mashups.services.ServiceManager.getService(com.ibm.mashups.enabler.services.ConfigService.SERVICE_NAME);
    	queueRendering = configService.getValue(com.ibm.mashups.enabler.services.ConfigConstants.QUEUE_RENDERING);
    },
    processTag: function(tag) {
        var id = dojo.attr(tag,"id");

        if (typeof id != "undefined") {
        	var lazyLoad = dojo.attr(tag,"lazyLoad");

            var iWidget = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().find(id);
            if (iWidget === null) {
                // create widget
                iWidget = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().createWidget(tag);
            }

            if (iWidget) {
                // render widget
                if (!lazyLoad || (lazyLoad && lazyLoad != "true")) {
                	//20349.
                	if ((queueRendering === true) && !dojo.hasClass(tag,"iw-Standalone")) {
                		this.queue.push({priority: dojo.position(tag).y, widgetId: id});
                        this.processQueue(false);
                    }
                    else {
                    	com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().renderWidget(iWidget);
                    }
                }
                else {
                    iWidget.lazyLoad = true;
                }
            }
        }
    },
    //20349
    processQueue: function(process) {
    	if (this.queue.length>0) {
    		if (process) {
    			// process queue
    			// pick the one of the lowest number
    			while (this.queue.length>0) {
    				var json = this.queue.shift();
    				var iWidget = com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().find(json.widgetId);

    				if (iWidget) {
    					com.ibm.mashups.iwidget.model.Factory.getGlobalWidgetModel().renderWidget(iWidget);
    					break;
    				}
    			}
    		} else {
    			// sort
    			this.queue.sort(function(node1, node2) {
    				return node1.priority - node2.priority;
    			});
    		}
    		if (!this.queueHandle) {
    			var that = this;
    			this.queueHandle = setTimeout(function() { // this timeout put them in a queue effectively and allows other system/skin JS to be executed first
    				that.queueHandle = setTimeout(function() { // this timeout give the browser a little bit of time to render the page before executing any further
    					that.queueHandle = null;
    				dojo.hitch(that, that.processQueue)(true);
    				}, 5);
    			}, 0);
    		}
    	}
    },
    unprocessTag: function(tag) {
        var ns = ["iw-", "mm_"];

        for (var n = 0, l = ns.length; n < l; n++) {
            // search the content nodes
            var contentNodes = dojo.query("." + ns[n] + iwConstants.CSSCLASS_INSTANCE.iwContent, tag);

            // iterate through them and delete them
            for (var i = 0; i < contentNodes.length; i++) {
                com.ibm.mm.enabler.utils.Dom.destroyNode(contentNodes[i]);
            }

        }
    }
});

}

});