You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cf...@apache.org on 2012/06/18 20:10:25 UTC

svn commit: r1351437 [7/12] - in /incubator/flex/trunk/frameworks/projects: automation_agent/ automation_agent/bundles/ automation_agent/bundles/da_DK/ automation_agent/bundles/de_DE/ automation_agent/bundles/en_US/ automation_agent/bundles/es_ES/ auto...

Added: incubator/flex/trunk/frameworks/projects/tool/src/mx/automation/tool/ToolAdapter.as
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/frameworks/projects/tool/src/mx/automation/tool/ToolAdapter.as?rev=1351437&view=auto
==============================================================================
--- incubator/flex/trunk/frameworks/projects/tool/src/mx/automation/tool/ToolAdapter.as (added)
+++ incubator/flex/trunk/frameworks/projects/tool/src/mx/automation/tool/ToolAdapter.as Mon Jun 18 18:10:20 2012
@@ -0,0 +1,3240 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.automation.tool
+{
+	
+	import flash.display.DisplayObject;
+	import flash.events.Event;
+	import flash.events.IEventDispatcher;
+	import flash.external.ExternalInterface;
+	import flash.system.Capabilities;
+	import flash.utils.getDefinitionByName;
+	
+	import mx.automation.Automation;
+	import mx.automation.AutomationClass;
+	import mx.automation.AutomationError;
+	import mx.automation.AutomationID;
+	import mx.automation.AutomationIDPart;
+	import mx.automation.IAutomationClass;
+	import mx.automation.IAutomationEventDescriptor;
+	import mx.automation.IAutomationManager2;
+	import mx.automation.IAutomationMethodDescriptor;
+	import mx.automation.IAutomationObject;
+	import mx.automation.IAutomationPropertyDescriptor;
+	import mx.automation.IAutomationTabularData;
+	import mx.automation.codec.AdvancedDataGridSelectedCellCodec;
+	import mx.automation.codec.ArrayPropertyCodec;
+	import mx.automation.codec.AssetPropertyCodec;
+	import mx.automation.codec.AutomationObjectPropertyCodec;
+	import mx.automation.codec.ChartItemCodec;
+	import mx.automation.codec.ColorPropertyCodec;
+	import mx.automation.codec.DatePropertyCodec;
+	import mx.automation.codec.DateRangePropertyCodec;
+	import mx.automation.codec.DateScrollDetailPropertyCodec;
+	import mx.automation.codec.DefaultPropertyCodec;
+	import mx.automation.codec.HitDataCodec;
+	import mx.automation.codec.IAutomationPropertyCodec;
+	import mx.automation.codec.KeyCodePropertyCodec;
+	import mx.automation.codec.KeyModifierPropertyCodec;
+	import mx.automation.codec.ListDataObjectCodec;
+	import mx.automation.codec.RendererPropertyCodec;
+	import mx.automation.codec.ScrollDetailPropertyCodec;
+	import mx.automation.codec.ScrollDirectionPropertyCodec;
+	import mx.automation.codec.TabObjectCodec;
+	import mx.automation.codec.TriggerEventPropertyCodec;
+	import mx.automation.events.AutomationCustomReplayEvent;
+	import mx.automation.events.AutomationRecordEvent;
+	import mx.automation.events.EventDetails;
+	import mx.controls.Image;
+	import mx.controls.SWFLoader;
+	import mx.core.Application;
+	import mx.core.EventPriority;
+	import mx.core.mx_internal;
+	import mx.managers.IMarshalSystemManager;
+	import mx.managers.ISystemManager;
+	import mx.managers.SystemManager;
+	import mx.resources.IResourceManager;
+	import mx.resources.ResourceManager;
+	
+	import spark.automation.codec.SparkDropDownListBaseSelectedItemCodec;
+	
+	use namespace mx_internal;
+	
+	[ResourceBundle("automation_agent")]
+	
+	/** 
+	 *  @private
+	 */
+	public class ToolAdapter implements IToolCodecHelper
+	{
+		include "../../core/Version.as";
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Class constants
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Captures all properties of all objects in the application's active 
+		 *  window/dialog box/Web page in the Active Screen of each step.
+		 *  This means that all objects can be added to object repository /
+		 *  added checkpoints, etc. 
+		 *  @private
+		 */
+		public static const COMPLETE:uint = 0;
+		
+		/**
+		 *  (Default). Captures all properties of all objects in the application's
+		 *  active window/dialog box/Web page in the Active Screen of the first
+		 *  step performed in an application's window, plus all properties
+		 *  of the recorded object in subsequent steps in the same window
+		 *  (it is an optimization of Complete mode). 
+		 *  As in Complete mode, in this mode, all objects can be added to object 
+		 *  repository / added checkpoints, etc. 
+		 *  @private
+		 */
+		public static const PARTIAL:uint = 1;
+		
+		/**
+		 *  Captures properties only for the recorded object and its parent in the
+		 *  Active Screen of each step.
+		 *  This means that only the recorded objects and its parents can be added
+		 *  to object repository / added checkpoints, etc. 
+		 *  @private
+		 */
+		public static const MINIMUM:uint = 2;
+		
+		/**
+		 *  Disables capturing of Active Screen files for all applications
+		 *  and Web pages.
+		 *  This means no Active Screen will be shown. 
+		 *  @private
+		 */
+		public static const NONE:uint = 3;
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Class variables
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private
+		 */	
+		private static var isInitialized:Boolean = false;
+		
+		/**
+		 *  @private
+		 */	
+		private static var toolCodecHelper:IToolCodecHelper;
+		
+		
+		/**
+		 *  @private
+		 */	
+		//private  var sandboxRoot:IEventDispatcher;
+		
+		
+		/**
+		 *  @private
+		 *  The highest place we can listen for events in our DOM
+		 */
+		private static var mainListenerObj:IEventDispatcher; 
+		
+		
+		/**
+		 *  @private
+		 */	
+		private var lastApplicationName:String;
+		
+		/**
+		 *  @private
+		 */	
+		private var lastRequestName:String;
+		
+		
+		/**
+		 *  @private
+		 */	
+		private var requestPending:Boolean;
+		
+		
+		/**
+		 *  @private
+		 */	
+		private var requestResultObjArray:Array;
+		
+		/**
+		 *  @private
+		 */	
+		private var resultRecieved:Boolean;
+		
+		/**
+		 *  @private
+		 */
+		private var sm:ISystemManager;
+		
+		/**
+		 *  @private
+		 */
+		//  private var smMSm:IMarshalSystemManager;
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Constructor
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function ToolAdapter()
+		{
+			super();
+			//sm = Application.application.systemManager;
+			sm = Automation.getMainApplication().systemManager;
+			//smMSm = IMarshalSystemManager((Automation.getMainApplication().systemManager as SystemManager).getImplementation("max.manager::IMarshalSystemManager"));
+			
+			// the following code is to take care of Marshalling in Automation
+			// we need to handle all the methods which can reach Tool (which will be a part of
+			// main applicaiton. We need to send the information about this function call to other applications.
+			//sandboxRoot = sm.getSandboxRoot();
+			// these events are coming from the main application and the children are listening to the main application
+			if(sm.isTopLevelRoot() == false)
+			{
+				var eventDetailsToListenFromParent:Array = new Array();
+				eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.FIND_OBJECTIDS,
+					interAppRequestHandler));
+				eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.RUN,
+					interAppRequestHandler));
+				eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_ACTIVESCREEN,
+					interAppRequestHandler));
+				eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_PARENT,
+					interAppRequestHandler));
+				eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_RECTANGLE,
+					interAppRequestHandler));
+				eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_ELEMENT_FROM_POINT,
+					interAppRequestHandler));
+				eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_ELEMENT_TYPE,
+					interAppRequestHandler));
+				eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_DISPLAY_NAME,
+					interAppRequestHandler));
+				eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_PROPERTIES,
+					interAppRequestHandler));
+				eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.BUILD_DESCRIPTION,
+					interAppRequestHandler));
+				eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_CHILDREN,
+					interAppRequestHandler));
+				eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.LEARN_CHILD_OBJECTS,
+					interAppRequestHandler));
+				eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_LAST_ERROR,
+					interAppRequestHandler));
+				eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.SET_LAST_ERROR,
+					interAppRequestHandler));
+				eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_TABULAR_ATTRIBUTES,
+					interAppRequestHandler));
+				eventDetailsToListenFromParent.push(new EventDetails(ToolMarshallingEvent.GET_TABULAR_DATA,
+					interAppRequestHandler));
+				
+				automationManager.addEventListenersToAllParentApplications(eventDetailsToListenFromParent);
+				//addEventListenersToAllParentApplications(eventDetailsToListenFromParent);
+			}
+			
+			
+			
+			var eventDetailsToListenFromChildren:Array = new Array();
+			eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.FIND_OBJECTIDS_REPLY,
+				interAppReplyHandler));
+			eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.RUN_REPLY,
+				interAppReplyHandler));
+			eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_ACTIVESCREEN_REPLY,
+				interAppReplyHandler));
+			eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_PARENT_REPLY,
+				interAppReplyHandler));
+			eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_RECTANGLE_REPLY,
+				interAppReplyHandler));
+			eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_ELEMENT_FROM_POINT_REPLY,
+				interAppReplyHandler));
+			eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_ELEMENT_TYPE_REPLY,
+				interAppReplyHandler));
+			eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_DISPLAY_NAME_REPLY,
+				interAppReplyHandler));
+			eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_PROPERTIES_REPLY,
+				interAppReplyHandler));
+			eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.BUILD_DESCRIPTION_REPLY,
+				interAppReplyHandler));
+			eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_CHILDREN_REPLY,
+				interAppReplyHandler));
+			eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.LEARN_CHILD_OBJECTS_REPLY,
+				interAppReplyHandler));
+			eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_LAST_ERROR_REPLY,
+				interAppReplyHandler));
+			eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_TABULAR_ATTRIBUTES_REPLY,
+				interAppReplyHandler));
+			eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.GET_TABULAR_DATA_REPLY,
+				interAppReplyHandler));
+			eventDetailsToListenFromChildren.push(new EventDetails(ToolMarshallingEvent.RECORD,
+				marhsalledRecordHandler));
+			
+			automationManager.addEventListenersToAllChildApplications(eventDetailsToListenFromChildren);
+			
+			// we shall let custom components to handle the event before we handle it. So we are using the DEFAULT_HANDLER (eventhough)
+			// we are not the same component who dispatched the event.    
+			// for this to work automationmanger should have dispatched the event as cancelable
+			automationManager.addEventListener(AutomationRecordEvent.RECORD,recordHandler, false, EventPriority.DEFAULT_HANDLER, true); 
+			
+			if (!isInitialized)
+			{
+				isInitialized = true; 
+				
+				toolCodecHelper = this;
+				
+				// Add the default serializers.
+				addPropertyCodec(
+					"object", new DefaultPropertyCodec());
+				
+				addPropertyCodec(
+					"keyCode", new KeyCodePropertyCodec());
+				
+				addPropertyCodec(
+					"keyModifier", new KeyModifierPropertyCodec());
+				
+				addPropertyCodec(
+					"object[]", new ArrayPropertyCodec(new DefaultPropertyCodec()));
+				
+				addPropertyCodec(
+					"color", new ColorPropertyCodec());
+				
+				addPropertyCodec(
+					"color[]", new ArrayPropertyCodec(new ColorPropertyCodec()));
+				
+				addPropertyCodec(
+					"automationObject", new AutomationObjectPropertyCodec());
+				
+				addPropertyCodec(
+					"automationObject[]",
+					new ArrayPropertyCodec(new AutomationObjectPropertyCodec()));
+				
+				addPropertyCodec(
+					"asset", new AssetPropertyCodec());
+				
+				addPropertyCodec(
+					"asset[]", new ArrayPropertyCodec(new AssetPropertyCodec()));
+				
+				addPropertyCodec(
+					"listDataObject", new ListDataObjectCodec());
+				
+				addPropertyCodec(
+					"listDataObject[]",
+					new ArrayPropertyCodec(new ListDataObjectCodec()));
+				
+				addPropertyCodec(
+					"rendererObject", new RendererPropertyCodec());
+				
+				addPropertyCodec(
+					"dateRange", new DateRangePropertyCodec());
+				
+				addPropertyCodec(
+					"dateObject", new DatePropertyCodec());
+				
+				addPropertyCodec(
+					"dateRange[]",
+					new ArrayPropertyCodec(new DateRangePropertyCodec()));
+				
+				addPropertyCodec(
+					"event", new TriggerEventPropertyCodec());
+				
+				addPropertyCodec(
+					"tab", new TabObjectCodec());
+				
+				addPropertyCodec(
+					"scrollDetail", new ScrollDetailPropertyCodec());
+				
+				addPropertyCodec(
+					"dateScrollDetail", new DateScrollDetailPropertyCodec());
+				
+				addPropertyCodec(
+					"scrollDirection", new ScrollDirectionPropertyCodec());
+				
+				addPropertyCodec(
+					"AdvancedDataGridSelectedCell[]", new ArrayPropertyCodec(new AdvancedDataGridSelectedCellCodec()));
+				
+				addPropertyCodec(
+					"ChartItemCodec", new ChartItemCodec()); 
+				
+				addPropertyCodec(
+					"ChartItemCodec[]", new ArrayPropertyCodec(new ChartItemCodec()));
+				
+				addPropertyCodec(
+					"hitDataCodec[]", new ArrayPropertyCodec(new HitDataCodec()));
+				
+				
+				addPropertyCodec(
+					"SparkDropDownListBaseSelectedItem", new SparkDropDownListBaseSelectedItemCodec());
+				
+				/*
+				This portion of the code is removed to make the automation_dmv source compilable in Flex Builder source.
+				
+				Why this code was used :
+				To make the application which does not need the datavisuaalisation components, not including these codes
+				The required codecs were supposed to be present in the automation_dmv swc and hence only if the user
+				provides this swc, these classes would have been loaded.
+				But to make these classes under the automation_dmv , we bring the dependancy of tool and automation source
+				as the codecs use IToolProper.... class. Hence we cannot compile them independantly
+				
+				try
+				{
+				// check for availability of chart codec.
+				// it may not be available if user has not included chart delegates
+				var codec:Object = getDefinitionByName("mx.automation.codec.HitDataCodec");
+				
+				addPropertyCodec(
+				"hitDataCodec[]", new ArrayPropertyCodec(new codec()));
+				}
+				catch(e:Error)
+				{
+				}
+				*/
+				
+				
+				
+				
+				// we shall do the registration of callbacks and register with Browser
+				// use External Interface only if we are the root application.
+				if(!sm.isTopLevelRoot())
+				{
+					return;
+				}
+				
+				
+				var message:String;
+				
+				if (Capabilities.playerType != "ActiveX")
+				{
+					message = resourceManager.getString(
+						"automation_agent", "notActiveX");
+					Automation.automationDebugTracer.traceMessage("QTooldapter","ToolAdapter()",message);
+					return;
+				}
+				
+				if (! Capabilities.os.match(/^Windows/))
+				{
+					message = resourceManager.getString(
+						"automation_agent", "notWindows", [Capabilities.os]);
+					Automation.automationDebugTracer.traceMessage("ToolAdapter","ToolAdapter()",message);
+					return;
+				}
+				
+				if (!ExternalInterface.available)
+				{
+					message = resourceManager.getString(
+						"automation_agent", "noExternalInterface");
+					Automation.automationDebugTracer.traceMessage("ToolAdapter","ToolAdapter()",message);
+					return;
+				}
+				
+				if (!playerID || playerID.length == 0)
+				{
+					message = resourceManager.getString(
+						"automation_agent", "noPlayerID");
+					Automation.automationDebugTracer.traceMessage("ToolAdapter","ToolAdapter()",message);
+					return;
+				}
+				
+				if (playerID.match(/[\.-]/))
+				{
+					message = resourceManager.getString(
+						"automation_agent", "invalidPlayerID", [playerID]);
+					Automation.automationDebugTracer.traceMessage("ToolAdapter","ToolAdapter()",message);
+					return;
+				}
+				
+				try
+				{
+					// for js driver
+					ExternalInterface.addCallback("SetTestingEnvironment", 
+						setTestingEnvironment);
+					
+					// Add Tool callbacks
+					ExternalInterface.addCallback("GetParent", getParent);
+					ExternalInterface.addCallback("GetChildren", getChildren);
+					ExternalInterface.addCallback("BuildDescription", buildDescription);
+					ExternalInterface.addCallback("FindObjectId", findObjectID);
+					ExternalInterface.addCallback("FindObjectId2", findObjectIDs);
+					ExternalInterface.addCallback("GetDisplayName", getDisplayName);
+					ExternalInterface.addCallback("GetElementType", getElementType);
+					ExternalInterface.addCallback("GetProperties", getProperties);
+					ExternalInterface.addCallback("GetTabularData", getTabularData);
+					ExternalInterface.addCallback("GetTabularAttributes", 
+						getTabularAttributes);
+					ExternalInterface.addCallback("Run", run);
+					ExternalInterface.addCallback("GetLastError", getLastError);
+					ExternalInterface.addCallback("SetLastError", setLastError);
+					ExternalInterface.addCallback("BeginRecording", beginRecording);
+					ExternalInterface.addCallback("EndRecording", endRecording);
+					ExternalInterface.addCallback("GetElementFromPoint", 
+						getElementFromPoint);
+					ExternalInterface.addCallback("GetRectangle", getRectangle);
+					ExternalInterface.addCallback("GetActiveScreen", getActiveScreen);
+					ExternalInterface.addCallback("LearnChildObjects", learnChildObjects);
+					
+					// Register ActiveX plugin
+					ExternalInterface.call("eval", 
+						"try { window._mx_testing_plugin_" + playerID + 
+						" = new ActiveXObject('TEAPluginIE.TEAFlexAgentIE'); }" +
+						"catch(e) { document.getElementById('" + playerID + 
+						"').SetLastError(e.message); } ");
+					
+					if (lastError)
+					{
+						message = resourceManager.getString(
+							"automation_agent", "unableToLoadPluginGeneric",
+							[lastError.message]);
+						Automation.automationDebugTracer.traceMessage("ToolAdapter","ToolAdapter()",message);
+						return;
+					}
+					
+					ExternalInterface.call("eval", 
+						"if (!window._mx_testing_plugin_" + playerID + 
+						".RegisterPluginWithTool(self, " + "'" + playerID + "')) {" +
+						"document.getElementById('" + playerID + 
+						"').SetLastError('TEAPluginIE.TEAFlexAgentIE is not scriptable'); }");
+					
+					if (lastError)
+					{
+						message = resourceManager.getString(
+							"automation_agent", "unableToLoadPluginGeneric",
+							[lastError.message]);
+						Automation.automationDebugTracer.traceMessage("ToolAdapter","ToolAdapter()",message);
+						return;
+					}
+					
+					// Load environment XML
+					var te:String = ExternalInterface.call("window._mx_testing_plugin_" + 
+						playerID + 
+						".GetTestingEnvironment");               
+					setTestingEnvironment(te);
+				}
+				catch (se:SecurityError)
+				{
+					message = resourceManager.getString(
+						"automation_agent", "unableToLoadPluginGeneric",
+						[se.message]);
+					Automation.automationDebugTracer.traceMessage("ToolAdapter","ToolAdapter()",message);
+				}
+			}
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Variables
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private
+		 */
+		private var lastError:Error;
+		
+		/**
+		 *  @private
+		 */
+		private var propertyCodecMap:Object = [];
+		
+		/**
+		 *  @private
+		 *  Used for accessing localized Error messages.
+		 */
+		private var resourceManager:IResourceManager =
+			ResourceManager.getInstance();
+		
+		
+		
+		/**
+		 *  @private
+		 *  Used for accessing localized Error messages.
+		 */
+		private var detailsSentToTool :Boolean = false;
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		//
+		//--------------------------------------------------------------------------
+		
+		//----------------------------------
+		//  automationManager
+		//----------------------------------
+		
+		/**
+		 *  @private
+		 */
+		private function get automationManager():IAutomationManager2  
+		{
+			return Automation.automationManager2 as IAutomationManager2;
+		}
+		
+		//----------------------------------
+		//  playerID
+		//----------------------------------
+		
+		/**
+		 *  @private
+		 */
+		private function get playerID():String 
+		{ 
+			//return Application.application.id;
+			return Automation.getMainApplication().id;
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Methods
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private
+		 *  Registers a custom codec to encoding an decoding of object properties and
+		 *  event properties to and from a testing tool.  For example, ColorPicker
+		 *  events can contain the selected color.  A special color codec is provided
+		 *  to encode and decode colors from their native number format to hex.
+		 *
+		 *  Predefined codecs include:
+		 *      "" - The default codec that supports basic types such as String, Number, int and uint.
+		 *      "color" - Converts a number to hex.
+		 *      "keyCode" - Converts a keyCode number to a human readable string
+		 *      "keyState" - Converts ctrlKey, shiftKey and altKey booleans to a human 
+		 *                   readable bitfield string.
+		 *      "skin" - Converts a skin asset class name to closely resemble it's 
+		 *               original asset name.  Path separators and periods in the orignal
+		 *               path name will be converted to underscores.  This is only available
+		 *               on readonly properties.
+		 *      "automationObject" - Converts an object to it's automationName.
+		 *
+		 *  @param codecName the name of the codec.
+		 * 
+		 *  @param codec the implementation of the codec.
+		 */
+		private function addPropertyCodec(codecName:String, codec:IAutomationPropertyCodec):void
+		{
+			propertyCodecMap[codecName] = codec;
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function setTestingEnvironment(te:String):void
+		{
+			automationManager.automationEnvironment = new ToolEnvironment(new XML(te));
+			// For supportig Marshalling we need the env information as string and
+			// the name of the class which interprets the information
+			// this information will be used by the Automation Manger in each of the AppDomain
+			// to intialise the class with the details.
+			// #IMP: MARSHALLING NOTE#: The name of the class needs to be maintained across versions
+			// However the implementation of the class can be different in each version.
+			automationManager.automationEnvironmentString = te;
+			automationManager.automationEnvironmentHandlingClassName = "mx.automation.tool.ToolEnvironment";
+		}
+		
+		/**
+		 *  Encodes a single value to a testing tool value.  Unlike encodeProperties which
+		 *  takes an object which contains all the properties to encode, this method
+		 *  takes the actual value to encode.  This is useful for encoding return values.
+		 *
+		 *  @param obj the value to be encoded.
+		 * 
+		 *  @param propertyDescriptor the property descriptor that describes this value.
+		 * 
+		 *  @param relativeParent the IAutomationObject that is related to this value.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function encodeValue(value:Object, 
+									testingToolType:String,
+									codecName:String,
+									relativeParent:IAutomationObject):Object
+		{
+			//setup a fake descriptor and object to send to the codec
+			var pd:ToolPropertyDescriptor = 
+				new ToolPropertyDescriptor("value",
+					false, 
+					false, 
+					testingToolType, 
+					codecName);
+			var obj:Object = {value:value};
+			return getPropertyValue(obj, pd, relativeParent);
+		}
+		
+		
+		public function getPropertyValue(obj:Object, 
+										 pd:ToolPropertyDescriptor,
+										 relativeParent:IAutomationObject = null):Object
+		{
+			var codec:IAutomationPropertyCodec = propertyCodecMap[pd.codecName];
+			
+			if (codec == null)
+				codec = propertyCodecMap["object"];
+			
+			if (relativeParent == null)
+				relativeParent = obj as IAutomationObject;
+			
+			return codec.encode(automationManager, obj, pd, relativeParent);
+		}
+		
+		/**
+		 *  Encodes properties in an AS object to an array of values for a testing tool
+		 *  using the codecs.  Since the object being passed in may not be an IAutomationObject 
+		 *  (it could be an event class) and some of the properties require the
+		 *  IAutomationObject to be transcoded (such as the item renderers in
+		 *  a list event), relativeParent should always be set to the relevant
+		 *  IAutomationObject.
+		 *
+		 *  @param obj the object that contains the properties to be encoded.
+		 * 
+		 *  @param propertyDescriptors the property descriptors that describes the properties for this object.
+		 * 
+		 *  @param relativeParent the IAutomationObject that is related to this object.
+		 *
+		 *  @return the encoded property value.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function encodeProperties(obj:Object,
+										 propertyDescriptors:Array,
+										 interactionReplayer:IAutomationObject):Array
+		{
+			var result:Array = [];
+			var consecutiveDefaultValueCount:Number = 0;
+			for (var i:int = 0; i < propertyDescriptors.length; i++)
+			{
+				var val:Object = getPropertyValue(obj, 
+					propertyDescriptors[i],
+					interactionReplayer);
+				
+				var isDefaultValueNull:Boolean = propertyDescriptors[i].defaultValue == "null";
+				
+				consecutiveDefaultValueCount = (!(val == null && isDefaultValueNull) &&
+					(propertyDescriptors[i].defaultValue == null || 
+						val == null ||
+						propertyDescriptors[i].defaultValue != val.toString())
+					? 0
+					: consecutiveDefaultValueCount + 1);
+				
+				result.push(val);
+			}
+			
+			result.splice(result.length - consecutiveDefaultValueCount, 
+				consecutiveDefaultValueCount);
+			
+			return result;
+		}
+		
+		
+		/**
+		 *  @private
+		 */
+		private function recordHandler(event:AutomationRecordEvent):void
+		{
+			if(event.isDefaultPrevented())
+				return;
+			
+			automationManager.incrementCacheCounter();
+			
+			try
+			{
+				var obj:IAutomationObject = event.automationObject ;
+				var rid:AutomationID = automationManager.createID(obj);
+				var descriptionXML:XML = getDescriptionXML(rid, obj);
+				
+				// We are storing the actual pretty printing value so that we can
+				// reset it back when we are done with our operation.
+				// Ref: http://bugs.adobe.com/jira/browse/FLEXENT-1140
+				var actualPrettyPrinting:Boolean = XML.prettyPrinting;
+				XML.prettyPrinting = false;
+				var parentRids:Array = [];
+				
+				while (obj)
+				{
+					rid = automationManager.createID(obj);
+					parentRids.push(rid.toString());
+					obj = automationManager.getParent(obj);
+				}
+				
+				if(sm.isTopLevelRoot() == false)
+				{
+					// send the event to the root applicaiton and let it call the External Interface call
+					// it was found the externalInterface call can be done from any application irrespective
+					// whether the applicaiton has registered the same or not.
+					// however this will not be applicable to the solutions which uses sockets for IPC. 
+					// hence to have the generalised approach across all solutions, we shall
+					// dispatch the event
+					var marshalledEvent:ToolMarshallingEvent = new ToolMarshallingEvent(
+						ToolMarshallingEvent.RECORD);
+					
+					// #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed 
+					// across versions. If any new arguements is needed in new versions 
+					// add them to the end of the list and handle appropriately in the 
+					// handler of this event.
+					var recordDetails:Array = new Array();
+					recordDetails.push(parentRids);
+					recordDetails.push(descriptionXML.toXMLString());
+					recordDetails.push(event.name);
+					recordDetails.push(event.args);
+					marshalledEvent.interAppDataToMainApp = recordDetails;
+					
+					//sandboxRoot.dispatchEvent(marshalledEvent);
+					dispatchEventToParent(marshalledEvent);
+					
+				}
+				else
+				{
+					
+					ExternalInterface.call("window._mx_testing_plugin_" + playerID + ".Record", 
+						parentRids,
+						descriptionXML.toXMLString(),
+						event.name,
+						checkForSpecialCharsInArray(event.args));
+				}             
+				XML.prettyPrinting = actualPrettyPrinting;
+			}
+			catch (e:Error)
+			{
+				lastError = e;
+				Automation.automationDebugTracer.traceMessage("ToolAdapter","recordHandler()",e.message);
+			}
+			
+			automationManager.decrementCacheCounter();
+		}
+		
+		private function checkForSpecialCharsInString(inputString:String):String
+		{
+			// currently we are only considering \.
+			// and other special chars issues are seems to be resolved in the 
+			// latest flash player version.
+			// dont add this solution locally, eventhough it is jsut one line. So that when another special char
+			// needs to be considered, irrespective of the usage occurance 
+			// we need only to change here.
+			if(inputString && inputString.length)
+				return inputString.replace(/\\/g, "\\\\" );
+			return inputString;
+		}
+		private function checkForSpecialCharsInArray(inputArray:Array):Array
+		{
+			// currently we are only considering \.
+			// and other special chars issues are seems to be resolved in the 
+			// latest flash player version.
+			var retArray:Array = new Array();
+			
+			var count:int  = inputArray ? inputArray.length :0;
+			
+			for (var i:int =0; i<count ; i++)
+			{
+				var currentElement:Object = inputArray[i];
+				if(currentElement is String)
+				{
+					currentElement = (currentElement as String).replace(/\\/g, "\\\\" );
+				}
+				else if(currentElement is Array)
+				{
+					currentElement = checkForSpecialCharsInArray(currentElement as Array);
+				}
+				
+				retArray.push(currentElement);
+				
+			}
+			return retArray;
+		}
+		private function marhsalledRecordHandler(event:Event):void
+		{
+			// Marshalling events are needeed across applicaiton domain
+			// so this conversion shall fail in the same domain
+			// i.e the above check is to avoid the echoing
+			if(event is ToolMarshallingEvent)
+				return;
+			
+			
+			// this handler is only for the main app. so if we are not the main app root 
+			// application, we should not handle it, we should just pass to our parent.
+			
+			//if(sm.useSWFBridge() == true)
+			if(!sm.isTopLevelRoot())
+			{
+				var event1:ToolMarshallingEvent = ToolMarshallingEvent.marshal(event);
+				dispatchEventToParent(event1);
+			}
+			else
+			{
+				// i.e take the deta send from the sub app and call the external interface call.
+				// #IMP: MARSHALLING NOTE#: 
+				var recordDetails:Array = event["interAppDataToMainApp"];
+				if(recordDetails && recordDetails.length == 4)
+				{
+					ExternalInterface.call("window._mx_testing_plugin_" + playerID + ".Record", 
+						recordDetails[0], //parentRids,
+						recordDetails[1], //descriptionXML.toXMLString(),
+						recordDetails[2], //event.name,
+						recordDetails[3]); // event.args);
+				}
+			}
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function beginRecording():Object
+		{
+			return useErrorHandler(function():Object
+			{
+				var o:Object = { result:null, error:0 };
+				automationManager.addEventListener(AutomationRecordEvent.RECORD,
+					recordHandler, false, EventPriority.DEFAULT_HANDLER, true);
+				automationManager.beginRecording();
+				
+				return o;
+			});
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function endRecording():Object
+		{
+			return useErrorHandler(function():Object
+			{
+				var o:Object = { result:null, error:0 };
+				automationManager.endRecording();
+				automationManager.removeEventListener(AutomationRecordEvent.RECORD,
+					recordHandler);
+				return o;
+			});
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function getElementType(objID:String, fromTool:Boolean = true):Object
+		{
+			return useErrorHandler(function():Object
+			{
+				var o:Object = { result:null, error:0 };
+				try
+				{
+					var rid:AutomationID = AutomationID.parse(objID);
+					// we need to find out whether the current app and the 
+					// reuired app are the same.
+					var requiredApplicationName:String = getApplicationNameFromAutomationID(rid);
+					var currentApplicationName:String  = getApplicationName();
+					if(requiredApplicationName == currentApplicationName)
+					{
+						if (fromTool == true)
+							detailsSentToTool = true; 
+						var target:IAutomationObject = automationManager.resolveIDToSingleObject(rid);
+						o.result = automationManager.getAutomationClassName(target);
+					}
+					else
+					{
+						// we need to send this as information to the other application 
+						// and let the appropriate application handle it.
+						
+						// #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed 
+						// across versions. If any new arguements is needed in new versions 
+						// add them to the end of the list and handle appropriately in the 
+						// handler of this event.
+						
+						var details:Array = new Array();
+						details.push(objID);	
+						
+						if(fromTool == true)
+						{
+							requestPending = false;
+							resultRecieved = false;
+						}
+						o.result =   handleRequestToDifferentApplication(requiredApplicationName,
+							ToolMarshallingEvent.GET_ELEMENT_TYPE,details);
+						
+						if((resultRecieved == true)&&(fromTool == true))
+						{
+							// since we have recieved the result, we can send the information back to Tool
+							o =  requestResultObjArray[0] as Object;
+							detailsSentToTool = true;
+						}
+						
+					}
+				}
+				catch (e:Error)
+				{
+					throw e;
+				}
+				return o;
+			});
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function getDisplayName(objID:String, fromTool:Boolean = true):Object
+		{
+			return useErrorHandler(function():Object
+			{
+				var o:Object = { result:null, error:0 };
+				try
+				{
+					var rid:AutomationID  = AutomationID.parse(objID);
+					
+					// we need to find out whether the current app and the 
+					// reuired app are the same.
+					var requiredApplicationName:String = getApplicationNameFromAutomationID(rid);
+					var currentApplicationName:String  = getApplicationName();
+					if(requiredApplicationName == currentApplicationName)
+					{
+						
+						if (fromTool == true)
+							detailsSentToTool = true; 
+						
+						var target:IAutomationObject = automationManager.resolveIDToSingleObject(rid);
+						o.result = automationManager.getAutomationName(target);
+					}
+					else
+					{
+						// we need to send this as information to the other application 
+						// and let the appropriate application handle it.
+						
+						
+						// #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed 
+						// across versions. If any new arguements is needed in new versions 
+						// add them to the end of the list and handle appropriately in the 
+						// handler of this event.
+						
+						var details:Array = new Array();
+						details.push(objID);
+						if(fromTool == true)
+						{
+							requestPending = false;
+							resultRecieved = false;
+						}
+						o.result =   handleRequestToDifferentApplication(requiredApplicationName,
+							ToolMarshallingEvent.GET_DISPLAY_NAME,details);
+						if((resultRecieved == true)&&(fromTool == true))
+						{
+							// since we have recieved the result, we can send the information back to Tool
+							o =  requestResultObjArray[0] as Object;
+							detailsSentToTool = true;
+						}
+					}
+				}
+				catch(e:Error)
+				{
+					throw e;
+				}
+				return o;
+			});
+		}
+		
+		private function replayEvent(target:IAutomationObject, eventName:String, args:Array):Object
+		{
+			var automationClass:IAutomationClass = 
+				automationManager.automationEnvironment.getAutomationClassByInstance(target);
+			
+			var message:String;
+			
+			// try to find the automation class
+			if (! automationClass)
+			{
+				message = resourceManager.getString(
+					"automation_agent", "classNotFound",
+					[AutomationClass.getClassName(target)]);
+				throw new Error(message);
+			}
+			
+			var eventDescriptor:IAutomationEventDescriptor =
+				automationClass.getDescriptorForEventByName(eventName);
+			
+			if (!eventDescriptor)
+			{
+				message = resourceManager.getString(
+					"automation_agent", "methodNotFound",
+					[eventName, automationClass]);
+				throw new Error(message);
+			}
+			
+			var retValue:Object = eventDescriptor.replay(target, args);
+			return {value:retValue, type:null};
+		}
+		
+		private function replayMethod(target:IAutomationObject, method:String, args:Array):Object
+		{
+			var automationClass:IAutomationClass = 
+				automationManager.automationEnvironment.getAutomationClassByInstance(target);
+			
+			var message:String;
+			
+			// try to find the automation class
+			if (! automationClass)
+			{
+				message = resourceManager.getString(
+					"automation_agent", "classNotFound",
+					[AutomationClass.getClassName(target)]);
+				throw new Error(message);
+			}
+			
+			var methodDescriptor:IAutomationMethodDescriptor =
+				automationClass.getDescriptorForMethodByName(method);
+			
+			if (!methodDescriptor)
+			{
+				message = resourceManager.getString(
+					"automation_agent", "methodNotFound",
+					[method, automationClass]);
+				throw new Error(message);
+			}
+			
+			var retValue:Object = methodDescriptor.replay(target, args);
+			
+			if(retValue is IAutomationObject)
+				retValue = automationManager.createID(IAutomationObject(retValue)).toString();
+			
+			return {value:retValue, type:methodDescriptor.returnType};
+		}
+		
+		private var replayResultObj:Object = null;
+		private function replayDefaultHandler(event:AutomationCustomReplayEvent):void
+		{
+			replayResultObj = { result:null, error:0 };
+			if(event.isDefaultPrevented())
+				return;
+			
+			automationManager.removeEventListener(AutomationCustomReplayEvent.CUSTOM_REPLAY,replayDefaultHandler);
+			
+			if((event.type != AutomationCustomReplayEvent.CUSTOM_REPLAY) || 
+				(event.automationObject == null )||
+				(event.name == null))
+				return;
+			
+			
+			
+			//var o:Object = { result:null, error:0 };
+			
+			try
+			{
+				replayResultObj.result = replayMethod(event.automationObject, event.name, event.args);        	
+			}
+			catch(e:Error)
+			{
+				try
+				{
+					//replayResultObj.result = replayEvent(target, method, args);
+					replayResultObj.result = replayEvent(event.automationObject, event.name, event.args);    	
+				}
+				catch(e:Error)
+				{
+					automationManager.decrementCacheCounter();
+					throw e;
+				}
+			}
+			
+		}
+		/**
+		 *  @private
+		 */
+		public function replay(target:IAutomationObject, method:String, args:Array):Object
+		{   
+			// first let us dispatch the custom replay event.
+			replayResultObj = null;
+			
+			// create the custom replay event and dispatch the same
+			var customReplayEventObj:AutomationCustomReplayEvent = 
+				new AutomationCustomReplayEvent(AutomationCustomReplayEvent.CUSTOM_REPLAY,false,true);
+			//customReplayEventObj.cancelable should be  true. We need to make this true as the default handler can prevent the default.
+			
+			customReplayEventObj.automationObject = target;
+			customReplayEventObj.name = method;
+			customReplayEventObj.args = args;
+			
+			
+			// dispatch the event from the automation manager.
+			automationManager.addEventListener(AutomationCustomReplayEvent.CUSTOM_REPLAY,replayDefaultHandler,false,
+				EventPriority.DEFAULT_HANDLER,false);
+			
+			automationManager.dispatchEvent(customReplayEventObj);
+			return replayResultObj;
+			
+		}
+		
+		
+		/**
+		 *  @private
+		 */
+		public function run(objID:String, method:String, args:String, fromTool:Boolean = true):Object
+		{
+			return useErrorHandler(function():Object
+			{
+				var resultObj:Object;
+				try
+				{
+					var rid:AutomationID = AutomationID.parse(objID);
+					
+					var requiredApplicationName:String = getApplicationNameFromAutomationID(rid);
+					var currentAppName:String = getApplicationName();
+					
+					if(requiredApplicationName != currentAppName)
+					{
+						// we need to send this as information to the other application 
+						// and let the appropriate application handle it.
+						
+						// #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed 
+						// across versions. If any new arguements is needed in new versions 
+						// add them to the end of the list and handle appropriately in the 
+						// handler of this event.
+						
+						var details:Array = new Array();
+						details.push(objID);
+						details.push(method);
+						details.push(args);	
+						
+						if(fromTool == true)
+						{
+							requestPending = false;
+							resultRecieved = false;
+						}
+						
+						resultObj =  handleRequestToDifferentApplication(requiredApplicationName, 
+							ToolMarshallingEvent.RUN,details);
+						if((resultRecieved == true)&&(fromTool == true))
+						{
+							// since we have recieved the result, we can send the information back to Tool
+							resultObj = requestResultObjArray[0];
+							detailsSentToTool = true;
+						}
+					}
+					else
+					{
+						
+						if (fromTool == true)
+							detailsSentToTool = true; 
+						
+						// *************************************** 
+						var target:IAutomationObject = automationManager.resolveIDToSingleObject(rid);
+						resultObj =  replay(target, method, convertArrayFromCrazyToAs(args));
+					}
+					
+					// if we have not sent the request to Tool, we need to send the error message that we are not yet synchronised
+					// we need this message only if the request to this method has come from Tool			
+					if((detailsSentToTool == false)&&(fromTool == true))
+					{
+						// we dont expect this case to happen. But just to be on the
+						// safe side we are keeping this error
+						var message:String = resourceManager.getString(
+							"automation_agent", "notSynchronized");
+						throw new AutomationError(message,
+							AutomationError.OBJECT_NOT_VISIBLE);	
+					}
+				}
+				catch(e:Error)
+				{
+					throw e;
+				}
+				
+				return resultObj;
+			});
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function findObjectID(descriptionXML:String):Object
+		{
+			// this method is not used in 3 onwards
+			// hence this method is modified to support Marshalling
+			return useErrorHandler(function():Object
+			{
+				var o:Object = { result:null, error:0 };
+				try
+				{
+					var rid:AutomationID = new AutomationID();
+					var x:XML = new XML(descriptionXML);
+					while (x)
+					{
+						var part:AutomationIDPart = new AutomationIDPart();
+						part.automationClassName = x.@type.toString();
+						var automationClass:IToolAutomationClass =
+						automationManager.automationEnvironment.getAutomationClassByName(part.automationClassName) as IToolAutomationClass;
+						var propertyCaseRemapping:Object = automationClass.propertyLowerCaseMap;
+						
+						for (var property:Object in x.Property)
+						{
+							var propertyName:String = x.Property[property].@name.toString().toLowerCase();
+							
+							if (propertyName in propertyCaseRemapping)
+							{
+								var propertyDescriptor:ToolPropertyDescriptor = 
+								propertyCaseRemapping[propertyName];
+								
+								propertyName = propertyDescriptor.name;
+								
+								var regEx:String = x.Property[property].@regExp;
+								var value:String = x.Property[property].@value;
+								
+								if (regEx == "true" || regEx == "t")
+									part[propertyName] = new RegExp(value);
+								else
+									part[propertyName] = value;
+							}
+						}
+						rid.addLast(part);
+						x = x.Element.length() == 1 ? x.Element[0] : null;
+					}
+					
+					var message:String;
+					if (!automationManager.isSynchronized(null))
+					{
+						message = resourceManager.getString(
+							"automation_agent", "notSynchronized");
+						throw new AutomationError(message,
+							AutomationError.OBJECT_NOT_VISIBLE);
+					}	
+					var obj:IAutomationObject = automationManager.resolveIDToSingleObject(rid);
+					if (!automationManager.isSynchronized(obj))
+					{
+						message = resourceManager.getString(
+							"automation_agent", "notSynchronized");
+						throw new AutomationError(message,
+							AutomationError.OBJECT_NOT_VISIBLE);
+					}
+					if (!automationManager.isVisible(obj as DisplayObject))
+					{
+						message = resourceManager.getString(
+							"automation_agent", "invisible");
+						throw new AutomationError(message,
+							AutomationError.OBJECT_NOT_VISIBLE);
+					}
+					o.result = automationManager.createID(obj).toString();
+				}
+				catch(e:Error)
+				{
+					throw e;
+				}
+				
+				return o;
+			});
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function findObjectIDs(descriptionXML:String, fromTool :Boolean = true):Object
+		{
+			
+			return useErrorHandler(function():Object
+			{
+				var o:Object = { result:null, error:0 };
+				try
+				{
+					var rid:AutomationID = new AutomationID();
+					var x:XML = new XML(descriptionXML);
+					var partIndex:int = 0;
+					
+					var sameApplication:Boolean = true;
+					var requiredApplicationName :String ;
+					
+					while (x && sameApplication)
+					{
+						var part:AutomationIDPart = new AutomationIDPart();
+						part.automationClassName = x.@type.toString();
+						var automationClass:IToolAutomationClass =
+						automationManager.automationEnvironment.
+						getAutomationClassByName(part.automationClassName) as IToolAutomationClass;
+						
+						var propertyCaseRemapping:Object = automationClass.propertyLowerCaseMap;
+						
+						for (var property:Object in x.Property)
+						{
+							var propertyName:String = x.Property[property].@name.toString().toLowerCase();
+							
+							if (propertyName in propertyCaseRemapping)
+							{
+								var propertyDescriptor:ToolPropertyDescriptor = 
+								propertyCaseRemapping[propertyName];
+								
+								propertyName = propertyDescriptor.name;
+								
+								var regEx:String = x.Property[property].@regExp;
+								var value:String = x.Property[property].@value;
+								
+								if (regEx == "true" || regEx == "t")
+									part[propertyName] = new RegExp(value);
+								else
+									part[propertyName] = value;
+							}
+						}
+						rid.addLast(part);
+						
+						// we need to decide whehter we are in the correct application
+						if((partIndex == 0) && (fromTool == true))
+						{
+							
+							//requiredApplicationName = part["automationName"][0].toString();
+							requiredApplicationName = getApplicationNameFromAutomationIDPart(part);
+							var currentAppName:String = getApplicationName();
+							
+							// we need to check whether this request is for the
+							// root application or sub application.
+							// if it is for the sub applicaiton, we need to send the information as event to the other
+							// applications and wait for the result.
+							if(requiredApplicationName != currentAppName )
+								sameApplication = false;
+							
+						}
+						partIndex++;
+						x = x.Element.length() == 1 ? x.Element[0] : null;
+					}
+					
+					if (!automationManager.isSynchronized(null))
+					{
+						var message:String = resourceManager.getString(
+							"automation_agent", "notSynchronized");
+						throw new AutomationError(message,
+							AutomationError.OBJECT_NOT_VISIBLE);	
+					}
+					
+					// before we call methods on the automation manger, whether this request is for the
+					// root application or sub application.
+					// if it is for the sub applicaiton, we need to send the information as event to the other
+					// applications and wait for the result.
+					if(sameApplication == true )
+					{
+						
+						if (fromTool == true)
+							detailsSentToTool = true; 
+						
+						//here we can proceed with the root applicaiton. 
+						var autObjects:Array = automationManager.resolveID(rid);
+						for (var i:int = 0; i < autObjects.length; ++i)
+						{
+							autObjects[i] = automationManager.createID(autObjects[i]).toString();
+						}
+						o.result = autObjects;
+						detailsSentToTool = true;
+					}
+					else
+					{
+						
+						
+						// #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed 
+						// across versions. If any new arguements is needed in new versions 
+						// add them to the end of the list and handle appropriately in the 
+						// handler of this event.
+						
+						var details:Array = new Array();
+						details.push(descriptionXML);
+						
+						if(fromTool == true)
+						{
+							requestPending = false;
+							resultRecieved = false;
+						}
+						o.result = handleRequestToDifferentApplication(requiredApplicationName,
+							ToolMarshallingEvent.FIND_OBJECTIDS ,
+							details); 
+						
+						if((resultRecieved == true)&&(fromTool == true))
+						{
+							// since we have recieved the result, we can send the information back to Tool
+							o.result = requestResultObjArray[0];
+							detailsSentToTool = true;
+						}
+					}
+					
+					// if we have not sent the request to Tool, we need to send the error message that we are not yet synchronised
+					// we need this message only if the request to this method has come from Tool			
+					if((detailsSentToTool == false)&&(fromTool == true))
+					{
+						// we dont expect this case to happen. But just to be on the
+						// safe side we are keeping this error
+						var message1:String = resourceManager.getString(
+							"automation_agent", "notSynchronized");
+						throw new AutomationError(message1,
+							AutomationError.OBJECT_NOT_VISIBLE);	
+					}
+					
+				}
+				catch(e:Error)
+				{
+					throw e;
+				}
+				
+				return o;
+			});
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function buildDescription(objID:String, fromTool:Boolean = true):Object
+		{
+			return useErrorHandler(function():Object
+			{
+				var o:Object = { result:null, error:0 };
+				try
+				{
+					var rid:AutomationID = AutomationID.parse(objID);
+					// we need to find out whether the current app and the 
+					// reuired app are the same.
+					var requiredApplicationName:String = getApplicationNameFromAutomationID(rid);
+					var currentApplicationName:String  = getApplicationName();
+					if(requiredApplicationName == currentApplicationName)
+					{
+						if (fromTool == true)
+							detailsSentToTool = true; 
+						
+						var obj:IAutomationObject = automationManager.resolveIDToSingleObject(rid);
+						//Don't use getDescriptionXML because it uses the attributes
+						//that were sent into us, and in theory those attributes could
+						//be regular expressions used to find the item
+						//var result:XML = getDescriptionXML(rid, obj);
+						//XML.prettyPrinting = false;
+						//o.result = stripSlashRHack(result.toXMLString());
+						o.result = getActiveOrLearnXMLTree(objID, false).learnChildrenXML;
+					}
+					else
+					{
+						// #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed 
+						// across versions. If any new arguements is needed in new versions 
+						// add them to the end of the list and handle appropriately in the 
+						// handler of this event.
+						
+						var details:Array = new Array();
+						details.push(objID);
+						
+						if(fromTool == true)
+						{
+							requestPending = false;
+							resultRecieved = false;
+						}
+						o.result = handleRequestToDifferentApplication(requiredApplicationName,
+							ToolMarshallingEvent.BUILD_DESCRIPTION ,
+							details); 
+						
+						if((resultRecieved == true)&&(fromTool == true))
+						{
+							// since we have recieved the result, we can send the information back to Tool
+							o = requestResultObjArray[0];
+							detailsSentToTool = true;
+						}
+						
+					}
+					
+					// if we have not sent the request to Tool, we need to send the error message that we are not yet synchronised
+					// we need this message only if the request to this method has come from Tool			
+					if((detailsSentToTool == false)&&(fromTool == true))
+					{
+						// we dont expect this case to happen. But just to be on the
+						// safe side we are keeping this error
+						var message:String = resourceManager.getString(
+							"automation_agent", "notSynchronized");
+						throw new AutomationError(message,
+							AutomationError.OBJECT_NOT_VISIBLE);	
+					}
+				}
+				catch (e:Error)
+				{
+					throw e;
+				}
+				return o;
+			});
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function getPropertyDescriptors(obj:IAutomationObject, 
+											   names:Array = null, 
+											   forVerification:Boolean = true, 
+											   forDescription:Boolean = true):Array
+		{
+			if (!obj)
+				return null;
+			
+			try
+			{
+				automationManager.incrementCacheCounter();
+				
+				var automationClass:IToolAutomationClass =
+					automationManager.automationEnvironment.getAutomationClassByInstance(obj) as IToolAutomationClass;
+				var i:int;
+				var propertyCaseRemapping:Object = automationClass.propertyLowerCaseMap;
+				
+				var result:Array = [];
+				if (!names)
+				{
+					var propertyDescriptors:Array = 
+						automationClass.getPropertyDescriptors(obj, 
+							forVerification, 
+							forDescription);
+					names = [];
+					for (i = 0; i < propertyDescriptors.length; i++)
+					{
+						names[i] = propertyDescriptors[i].name;
+					}
+				}
+				for (i = 0; i < names.length; i++)
+				{
+					var lowerCaseName:String = names[i].toLowerCase();
+					var propertyDescriptor:ToolPropertyDescriptor = 
+						propertyCaseRemapping[lowerCaseName];
+					result.push(propertyDescriptor);
+				}
+				
+				automationManager.decrementCacheCounter();
+			}
+			catch(e:Error)
+			{
+				automationManager.decrementCacheCounter();
+				
+				throw e;
+			}
+			
+			return result;
+		}
+		
+		private function encodeValues(obj:IAutomationObject, values:Array, descriptors:Array):Array
+		{
+			var result:Array = [];
+			for (var i:int = 0; i < values.length; ++i)
+			{
+				var descriptor:ToolPropertyDescriptor = descriptors[i];
+				var codec:IAutomationPropertyCodec = propertyCodecMap[descriptor.codecName];
+				
+				if (codec == null)
+					codec = propertyCodecMap["object"];
+				
+				var relativeParent:IAutomationObject = obj;
+				
+				var retValue:Object = codec.encode(automationManager, obj, descriptor, relativeParent);
+				result.push({value:retValue, descriptor:descriptor});
+			}
+			
+			return result;
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function getProperties(objID:String, names:String, fromTool:Boolean = true):Object
+		{
+			return useErrorHandler(function():Object
+			{
+				var o:Object = { result:null, error:0 };
+				try
+				{
+					var rid:AutomationID = AutomationID.parse(objID);
+					
+					// we need to find out whether the current app and the 
+					// reuired app are the same.
+					var requiredApplicationName:String = getApplicationNameFromAutomationID(rid);
+					var currentApplicationName:String  = getApplicationName();
+					if(requiredApplicationName == currentApplicationName)
+					{
+						
+						if (fromTool == true)
+							detailsSentToTool = true; 
+						
+						// we are in the same applicaiton, and hence we can proceed.
+						var obj:IAutomationObject = automationManager.resolveIDToSingleObject(rid);
+						var asNames:Array = convertArrayFromCrazyToAs(names);
+						var descriptors:Array = [];
+						if(asNames && asNames.length)
+						{
+							var automationClass:IToolAutomationClass =
+							automationManager.automationEnvironment.getAutomationClassByInstance(obj) as IToolAutomationClass;;
+							var propertyCaseRemapping:Object = automationClass.propertyLowerCaseMap;
+							for (var i:int = 0; i < asNames.length; i++)
+							{
+								var lowerCaseName:String = asNames[i].toLowerCase();
+								var propertyDescriptor:IAutomationPropertyDescriptor = 
+								propertyCaseRemapping[lowerCaseName];
+								if(propertyDescriptor)
+								{
+									asNames[i] = propertyDescriptor.name;
+									descriptors.push(propertyDescriptor);
+								}
+								else
+									// descriptor was not found delete the entry.
+									asNames.splice(i, 1);
+								
+							}
+							
+						}
+						
+						var values:Array = automationManager.getProperties(obj, asNames);
+						var x:Array = encodeValues(obj, values, descriptors);
+						for (var no:int = 0; no < x.length; ++no)
+						{
+							if((x[no].value) is String)
+								x[no] = checkForSpecialCharsInString((x[no].value) as String );
+							else
+								x[no] = (x[no].value);
+						}
+						
+						o.result = x;
+					}
+					else
+					{
+						// we need to send this as information to the other application 
+						// and let the appropriate application handle it.
+						
+						// #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed 
+						// across versions. If any new arguements is needed in new versions 
+						// add them to the end of the list and handle appropriately in the 
+						// handler of this event.
+						
+						var details:Array = new Array();
+						details.push(objID);
+						details.push(names);
+						
+						if(fromTool == true)
+						{
+							requestPending = false;
+							resultRecieved = false;
+						}
+						o.result =   handleRequestToDifferentApplication(requiredApplicationName, 
+							ToolMarshallingEvent.GET_PROPERTIES,details);
+						if((resultRecieved == true)&&(fromTool == true))
+						{
+							// since we have recieved the result, we can send the information back to Tool
+							o =  requestResultObjArray[0] as Object;
+							detailsSentToTool = true;
+						}
+					}
+				}
+				catch (e:Error)
+				{
+					throw e;
+				}
+				return o;
+			});
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function getParent(objID:String, fromTool:Boolean = true):Object
+		{
+			return useErrorHandler(function():Object
+			{
+				var o:Object = { result:null, error:0 };
+				try
+				{
+					var rid:AutomationID = AutomationID.parse(objID);        	
+					// we need to find out whether the current app and the 
+					// reuired app are the same.
+					var requiredApplicationName:String = getApplicationNameFromAutomationID(rid);
+					var currentApplicationName:String  = getApplicationName();
+					if(requiredApplicationName == currentApplicationName)
+					{
+						
+						if (fromTool == true)
+							detailsSentToTool = true; 
+						
+						var obj:IAutomationObject = automationManager.resolveIDToSingleObject(rid);
+						obj = automationManager.getParent(obj);
+						o.result = (obj 
+							? automationManager.createID(obj).toString() 
+							: null);
+					}
+					else
+					{
+						// we need to send this as information to the other application 
+						// and let the appropriate application handle it.
+						
+						// #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed 
+						// across versions. If any new arguements is needed in new versions 
+						// add them to the end of the list and handle appropriately in the 
+						// handler of this event.
+						
+						var details:Array = new Array();
+						details.push(objID);	
+						
+						if(fromTool == true)
+						{
+							requestPending = false;
+							resultRecieved = false;
+						}
+						o.result =   handleRequestToDifferentApplication(requiredApplicationName, 
+							ToolMarshallingEvent.GET_PARENT,details);
+						if((resultRecieved == true)&&(fromTool == true))
+						{
+							// since we have recieved the result, we can send the information back to Tool
+							o =  requestResultObjArray[0] as Object;
+							detailsSentToTool = true;
+						}
+					}
+					
+					// if we have not sent the request to Tool, we need to send the error message that we are not yet synchronised
+					// we need this message only if the request to this method has come from Tool			
+					if((detailsSentToTool == false)&&(fromTool == true))
+					{
+						// we dont expect this case to happen. But just to be on the
+						// safe side we are keeping this error
+						var message:String = resourceManager.getString(
+							"automation_agent", "notSynchronized");
+						throw new AutomationError(message,
+							AutomationError.OBJECT_NOT_VISIBLE);	
+					}
+				}
+				catch(e:Error)
+				{
+					throw e;
+				}
+				return o;
+			});
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function getChildren(objID:String, 
+									filterXMLString:String = null, fromTool:Boolean = true):Object
+		{
+			return useErrorHandler(function():Object
+			{
+				var o:Object = { result:null, error:0 };
+				try
+				{
+					var rid:AutomationID = AutomationID.parse(objID);
+					// we need to find out whether the current app and the 
+					// reuired app are the same.
+					var requiredApplicationName:String = getApplicationNameFromAutomationID(rid);
+					var currentApplicationName:String  = getApplicationName();
+					if(requiredApplicationName == currentApplicationName)
+					{
+						
+						if (fromTool == true)
+							detailsSentToTool = true; 
+						
+						var autObject:IAutomationObject = automationManager.resolveIDToSingleObject(rid);
+						var children:Array;
+						if (autObject.numAutomationChildren > 0)
+						{
+							var part:AutomationIDPart = createPartFromFilterXML(filterXMLString);
+							children = automationManager.getChildrenFromIDPart(autObject, part);
+							
+							for (var i:int = 0; i < children.length; ++i)
+							{
+								children[i] = automationManager.createID(children[i]).toString();
+							}
+						}
+						else
+							children = [automationManager.createID(autObject).toString()];
+						
+						o.result = children;
+					} 
+					else
+					{
+						// we need to send this as information to the other application 
+						// and let the appropriate application handle it.
+						
+						// #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed 
+						// across versions. If any new arguements is needed in new versions 
+						// add them to the end of the list and handle appropriately in the 
+						// handler of this event.
+						
+						var details:Array = new Array();
+						details.push(objID);
+						details.push(filterXMLString);	
+						
+						if(fromTool == true)
+						{
+							requestPending = false;
+							resultRecieved = false;
+						}
+						o.result =   handleRequestToDifferentApplication(requiredApplicationName, 
+							ToolMarshallingEvent.GET_CHILDREN,details);
+						if((resultRecieved == true)&&(fromTool == true))
+						{
+							// since we have recieved the result, we can send the information back to Tool
+							o =  requestResultObjArray[0] as Object;
+							detailsSentToTool = true;
+						}
+					}
+				}
+				catch (e:Error)
+				{
+					throw e;
+				}
+				return o;
+			});
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function setLastError(message:String,fromTool:Boolean = true):void
+		{
+			var message:String = "WARNING....... somebody called setLastError. This was not tested for Marshalling";
+			Automation.automationDebugTracer.traceMessage("ToolAdapter","setLastError()",message);
+			// we need to find out which was the last responded application.
+			var currentAppname:String = getApplicationName();
+			if ((fromTool == false) || (currentAppname == lastResponseRecievedApplicationName))
+			{
+				lastError = new Error(message);
+			}
+			else
+			{
+				// this will be called if the fromTool == true and currentAppname != lastResponseRecievedApplicationName
+				// we need to dispatch the event and get the error details from the appropriate application
+				
+				// we need to send this as information to the other application 
+				// and let the appropriate application handle it.
+				
+				// #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed 
+				// across versions. If any new arguements is needed in new versions 
+				// add them to the end of the list and handle appropriately in the 
+				// handler of this event.
+				
+				var details:Array = new Array();
+				details.push(message);	
+				handleRequestToDifferentApplication(lastResponseRecievedApplicationName, 
+					ToolMarshallingEvent.SET_LAST_ERROR,details);
+				
+			}
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function getLastError(fromTool:Boolean = true):Object
+		{
+			// we need to find out which was the last responded application.
+			var currentAppname:String = getApplicationName();
+			if ((fromTool == false) || (currentAppname == lastResponseRecievedApplicationName))
+			{
+				detailsSentToTool = true; 
+				return { result: (lastError ? lastError.message.substr(0, 1 << 9) : ""), 
+					error: 0 };
+				
+			}
+			else
+			{
+				var o:Object = { result:"", error:0 };
+				// we will reach this condition only when fromTool == true and 
+				// currentAppname != lastResponseRecievedApplicationName
+				// we need to dispatch the event and get the error details from the appropriate application
+				
+				// we need to send this as information to the other application 
+				// and let the appropriate application handle it.
+				
+				// #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed 
+				// across versions. If any new arguements is needed in new versions 
+				// add them to the end of the list and handle appropriately in the 
+				// handler of this event.
+				
+				var details:Array = new Array();
+				//details.push(lastResponseRecievedApplicationName);	
+				
+				if(fromTool == true)
+				{
+					requestPending = false;
+					resultRecieved = false;
+				}
+				
+				o.result =   handleRequestToDifferentApplication(lastResponseRecievedApplicationName, 
+					ToolMarshallingEvent.GET_LAST_ERROR,details);
+				if(o.result == null)
+					o.result = "";
+				if((resultRecieved == true)&&(fromTool == true))
+				{
+					// since we have recieved the result, we can send the information back to Tool
+					o =  requestResultObjArray[0] as Object;
+					detailsSentToTool = true;
+				}
+				
+				return o;
+			}
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function getRectangle(objID:String, fromTool:Boolean = true):Object
+		{
+			return useErrorHandler(function():Object
+			{
+				var o:Object = { result:null, error:0 };
+				try
+				{
+					var rid:AutomationID = AutomationID.parse(objID);
+					// we need to find out whether the current app and the 
+					// reuired app are the same.
+					var requiredApplicationName:String = getApplicationNameFromObjectIDString(objID);
+					var currentApplicationName:String  = getApplicationName();
+					if(requiredApplicationName == currentApplicationName)
+					{
+						
+						if (fromTool == true)
+							detailsSentToTool = true; 
+						
+						var obj:IAutomationObject = automationManager.resolveIDToSingleObject(rid);
+						o.result = automationManager.getRectangle(obj as DisplayObject);	            
+					}
+					else
+					{
+						// we need to send this as information to the other application 
+						// and let the appropriate application handle it.
+						
+						// #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed 
+						// across versions. If any new arguements is needed in new versions 
+						// add them to the end of the list and handle appropriately in the 
+						// handler of this event.
+						var details:Array = new Array();
+						details.push(objID);	
+						
+						if(fromTool == true)
+						{
+							requestPending = false;
+							resultRecieved = false;
+						}
+						
+						o.result =   handleRequestToDifferentApplication(requiredApplicationName,
+							ToolMarshallingEvent.GET_RECTANGLE,details);
+						if((resultRecieved == true)&&(fromTool == true))
+						{
+							// since we have recieved the result, we can send the information back to Tool
+							o =  requestResultObjArray[0] as Object;
+							detailsSentToTool = true;
+						}
+					}
+					
+				}
+				catch(e:Error)
+				{
+					throw e;
+				}
+				return o;
+			});
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function getElementFromPoint(x:int, y:int, fromTool:Boolean= true):Object
+		{
+			return useErrorHandler(function():Object
+			{
+				var o:Object = { result:null, error:0 };
+				try
+				{
+					var details:Array = new Array();
+					details.push(x);
+					details.push(y);
+					var isApplication:Boolean;
+					
+					// here the handling is different from the other methods
+					// here we need just let the sub application handle the point
+					// first. if no sub application handles the point, then the main application needs to handle the same
+					if(fromTool == true)
+					{
+						// we need to send this as information to the other application 
+						// and let the appropriate application handle it.
+						
+						// #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed 
+						// across versions. If any new arguements is needed in new versions 
+						// add them to the end of the list and handle appropriately in the 
+						// handler of this event.
+						if(fromTool == true)
+						{
+							requestPending = false;
+							resultRecieved = false;
+						}
+						// in the case of this method, we need to let all application process
+						// the request. If the application is able to process the details, we need to 
+						// get the details. If we get a Popup or Alerts we need to give the importance of the same.
+						// secondly we need to give priority of a non SWFLoader object.
+						
+						
+						// first let us call from the main applicaiton
+						var obj:IAutomationObject = automationManager.getElementFromPoint(x, y);
+						var mainAppObj:Object = null;
+						
+						
+						// add the result to the resultObejct array  if the result is not a SWFLoader
+						// Note: we need to check how the object is to be handled when the 
+						// application is loaded using Loader
+						if((obj != null) && (!(isObjectSWFLoader(obj1))))
+						{	
+							isApplication = obj is Application;
+							var currentAppName1:String =  getApplicationName();
+							// we dont need to find out if the object belong to popup
+							// if we dont get a pop up from child, and if we got and
+							// object from main application, main application object has the 
+							// preference.
+							var isPopup1:Boolean = automationManager.isObjectPopUp(obj);
+							mainAppObj = { result:null, applicationName:currentAppName1, 
+								isPopup:isPopup1, error:0, isApplication:isApplication };			    		
+							var result:AutomationID = automationManager.createID(obj);
+							mainAppObj.result = result.toString();
+						}
+						
+						// irrespective of the result from the main application we 
+						// to check what is the object at this point by other application.
+						handleRequestToDifferentApplication(null, 
+							ToolMarshallingEvent.GET_ELEMENT_FROM_POINT,details);
+						
+						if(mainAppObj)
+						{
+							var tempArray:Array = new Array();
+							tempArray.push(mainAppObj);
+							requestResultObjArray = tempArray.concat(requestResultObjArray);
+						}	
+						
+						
+						
+						// we would have got replies from all applicaitons which could process the object
+						var count:int = requestResultObjArray.length;
+						if(count != 0)
+						{
+							var index:int = 0;
+							var requiredObjectIdentified:Boolean = false;
+							// process each object
+							var currentObj:Object = null;
+							while((!requiredObjectIdentified) && (index < count))
+							{
+								currentObj = requestResultObjArray[index];
+								if(currentObj["isPopup"]  == true) 
+								{
+									// NOTE: TBD: we need to handle the case of other objects which can be
+									// hosted by the PopupManager
+									requiredObjectIdentified = true;
+								}
+								index++;
+							}
+							
+							if(requiredObjectIdentified == true)
+							{
+								lastApplicationName = currentObj["applicationName" ];
+								o.result = currentObj.result;
+							}
+							else
+							{
+								// the last loaded application need not be the application on the top.
+								// this depends on the order of the swfloader in an application.
+								// so we need to get the index of the last application.
+								var lastRequiredObjectIndex:int =  automationManager.getTopApplicationIndex(requestResultObjArray);
+								
+								//var lastRequiredObjectIndex:int = requestResultObjArray.length - 1;			    			
+								
+								if(lastRequiredObjectIndex != -1)
+								{
+									currentObj = requestResultObjArray[lastRequiredObjectIndex];
+									lastApplicationName = currentObj["applicationName" ];
+									o.result = currentObj.result;
+								}
+							}
+						}
+						
+						detailsSentToTool = true;
+						
+					}
+					else
+					{
+						var obj1:IAutomationObject = automationManager.getElementFromPoint(x, y);
+						
+						// check whether the object is a child of system manager
+						// we expect the Alerts and object hosted by the PopupManager 
+						// only to get a special treatment
+						if((obj1 != null) && (!isObjectSWFLoader(obj1)))
+						{
+							var isPopup:Boolean = automationManager.isObjectPopUp(obj1);
+							
+							var result1:AutomationID = automationManager.createID(obj1);
+							isApplication = obj1 is Application;
+							var currentAppName:String =  getApplicationName();
+							var o2:Object = { result:null, applicationName:currentAppName, 
+								isPopup:isPopup, error:0, isApplication:isApplication };
+							o2.result = result1.toString();
+							return o2;
+						}
+						
+					}
+				}
+				catch (e:Error)
+				{
+					throw e;
+				}
+				return o;
+			});
+		}
+		
+		
+		private function isObjectSWFLoader(obj:Object):Boolean
+		{
+			var retValue:Boolean = false;
+			if(obj is SWFLoader)
+			{
+				// Image is also a SWFLoader. But we should not ignore that.
+				if(!(obj is Image))
+					retValue = true;
+			}
+			return retValue
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function getActiveScreen(level:uint, 
+										objID:String,
+										leftOffset:int,
+										topOffset:int, fromTool:Boolean = true):Object
+		{
+			return useErrorHandler(function():Object
+			{
+				var o:Object = { result:null, error:0 };
+				try
+				{
+					// we need to find out whether the current app and the 
+					// reuired app are the same.
+					var requiredApplicationName:String = getApplicationNameFromObjectIDString(objID);
+					var currentApplicationName:String  = getApplicationName();
+					if(requiredApplicationName == currentApplicationName)
+					{
+						if (fromTool == true)
+							detailsSentToTool = true; 
+						//we could make the 2nd parameter true if we wanted to support
+						//the complete level
+						o.result = getActiveOrLearnXMLTree(objID, false, "", true, leftOffset, topOffset).learnChildrenXML;
+					}
+					else
+					{
+						// we need to send this as information to the other application 
+						// and let the appropriate application handle it.
+						
+						// #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed 
+						// across versions. If any new arguements is needed in new versions 
+						// add them to the end of the list and handle appropriately in the 
+						// handler of this event.
+						var details:Array = new Array();
+						details.push(level);
+						details.push(objID);
+						details.push(leftOffset);
+						details.push(topOffset);	
+						
+						if(fromTool == true)
+						{
+							requestPending = false;
+							resultRecieved = false;
+						}
+						
+						o.result =   handleRequestToDifferentApplication(requiredApplicationName,
+							ToolMarshallingEvent.GET_ACTIVESCREEN,details);
+						if((resultRecieved == true)&&(fromTool == true))
+						{
+							// since we have recieved the result, we can send the information back to Tool
+							o =  requestResultObjArray[0] as Object;
+							detailsSentToTool = true;
+						}
+					}
+					
+				}
+				catch(e:Error)
+				{
+					throw e;
+				}
+				
+				return o;
+			});
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function learnChildObjects(objID:String,
+										  filterXMLString:String, fromTool:Boolean = true):Object
+		{
+			return useErrorHandler(function():Object
+			{
+				var o:Object = { result:null, error:0 };
+				try
+				{
+					// we need to find out whether the current app and the 
+					// reuired app are the same.
+					var requiredApplicationName:String = getApplicationNameFromObjectIDString(objID);
+					var currentApplicationName:String  = getApplicationName();
+					if(requiredApplicationName == currentApplicationName)
+					{
+						if (fromTool == true)
+							detailsSentToTool = true; 
+						//we could make the 2nd parameter true if we wanted to support
+						//the complete level
+						o.result = getActiveOrLearnXMLTree(objID, true, filterXMLString);
+					}
+					else
+					{
+						// we need to send this as information to the other application 
+						// and let the appropriate application handle it.
+						
+						// #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed 
+						// across versions. If any new arguements is needed in new versions 
+						// add them to the end of the list and handle appropriately in the 
+						// handler of this event.
+						var details:Array = new Array();
+						details.push(objID);			
+						details.push(filterXMLString);	
+						
+						if(fromTool == true)
+						{
+							requestPending = false;
+							resultRecieved = false;
+						}
+						o.result =   handleRequestToDifferentApplication(requiredApplicationName, 
+							ToolMarshallingEvent.LEARN_CHILD_OBJECTS,details);
+						if((resultRecieved == true)&&(fromTool == true))
+						{
+							// since we have recieved the result, we can send the information back to Tool
+							o =  requestResultObjArray[0] as Object;
+							detailsSentToTool = true;
+						}
+					}
+					
+				}
+				catch(e:Error)
+				{
+					throw e;
+				}
+				return o;
+			});
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function getTabularData(objID:String, begin:uint = 0, end:uint = 0, fromTool:Boolean = true):Object
+		{
+			return useErrorHandler(function():Object
+			{
+				var o:Object = { result:null, error:0 };
+				try
+				{
+					var rid:AutomationID = AutomationID.parse(objID);
+					
+					
+					// we need to find out whether the current app and the 
+					// reuired app are the same.
+					var requiredApplicationName:String = getApplicationNameFromAutomationID(rid);
+					var currentApplicationName:String  = getApplicationName();
+					if(requiredApplicationName == currentApplicationName)
+					{
+						if (fromTool == true)
+							detailsSentToTool = true; 
+						
+						var obj:IAutomationObject = automationManager.resolveIDToSingleObject(rid);
+						var td:IAutomationTabularData = automationManager.getTabularData(obj);
+						o.result = {
+							columnTitles: td ? td.columnNames : [],
+							tableData: (td 
+								? checkForSpecialCharsInArray(td.getValues(begin, end)) 
+								: [[]])
+						};
+					}
+					else
+					{
+						// we need to send this as information to the other application 
+						// and let the appropriate application handle it.
+						
+						// #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed 
+						// across versions. If any new arguements is needed in new versions 
+						// add them to the end of the list and handle appropriately in the 
+						// handler of this event.
+						var details:Array = new Array();
+						details.push(objID);			
+						details.push(begin);				
+						details.push(end);			    	
+						if(fromTool == true)
+						{
+							requestPending = false;
+							resultRecieved = false;
+						}
+						o.result =   handleRequestToDifferentApplication(requiredApplicationName, 
+							ToolMarshallingEvent.GET_TABULAR_DATA,details);
+						if((resultRecieved == true)&&(fromTool == true))
+						{
+							// since we have recieved the result, we can send the information back to Tool
+							o =  requestResultObjArray[0] as Object;
+							detailsSentToTool = true;
+						}
+					}
+					
+				}
+				catch(e:Error)
+				{
+					throw e;
+				}
+				return o;
+			});
+		}
+		
+		public function getTabularAttributes(objID:String, fromTool:Boolean = true):Object
+		{
+			return useErrorHandler(function():Object
+			{
+				var o:Object = { result:null, error:0 };
+				try
+				{
+					var rid:AutomationID = AutomationID.parse(objID);
+					
+					
+					// we need to find out whether the current app and the 
+					// reuired app are the same.
+					var requiredApplicationName:String = getApplicationNameFromAutomationID(rid);
+					var currentApplicationName:String  = getApplicationName();
+					if(requiredApplicationName == currentApplicationName)
+					{
+						if (fromTool == true)
+							detailsSentToTool = true; 
+						
+						var obj:IAutomationObject = automationManager.resolveIDToSingleObject(rid);
+						var td:IAutomationTabularData = automationManager.getTabularData(obj);
+						o.result = {
+							minVisibleRow: td ? td.firstVisibleRow : [],
+							maxVisibleRow: td ? td.lastVisibleRow : [],
+							fullSize: td ? td.numRows : []
+						};
+						
+					}
+					else
+					{
+						// we need to send this as information to the other application 
+						// and let the appropriate application handle it.
+						
+						// #IMP: MARSHALLING NOTE#: This order of ariguments should not be changed 
+						// across versions. If any new arguements is needed in new versions 
+						// add them to the end of the list and handle appropriately in the 
+						// handler of this event.
+						var details:Array = new Array();
+						details.push(objID);		    	
+						if(fromTool == true)
+						{
+							requestPending = false;
+							resultRecieved = false;
+						}
+						o.result =   handleRequestToDifferentApplication(requiredApplicationName, 
+							ToolMarshallingEvent.GET_TABULAR_ATTRIBUTES,details);
+						if((resultRecieved == true)&&(fromTool == true))
+						{
+							// since we have recieved the result, we can send the information back to Tool
+							o =  requestResultObjArray[0] as Object;
+							detailsSentToTool = true;
+						}
+					}
+					
+				}
+				catch(e:Error)
+				{
+					throw e;
+				}
+				return o;
+			});
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function useErrorHandler(f:Function):Object
+		{
+			var o:Object = { result:null, error:0 };
+			try
+			{
+				o = f();
+			}
+			catch (e:Error)
+			{
+				lastError = e;
+				o.error = (e is AutomationError 
+					? AutomationError(e).code 
+					: AutomationError.ILLEGAL_OPERATION);
+				Automation.automationDebugTracer.traceMessage("ToolAdapter","useErrorHandler()",e.message);
+			}
+			return o;
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function getDescriptionXML(rid:AutomationID, 
+										   target:IAutomationObject):XML
+		{
+			var obj:IAutomationObject = target;
+			var result:XML;
+			while (obj)
+			{
+				var part:AutomationIDPart = rid.removeLast();
+				if (automationManager.showInHierarchy(obj) || target == obj)
+				{
+					var automationClass:String = automationManager.getAutomationClassName(obj);
+					var automationName:String = part.automationName;
+					
+					//build description xml - probably could use the same methods
+					//that learn and activescreen use, but those were added later
+					//and this has been working so don't fix it
+					var x:XML = (<Element type={automationClass}
+						name={automationName}/>);
+					for (var i:String in part)
+						x.appendChild(<Property name={i} value={part[i] != null ? part[i] : ""}/>);
+					
+					if (result)
+						x.appendChild(result);
+					result = x;
+				}
+				obj = automationManager.getParent(obj);
+			}
+			return new XML(result);
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function createPartFromFilterXML(filterXMLString:String):AutomationIDPart
+		{
+			var part:AutomationIDPart = new AutomationIDPart();
+			var filterXML:XML = new XML(filterXMLString);
+			for (var o:Object in filterXML.Property)
+			{
+				var propertyNode:XML = filterXML.Property[o];
+				var name:String = propertyNode.@Name.toString();
+				var value:String = propertyNode.@Value.toString();
+				
+				if(name.toLowerCase() == "automationname")
+					name = "automationName";
+				else if(name.toLowerCase() == "automationindex")
+					name = "automationIndex";
+				else if(name.toLowerCase() == "classname")
+					name = "className";
+				else if(name.toLowerCase() == "id")
+					name = "id";
+				if (propertyNode.@RegExp.toString() == "true")
+					part[name] = new RegExp(value);
+				else
+					part[name] = value;
+			}
+			
+			if (filterXML.@Type && filterXML.@Type.toString().length != 0)
+				part["automationClassName"] = filterXML.@Type.toString();
+			
+			return part;
+		}    
+		
+		/**
+		 *  @private
+		 */
+		private function getActiveOrLearnXMLTree(objID:String,
+												 addChildren:Boolean,
+												 filterXML:String = "",
+												 addActiveInfo:Boolean = false,
+												 leftOffset:int = -1,
+												 topOffset:int = -1):Object
+		{
+			var rid:AutomationID = AutomationID.parse(objID);
+			var activeAO:IAutomationObject = automationManager.resolveIDToSingleObject(rid);
+			var rids:Array = addActiveInfo ? null : [];
+			
+			//add the current item
+			var activeNode:XML = getActiveOrLearnScreenXML(rids, 
+				activeAO, 
+				true, 
+				addActiveInfo, 
+				leftOffset, 
+				topOffset);
+			
+			//add the children
+			if (addChildren)
+				getActiveOrLearnChildrenXML(rids, 
+					activeAO, 
+					filterXML, 
+					activeNode, 
+					addActiveInfo, 
+					leftOffset, 
+					topOffset);
+			
+			//add the parents
+			var result:XML = getActiveOrLearnParentsXML(rids, 
+				automationManager.getParent(activeAO), 
+				activeNode, 
+				addActiveInfo, 
+				leftOffset, 
+				topOffset);
+			// We are storing the actual pretty printing value so that we can
+			// reset it back when we are done with our operation.
+			// Ref: http://bugs.adobe.com/jira/browse/FLEXENT-1140
+			var actualPrettyPrinting:Boolean = XML.prettyPrinting;
+			
+			XML.prettyPrinting = false;
+			var resultXMLString:String;
+			
+			// using the check to see if we are requesting activeScreen XML or learn XML
+			// activeScreenXML requires the outermost element to contain the bounding rectangle
+			// learn XML doesnot require this.
+			// let us try to get the global coordinate of the start point of the application.
+			/*
+			if(leftOffset != -1)
+			{
+			var wrapper:XML = <Element> 
+			<Rectangle left={leftOffset} top={topOffset} 
+			right={leftOffset + Application.application.screen.right}
+			bottom = {topOffset + Application.application.screen.bottom}/> 
+			</Element>;
+			wrapper.appendChild(result);
+			resultXMLString = String(wrapper.toXMLString());
+			}
+			*/
+			
+			var appObj:Object = Automation.getMainApplication();
+			
+			// when there are multiple application we cannot directly treat the player start coordinates
+			// as our start coordinate. So we need to find the start coordinate of the current application

[... 620 lines stripped ...]