You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ti...@apache.org on 2012/01/06 21:58:45 UTC

svn commit: r1228400 [2/6] - in /incubator/flex/whiteboard/navigators: ./ .settings/ src/ src/ws/ src/ws/tink/ src/ws/tink/spark/ src/ws/tink/spark/containers/ src/ws/tink/spark/containers/supportClasses/ src/ws/tink/spark/controls/ src/ws/tink/spark/c...

Added: incubator/flex/whiteboard/navigators/src/ws/tink/spark/containers/Navigator.as
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/navigators/src/ws/tink/spark/containers/Navigator.as?rev=1228400&view=auto
==============================================================================
--- incubator/flex/whiteboard/navigators/src/ws/tink/spark/containers/Navigator.as (added)
+++ incubator/flex/whiteboard/navigators/src/ws/tink/spark/containers/Navigator.as Fri Jan  6 20:58:43 2012
@@ -0,0 +1,1520 @@
+/*
+
+Copyright (c) 2010 Tink Ltd - http://www.tink.ws
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
+THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+*/
+
+package ws.tink.spark.containers
+{
+	import flash.events.Event;
+	
+	import mx.core.ContainerCreationPolicy;
+	import mx.core.IDeferredContentOwner;
+	import mx.core.IDeferredInstance;
+	import mx.core.IFlexModuleFactory;
+	import mx.core.ISelectableList;
+	import mx.core.IVisualElement;
+	import mx.core.IVisualElementContainer;
+	import mx.core.mx_internal;
+	import mx.events.CollectionEvent;
+	import mx.events.FlexEvent;
+	import mx.utils.BitFlagUtil;
+	
+	import spark.components.supportClasses.SkinnableContainerBase;
+	import spark.events.ElementExistenceEvent;
+	import spark.events.IndexChangeEvent;
+	import spark.layouts.supportClasses.LayoutBase;
+	
+	import ws.tink.spark.layouts.supportClasses.INavigatorLayout;
+	import ws.tink.spark.supportClasses.INavigator;
+	
+	use namespace mx_internal;
+	
+	
+	
+	//--------------------------------------
+	//  Styles
+	//--------------------------------------
+	
+	/**
+	 *  Alpha level of the color defined by the <code>borderColor</code> style.
+	 *  
+	 *  Valid values range from 0.0 to 1.0. 
+	 *  
+	 *  @default 1.0
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	[Style(name="borderAlpha", type="Number", inherit="no")]
+	
+	/**
+	 *  Color of the border.
+	 *  
+	 *  @default 0xB7BABC
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	[Style(name="borderColor", type="uint", format="Color", inherit="no")]
+	
+	/**
+	 *  Determines if the border is visible or not. 
+	 *  If <code>false</code>, then no border is visible
+	 *  except a border set by using the <code>borderStroke</code> property. 
+	 *   
+	 *  @default true
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	[Style(name="borderVisible", type="Boolean", inherit="no")]
+	
+	
+	
+	//--------------------------------------
+	//  Events
+	//--------------------------------------
+	
+	/**
+	 *  Dispatched after the content for this component has been created. With deferred 
+	 *  instantiation, the content for a component may be created long after the 
+	 *  component is created.
+	 *
+	 *  @eventType mx.events.FlexEvent.CONTENT_CREATION_COMPLETE
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	[Event(name="contentCreationComplete", type="mx.events.FlexEvent")]
+	
+	/**
+	 *  Dispatched when a visual element is added to the content holder.
+	 *  <code>event.element</code> is the visual element that was added.
+	 *
+	 *  @eventType spark.events.ElementExistenceEvent.ELEMENT_ADD
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	[Event(name="elementAdd", type="spark.events.ElementExistenceEvent")]
+	
+	/**
+	 *  Dispatched when a visual element is removed from the content holder.
+	 *  <code>event.element</code> is the visual element that's being removed.
+	 *
+	 *  @eventType spark.events.ElementExistenceEvent.ELEMENT_REMOVE
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	[Event(name="elementRemove", type="spark.events.ElementExistenceEvent")]
+	
+	//--------------------------------------
+	//  Events
+	//--------------------------------------
+	
+	/**
+	 *  Dispatched when the ISelectableList has been updated in some way.
+	 *
+	 *  @eventType mx.events.CollectionEvent.COLLECTION_CHANGE
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	[Event(name="collectionChange", type="mx.events.CollectionEvent")]
+	
+	/**
+	 *  Dispatched after the selection has changed. 
+	 *  This event is dispatched when the user interacts with the control.
+	 * 
+	 *  <p>When you change the value of the <code>selectedIndex</code> 
+	 *  or <code>selectedItem</code> properties programmatically, 
+	 *  the control does not dispatch the <code>change</code> event. 
+	 *  It dispatches the <code>valueCommit</code> event instead.</p>
+	 *
+	 *  @eventType spark.events.IndexChangeEvent.CHANGE
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	[Event(name="change", type="spark.events.IndexChangeEvent")]
+	
+//	include "../styles/metadata/BasicInheritingTextStyles.as"
+//	include "../styles/metadata/AdvancedInheritingTextStyles.as"
+//	include "../styles/metadata/SelectionFormatTextStyles.as"
+	
+	/**
+	 *  @copy spark.components.supportClasses.GroupBase#style:accentColor
+	 * 
+	 *  @default #0099FF
+	 * 
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	[Style(name="accentColor", type="uint", format="Color", inherit="yes", theme="spark")]
+	
+	/**
+	 *  @copy spark.components.supportClasses.GroupBase#style:alternatingItemColors
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	[Style(name="alternatingItemColors", type="Array", arrayType="uint", format="Color", inherit="yes", theme="spark")]
+	
+	/**
+	 *  Alpha level of the background for this component.
+	 *  Valid values range from 0.0 to 1.0. 
+	 *  
+	 *  @default 1.0
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	[Style(name="backgroundAlpha", type="Number", inherit="no", theme="spark")]
+	
+	/**
+	 *  Background color of a component.
+	 *  
+	 *  @default 0xFFFFFF
+	 * 
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	[Style(name="backgroundColor", type="uint", format="Color", inherit="no", theme="spark")]
+	
+	/**
+	 *  The alpha of the content background for this component.
+	 * 
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	[Style(name="contentBackgroundAlpha", type="Number", inherit="yes", theme="spark")]
+	
+	/**
+	 *  @copy spark.components.supportClasses.GroupBase#style:contentBackgroundColor
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */ 
+	[Style(name="contentBackgroundColor", type="uint", format="Color", inherit="yes", theme="spark")]
+	
+	/**
+	 *  @copy spark.components.supportClasses.GroupBase#style:focusColor
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */ 
+	[Style(name="focusColor", type="uint", format="Color", inherit="yes", theme="spark")]
+	
+	/**
+	 * @copy spark.components.supportClasses.GroupBase#style:rollOverColor
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */ 
+	[Style(name="rollOverColor", type="uint", format="Color", inherit="yes", theme="spark")]
+	
+	/**
+	 *  @copy spark.components.supportClasses.GroupBase#style:symbolColor
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */ 
+	[Style(name="symbolColor", type="uint", format="Color", inherit="yes", theme="spark")]
+	
+	
+//	[IconFile("SkinnableContainer.png")]
+	
+	//--------------------------------------
+	//  Excluded APIs
+	//--------------------------------------
+	
+	[DefaultProperty("mxmlContentFactory")]
+	
+	/**
+	 *  The SkinnableContainer class is the base class for skinnable containers that have 
+	 *  visual content.
+	 *  The SkinnableContainer container takes as children any components that implement 
+	 *  the IVisualElement interface. 
+	 *  All Spark and Halo components implement the IVisualElement interface, as does
+	 *  the GraphicElement class. 
+	 *  That means the container can use the graphics classes, such as Rect and Ellipse, as children.
+	 *
+	 *  <p>To improve performance and minimize application size, 
+	 *  you can use the Group container. The Group container cannot be skinned.</p>
+	 *
+	 *  <p>The SkinnableContainer container has the following default characteristics:</p>
+	 *  <table class="innertable">
+	 *     <tr><th>Characteristic</th><th>Description</th></tr>
+	 *     <tr><td>Default size</td><td>Large enough to display its children</td></tr>
+	 *     <tr><td>Minimum size</td><td>0 pixels</td></tr>
+	 *     <tr><td>Maximum size</td><td>10000 pixels wide and 10000 pixels high</td></tr>
+	 *  </table>
+	 * 
+	 *  @mxml
+	 *
+	 *  <p>The <code>&lt;s:SkinnableContainer&gt;</code> tag inherits all of the tag 
+	 *  attributes of its superclass and adds the following tag attributes:</p>
+	 *
+	 *  <pre>
+	 *  &lt;s:SkinnableContainer
+	 *    <strong>Properties</strong>
+	 *    autoLayout="true"
+	 *    creationPolicy="auto"
+	 *    horizontalScrollPosition="null"
+	 *    layout="BasicLayout"
+	 *  
+	 *    <strong>Styles</strong>
+	 *    accentColor="0x0099FF"
+	 *    alignmentBaseline="useDominantBaseline"
+	 *    alternatingItemColors=""
+	 *    backgroundAlpha="1.0"
+	 *    backgroundColor="0xFFFFFF"
+	 *    baselineShift="0.0"
+	 *    blockProgression="TB"
+	 *    breakOpportunity="auto"
+	 *    cffHinting="horizontal_stem"
+	 *    color="0"
+	 *    contentBackgroundAlpha=""
+	 *    contentBackgroundColor=""
+	 *    digitCase="default"
+	 *    digitWidth="default"
+	 *    direction="LTR"
+	 *    dominantBaseline="auto"
+	 *    firstBaselineOffset="auto"
+	 *    focusColor=""
+	 *    focusedTextSelectionColor=""
+	 *    fontFamily="Times New Roman"
+	 *    fontLookup="device"
+	 *    fontSize="12"
+	 *    fontStyle="normal"
+	 *    fontWeight="normal"
+	 *    inactiveTextSelectionColor="0xE8E8E8"
+	 *    justificationRule="auto"
+	 *    justificationStyle="auto"
+	 *    kerning="auto"
+	 *    leadingModel="auto"
+	 *    ligatureLevel="common"
+	 *    lineHeight="120%"
+	 *    lineThrough="false"
+	 *    locale="en"
+	 *    paragraphEndIndent="0"
+	 *    paragraphSpaceAfter="0"
+	 *    paragraphSpaceBefore="0"
+	 *    paragraphStartIndent="0"
+	 *    renderingMode="CFF"
+	 *    rollOverColor=""
+	 *    symbolColor=""
+	 *    tabStops="null"
+	 *    textAlign="start"
+	 *    textAlignLast="start"
+	 *    textAlpha="1"
+	 *    textDecoration="none"
+	 *    textIndent="0"
+	 *    textJustify="inter_word"
+	 *    textRotation="auto"
+	 *    trackingLeft="0"
+	 *    trackingRight="0"
+	 *    typographicCase="default"
+	 *    unfocusedTextSelectionColor=""
+	 *    verticalScrollPolicy="auto"
+	 *    whiteSpaceCollapse="collapse"
+	 *  
+	 *    <strong>Events</strong>
+	 *    elementAdd="<i>No default</i>"
+	 *    elementRemove="<i>No default</i>"
+	 *  /&gt;
+	 *  </pre>
+	 *
+	 *  @see SkinnableDataContainer
+	 *  @see Group
+	 *  @see spark.skins.spark.SkinnableContainerSkin
+	 *
+	 *  @includeExample examples/SkinnableContainerExample.mxml
+	 *  @includeExample examples/MyBorderSkin.mxml -noswf
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	public class Navigator extends SkinnableContainerBase 
+		implements IDeferredContentOwner, IVisualElementContainer, INavigator
+	{
+
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Class constants
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private
+		 */
+		private static const AUTO_LAYOUT_PROPERTY_FLAG:uint = 1 << 0;
+		
+		/**
+		 *  @private
+		 */
+		private static const LAYOUT_PROPERTY_FLAG:uint = 1 << 1;
+		
+		/**
+		 *  @private
+		 */
+		private static const SELECTED_INDEX_PROPERTY_FLAG:uint = 1 << 2;
+		
+		/**
+		 *  @private
+		 */
+		private static const CREATION_POLICY_PROPERTY_FLAG:uint = 1 << 3;
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Constructor. 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function Navigator()
+		{
+			super();
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Skin Parts
+		//
+		//--------------------------------------------------------------------------
+		
+		[SkinPart(required="false")]
+		
+		/**
+		 *  An optional skin part that defines the Group where the content 
+		 *  children get pushed into and laid out.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public var contentGroup:NavigatorGroup;
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Variables 
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private
+		 *  Several properties are proxied to contentGroup.  However, when contentGroup
+		 *  is not around, we need to store values set on SkinnableContainer.  This object 
+		 *  stores those values.  If contentGroup is around, the values are stored 
+		 *  on the contentGroup directly.  However, we need to know what values 
+		 *  have been set by the developer on the SkinnableContainer (versus set on 
+		 *  the contentGroup or defaults of the contentGroup) as those are values 
+		 *  we want to carry around if the contentGroup changes (via a new skin). 
+		 *  In order to store this info effeciently, contentGroupProperties becomes 
+		 *  a uint to store a series of BitFlags.  These bits represent whether a 
+		 *  property has been explicitely set on this SkinnableContainer.  When the 
+		 *  contentGroup is not around, contentGroupProperties is a typeless 
+		 *  object to store these proxied properties.  When contentGroup is around,
+		 *  contentGroupProperties stores booleans as to whether these properties 
+		 *  have been explicitely set or not.
+		 */
+		private var contentGroupProperties:Object = {};
+		
+		/**
+		 *  @private
+		 */
+		private var _hasCollectionChangeListener:Boolean;
+		
+		
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Properties 
+		//
+		//--------------------------------------------------------------------------
+		
+		
+		//----------------------------------
+		//  selectedIndex
+		//---------------------------------- 
+		
+		[Bindable("change")]
+		[Bindable("valueCommit")]
+		
+		/**
+		 *  @copy ws.tink.spark.controls.DataNavigatorGroup#selectedIndex
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get selectedIndex():int
+		{
+			return contentGroup ? contentGroup.selectedIndex : contentGroupProperties.selectedIndex;
+		}
+		/**
+		 *  @private
+		 */
+		public function set selectedIndex( value:int ):void
+		{
+			if( value == selectedIndex ) return;
+			
+			if (contentGroup)
+			{
+				contentGroup.selectedIndex = value;
+				contentGroupProperties = BitFlagUtil.update(contentGroupProperties as uint, 
+					SELECTED_INDEX_PROPERTY_FLAG, true);
+			}
+			else
+				contentGroupProperties.selectedIndex = value;
+		}
+		
+		
+		//----------------------------------
+		//  selectedItem
+		//---------------------------------- 
+		
+		[Bindable("change")]
+		[Bindable("valueCommit")]
+		
+		/**
+		 *  @copy ws.tink.spark.containers.NavigatorGroup#selectedItem
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get selectedItem():IVisualElement
+		{
+			var index:int = selectedIndex;
+			return index != -1 ? getElementAt( index ) : null;
+		}
+		/**
+		 *  @private
+		 */
+		public function set selectedItem( value:IVisualElement ):void
+		{
+			var index:int = getElementIndex( value );
+			if( index != -1 ) selectedIndex = index;
+		}
+		
+		
+		//----------------------------------
+		//  length
+		//---------------------------------- 
+		
+		/**
+		 *  @copy ws.tink.spark.containers.NavigatorGroup#length
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get length():int
+		{
+			return currentContentGroup.length;
+		}
+		
+		
+		//----------------------------------
+		//  currentContentGroup
+		//----------------------------------
+		
+		// Used to hold the content until the contentGroup is created. 
+		private var _placeHolderGroup:NavigatorGroup;
+		
+		mx_internal function get currentContentGroup():NavigatorGroup
+		{          
+			createContentIfNeeded();
+			
+			if (!contentGroup)
+			{
+				if (!_placeHolderGroup)
+				{
+					_placeHolderGroup = new NavigatorGroup();
+					
+					if (_mxmlContent)
+					{
+						_placeHolderGroup.mxmlContent = _mxmlContent;
+						_mxmlContent = null;
+					}
+					
+					_placeHolderGroup.addEventListener( ElementExistenceEvent.ELEMENT_ADD, onContentGroupElementAdded );
+					_placeHolderGroup.addEventListener( ElementExistenceEvent.ELEMENT_REMOVE, onContentGroupElementRemoved );
+				}
+
+				return _placeHolderGroup;
+			}
+			else
+			{
+				return contentGroup;    
+			}
+		}
+		
+		
+		//----------------------------------
+		//  creationPolicy
+		//----------------------------------
+		
+//		[Inspectable(enumeration="auto,all,none", defaultValue="auto")]
+		[Inspectable(enumeration="visible,construct,all,none", defaultValue="visible")]
+		/**
+		 *  @copy ws.tink.spark.containers.DeferredGroup#creationPolicy
+		 *
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get creationPolicy():String
+		{
+			return contentGroup ? contentGroup.creationPolicy : contentGroupProperties.creationPolicy;
+		}
+		/**
+		 *  @private
+		 */
+		public function set creationPolicy( value:String ):void
+		{
+			if( value == creationPolicy ) return;
+			
+			if (contentGroup)
+			{
+				contentGroup.creationPolicy = value;
+				contentGroupProperties = BitFlagUtil.update(contentGroupProperties as uint, 
+					CREATION_POLICY_PROPERTY_FLAG, true);
+			}
+			else
+				contentGroupProperties.creationPolicy = value;
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden Properties 
+		//
+		//--------------------------------------------------------------------------
+		
+		//----------------------------------
+		//  moduleFactory
+		//----------------------------------
+		/**
+		 *  @private
+		 */
+		override public function set moduleFactory(moduleFactory:IFlexModuleFactory):void
+		{
+			super.moduleFactory = moduleFactory;
+			
+			// Register the _creationPolicy style as inheriting. See the creationPolicy
+			// getter for details on usage of this style.
+			styleManager.registerInheritingStyle("_creationPolicy");
+		}
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Properties proxied to contentGroup
+		//
+		//--------------------------------------------------------------------------
+		
+		//----------------------------------
+		//  autoLayout
+		//----------------------------------
+		
+		[Inspectable(defaultValue="true")]
+		
+		/**
+		 *  @copy spark.components.supportClasses.GroupBase#autoLayout
+		 *
+		 *  @default true
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get autoLayout():Boolean
+		{
+			if (contentGroup)
+				return contentGroup.autoLayout;
+			else
+			{
+				// want the default to be true
+				var v:* = contentGroupProperties.autoLayout;
+				return (v === undefined) ? true : v;
+			}
+		}
+		
+		/**
+		 *  @private
+		 */
+		public function set autoLayout(value:Boolean):void
+		{
+			if (contentGroup)
+			{
+				contentGroup.autoLayout = value;
+				contentGroupProperties = BitFlagUtil.update(contentGroupProperties as uint, 
+					AUTO_LAYOUT_PROPERTY_FLAG, true);
+			}
+			else
+				contentGroupProperties.autoLayout = value;
+		}
+		
+		
+		//----------------------------------
+		//  layout
+		//----------------------------------
+		
+		/**
+		 *  @copy spark.components.supportClasses.GroupBase#layout
+		 *
+		 *  @default BasicLayout
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get layout():INavigatorLayout
+		{
+			return ( contentGroup ) ? INavigatorLayout( contentGroup.layout ) 
+				: INavigatorLayout( contentGroupProperties.layout );
+		}
+		/**
+		 *  @private
+		 */
+		public function set layout( value:INavigatorLayout ):void
+		{
+			if ( contentGroup )
+			{
+				contentGroup.layout = value as LayoutBase;
+				contentGroupProperties = BitFlagUtil.update(contentGroupProperties as uint, 
+					LAYOUT_PROPERTY_FLAG, true);
+			}
+			else
+			{
+				contentGroupProperties.layout = value;
+			}
+		}
+		
+		
+		//----------------------------------
+		//  mxmlContent
+		//----------------------------------    
+		
+		/**
+		 *  @private
+		 *  Variable used to store the mxmlContent when the contentGroup is 
+		 *  not around, and there hasnt' been a need yet for the placeHolderGroup.
+		 */
+		private var _mxmlContent:Array;
+		
+		/**
+		 *  @private
+		 *  Variable that represents whether the content has been explicitely set 
+		 *  (via mxmlContent setter or with the mutation APIs, like addElement).  
+		 *  This is used to figure out whether we should override the default "content"
+		 *  that is in the contentGroup of a skin.
+		 */
+		private var _contentModified:Boolean = false;
+		
+		[ArrayElementType("mx.core.IVisualElement")]
+		
+		/**
+		 *  @copy spark.components.Group#mxmlContent
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function set mxmlContent(value:Array):void
+		{
+			if (contentGroup)
+				contentGroup.mxmlContent = value;
+			else if (_placeHolderGroup)
+				_placeHolderGroup.mxmlContent = value;
+			else
+				_mxmlContent = value;
+			
+//			trace( "111", _contentModified );
+//			var c:NavigatorGroup = currentContentGroup;
+//			trace( "huh", c );
+//			c.mxmlContent = value;
+//			trace( "222", _contentModified )
+			if (value != null)
+				_contentModified = true;
+//			_mxmlContent = value;
+		}
+		
+		//----------------------------------
+		//  mxmlContentFactory
+		//----------------------------------
+		
+		/** 
+		 *  @private
+		 *  Backing variable for the contentFactory property.
+		 */
+		private var _mxmlContentFactory:IDeferredInstance;
+		
+		/**
+		 *  @private
+		 *  Flag that indicates whether or not the content has been created.
+		 */
+		private var mxmlContentCreated:Boolean = false;
+		
+		[InstanceType("Array")]
+		[ArrayElementType("mx.core.IVisualElement")]
+		
+		/**
+		 *  A factory object that creates the initial value for the
+		 *  <code>content</code> property.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function set mxmlContentFactory(value:IDeferredInstance):void
+		{
+			if (value == _mxmlContentFactory)
+				return;
+			
+			_mxmlContentFactory = value;
+			mxmlContentCreated = false;
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Methods proxied to contentGroup
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @copy ws.tink.spark.containers.NavigatorGroup#addItem
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function addItem( item:Object ):void
+		{
+			addItemAt( item, length );
+		}
+		
+		/**
+		 *  @copy ws.tink.spark.containers.NavigatorGroup#addItemAt
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function addItemAt( item:Object, index:int ):void
+		{
+			currentContentGroup.addItemAt( item, index );
+		}
+		
+		/**
+		 *  @copy ws.tink.spark.containers.NavigatorGroup#getItemAt
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function getItemAt( index:int, prefetch:int = 0 ):Object
+		{
+			return currentContentGroup.getItemAt( index );
+		}
+		
+		/**
+		 *  @copy ws.tink.spark.containers.NavigatorGroup#getItemIndex
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function getItemIndex( item:Object ):int
+		{
+			return currentContentGroup.getItemIndex( item );
+		}
+		
+		/**
+		 *  @copy ws.tink.spark.containers.NavigatorGroup#itemUpdated
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function itemUpdated( item:Object, property:Object=null, oldValue:Object=null, newValue:Object=null ):void
+		{
+			currentContentGroup.itemUpdated( item, property, oldValue, newValue );
+		}
+		
+		/**
+		 *  @copy ws.tink.spark.containers.NavigatorGroup#removeAll
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function removeAll():void
+		{
+			currentContentGroup.removeAll();
+		}
+		
+		/**
+		 *  @copy ws.tink.spark.containers.NavigatorGroup#removeItemAt
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function removeItemAt( index:int ):Object
+		{
+			return currentContentGroup.removeItemAt( index );
+		}
+		
+		/**
+		 *  @copy ws.tink.spark.containers.NavigatorGroup#setItemAt
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function setItemAt( item:Object, index:int ):Object
+		{
+			return currentContentGroup.setItemAt( item, index );
+		}
+		
+		/**
+		 *  @copy ws.tink.spark.containers.NavigatorGroup#toArray
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function toArray():Array
+		{
+			return currentContentGroup.toArray();
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get numElements():int
+		{
+			return currentContentGroup.numElements;
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function getElementAt(index:int):IVisualElement
+		{
+			return currentContentGroup.getElementAt(index);
+		}
+		
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function getElementIndex(element:IVisualElement):int
+		{
+			return currentContentGroup.getElementIndex(element);
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function addElement(element:IVisualElement):IVisualElement
+		{
+			_contentModified = true;
+			return currentContentGroup.addElement(element);
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function addElementAt(element:IVisualElement, index:int):IVisualElement
+		{
+			_contentModified = true;
+			return currentContentGroup.addElementAt(element, index);
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function removeElement(element:IVisualElement):IVisualElement
+		{
+			_contentModified = true;
+			return currentContentGroup.removeElement(element);
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function removeElementAt(index:int):IVisualElement
+		{
+			_contentModified = true;
+			return currentContentGroup.removeElementAt(index);
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function removeAllElements():void
+		{
+			_contentModified = true;
+			currentContentGroup.removeAllElements();
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function setElementIndex (element:IVisualElement, index:int ):void
+		{
+			_contentModified = true;
+			currentContentGroup.setElementIndex(element, index);
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function swapElements(element1:IVisualElement, element2:IVisualElement):void
+		{
+			_contentModified = true;
+			
+			// TODO tink swapElements
+			swapElementsAt( getElementIndex( element1 ), getElementIndex( element1 ) )
+			
+			//currentContentGroup.swapElements(element1, element2);
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function swapElementsAt(index1:int, index2:int):void
+		{
+			_contentModified = true;
+			currentContentGroup.swapElementsAt(index1, index2);
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  IDeferredContentOwner methods
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Create the content for this component. 
+		 *  When the <code>creationPolicy</code> property is <code>auto</code> or
+		 *  <code>all</code>, this function is called automatically by the Flex framework.
+		 *  When <code>creationPolicy</code> is <code>none</code>, you call this method to initialize
+		 *  the content.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function createDeferredContent():void
+		{
+			if (!mxmlContentCreated)
+			{
+				mxmlContentCreated = true;
+				
+				if (_mxmlContentFactory)
+				{
+					var deferredContent:Object = _mxmlContentFactory.getInstance();
+					mxmlContent = deferredContent as Array;
+					_deferredContentCreated = true;
+					dispatchEvent(new FlexEvent(FlexEvent.CONTENT_CREATION_COMPLETE));
+				}
+			}
+		}
+		
+		private var _deferredContentCreated:Boolean;
+		
+		/**
+		 *  Contains <code>true</code> if deferred content has been created.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get deferredContentCreated():Boolean
+		{
+			return _deferredContentCreated;
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function createContentIfNeeded():void
+		{
+			if (!mxmlContentCreated && creationPolicy != ContainerCreationPolicy.NONE)
+				createDeferredContent();
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden Methods
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override public function addEventListener( type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false ):void
+		{
+			super.addEventListener( type, listener, useCapture, priority, useWeakReference );
+			
+			if( type == CollectionEvent.COLLECTION_CHANGE &&
+				hasEventListener( CollectionEvent.COLLECTION_CHANGE ) &&
+				currentContentGroup.hasEventListener( CollectionEvent.COLLECTION_CHANGE ) )
+			{
+				currentContentGroup.addEventListener( CollectionEvent.COLLECTION_CHANGE, onBubbleContentGroupEvent, false, 0, true );
+			}
+			
+			if( type == IndexChangeEvent.CHANGE &&
+				hasEventListener( IndexChangeEvent.CHANGE ) &&
+				currentContentGroup.hasEventListener( IndexChangeEvent.CHANGE ) )
+			{
+				currentContentGroup.addEventListener( IndexChangeEvent.CHANGE, onBubbleContentGroupEvent, false, 0, true );
+			}
+			
+			if( type == FlexEvent.VALUE_COMMIT &&
+				hasEventListener( FlexEvent.VALUE_COMMIT ) &&
+				currentContentGroup.hasEventListener( FlexEvent.VALUE_COMMIT ) )
+			{
+				currentContentGroup.addEventListener( FlexEvent.VALUE_COMMIT, onBubbleContentGroupEvent, false, 0, true );
+			}
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override public function removeEventListener( type:String, listener:Function, useCapture:Boolean = false ):void
+		{
+			super.removeEventListener( type, listener, useCapture );
+			
+			if( type == CollectionEvent.COLLECTION_CHANGE &&
+				!hasEventListener( CollectionEvent.COLLECTION_CHANGE ) &&
+				currentContentGroup.hasEventListener( CollectionEvent.COLLECTION_CHANGE ) )
+			{
+				currentContentGroup.removeEventListener( CollectionEvent.COLLECTION_CHANGE, onBubbleContentGroupEvent, false );
+			}
+			
+			if( type == IndexChangeEvent.CHANGE &&
+				!hasEventListener( IndexChangeEvent.CHANGE ) &&
+				currentContentGroup.hasEventListener( IndexChangeEvent.CHANGE ) )
+			{
+				currentContentGroup.removeEventListener( IndexChangeEvent.CHANGE, onBubbleContentGroupEvent, false );
+			}
+			
+			if( type == FlexEvent.VALUE_COMMIT &&
+				!hasEventListener( FlexEvent.VALUE_COMMIT ) &&
+				currentContentGroup.hasEventListener( FlexEvent.VALUE_COMMIT ) )
+			{
+				currentContentGroup.removeEventListener( FlexEvent.VALUE_COMMIT, onBubbleContentGroupEvent, false );
+			}
+		}
+		
+		/**
+		 *  Create content children, if the <code>creationPolicy</code> property 
+		 *  is not equal to <code>none</code>.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override protected function createChildren():void
+		{
+			super.createChildren();
+			
+			// TODO (rfrishbe): When contentGroup support is added, this is where we would 
+			// determine if content should be created now, or wait until
+			// later. For now, we always create content here unless
+			// creationPolicy="none".
+			createContentIfNeeded();
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override protected function partAdded(partName:String, instance:Object):void
+		{
+			super.partAdded(partName, instance);
+			
+			if (instance == contentGroup)
+			{
+				if (_contentModified)
+				{
+					if (_placeHolderGroup != null)
+					{
+						var sourceContent:Array = _placeHolderGroup.getMXMLContent();
+						
+						// TODO (rfrishbe): Also look at why we need a defensive copy for mxmlContent in Group, 
+						// especially if we make it mx_internal.  Also look at controlBarContent.
+						
+						// If a child element has been addElemented() to the placeHolderGroup, 
+						// then it wouldn't been added to the display list and we can't just 
+						// copy the mxmlContent from the placeHolderGroup, but we must also 
+						// call removeElement() on those children.
+						for (var i:int = _placeHolderGroup.numElements; i > 0; i--)
+						{
+							_placeHolderGroup.removeElementAt(0);  
+						}
+						
+						contentGroup.mxmlContent = sourceContent ? sourceContent.slice() : null;
+					}
+					else if (_mxmlContent != null)
+					{
+						contentGroup.mxmlContent = _mxmlContent;
+						_mxmlContent = null;
+					}
+				}
+				
+				// Not your typical delegation, see 'set useVirtualLayout'
+//				if( _useVirtualLayout && contentGroup.layout )
+//					contentGroup.layout.useVirtualLayout = true;
+				
+				// copy proxied values from contentGroupProperties (if set) to contentGroup
+				
+				var newContentGroupProperties:uint = 0;
+				
+				if (contentGroupProperties.autoLayout !== undefined)
+				{
+					contentGroup.autoLayout = contentGroupProperties.autoLayout;
+					newContentGroupProperties = BitFlagUtil.update(newContentGroupProperties, 
+						AUTO_LAYOUT_PROPERTY_FLAG, true);
+				}
+				
+				if (contentGroupProperties.layout !== undefined)
+				{
+					contentGroup.layout = contentGroupProperties.layout;
+					newContentGroupProperties = BitFlagUtil.update(newContentGroupProperties, 
+						LAYOUT_PROPERTY_FLAG, true);
+				}
+				
+				if (contentGroupProperties.selectedIndex > 0)
+				{
+					contentGroup.selectedIndex = contentGroupProperties.selectedIndex;
+					newContentGroupProperties = BitFlagUtil.update(newContentGroupProperties as uint, 
+						SELECTED_INDEX_PROPERTY_FLAG, true);
+				}
+				
+				if (contentGroupProperties.creationPolicy  !== undefined)
+				{
+					contentGroup.creationPolicy = contentGroupProperties.creationPolicy;
+					newContentGroupProperties = BitFlagUtil.update(newContentGroupProperties as uint, 
+						CREATION_POLICY_PROPERTY_FLAG, true);
+				}
+				
+				contentGroupProperties = newContentGroupProperties;
+				
+				contentGroup.addEventListener( ElementExistenceEvent.ELEMENT_ADD, onContentGroupElementAdded );
+				contentGroup.addEventListener( ElementExistenceEvent.ELEMENT_REMOVE, onContentGroupElementRemoved );
+				
+				const bubbleEvents:Vector.<String> = new Vector.<String>();
+				if( hasEventListener( CollectionEvent.COLLECTION_CHANGE ) )
+				{
+					bubbleEvents.push( CollectionEvent.COLLECTION_CHANGE );
+					contentGroup.addEventListener( CollectionEvent.COLLECTION_CHANGE, onBubbleContentGroupEvent, false, 0, true );
+				}
+				
+				if( hasEventListener( IndexChangeEvent.CHANGE ) )
+				{
+					bubbleEvents.push(  IndexChangeEvent.CHANGE );
+					contentGroup.addEventListener( IndexChangeEvent.CHANGE, onBubbleContentGroupEvent, false, 0, true );
+				}
+				
+				if( hasEventListener( FlexEvent.VALUE_COMMIT ) )
+				{
+					bubbleEvents.push(  FlexEvent.VALUE_COMMIT );
+					contentGroup.addEventListener( FlexEvent.VALUE_COMMIT, onBubbleContentGroupEvent, false, 0, true );
+				}
+				
+				if( _placeHolderGroup )
+				{
+					_placeHolderGroup.removeEventListener( ElementExistenceEvent.ELEMENT_ADD, onContentGroupElementAdded );
+					_placeHolderGroup.removeEventListener( ElementExistenceEvent.ELEMENT_REMOVE, onContentGroupElementRemoved );
+					for each( var event:String in bubbleEvents )
+					{
+						_placeHolderGroup.removeEventListener( event, onBubbleContentGroupEvent, false );
+					}
+					_placeHolderGroup = null;
+				}
+			}
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override protected function partRemoved(partName:String, instance:Object):void
+		{
+			super.partRemoved(partName, instance);
+			
+			if (instance == contentGroup)
+			{
+				contentGroup.removeEventListener( ElementExistenceEvent.ELEMENT_ADD, onContentGroupElementAdded );
+				contentGroup.removeEventListener( ElementExistenceEvent.ELEMENT_REMOVE, onContentGroupElementRemoved );
+				
+				const bubbleEvents:Vector.<String> = new Vector.<String>();
+				if( hasEventListener( CollectionEvent.COLLECTION_CHANGE ) )
+				{
+					bubbleEvents.push( CollectionEvent.COLLECTION_CHANGE );
+					contentGroup.removeEventListener( CollectionEvent.COLLECTION_CHANGE, onBubbleContentGroupEvent, false );
+				}
+				
+				if( hasEventListener( IndexChangeEvent.CHANGE ) )
+				{
+					bubbleEvents.push(  IndexChangeEvent.CHANGE );
+					contentGroup.removeEventListener( IndexChangeEvent.CHANGE, onBubbleContentGroupEvent, false );
+				}
+				
+				if( hasEventListener( FlexEvent.VALUE_COMMIT ) )
+				{
+					bubbleEvents.push(  FlexEvent.VALUE_COMMIT );
+					contentGroup.removeEventListener( FlexEvent.VALUE_COMMIT, onBubbleContentGroupEvent, false );
+				}
+				
+				// copy proxied values from contentGroup (if explicitely set) to contentGroupProperties
+				
+				var newContentGroupProperties:Object = {};
+				
+				if (BitFlagUtil.isSet(contentGroupProperties as uint, AUTO_LAYOUT_PROPERTY_FLAG))
+					newContentGroupProperties.autoLayout = contentGroup.autoLayout;
+				
+				if (BitFlagUtil.isSet(contentGroupProperties as uint, LAYOUT_PROPERTY_FLAG))
+					newContentGroupProperties.layout = contentGroup.layout;
+				
+				if (BitFlagUtil.isSet(contentGroupProperties as uint, SELECTED_INDEX_PROPERTY_FLAG))
+					newContentGroupProperties.selectedIndex = contentGroup.selectedIndex;
+				
+				if (BitFlagUtil.isSet(contentGroupProperties as uint, CREATION_POLICY_PROPERTY_FLAG))
+					newContentGroupProperties.creationPolicy = contentGroup.creationPolicy;
+				
+				contentGroupProperties = newContentGroupProperties;
+				
+				var myMxmlContent:Array = contentGroup.getMXMLContent();
+				
+				if (_contentModified && myMxmlContent)
+				{
+					_placeHolderGroup = new NavigatorGroup();
+					
+					_placeHolderGroup.mxmlContent = myMxmlContent;
+					
+					_placeHolderGroup.addEventListener( ElementExistenceEvent.ELEMENT_ADD, onContentGroupElementAdded );
+					_placeHolderGroup.addEventListener( ElementExistenceEvent.ELEMENT_REMOVE, onContentGroupElementRemoved );
+					for each( var event:String in bubbleEvents )
+					{
+						_placeHolderGroup.addEventListener( event, onBubbleContentGroupEvent, false, 0, true );
+					}
+				}
+				
+				contentGroup.mxmlContent = null;
+				contentGroup.layout = null;
+			}
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Event Listeners
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private
+		 */
+		private function onContentGroupElementAdded( event:ElementExistenceEvent ):void
+		{
+			event.element.owner = this
+			dispatchEvent( event );
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function onContentGroupElementRemoved( event:ElementExistenceEvent ):void
+		{
+			event.element.owner = null;
+			dispatchEvent( event );
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function onBubbleContentGroupEvent( event:Event ):void
+		{
+			dispatchEvent( event );
+		}
+		
+	}
+	
+}

Added: incubator/flex/whiteboard/navigators/src/ws/tink/spark/containers/NavigatorGroup.as
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/navigators/src/ws/tink/spark/containers/NavigatorGroup.as?rev=1228400&view=auto
==============================================================================
--- incubator/flex/whiteboard/navigators/src/ws/tink/spark/containers/NavigatorGroup.as (added)
+++ incubator/flex/whiteboard/navigators/src/ws/tink/spark/containers/NavigatorGroup.as Fri Jan  6 20:58:43 2012
@@ -0,0 +1,775 @@
+/*
+
+Copyright (c) 2010 Tink Ltd - http://www.tink.ws
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
+THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+*/
+
+package ws.tink.spark.containers
+{
+	import flash.events.Event;
+	
+	import mx.core.ISelectableList;
+	import mx.core.IVisualElement;
+	import mx.events.CollectionEvent;
+	import mx.events.CollectionEventKind;
+	import mx.events.FlexEvent;
+	import mx.events.PropertyChangeEvent;
+	import mx.events.PropertyChangeEventKind;
+	
+	import spark.events.IndexChangeEvent;
+	import spark.layouts.supportClasses.LayoutBase;
+	
+	import ws.tink.spark.containers.supportClasses.DeferredCreationPolicy;
+	import ws.tink.spark.layouts.StackLayout;
+	import ws.tink.spark.layouts.supportClasses.AnimationNavigatorLayoutBase;
+	import ws.tink.spark.layouts.supportClasses.INavigatorLayout;
+	
+
+	//--------------------------------------
+	//  Events
+	//--------------------------------------
+	
+	/**
+	 *  Dispatched when the ISelectableList has been updated in some way.
+	 *
+	 *  @eventType mx.events.CollectionEvent.COLLECTION_CHANGE
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 9
+	 *  @playerversion AIR 1.1
+	 *  @productversion Flex 3
+	 */
+	[Event(name="collectionChange", type="mx.events.CollectionEvent")]
+	
+	/**
+	 *  Dispatched after the selection has changed. 
+	 *  This event is dispatched when the user interacts with the control.
+	 * 
+	 *  <p>When you change the value of the <code>selectedIndex</code> 
+	 *  or <code>selectedItem</code> properties programmatically, 
+	 *  the control does not dispatch the <code>change</code> event. 
+	 *  It dispatches the <code>valueCommit</code> event instead.</p>
+	 *
+	 *  @eventType spark.events.IndexChangeEvent.CHANGE
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	[Event(name="change", type="spark.events.IndexChangeEvent")]
+	
+	/**
+	 *  The NavigatorGroup class is the base container for navigating all visual elements.
+	 * 
+	 *  The NavigatorGroup container takes as children any components that implement 
+ 	 *  the IUIComponent interface, and any components that implement 
+	 *  the IGraphicElement interface. 
+ 	 *  Use this container when you want to navigate between visual children, 
+ 	 *  both visual elements and graphical elements.
+	 *  
+	 *  <p>The layout for a NavigatorGroup must implement INavigatorLayout.</p>
+	 *
+	 *  <p>To improve performance and minimize application size, 
+	 *  the NavigatorGroup container cannot be skinned. 
+	 *  If you want to apply a skin, use the Navigator instead.</p>
+	 * 
+	 *  <p>The NavigatorGroup container has the following default characteristics:</p>
+ 	 *  <table class="innertable">
+	 *     <tr><th>Characteristic</th><th>Description</th></tr>
+	 *     <tr><td>Default size</td><td>Large enough to display its children</td></tr>
+	 *     <tr><td>Minimum size</td><td>0 pixels</td></tr>
+	 *     <tr><td>Maximum size</td><td>10000 pixels wide and 10000 pixels high</td></tr>
+	 *  </table>
+	 *
+	 *  @mxml <p>The <code>&lt;st:NavigatorGroup&gt;</code> tag inherits all of the tag 
+	 *  attributes of its superclass and adds the following tag attributes:</p>
+	 *
+	 *  <pre>
+	 *  &lt;st:NavigatorGroup
+	 *
+	 *    <strong>Properties</strong>
+	 *    selectedIndex="-1"
+	 *    selectedItem="undefined"
+	 *    length="0"
+	 * 
+	 *    <strong>Events</strong>
+	 *    change="<i>No default</i>"
+	 *    collectionChange="<i>No default</i>"
+	 *  /&gt;
+	 *  </pre>
+	 *  
+	 *  @see ws.tink.spark.containers.Navigator
+	 *  @see ws.tink.spark.layouts.supportClasses.INavigatorLayout
+	 *
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	public class NavigatorGroup extends DeferredGroup implements ISelectableList
+	{
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Constructor. 
+		 *  Initializes the <code>creationPolicy</code> property to "construct". 
+		 * 
+		 *  @see #creationPolicy
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */  
+		public function NavigatorGroup()
+		{
+			super();
+			
+			creationPolicy = DeferredCreationPolicy.CONSTRUCT;
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		//
+		//--------------------------------------------------------------------------
+		
+		//----------------------------------
+		//  selectedIndex
+		//---------------------------------- 
+		
+		/**
+		 *  @private
+		 *  Storage property for selectedIndex.
+		 */
+		private var _selectedIndex		: int = -1;
+		
+		[Bindable("change")]
+		[Bindable("valueCommit")]
+		
+		/**
+		 *  The index of the currently selected item IList item.
+		 *  Setting this property deselects the currently selected 
+		 *  index and selects the newly specified item.
+		 *  
+		 *  @default -1
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function set selectedIndex( value:int ):void
+		{
+			if( _selectedIndex == value ) return;
+			
+			_selectedIndex = value;
+			
+			if( layout ) INavigatorLayout( layout ).selectedIndex = _selectedIndex;
+		}
+		/**
+		 *  @private
+		 */
+		public function get selectedIndex():int
+		{
+			return ( layout ) ? INavigatorLayout( layout ).selectedIndex : _selectedIndex;
+		}
+		
+		
+		//----------------------------------
+		//  selectedItem
+		//---------------------------------- 
+		
+		[Bindable("change")]
+		[Bindable("valueCommit")]
+		
+		/**
+		 *  The item that is currently selected. 
+		 *  Setting this property deselects the currently selected 
+		 *  item and selects the newly specified item.
+		 *
+		 *  @default undefined
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get selectedItem():IVisualElement
+		{
+			var index:int = selectedIndex;
+			return index != -1 ? getElementAt( index ) : null;
+		}
+		/**
+		 *  @private
+		 */
+		public function set selectedItem( value:IVisualElement ):void
+		{
+			var index:int = getElementIndex( value );
+			if( index != -1 ) selectedIndex = index;
+		}
+		
+		
+		//----------------------------------
+		//  length
+		//---------------------------------- 
+		
+		/**
+		 *  The number of items in this collection. 
+		 *  0 means no items while -1 means the length is unknown. 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function get length():int
+		{
+			return numElements;
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden Properties
+		//
+		//--------------------------------------------------------------------------
+		
+		//----------------------------------
+		//  layout
+		//----------------------------------    
+		/**
+		 *  @private
+		 */
+		override public function set layout( value:LayoutBase ):void
+		{
+			if( layout == value ) return;
+			
+			if( value is INavigatorLayout )
+			{
+				removeLayoutListeners();
+				super.layout = value;
+				INavigatorLayout( value ).selectedIndex = _selectedIndex;
+				addLayoutListeners();
+			}
+			else
+			{
+				throw new Error( "Layout must implement INavigatorLayout" );
+			}
+			
+		}
+		
+		
+		//----------------------------------
+		//  mxmlContent
+		//----------------------------------  
+		
+		/**
+		 *  @private
+		 */
+		override public function set mxmlContent( value:Array ):void
+		{
+			super.mxmlContent = value;
+			
+			adjustSelection( length ? 0 : -1 );
+			
+			dispatchEvent( new CollectionEvent( CollectionEvent.COLLECTION_CHANGE, false, false, CollectionEventKind.RESET, -1, -1, toArray() ) );
+		}
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Methods
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Adds the specified item to the end of the list.
+		 *  Equivalent to <code>addItemAt(item, length)</code>.
+		 *
+		 *  @param item The item to add.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function addItem( item:Object ):void
+		{
+			addItemAt( item, length );
+		}
+		
+		/**
+		 *  Adds the item at the specified index.  
+		 *  The index of any item greater than the index of the added item is increased by one.  
+		 *  If the the specified index is less than zero or greater than the length
+		 *  of the list, a RangeError is thrown.
+		 * 
+		 *  @param item The item to place at the index.
+		 *
+		 *  @param index The index at which to place the item.
+		 *
+		 *  @throws RangeError if index is less than 0 or greater than the length of the list. 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function addItemAt( item:Object, index:int ):void
+		{
+			addElementAt( item as IVisualElement, index );
+		}
+		
+		/**
+		 *  Gets the item at the specified index.
+		 * 
+		 *  @param index The index in the list from which to retrieve the item.
+		 *
+		 *  @param prefetch An <code>int</code> indicating both the direction
+		 *  and number of items to fetch during the request if the item is
+		 *  not local.
+		 *
+		 *  @return The item at that index, or <code>null</code> if there is none.
+		 *
+		 *  @throws mx.collections.errors.ItemPendingError if the data for that index needs to be 
+		 *  loaded from a remote location.
+		 *
+		 *  @throws RangeError if <code>index &lt; 0</code>
+		 *  or <code>index >= length</code>.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function getItemAt( index:int, prefetch:int = 0 ):Object
+		{
+			return  _mxmlContent[ index ];
+		}
+		
+		/**
+		 *  Returns the index of the item if it is in the list such that
+		 *  getItemAt(index) == item.
+		 * 
+		 *  <p>Note: unlike <code>IViewCursor.find<i>xxx</i>()</code> methods,
+		 *  The <code>getItemIndex()</code> method cannot take a parameter with 
+		 *  only a subset of the fields in the item being serched for; 
+		 *  this method always searches for an item that exactly matches
+		 *  the input parameter.</p>
+		 * 
+		 *  @param item The item to find.
+		 *
+		 *  @return The index of the item, or -1 if the item is not in the list.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function getItemIndex( item:Object ):int
+		{
+			return getElementIndex( IVisualElement( item ) );
+		}
+		
+		/**
+		 *  Notifies the view that an item has been updated.  
+		 *  This is useful if the contents of the view do not implement 
+		 *  <code>IEventDispatcher</code> and dispatches a 
+		 *  <code>PropertyChangeEvent</code>.  
+		 *  If a property is specified the view may be able to optimize its 
+		 *  notification mechanism.
+		 *  Otherwise it may choose to simply refresh the whole view.
+		 *
+		 *  @param item The item within the view that was updated.
+		 *
+		 *  @param property The name of the property that was updated.
+		 *
+		 *  @param oldValue The old value of that property. (If property was null,
+		 *  this can be the old value of the item.)
+		 *
+		 *  @param newValue The new value of that property. (If property was null,
+		 *  there's no need to specify this as the item is assumed to be
+		 *  the new value.)
+		 *
+		 *  @see mx.events.CollectionEvent
+		 *  @see mx.events.PropertyChangeEvent
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function itemUpdated( item:Object, property:Object=null, oldValue:Object=null, newValue:Object=null ):void
+		{
+			var event:PropertyChangeEvent = new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
+			
+			event.kind = PropertyChangeEventKind.UPDATE;
+			event.source = item;
+			event.property = property;
+			event.oldValue = oldValue;
+			event.newValue = newValue;
+			
+			internalDispatchEvent( CollectionEventKind.UPDATE, event );
+			
+			// need to dispatch object event now
+			if( hasEventListener( PropertyChangeEvent.PROPERTY_CHANGE ) )
+			{
+				var objEvent:PropertyChangeEvent = PropertyChangeEvent( event.clone() );
+				var index:uint = getItemIndex(event.target);
+				objEvent.property = index.toString() + "." + event.property;
+				dispatchEvent(objEvent);
+			}
+		}
+		
+		/** 
+		 *  Removes all items from the list.
+		 *
+		 *  <p>If any item is not local and an asynchronous operation must be
+		 *  performed, an <code>ItemPendingError</code> will be thrown.</p>
+		 *
+		 *  <p>See the ItemPendingError documentation as well as
+		 *  the collections documentation for more information
+		 *   on using the <code>ItemPendingError</code>.</p>
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function removeAll():void
+		{
+			removeAllElements();
+		}
+		
+		/**
+		 *  Removes the item at the specified index and returns it.  
+		 *  Any items that were after this index are now one index earlier.
+		 *
+		 *  @param index The index from which to remove the item.
+		 *
+		 *  @return The item that was removed.
+		 *
+		 *  @throws RangeError is index is less than 0 or greater than length. 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function removeItemAt( index:int ):Object
+		{
+			return removeElementAt( index );
+		}
+		
+		/**
+		 *  Places the item at the specified index.  
+		 *  If an item was already at that index the new item will replace it
+		 *  and it will be returned.
+		 *
+		 *  @param item The new item to be placed at the specified index.
+		 *
+		 *  @param index The index at which to place the item.
+		 *
+		 *  @return The item that was replaced, or <code>null</code> if none.
+		 *
+		 *  @throws RangeError if index is less than 0 or greater than length.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		public function setItemAt( item:Object, index:int ):Object
+		{
+			var result:Object = removeElementAt( index );
+			addElementAt( item as IVisualElement,index );
+			
+			if( hasEventListener( CollectionEvent.COLLECTION_CHANGE ) )
+			{
+				var propertyChangeEvent:PropertyChangeEvent = new PropertyChangeEvent( PropertyChangeEvent.PROPERTY_CHANGE );
+				propertyChangeEvent.kind = PropertyChangeEventKind.UPDATE;
+				propertyChangeEvent.oldValue = result;
+				propertyChangeEvent.newValue = item;
+				propertyChangeEvent.property = index;
+					
+				internalDispatchEvent( CollectionEventKind.REPLACE, propertyChangeEvent, index );
+			}
+			
+			return result;
+		}
+		
+		/**
+		 *  Returns an Array that is populated in the same order as the IList
+		 *  implementation.
+		 *  This method can throw an ItemPendingError.
+		 *
+		 *  @return The array.
+		 *  
+		 *  @throws mx.collections.errors.ItemPendingError If the data is not yet completely loaded
+		 *  from a remote location.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */ 
+		public function toArray():Array
+		{
+			return _mxmlContent;
+		}
+		
+		/**
+		 *  Adjusts the selected index to account for items being added to or 
+		 *  removed from this component.
+		 *
+		 *  @param newIndex The new index.
+		 *   
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		protected function adjustSelection( newIndex:int ):void
+		{
+			var nl:INavigatorLayout = INavigatorLayout( layout );
+			if( !nl ) return;
+			
+			if( nl is AnimationNavigatorLayoutBase )
+			{
+				var anl:AnimationNavigatorLayoutBase = AnimationNavigatorLayoutBase( nl );
+				var duration:Number = anl.duration;
+				anl.duration = 0;
+			}
+			
+			nl.selectedIndex = newIndex;
+			
+			if( anl ) anl.duration = duration;
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function addLayoutListeners():void
+		{
+			if( !layout ) return;
+			layout.addEventListener( IndexChangeEvent.CHANGE, onBubbleLayoutEvent, false, 0, true );
+			layout.addEventListener( FlexEvent.VALUE_COMMIT, onBubbleLayoutEvent, false, 0, true );
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function removeLayoutListeners():void
+		{
+			if( !layout ) return;
+			layout.removeEventListener( IndexChangeEvent.CHANGE, onBubbleLayoutEvent, false );
+			layout.removeEventListener( FlexEvent.VALUE_COMMIT, onBubbleLayoutEvent, false );
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function onBubbleLayoutEvent( event:Event ):void
+		{
+			if( hasEventListener( event.type ) ) dispatchEvent( event );
+		}
+		
+		/**
+		 *  Dispatches a collection event with the specified information.
+		 *
+		 *  @param kind String indicates what the kind property of the event should be
+		 *  @param item Object reference to the item that was added or removed
+		 *  @param location int indicating where in the source the item was added.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		private function internalDispatchEvent( kind:String, item:Object = null, location:int = -1):void
+		{
+			switch( kind )
+			{
+				case CollectionEventKind.ADD :
+				{
+					if( location <= selectedIndex ) adjustSelection( selectedIndex + 1 );
+					break;
+				}
+				case CollectionEventKind.REMOVE :
+				{
+					if( location <= selectedIndex ) adjustSelection( length ? selectedIndex == 0 ? 0 : selectedIndex - 1 : -1 );
+					break;
+				}
+				case CollectionEventKind.RESET :
+				{
+					adjustSelection( length ? 0 : -1 );
+					break;
+				}
+			}
+			
+			if( hasEventListener( CollectionEvent.COLLECTION_CHANGE ) )
+			{
+				var event:CollectionEvent = new CollectionEvent( CollectionEvent.COLLECTION_CHANGE );
+				event.kind = kind;
+				event.items.push( item );
+				event.location = location;
+				dispatchEvent(event);
+			}
+		}
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Overridden Methods
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  <p>If the layout object has not been set yet, 
+		 *  createChildren() assigns this container a 
+		 *  default layout object, BasicLayout.</p>
+		 */ 
+		override protected function createChildren():void
+		{
+			if( !layout ) layout = new StackLayout();
+			layout.useVirtualLayout = useVirtualLayout;
+			
+			if( _selectedIndex != -1 ) INavigatorLayout( layout ).selectedIndex = _selectedIndex;
+			super.createChildren();
+		}	
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override public function addElementAt( element:IVisualElement, index:int ):IVisualElement
+		{
+			super.addElementAt( element, index );
+			internalDispatchEvent( CollectionEventKind.ADD, element, index );
+			return element;
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override public function removeAllElements():void
+		{
+			super.removeAllElements();
+			internalDispatchEvent( CollectionEventKind.RESET );
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override public function removeElementAt(index:int):IVisualElement
+		{
+			var removed:IVisualElement = super.removeElementAt( index );
+			internalDispatchEvent( CollectionEventKind.REMOVE, removed, index );
+			return removed;
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override public function swapElementsAt( index1:int, index2:int ):void
+		{
+			super.swapElementsAt( index1, index2 );
+			
+			if( hasEventListener( CollectionEvent.COLLECTION_CHANGE ) )
+			{
+				dispatchEvent( new CollectionEvent( CollectionEvent.COLLECTION_CHANGE, false, false, CollectionEventKind.MOVE, index1, index2, [ getElementAt( index1 ) ] ) );
+				dispatchEvent( new CollectionEvent( CollectionEvent.COLLECTION_CHANGE, false, false, CollectionEventKind.MOVE, index2, index1, [ getElementAt( index2 ) ] ) );
+			}
+		}
+		
+		/**
+		 *  @inheritDoc
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */
+		override public function setElementIndex( element:IVisualElement, index:int ):void
+		{
+			const oldIndex:int = hasEventListener( CollectionEvent.COLLECTION_CHANGE ) ? getElementIndex( element ) : -1;
+			
+			super.setElementIndex( element, index );
+			
+			if( oldIndex != -1 )
+			{
+				var i:int;
+				var loops:int;
+				var direction:int;
+				if( oldIndex < index )
+				{
+					i = oldIndex;
+					loops = index;
+					for( i; i < loops; i++ )
+					{
+						dispatchEvent( new CollectionEvent( CollectionEvent.COLLECTION_CHANGE, false, false, CollectionEventKind.MOVE, i, i + 1, [ getElementAt( i ) ] ) );
+					}
+					dispatchEvent( new CollectionEvent( CollectionEvent.COLLECTION_CHANGE, false, false, CollectionEventKind.MOVE, index, oldIndex, [ element ] ) );
+				}
+				else
+				{
+					i = index;
+					loops = oldIndex;
+					dispatchEvent( new CollectionEvent( CollectionEvent.COLLECTION_CHANGE, false, false, CollectionEventKind.MOVE, index, oldIndex, [ element ] ) );
+					for( i; i < loops; i++ )
+					{
+						dispatchEvent( new CollectionEvent( CollectionEvent.COLLECTION_CHANGE, false, false, CollectionEventKind.MOVE, i, i - 1, [ getElementAt( i ) ] ) )
+					}
+				}
+			}
+		}
+	}
+}
\ No newline at end of file

Added: incubator/flex/whiteboard/navigators/src/ws/tink/spark/containers/supportClasses/DeferredCreationPolicy.as
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/navigators/src/ws/tink/spark/containers/supportClasses/DeferredCreationPolicy.as?rev=1228400&view=auto
==============================================================================
--- incubator/flex/whiteboard/navigators/src/ws/tink/spark/containers/supportClasses/DeferredCreationPolicy.as (added)
+++ incubator/flex/whiteboard/navigators/src/ws/tink/spark/containers/supportClasses/DeferredCreationPolicy.as Fri Jan  6 20:58:43 2012
@@ -0,0 +1,129 @@
+/*
+
+Copyright (c) 2010 Tink Ltd - http://www.tink.ws
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
+THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+*/
+package ws.tink.spark.containers.supportClasses
+{
+	
+
+	/**
+	 *  The DeferredCreationPolicy class defines the constant values
+	 *  for the <code>creationPolicy</code> property of the DeferedGroup class.
+	 *
+	 *  @see ws.tink.spark.containers.DeferredGroup#creationPolicy
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @productversion Flex 4
+	 */
+	public class DeferredCreationPolicy
+	{
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Class constants
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Immediately create all descendants.
+		 *
+		 *  <p>Avoid using this <code>creationPolicy</code> because
+		 *  it increases the startup time of your application.
+		 *  There is usually no good reason to create components at startup
+		 *  which the user cannot see.
+		 *  If you are using this policy so that you can "push" data into
+		 *  hidden components at startup, you should instead design your
+		 *  application so that the data is stored in data variables
+		 *  and components which are created later "pull" in this data,
+		 *  via databinding or an <code>initialize</code> handler.</p>
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static const ALL:String = "all";
+		
+		/**
+		 *  Construct all decendants immediately but only inialize those
+		 *  that are visible.
+		 *  
+		 *  <p>This is useful if you using the container as a dataProvider
+		 *  to a MenuBar, as the MenuBar requires all the children to be created
+		 *  to get the correct dataProvider to drive its content.</p>
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static const CONSTRUCT:String = "construct";
+		
+		/**
+		 *  Only construct the immediate descendants and initialize
+		 *  those that are visible.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static const VISIBLE:String = "visible";
+		
+		/**
+		 *  Do not create any children.
+		 *
+		 *  <p>With this <code>creationPolicy</code>, it is the developer's
+		 *  responsibility to programmatically create the children 
+		 *  from the UIComponentDescriptors by calling
+		 *  <code>createComponentsFromDescriptors()</code>
+		 *  on the parent container.</p>
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public static const NONE:String = "none";
+		
+		
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Constructor
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion Flash 9
+		 *  @playerversion AIR 1.1
+		 *  @productversion Flex 3
+		 */
+		public function DeferredCreationPolicy()
+		{
+			
+		}
+	}
+}
\ No newline at end of file

Added: incubator/flex/whiteboard/navigators/src/ws/tink/spark/controls/BorderDataNavigator.as
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/navigators/src/ws/tink/spark/controls/BorderDataNavigator.as?rev=1228400&view=auto
==============================================================================
--- incubator/flex/whiteboard/navigators/src/ws/tink/spark/controls/BorderDataNavigator.as (added)
+++ incubator/flex/whiteboard/navigators/src/ws/tink/spark/controls/BorderDataNavigator.as Fri Jan  6 20:58:43 2012
@@ -0,0 +1,123 @@
+/*
+Copyright (c) 2010 Tink Ltd - http://www.tink.ws
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
+THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+package ws.tink.spark.controls
+{
+	import mx.graphics.IFill;
+	import mx.graphics.IStroke;
+	import ws.tink.spark.controls.DataNavigator;
+
+	public class BorderDataNavigator extends DataNavigator
+	{
+		public function BorderDataNavigator()
+		{
+		}
+		
+		private var _backgroundFill:IFill;
+		
+		/**
+		 *  Defines the background of the BorderContainer. 
+		 *  Setting this property override the <code>backgroundAlpha</code>, 
+		 *  <code>backgroundColor</code>, <code>backgroundImage</code>, 
+		 *  and <code>backgroundImageFillMode</code> styles.
+		 * 
+		 *  <p>The following example uses the <code>backgroundFill</code> property
+		 *  to set the background color to red:</p>
+		 *
+		 *  <pre>
+		 *  &lt;s:BorderContainer cornerRadius="10"&gt; 
+		 *     &lt;s:backgroundFill&gt; 
+		 *         &lt;s:SolidColor 
+		 *             color="red" 
+		 *             alpha="1"/&gt; 
+		 *     &lt;/s:backgroundFill&gt; 
+		 *  &lt;/s:BorderContainer&gt; </pre>
+		 *
+		 *  @default null
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */ 
+		public function get backgroundFill():IFill
+		{
+			return _backgroundFill;
+		}
+		
+		/**
+		 *  @private
+		 */ 
+		public function set backgroundFill(value:IFill):void
+		{
+			if (value == _backgroundFill)
+				return;
+			
+			_backgroundFill = value;
+			
+			if (skin)
+				skin.invalidateDisplayList();
+		}
+		
+		private var _borderStroke:IStroke;
+		
+		/**
+		 *  Defines the stroke of the BorderContainer container. 
+		 *  Setting this property override the <code>borderAlpha</code>, 
+		 *  <code>borderColor</code>, <code>borderStyle</code>, <code>borderVisible</code>, 
+		 *  and <code>borderWeight</code> styles.  
+		 * 
+		 *  <p>The following example sets the <code>borderStroke</code> property:</p>
+		 *
+		 *  <pre>
+		 *  &lt;s:BorderContainer cornerRadius="10"&gt; 
+		 *     &lt;s:borderStroke&gt; 
+		 *         &lt;mx:SolidColorStroke 
+		 *             color="black" 
+		 *             weight="3"/&gt; 
+		 *     &lt;/s:borderStroke&gt; 
+		 *  &lt;/s:BorderContainer&gt; </pre>
+		 *
+		 *  @default null
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion Flash 10
+		 *  @playerversion AIR 1.5
+		 *  @productversion Flex 4
+		 */ 
+		public function get borderStroke():IStroke
+		{
+			return _borderStroke;
+		}
+		
+		/**
+		 *  @private
+		 */ 
+		public function set borderStroke(value:IStroke):void
+		{
+			if (value == _borderStroke)
+				return;
+			
+			_borderStroke = value;
+			
+			if (skin)
+				skin.invalidateDisplayList();
+		}
+		
+	}
+}
\ No newline at end of file