Transferred from the Adobe Open Source Subversion Repository

Revision: 12850
Author:   jimurphy@adobe.com
Date:     2009-12-11T14:57:14.623098Z

Log Message:
-----------
add 6 new DMV projects to the SDK:
automation
automation_air
automation_dmv
automation_flashflexkit
automation_spark
datavisualization

These projects are setup to build in an ant main call.  There are currently several warnings in the datavisualization project that will be cleaned up.  No checkintests exist for these projects as of yet.

I also modified the exisitng projects build files for easier management of the localization targets, bundle and fat-swc. If the projects that I updated:airframework,airspark,framework,playerglobal,rpc,and spark.  All the new projects have been implemented this same way.

QE notes: DMV folks should run through their tests
Doc notes: probably
Bugs: nope
Reviewer:
Tests run: ran the following targets: compile,checkintests,other.locales and doc
Is noteworthy for integration: no

Modified Paths:
--------------
1404 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1252116 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/automation_spark/src/spark/automation/delegates/components/SparkGroupAutomationImpl.as
+++ frameworks/projects/automation_spark/src/spark/automation/delegates/components/SparkGroupAutomationImpl.as
@@ -0,0 +1,205 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  ADOBE SYSTEMS INCORPORATED
+//  Copyright 2009 Adobe Systems Incorporated
+//  All Rights Reserved.
+//
+//  NOTICE: Adobe permits you to use, modify, and distribute this file
+//  in accordance with the terms of the license agreement accompanying it.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.automation.delegates.components
+{
+	import flash.display.DisplayObject;
+	import flash.events.Event;
+	import flash.events.KeyboardEvent;
+	import flash.events.MouseEvent;
+
+	import mx.automation.Automation;
+	import mx.automation.IAutomationObject;
+	import mx.automation.IAutomationObjectHelper;
+	import mx.core.mx_internal;
+
+	import spark.automation.delegates.components.supportClasses.SparkGroupBaseAutomationImpl;
+	import spark.components.Group;
+
+	use namespace mx_internal;
+
+	[Mixin]
+	/**
+	 *
+	 *  Defines methods and properties required to perform instrumentation for the
+	 *  Group control.
+	 *
+	 *  @see spark.components.Group
+	 *
+	 */
+	public class SparkGroupAutomationImpl extends SparkGroupBaseAutomationImpl
+	{
+		include "../../../core/Version.as";
+		//--------------------------------------------------------------------------
+		//
+		//  Class methods
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  Registers the delegate class for a component class with automation manager.
+		 *
+		 *  @param root The SystemManger of the application.
+		 */
+		public static function init(root:DisplayObject):void
+		{
+			Automation.registerDelegateClass(spark.components.Group, SparkGroupAutomationImpl);
+		}
+
+		/**
+		 *  Constructor.
+		 * @param obj Group object to be automated.
+		 */
+		public function SparkGroupAutomationImpl(obj:spark.components.Group)
+		{
+			super(obj);
+			recordClick = true;
+		}
+
+		/**
+		 *  @private
+		 *  storage for the owner component
+		 */
+		protected function get group():spark.components.Group
+		{
+			return uiComponent as spark.components.Group;
+		}
+
+		//----------------------------------
+		//  automationName
+		//----------------------------------
+
+		/**
+		 *  @private
+		 */
+		override public function get automationName():String
+		{
+			if (group.id)
+				return group.id;
+			else
+			{
+				var result:String ;
+
+				var childList:Array = getAutomationChildren();
+				var n:int = childList ? childList.length:0;
+				for (var i:int = 0; i < n; i++)
+				{
+					var child:IAutomationObject = childList[i];
+					if(child != null) // we can have non automation elements like graphic elements also.
+					{
+						if((result == null) || (result == ""))
+							result = child.automationName;
+						else
+							result = result + "|" + child.automationName;
+					}
+				}
+
+				if(result == "")
+					return super.automationName;
+				else
+					return result;
+			}
+
+
+		}
+
+		//----------------------------------
+		//  automationValue
+		//----------------------------------
+
+		/**
+		 *  @private
+		 */
+		override public function get automationValue():Array
+		{
+			if (group.id && group.id.length != 0)
+				return [ group.id ];
+
+			var result:Array = [];
+			var childList:Array = getAutomationChildren();
+			var n:int = childList ? childList.length:0;
+			for (var i:int = 0; i < n; i++)
+			{
+				var child:IAutomationObject = childList[i];
+				if(child != null) // we can have non automation elements like graphic elements also.
+				{
+					var x:Array = child.automationValue;
+					if (x && x.length != 0)
+						result.push(x.join(" | "));
+				}
+			}
+
+			return  result;
+
+		}
+
+
+
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden methods
+		//
+		//--------------------------------------------------------------------------
+
+		/**
+		 *  @private
+		 *  Replays click interactions on the button.
+		 *  If the interaction was from the mouse,
+		 *  dispatches MOUSE_DOWN, MOUSE_UP, and CLICK.
+		 *  If interaction was from the keyboard,
+		 *  dispatches KEY_DOWN, KEY_UP.
+		 *  Button's KEY_UP handler then dispatches CLICK.
+		 *
+		 *  @param event ReplayableClickEvent to replay.
+		 */
+		override public function replayAutomatableEvent(event:Event):Boolean
+		{
+			var help:IAutomationObjectHelper = Automation.automationObjectHelper;
+
+			if (event is MouseEvent && event.type == MouseEvent.CLICK)
+				return help.replayClick(uiComponent, MouseEvent(event));
+			else if (event is KeyboardEvent)
+			{
+				// the key board events happens on the scroller.
+				var scroller:spark.components.Scroller = getInternalScroller();
+				if(scroller)
+				{
+					var helper:IAutomationObjectHelper = Automation.automationObjectHelper;
+					if(helper)
+						helper.replayKeyboardEvent(scroller,event as KeyboardEvent);
+
+				}
+				return true;
+			}
+			else
+				return super.replayAutomatableEvent(event);
+		}
+
+
+		/**
+		 *  @private
+		 */
+		override public function get numAutomationChildren():int
+		{
+			return group.numChildren;
+		}
+
+		/**
+		 *  @private
+		 */
+		override public function getAutomationChildAt(index:int):IAutomationObject
+		{
+			return group.getChildAt(index) as IAutomationObject;
+		}
+
+	}
+
+}


Transferred from the Adobe Open Source Subversion Repository

Revision: 16822
Author:   deeptika@adobe.com
Date:     2010-07-07T06:16:32.586582Z

Log Message:
-----------
Removing deprecated API and their usage.

QE notes:
Doc notes:
Bugs: FLEXDMV-2463 (LineaSeries legendData marker are not working if the series has lineStroke to a SolidColorStroke)
FLEXDMV-2470 (Remove deprecation or Remove deprecated properties in charting)
Reviewer:
Tests run:
Is noteworthy for integration:

Modified Paths:
--------------
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/BarChart.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/automation_dmv/src/mx/automation/delegates/charts/CartesianChartAutomationImpl.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/renderers/AreaRenderer.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/AreaChart.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/series/HLOCSeries.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/series/LineSeries.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/PlotChart.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/series/BubbleSeries.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/series/ColumnSeries.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/automation/src/mx/automation/tabularData/CartesianChartTabularData.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/CandlestickChart.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/HLOCChart.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/chartClasses/StackedSeries.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/series/BarSeries.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/LineChart.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/chartClasses/HLOCSeriesBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/chartClasses/CartesianChart.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/chartClasses/ChartBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/BubbleChart.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/series/AreaSeries.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/chartClasses/PolarChart.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/ColumnChart.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/series/PlotSeries.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/datavisualization/src/mx/charts/renderers/HLOCItemRenderer.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1253036 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/charts/src/mx/charts/chartClasses/HLOCSeriesBase.as
+++ frameworks/projects/charts/src/mx/charts/chartClasses/HLOCSeriesBase.as
@@ -729,13 +729,7 @@
                     allSeriesTransform = false;
             }

-         	n = cChart.secondSeries.length;
-            for (i = 0; i < n; i++)
-            {
-                if (cChart.getSeriesTransformState(cChart.secondSeries[i]))
-                    allSeriesTransform = false;
-            }
-            if (allSeriesTransform)
+         	if (allSeriesTransform)
                 cChart.measureLabels();
         }
     }
@@ -775,26 +769,14 @@
         {
             if (!_horizontalAxis)
             {
-                if (c.secondSeries.indexOf(this) != -1 && c.secondHorizontalAxis)
-                {
-                    if (dataTransform.axes[CartesianTransform.HORIZONTAL_AXIS] != c.secondHorizontalAxis)
-                        CartesianTransform(dataTransform).setAxis(
-                            CartesianTransform.HORIZONTAL_AXIS,c.secondHorizontalAxis);
-                }
-                else if (dataTransform.axes[CartesianTransform.HORIZONTAL_AXIS] != c.horizontalAxis)
+                if (dataTransform.axes[CartesianTransform.HORIZONTAL_AXIS] != c.horizontalAxis)
                         CartesianTransform(dataTransform).setAxis(
                             CartesianTransform.HORIZONTAL_AXIS,c.horizontalAxis);
             }

             if (!_verticalAxis)
             {
-                if (c.secondSeries.indexOf(this) != -1 && c.secondVerticalAxis)
-                {
-                    if (dataTransform.axes[CartesianTransform.VERTICAL_AXIS] != c.secondVerticalAxis)
-                        CartesianTransform(dataTransform).setAxis(
-                            CartesianTransform.VERTICAL_AXIS,c.secondVerticalAxis);
-                }
-                else if (dataTransform.axes[CartesianTransform.VERTICAL_AXIS] != c.verticalAxis)
+                if (dataTransform.axes[CartesianTransform.VERTICAL_AXIS] != c.verticalAxis)
                         CartesianTransform(dataTransform).setAxis(
                             CartesianTransform.VERTICAL_AXIS, c.verticalAxis);
             }


Transferred from the Adobe Open Source Subversion Repository

Revision: 23243
Author:   cframpto@adobe.com
Date:     2011-12-20T00:59:57.384047Z

Log Message:
-----------
In frameworks, remove Adobe headers from all files except xml/mxml file types.  There are also a few .txt files that are license files that I didn't touch yet.

Modified Paths:
--------------
2361 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1253117 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/charts/src/mx/charts/chartClasses/PolarTransform.as
+++ frameworks/projects/charts/src/mx/charts/chartClasses/PolarTransform.as
@@ -1,13 +1,3 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-//  ADOBE SYSTEMS INCORPORATED
-//  Copyright 2009 Adobe Systems Incorporated
-//  All Rights Reserved.
-//
-//  NOTICE: Adobe permits you to use, modify, and distribute this file
-//  in accordance with the terms of the license agreement accompanying it.
-//
-////////////////////////////////////////////////////////////////////////////////

 package mx.charts.chartClasses
 {


Transferred from the Adobe Open Source Subversion Repository

Revision: 5367
Author:   rfrishbe@adobe.com
Date:     2009-03-17T22:26:35.014500Z

Log Message:
-----------
The changes here are mostly fixing some sizing issues.

For the FlashContainerPlaceholder, the first child is now MyFlexContentHolder, which extends mx.flash.FlexContentHolder but meets the invariant that it has 1 child and that child is  FlexContentHolderThumbnail, which I’ve added as a swc to the project.  I changed this by accident last time to refer to mx.flash.FlexContentHolder, when it should've referred to a concrete instance created by Flash from a swc.  I also added a chrome of 151x151 to match the FlexContentHolderThumbnail since otherwise the container itself would have no chrome at all, and this let’s it size correctly.

Also, for sizing, in a container, rather than sizing to the size of the chrome, I now size to the size of the FlexContentHolder thumbnail that all FlexContentHolder’s have.  This means in ContainerMovieClip, I don’t need to override bounds anymore.

ContainerMovieClip now implements IVisualElementContainer.

Also, I fixed a resizing event bug in UIMovieClip where the resize event was getting dispatched more than once.

QE Notes: -
Doc Notes: -
Bugs: SDK-19271, SDK-19788, SDK-19789
Reviewer: Glenn
tests: checkintests

Modified Paths:
--------------
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/utilities/src/FlashComponentPlaceholder.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/utilities/src/FlashContainerPlaceholder.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/utilities/build.xml</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/utilities/libs/FlexContentHolderThumbnail.swc</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flash-integration/src/mx/flash/UIMovieClip.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flash-integration/src/mx/flash/FlexContentHolder.as</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/utilities/src/MyFlexContentHolder.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/flash-integration/src/mx/flash/ContainerMovieClip.as</path>
<path kind="dir" action="A">/flex/sdk/trunk/frameworks/projects/utilities/libs</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1253704 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/flash-integration/src/mx/flash/FlexContentHolder.as
+++ frameworks/projects/flash-integration/src/mx/flash/FlexContentHolder.as
@@ -15,6 +15,7 @@
 import flash.display.DisplayObject;
 import flash.display.DisplayObjectContainer;
 import flash.display.InteractiveObject;
+import flash.events.Event;
 import flash.utils.getDefinitionByName;

 import mx.core.IUIComponent;
@@ -49,7 +50,13 @@
         super();
         trackSizeChanges = false;
         showInAutomationHierarchy = false;
-
+
+        _width = this.width;
+        _height = this.height;
+        mx_internal::$scaleX = mx_internal::$scaleY = 1;
+
+        // No need to listen to enterFrameHandler events for the contentHolder
+        removeEventListener(Event.ENTER_FRAME, enterFrameHandler, false);
     }

     //--------------------------------------------------------------------------
@@ -325,16 +332,14 @@
                  }

                 flexContent.initialize();
