You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ha...@apache.org on 2017/03/16 13:37:23 UTC

[03/42] flex-asjs git commit: And here’s TLF…

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/MoveChildrenOperation.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/MoveChildrenOperation.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/MoveChildrenOperation.as
new file mode 100644
index 0000000..dac768c
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/MoveChildrenOperation.as
@@ -0,0 +1,199 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.operations {
+	import org.apache.flex.textLayout.debug.assert;
+	import org.apache.flex.textLayout.edit.MementoList;
+	import org.apache.flex.textLayout.edit.ModelEdit;
+	import org.apache.flex.textLayout.edit.SelectionState;
+	import org.apache.flex.textLayout.elements.IFlowGroupElement;
+	import org.apache.flex.textLayout.elements.ListElement;
+	import org.apache.flex.textLayout.elements.ListItemElement;
+	import org.apache.flex.textLayout.elements.TextFlow;
+	
+	/**
+	 * The MoveChildrenOperation class allows moving a set of siblings out of its immediate parent chain, and the operation removes any empty ancestor chain left behind.
+	 *
+	 * @see org.apache.flex.textLayout.elements.FlowElement
+	 * @see org.apache.flex.textLayout.edit.EditManager
+	 * @see org.apache.flex.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class MoveChildrenOperation extends FlowTextOperation
+	{	
+		private var _source:IFlowGroupElement;
+		private var _sourceIndex:int;
+		private var _numChildren:int;
+		private var _destination:IFlowGroupElement;
+		private var _destinationIndex:int;
+		private var _mementoList:MementoList;
+		
+		/** 
+		 * Creates a MoveChildrenOperation object. 
+		 * 
+		 * <p>This operation moves a consecutive number of children of source into the destination
+		 * context.  Also, if moving the children leaves the source element with no children, then
+		 * source will be removed.  The removal is done recursively such that if source's parent
+		 * becomes empty from the removal of source, it too will be deleted, and on up the parent chain.</p>
+		 * 
+		 * @param operationState Specifies the SelectionState of this operation
+		 * @param source Specifies the parent of the item(s) to move.
+		 * @param sourceIndex Specifies the index of the first item to move.
+		 * @param numChildren Specifies the number of children to move.
+		 * @param destination Specifies the new parent of the items.
+		 * @param destinationIndex Specifies the new child index of the first element.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function MoveChildrenOperation(operationState:SelectionState, source:IFlowGroupElement, sourceIndex:int, numChildren:int, destination:IFlowGroupElement, destinationIndex:int)
+		{
+			super(operationState);
+			_source = source;
+			_sourceIndex = sourceIndex;
+			_numChildren = numChildren;
+			_destination = destination;
+			_destinationIndex = destinationIndex;
+			_mementoList = new MementoList(operationState.textFlow);
+		}
+		
+		/** Specifies the parent of the item(s) to move.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get source():IFlowGroupElement
+		{ return _source; }
+		public function set source(val:IFlowGroupElement):void
+		{ _source = val; }
+		
+		/** Specifies the number of children to move.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function get sourceIndex():int
+		{ return _sourceIndex; }
+		public function set sourceIndex(val:int):void
+		{ _sourceIndex = val; }
+		
+		/** Specifies the index of the first item to move.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function get numChildren():int
+		{ return _numChildren; }
+		public function set numChildren(val:int):void
+		{ _numChildren = val; }
+		
+		/** Specifies the new parent of the items.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function get destination():IFlowGroupElement
+		{ return _destination; }
+		public function set destination(val:IFlowGroupElement):void
+		{ _destination = val; }
+		
+		/** Specifies the new child index of the first element.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function get destinationIndex():int
+		{ return _destinationIndex; }
+		public function set destinationIndex(val:int):void
+		{ _destinationIndex = val; }
+		
+		/**
+		 *  @private
+		 * @flexjsignorecoercion org.apache.flex.textLayout.elements.IFlowGroupElement
+		 */
+		public override function doOperation():Boolean
+		{
+
+			CONFIG::debug
+			{
+				assert(_destination != null, "MoveChildrenOperation attempted on a null target");
+				assert(_source != null, "MoveChildrenOperation attempted on a null element");
+			}
+
+			var insertContext:IFlowGroupElement;
+			
+			for(var count:int = 0; count < _numChildren; count++)
+			{
+				// special case for list items moving into non-list parent - move the children of the item and remove the item
+				if(_source.getChildAt(_sourceIndex) is ListItemElement && !(_destination is ListElement))
+				{
+					for(var count2:int = 0; count2 = (_source.getChildAt(_sourceIndex) as IFlowGroupElement).numChildren; count2++)
+					{
+						_mementoList.push(ModelEdit.moveElement(textFlow, (_source.getChildAt(_sourceIndex) as IFlowGroupElement).getChildAt(0), _destination, _destinationIndex++));
+					}
+					_mementoList.push(ModelEdit.removeElements(textFlow, _source, _sourceIndex, 1));
+				}
+				else
+				{
+					_mementoList.push(ModelEdit.moveElement(textFlow, _source.getChildAt(_sourceIndex), _destination, _destinationIndex++));
+				}
+			}
+			
+			var parent:IFlowGroupElement = _source;
+			var idx:int;
+			while(parent.numChildren == 0 && !(parent is TextFlow))
+			{
+				idx = parent.parent.getChildIndex(parent);
+				parent = parent.parent;
+				_mementoList.push(ModelEdit.removeElements(textFlow, parent, idx, 1));
+				insertContext = parent;
+			}
+			
+			if(parent is ListElement)
+			{
+				insertContext = parent.parent;
+				idx = parent.parent.getChildIndex(parent);
+			}
+			
+			return true;
+		}
+		
+		/** @private */ 
+		public override function undo():SelectionState
+		{
+			_mementoList.undo();
+			return originalSelectionState; 
+		}
+		
+		/** @private */ 
+		public override function redo():SelectionState
+		{
+			_mementoList.redo();
+			return originalSelectionState; 
+		}
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/PasteOperation.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/PasteOperation.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/PasteOperation.as
new file mode 100644
index 0000000..d0eda48
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/PasteOperation.as
@@ -0,0 +1,196 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.operations
+{
+	import org.apache.flex.textLayout.conversion.ConversionConstants;
+	import org.apache.flex.textLayout.edit.ModelEdit;
+	import org.apache.flex.textLayout.edit.SelectionState;
+	import org.apache.flex.textLayout.edit.TextFlowEdit;
+	import org.apache.flex.textLayout.edit.TextScrap;
+	import org.apache.flex.textLayout.elements.IFlowLeafElement;
+	import org.apache.flex.textLayout.elements.IParagraphElement;
+	import org.apache.flex.textLayout.elements.ITextFlow;
+	import org.apache.flex.textLayout.formats.ITextLayoutFormat;
+	import org.apache.flex.textLayout.formats.TextLayoutFormat;
+
+
+
+
+
+
+	/**
+	 * The PasteOperation class encapsulates a paste operation.
+	 *
+	 * <p>The specified range is replaced by the new content.</p>
+	 * 
+	 * <p><b>Note:</b> The edit manager is responsible for copying the 
+	 * contents of the clipboard.</p>
+	 * 
+	 * @see org.apache.flex.textLayout.edit.EditManager
+	 * @see org.apache.flex.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */			
+	public class PasteOperation extends FlowTextOperation
+	{
+		private var _textScrap:TextScrap;
+		private var _numCharsAdded:int = 0;
+		private var _deleteTextOperation:DeleteTextOperation;
+		private var _applyParagraphSettings:Array;
+		private var _pointFormat:ITextLayoutFormat;
+		private var _applyPointFormat:ApplyFormatOperation;
+		
+		/** 
+		 * Creates a PasteOperation object.
+		 * 
+		 * @param operationState Describes the insertion point or a range of text 
+		 * to replace.
+		 * @param textScrap The content to paste into the text flow.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function PasteOperation(operationState:SelectionState, textScrap:TextScrap)
+		{
+			_pointFormat = operationState.pointFormat;
+			super(operationState);
+			_textScrap = textScrap;
+		}
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			if (_textScrap != null)
+			{
+				if (absoluteStart != absoluteEnd)	
+				{
+					_deleteTextOperation = new DeleteTextOperation(originalSelectionState);
+					_deleteTextOperation.doOperation();
+				}
+				
+				var preserveScrapParagraph:Boolean = false;
+				var plainText:Boolean = _textScrap.isPlainText();
+				if (!plainText)
+				{
+					// If we're pasting formatted text into an empty paragraph, apply the paragraph settings from the scrap to the paragraph in the TextFlow
+					var leaf:IFlowLeafElement = textFlow.findLeaf(absoluteStart);
+					var paragraph:IParagraphElement = leaf.getParagraph();
+					if (paragraph.textLength == 1)
+						preserveScrapParagraph = true;
+				}
+				var nextInsertPosition:int = TextFlowEdit.insertTextScrap(textFlow, absoluteStart, _textScrap, plainText);
+				if (textFlow.interactionManager)
+					textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, nextInsertPosition - absoluteStart);				
+				_numCharsAdded = (nextInsertPosition - absoluteStart);
+				
+				if (preserveScrapParagraph)
+				{
+					applyPreserveSettings();
+				} 
+				else if (_pointFormat && plainText)
+				{
+					_applyPointFormat = new ApplyFormatOperation(new SelectionState(textFlow, absoluteStart, absoluteStart + _numCharsAdded), _pointFormat, null, null);
+					_applyPointFormat.doOperation();
+				}
+
+				
+				
+			}
+			return true;	
+		}
+		
+		private function applyPreserveSettings():void
+		{
+			var scrap:ITextFlow = _textScrap.textFlow;
+			var scrapParagraph:IParagraphElement = scrap.getFirstLeaf().getParagraph();
+			
+			_applyParagraphSettings = [];
+			var format:TextLayoutFormat = new TextLayoutFormat(scrapParagraph.format);
+			format.setStyle(ConversionConstants.MERGE_TO_NEXT_ON_PASTE, undefined);
+			var applyParagraphFormat:ApplyFormatToElementOperation = new ApplyFormatToElementOperation(originalSelectionState, textFlow.findLeaf(absoluteStart).getParagraph(), format);
+			applyParagraphFormat.doOperation();
+			_applyParagraphSettings.push(applyParagraphFormat);			
+			
+			//bug #2826905
+			if(scrap.numChildren > 1){
+				var scrapEndParagraph:IParagraphElement = scrap.getLastLeaf().getParagraph();
+				format = new TextLayoutFormat(scrapEndParagraph.format);
+				format.setStyle(ConversionConstants.MERGE_TO_NEXT_ON_PASTE, undefined);
+				var applyEndParagraphFormat:ApplyFormatToElementOperation = new ApplyFormatToElementOperation(originalSelectionState, textFlow.findLeaf(absoluteStart + scrap.textLength - 1).getParagraph(), format);
+				applyEndParagraphFormat.doOperation();
+				_applyParagraphSettings.push(applyEndParagraphFormat);
+			}
+		}
+		
+		/** @private */
+		public override function undo():SelectionState
+		{
+			if (_textScrap != null)
+			{
+				if (_applyPointFormat)
+					_applyPointFormat.undo(); 
+				if (_applyParagraphSettings)
+				{
+					for (var i:int = _applyParagraphSettings.length - 1; i >= 0; --i)
+						_applyParagraphSettings[i].undo();
+				}
+				ModelEdit.deleteText(textFlow, absoluteStart, absoluteStart + _numCharsAdded, false);
+				if (_deleteTextOperation)
+					_deleteTextOperation.undo();
+			}
+			return originalSelectionState;	
+		}
+	
+		/** @private */
+		public override function redo():SelectionState
+		{
+			if (_textScrap != null)
+			{
+				if (_deleteTextOperation)
+					_deleteTextOperation.redo();
+				var nextInsertPosition:int = TextFlowEdit.insertTextScrap(textFlow, absoluteStart, _textScrap, _textScrap.isPlainText());
+				if (textFlow.interactionManager)
+					textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, nextInsertPosition - absoluteStart);		
+				if (_applyParagraphSettings)
+				{
+					for (var i:int = _applyParagraphSettings.length - 1; i >= 0; --i)
+						_applyParagraphSettings[i].redo();
+				}
+				if (_applyPointFormat)
+					_applyPointFormat.redo(); 
+			}
+			return new SelectionState(textFlow, absoluteStart + _numCharsAdded, absoluteStart + _numCharsAdded,null);	
+		}		
+
+		/** 
+		 * textScrap the text being pasted
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function get textScrap():TextScrap
+		{ return _textScrap; }
+		public function set textScrap(val:TextScrap):void
+		{ _textScrap = val; }		
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/RedoOperation.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/RedoOperation.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/RedoOperation.as
new file mode 100644
index 0000000..17ac4e4
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/RedoOperation.as
@@ -0,0 +1,70 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.operations {
+
+
+
+
+	/** 
+	 * The RedoOperation class encapsulates a redo operation.
+	 *
+	 * @see org.apache.flex.textLayout.edit.EditManager
+	 * @see org.apache.flex.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class RedoOperation extends FlowOperation
+	{
+		private var _operation:FlowOperation;	/** Operation to be undone - here so listeners on FlowOperationEvent can see. */
+		
+		/** 
+		 * Creates a RedoOperation object.
+		 * 
+		 * @param operation	The operation to redo.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function RedoOperation(operation:FlowOperation)
+		{ 
+			super(operation.textFlow);
+			_operation = operation;
+		}
+
+
+		/** 
+		 * The operation to redo.
+		 *  
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get operation():FlowOperation
+		{
+			return _operation;
+		}
+		public function set operation(value:FlowOperation):void
+		{
+			_operation = value;
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/SplitElementOperation.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/SplitElementOperation.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/SplitElementOperation.as
new file mode 100644
index 0000000..eeedaa7
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/SplitElementOperation.as
@@ -0,0 +1,191 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.operations {
+	import org.apache.flex.textLayout.elements.IFlowGroupElement;
+	import org.apache.flex.textLayout.edit.ElementMark;
+	import org.apache.flex.textLayout.edit.IMemento;
+	import org.apache.flex.textLayout.edit.ModelEdit;
+	import org.apache.flex.textLayout.edit.SelectionState;
+	import org.apache.flex.textLayout.elements.IFlowGroupElement;
+	import org.apache.flex.textLayout.elements.IParagraphElement;
+	import org.apache.flex.textLayout.elements.IListItemElement;
+	import org.apache.flex.textLayout.elements.ISubParagraphGroupElementBase;
+	import org.apache.flex.textLayout.formats.ListMarkerFormat;
+	import org.apache.flex.textLayout.formats.TextLayoutFormat;
+
+	
+
+
+
+
+
+	/**
+	 * The SplitElementOperation class encapsulates a change that splits any IFlowGroupElement into two elements.
+	 *
+	 * This operation splits target at operationState.absoluteStart.
+	 * 
+	 * @see org.apache.flex.textLayout.elements.ParagraphElement
+	 * @see org.apache.flex.textLayout.edit.EditManager
+	 * @see org.apache.flex.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */			
+	public class SplitElementOperation extends FlowTextOperation
+	{
+		//range for block delete
+		private var delSelOp:DeleteTextOperation;		
+
+		// describes the target
+		private var _targetMark:ElementMark;
+		
+		// moment to undo
+		private var _memento:IMemento;
+		
+		// new element to return to client
+		private var _newElement:IFlowGroupElement;
+		/** 
+		 * Creates a SplitElementOperation object.  This operation deletes a block selection and then splits the target at absoluteStart.  The block selection should not cause target to be deleted.
+		 * Target is a IFlowGroupElement but may not be a LinkElement, TCYElement or SubParagraphGroupElement.
+		 * 
+		 * @param operationState Describes the point at which to split the element.
+		 * If a range of text is specified, the contents of the range are deleted.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function SplitElementOperation(operationState:SelectionState, targetElement:IFlowGroupElement)
+		{
+			super(operationState);
+			this.targetElement = targetElement;
+		}
+		
+		/** 
+		 * Specifies the element this operation modifies.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function get targetElement():IFlowGroupElement
+		{
+			return _targetMark.findElement(originalSelectionState.textFlow) as IFlowGroupElement;
+		}
+		public function set targetElement(value:IFlowGroupElement):void
+		{
+			_targetMark = new ElementMark(value,0);
+		}
+		
+		/** 
+		 * Returns the new element created by doOperation.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function get newElement():IFlowGroupElement
+		{ return _newElement; }
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{ 
+			var target:IFlowGroupElement = targetElement;
+			
+			if (absoluteStart < absoluteEnd)
+			{
+				// watch out for total deletion of target
+				var targStart:int = target.getAbsoluteStart();
+				var targEnd:int   = targStart + target.textLength;
+				
+				delSelOp = new DeleteTextOperation(originalSelectionState);
+				delSelOp.doOperation();
+				
+				if (absoluteStart <= targStart && targEnd <= absoluteEnd)
+				{
+					// completely deleted
+					if (target is IParagraphElement)
+						target = textFlow.findAbsoluteParagraph(absoluteStart);
+					else
+						target = null;	
+				}
+				else
+					target = targetElement;	// recalculate
+				
+			}
+			
+			// SubParagraphGroupElements don't split as the target - they just merge again in normalize.  
+			// Consider some sort of way to do this.  Generally has to be combined with another operation or somehow marked as don't merge
+			// make sure it hasn't been deleted during the delete phase
+			if (target != null && !(target is ISubParagraphGroupElementBase) && target.getTextFlow() == textFlow)
+			{
+				var oldLength:int = textFlow.textLength;
+				var relativePosition:int = absoluteStart-target.getAbsoluteStart();
+				_memento = ModelEdit.splitElement(textFlow,target,relativePosition);
+				_newElement = target.parent.getChildAt(target.parent.getChildIndex(target)+1) as IFlowGroupElement;
+
+				// fix for 2702736 - when splitting a IListItemElement, make sure not to clone the counterReset marker format - it creates unexpected results, new items don't increment
+				if(_newElement is IListItemElement && 
+					_newElement.listMarkerFormat && 
+					_newElement.listMarkerFormat.counterReset !== undefined)
+				{
+					var listMarkerFormat:ListMarkerFormat = new ListMarkerFormat(_newElement.listMarkerFormat);
+					listMarkerFormat.counterReset = undefined;
+					_newElement.listMarkerFormat = listMarkerFormat;
+				}
+				
+				
+				if( target is IParagraphElement )
+				{
+					// fix for bug#2948473 - when splitting, the contain/column break settings will not be copied to the
+					// new paragraph element
+					var newFormat:TextLayoutFormat = new TextLayoutFormat(_newElement.format);
+					newFormat.containerBreakAfter = undefined;
+					newFormat.containerBreakBefore = undefined;
+					newFormat.columnBreakAfter = undefined;
+					newFormat.columnBreakBefore = undefined;
+					_newElement.format = newFormat;
+					
+					if (textFlow.interactionManager && oldLength != textFlow.textLength)
+						textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, textFlow.textLength-oldLength);
+				}
+						
+					
+			}
+
+			return true;
+		}
+	
+		/** @private */
+		public override function undo():SelectionState
+		{ 
+			if (_memento)
+				_memento.undo();	
+			_newElement = null;
+			
+			return absoluteStart < absoluteEnd ? delSelOp.undo() : originalSelectionState;
+		}
+		
+		/** @private */
+		public override function redo():SelectionState
+		{
+			super.redo();
+			return textFlow.interactionManager.getSelectionState();
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/SplitParagraphOperation.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/SplitParagraphOperation.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/SplitParagraphOperation.as
new file mode 100644
index 0000000..5b3bbdd
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/SplitParagraphOperation.as
@@ -0,0 +1,73 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.operations {
+	import org.apache.flex.textLayout.edit.SelectionState;
+	import org.apache.flex.textLayout.elements.IParagraphElement;
+
+	
+
+
+
+
+
+	/**
+	 * The SplitParagraphOperation class encapsulates a change that splits a paragraph into two elements.
+	 *
+	 * <p>The operation creates a new paragraph containing the text from 
+	 * the specified position to the end of the paragraph. If a range of text is specified, the text 
+	 * in the range is deleted first.</p>
+	 * 
+	 * @see org.apache.flex.textLayout.elements.ParagraphElement
+	 * @see org.apache.flex.textLayout.edit.EditManager
+	 * @see org.apache.flex.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */			
+	public class SplitParagraphOperation extends SplitElementOperation
+	{		
+		/** 
+		 * Creates a SplitParagraphOperation object.
+		 * 
+		 * @param operationState Describes the point at which to split the paragraph.
+		 * If a range of text is specified, the contents of the range are deleted.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function SplitParagraphOperation(operationState:SelectionState)
+		{
+			var para:IParagraphElement = operationState.textFlow.findLeaf(operationState.absoluteStart).getParagraph();
+			super(operationState, para);
+		}
+		
+		/** @private */
+		public override function merge(operation:FlowOperation):FlowOperation
+		{
+			if (this.endGeneration != operation.beginGeneration)
+				return null;
+			// TODO we could probably do something a bit more efficient for a backspace
+			if ((operation is SplitParagraphOperation) || (operation is InsertTextOperation))
+				return new CompositeOperation([this,operation]);
+			return null;
+		}
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/UndoOperation.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/UndoOperation.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/UndoOperation.as
new file mode 100644
index 0000000..0b86013
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/operations/UndoOperation.as
@@ -0,0 +1,71 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.operations
+{
+	import org.apache.flex.textLayout.edit.SelectionState;
+
+
+
+
+	/** 
+	 * The UndoOperation class encapsulates an undo operation.
+	 *
+	 * @see org.apache.flex.textLayout.edit.EditManager
+	 * @see org.apache.flex.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class UndoOperation extends FlowOperation
+	{
+		private var _operation:FlowOperation;	/** Operation to be undone - here so listeners on FlowOperationEvent can see. */
+		
+		/** 
+		 * Creates an UndoOperation object.
+		 * 
+		 * @param op	The operation to undo.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function UndoOperation(op:FlowOperation)
+		{ 
+			super(null);
+			_operation = op;
+		}
+		
+		/** 
+		 * The operation to undo. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function get operation():FlowOperation
+		{
+			return _operation;
+		}
+		public function set operation(value:FlowOperation):void
+		{
+			_operation = value;
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/ArrayProperty.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/ArrayProperty.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/ArrayProperty.as
new file mode 100644
index 0000000..bf84731
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/ArrayProperty.as
@@ -0,0 +1,201 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.property
+{
+	import org.apache.flex.textLayout.debug.assert;
+	import org.apache.flex.textLayout.formats.FormatValue;
+
+		
+
+		
+	// [ExcludeClass]
+	/** A property description with an Array value.@private */
+	public class ArrayProperty extends Property
+	{
+		private var _memberType:*;
+		
+		public function ArrayProperty(nameValue:String, defaultValue:Array, inherited:Boolean, categories:Vector.<String>, mType:Class)
+		{
+			super(nameValue, defaultValue, inherited, categories); 
+			_memberType = mType;
+			CONFIG::debug { assert(_memberType.description != null,"Array member class must have description"); }
+			// can defaultValue be INHERIT?
+			CONFIG::debug { assert(checkArrayTypes(defaultValue),"Array has bad defaultValue"); }
+		}
+		
+		/** The type the members of the array are required to be. */
+		public function get memberType():*
+		{ return _memberType; }
+		
+		protected function checkArrayTypes(val:Object):Boolean
+		{
+			if (val == null)
+				return true;
+			if (!(val is Array))
+				return false;
+			if (_memberType == null)
+				return true;
+			for each (var obj:Object in (val as Array))
+			{
+				if (!(obj is _memberType))
+					return false;
+			}
+			return true;
+		}
+		
+		/** @private */
+		public override function get defaultValue():*
+		{ return super.defaultValue == null ? null : (super.defaultValue as Array).slice();	}
+				
+		/** @private */
+		public override function setHelper(currVal:*,newVal:*):*
+		{
+			if (newVal === null)
+				newVal = undefined;
+			
+			if (newVal == undefined || newVal == FormatValue.INHERIT)
+				return newVal;
+
+			if (newVal is String)
+				newVal = this.valueFromString(String(newVal));
+			
+			if (!checkArrayTypes(newVal))
+			{
+				PropertyUtil.errorHandler(this,newVal);
+				return currVal;
+			}
+			return (newVal as Array).slice(); 
+		}
+
+		/** @private */
+		public override function concatInheritOnlyHelper(currVal:*,concatVal:*):*
+		{
+			return (inherited && currVal === undefined) || currVal == FormatValue.INHERIT ? ((concatVal is Array) ? (concatVal as Array).slice() : concatVal) : currVal;
+
+		}	
+		/** @private */
+		public override function concatHelper(currVal:*,concatVal:*):*
+		{
+			if (inherited)
+				return currVal === undefined || currVal == FormatValue.INHERIT ? ((concatVal is Array) ? (concatVal as Array).slice() : concatVal) : currVal;
+			if (currVal === undefined)
+				return defaultValue;
+			return currVal == FormatValue.INHERIT ? ((concatVal is Array) ? (concatVal as Array).slice() : concatVal) : currVal;
+
+		}	
+		/** @private */
+		public override function equalHelper(v1:*,v2:*):Boolean
+		{
+			if (_memberType != null)
+			{			
+				var v1Array:Array = v1 as Array;
+				var v2Array:Array = v2 as Array;
+		
+				if (v1Array && v2Array)
+				{			
+					if (v1Array.length == v2Array.length)
+					{
+						var desc:Object = _memberType.description;
+						for (var i:int=0; i < v1Array.length; ++i)
+						{
+							if (!PropertyUtil.equalAllHelper(desc, v1[i], v2[i]))
+								return false;
+						}
+						return true;
+					}
+				}
+			}
+			return v1 == v2;				
+		}
+		
+		/** @private */
+		public override function toXMLString(val:Object):String
+		{
+			if (val == FormatValue.INHERIT)
+				return String(val);
+			// TODO-7/7/2008-The XML format for array properties (as implemented below)
+			// is appropriate for what it is currently used, but can be ambiguous.
+			// For example, what if XML representations of contained elements contain the delimiters used here? 
+			 
+			// TODO: Check for description?
+			var desc:Object = _memberType.description;
+			var rslt:String = "";
+			var addSemi:Boolean = false;
+			for each (var member:Object in val)
+			{
+				if (addSemi)
+					rslt += "; ";
+				// export each element ',' separated
+				var addComma:Boolean = false;
+				for each (var prop:Property in desc)
+				{
+					var memberVal:Object = member[prop.name];
+					if (memberVal != null)
+					{
+						if (addComma)
+							rslt += ", ";
+						rslt += prop.name + ":" + prop.toXMLString(memberVal);
+						addComma = true;
+					}
+				}
+				addSemi = true;
+			}
+			return rslt;
+		}
+		
+		/** @private */
+		private function valueFromString(str:String):*
+		{ 	
+			// TODO-7/7/2008-The XML format for array properties can be ambiguous.
+			// See comment in toXMLString.
+			if ((str == null) || (str == "")) 
+				return null;
+			if (str == FormatValue.INHERIT)
+				return str;
+			var result:Array = new Array();
+			var desc:Object = _memberType.description;
+			
+			var attrsAll:Array = str.split('; '); 
+			for each (var attrs:String in attrsAll)
+			{
+			 	var obj:Object = new _memberType();	// NO PMD
+			 	
+			 	var attrsOne:Array = attrs.split(', ');
+			 	for each (var attr:String in attrsOne)
+			 	{
+			 		var nameValArr:Array = attr.split(':');
+			 		var propName:String = nameValArr[0];
+			 		var propVal:String = nameValArr[1];
+			 	
+				 	for each (var prop:Property in desc)
+				 	{
+				 		if (prop.name == propName)
+				 		{
+				 			obj[propName] = prop.setHelper(propVal,obj[propName]);
+				 			break;
+				 		}
+			 		}
+			 	}
+			 	result.push(obj);
+			}
+				
+			return result; 
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/BooleanPropertyHandler.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/BooleanPropertyHandler.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/BooleanPropertyHandler.as
new file mode 100644
index 0000000..a41e478
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/BooleanPropertyHandler.as
@@ -0,0 +1,43 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.property {
+
+		
+
+		
+	// [ExcludeClass]
+	/** A property description with a Boolean value. @private */
+	public class BooleanPropertyHandler extends PropertyHandler
+	{
+		override public function get className():String
+		{
+			return "BooleanPropertyHandler";
+		}
+		public override function owningHandlerCheck(newVal:*):*
+		{ 
+			if (newVal is Boolean)
+				return newVal;
+			
+			if (newVal == "true" || newVal == "false")
+				return newVal == "true";
+			
+			return undefined;	
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/CounterContentHandler.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/CounterContentHandler.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/CounterContentHandler.as
new file mode 100644
index 0000000..aca117e
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/CounterContentHandler.as
@@ -0,0 +1,214 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.property
+{
+	import org.apache.flex.textLayout.debug.assert;
+	import org.apache.flex.textLayout.elements.ListElement;	
+	
+	// [ExcludeClass]
+	public class CounterContentHandler extends PropertyHandler
+	{
+		override public function get className():String
+		{
+			return "CounterContentHandler";
+		}
+		// check to see if this handler has a custom exporter that must be used when owningHandlerCheck is true
+		public override function get customXMLStringHandler():Boolean
+		{ return true; }
+		
+		public override function toXMLString(val:Object):String
+		{ 
+			if (val.hasOwnProperty("counter"))
+				return val.ordered == null ? "counter(ordered)" : "counter(ordered," + val.ordered + ")";
+			if (val.hasOwnProperty("counters"))
+			{
+				var rslt:String = "counters(ordered";
+				if (val.suffix != null)
+				{
+					rslt += ",\"" + val.suffix + "\"";
+					if (val.ordered)
+						rslt += "," + val.ordered;
+				}
+				rslt += ")";
+				return rslt;
+			}
+			return val.toString();
+		}
+		
+		/** matches counter(ordered) */
+		static private  const _counterContentPattern1:RegExp = /^\s*counter\s*\(\s*ordered\s*\)\s*$/;
+		/** matches counter(ordered,ListStyleType) */
+		static private  const _counterContentPattern2:RegExp = /^\s*counter\s*\(\s*ordered\s*,\s*\S+\s*\)\s*$/;
+		
+		/** matches counters(ordered) */
+		static private  const _countersContentPattern1:RegExp = /^\s*counters\s*\(\s*ordered\s*\)\s*$/;
+		/** matches counters(ordered,"suffix") */
+		static private  const _countersContentPattern2:RegExp = /^\s*counters\s*\(\s*ordered\s*,\s*".*"\s*\)\s*$/;
+		/** matches counters(ordered,"suffix",ListStyleType) */
+		static private  const _countersContentPattern3:RegExp = /^\s*counters\s*\(\s*ordered\s*,\s*".*"\s*,\s*\S+\s*\)\s*$/;
+		
+		// return a value if this handler "owns" this property - otherwise return undefined
+		public override function owningHandlerCheck(newVal:*):*
+		{ 
+			var listStyleType:String;
+			
+			// check for the more efficient parsed representation
+			if (!(newVal is String))
+				return newVal.hasOwnProperty("counter") || newVal.hasOwnProperty("counters") ? newVal : undefined;
+			
+			if (_counterContentPattern1.test(newVal))
+				return newVal;
+			
+			if (_counterContentPattern2.test(newVal))
+			{
+				// need to validate the specified listStyleType
+				listStyleType = extractListStyleTypeFromCounter(newVal);
+				return ListElement.listSuffixes[listStyleType] !== undefined ? newVal : undefined;
+			}
+			
+			if (_countersContentPattern1.test(newVal))
+				return newVal;
+			
+			if (_countersContentPattern2.test(newVal))
+				return newVal;
+			
+			if (_countersContentPattern3.test(newVal))
+			{
+				listStyleType = extractListStyleTypeFromCounters(newVal);
+				return ListElement.listSuffixes[listStyleType] !== undefined ? newVal : undefined;
+			}
+			
+			return undefined;
+		}
+		
+		static private const _counterBeginPattern:RegExp = /^\s*counter\s*\(\s*ordered\s*,\s*/g;
+		static private const _trailingStuff:RegExp = /\s*\)\s*/g;
+			
+		/** @private - from _counterContentPattern2  counters(ordered,"suffix") */
+		static public function extractListStyleTypeFromCounter(s:String):String
+		{
+			CONFIG::debug { assert(_counterContentPattern2.test(s),"Bad Parameter to extractListStyleTypeFromCounter"); }
+			_counterBeginPattern.lastIndex = 0;
+			_counterBeginPattern.test(s);
+			s = s.substr(_counterBeginPattern.lastIndex);
+
+			_trailingStuff.lastIndex = 0;
+			_trailingStuff.test(s);
+			s = s.substr(0,_trailingStuff.lastIndex-1);
+
+			return s;
+		}
+		
+		static private const _countersTillSuffixPattern:RegExp = /^\s*counters\s*\(\s*ordered\s*,\s*"/g;
+		static private const _afterSuffixPattern2:RegExp = /^"\s*\)\s*$/;
+
+		/** @private - from _countersContentPattern2  */
+		static public function extractSuffixFromCounters2(s:String):String
+		{
+			CONFIG::debug { assert(_countersContentPattern2.test(s),"Bad Parameter to extractListStyleTypeFromCounter2"); }
+			_countersTillSuffixPattern.lastIndex = 0;
+			_countersTillSuffixPattern.test(s);
+			s = s.substr(_countersTillSuffixPattern.lastIndex);
+			
+			var rslt:String = "";
+			while (!_afterSuffixPattern2.test(s))
+			{
+				rslt += s.substr(0,1);
+				s = s.substr(1);
+			}
+			
+			return rslt;
+		}	
+		
+		static private const _afterSuffixPattern3:RegExp = /^"\s*,\s*\S+\s*\)\s*$/;
+		
+		static public function extractSuffixFromCounters3(s:String):String
+		{
+			CONFIG::debug { assert(_countersContentPattern3.test(s),"Bad Parameter to extractListStyleTypeFromCounter2"); }
+			_countersTillSuffixPattern.lastIndex = 0;
+			_countersTillSuffixPattern.test(s);
+			s = s.substr(_countersTillSuffixPattern.lastIndex);
+			
+			var rslt:String = "";
+			while (!_afterSuffixPattern3.test(s))
+			{
+				rslt += s.substr(0,1);
+				s = s.substr(1);
+			}
+			
+			return rslt;
+		}
+		
+		static private const _countersTillListStyleTypePattern:RegExp = /^\s*counters\s*\(\s*ordered\s*,\s*".*"\s*,\s*/g;
+		
+		/** @private - from _countersContentPattern2 */
+		static public function extractListStyleTypeFromCounters(s:String):String
+		{
+			CONFIG::debug { assert(_countersContentPattern3.test(s),"Bad Parameter to extractListStyleTypeFromCounter"); }
+			_countersTillListStyleTypePattern.lastIndex = 0;
+			_countersTillListStyleTypePattern.test(s);
+			s = s.substr(_countersTillListStyleTypePattern.lastIndex);
+			
+			_trailingStuff.lastIndex = 0;
+			_trailingStuff.test(s);
+			s = s.substr(0,_trailingStuff.lastIndex-1);
+			
+			return s;
+		}
+			
+		/** parse the input string and create a valid input value */
+		public override function setHelper(newVal:*):*
+		{ 
+			var s:String = newVal as String;
+			
+			var listStyleType:String;
+			var suffix:String;
+			
+			if (s == null)
+				return newVal;	// assume its an object that's been parsed already
+			
+			if (_counterContentPattern1.test(newVal))
+				return { counter:"ordered" }; 
+
+			if (_counterContentPattern2.test(newVal))
+			{
+				listStyleType = extractListStyleTypeFromCounter(newVal);
+				return { counter:"ordered", ordered:listStyleType };
+			}
+			
+			if (_countersContentPattern1.test(newVal))
+				return { counters:"ordered" }; 
+			
+			if (_countersContentPattern2.test(newVal))
+			{
+				suffix = extractSuffixFromCounters2(newVal);
+				return { counters:"ordered", suffix:suffix }; 
+			}
+			
+			if (_countersContentPattern3.test(newVal))
+			{
+				listStyleType = extractListStyleTypeFromCounters(newVal);
+				suffix = extractSuffixFromCounters3(newVal);
+				return { counters:"ordered", suffix:suffix, ordered:listStyleType };
+			}
+			
+			return undefined;
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/CounterPropHandler.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/CounterPropHandler.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/CounterPropHandler.as
new file mode 100644
index 0000000..c5c5fe7
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/CounterPropHandler.as
@@ -0,0 +1,65 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.property
+{
+	// [ExcludeClass]
+	public class CounterPropHandler extends PropertyHandler
+	{
+		override public function get className():String
+		{
+			return "CounterPropHandler";
+		}
+		private var _defaultNumber:int;
+		
+		public function CounterPropHandler(defaultNumber:int)
+		{ _defaultNumber = defaultNumber; }
+		
+		public function get defaultNumber():int
+		{ return _defaultNumber; }
+		
+		// check to see if this handler has a custom exporter that must be used when owningHandlerCheck is true
+		public override function get customXMLStringHandler():Boolean
+		{ return true; }
+		
+		public override function toXMLString(val:Object):String
+		{ return val["ordered"] == 1 ? "ordered" : "ordered " + val["ordered"]; }
+		
+		static private  const _orderedPattern:RegExp = /^\s*ordered(\s+-?\d+){0,1}\s*$/;
+		
+		// return a value if this handler "owns" this property - otherwise return undefined
+		public override function owningHandlerCheck(newVal:*):*
+		{ return newVal is String && _orderedPattern.test(newVal) || newVal.hasOwnProperty("ordered") ? newVal : undefined; }
+		
+		static private const _orderedBeginPattern:RegExp = /^\s*ordered\s*/g;
+		
+		// returns a new val based on - assumes owningHandlerCheck(newval) is true
+		public override function setHelper(newVal:*):*
+		{ 
+			var s:String = newVal as String;
+			if (s == null)
+				return newVal;	// assume its an object that's been parsed already
+
+			_orderedBeginPattern.lastIndex = 0;
+			_orderedBeginPattern.test(s);
+			var number:int = (_orderedBeginPattern.lastIndex != s.length) ? parseInt(s.substr(_orderedBeginPattern.lastIndex)) : _defaultNumber; 
+				
+			return { ordered:number }; 
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/EnumPropertyHandler.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/EnumPropertyHandler.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/EnumPropertyHandler.as
new file mode 100644
index 0000000..6b8fb21
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/EnumPropertyHandler.as
@@ -0,0 +1,49 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.property {
+		
+	// [ExcludeClass]
+	/** An property description with an enumerated string as its value. @private */
+	public class EnumPropertyHandler extends PropertyHandler
+	{
+		override public function get className():String
+		{
+			return "EnumPropertyHandler";
+		}
+		private var _range:Object;
+		
+		public function EnumPropertyHandler(propArray:Array)
+		{
+			_range = PropertyHandler.createRange(propArray);
+		}
+
+		
+		/** Returns object whose properties are the legal enum values */
+		public function get range():Object
+		{
+			return PropertyUtil.shallowCopy(_range); 
+		}		
+		
+		/** @private */
+		public override function owningHandlerCheck(newVal:*):*
+		{ 
+			return _range.hasOwnProperty(newVal) ? newVal : undefined;
+		}	
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/FormatPropertyHandler.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/FormatPropertyHandler.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/FormatPropertyHandler.as
new file mode 100644
index 0000000..3d4eb06
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/FormatPropertyHandler.as
@@ -0,0 +1,45 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.property
+{
+	
+	// [ExcludeClass]
+	public class FormatPropertyHandler extends PropertyHandler
+	{
+		override public function get className():String
+		{
+			return "FormatPropertyHandler";
+		}
+		private var _converter:Function;
+		
+		public function get converter():Function
+		{ return _converter; }
+		
+		public function set converter(val:Function):void
+		{ _converter = val; }
+
+		/** Attempts to handle Object as key value pairs - strings fail */
+		public override function owningHandlerCheck(newVal:*):*
+		{ return newVal is String ? undefined : newVal; }
+				
+		public override function setHelper(newVal:*):*
+		{ return _converter(newVal); }
+	}
+}
+

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/IntPropertyHandler.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/IntPropertyHandler.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/IntPropertyHandler.as
new file mode 100644
index 0000000..046e98d
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/IntPropertyHandler.as
@@ -0,0 +1,76 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.property
+{
+
+		
+
+
+	// [ExcludeClass]
+	/** A property description with a Number as its value. @private */
+	public class IntPropertyHandler extends PropertyHandler
+	{
+		override public function get className():String
+		{
+			return "IntPropertyHandler";
+		}
+		private const ALL_LIMITS:String = "allLimits";
+		private const LOWER_LIMIT:String ="lowerLimit";
+		private const UPPER_LIMIT:String = "upperLimit";
+		private var _minValue:int;
+		private var _maxValue:int;
+		private var _limits:String;
+		
+		public function IntPropertyHandler(minValue:int,maxValue:int,limits:String = ALL_LIMITS)
+		{
+			_minValue = minValue;
+			_maxValue = maxValue;
+			_limits = limits;
+		}
+		
+		override public function get minValue():Number
+		{ return _minValue; }
+		override public function get maxValue():Number
+		{ return _maxValue; } 
+
+		/** not yet enabled.  @private */
+		public function checkLowerLimit():Boolean
+		{ return _limits == ALL_LIMITS || _limits == LOWER_LIMIT; }
+		
+		/** not yet enabled.  @private */
+		public function checkUpperLimit():Boolean
+		{ return _limits == ALL_LIMITS || _limits == UPPER_LIMIT; }	
+		
+		// return true if this handler can "own" this property
+		public override function owningHandlerCheck(newVal:*):*
+		{			
+			var newNumber:Number = newVal is String ? parseInt(newVal) : int(newVal);
+			if (isNaN(newNumber))
+				return undefined;
+
+			var newInt:int = int(newNumber);
+			if (checkLowerLimit() && newInt < _minValue)
+				return undefined;
+			if (checkUpperLimit() && newInt > _maxValue)
+				return undefined;
+			return newInt;	
+		}
+				
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/NumberPropertyHandler.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/NumberPropertyHandler.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/NumberPropertyHandler.as
new file mode 100644
index 0000000..5d08142
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/NumberPropertyHandler.as
@@ -0,0 +1,81 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.property {
+
+		
+
+
+	// [ExcludeClass]
+	/** A property description with a Number as its value. @private */
+	public class NumberPropertyHandler extends PropertyHandler
+	{
+		override public function get className():String
+		{
+			return "NumberPropertyHandler";
+		}
+		private const ALL_LIMITS:String = "allLimits";
+		private const LOWER_LIMIT:String ="lowerLimit";
+		private const UPPER_LIMIT:String = "upperLimit";
+		private var _minValue:Number;
+		private var _maxValue:Number;
+		private var _limits:String;
+		
+		public function NumberPropertyHandler(minValue:Number,maxValue:Number,limits:String = ALL_LIMITS)
+		{
+			_minValue = minValue;
+			_maxValue = maxValue;
+			_limits = limits;
+		}
+		
+		override public function get minValue():Number
+		{ return _minValue; }
+		override public function get maxValue():Number
+		{ return _maxValue; } 
+
+		/** not yet enabled.  @private */
+		public function checkLowerLimit():Boolean
+		{ return _limits == ALL_LIMITS || _limits == LOWER_LIMIT; }
+		
+		/** not yet enabled.  @private */
+		public function checkUpperLimit():Boolean
+		{ return _limits == ALL_LIMITS || _limits == UPPER_LIMIT; }	
+		
+		// return true if this handler can "own" this property
+		public override function owningHandlerCheck(newVal:*):*
+		{			
+			var newNumber:Number = newVal is String ? parseFloat(newVal) : Number(newVal);
+			if (isNaN(newNumber))
+				return undefined;
+			if (checkLowerLimit() && newNumber < _minValue)
+				return undefined;
+			if (checkUpperLimit() && newNumber > _maxValue)
+				return undefined;
+			return newNumber;	
+		}
+
+		public function clampToRange(val:Number):Number
+		{
+			if (checkLowerLimit() && val < _minValue)
+				return _minValue;
+			if (checkUpperLimit() && val > _maxValue)
+				return _maxValue;
+			return val;			
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/PercentPropertyHandler.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/PercentPropertyHandler.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/PercentPropertyHandler.as
new file mode 100644
index 0000000..d348a85
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/PercentPropertyHandler.as
@@ -0,0 +1,72 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.property {
+
+		
+
+	
+	// [ExcludeClass]
+	/** A property description with a Number or a Percent as its value. @private */
+	public class PercentPropertyHandler extends PropertyHandler
+	{
+		override public function get className():String
+		{
+			return "PercentPropertyHandler";
+		}
+		private const ALL_LIMITS:String = "allLimits";
+		private const LOWER_LIMIT:String ="lowerLimit";
+		private const UPPER_LIMIT:String = "upperLimit";
+		private var _minValue:Number;
+		private var _maxValue:Number;
+		private var _limits:String;
+		
+		public function PercentPropertyHandler(minValue:String,maxValue:String,limits:String = ALL_LIMITS)
+		{
+			_minValue = PropertyUtil.toNumberIfPercent(minValue);
+			_maxValue = PropertyUtil.toNumberIfPercent(maxValue);
+			_limits = limits;
+		}
+
+		override public function get minValue():Number
+		{ return _minValue; }
+		override public function get maxValue():Number
+		{ return _maxValue; } 
+
+		/** not yet enabled.  @private */
+		public function checkLowerLimit():Boolean
+		{ return _limits == ALL_LIMITS || _limits == LOWER_LIMIT; }
+		
+		/** not yet enabled.  @private */
+		public function checkUpperLimit():Boolean
+		{ return _limits == ALL_LIMITS || _limits == UPPER_LIMIT; }	
+		
+		// return true if this handler can "own" this property
+		public override function owningHandlerCheck(newVal:*):*
+		{			
+			var newNumber:Number = PropertyUtil.toNumberIfPercent(newVal);
+			if (isNaN(newNumber))
+				return undefined;
+			if (checkLowerLimit() && newNumber < _minValue)
+				return undefined;
+			if (checkUpperLimit() && newNumber > _maxValue)
+				return undefined;
+			return newVal;
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/PropConst.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/PropConst.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/PropConst.as
new file mode 100644
index 0000000..415898f
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/PropConst.as
@@ -0,0 +1,24 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.property
+{
+	public class PropConst
+	{
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/Property.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/Property.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/Property.as
new file mode 100644
index 0000000..fdeef86
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/Property.as
@@ -0,0 +1,181 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.property
+{
+	import org.apache.flex.textLayout.elements.GlobalSettings;
+	import org.apache.flex.textLayout.formats.FormatValue;
+		
+	// [ExcludeClass]
+	/** Base class of property metadata.  Each property in the various TextLayout attributes structures has a metadata singletion Property class instance.  The instance
+	 * can be used to process the property to and from xml, find out range information and help with the attribute cascade.  The Property class also contains static functions
+	 * for processing all the properties collected in a TextLayout Format object. @private  */
+	public class Property
+	{		
+		
+	
+		// storing name here is redundant but is more efficient 
+		private var _name:String;
+		private var _default:*;
+		private var _inherited:Boolean;
+		private var _categories:Vector.<String>;
+		private var _hasCustomExporterHandler:Boolean;
+		private var _numberPropertyHandler:Object;
+		
+		protected var _handlers:Vector.<PropertyHandler>;
+		
+		/** Initializer.  Each property has a name and a default. */
+		public function Property(nameValue:String,defaultValue:*,inherited:Boolean,categories:Vector.<String>)
+		{ 
+			_name = nameValue;
+			_default = defaultValue;
+			_inherited = inherited;
+			_categories = categories;
+			_hasCustomExporterHandler = false;
+		}
+		
+		/** The name of the property */
+		public function get name():String
+		{ return _name; }
+		
+		/** The default value of this property */
+		public function get defaultValue():*
+		{ return _default; }
+		
+		/** Is this property inherited */
+		public function get inherited():Object
+		{ return _inherited; }
+		
+		/** First listed Category of this property. This is the legacy category from when Properties could only be in one category.  */
+		public function get category():String
+		{ return _categories[0]; }
+		
+		/** Return the list of categories */
+		public function get categories():Vector.<String>
+		{ return _categories; }
+				
+		public function addHandlers(... rest):void
+		{
+			_handlers = new Vector.<PropertyHandler>(rest.length,true);
+			for (var idx:int = 0; idx < rest.length; idx++)
+			{
+				var handler:PropertyHandler = rest[idx];
+				_handlers[idx] = handler;
+				if (handler.customXMLStringHandler)
+					_hasCustomExporterHandler = true;
+				if (handler.className == "NumberPropertyHandler")
+					_numberPropertyHandler = handler;
+			}
+		}
+		
+		public function findHandler(handlerClass:String):PropertyHandler
+		{
+			for each (var prop:PropertyHandler in _handlers)
+			{
+				if (prop.className == handlerClass)
+					return prop;
+			}
+			return null;
+		}
+
+		/** Helper function when setting the property */
+		public function setHelper(currVal:*,newVal:*):*
+		{
+			for each (var handler:PropertyHandler in _handlers)
+			{
+				var checkRslt:* = handler.owningHandlerCheck(newVal);
+				if (checkRslt !== undefined)
+					return handler.setHelper(checkRslt);
+			}
+			
+			PropertyUtil.errorHandler(this,newVal);
+			return currVal;	
+		}
+				
+		/** Helper function when merging the property to compute actual attributes */
+		public function concatInheritOnlyHelper(currVal:*,concatVal:*):*
+		{ return (_inherited && currVal === undefined) || currVal == FormatValue.INHERIT ? concatVal : currVal; }
+
+		/** Helper function when merging the property to compute actual attributes */
+		public function concatHelper(currVal:*,concatVal:*):*
+		{
+			if (_inherited)
+				return currVal === undefined || currVal == FormatValue.INHERIT ? concatVal : currVal;
+			if (currVal === undefined)
+				return defaultValue;
+			return currVal == FormatValue.INHERIT ? concatVal : currVal;
+		}
+		
+		/** Helper function when comparing the property */
+		public function equalHelper(v1:*,v2:*):Boolean
+		{ return v1 == v2; }
+		
+		/** Convert the value of this property to a string appropriate for XML export */
+		public function toXMLString(val:Object):String
+		{
+			if (_hasCustomExporterHandler)
+			{
+				for each (var prop:PropertyHandler in _handlers)
+				{
+					if (prop.customXMLStringHandler && prop.owningHandlerCheck(val) !== undefined)
+						return prop.toXMLString(val);
+				}				
+			}
+			return val.toString();
+		}
+		
+		public function get maxPercentValue():Number
+		{
+			var handler:PropertyHandler = findHandler("PercentPropertyHandler");
+			return handler ? handler.maxValue : NaN;
+		}
+		public function get minPercentValue():Number
+		{
+			var handler:PropertyHandler = findHandler("PercentPropertyHandler");
+			return handler ? handler.minValue : NaN;
+		}
+		public function get minValue():Number
+		{
+			var numberHandler:PropertyHandler = findHandler("NumberPropertyHandler");
+			if (numberHandler)
+				return numberHandler.minValue;
+			var intHandler:PropertyHandler = findHandler("IntPropertyHandler");
+			return intHandler ? intHandler.minValue : NaN;
+		}
+		public function get maxValue():Number
+		{
+			var numberHandler:PropertyHandler = findHandler("NumberPropertyHandler");
+			if (numberHandler)
+				return numberHandler.maxValue;
+			var intHandler:PropertyHandler = findHandler("IntPropertyHandler");
+			return intHandler ? intHandler.maxValue : NaN;
+		}
+		
+		public function computeActualPropertyValue(propertyValue:Object,percentInput:Number):Number
+		{				
+			var percent:Number = PropertyUtil.toNumberIfPercent(propertyValue);
+			if (isNaN(percent))
+				return Number(propertyValue);
+			
+			// its a percent - calculate and clamp
+			var rslt:Number =  percentInput * (percent / 100);
+			return _numberPropertyHandler ? _numberPropertyHandler.clampToRange(rslt) : rslt;
+		}
+
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/PropertyFactory.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/PropertyFactory.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/PropertyFactory.as
new file mode 100644
index 0000000..36904fc
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/PropertyFactory.as
@@ -0,0 +1,133 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.property {
+	import org.apache.flex.textLayout.formats.FormatValue;
+	public class PropertyFactory {
+		// shared propertyHandler instances
+		/** @private */
+		public static const sharedStringHandler:StringPropertyHandler = new StringPropertyHandler();
+		/** @private */
+		public static const sharedInheritEnumHandler:EnumPropertyHandler = new EnumPropertyHandler([ FormatValue.INHERIT ]);
+		/** @private */
+		public static const sharedUndefinedHandler:UndefinedPropertyHandler = new UndefinedPropertyHandler();
+		/** @private */
+		public static const sharedUintHandler:UintPropertyHandler = new UintPropertyHandler();
+		/** @private */
+		public static const sharedBooleanHandler:BooleanPropertyHandler = new BooleanPropertyHandler();
+		
+		/** @private */
+		public static const sharedTextLayoutFormatHandler:FormatPropertyHandler = new FormatPropertyHandler();
+		/** @private */
+		public static const sharedListMarkerFormatHandler:FormatPropertyHandler = new FormatPropertyHandler();
+		
+		public static function bool(nameValue:String, defaultValue:Boolean, inherited:Boolean, categories:Vector.<String>):Property
+		{			
+			var rslt:Property = new Property(nameValue, defaultValue, inherited, categories);
+			rslt.addHandlers(sharedUndefinedHandler,sharedBooleanHandler,sharedInheritEnumHandler);
+			return rslt;
+		}
+		
+		public static function string(nameValue:String, defaultValue:String, inherited:Boolean, categories:Vector.<String>):Property
+		{
+			var rslt:Property = new Property(nameValue, defaultValue, inherited, categories);
+			rslt.addHandlers(sharedUndefinedHandler,sharedStringHandler);
+			return rslt;			
+		}
+		public static function uintProp(nameValue:String, defaultValue:uint, inherited:Boolean, categories:Vector.<String>):Property
+		{
+			var rslt:Property = new Property(nameValue, defaultValue, inherited, categories);
+			rslt.addHandlers(sharedUndefinedHandler,sharedUintHandler,sharedInheritEnumHandler);
+			return rslt;
+		}
+
+		public static function enumString(nameValue:String, defaultValue:String, inherited:Boolean, categories:Vector.<String>, ... rest):Property
+		{
+			var rslt:Property = new Property(nameValue, defaultValue, inherited, categories);
+			rslt.addHandlers(sharedUndefinedHandler,new EnumPropertyHandler(rest),sharedInheritEnumHandler);
+			return rslt;
+		}
+		
+		public static function intOrEnum(nameValue:String, defaultValue:Object, inherited:Boolean, categories:Vector.<String>, minValue:int, maxValue:int, ... rest):Property
+		{		
+			var rslt:Property = new Property(nameValue, defaultValue, inherited, categories);
+			rslt.addHandlers(sharedUndefinedHandler,new EnumPropertyHandler(rest),new IntPropertyHandler(minValue,maxValue),sharedInheritEnumHandler);
+			return rslt;
+		}
+		
+		public static function uintOrEnum(nameValue:String, defaultValue:Object, inherited:Boolean, categories:Vector.<String>,  ... rest):Property
+		{			
+			var rslt:Property = new Property(nameValue, defaultValue, inherited, categories);
+			rslt.addHandlers(sharedUndefinedHandler,new EnumPropertyHandler(rest),sharedUintHandler,sharedInheritEnumHandler);
+			return rslt;
+		}
+
+		public static function number(nameValue:String, defaultValue:Number, inherited:Boolean, categories:Vector.<String>, minValue:Number, maxValue:Number):Property
+		{
+			var rslt:Property = new Property(nameValue, defaultValue, inherited, categories);
+			rslt.addHandlers(sharedUndefinedHandler,new NumberPropertyHandler(minValue,maxValue),sharedInheritEnumHandler);
+			return rslt;
+		}
+		public static function 	numPercentEnum(nameValue:String, defaultValue:Object, inherited:Boolean, categories:Vector.<String>, minValue:Number, maxValue:Number, minPercentValue:String, maxPercentValue:String, ... rest):Property
+		{
+			var rslt:Property = new Property(nameValue, defaultValue, inherited, categories);
+			rslt.addHandlers(sharedUndefinedHandler,new EnumPropertyHandler(rest),new PercentPropertyHandler(minPercentValue,maxPercentValue),new NumberPropertyHandler(minValue,maxValue),sharedInheritEnumHandler);
+			return rslt;
+		}
+		public static function numPercent(nameValue:String, defaultValue:Object, inherited:Boolean, categories:Vector.<String>, minValue:Number, maxValue:Number, minPercentValue:String, maxPercentValue:String):Property
+		{			
+			var rslt:Property = new Property(nameValue, defaultValue, inherited, categories);
+			rslt.addHandlers(sharedUndefinedHandler,new PercentPropertyHandler(minPercentValue,maxPercentValue),new NumberPropertyHandler(minValue,maxValue),sharedInheritEnumHandler);
+			return rslt;
+		}
+		public static function numEnum(nameValue:String, defaultValue:Object, inherited:Boolean, categories:Vector.<String>, minValue:Number, maxValue:Number, ... rest):Property
+		{			
+			var rslt:Property = new Property(nameValue, defaultValue, inherited, categories);
+			rslt.addHandlers(sharedUndefinedHandler,new EnumPropertyHandler(rest),new NumberPropertyHandler(minValue,maxValue),sharedInheritEnumHandler);
+			return rslt;
+		}
+		public static function tabStopsProp(nameValue:String, defaultValue:Array, inherited:Boolean, categories:Vector.<String>):Property
+		{
+			return new TabStopsProperty(nameValue,defaultValue,inherited,categories);
+		}
+		public static function spacingLimitProp(nameValue:String, defaultValue:Object, inherited:Boolean, categories:Vector.<String>, minPercentValue:String, maxPercentValue:String):Property
+		{
+			var rslt:Property = new Property(nameValue,defaultValue,inherited,categories);
+			rslt.addHandlers(sharedUndefinedHandler, new SpacingLimitPropertyHandler(minPercentValue, maxPercentValue), sharedInheritEnumHandler);
+			return rslt;
+		}
+		
+		private static const undefinedValue:* = undefined;
+		
+		public static function tlfProp(nameValue:String, defaultValue:Object, inherited:Boolean, categories:Vector.<String>):Property
+		{
+			// passing undefined as a value seems to confuse the compiler
+			var rslt:Property = new Property(nameValue, undefinedValue, inherited, categories);
+			rslt.addHandlers(sharedUndefinedHandler,sharedTextLayoutFormatHandler,sharedInheritEnumHandler);
+			return rslt;
+		}
+		public static function listMarkerFormatProp(nameValue:String, defaultValue:Object, inherited:Boolean, categories:Vector.<String>):Property
+		{
+			// passing undefined as a value seems to confuse the compiler
+			var rslt:Property = new Property(nameValue, undefinedValue, inherited, categories);
+			rslt.addHandlers(sharedUndefinedHandler,sharedListMarkerFormatHandler,sharedInheritEnumHandler);
+			return rslt;
+		}		
+	
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/fd08d137/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/PropertyHandler.as
----------------------------------------------------------------------
diff --git a/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/PropertyHandler.as b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/PropertyHandler.as
new file mode 100644
index 0000000..284377c
--- /dev/null
+++ b/frameworks/projects/TLF/src/main/flex/org/apache/flex/textLayout/property/PropertyHandler.as
@@ -0,0 +1,63 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.flex.textLayout.property
+{
+	// [ExcludeClass]
+	public class PropertyHandler
+	{
+		public static function createRange(rest:Array):Object
+		{
+			var range:Object = {};
+			// rest is the list of possible values
+			for (var i:int = 0; i < rest.length; i++)
+				range[rest[i]] = null;
+			return range;
+		}
+		public function get className():String
+		{
+			return "PropertyHandler";
+		}
+		
+		// check to see if this handler has a custom exporter that must be used when owningHandlerCheck is true
+		public function get customXMLStringHandler():Boolean
+		{ return false; }
+	
+		public function toXMLString(val:Object):String	// No PMD
+		{ return null; }
+
+		// return a value if this handler "owns" this property - otherwise return undefined
+		public function owningHandlerCheck(newVal:*):*	// No PMD
+		{ return undefined; }
+		
+			
+		// returns a new val based on - assumes owningHandlerCheck(newval) is true
+		public function setHelper(newVal:*):*
+		{ return newVal; }
+
+		public function get maxValue():Number
+		{
+			return NaN;
+		}
+		public function get minValue():Number
+		{
+			return NaN;
+		}
+	}
+
+}