-
-                 sizeFlexContent();
             }
         }
     }
-
+
     /**
      *  @private
      */
-    protected function sizeFlexContent():void
+    public function sizeFlexContent():void
     {
         if (!flexContent)
             return;
@@ -354,8 +359,6 @@

             if (flexContent.explicitHeight)
                 contentHeight = Math.min(contentHeight, flexContent.explicitHeight);
-
-            flexContent.setActualSize(contentWidth, contentHeight);
         }
         else
         {
@@ -365,13 +368,26 @@
             // We don't do anything too fancy here for layout, like make sure
             // our size is large enough to hold our content in the first place

-            contentWidth = Math.max(flexContent.minWidth,
-                Math.min(_width, flexContent.getExplicitOrMeasuredWidth()));
-            contentHeight = Math.max(flexContent.minHeight,
-                Math.min(_height, flexContent.getExplicitOrMeasuredHeight()));
-
-            flexContent.setActualSize(contentWidth, contentHeight);
-        }
+            contentWidth = Math.min(_width, flexContent.getExplicitOrMeasuredWidth());
+            contentHeight = Math.min(_height, flexContent.getExplicitOrMeasuredHeight());
+        }
+
+        // width and height are what we actually want our content
+        // to fill up, but it doesn't take in to account our secretScale.
+        if (!myParent.scaleContent)
+        {
+            // apply the scale to the width/height
+            var secretScaleX:Number = myParent.mx_internal::$scaleX/myParent.scaleX;
+            var secretScaleY:Number = myParent.mx_internal::$scaleY/myParent.scaleY;
+
+            contentWidth *= secretScaleX;
+            contentHeight *= secretScaleY;
+        }
+
+        contentWidth = Math.max(flexContent.minWidth, contentWidth);
+        contentHeight = Math.max(flexContent.minHeight, contentHeight);
+
+        flexContent.setActualSize(contentWidth, contentHeight);
     }
 }
 }


Transferred from the Adobe Open Source Subversion Repository

Revision: 23243
Author:   cframpto@adobe.com
Date:     2011-12-20T00:59:57.384047Z

Log Message:
-----------
In frameworks, remove Adobe headers from all files except xml/mxml file types.  There are also a few .txt files that are license files that I didn't touch yet.

Modified Paths:
--------------
2361 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1278063 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/spark/src/spark/accessibility/RadioButtonAccImpl.as
+++ frameworks/projects/spark/src/spark/accessibility/RadioButtonAccImpl.as
@@ -1,13 +1,3 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-//  ADOBE SYSTEMS INCORPORATED
-//  Copyright 2009 Adobe Systems Incorporated
-//  All Rights Reserved.
-//
-//  NOTICE: Adobe permits you to use, modify, and distribute this file
-//  in accordance with the terms of the license agreement accompanying it.
-//
-////////////////////////////////////////////////////////////////////////////////

 package spark.accessibility
 {


Transferred from the Adobe Open Source Subversion Repository

Revision: 23246
Author:   cframpto@adobe.com
Date:     2011-12-20T17:40:08.069454Z

Log Message:
-----------
Rollback 23243.  If comment followed header it was stripped as well.

Modified Paths:
--------------
2361 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1258847 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/framework/src/mx/controls/ProgressBarDirection.as
+++ frameworks/projects/framework/src/mx/controls/ProgressBarDirection.as
@@ -1,3 +1,13 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  ADOBE SYSTEMS INCORPORATED
+//  Copyright 2005-2006 Adobe Systems Incorporated
+//  All Rights Reserved.
+//
+//  NOTICE: Adobe permits you to use, modify, and distribute this file
+//  in accordance with the terms of the license agreement accompanying it.
+//
+////////////////////////////////////////////////////////////////////////////////

 package mx.controls
 {


Transferred from the Adobe Open Source Subversion Repository

Revision: 7502
Author:   jszeto@adobe.com
Date:     2009-06-03T00:34:08.950238Z

Log Message:
-----------
Fixed RadialGradientStroke rotation bug

http://bugs.adobe.com/jira/browse/SDK-18372 -  RadialGradientStroke transform does not rotate

Copied the logic from RadialGradient to RadialGradientStroke. The createGradientBox function doesn’t do what we want because it rotates first and then scales. We want to scale first and then rotate.

Added constant for the width and height of the untransformed gradient to all of the gradient classes.

QE Notes: Test RadialGradientStroke rotation
Doc Notes: None
Bugs: SDK-18372
Reviewer: Glenn

Modified Paths:
--------------
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/graphics/LinearGradientStroke.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/graphics/RadialGradientStroke.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/graphics/GradientBase.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/graphics/LinearGradient.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/graphics/RadialGradient.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1261158 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/framework/src/mx/graphics/RadialGradientStroke.as
+++ frameworks/projects/framework/src/mx/graphics/RadialGradientStroke.as
@@ -281,20 +281,23 @@
      */
     private function calculateTransformationMatrix(rect:Rectangle, matrix:Matrix):void
     {
+    	matrix.identity();
+
         if (!compoundTransform)
-        {
+        {
             var w:Number = !isNaN(scaleX) ? scaleX : rect.width;
-            var h:Number = !isNaN(scaleY) ? scaleY : rect.height;
-            var bX:Number = !isNaN(x) ? x + rect.left : rect.left;
-            var bY:Number = !isNaN(y) ? y + rect.top : rect.top;
-
-            matrix.createGradientBox(w, h, rotationInRadians,
-                bX, bY);
+	    	var h:Number = !isNaN(scaleY) ? scaleY : rect.height;
+			var regX:Number = rect.left + (!isNaN(x) ? x : rect.width / 2);
+			var regY:Number = rect.top + (!isNaN(y) ? y : rect.height / 2);
+
+            matrix.scale (w / GRADIENT_DIMENSION, h / GRADIENT_DIMENSION);
+	        matrix.rotate(!isNaN(mx_internal::_angle) ?
+											mx_internal::_angle : mx_internal::rotationInRadians);
+	        matrix.translate(regX, regY);
         }
         else
         {
-            matrix.identity();
-            matrix.scale (rect.width / 1638.4, rect.height / 1638.4);
+            matrix.scale (rect.width / GRADIENT_DIMENSION, rect.height / GRADIENT_DIMENSION);
             matrix.translate(rect.left, rect.top);
             matrix.concat(compoundTransform.matrix);
         }


Transferred from the Adobe Open Source Subversion Repository

Revision: 5099
Author:   gauravj@adobe.com
Date:     2009-02-27T03:43:02.639229Z

Log Message:
-----------
Update action script files with asdoc version tags.

QE Notes: None.
Doc Notes: Please review and update as necessary.
tests: checkintests

Modified Paths:
--------------
147 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1273653 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/rpc/src/mx/messaging/channels/SecureAMFChannel.as
+++ frameworks/projects/rpc/src/mx/messaging/channels/SecureAMFChannel.as
@@ -15,6 +15,12 @@
 /**
  *  The SecureAMFChannel class is identical to the AMFChannel class except that it uses a
  *  secure protocol, HTTPS, to send messages to an AMF endpoint.
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion BlazeDS 4
+ *  @productversion LCDS 3
  */
 public class SecureAMFChannel extends AMFChannel
 {
@@ -30,6 +36,12 @@
 	 *  @param id The id of this Channel.
 	 *
 	 *  @param uri The uri for this Channel.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
      */
     public function SecureAMFChannel(id:String = null, uri:String = null)
     {
@@ -44,6 +56,12 @@

     /**
      *  Returns the protocol for this channel (https).
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion BlazeDS 4
+     *  @productversion LCDS 3
      */
     override public function get protocol():String
     {


Transferred from the Adobe Open Source Subversion Repository

Revision: 23243
Author:   cframpto@adobe.com
Date:     2011-12-20T00:59:57.384047Z

Log Message:
-----------
In frameworks, remove Adobe headers from all files except xml/mxml file types.  There are also a few .txt files that are license files that I didn't touch yet.

Modified Paths:
--------------
2361 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1250091 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/airframework/src/mx/skins/halo/ApplicationTitleBarBackgroundSkin.as
+++ frameworks/projects/airframework/src/mx/skins/halo/ApplicationTitleBarBackgroundSkin.as
@@ -1,13 +1,3 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-//  ADOBE SYSTEMS INCORPORATED
-//  Copyright 2007 Adobe Systems Incorporated
-//  All Rights Reserved.
-//
-//  NOTICE: Adobe permits you to use, modify, and distribute this file
-//  in accordance with the terms of the license agreement accompanying it.
-//
-////////////////////////////////////////////////////////////////////////////////

 package mx.skins.halo
 {


This closes This closes #19

This closes This closes #19

Update DateTimeFormatterEx.as

Proposing patch for bug Apache Flex / FLEX-34581: DateSpinner crash when locale that uses a 24-hour setting.

Updated public function getUse24HourFlag() of DateTimeFormatterEx.as to return a Boolean value instead of an Object value.

Signed-off-by: OmPrakash Muppirala <1b24872869b46beedbb4012b2e947e40e0f6307d@gmail.com>

--- frameworks/projects/spark/src/spark/globalization/supportClasses/DateTimeFormatterEx.as
+++ frameworks/projects/spark/src/spark/globalization/supportClasses/DateTimeFormatterEx.as
@@ -681,12 +681,12 @@
      *          because the current pattern does not contain either
      *          "H" or "h".
      */
-    public function getUse24HourFlag():Object
+    public function getUse24HourFlag():Boolean
     {
         const hourPattern:String = getHourPattern();

         if (!hourPattern)
-            return null;
+            return false;

         const use24Hour:Boolean = hourPattern.indexOf("H") >= 0;
         const use12Hour:Boolean = hourPattern.indexOf("h") >= 0;
@@ -694,8 +694,7 @@
             return true;
         else if (!use24Hour && use12Hour)
             return false;
-
-        return null;
+        else return false;
     }

     [Bindable("change")]


def: 6079 don't update selectedIndex for bumper entries..

git-svn-id: 3f608e5a9a704dd448217c0a64c508e7f145cfa1@91348 6b8eccd3-e8c5-4e7d-8186-e12b5326b719

--- plugins/playlistApiPlugin/src/com/kaltura/kdpfl/plugin/component/PlaylistAPIMediator.as
+++ plugins/playlistApiPlugin/src/com/kaltura/kdpfl/plugin/component/PlaylistAPIMediator.as
@@ -7,6 +7,7 @@
  */
 package com.kaltura.kdpfl.plugin.component {

+	import com.kaltura.kdpfl.model.SequenceProxy;
 	import com.kaltura.kdpfl.model.type.NotificationType;
 	import com.kaltura.kdpfl.plugin.type.PlaylistNotificationType;

@@ -94,7 +95,8 @@
 					}
 					break;
 				case NotificationType.CHANGE_MEDIA: {
-					playlistAPI.changeMedia(note.getBody().entryId);
+					if (!(facade.retrieveProxy(SequenceProxy.NAME) as SequenceProxy).vo.isInSequence)
+						playlistAPI.changeMedia(note.getBody().entryId);
 					break;
 				}
 			}


tweaked initial seed

tweaked initial seed

--- src/com/phylake/pooling/ObjectPool.as
+++ src/com/phylake/pooling/ObjectPool.as
@@ -24,7 +24,7 @@
                 var minSize:uint = _minSize;
                 while (minSize-- > 0)
                 {
-                    getObject();
+                    _available.push(value());
                 }
             }
         }


commented out ref to EntityNodeSearch because it was crashing

--- WeaveJS/src/WeaveTest.as
+++ WeaveJS/src/WeaveTest.as
@@ -149,7 +149,7 @@
 			CKANDataSource,
 			KeyColumn,
 			ExternalTool,
-			EntityNodeSearch,
+//			EntityNodeSearch,

 			WeaveMenuItem,
 			ZoomBounds,


initialize $version variable

initialize $version variable

--- libswfdec/swfdec_initialize.as
+++ libswfdec/swfdec_initialize.as
@@ -131,9 +131,10 @@

 System = {};
 System.capabilities = {};
-System.capabilities.Query = ASnative(11, 0);
-System.capabilities.Query();
+System.capabilities.Query = ASnative (11, 0);
+System.capabilities.Query ();
 delete System.capabilities.Query;
+$version = System.capabilities.version;

 /*** OH THE HUMANITY ***/


Transferred from the Adobe Open Source Subversion Repository

Revision: 23243
Author:   cframpto@adobe.com
Date:     2011-12-20T00:59:57.384047Z

Log Message:
-----------
In frameworks, remove Adobe headers from all files except xml/mxml file types.  There are also a few .txt files that are license files that I didn't touch yet.

Modified Paths:
--------------
2361 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1265271 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/mobiletheme/src/spark/skins/mobile/DefaultBeveledBackButtonSkin.as
+++ frameworks/projects/mobiletheme/src/spark/skins/mobile/DefaultBeveledBackButtonSkin.as
@@ -1,13 +1,3 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-//  ADOBE SYSTEMS INCORPORATED
-//  Copyright 2011 Adobe Systems Incorporated
-//  All Rights Reserved.
-//
-//  NOTICE: Adobe permits you to use, modify, and distribute this file
-//  in accordance with the terms of the license agreement accompanying it.
-//
-////////////////////////////////////////////////////////////////////////////////

 package spark.skins.mobile
 {


fixed bugs in circle selection by setting coords at appropriate time.

Change-Id: Iab02788038411032d7a2cf25ebc0b2067446d3fb

--- WeaveUI/src/weave/visualization/layers/InteractiveVisualization.as
+++ WeaveUI/src/weave/visualization/layers/InteractiveVisualization.as
@@ -1,946 +1,962 @@
-/*
-Weave (Web-based Analysis and Visualization Environment)
-Copyright (C) 2008-2011 University of Massachusetts Lowell
-
-This file is a part of Weave.
-
-Weave is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License, Version 3,
-as published by the Free Software Foundation.
-
-Weave is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Weave.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package weave.visualization.layers
-{
-	import com.cartogrammar.drawing.DashedLine;
-
-	import flash.display.Graphics;
-	import flash.display.InteractiveObject;
-	import flash.events.ContextMenuEvent;
-	import flash.events.Event;
-	import flash.events.KeyboardEvent;
-	import flash.events.MouseEvent;
-	import flash.geom.Point;
-	import flash.ui.ContextMenu;
-	import flash.ui.Keyboard;
-
-	import mx.containers.Canvas;
-
-	import weave.Weave;
-	import weave.api.WeaveAPI;
-	import weave.api.data.IQualifiedKey;
-	import weave.api.detectLinkableObjectChange;
-	import weave.api.newLinkableChild;
-	import weave.api.primitives.IBounds2D;
-	import weave.api.registerLinkableChild;
-	import weave.api.ui.IPlotLayer;
-	import weave.core.LinkableBoolean;
-	import weave.core.LinkableNumber;
-	import weave.core.StageUtils;
-	import weave.data.KeySets.KeySet;
-	import weave.primitives.Bounds2D;
-	import weave.primitives.SimpleGeometry;
-	import weave.utils.CustomCursorManager;
-	import weave.utils.DebugTimer;
-	import weave.utils.ProbeTextUtils;
-	import weave.utils.SpatialIndex;
-	import weave.utils.ZoomUtils;
-
-	/**
-	 * This is a container for a list of PlotLayers
-	 *
-	 * @author adufilie
-	 */
-	public class InteractiveVisualization extends PlotLayerContainer
-	{
-		public function InteractiveVisualization()
-		{
-			doubleClickEnabled = true;
-
-			enableZoomAndPan.value = true;
-			enableSelection.value = true;
-			enableProbe.value = true;
-			enableAutoZoomToExtent.value = true;
-			// adding a canvas as child gets the selection rectangle on top of the vis
-			addChild(selectionCanvas);
-
-			addContextMenuEventListener();
-
-			addEventListener(MouseEvent.DOUBLE_CLICK, handleDoubleClick);
-			addEventListener(MouseEvent.MOUSE_DOWN, handleMouseDown);
-			addEventListener(MouseEvent.ROLL_OUT, handleRollOut);
-			addEventListener(MouseEvent.ROLL_OVER, handleRollOver);
-			addEventListener(MouseEvent.MOUSE_WHEEL,handleMouseWheel);
-			WeaveAPI.StageUtils.addEventCallback(MouseEvent.MOUSE_MOVE, this, handleMouseMove);
-			WeaveAPI.StageUtils.addEventCallback(MouseEvent.MOUSE_UP, this, handleMouseUp);
-			WeaveAPI.StageUtils.addEventCallback(KeyboardEvent.KEY_DOWN, this, handleKeyboardEvent);
-			WeaveAPI.StageUtils.addEventCallback(KeyboardEvent.KEY_UP, this, handleKeyboardEvent);
-			WeaveAPI.StageUtils.addEventCallback(StageUtils.POINT_CLICK_EVENT, this, _handlePointClick);
-
-			//			addEventListener(KeyboardEvent.KEY_DOWN, handleKeyboardEvent);
-			//			addEventListener(KeyboardEvent.KEY_UP, handleKeyboardEvent);
-
-			Weave.properties.dashedSelectionBox.addImmediateCallback(this, validateDashedLine, true);
-
-		}
-
-		private function addContextMenuEventListener():void
-		{
-			var contextMenu:ContextMenu = (WeaveAPI.topLevelApplication as InteractiveObject).contextMenu;
-			if (!contextMenu)
-				return callLater(addContextMenuEventListener);
-			contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, removeCursor);
-		}
-		private function removeCursor(e:Event):void
-		{
-			CustomCursorManager.removeCurrentCursor();
-		}
-
-		public const enableZoomAndPan:LinkableBoolean = newLinkableChild(this, LinkableBoolean);
-		public const enableSelection:LinkableBoolean = newLinkableChild(this, LinkableBoolean);
-		public const enableProbe:LinkableBoolean = newLinkableChild(this, LinkableBoolean);
-		public const zoomFactor:LinkableNumber = registerLinkableChild(this, new LinkableNumber(2, verifyZoomFactor));
-
-		private function verifyZoomFactor(value:Number):Boolean
-		{
-			return value >= 1;
-		}
-
-		private var activeKeyType:String = null;
-		private var mouseDragActive:Boolean = false;
-		private const selectionCanvas:Canvas = new Canvas();
-
-		private const mouseDragStageCoords:IBounds2D = new Bounds2D();
-
-		private var _mouseMode:String = null;
-
-		private function isModeSelection(mode:String):Boolean
-		{
-			return mode == InteractionController.SELECT_ADD
-				|| mode == InteractionController.SELECT
-				|| mode == InteractionController.SELECT_REMOVE;
-		}
-
-		private function isModeZoom(mode:String):Boolean
-		{
-			return mode == InteractionController.ZOOM
-				|| mode == InteractionController.ZOOM_IN
-				|| mode == InteractionController.ZOOM_OUT
-				|| mode == InteractionController.ZOOM_TO_EXTENT;
-		}
-
-
-		private function updateMouseMode(mouseEventType:String = null):void
-		{
-			if (mouseEventType)
-				_mouseMode = Weave.properties.toolInteractions.determineInteraction(mouseEventType);
-			else
-				_mouseMode = Weave.properties.toolInteractions.determineInteractionMode();
-
-			if (!enableZoomAndPan.value && (isModeZoom(_mouseMode) || _mouseMode == InteractionController.PAN))
-			{
-				_mouseMode = InteractionController.SELECT;
-			}
-			if (!enableSelection.value && isModeSelection(_mouseMode))
-			{
-				_mouseMode = null;//Weave.properties.toolInteractions.defaultDragMode.value;
-			}
-
-			updateMouseCursor();
-		}
-
-		private var _selectModeCursorOffsetX:int = -2;
-		private var _selectModeCursorOffsetY:int = -2;
-		private function updateMouseCursor():void
-		{
-			if (mouseIsRolledOver)
-			{
-				if (_mouseMode == InteractionController.PAN)
-				{
-					if (WeaveAPI.StageUtils.mouseButtonDown)
-						CustomCursorManager.showCursor(CustomCursorManager.HAND_GRAB_CURSOR);
-					else
-						CustomCursorManager.showCursor(CustomCursorManager.HAND_CURSOR);
-				}
-				else if (_mouseMode == InteractionController.SELECT_ADD)
-				{
-					CustomCursorManager.showCursor(CustomCursorManager.SELECT_ADD_CURSOR, 2, _selectModeCursorOffsetX, _selectModeCursorOffsetY);
-				}
-				else if (_mouseMode == InteractionController.SELECT || _mouseMode == InteractionController.PROBE)
-				{
-					CustomCursorManager.showCursor(CustomCursorManager.SELECT_REPLACE_CURSOR, 2, _selectModeCursorOffsetX, _selectModeCursorOffsetY);
-				}
-				else if (_mouseMode == InteractionController.SELECT_REMOVE)
-				{
-					CustomCursorManager.showCursor(CustomCursorManager.SELECT_SUBTRACT_CURSOR, 2, _selectModeCursorOffsetX, _selectModeCursorOffsetY);
-				}
-				else if (_mouseMode == InteractionController.ZOOM)
-				{
-					CustomCursorManager.showCursor(CustomCursorManager.ZOOM_CURSOR);
-				}
-			}
-		}
-
-		private function handleKeyboardEvent():void
-		{
-			// if the escape key was hit, stop whatever mouse drag operation is in progress
-			if (WeaveAPI.StageUtils.keyboardEvent && WeaveAPI.StageUtils.keyboardEvent.keyCode == Keyboard.ESCAPE)
-			{
-				mouseDragActive = false;
-			}
-
-			// if currently dragging, don't change mouse mode
-			if (!mouseDragActive)
-				updateMouseMode();
-		}
-
-		/**
-		 * This function gets called whenever StageUtils runs point click event callbacks.
-		 * This function should remain private.
-		 */
-		private function _handlePointClick():void
-		{
-			// only handle the event if the mouse is rolled over
-			if (mouseIsRolledOver)
-				handleMouseClick(WeaveAPI.StageUtils.mouseEvent);
-		}
-
-		// this function can be defined with override by extending classes and call super.handleMouseClick(event);
-		protected function handleMouseClick(event:MouseEvent):void
-		{
-			handleMouseEvent(event);
-		}
-
-
-		protected function handleDoubleClick(event:MouseEvent):void
-		{
-			handleMouseEvent(event);
-		}
-
-		protected function handleMouseDown(event:MouseEvent):void
-		{
-			updateMouseMode(InteractionController.DRAG); // modifier keys may have changed just prior to pressing mouse button, so update mode now
-
-			//for detecting change between drag start and drag end
-			// TEMPORARY HACK - Weave.defaultSelectionKeySet
-			detectLinkableObjectChange( handleMouseDown, Weave.defaultSelectionKeySet );
-
-			mouseDragActive = true;
-			// clear probe when drag starts
-			clearProbe();
-			// start the selection rectangle from the mouse down point
-			// for accuracy, use the stage coordinates from the event, not the current coordinates from the stage
-			mouseDragStageCoords.setRectangle(event.stageX, event.stageY, 0, 0);
-			updateSelectionCoords(true);
-
-			handleMouseEvent(event);
-		}
-		protected function handleMouseUp():void
-		{
-			updateMouseCursor();
-
-			// when the mouse is released, handle mouse move so the selection rectangle will cause the selection to update.
-			handleMouseEvent(WeaveAPI.StageUtils.mouseEvent);
-		}
-		protected function handleMouseMove():void
-		{
-			handleMouseEvent(WeaveAPI.StageUtils.mouseEvent);
-		}
-		protected function handleRollOut(event:MouseEvent):void
-		{
-			if (mouseIsRolledOver)
-			{
-				CustomCursorManager.removeAllCursors();
-				mouseIsRolledOver = false;
-
-				// when rolled over goes from true to false, clear the probe
-				clearProbe();
-			}
-			handleMouseEvent(event);
-
-			updateMouseCursor();
-		}
-		protected function handleRollOver(event:MouseEvent):void
-		{
-			mouseIsRolledOver = true;
-			handleMouseEvent(event);
-
-			updateMouseCursor();
-		}
-
-		protected var mouseIsRolledOver:Boolean = false; // start this at false because we don't want tools probing when mouse is not rolled over
-
-		private const _tempBounds:IBounds2D = new Bounds2D();
-		private const _screenBounds:IBounds2D = new Bounds2D();
-		protected function handleMouseWheel(event:MouseEvent):void
-		{
-			if (Weave.properties.enableMouseWheel.value)
-				handleMouseEvent(event);
-		}
-
-		protected function handleMouseEvent(event:MouseEvent):void
-		{
-			// determine proper event type
-			var eventType:String = null;
-			switch (event.type)
-			{
-				case MouseEvent.CLICK:
-				{
-					eventType = InteractionController.CLICK;
-					break;
-				}
-				case MouseEvent.DOUBLE_CLICK:
-				{
-					if (!mouseIsRolledOver)
-						return;
-
-					eventType = InteractionController.DCLICK;
-					break;
-				}
-				case MouseEvent.MOUSE_MOVE:
-				case MouseEvent.ROLL_OVER:
-				case MouseEvent.ROLL_OUT:
-				{
-					if (event.buttonDown)
-						eventType = InteractionController.DRAG;
-					else
-						eventType = InteractionController.MOVE;
-
-					break;
-				}
-				case MouseEvent.MOUSE_WHEEL:
-				{
-					eventType = InteractionController.WHEEL;
-					break;
-				}
-			}
-
-			// if currently dragging, update drag coords and don't change mouse mode
-			if (mouseDragActive)
-			{
-				// update end coordinates of selection rectangle
-				if (event.type == MouseEvent.MOUSE_UP)
-				{
-					// on a mouse up event, we want accuracy, so use the mouse up event coordinates
-					mouseDragStageCoords.setMaxCoords(event.stageX, event.stageY);
-				}
-				else
-				{
-					// IMPORTANT: for speed, use the current mouse coordinates instead of the event coordinates
-					mouseDragStageCoords.setMaxCoords(stage.mouseX, stage.mouseY);
-				}
-				updateSelectionCoords();
-			}
-			else // not dragging -- ok to update mouse mode
-			{
-				updateMouseMode(eventType);
-			}
-
-			var dragReleased:Boolean = mouseDragActive && !event.buttonDown;
-			switch (_mouseMode)
-			{
-				case InteractionController.SELECT_ADD:
-				{
-					if (mouseDragActive)
-						handleSelection(event, _mouseMode);
-					break;
-				}
-				case InteractionController.SELECT:
-				{
-				   	if (mouseDragActive)
-						handleSelection(event, _mouseMode);
-					break;
-				}
-				case InteractionController.SELECT_REMOVE:
-				{
-					if (mouseDragActive)
-						handleSelection(event, _mouseMode);
-					break;
-				}
-				case InteractionController.SELECT_ALL:
-				{
-					if (mouseIsRolledOver)
-						selectAllVisibleRecords();
-					break;
-				}
-				case InteractionController.PAN:
-				{
-					if (enableZoomAndPan.value && mouseDragActive)
-					{
-						// pan the dragged distance
-						projectDragBoundsToDataQueryBounds(null, false);
-						zoomBounds.getDataBounds(tempDataBounds);
-						tempDataBounds.setCenter(tempDataBounds.getXCenter() - queryBounds.getWidth(), tempDataBounds.getYCenter() - queryBounds.getHeight());
-						zoomBounds.setDataBounds(tempDataBounds);
-						// set begin point for next pan
-						mouseDragStageCoords.getMaxPoint(tempPoint);
-						mouseDragStageCoords.setMinPoint(tempPoint);
-					}
-					break;
-				}
-				case InteractionController.ZOOM:
-				{
-					if (enableZoomAndPan.value)
-					{
-						if (eventType == InteractionController.WHEEL)
-						{
-							zoomBounds.getDataBounds(_tempBounds);
-							zoomBounds.getScreenBounds(_screenBounds);
-							if (event.delta > 0)
-								ZoomUtils.zoomDataBoundsByRelativeScreenScale(_tempBounds,_screenBounds,mouseX,mouseY,zoomFactor.value,false);
-							else if (event.delta < 0)
-								ZoomUtils.zoomDataBoundsByRelativeScreenScale(_tempBounds,_screenBounds,mouseX,mouseY,1/zoomFactor.value,false);
-							zoomBounds.setDataBounds(_tempBounds);
-						}
-						else if (dragReleased)
-						{
-							// zoom to selected data bounds if area > 0
-							projectDragBoundsToDataQueryBounds(null, true); // data bounds in same direction when zooming
-							if (queryBounds.getArea() > 0)
-								zoomBounds.setDataBounds(queryBounds);
-						}
-					}
-					break;
-				}
-				case InteractionController.PROBE:
-				{
-					if (mouseIsRolledOver)
-					{
-						// probe when mouse is rolled over and selection is inactive
-						handleProbe();
-					}
-
-					break;
-				}
-				case InteractionController.ZOOM_TO_EXTENT:
-				{
-					if (enableZoomAndPan.value)
-						zoomBounds.setDataBounds(fullDataBounds, true); // zoom to full extent
-					break;
-				}
-				case InteractionController.ZOOM_IN:
-				case InteractionController.ZOOM_OUT:
-				{
-					if (enableZoomAndPan.value)
-					{
-						var multiplier:Number = 1;
-						if (_mouseMode == InteractionController.ZOOM_IN)
-							multiplier = 1 / zoomFactor.value;
-						else
-							multiplier = zoomFactor.value;
-
-						projectDragBoundsToDataQueryBounds(null, false);
-						zoomBounds.getDataBounds(_tempBounds);
-						_tempBounds.setCenter(queryBounds.getXCenter(), queryBounds.getYCenter());
-
-						_tempBounds.centeredResize(_tempBounds.getWidth() * multiplier, _tempBounds.getHeight() * multiplier);
-
-						zoomBounds.setDataBounds(_tempBounds);
-					}
-					break;
-				}
-			}
-
-			// finally, unset mouseDragActive if button was released
-			if (dragReleased)
-			{
-				mouseDragActive = false;
-			}
-
-			updateSelectionRectangleGraphics();
-		}
-
-		//TODO - use this
-		private function selectAllVisibleRecords():void
-		{
-			// clear selection or select all
-
-			// set up mouse drag rectangle to select or deselect visible area
-			zoomBounds.getScreenBounds(_screenBounds);
-			_screenBounds.getMinPoint(tempPoint);
-			mouseDragStageCoords.setMinPoint(localToGlobal(tempPoint));
-			_screenBounds.getMaxPoint(tempPoint);
-			mouseDragStageCoords.setMaxPoint(localToGlobal(tempPoint));
-
-			immediateHandleSelection();
-		}
-
-		private var _selectionGraphicsCleared:Boolean = true;
-		private const _selectionGeometry:SimpleGeometry = new SimpleGeometry();
-		private var _lassoScreenPoints:Array = [];
-		private var _lastLassoPoint:Point = null;
-
-		protected function updateSelectionCoords(reset:Boolean = false):void
-		{
-			mouseDragStageCoords.getMaxPoint(tempPoint); // stage coords
-
-			var localMaxPoint:Point = selectionCanvas.globalToLocal(tempPoint); // local screen coords
-			if (reset || _lassoScreenPoints.length == 0)
-			{
-				mouseDragStageCoords.getMinPoint(tempPoint); // stage coords
-				var localMinPoint:Point = selectionCanvas.globalToLocal(tempPoint); // local screen coords
-
-				_lassoScreenPoints = [localMinPoint, localMaxPoint];
-				_lastLassoPoint = localMaxPoint;
-			}
-			else if (Math.abs(localMaxPoint.x - _lastLassoPoint.x) >= 5 || Math.abs(localMaxPoint.y - _lastLassoPoint.y) >= 5 )
-			{
-				// if the new point is far enough away from the previous point, add it to the coords
-				_lassoScreenPoints.push(localMaxPoint);
-				_lastLassoPoint = localMaxPoint;
-			}
-		}
-
-		protected function updateSelectionRectangleGraphics():void
-		{
-			if (!Weave.properties.enableToolSelection.value || !enableSelection.value)
-				return;
-
-			var g:Graphics = selectionCanvas.graphics;
-			if (!_selectionGraphicsCleared)
-				g.clear();
-
-			if (!mouseDragActive || _mouseMode == InteractionController.PAN)
-			{
-				_selectionGraphicsCleared = true;
-				return;
-			}
-
-			_selectionGraphicsCleared = false;
-
-			// use a blue rectangle for zoom mode, green for selection
-			_dashedLine.graphics = g;
-			if (_mouseMode == InteractionController.ZOOM)
-			{
-				_dashedLine.lineStyle(2, 0x00faff, .75);
-			}
-			else
-			{
-				_dashedLine.lineStyle(2, 0x00ff00, .75);
-			}
-
-			mouseDragStageCoords.getMinPoint(tempPoint); // stage coords
-			var localMinPoint:Point = selectionCanvas.globalToLocal(tempPoint); // local screen coords
-			mouseDragStageCoords.getMaxPoint(tempPoint); // stage coords
-			var localMaxPoint:Point = selectionCanvas.globalToLocal(tempPoint); // local screen coords
-
-			tempScreenBounds.setMinPoint(localMinPoint);
-			tempScreenBounds.setMaxPoint(localMaxPoint);
-			var dragX:Number = tempScreenBounds.getXMin();
-			var dragY:Number = tempScreenBounds.getYMin();
-			var dragWidth:Number = tempScreenBounds.getWidth();
-			var dragHeight:Number = tempScreenBounds.getHeight();
-
-			// init temp bounds for reprojecting coordinates
-			zoomBounds.getDataBounds(tempDataBounds);
-			zoomBounds.getScreenBounds(tempScreenBounds);
-
-			if (Weave.properties.selectionMode.value == InteractionController.SELECTION_MODE_RECTANGLE)
-			{
-				_dashedLine.drawRect(dragX, dragY, dragWidth, dragHeight);
-			}
-			else if (Weave.properties.selectionMode.value == InteractionController.SELECTION_MODE_CIRCLE)
-			{
-				var direction:Number = -mouseDragStageCoords.getXDirection() || 1;
-				var thetaOffset:Number = Math.atan2(mouseDragStageCoords.getHeight(), mouseDragStageCoords.getWidth());
-				var radius:Number = Math.sqrt(dragWidth*dragWidth + dragHeight*dragHeight);
-				var points:Array = [];
-
-				var segmentLength:Number = 8; // pixels
-				var segmentSpan:Number = segmentLength / radius; // radians
-				segmentSpan = Math.min(Math.PI / 4, segmentSpan); // maximum 45 degrees per segment
-				// draw the segments
-				var segmentCount:Number = Math.ceil(Math.PI * 2 / segmentSpan);
-				segmentCount = Math.min(64, segmentCount);
-
-				for (var i:int = 0; i < segmentCount + 1; i++)
-				{
-					var theta:Number = direction * i * 2 * Math.PI / segmentCount + thetaOffset;
-					var circleX:Number = dragX + radius * Math.cos(theta); // center a + radius x * cos(theta)
-					var circleY:Number = dragY + radius * Math.sin(theta); // center b + radius y * sin(theta)
-					if (i == 0)
-						_dashedLine.moveTo(circleX, circleY);
-					else
-						_dashedLine.lineTo(circleX, circleY);
-
-					var currPoint:Point = new Point(circleX, circleY);
-					tempScreenBounds.projectPointTo(currPoint, tempDataBounds);
-					points.push(currPoint);
-				}
-				_selectionGeometry.setVertices(points);//set the geometry for making the query
-			}
-			else if (Weave.properties.selectionMode.value == InteractionController.SELECTION_MODE_LASSO)
-			{
-				fillPolygon(g, _dashedLine.lineColor, 0.05, _lassoScreenPoints);
-
-				for (var k:int = 0; k < _lassoScreenPoints.length + 1; k++)
-				{
-					if (k == 0)
-						_dashedLine.moveTo(_lassoScreenPoints[k].x, _lassoScreenPoints[k].y);
-					else if (k == _lassoScreenPoints.length)
-					{
-						_dashedLine.lineTo(_lassoScreenPoints[0].x, _lassoScreenPoints[0].y);//closing the lasso
-						break;
-					}
-					else
-						_dashedLine.lineTo(_lassoScreenPoints[k].x, _lassoScreenPoints[k].y);
-				}
-			}
-		}
-
-		private function fillPolygon(graphics:Graphics, color:uint, alpha:Number, points:Array):void
-		{
-			graphics.lineStyle(0,0,0);
-			var n:int = points.length;
-			for (var i:int = 0; i <= n; i++)
-			{
-				var point:Point = points[i % n];
-				if (i == 0)
-				{
-					graphics.moveTo(point.x, point.y);
-					graphics.beginFill(color, alpha);
-				}
-				else
-					graphics.lineTo(point.x, point.y);
-			}
-			graphics.endFill();
-		}
-
-		private const _dashedLine:DashedLine = new DashedLine(0, 0, null);
-		private function validateDashedLine():void
-		{
-			_dashedLine.lengthsString = Weave.properties.dashedSelectionBox.value;
-		}
-
-		private function handleSelection(event:MouseEvent, mode:String):void
-		{
-			var _layers:Array;
-			var i:int;
-			var layer:SelectablePlotLayer;
-
-			// update end coordinates of selection rectangle
-			if (event.type == MouseEvent.MOUSE_UP)
-			{
-				// on a mouse up event, we want accuracy, so use the mouse up event coordinates
-				mouseDragStageCoords.setMaxCoords(event.stageX, event.stageY);
-			}
-			else
-			{
-				// IMPORTANT: for interaction speed, use the current mouse coordinates instead of the event coordinates.
-				// otherwise, queued mouse events will be handled individually and it will feel sluggish
-				mouseDragStageCoords.setMaxCoords(stage.mouseX, stage.mouseY);
-			}
-
-			if ( isModeSelection(mode) )
-			{
-				// only if selection is enabled
-				if (enableSelection.value)
-					delayedHandleSelection();
-			}
-		}
-		private function clearSelection():void
-		{
-			var _layers:Array = layers.getObjects(SelectablePlotLayer);
-			for (var i:int = 0; i < _layers.length; i++)
-			{
-				setSelectionKeys(_layers[i], []);
-			}
-		}
-
-		/**
-		 * This function projects drag start,stop screen coordinates into data coordinates and stores the result in queryBounds.
-		 * @param layer If layer is null, InteractiveVisualization's screen/data bounds will be used.  Otherwise, uses IPlotLayer's bounds.
-		 * @param zooming Specify true when computing zoom coordinates.
-		 */
-		protected function projectDragBoundsToDataQueryBounds(layer:IPlotLayer, zooming:Boolean):void
-		{
-			if (layer)
-			{
-				layer.getDataBounds(tempDataBounds);
-				layer.getScreenBounds(tempScreenBounds);
-			}
-			else
-			{
-				zoomBounds.getDataBounds(tempDataBounds);
-				zoomBounds.getScreenBounds(tempScreenBounds);
-			}
-
-			// project stage coords to local layer coords
-			mouseDragStageCoords.getMinPoint(tempPoint); // stage coords
-			var localMinPoint:Point = globalToLocal(tempPoint); // local screen coords
-			mouseDragStageCoords.getMaxPoint(tempPoint); // stage coords
-			var localMaxPoint:Point = globalToLocal(tempPoint); // local screen coords
-
-			// project screen coords to data coords
-			tempScreenBounds.projectPointTo(localMinPoint, tempDataBounds);
-			tempScreenBounds.projectPointTo(localMaxPoint, tempDataBounds);
-
-			// query the spatial index, set selection
-			queryBounds.setMinPoint(localMinPoint);
-			queryBounds.setMaxPoint(localMaxPoint);
-
-			if (zooming)
-			{
-				// swap min,max coordinates if necessary
-				if (queryBounds.getXDirection() != tempDataBounds.getXDirection())
-					queryBounds.setXRange(queryBounds.getXMax(), queryBounds.getXMin());
-				if (queryBounds.getYDirection() != tempDataBounds.getYDirection())
-					queryBounds.setYRange(queryBounds.getYMax(), queryBounds.getYMin());
-
-				// expand rectangle if necessary to match screen aspect ratio
-				var xScale:Number = queryBounds.getXCoverage() / tempScreenBounds.getXCoverage();
-				var yScale:Number = queryBounds.getYCoverage() / tempScreenBounds.getYCoverage();
-				if (xScale > yScale)
-					queryBounds.setHeight( queryBounds.getYDirection() * tempScreenBounds.getYCoverage() * xScale );
-				if (yScale > xScale)
-					queryBounds.setWidth( queryBounds.getXDirection() * tempScreenBounds.getXCoverage() * yScale );
-			}
-		}
-
-		protected function delayedHandleSelection(allowCallLater:Boolean = true):void
-		{
-			if (!parent)
-				return;
-
-			if (WeaveAPI.StageUtils.mouseMoved)
-			{
-				if (allowCallLater)
-					callLater(delayedHandleSelection, [false]);
-			}
-			else
-			{
-				// handle selection when mouse hasn't moved since last frame.
-				immediateHandleSelection();
-			}
-		}
-
-		protected function immediateHandleSelection():void
-		{
-			// don't set a selection or clear the probe keys if selection is disabled
-			if (!enableSelection.value)
-				return;
-
-			var _layers:Array = layers.getObjects(SelectablePlotLayer); // bottom to top
-			// loop from bottom layer to top layer
-			for (var index:int = 0; index < _layers.length; index++)
-			{
-				var layer:SelectablePlotLayer = _layers[index] as SelectablePlotLayer;
-				// skip this layer if it is disabled
-				if (!layer.shouldBeRendered() || !layer.layerIsSelectable.value)
-					continue;
-				// skip this layer if it does not contain lastProbedQKey
-				if (_lastProbedQKey && !layer.plotter.keySet.containsKey(_lastProbedQKey))
-					continue;
-
-				// when using the selection layer, clear the probe
-				setProbeKeys(layer, []);
-				projectDragBoundsToDataQueryBounds(layer, false);
-
-				// calculate minImportance
-				layer.getDataBounds(tempDataBounds);
-				layer.getScreenBounds(tempScreenBounds);
-				var minImportance:Number = tempDataBounds.getArea() / tempScreenBounds.getArea();
-
-				// don't query outside visible data bounds
-				if (!tempDataBounds.overlaps(queryBounds))
-					continue;
-				tempDataBounds.constrainBounds(queryBounds, false);
-
-				var keys:Array = [];
-				if (Weave.properties.selectionMode.value == InteractionController.SELECTION_MODE_RECTANGLE)
-				{
-					keys = (layer.spatialIndex as SpatialIndex).getKeysGeometryOverlap(queryBounds, minImportance, false, tempDataBounds);
-				}
-				else if (Weave.properties.selectionMode.value == InteractionController.SELECTION_MODE_CIRCLE)
-				{
-					//TODO - set geom coords here
-					keys = (layer.spatialIndex as SpatialIndex).getKeysGeometryOverlapGeometry(_selectionGeometry, minImportance, false);
-				}
-				else if (Weave.properties.selectionMode.value == InteractionController.SELECTION_MODE_LASSO)
-				{
-					var lassoDataPoints:Array = [];
-					for each (var screenPoint:Point in _lassoScreenPoints)
-					{
-						var tempDataPoint:Point = screenPoint.clone();
-						tempScreenBounds.projectPointTo(tempDataPoint, tempDataBounds);
-						lassoDataPoints.push(tempDataPoint);
-					}
-					_selectionGeometry.setVertices(lassoDataPoints);
-
-					keys = (layer.spatialIndex as SpatialIndex).getKeysGeometryOverlapGeometry(_selectionGeometry, minImportance, false);
-				}
-
-
-				setSelectionKeys(layer, keys, true);
-
-				break; // select only one layer at a time
-			}
-
-
-			// if mouse is released and selection hasn't changed since mouse down, clear selection
-			// TEMPORARY HACK - Weave.defaultSelectionKeySet
-			if (_mouseMode == InteractionController.SELECT &&
-				!WeaveAPI.StageUtils.mouseButtonDown &&
-				!detectLinkableObjectChange(handleMouseDown, Weave.defaultSelectionKeySet))
-			{
-				clearSelection();
-			}
-
-		}
-
-		/**
-		 * This is the last IQualifiedKey (record identifier) that was probed.
-		 */
-		public function get lastProbedKey():IQualifiedKey { return _lastProbedQKey; }
-		private var _lastProbedQKey:IQualifiedKey = null;
-
-		protected function handleProbe(allowCallLater:Boolean = true):void
-		{
-			if (!parent || !Weave.properties.enableToolProbe.value || !enableProbe.value)
-				return;
-
-			// NOTE: this code is hacked to work with only one global probe KeySet
-
-			// only probe if the mouse coords are the same two frames in a row
-			if (WeaveAPI.StageUtils.mouseMoved)
-			{
-				if (allowCallLater)
-					callLater(handleProbe, [false]);
-			}
-			else if (mouseIsRolledOver)
-			{
-				// handle probe when mouse hasn't moved since last frame.
-				var _layers:Array = layers.getObjects(SelectablePlotLayer).reverse(); // top to bottom
-				var lastActiveLayer:SelectablePlotLayer = null;
-				for (var i:int = 0; i < _layers.length; i++)
-				{
-					var layer:SelectablePlotLayer = _layers[i];
-					if (!layer.shouldBeRendered() || !layer.layerIsSelectable.value)
-						continue;
-
-					lastActiveLayer = layer;
-
-					layer.getDataBounds(tempDataBounds);
-					layer.getScreenBounds(tempScreenBounds);
-					//trace(layers.getName(layer),tempDataBounds,tempScreenBounds);
-
-					// get data coords from screen coords
-					var bufferSize:Number = 10;
-
-					queryBounds.setCenteredRectangle(mouseX, mouseY, bufferSize, bufferSize);
-					tempScreenBounds.projectCoordsTo(queryBounds, tempDataBounds);
-
-					var xPrecision:Number = tempDataBounds.getXCoverage() / tempScreenBounds.getXCoverage();
-					var yPrecision:Number = tempDataBounds.getYCoverage() / tempScreenBounds.getYCoverage();
-
-					//trace(layers.getName(layer),queryBounds);
-
-					// probe for records
-
-					if (!tempDataBounds.overlaps(queryBounds))
-						continue;
-					tempDataBounds.constrainBounds(queryBounds, false);
-					var keys:Array = (layer.spatialIndex as SpatialIndex).getClosestOverlappingKeys(queryBounds, xPrecision, yPrecision, tempDataBounds);
-					//trace(layers.getName(layer),keys);
-
-					// stop when we find keys
-					if (keys.length > 0)
-					{
-						setProbeKeys(layer, keys);
-						_lastProbedQKey = keys[0] as IQualifiedKey;
-
-						return;
-					}
-				}
-				// clear keys if nothing was probed
-				// NOTE: this code is hacked to work with only one global probe KeySet
-				if (lastActiveLayer)
-					setProbeKeys(lastActiveLayer, []);
-			}
-			// either not rolled over or nothing was probed
-			_lastProbedQKey = null;
-		}
-
-		protected function setSelectionKeys(layer:SelectablePlotLayer, keys:Array, useMouseMode:Boolean = false):void
-		{
-			if (!Weave.properties.enableToolSelection.value || !enableSelection.value)
-				return;
-
-			// set the probe filter to a new set of keys
-			var keySet:KeySet = layer.selectionFilter.internalObject as KeySet;
-			if (keySet != null)
-			{
-				if (useMouseMode && _mouseMode == InteractionController.SELECT_ADD)
-					keySet.addKeys(keys);
-				else if (useMouseMode && _mouseMode == InteractionController.SELECT_REMOVE)
-					keySet.removeKeys(keys);
-				else
-					keySet.replaceKeys(keys);
-			}
-		}
-
-		protected function setProbeKeys(layer:SelectablePlotLayer, keys:Array):void
-		{
-			//trace("setProbeKeys()",keys);
-			// set the probe filter to a new set of keys
-			var keySet:KeySet = layer.probeFilter.internalObject as KeySet;
-
-			if (keySet != null)
-			{
-				keySet.replaceKeys(keys);
-
-				if (keys.length == 0)
-				{
-					ProbeTextUtils.hideProbeToolTip();
-				}
-				else
-				{
-					var text:String = ProbeTextUtils.getProbeText(keySet.keys, additionalProbeColumns);
-					ProbeTextUtils.showProbeToolTip(text, stage.mouseX, stage.mouseY);
-				}
-			}
-		}
-
-		/**
-		 * An array of additional columns to be displayed in the probe tooltip for this visualization instance
-		 */
-		public var additionalProbeColumns:Array = null;
-
-		protected function clearProbe():void
-		{
-			// don't clear the probe if selection is disabled
-			if (!enableSelection.value)
-				return;
-
-			var spls:Array = layers.getObjects(SelectablePlotLayer);
-			for (var i:int = 0; i < spls.length; i++)
-				setProbeKeys(spls[i], emptyArray);
-		}
-		private const emptyArray:Array = [];
-		protected const queryBounds:IBounds2D = new Bounds2D(); // reusable temporary object
-		protected const tempDataBounds:IBounds2D = new Bounds2D(); // reusable temporary object
-		protected const tempScreenBounds:IBounds2D = new Bounds2D(); // reusable temporary object
-		private const tempPoint:Point = new Point(); // reusable temporary object
-
-		//-----------------------------------------------
-		// backwards compatibility
-		[Deprecated(replacement="InteractionController.defaultDragMode")] public function set defaultMouseMode(value:String):void
-		{
-			var backwardsCompatibility:Object = {
-				"InteractiveVisualization.SELECT_MODE_REPLACE": InteractionController.SELECT,
-				"InteractiveVisualization.SELECT_MODE_SUBTRACT": InteractionController.SELECT_REMOVE,
-				"InteractiveVisualization.SELECT_MODE_ADD": InteractionController.SELECT_ADD,
-				"InteractiveVisualization.PAN_MODE": InteractionController.PAN,
-				"InteractiveVisualization.ZOOM_MODE": InteractionController.ZOOM
-			};
-			Weave.properties.toolInteractions.defaultDragMode.value = backwardsCompatibility[value];
-		}
-	}
-}
+/*
+Weave (Web-based Analysis and Visualization Environment)
+Copyright (C) 2008-2011 University of Massachusetts Lowell
+
+This file is a part of Weave.
+
+Weave is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License, Version 3,
+as published by the Free Software Foundation.
+
+Weave is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Weave.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package weave.visualization.layers
+{
+	import com.cartogrammar.drawing.DashedLine;
+
+	import flash.display.Graphics;
+	import flash.display.InteractiveObject;
+	import flash.events.ContextMenuEvent;
+	import flash.events.Event;
+	import flash.events.KeyboardEvent;
+	import flash.events.MouseEvent;
+	import flash.geom.Point;
+	import flash.ui.ContextMenu;
+	import flash.ui.Keyboard;
+
+	import mx.containers.Canvas;
+
+	import weave.Weave;
+	import weave.api.WeaveAPI;
+	import weave.api.data.IQualifiedKey;
+	import weave.api.detectLinkableObjectChange;
+	import weave.api.newLinkableChild;
+	import weave.api.primitives.IBounds2D;
+	import weave.api.registerLinkableChild;
+	import weave.api.ui.IPlotLayer;
+	import weave.core.LinkableBoolean;
+	import weave.core.LinkableNumber;
+	import weave.core.StageUtils;
+	import weave.data.KeySets.KeySet;
+	import weave.primitives.Bounds2D;
+	import weave.primitives.SimpleGeometry;
+	import weave.utils.CustomCursorManager;
+	import weave.utils.DebugTimer;
+	import weave.utils.ProbeTextUtils;
+	import weave.utils.SpatialIndex;
+	import weave.utils.ZoomUtils;
+
+	/**
+	 * This is a container for a list of PlotLayers
+	 *
+	 * @author adufilie
+	 */
+	public class InteractiveVisualization extends PlotLayerContainer
+	{
+		public function InteractiveVisualization()
+		{
+			doubleClickEnabled = true;
+
+			enableZoomAndPan.value = true;
+			enableSelection.value = true;
+			enableProbe.value = true;
+			enableAutoZoomToExtent.value = true;
+			// adding a canvas as child gets the selection rectangle on top of the vis
+			addChild(selectionCanvas);
+
+			addContextMenuEventListener();
+
+			addEventListener(MouseEvent.DOUBLE_CLICK, handleDoubleClick);
+			addEventListener(MouseEvent.MOUSE_DOWN, handleMouseDown);
+			addEventListener(MouseEvent.ROLL_OUT, handleRollOut);
+			addEventListener(MouseEvent.ROLL_OVER, handleRollOver);
+			addEventListener(MouseEvent.MOUSE_WHEEL,handleMouseWheel);
+			WeaveAPI.StageUtils.addEventCallback(MouseEvent.MOUSE_MOVE, this, handleMouseMove);
+			WeaveAPI.StageUtils.addEventCallback(MouseEvent.MOUSE_UP, this, handleMouseUp);
+			WeaveAPI.StageUtils.addEventCallback(KeyboardEvent.KEY_DOWN, this, handleKeyboardEvent);
+			WeaveAPI.StageUtils.addEventCallback(KeyboardEvent.KEY_UP, this, handleKeyboardEvent);
+			WeaveAPI.StageUtils.addEventCallback(StageUtils.POINT_CLICK_EVENT, this, _handlePointClick);
+
+			//			addEventListener(KeyboardEvent.KEY_DOWN, handleKeyboardEvent);
+			//			addEventListener(KeyboardEvent.KEY_UP, handleKeyboardEvent);
+
+			Weave.properties.dashedSelectionBox.addImmediateCallback(this, validateDashedLine, true);
+
+		}
+
+		private function addContextMenuEventListener():void
+		{
+			var contextMenu:ContextMenu = (WeaveAPI.topLevelApplication as InteractiveObject).contextMenu;
+			if (!contextMenu)
+				return callLater(addContextMenuEventListener);
+			contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, removeCursor);
+		}
+		private function removeCursor(e:Event):void
+		{
+			CustomCursorManager.removeCurrentCursor();
+		}
+
+		public const enableZoomAndPan:LinkableBoolean = newLinkableChild(this, LinkableBoolean);
+		public const enableSelection:LinkableBoolean = newLinkableChild(this, LinkableBoolean);
+		public const enableProbe:LinkableBoolean = newLinkableChild(this, LinkableBoolean);
+		public const zoomFactor:LinkableNumber = registerLinkableChild(this, new LinkableNumber(2, verifyZoomFactor));
+
+		private function verifyZoomFactor(value:Number):Boolean
+		{
+			return value >= 1;
+		}
+
+		private var activeKeyType:String = null;
+		private var mouseDragActive:Boolean = false;
+		private const selectionCanvas:Canvas = new Canvas();
+
+		private const mouseDragStageCoords:IBounds2D = new Bounds2D();
+
+		private var _mouseMode:String = null;
+
+		private function isModeSelection(mode:String):Boolean
+		{
+			return mode == InteractionController.SELECT_ADD
+				|| mode == InteractionController.SELECT
+				|| mode == InteractionController.SELECT_REMOVE;
+		}
+
+		private function isModeZoom(mode:String):Boolean
+		{
+			return mode == InteractionController.ZOOM
+				|| mode == InteractionController.ZOOM_IN
+				|| mode == InteractionController.ZOOM_OUT
+				|| mode == InteractionController.ZOOM_TO_EXTENT;
+		}
+
+
+		private function updateMouseMode(mouseEventType:String = null):void
+		{
+			if (mouseEventType)
+				_mouseMode = Weave.properties.toolInteractions.determineInteraction(mouseEventType);
+			else
+				_mouseMode = Weave.properties.toolInteractions.determineInteractionMode();
+
+			if (!enableZoomAndPan.value && (isModeZoom(_mouseMode) || _mouseMode == InteractionController.PAN))
+			{
+				_mouseMode = InteractionController.SELECT;
+			}
+			if (!enableSelection.value && isModeSelection(_mouseMode))
+			{
+				_mouseMode = null;//Weave.properties.toolInteractions.defaultDragMode.value;
+			}
+
+			updateMouseCursor();
+		}
+
+		private var _selectModeCursorOffsetX:int = -2;
+		private var _selectModeCursorOffsetY:int = -2;
+		private function updateMouseCursor():void
+		{
+			if (mouseIsRolledOver)
+			{
+				if (_mouseMode == InteractionController.PAN)
+				{
+					if (WeaveAPI.StageUtils.mouseButtonDown)
+						CustomCursorManager.showCursor(CustomCursorManager.HAND_GRAB_CURSOR);
+					else
+						CustomCursorManager.showCursor(CustomCursorManager.HAND_CURSOR);
+				}
+				else if (_mouseMode == InteractionController.SELECT_ADD)
+				{
+					CustomCursorManager.showCursor(CustomCursorManager.SELECT_ADD_CURSOR, 2, _selectModeCursorOffsetX, _selectModeCursorOffsetY);
+				}
+				else if (_mouseMode == InteractionController.SELECT || _mouseMode == InteractionController.PROBE)
+				{
+					CustomCursorManager.showCursor(CustomCursorManager.SELECT_REPLACE_CURSOR, 2, _selectModeCursorOffsetX, _selectModeCursorOffsetY);
+				}
+				else if (_mouseMode == InteractionController.SELECT_REMOVE)
+				{
+					CustomCursorManager.showCursor(CustomCursorManager.SELECT_SUBTRACT_CURSOR, 2, _selectModeCursorOffsetX, _selectModeCursorOffsetY);
+				}
+				else if (_mouseMode == InteractionController.ZOOM)
+				{
+					CustomCursorManager.showCursor(CustomCursorManager.ZOOM_CURSOR);
+				}
+			}
+		}
+
+		private function handleKeyboardEvent():void
+		{
+			// if the escape key was hit, stop whatever mouse drag operation is in progress
+			if (WeaveAPI.StageUtils.keyboardEvent && WeaveAPI.StageUtils.keyboardEvent.keyCode == Keyboard.ESCAPE)
+			{
+				mouseDragActive = false;
+			}
+
+			// if currently dragging, don't change mouse mode
+			if (!mouseDragActive)
+				updateMouseMode();
+		}
+
+		/**
+		 * This function gets called whenever StageUtils runs point click event callbacks.
+		 * This function should remain private.
+		 */
+		private function _handlePointClick():void
+		{
+			// only handle the event if the mouse is rolled over
+			if (mouseIsRolledOver)
+				handleMouseClick(WeaveAPI.StageUtils.mouseEvent);
+		}
+
+		// this function can be defined with override by extending classes and call super.handleMouseClick(event);
+		protected function handleMouseClick(event:MouseEvent):void
+		{
+			handleMouseEvent(event);
+		}
+
+
+		protected function handleDoubleClick(event:MouseEvent):void
+		{
+			handleMouseEvent(event);
+		}
+
+		protected function handleMouseDown(event:MouseEvent):void
+		{
+			updateMouseMode(InteractionController.DRAG); // modifier keys may have changed just prior to pressing mouse button, so update mode now
+
+			//for detecting change between drag start and drag end
+			// TEMPORARY HACK - Weave.defaultSelectionKeySet
+			detectLinkableObjectChange( handleMouseDown, Weave.defaultSelectionKeySet );
+
+			mouseDragActive = true;
+			// clear probe when drag starts
+			clearProbe();
+			// start the selection rectangle from the mouse down point
+			// for accuracy, use the stage coordinates from the event, not the current coordinates from the stage
+			mouseDragStageCoords.setRectangle(event.stageX, event.stageY, 0, 0);
+			updateSelectionCoords(true);
+
+			handleMouseEvent(event);
+		}
+		protected function handleMouseUp():void
+		{
+			updateMouseCursor();
+
+			// when the mouse is released, handle mouse move so the selection rectangle will cause the selection to update.
+			handleMouseEvent(WeaveAPI.StageUtils.mouseEvent);
+		}
+		protected function handleMouseMove():void
+		{
+			handleMouseEvent(WeaveAPI.StageUtils.mouseEvent);
+		}
+		protected function handleRollOut(event:MouseEvent):void
+		{
+			if (mouseIsRolledOver)
+			{
+				CustomCursorManager.removeAllCursors();
+				mouseIsRolledOver = false;
+
+				// when rolled over goes from true to false, clear the probe
+				clearProbe();
+			}
+			handleMouseEvent(event);
+
+			updateMouseCursor();
+		}
+		protected function handleRollOver(event:MouseEvent):void
+		{
+			mouseIsRolledOver = true;
+			handleMouseEvent(event);
+
+			updateMouseCursor();
+		}
+
+		protected var mouseIsRolledOver:Boolean = false; // start this at false because we don't want tools probing when mouse is not rolled over
+
+		private const _tempBounds:IBounds2D = new Bounds2D();
+		private const _screenBounds:IBounds2D = new Bounds2D();
+		protected function handleMouseWheel(event:MouseEvent):void
+		{
+			if (Weave.properties.enableMouseWheel.value)
+				handleMouseEvent(event);
+		}
+
+		protected function handleMouseEvent(event:MouseEvent):void
+		{
+			// determine proper event type
+			var eventType:String = null;
+			switch (event.type)
+			{
+				case MouseEvent.CLICK:
+				{
+					eventType = InteractionController.CLICK;
+					break;
+				}
+				case MouseEvent.DOUBLE_CLICK:
+				{
+					if (!mouseIsRolledOver)
+						return;
+
+					eventType = InteractionController.DCLICK;
+					break;
+				}
+				case MouseEvent.MOUSE_MOVE:
+				case MouseEvent.ROLL_OVER:
+				case MouseEvent.ROLL_OUT:
+				{
+					if (event.buttonDown)
+						eventType = InteractionController.DRAG;
+					else
+						eventType = InteractionController.MOVE;
+
+					break;
+				}
+				case MouseEvent.MOUSE_WHEEL:
+				{
+					eventType = InteractionController.WHEEL;
+					break;
+				}
+			}
+
+			// if currently dragging, update drag coords and don't change mouse mode
+			if (mouseDragActive)
+			{
+				// update end coordinates of selection rectangle
+				if (event.type == MouseEvent.MOUSE_UP)
+				{
+					// on a mouse up event, we want accuracy, so use the mouse up event coordinates
+					mouseDragStageCoords.setMaxCoords(event.stageX, event.stageY);
+				}
+				else
+				{
+					// IMPORTANT: for speed, use the current mouse coordinates instead of the event coordinates
+					mouseDragStageCoords.setMaxCoords(stage.mouseX, stage.mouseY);
+				}
+				if (isModeSelection(_mouseMode))
+					updateSelectionCoords();
+			}
+			else // not dragging -- ok to update mouse mode
+			{
+				updateMouseMode(eventType);
+			}
+
+			var dragReleased:Boolean = mouseDragActive && !event.buttonDown;
+			switch (_mouseMode)
+			{
+				case InteractionController.SELECT_ADD:
+				{
+					if (mouseDragActive)
+						handleSelection(event, _mouseMode);
+					break;
+				}
+				case InteractionController.SELECT:
+				{
+				   	if (mouseDragActive)
+						handleSelection(event, _mouseMode);
+					break;
+				}
+				case InteractionController.SELECT_REMOVE:
+				{
+					if (mouseDragActive)
+						handleSelection(event, _mouseMode);
+					break;
+				}
+				case InteractionController.SELECT_ALL:
+				{
+					if (mouseIsRolledOver)
+						selectAllVisibleRecords();
+					break;
+				}
+				case InteractionController.PAN:
+				{
+					if (enableZoomAndPan.value && mouseDragActive)
+					{
+						// pan the dragged distance
+						projectDragBoundsToDataQueryBounds(null, false);
+						zoomBounds.getDataBounds(tempDataBounds);
+						tempDataBounds.setCenter(tempDataBounds.getXCenter() - queryBounds.getWidth(), tempDataBounds.getYCenter() - queryBounds.getHeight());
+						zoomBounds.setDataBounds(tempDataBounds);
+						// set begin point for next pan
+						mouseDragStageCoords.getMaxPoint(tempPoint);
+						mouseDragStageCoords.setMinPoint(tempPoint);
+					}
+					break;
+				}
+				case InteractionController.ZOOM:
+				{
+					if (enableZoomAndPan.value)
+					{
+						if (eventType == InteractionController.WHEEL)
+						{
+							zoomBounds.getDataBounds(_tempBounds);
+							zoomBounds.getScreenBounds(_screenBounds);
+							if (event.delta > 0)
+								ZoomUtils.zoomDataBoundsByRelativeScreenScale(_tempBounds,_screenBounds,mouseX,mouseY,zoomFactor.value,false);
+							else if (event.delta < 0)
+								ZoomUtils.zoomDataBoundsByRelativeScreenScale(_tempBounds,_screenBounds,mouseX,mouseY,1/zoomFactor.value,false);
+							zoomBounds.setDataBounds(_tempBounds);
+						}
+						else if (dragReleased)
+						{
+							// zoom to selected data bounds if area > 0
+							projectDragBoundsToDataQueryBounds(null, true); // data bounds in same direction when zooming
+							if (queryBounds.getArea() > 0)
+								zoomBounds.setDataBounds(queryBounds);
+						}
+					}
+					break;
+				}
+				case InteractionController.PROBE:
+				{
+					if (mouseIsRolledOver)
+					{
+						// probe when mouse is rolled over and selection is inactive
+						handleProbe();
+					}
+
+					break;
+				}
+				case InteractionController.ZOOM_TO_EXTENT:
+				{
+					if (enableZoomAndPan.value)
+						zoomBounds.setDataBounds(fullDataBounds, true); // zoom to full extent
+					break;
+				}
+				case InteractionController.ZOOM_IN:
+				case InteractionController.ZOOM_OUT:
+				{
+					if (enableZoomAndPan.value)
+					{
+						var multiplier:Number = 1;
+						if (_mouseMode == InteractionController.ZOOM_IN)
+							multiplier = 1 / zoomFactor.value;
+						else
+							multiplier = zoomFactor.value;
+
+						projectDragBoundsToDataQueryBounds(null, false);
+						zoomBounds.getDataBounds(_tempBounds);
+						_tempBounds.setCenter(queryBounds.getXCenter(), queryBounds.getYCenter());
+
+						_tempBounds.centeredResize(_tempBounds.getWidth() * multiplier, _tempBounds.getHeight() * multiplier);
+
+						zoomBounds.setDataBounds(_tempBounds);
+					}
+					break;
+				}
+			}
+
+			// finally, unset mouseDragActive if button was released
+			if (dragReleased)
+			{
+				mouseDragActive = false;
+			}
+
+			updateSelectionRectangleGraphics();
+		}
+
+		//TODO - use this
+		private function selectAllVisibleRecords():void
+		{
+			// clear selection or select all
+
+			// set up mouse drag rectangle to select or deselect visible area
+			zoomBounds.getScreenBounds(_screenBounds);
+			_screenBounds.getMinPoint(tempPoint);
+			mouseDragStageCoords.setMinPoint(localToGlobal(tempPoint));
+			_screenBounds.getMaxPoint(tempPoint);
+			mouseDragStageCoords.setMaxPoint(localToGlobal(tempPoint));
+
+			immediateHandleSelection();
+		}
+
+		private var _selectionGraphicsCleared:Boolean = true;
+		private const _selectionGeometry:SimpleGeometry = new SimpleGeometry();
+		private var _lassoScreenPoints:Array = [];
+		private var _lastLassoPoint:Point = null;
+
+		protected function updateSelectionCoords(reset:Boolean = false):void
+		{
+			if (!isModeSelection(_mouseMode))
+				return;
+
+			mouseDragStageCoords.getMaxPoint(tempPoint); // stage coords
+			var localMaxPoint:Point = selectionCanvas.globalToLocal(tempPoint); // local screen coords
+
+			if (reset || _lassoScreenPoints.length == 0)
+			{
+				mouseDragStageCoords.getMinPoint(tempPoint); // stage coords
+				var localMinPoint:Point = selectionCanvas.globalToLocal(tempPoint); // local screen coords
+
+				_lassoScreenPoints = [localMinPoint, localMaxPoint];
+				_lastLassoPoint = localMaxPoint;
+			}
+			else if (Math.abs(localMaxPoint.x - _lastLassoPoint.x) >= 5 || Math.abs(localMaxPoint.y - _lastLassoPoint.y) >= 5 )
+			{
+				// if the new point is far enough away from the previous point, add it to the coords
+				_lassoScreenPoints.push(localMaxPoint);
+				_lastLassoPoint = localMaxPoint;
+			}
+		}
+
+		protected function updateSelectionRectangleGraphics():void
+		{
+			if (!Weave.properties.enableToolSelection.value || !enableSelection.value)
+				return;
+
+			var g:Graphics = selectionCanvas.graphics;
+			if (!_selectionGraphicsCleared)
+				g.clear();
+
+			if (!mouseDragActive || _mouseMode == InteractionController.PAN)
+			{
+				_selectionGraphicsCleared = true;
+				return;
+			}
+
+			_selectionGraphicsCleared = false;
+
+			// use a blue rectangle for zoom mode, green for selection
+			_dashedLine.graphics = g;
+			if (_mouseMode == InteractionController.ZOOM)
+			{
+				_dashedLine.lineStyle(2, 0x00faff, .75);
+			}
+			else
+			{
+				_dashedLine.lineStyle(2, 0x00ff00, .75);
+			}
+
+			mouseDragStageCoords.getMinPoint(tempPoint); // stage coords
+			var localMinPoint:Point = selectionCanvas.globalToLocal(tempPoint); // local screen coords
+			mouseDragStageCoords.getMaxPoint(tempPoint); // stage coords
+			var localMaxPoint:Point = selectionCanvas.globalToLocal(tempPoint); // local screen coords
+
+			var dragX:Number = localMinPoint.x;
+			var dragY:Number = localMinPoint.y;
+			var dragWidth:Number = localMaxPoint.x - localMinPoint.x;
+			var dragHeight:Number = localMaxPoint.y - localMinPoint.y;
+
+			// init temp bounds for reprojecting coordinates
+			zoomBounds.getDataBounds(tempDataBounds);
+			zoomBounds.getScreenBounds(tempScreenBounds);
+
+			if (Weave.properties.selectionMode.value == InteractionController.SELECTION_MODE_RECTANGLE)
+			{
+				_dashedLine.drawRect(dragX, dragY, dragWidth, dragHeight);
+			}
+			else if (Weave.properties.selectionMode.value == InteractionController.SELECTION_MODE_CIRCLE)
+			{
+				var coords:Array = getCircleLocalScreenCoords();
+				for (var i:int = 0; i <= coords.length; i++)
+				{
+					var point:Point = coords[i % coords.length];
+					if (i == 0)
+						_dashedLine.moveTo(point.x, point.y);
+					else
+						_dashedLine.lineTo(point.x, point.y);
+				}
+			}
+			else if (Weave.properties.selectionMode.value == InteractionController.SELECTION_MODE_LASSO)
+			{
+				fillPolygon(g, _dashedLine.lineColor, 0.05, _lassoScreenPoints);
+
+				for (var k:int = 0; k <= _lassoScreenPoints.length; k++)
+				{
+					var kp:Point = _lassoScreenPoints[k % _lassoScreenPoints.length];
+					if (k == 0)
+						_dashedLine.moveTo(kp.x, kp.y);
+					else
+						_dashedLine.lineTo(kp.x, kp.y);
+				}
+			}
+		}
+
+		private function getCircleLocalScreenCoords():Array
+		{
+			mouseDragStageCoords.getMinPoint(tempPoint); // stage coords
+			var localMinPoint:Point = selectionCanvas.globalToLocal(tempPoint); // local screen coords
+			mouseDragStageCoords.getMaxPoint(tempPoint); // stage coords
+			var localMaxPoint:Point = selectionCanvas.globalToLocal(tempPoint); // local screen coords
+
+			var dragWidth:Number = localMaxPoint.x - localMinPoint.x;
+			var dragHeight:Number = localMaxPoint.y - localMinPoint.y;
+
+			var direction:Number = -mouseDragStageCoords.getXDirection() || 1;
+			var thetaOffset:Number = Math.atan2(dragHeight, dragWidth);
+			var radius:Number = Math.sqrt(dragWidth*dragWidth + dragHeight*dragHeight);
+
+			const segmentLength:Number = 8; // pixels
+			var segmentSpan:Number = segmentLength / radius; // radians
+			segmentSpan = Math.min(Math.PI / 4, segmentSpan); // maximum 45 degrees per segment
+			// draw the segments
+			var segmentCount:Number = Math.ceil(Math.PI * 2 / segmentSpan);
+			segmentCount = Math.min(64, segmentCount);
+
+			var result:Array = [];
+			for (var i:int = 0; i < segmentCount + 1; i++)
+			{
+				var theta:Number = direction * i * 2 * Math.PI / segmentCount + thetaOffset;
+				var _x:Number = localMinPoint.x + radius * Math.cos(theta); // center a + radius x * cos(theta)
+				var _y:Number = localMinPoint.y + radius * Math.sin(theta); // center b + radius y * sin(theta)
+				result.push(new Point(_x, _y));
+			}
+			return result;
+		}
+
+		private function fillPolygon(graphics:Graphics, color:uint, alpha:Number, points:Array):void
+		{
+			graphics.lineStyle(0,0,0);
+			var n:int = points.length;
+			for (var i:int = 0; i <= n; i++)
+			{
+				var point:Point = points[i % n];
+				if (i == 0)
+				{
+					graphics.moveTo(point.x, point.y);
+					graphics.beginFill(color, alpha);
+				}
+				else
+					graphics.lineTo(point.x, point.y);
+			}
+			graphics.endFill();
+		}
+
+		private const _dashedLine:DashedLine = new DashedLine(0, 0, null);
+		private function validateDashedLine():void
+		{
+			_dashedLine.lengthsString = Weave.properties.dashedSelectionBox.value;
+		}
+
+		private function handleSelection(event:MouseEvent, mode:String):void
+		{
+			var _layers:Array;
+			var i:int;
+			var layer:SelectablePlotLayer;
+
+			// update end coordinates of selection rectangle
+			if (event.type == MouseEvent.MOUSE_UP)
+			{
+				// on a mouse up event, we want accuracy, so use the mouse up event coordinates
+				mouseDragStageCoords.setMaxCoords(event.stageX, event.stageY);
+			}
+			else
+			{
+				// IMPORTANT: for interaction speed, use the current mouse coordinates instead of the event coordinates.
+				// otherwise, queued mouse events will be handled individually and it will feel sluggish
+				mouseDragStageCoords.setMaxCoords(stage.mouseX, stage.mouseY);
+			}
+
+			if ( isModeSelection(mode) )
+			{
+				// only if selection is enabled
+				if (enableSelection.value)
+					delayedHandleSelection();
+			}
+		}
+		private function clearSelection():void
+		{
+			var _layers:Array = layers.getObjects(SelectablePlotLayer);
+			for (var i:int = 0; i < _layers.length; i++)
+			{
+				setSelectionKeys(_layers[i], []);
+			}
+		}
+
+		/**
+		 * This function projects drag start,stop screen coordinates into data coordinates and stores the result in queryBounds.
+		 * @param layer If layer is null, InteractiveVisualization's screen/data bounds will be used.  Otherwise, uses IPlotLayer's bounds.
+		 * @param zooming Specify true when computing zoom coordinates.
+		 */
+		protected function projectDragBoundsToDataQueryBounds(layer:IPlotLayer, zooming:Boolean):void
+		{
+			if (layer)
+			{
+				layer.getDataBounds(tempDataBounds);
+				layer.getScreenBounds(tempScreenBounds);
+			}
+			else
+			{
+				zoomBounds.getDataBounds(tempDataBounds);
+				zoomBounds.getScreenBounds(tempScreenBounds);
+			}
+
+			// project stage coords to local layer coords
+			mouseDragStageCoords.getMinPoint(tempPoint); // stage coords
+			var localMinPoint:Point = globalToLocal(tempPoint); // local screen coords
+			mouseDragStageCoords.getMaxPoint(tempPoint); // stage coords
+			var localMaxPoint:Point = globalToLocal(tempPoint); // local screen coords
+
+			// project screen coords to data coords
+			tempScreenBounds.projectPointTo(localMinPoint, tempDataBounds);
+			tempScreenBounds.projectPointTo(localMaxPoint, tempDataBounds);
+
+			// query the spatial index, set selection
+			queryBounds.setMinPoint(localMinPoint);
+			queryBounds.setMaxPoint(localMaxPoint);
+
+			if (zooming)
+			{
+				// swap min,max coordinates if necessary
+				if (queryBounds.getXDirection() != tempDataBounds.getXDirection())
+					queryBounds.setXRange(queryBounds.getXMax(), queryBounds.getXMin());
+				if (queryBounds.getYDirection() != tempDataBounds.getYDirection())
+					queryBounds.setYRange(queryBounds.getYMax(), queryBounds.getYMin());
+
+				// expand rectangle if necessary to match screen aspect ratio
+				var xScale:Number = queryBounds.getXCoverage() / tempScreenBounds.getXCoverage();
+				var yScale:Number = queryBounds.getYCoverage() / tempScreenBounds.getYCoverage();
+				if (xScale > yScale)
+					queryBounds.setHeight( queryBounds.getYDirection() * tempScreenBounds.getYCoverage() * xScale );
+				if (yScale > xScale)
+					queryBounds.setWidth( queryBounds.getXDirection() * tempScreenBounds.getXCoverage() * yScale );
+			}
+		}
+
+		protected function delayedHandleSelection(allowCallLater:Boolean = true):void
+		{
+			if (!parent)
+				return;
+
+			if (WeaveAPI.StageUtils.mouseMoved)
+			{
+				if (allowCallLater)
+					callLater(delayedHandleSelection, [false]);
+			}
+			else
+			{
+				// handle selection when mouse hasn't moved since last frame.
+				immediateHandleSelection();
+			}
+		}
+
+		protected function immediateHandleSelection():void
+		{
+			// don't set a selection or clear the probe keys if selection is disabled
+			if (!enableSelection.value)
+				return;
+
+			var _layers:Array = layers.getObjects(SelectablePlotLayer); // bottom to top
+			// loop from bottom layer to top layer
+			for (var index:int = 0; index < _layers.length; index++)
+			{
+				var layer:SelectablePlotLayer = _layers[index] as SelectablePlotLayer;
+				// skip this layer if it is disabled
+				if (!layer.shouldBeRendered() || !layer.layerIsSelectable.value)
+					continue;
+				// skip this layer if it does not contain lastProbedQKey
+				if (_lastProbedQKey && !layer.plotter.keySet.containsKey(_lastProbedQKey))
+					continue;
+
+				// when using the selection layer, clear the probe
+				setProbeKeys(layer, []);
+				projectDragBoundsToDataQueryBounds(layer, false);
+
+				// calculate minImportance
+				layer.getDataBounds(tempDataBounds);
+				layer.getScreenBounds(tempScreenBounds);
+				var minImportance:Number = tempDataBounds.getArea() / tempScreenBounds.getArea();
+
+				// don't query outside visible data bounds
+				if (!tempDataBounds.overlaps(queryBounds))
+					continue;
+				tempDataBounds.constrainBounds(queryBounds, false);
+
+				var keys:Array = [];
+				if (Weave.properties.selectionMode.value == InteractionController.SELECTION_MODE_RECTANGLE)
+				{
+					keys = (layer.spatialIndex as SpatialIndex).getKeysGeometryOverlap(queryBounds, minImportance, false, tempDataBounds);
+				}
+				else if (Weave.properties.selectionMode.value == InteractionController.SELECTION_MODE_CIRCLE)
+				{
+					var coords:Array = getCircleLocalScreenCoords();
+					for each (var point:Point in coords)
+						tempScreenBounds.projectPointTo(point, tempDataBounds);
+					_selectionGeometry.setVertices(coords);
+
+					keys = (layer.spatialIndex as SpatialIndex).getKeysGeometryOverlapGeometry(_selectionGeometry, minImportance, false);
+				}
+				else if (Weave.properties.selectionMode.value == InteractionController.SELECTION_MODE_LASSO)
+				{
+					var lassoDataPoints:Array = [];
+					for each (var screenPoint:Point in _lassoScreenPoints)
+					{
+						var tempDataPoint:Point = screenPoint.clone();
+						tempScreenBounds.projectPointTo(tempDataPoint, tempDataBounds);
+						lassoDataPoints.push(tempDataPoint);
+					}
+					_selectionGeometry.setVertices(lassoDataPoints);
+
+					keys = (layer.spatialIndex as SpatialIndex).getKeysGeometryOverlapGeometry(_selectionGeometry, minImportance, false);
+				}
+
+
+				setSelectionKeys(layer, keys, true);
+
+				break; // select only one layer at a time
+			}
+
+
+			// if mouse is released and selection hasn't changed since mouse down, clear selection
+			// TEMPORARY HACK - Weave.defaultSelectionKeySet
+			if (_mouseMode == InteractionController.SELECT &&
+				!WeaveAPI.StageUtils.mouseButtonDown &&
+				!detectLinkableObjectChange(handleMouseDown, Weave.defaultSelectionKeySet))
+			{
+				clearSelection();
+			}
+
+		}
+
+		/**
+		 * This is the last IQualifiedKey (record identifier) that was probed.
+		 */
+		public function get lastProbedKey():IQualifiedKey { return _lastProbedQKey; }
+		private var _lastProbedQKey:IQualifiedKey = null;
+
+		protected function handleProbe(allowCallLater:Boolean = true):void
+		{
+			if (!parent || !Weave.properties.enableToolProbe.value || !enableProbe.value)
+				return;
+
+			// NOTE: this code is hacked to work with only one global probe KeySet
+
+			// only probe if the mouse coords are the same two frames in a row
+			if (WeaveAPI.StageUtils.mouseMoved)
+			{
+				if (allowCallLater)
+					callLater(handleProbe, [false]);
+			}
+			else if (mouseIsRolledOver)
+			{
+				// handle probe when mouse hasn't moved since last frame.
+				var _layers:Array = layers.getObjects(SelectablePlotLayer).reverse(); // top to bottom
+				var lastActiveLayer:SelectablePlotLayer = null;
+				for (var i:int = 0; i < _layers.length; i++)
+				{
+					var layer:SelectablePlotLayer = _layers[i];
+					if (!layer.shouldBeRendered() || !layer.layerIsSelectable.value)
+						continue;
+
+					lastActiveLayer = layer;
+
+					layer.getDataBounds(tempDataBounds);
+					layer.getScreenBounds(tempScreenBounds);
+					//trace(layers.getName(layer),tempDataBounds,tempScreenBounds);
+
+					// get data coords from screen coords
+					var bufferSize:Number = 10;
+
+					queryBounds.setCenteredRectangle(mouseX, mouseY, bufferSize, bufferSize);
+					tempScreenBounds.projectCoordsTo(queryBounds, tempDataBounds);
+
+					var xPrecision:Number = tempDataBounds.getXCoverage() / tempScreenBounds.getXCoverage();
+					var yPrecision:Number = tempDataBounds.getYCoverage() / tempScreenBounds.getYCoverage();
+
+					//trace(layers.getName(layer),queryBounds);
+
+					// probe for records
+
+					if (!tempDataBounds.overlaps(queryBounds))
+						continue;
+					tempDataBounds.constrainBounds(queryBounds, false);
+					var keys:Array = (layer.spatialIndex as SpatialIndex).getClosestOverlappingKeys(queryBounds, xPrecision, yPrecision, tempDataBounds);
+					//trace(layers.getName(layer),keys);
+
+					// stop when we find keys
+					if (keys.length > 0)
+					{
+						setProbeKeys(layer, keys);
+						_lastProbedQKey = keys[0] as IQualifiedKey;
+
+						return;
+					}
+				}
+				// clear keys if nothing was probed
+				// NOTE: this code is hacked to work with only one global probe KeySet
+				if (lastActiveLayer)
+					setProbeKeys(lastActiveLayer, []);
+			}
+			// either not rolled over or nothing was probed
+			_lastProbedQKey = null;
+		}
+
+		protected function setSelectionKeys(layer:SelectablePlotLayer, keys:Array, useMouseMode:Boolean = false):void
+		{
+			if (!Weave.properties.enableToolSelection.value || !enableSelection.value)
+				return;
+
+			// set the probe filter to a new set of keys
+			var keySet:KeySet = layer.selectionFilter.internalObject as KeySet;
+			if (keySet != null)
+			{
+				if (useMouseMode && _mouseMode == InteractionController.SELECT_ADD)
+					keySet.addKeys(keys);
+				else if (useMouseMode && _mouseMode == InteractionController.SELECT_REMOVE)
+					keySet.removeKeys(keys);
+				else
+					keySet.replaceKeys(keys);
+			}
+		}
+
+		protected function setProbeKeys(layer:SelectablePlotLayer, keys:Array):void
+		{
+			//trace("setProbeKeys()",keys);
+			// set the probe filter to a new set of keys
+			var keySet:KeySet = layer.probeFilter.internalObject as KeySet;
+
+			if (keySet != null)
+			{
+				keySet.replaceKeys(keys);
+
+				if (keys.length == 0)
+				{
+					ProbeTextUtils.hideProbeToolTip();
+				}
+				else
+				{
+					var text:String = ProbeTextUtils.getProbeText(keySet.keys, additionalProbeColumns);
+					ProbeTextUtils.showProbeToolTip(text, stage.mouseX, stage.mouseY);
+				}
+			}
+		}
+
+		/**
+		 * An array of additional columns to be displayed in the probe tooltip for this visualization instance
+		 */
+		public var additionalProbeColumns:Array = null;
+
+		protected function clearProbe():void
+		{
+			// don't clear the probe if selection is disabled
+			if (!enableSelection.value)
+				return;
+
+			var spls:Array = layers.getObjects(SelectablePlotLayer);
+			for (var i:int = 0; i < spls.length; i++)
+				setProbeKeys(spls[i], emptyArray);
+		}
+		private const emptyArray:Array = [];
+		protected const queryBounds:IBounds2D = new Bounds2D(); // reusable temporary object
+		protected const tempDataBounds:IBounds2D = new Bounds2D(); // reusable temporary object
+		protected const tempScreenBounds:IBounds2D = new Bounds2D(); // reusable temporary object
+		private const tempPoint:Point = new Point(); // reusable temporary object
+
+		//-----------------------------------------------
+		// backwards compatibility
+		[Deprecated(replacement="InteractionController.defaultDragMode")] public function set defaultMouseMode(value:String):void
+		{
+			var backwardsCompatibility:Object = {
+				"InteractiveVisualization.SELECT_MODE_REPLACE": InteractionController.SELECT,
+				"InteractiveVisualization.SELECT_MODE_SUBTRACT": InteractionController.SELECT_REMOVE,
+				"InteractiveVisualization.SELECT_MODE_ADD": InteractionController.SELECT_ADD,
+				"InteractiveVisualization.PAN_MODE": InteractionController.PAN,
+				"InteractiveVisualization.ZOOM_MODE": InteractionController.ZOOM
+			};
+			Weave.properties.toolInteractions.defaultDragMode.value = backwardsCompatibility[value];
+		}
+	}
+}