diff --git a/DISCLAIMER b/DISCLAIMER
new file mode 100644
index 0000000..46661d6
--- /dev/null
+++ b/DISCLAIMER
@@ -0,0 +1,8 @@
+Apache Flex is an effort undergoing incubation at The Apache 
+Software Foundation (ASF), sponsored by the Apache Incubator. 
+Incubation is required of all newly accepted projects until a further 
+review indicates that the infrastructure, communications, and decision 
+making process have stabilized in a manner consistent with other 
+successful ASF projects. While incubation status is not necessarily a 
+reflection of the completeness or stability of the code, it does indicate 
+that the project has yet to be fully endorsed by the ASF.
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..1f7e9d8
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,717 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+------------------------------------------------------------------------------------------
+
+For the easing algorithms used in frameworks/src/mx/effect/easing:
+
+TERMS OF USE - EASING EQUATIONS
+
+Open source under the BSD License. 
+
+Easing Equations © 2001-2003, Robert Penner
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are 
+permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of 
+conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice, this list of 
+conditions and the following disclaimer in the documentation and/or other materials 
+provided with the distribution.
+Neither the name of the author nor the names of contributors may be used to endorse or 
+promote products derived from this software without specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+See frameworks/project/framework/src/mx/effect/easing/easing_readme.txt for more details 
+on what was used in this product.
+
+------------------------------------------------------------------------------------------
+
+For all directories except for the asc compiler in modules/asc, and modules/thirdparty 
+directories:
+
+Adobe Flex
+Copyright date 2003 - 2012 Adobe Systems Incorporated. All Rights Reserved.
+
+                          MOZILLA PUBLIC LICENSE
+                                Version 1.1
+
+                              ---------------
+
+1. Definitions.
+
+     1.0.1. "Commercial Use" means distribution or otherwise making the
+     Covered Code available to a third party.
+
+     1.1. "Contributor" means each entity that creates or contributes to
+     the creation of Modifications.
+
+     1.2. "Contributor Version" means the combination of the Original
+     Code, prior Modifications used by a Contributor, and the Modifications
+     made by that particular Contributor.
+
+     1.3. "Covered Code" means the Original Code or Modifications or the
+     combination of the Original Code and Modifications, in each case
+     including portions thereof.
+
+     1.4. "Electronic Distribution Mechanism" means a mechanism generally
+     accepted in the software development community for the electronic
+     transfer of data.
+
+     1.5. "Executable" means Covered Code in any form other than Source
+     Code.
+
+     1.6. "Initial Developer" means the individual or entity identified
+     as the Initial Developer in the Source Code notice required by Exhibit
+     A.
+
+     1.7. "Larger Work" means a work which combines Covered Code or
+     portions thereof with code not governed by the terms of this License.
+
+     1.8. "License" means this document.
+
+     1.8.1. "Licensable" means having the right to grant, to the maximum
+     extent possible, whether at the time of the initial grant or
+     subsequently acquired, any and all of the rights conveyed herein.
+
+     1.9. "Modifications" means any addition to or deletion from the
+     substance or structure of either the Original Code or any previous
+     Modifications. When Covered Code is released as a series of files, a
+     Modification is:
+          A. Any addition to or deletion from the contents of a file
+          containing Original Code or previous Modifications.
+
+          B. Any new file that contains any part of the Original Code or
+          previous Modifications.
+
+     1.10. "Original Code" means Source Code of computer software code
+     which is described in the Source Code notice required by Exhibit A as
+     Original Code, and which, at the time of its release under this
+     License is not already Covered Code governed by this License.
+
+     1.10.1. "Patent Claims" means any patent claim(s), now owned or
+     hereafter acquired, including without limitation,  method, process,
+     and apparatus claims, in any patent Licensable by grantor.
+
+     1.11. "Source Code" means the preferred form of the Covered Code for
+     making modifications to it, including all modules it contains, plus
+     any associated interface definition files, scripts used to control
+     compilation and installation of an Executable, or source code
+     differential comparisons against either the Original Code or another
+     well known, available Covered Code of the Contributor's choice. The
+     Source Code can be in a compressed or archival form, provided the
+     appropriate decompression or de-archiving software is widely available
+     for no charge.
+
+     1.12. "You" (or "Your")  means an individual or a legal entity
+     exercising rights under, and complying with all of the terms of, this
+     License or a future version of this License issued under Section 6.1.
+     For legal entities, "You" includes any entity which controls, is
+     controlled by, or is under common control with You. For purposes of
+     this definition, "control" means (a) the power, direct or indirect,
+     to cause the direction or management of such entity, whether by
+     contract or otherwise, or (b) ownership of more than fifty percent
+     (50%) of the outstanding shares or beneficial ownership of such
+     entity.
+
+2. Source Code License.
+
+     2.1. The Initial Developer Grant.
+     The Initial Developer hereby grants You a world-wide, royalty-free,
+     non-exclusive license, subject to third party intellectual property
+     claims:
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Initial Developer to use, reproduce,
+          modify, display, perform, sublicense and distribute the Original
+          Code (or portions thereof) with or without Modifications, and/or
+          as part of a Larger Work; and
+
+          (b) under Patents Claims infringed by the making, using or
+          selling of Original Code, to make, have made, use, practice,
+          sell, and offer for sale, and/or otherwise dispose of the
+          Original Code (or portions thereof).
+
+          (c) the licenses granted in this Section 2.1(a) and (b) are
+          effective on the date Initial Developer first distributes
+          Original Code under the terms of this License.
+
+          (d) Notwithstanding Section 2.1(b) above, no patent license is
+          granted: 1) for code that You delete from the Original Code; 2)
+          separate from the Original Code;  or 3) for infringements caused
+          by: i) the modification of the Original Code or ii) the
+          combination of the Original Code with other software or devices.
+
+     2.2. Contributor Grant.
+     Subject to third party intellectual property claims, each Contributor
+     hereby grants You a world-wide, royalty-free, non-exclusive license
+
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Contributor, to use, reproduce, modify,
+          display, perform, sublicense and distribute the Modifications
+          created by such Contributor (or portions thereof) either on an
+          unmodified basis, with other Modifications, as Covered Code
+          and/or as part of a Larger Work; and
+
+          (b) under Patent Claims infringed by the making, using, or
+          selling of  Modifications made by that Contributor either alone
+          and/or in combination with its Contributor Version (or portions
+          of such combination), to make, use, sell, offer for sale, have
+          made, and/or otherwise dispose of: 1) Modifications made by that
+          Contributor (or portions thereof); and 2) the combination of
+          Modifications made by that Contributor with its Contributor
+          Version (or portions of such combination).
+
+          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+          effective on the date Contributor first makes Commercial Use of
+          the Covered Code.
+
+          (d)    Notwithstanding Section 2.2(b) above, no patent license is
+          granted: 1) for any code that Contributor has deleted from the
+          Contributor Version; 2)  separate from the Contributor Version;
+          3)  for infringements caused by: i) third party modifications of
+          Contributor Version or ii)  the combination of Modifications made
+          by that Contributor with other software  (except as part of the
+          Contributor Version) or other devices; or 4) under Patent Claims
+          infringed by Covered Code in the absence of Modifications made by
+          that Contributor.
+
+3. Distribution Obligations.
+
+     3.1. Application of License.
+     The Modifications which You create or to which You contribute are
+     governed by the terms of this License, including without limitation
+     Section 2.2. The Source Code version of Covered Code may be
+     distributed only under the terms of this License or a future version
+     of this License released under Section 6.1, and You must include a
+     copy of this License with every copy of the Source Code You
+     distribute. You may not offer or impose any terms on any Source Code
+     version that alters or restricts the applicable version of this
+     License or the recipients' rights hereunder. However, You may include
+     an additional document offering the additional rights described in
+     Section 3.5.
+
+     3.2. Availability of Source Code.
+     Any Modification which You create or to which You contribute must be
+     made available in Source Code form under the terms of this License
+     either on the same media as an Executable version or via an accepted
+     Electronic Distribution Mechanism to anyone to whom you made an
+     Executable version available; and if made available via Electronic
+     Distribution Mechanism, must remain available for at least twelve (12)
+     months after the date it initially became available, or at least six
+     (6) months after a subsequent version of that particular Modification
+     has been made available to such recipients. You are responsible for
+     ensuring that the Source Code version remains available even if the
+     Electronic Distribution Mechanism is maintained by a third party.
+
+     3.3. Description of Modifications.
+     You must cause all Covered Code to which You contribute to contain a
+     file documenting the changes You made to create that Covered Code and
+     the date of any change. You must include a prominent statement that
+     the Modification is derived, directly or indirectly, from Original
+     Code provided by the Initial Developer and including the name of the
+     Initial Developer in (a) the Source Code, and (b) in any notice in an
+     Executable version or related documentation in which You describe the
+     origin or ownership of the Covered Code.
+
+     3.4. Intellectual Property Matters
+          (a) Third Party Claims.
+          If Contributor has knowledge that a license under a third party's
+          intellectual property rights is required to exercise the rights
+          granted by such Contributor under Sections 2.1 or 2.2,
+          Contributor must include a text file with the Source Code
+          distribution titled "LEGAL" which describes the claim and the
+          party making the claim in sufficient detail that a recipient will
+          know whom to contact. If Contributor obtains such knowledge after
+          the Modification is made available as described in Section 3.2,
+          Contributor shall promptly modify the LEGAL file in all copies
+          Contributor makes available thereafter and shall take other steps
+          (such as notifying appropriate mailing lists or newsgroups)
+          reasonably calculated to inform those who received the Covered
+          Code that new knowledge has been obtained.
+
+          (b) Contributor APIs.
+          If Contributor's Modifications include an application programming
+          interface and Contributor has knowledge of patent licenses which
+          are reasonably necessary to implement that API, Contributor must
+          also include this information in the LEGAL file.
+
+               (c)    Representations.
+          Contributor represents that, except as disclosed pursuant to
+          Section 3.4(a) above, Contributor believes that Contributor's
+          Modifications are Contributor's original creation(s) and/or
+          Contributor has sufficient rights to grant the rights conveyed by
+          this License.
+
+     3.5. Required Notices.
+     You must duplicate the notice in Exhibit A in each file of the Source
+     Code.  If it is not possible to put such notice in a particular Source
+     Code file due to its structure, then You must include such notice in a
+     location (such as a relevant directory) where a user would be likely
+     to look for such a notice.  If You created one or more Modification(s)
+     You may add your name as a Contributor to the notice described in
+     Exhibit A.  You must also duplicate this License in any documentation
+     for the Source Code where You describe recipients' rights or ownership
+     rights relating to Covered Code.  You may choose to offer, and to
+     charge a fee for, warranty, support, indemnity or liability
+     obligations to one or more recipients of Covered Code. However, You
+     may do so only on Your own behalf, and not on behalf of the Initial
+     Developer or any Contributor. You must make it absolutely clear than
+     any such warranty, support, indemnity or liability obligation is
+     offered by You alone, and You hereby agree to indemnify the Initial
+     Developer and every Contributor for any liability incurred by the
+     Initial Developer or such Contributor as a result of warranty,
+     support, indemnity or liability terms You offer.
+
+     3.6. Distribution of Executable Versions.
+     You may distribute Covered Code in Executable form only if the
+     requirements of Section 3.1-3.5 have been met for that Covered Code,
+     and if You include a notice stating that the Source Code version of
+     the Covered Code is available under the terms of this License,
+     including a description of how and where You have fulfilled the
+     obligations of Section 3.2. The notice must be conspicuously included
+     in any notice in an Executable version, related documentation or
+     collateral in which You describe recipients' rights relating to the
+     Covered Code. You may distribute the Executable version of Covered
+     Code or ownership rights under a license of Your choice, which may
+     contain terms different from this License, provided that You are in
+     compliance with the terms of this License and that the license for the
+     Executable version does not attempt to limit or alter the recipient's
+     rights in the Source Code version from the rights set forth in this
+     License. If You distribute the Executable version under a different
+     license You must make it absolutely clear that any terms which differ
+     from this License are offered by You alone, not by the Initial
+     Developer or any Contributor. You hereby agree to indemnify the
+     Initial Developer and every Contributor for any liability incurred by
+     the Initial Developer or such Contributor as a result of any such
+     terms You offer.
+
+     3.7. Larger Works.
+     You may create a Larger Work by combining Covered Code with other code
+     not governed by the terms of this License and distribute the Larger
+     Work as a single product. In such a case, You must make sure the
+     requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+     If it is impossible for You to comply with any of the terms of this
+     License with respect to some or all of the Covered Code due to
+     statute, judicial order, or regulation then You must: (a) comply with
+     the terms of this License to the maximum extent possible; and (b)
+     describe the limitations and the code they affect. Such description
+     must be included in the LEGAL file described in Section 3.4 and must
+     be included with all distributions of the Source Code. Except to the
+     extent prohibited by statute or regulation, such description must be
+     sufficiently detailed for a recipient of ordinary skill to be able to
+     understand it.
+
+5. Application of this License.
+
+     This License applies to code to which the Initial Developer has
+     attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+     6.1. New Versions.
+     Netscape Communications Corporation ("Netscape") may publish revised
+     and/or new versions of the License from time to time. Each version
+     will be given a distinguishing version number.
+
+     6.2. Effect of New Versions.
+     Once Covered Code has been published under a particular version of the
+     License, You may always continue to use it under the terms of that
+     version. You may also choose to use such Covered Code under the terms
+     of any subsequent version of the License published by Netscape. No one
+     other than Netscape has the right to modify the terms applicable to
+     Covered Code created under this License.
+
+     6.3. Derivative Works.
+     If You create or use a modified version of this License (which you may
+     only do in order to apply it to code which is not already Covered Code
+     governed by this License), You must (a) rename Your license so that
+     the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+     "MPL", "NPL" or any confusingly similar phrase do not appear in your
+     license (except to note that your license differs from this License)
+     and (b) otherwise make it clear that Your version of the license
+     contains terms which differ from the Mozilla Public License and
+     Netscape Public License. (Filling in the name of the Initial
+     Developer, Original Code or Contributor in the notice described in
+     Exhibit A shall not of themselves be deemed to be modifications of
+     this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+     8.1.  This License and the rights granted hereunder will terminate
+     automatically if You fail to comply with terms herein and fail to cure
+     such breach within 30 days of becoming aware of the breach. All
+     sublicenses to the Covered Code which are properly granted shall
+     survive any termination of this License. Provisions which, by their
+     nature, must remain in effect beyond the termination of this License
+     shall survive.
+
+     8.2.  If You initiate litigation by asserting a patent infringement
+     claim (excluding declatory judgment actions) against Initial Developer
+     or a Contributor (the Initial Developer or Contributor against whom
+     You file such action is referred to as "Participant")  alleging that:
+
+     (a)  such Participant's Contributor Version directly or indirectly
+     infringes any patent, then any and all rights granted by such
+     Participant to You under Sections 2.1 and/or 2.2 of this License
+     shall, upon 60 days notice from Participant terminate prospectively,
+     unless if within 60 days after receipt of notice You either: (i)
+     agree in writing to pay Participant a mutually agreeable reasonable
+     royalty for Your past and future use of Modifications made by such
+     Participant, or (ii) withdraw Your litigation claim with respect to
+     the Contributor Version against such Participant.  If within 60 days
+     of notice, a reasonable royalty and payment arrangement are not
+     mutually agreed upon in writing by the parties or the litigation claim
+     is not withdrawn, the rights granted by Participant to You under
+     Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+     the 60 day notice period specified above.
+
+     (b)  any software, hardware, or device, other than such Participant's
+     Contributor Version, directly or indirectly infringes any patent, then
+     any rights granted to You by such Participant under Sections 2.1(b)
+     and 2.2(b) are revoked effective as of the date You first made, used,
+     sold, distributed, or had made, Modifications made by that
+     Participant.
+
+     8.3.  If You assert a patent infringement claim against Participant
+     alleging that such Participant's Contributor Version directly or
+     indirectly infringes any patent where such claim is resolved (such as
+     by license or settlement) prior to the initiation of patent
+     infringement litigation, then the reasonable value of the licenses
+     granted by such Participant under Sections 2.1 or 2.2 shall be taken
+     into account in determining the amount or value of any payment or
+     license.
+
+     8.4.  In the event of termination under Sections 8.1 or 8.2 above,
+     all end user license agreements (excluding distributors and resellers)
+     which have been validly granted by You or any distributor hereunder
+     prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+     The Covered Code is a "commercial item," as that term is defined in
+     48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+     software" and "commercial computer software documentation," as such
+     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+     all U.S. Government End Users acquire Covered Code with only those
+     rights set forth herein.
+
+11. MISCELLANEOUS.
+
+     This License represents the complete agreement concerning subject
+     matter hereof. If any provision of this License is held to be
+     unenforceable, such provision shall be reformed only to the extent
+     necessary to make it enforceable. This License shall be governed by
+     California law provisions (except to the extent applicable law, if
+     any, provides otherwise), excluding its conflict-of-law provisions.
+     With respect to disputes in which at least one party is a citizen of,
+     or an entity chartered or registered to do business in the United
+     States of America, any litigation relating to this License shall be
+     subject to the jurisdiction of the Federal Courts of the Northern
+     District of California, with venue lying in Santa Clara County,
+     California, with the losing party responsible for costs, including
+     without limitation, court costs and reasonable attorneys' fees and
+     expenses. The application of the United Nations Convention on
+     Contracts for the International Sale of Goods is expressly excluded.
+     Any law or regulation which provides that the language of a contract
+     shall be construed against the drafter shall not apply to this
+     License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+     As between Initial Developer and the Contributors, each party is
+     responsible for claims and damages arising, directly or indirectly,
+     out of its utilization of rights under this License and You agree to
+     work with Initial Developer and Contributors to distribute such
+     responsibility on an equitable basis. Nothing herein is intended or
+     shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+     Initial Developer may designate portions of the Covered Code as
+     "Multiple-Licensed".  "Multiple-Licensed" means that the Initial
+     Developer permits you to utilize portions of the Covered Code under
+     Your choice of the NPL or the alternative licenses, if any, specified
+     by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+     ``The contents of this file are subject to the Mozilla Public License
+     Version 1.1 (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.mozilla.org/MPL/
+
+     Software distributed under the License is distributed on an "AS IS"
+     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+     License for the specific language governing rights and limitations
+     under the License.
+
+     The Original Code is ______________________________________.
+
+     The Initial Developer of the Original Code is ________________________.
+     Portions created by ______________________ are Copyright (C) ______
+     _______________________. All Rights Reserved.
+
+     Contributor(s): ______________________________________.
+
+     Alternatively, the contents of this file may be used under the terms
+     of the _____ license (the  "[___] License"), in which case the
+     provisions of [______] License are applicable instead of those
+     above.  If you wish to allow use of your version of this file only
+     under the terms of the [____] License and not to allow others to use
+     your version of this file under the MPL, indicate your decision by
+     deleting  the provisions above and replace  them with the notice and
+     other provisions required by the [___] License.  If you do not delete
+     the provisions above, a recipient may use your version of this file
+     under either the MPL or the [___] License."
+
+     [NOTE: The text of this Exhibit A may differ slightly from the text of
+     the notices in the Source Code files of the Original Code. You should
+     use the text of this Exhibit A rather than the text found in the
+     Original Code Source Code for Your Modifications.]
+
+------------------------------------------------------------------------------------------
+
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..8057945
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,9 @@
+Apache Flex Text Layout Framework
+Copyright 2012 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+The Initial Developer of the Original Code, known as Adobe Text Layout Framework, is Adobe Systems Incorporated (http://www.adobe.com/).
+    Copyright 2003 - 2012 Adobe Systems Incorporated. All Rights Reserved.
+
diff --git a/build.xml b/build.xml
new file mode 100755
index 0000000..de709ee
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,130 @@
+<!--
+  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.
+-->
+
+<project name="tlf" default="main" basedir=".">
+	<property name="FLEX_HOME" value="D:\flex_sdk_4.5.0.19786"/>
+	<property name="flex.sdk.frameworks" value="${FLEX_HOME}/frameworks"/>
+	<property name="flex.locale" value="en_US"/>
+
+	<property name="output.dir" value="bin"/>
+	<property name="output.docs" value="${FLEX_HOME}/tempDoc"/>
+	<property name="flexTasks.location" value="${FLEX_HOME}/ant/lib/flexTasks.jar"/>
+	<property name="project.uri" value="library://ns.adobe.com/flashx/textLayout"/>
+	<property name="compc.jvm.args" value="-Xmx384m" />
+	<property name="textLayout.namespace" value="flashx.textLayout"/>
+	
+	<property name="textLayout_core.dir" value="${basedir}/textLayout_core"/>
+	<property name="textLayout_layout.dir" value="${basedir}/textLayout_layout"/>
+	<property name="textLayout_conversion.dir" value="${basedir}/textLayout_conversion"/>
+	<property name="textLayout_edit.dir" value="${basedir}/textLayout_edit"/>
+	<property name="test.dir" value="${basedir}/test"/>
+
+        <!-- We use abbreviated token names here as, the 'release' 
+             and 'debug' tokens conflict with those specified in 
+             build.properties -->
+	<property name="dbg" value="false"/>
+	<property name="rel" value="true"/>
+
+	<condition property="digest" value="false" else="true">
+		<istrue value="${debug}"/>
+	</condition>
+
+	<taskdef resource="flexTasks.tasks" classpath="${flexTasks.location}"/>
+	<target name="main" depends="clean,textLayout_core, textLayout_conversion, textLayout_layout, textLayout_edit"/>
+
+	<target name="clean" description="Cleans all SWCs and SWFs">
+		<delete failonerror="false">
+			<fileset dir="${output.dir}">
+			</fileset>
+		</delete>
+	</target>
+
+	<target name="textLayout_core" description="Compiles textLayout_core.swc">
+   		<compc fork="true"
+			   output="${output.dir}/textLayout_core.swc"
+			   compute-digest="true"
+			   include-classes="flashx.textLayout.CoreClasses">
+			<jvmarg line="${compc.jvm.args}"/>
+			<include-namespaces uri="${project.uri}"/>
+			<namespace uri="${project.uri}" manifest="${textLayout_core.dir}/manifest.xml"/>
+			<source-path path-element="${textLayout_core.dir}/src"/>
+			<library-path/>
+			<include-file name="manifest.xml" path="${textLayout_core.dir}/manifest.xml"/>
+			<external-library-path dir="${flex.sdk.frameworks}/libs/player/10.0" includes="playerglobal.swc" 	append="false"/>
+			<static-link-runtime-shared-libraries/>
+			<define name="CONFIG::debug" value="${dbg}"/>
+			<define name="CONFIG::release" value="${rel}"/>
+		</compc>
+     </target>
+		 
+	 <target name="textLayout_conversion" description="Compiles textLayout_conversion.swc">
+   		<compc fork="true"
+			   output="${output.dir}/textLayout_conversion.swc"
+			   compute-digest="true"
+			   include-classes="flashx.textLayout.ConversionClasses">
+			<jvmarg line="${compc.jvm.args}"/>
+			
+			<source-path path-element="${textLayout_conversion.dir}/src"/>
+			<library-path/>
+			
+			<external-library-path dir="${flex.sdk.frameworks}/libs/player/10.0" includes="playerglobal.swc" 	append="false"/>
+			<external-library-path dir="${output.dir}" includes="textLayout_core.swc" 	append="true"/>
+			<static-link-runtime-shared-libraries/>
+			<define name="CONFIG::debug" value="${dbg}"/>
+			<define name="CONFIG::release" value="${rel}"/>
+		</compc>
+     </target>
+	
+	<target name="textLayout_layout" description="Compiles textLayout_layout.swc">
+   		<compc fork="true"
+			   output="${output.dir}/textLayout_layout.swc"
+			   compute-digest="true"
+			   include-classes="flashx.textLayout.LayoutClasses">
+			<jvmarg line="${compc.jvm.args}"/>
+			
+			<source-path path-element="${textLayout_layout.dir}/src"/>
+			<library-path/>
+			
+			<external-library-path dir="${flex.sdk.frameworks}/libs/player/10.0" includes="playerglobal.swc" 	append="false"/>
+			<external-library-path dir="${output.dir}" includes="textLayout_core.swc" 	append="true"/>
+			<external-library-path dir="${output.dir}" includes="textLayout_conversion.swc" 		append="true"/>
+			<static-link-runtime-shared-libraries/>
+			<define name="CONFIG::debug" value="${dbg}"/>
+			<define name="CONFIG::release" value="${rel}"/>
+		</compc>
+     </target>
+	 
+	 <target name="textLayout_edit" description="Compiles textLayout_edit.swc">
+   		<compc fork="true"
+			   output="${output.dir}/textLayout_edit.swc"
+			   compute-digest="true"
+			   include-classes="flashx.textLayout.EditClasses">
+			<jvmarg line="${compc.jvm.args}"/>
+
+			<source-path path-element="${textLayout_edit.dir}/src"/>
+			<library-path/>
+			
+			<external-library-path dir="${flex.sdk.frameworks}/libs/player/10.0" includes="playerglobal.swc" 	append="false"/>
+			<external-library-path dir="${output.dir}" includes="textLayout_core.swc" 	append="true"/>
+			<external-library-path dir="${output.dir}" includes="textLayout_conversion.swc" 		append="true"/>
+			<static-link-runtime-shared-libraries/>
+			<define name="CONFIG::debug" value="${dbg}"/>
+			<define name="CONFIG::release" value="${rel}"/>
+		</compc>
+     </target>
+
+</project>
diff --git a/config.xml b/config.xml
new file mode 100755
index 0000000..6a6c342
--- /dev/null
+++ b/config.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<!-- Settings for compiling Vellum with Eclipse -->
+<flex-config xmlns="http://www.adobe.com/2006/flex-config">
+  <compiler>
+	<define>
+      <name>CONFIG::debug</name>
+      <value>false</value>
+    </define>
+    <define>
+      <name>CONFIG::release</name>
+      <value>true</value>
+    </define>
+  </compiler>
+  <!-- this may be redundant if its also set in the SDK.  -->
+  <!-- some versions of the flex compilers may generate errors on multiple settings -->
+  <target-player>10.0.0</target-player>
+  <static-link-runtime-shared-libraries>true</static-link-runtime-shared-libraries>
+</flex-config>
diff --git a/textLayout_conversion/.actionScriptProperties b/textLayout_conversion/.actionScriptProperties
new file mode 100755
index 0000000..602e000
--- /dev/null
+++ b/textLayout_conversion/.actionScriptProperties
@@ -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.
+
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<actionScriptProperties mainApplicationPath="textLayout_conversion.as" projectUUID="c4b9cf5f-a4b7-497c-b3e2-c56e5572f10f" version="6">
+  <compiler additionalCompilerArguments="-locale en_US -load-config+=../../config.xml" autoRSLOrdering="true" copyDependentFiles="false" generateAccessible="false" htmlExpressInstall="true" htmlGenerate="false" htmlHistoryManagement="false" htmlPlayerVersionCheck="true" includeNetmonSwc="false" outputFolderPath="bin" sourceFolderPath="src" strict="true" targetPlayerVersion="0.0.0" useApolloConfig="false" useDebugRSLSwfs="true" verifyDigests="true" warn="true">
+    <compilerSourcePath/>
+    <libraryPath defaultLinkType="0">
+      <libraryPathEntry kind="3" linkType="4" path="/textLayout_core/bin/textLayout_core.swc" useDefaultLinkType="true"/>
+      <libraryPathEntry kind="4" path="">
+        <excludedEntries>
+          <libraryPathEntry kind="1" linkType="1" path="${PROJECT_FRAMEWORKS}/locale/{locale}"/>
+          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/flex.swc" useDefaultLinkType="false"/>
+          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/sparkskins.swc" useDefaultLinkType="false"/>
+          <libraryPathEntry index="4" kind="3" linkType="4" path="${PROJECT_FRAMEWORKS}/libs/rpc.swc" useDefaultLinkType="true">
+            <crossDomainRsls>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="http://fpdownload.adobe.com/pub/swz/crossdomain.xml" rslUrl="http://fpdownload.adobe.com/pub/swz/flex/4.0.0.10485/rpc_4.0.0.10485.swz"/>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="" rslUrl="rpc_4.0.0.10485.swz"/>
+            </crossDomainRsls>
+          </libraryPathEntry>
+          <libraryPathEntry index="2" kind="3" linkType="4" path="${PROJECT_FRAMEWORKS}/libs/framework.swc" useDefaultLinkType="true">
+            <crossDomainRsls>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="http://fpdownload.adobe.com/pub/swz/crossdomain.xml" rslUrl="http://fpdownload.adobe.com/pub/swz/flex/4.0.0.10485/framework_4.0.0.10485.swz"/>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="" rslUrl="framework_4.0.0.10485.swz"/>
+            </crossDomainRsls>
+          </libraryPathEntry>
+          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/datavisualization.swc" useDefaultLinkType="false"/>
+          <libraryPathEntry index="1" kind="3" linkType="4" path="${PROJECT_FRAMEWORKS}/libs/textLayout.swc" useDefaultLinkType="true">
+            <crossDomainRsls>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="http://fpdownload.adobe.com/pub/swz/crossdomain.xml" rslUrl="http://fpdownload.adobe.com/pub/swz/flex/4.0.0.10485/textLayout_4.0.0.10485.swz"/>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="" rslUrl="textLayout_4.0.0.10485.swz"/>
+            </crossDomainRsls>
+          </libraryPathEntry>
+          <libraryPathEntry index="3" kind="3" linkType="4" path="${PROJECT_FRAMEWORKS}/libs/spark.swc" useDefaultLinkType="true">
+            <crossDomainRsls>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="http://fpdownload.adobe.com/pub/swz/crossdomain.xml" rslUrl="http://fpdownload.adobe.com/pub/swz/flex/4.0.0.10485/spark_4.0.0.10485.swz"/>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="" rslUrl="spark_4.0.0.10485.swz"/>
+            </crossDomainRsls>
+          </libraryPathEntry>
+          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/utilities.swc" useDefaultLinkType="false"/>
+        </excludedEntries>
+      </libraryPathEntry>
+    </libraryPath>
+    <sourceAttachmentPath/>
+  </compiler>
+  <applications>
+    <application path="textLayout_conversion.as"/>
+  </applications>
+  <modules/>
+  <buildCSSFiles/>
+</actionScriptProperties>
diff --git a/textLayout_conversion/.flexLibProperties b/textLayout_conversion/.flexLibProperties
new file mode 100755
index 0000000..651ebac
--- /dev/null
+++ b/textLayout_conversion/.flexLibProperties
@@ -0,0 +1,23 @@
+# 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.
+
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<flexLibProperties includeAllClasses="false" version="3">
+  <includeClasses>
+    <classEntry path="flashx.textLayout.ConversionClasses"/>
+  </includeClasses>
+  <includeResources/>
+  <namespaceManifests/>
+</flexLibProperties>
diff --git a/textLayout_conversion/.project b/textLayout_conversion/.project
new file mode 100755
index 0000000..cdd2333
--- /dev/null
+++ b/textLayout_conversion/.project
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<projectDescription>
+	<name>textLayout_conversion</name>
+	<comment></comment>
+	<projects>
+		<project>textLayout_core</project>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.adobe.flexbuilder.project.flexbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.adobe.flexbuilder.project.flexlibnature</nature>
+		<nature>com.adobe.flexbuilder.project.actionscriptnature</nature>
+	</natures>
+</projectDescription>
diff --git a/textLayout_conversion/src/flashx/textLayout/ConversionClasses.as b/textLayout_conversion/src/flashx/textLayout/ConversionClasses.as
new file mode 100755
index 0000000..c45c534
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/ConversionClasses.as
@@ -0,0 +1,29 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout
+{
+	internal class ConversionClasses
+	{
+		import flashx.textLayout.conversion.ITextImporter; ITextImporter; 
+		import flashx.textLayout.conversion.ITextExporter; ITextExporter; 
+		import flashx.textLayout.conversion.TextConverter; TextConverter;
+		import flashx.textLayout.conversion.TextLayoutImporter; TextLayoutImporter;
+		// Alphabetical list of classes to be included as part of text_conversion.swc
+	}
+}
\ No newline at end of file
diff --git a/textLayout_conversion/src/flashx/textLayout/conversion/BaseTextLayoutExporter.as b/textLayout_conversion/src/flashx/textLayout/conversion/BaseTextLayoutExporter.as
new file mode 100755
index 0000000..5cbcfa4
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/conversion/BaseTextLayoutExporter.as
@@ -0,0 +1,425 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.conversion
+{
+	import flash.utils.getQualifiedClassName;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.LinkElement;
+	import flashx.textLayout.elements.ParagraphFormattedElement;
+	import flashx.textLayout.elements.SpanElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.WhiteSpaceCollapse;
+	import flashx.textLayout.property.Property;
+	import flashx.textLayout.tlf_internal;
+	use namespace tlf_internal;
+	
+	[ExcludeClass]
+	/** 
+	 * @private 
+	 * Export filter for TextLayout format. 
+	 */
+	internal class BaseTextLayoutExporter implements ITextExporter
+	{	
+		private var _config:ImportExportConfiguration;
+		private var _rootTag:XML;
+		private var _ns:Namespace;
+				
+		public function BaseTextLayoutExporter(ns:Namespace, rootTag:XML, config:ImportExportConfiguration)
+		{
+			_config = config;
+			_ns = ns;
+			_rootTag = rootTag;
+		}
+
+		
+		/** Clear results from last export. */
+		protected function clear():void
+		{
+			// does nothing
+		}
+		
+		/** Export text content
+		 * @param source	the text to export
+		 * @param conversionType 	what type to return
+		 * @return Object	the exported content
+		 */
+		public function export(source:TextFlow, conversionType:String):Object
+		{
+			clear();
+			if (conversionType == ConversionType.STRING_TYPE)
+				return exportToString(source);
+			else if (conversionType == ConversionType.XML_TYPE)
+				return exportToXML(source);
+			return null;
+		}
+
+		/** Export text content of a TextFlow into XFL format.
+		 * @param source	the text to export
+		 * @return XML	the exported content
+		 */
+		protected function exportToXML(textFlow:TextFlow) : XML
+		{
+			var result:XML;
+			if (_rootTag)
+			{
+				result = new XML(_rootTag);
+				result.addNamespace(_ns);
+				result.appendChild(exportChild(textFlow));
+			}
+			else
+			{
+				result = XML(exportTextFlow(this, textFlow));
+				result.addNamespace(_ns);
+			}
+			return result;
+		}
+		
+		/** Export text content as a string
+		 * @param source	the text to export
+		 * @return String	the exported content
+		 */
+		protected function exportToString(source:TextFlow):String
+		{
+			var result:String;
+			// We do some careful type casting here so that leading and trailing spaces in the XML don't
+			// get dropped when it is converted to a string
+			var originalSettings:Object = XML.settings();
+			try
+			{
+				XML.ignoreProcessingInstructions = false;		
+				XML.ignoreWhitespace = false;
+				XML.prettyPrinting = false;
+				result = exportToXML(source).toXMLString();
+				XML.setSettings(originalSettings);
+			}
+			
+			catch(e:Error)
+			{
+				XML.setSettings(originalSettings);
+				throw(e);
+			}		
+			return result;
+		}
+
+	
+		/** Base functionality for exporting a FlowElement. 
+		 * @param exporter	Root object for the export
+		 * @param flowElement	Element to export
+		 * @return XMLList	XML for the element
+		 */
+		static public function exportFlowElement(exporter:BaseTextLayoutExporter, flowElement:FlowElement):XMLList
+		{
+			return exporter.exportFlowElement(flowElement);
+		}
+		
+		/** Overridable worker method for exporting a FlowElement. Creates the XMLList.
+		 * @param flowElement	Element to export
+		 * @return XMLList	XML for the element
+		 */
+		protected function exportFlowElement (flowElement:FlowElement):XMLList
+		{
+			var className:String = flash.utils.getQualifiedClassName(flowElement);
+			var elementName:String = _config.lookupName(className);
+			var output:XML = <{elementName}/>;
+			output.setNamespace(_ns);
+			return XMLList(output);
+		}
+		
+		static public function exportSpanText(destination:XML, span:SpanElement, replacementRegex:RegExp, replacementXMLCallback:Function):void
+		{
+			//get the text for this span
+			var spanText:String = span.text;
+
+			// Check to see if it has text that needs to be converted			
+			var matchLocation:Array = spanText.match(replacementRegex);
+			
+			if(matchLocation)	
+			{
+				var dummy:XML;
+				
+				// We have text that has characters to be converted. Break it up into runs of text interspersed with elements corresponding to match these characters
+				while(matchLocation != null)
+				{
+					var ix:int = matchLocation.index;
+					var tempStr:String = spanText.substr(0, ix);
+					
+					//if we have some text which does not need to be replaced, then write it now
+					if(tempStr.length > 0)
+					{
+						// output[0].appendChild(tempStr); // extraneous tags can appear around a string child added after an XML element: see bug 1852072  
+						
+						// workaround for above-mentioned bug
+						dummy = <dummy/>;
+						dummy.appendChild(tempStr); // no extraneous tags here since there is no preceding XML element sibling
+						destination.appendChild(dummy.text()[0]);
+					}
+					
+					var replacementXML:XML = replacementXMLCallback(spanText.charAt(ix));
+					CONFIG::debug{ assert(replacementXML != null, "Specified match regex, but provided null replacement XML"); }
+					destination.appendChild(replacementXML);
+					
+					//remove the text up to this point
+					spanText = spanText.slice(ix + 1, spanText.length);
+					
+					//look for another character to be replaced
+					matchLocation = spanText.match(replacementRegex);
+					
+					//if we don't have any more matches, but there is still text, write that out as the last span
+					if(!matchLocation && spanText.length > 0)
+					{
+						// output[0].appendChild(spanText); // extraneous tags can appear around a string child added after an XML element: see bug 1852072  
+						
+						// workaround for above-mentioned bug
+						dummy = <dummy/>;
+						dummy.appendChild(spanText); // no extraneous tags here since there is no preceding XML element sibling
+						destination.appendChild(dummy.text()[0]);
+					}
+				}
+			}
+			else
+			{
+				//this is the simple case where we don't have a character to replace
+				destination.appendChild(span.text);
+			}		
+		}  
+		
+		/** Base functionality for exporting a Span. Exports as a FlowElement,
+		 * and exports the text of the span.
+		 * @param exporter	Root object for the export
+		 * @param span	Element to export
+		 * @return XMLList	XML for the element
+		 */
+		static public function exportSpan(exporter:BaseTextLayoutExporter, span:SpanElement):XMLList
+		{
+			var output:XMLList = exportFlowElement(exporter, span);	
+			exportSpanText(output[0], span, exporter.spanTextReplacementRegex, exporter.getSpanTextReplacementXML);
+			return output;
+		}
+		
+		static private const brRegEx:RegExp = /\u2028/;
+		
+		/** Gets the regex that specifies characters in span text to be replaced with XML elements
+		 *  Note: Each match is a single character 
+		 */
+		protected function get spanTextReplacementRegex():RegExp
+		{
+			return brRegEx;
+		}
+
+		/** Gets the xml element used to represent a character in the export format
+		 */
+		protected function getSpanTextReplacementXML(ch:String):XML
+		{
+			CONFIG::debug {assert(ch == '\u2028', "Did not recognize character to be replaced with XML"); }
+			var breakXML:XML = <br/>;
+			breakXML.setNamespace(flowNS);
+			return breakXML;
+		}
+		
+		/** Base functionality for exporting a FlowGroupElement. Exports as a FlowElement,
+		 * and exports the children of a element.
+		 * @param exporter	Root object for the export
+		 * @param flowBlockElement	Element to export
+		 * @return XMLList	XML for the element
+		 */
+		static public function exportFlowGroupElement(exporter:BaseTextLayoutExporter, flowBlockElement:FlowGroupElement):XMLList
+		{
+			var output:XMLList = exportFlowElement(exporter, flowBlockElement);
+			
+			// output each child
+			for(var childIter:int = 0; childIter < flowBlockElement.numChildren; ++childIter)
+			{
+				var flowChild:FlowElement = flowBlockElement.getChildAt(childIter);
+				var childXML:XMLList = exporter.exportChild(flowChild);
+				if (childXML)
+					output.appendChild(childXML);
+			}
+			return output;
+		}
+
+		/** Base functionality for exporting a ParagraphFormattedElement. Exports as a FlowGroupElement,
+		 * and exports paragraph attributes.
+		 * @param exporter	Root object for the export
+		 * @param flowParagraph	Element to export
+		 * @return XMLList	XML for the element
+		 */
+		static public function exportParagraphFormattedElement(exporter:BaseTextLayoutExporter, flowParagraph:ParagraphFormattedElement):XMLList
+		{
+			return exporter.exportParagraphFormattedElement(flowParagraph);
+		}
+		
+		/** Overridable worker method for exporting a ParagraphFormattedElement. Creates the XMLList.
+		 * @param flowElement	Element to export
+		 * @return XMLList	XML for the element
+		 */
+		protected function exportParagraphFormattedElement(flowElement:FlowElement):XMLList
+		{
+			var rslt:XMLList = exportFlowElement(flowElement);
+			// output each child
+			for(var childIter:int = 0; childIter < ParagraphFormattedElement(flowElement).numChildren; ++childIter)
+			{
+				var flowChild:FlowElement = ParagraphFormattedElement(flowElement).getChildAt(childIter);
+				rslt.appendChild(exportChild(flowChild));
+			}
+			return rslt;
+		}
+		/** Base functionality for exporting a ContainerFormattedElement. Exports as a ParagraphFormattedElement,
+		 * and exports container attributes.
+		 * @param exporter	Root object for the export
+		 * @param container	Element to export
+		 * @return XMLList	XML for the element
+		 */
+		static public function exportContainerFormattedElement(exporter:BaseTextLayoutExporter, container:ContainerFormattedElement):XMLList
+		{
+			return exporter.exportContainerFormattedElement(container);
+		}
+		
+		/** Overridable worker method for exporting a ParagraphFormattedElement. Creates the XMLList.
+		 * @param flowElement	Element to export
+		 * @return XMLList	XML for the element
+		 */
+		protected function exportContainerFormattedElement(flowElement:FlowElement):XMLList
+		{
+			return exportParagraphFormattedElement(flowElement);
+		}
+
+		/** Base functionality for exporting a TextFlow. Exports as a ContainerElement,
+		 * and exports container attributes.
+		 * @param exporter	Root object for the export
+		 * @param textFlow	Element to export
+		 * @return XMLList	XML for the element
+		 */
+		static public function exportTextFlow(exporter:BaseTextLayoutExporter, textFlow:TextFlow):XMLList
+		{
+			var output:XMLList = exportContainerFormattedElement(exporter, textFlow);
+			
+			// TextLayout will use PRESERVE on output
+			output.@[TextLayoutFormat.whiteSpaceCollapseProperty.name] = WhiteSpaceCollapse.PRESERVE;
+						
+			return output;
+		}
+
+
+		/** Exports the object. It will find the appropriate exporter and use it to 
+		 * export the object.
+		 * @param exporter	Root object for the export
+		 * @param flowElement	Element to export
+		 * @return XMLList	XML for the flowElement
+		 */
+		public function exportChild(flowElement:FlowElement):XMLList
+		{
+			var className:String = flash.utils.getQualifiedClassName(flowElement);
+			var info:FlowElementInfo = _config.lookupByClass(className);
+			if (info != null)
+				return info.exporter(this, flowElement);
+			return null;
+		}
+				
+		private function exportObjectAsDictionary(key:String,styleDict:Object):XMLList
+		{
+			// link attributes only right now
+			if (key != LinkElement.LINK_NORMAL_FORMAT_NAME && key != LinkElement.LINK_ACTIVE_FORMAT_NAME && key != LinkElement.LINK_HOVER_FORMAT_NAME)
+				return null;
+
+			// create the TextLayoutFormat element
+			var elementName:String = "TextLayoutFormat";
+			var formatXML:XML = <{elementName}/>;
+			formatXML.setNamespace(flowNS);
+			exportStyles(XMLList(formatXML), styleDict, formatDescription);
+
+			// create the link format element
+			var linkFormatXML:XMLList = XMLList(<{key}/>);
+			linkFormatXML.appendChild(formatXML);
+			return linkFormatXML;
+		}
+		
+		/** Helper function to export styles (core or user) in the form of xml attributes or xml children
+		 *
+		 * @param xml object to which attributes/children are added 
+		 * @styles the styles object: core styles, user styles, or a style dictionary 
+		 * @param description attribute class metadata object; must be specified for core styles, not otherwise
+		 * @param exclusions values to be excluded from being exported
+		 */
+		protected function exportStyles(xml:XMLList, styles:Object, description:Object=null, exclusions:Array=null):void
+		{
+			var sortableStyles:Array = [];
+			for (var key:Object in styles)
+			{
+				var val:Object = styles[key];
+				if (!exclusions || exclusions.indexOf(val) == -1)
+				{
+					if (description)
+					{
+						// Core style
+						// Use the description object to filter out styles that should not be exported
+						// and to obtain the corresponding String to be used as an XML attribute value
+						var prop:Property = description[key];
+						if (prop)
+							sortableStyles.push({xmlName:key, xmlVal:prop.toXMLString(val)});
+					}
+					else
+					{
+						// User style
+						if ((val is String) || val.hasOwnProperty("toString"))
+						{
+							// Is or can be converted to a String which will be used as an XML attribute value
+							sortableStyles.push({xmlName:key, xmlVal:val});
+						}
+						else
+						{
+							// A style dictionary; Will be converted to an XMLList containing elements to be added as children 
+							var customDictProp:XMLList = exportObjectAsDictionary(key as String,val);
+							if (customDictProp)
+								sortableStyles.push({xmlName:key, xmlVal:customDictProp});
+						}
+						
+					}
+				}
+			}
+			
+			// Sort the styles based on name for predictable export order
+			sortableStyles.sortOn("xmlName");
+			
+			for each(var exportInfo:Object in sortableStyles)
+            {
+            	var xmlVal:Object = exportInfo.xmlVal;
+            	if (xmlVal is String)
+					xml.@[exportInfo.xmlName] = xmlVal; // as an attribute
+				else if (xmlVal is XMLList)
+					xml.appendChild(xmlVal);			// as a child 
+            }  
+		}
+
+		internal function get flowNS():Namespace
+		{
+			return _ns;
+		}
+
+		protected function get formatDescription():Object
+		{
+			return null;
+		}		
+
+	}
+}
diff --git a/textLayout_conversion/src/flashx/textLayout/conversion/BaseTextLayoutImporter.as b/textLayout_conversion/src/flashx/textLayout/conversion/BaseTextLayoutImporter.as
new file mode 100755
index 0000000..8eaa1be
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/conversion/BaseTextLayoutImporter.as
@@ -0,0 +1,606 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.conversion 
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.BreakElement;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.GlobalSettings;
+	import flashx.textLayout.elements.IConfiguration;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.ParagraphFormattedElement;
+	import flashx.textLayout.elements.SpanElement;
+	import flashx.textLayout.elements.TabElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.property.Property;
+	import flashx.textLayout.tlf_internal;
+	use namespace tlf_internal;
+
+	[ExcludeClass]
+	/**
+	 * @private  
+	 * BaseTextLayoutImportFilter is a base class for handling the import/export of TextLayout text in the native format.
+	 */ 
+	internal class BaseTextLayoutImporter implements ITextImporter
+	{	
+		private var _ns:Namespace;		// namespace of expected in imported/exported content
+		
+		private var _errors:Vector.<String>;
+		private var _textFlowNamespace:Namespace; // namespace of the TextFlow element against which the namespaces of the following elements are validated
+		
+		private var _throwOnError:Boolean;
+		
+		protected var _config:ImportExportConfiguration;
+		protected var _textFlowConfiguration:IConfiguration;
+		
+		// static private const anyPrintChar:RegExp = /[^\s]/g;
+		// Consider only tab, line feed, carriage return, and space as characters used for pretty-printing. 
+		// While debatable, this is consistent with what CSS does. 
+		static private const anyPrintChar:RegExp = /[^\u0009\u000a\u000d\u0020]/g; 
+
+		public function BaseTextLayoutImporter(textFlowConfiguration:IConfiguration, nsValue:Namespace, config:ImportExportConfiguration)
+		{
+			_textFlowConfiguration = textFlowConfiguration;
+			_ns = nsValue;
+			_config = config;
+		}
+		
+		protected function clear():void
+		{
+			if (errors)
+				errors.splice(0, errors.length);
+			_textFlowNamespace = null;
+			_impliedPara = null;
+		}
+		
+		/** Import text content, from an external source, and convert it into a TextFlow.
+		 * @param source		source data to convert, may be string or XML
+		 * @return TextFlow that was created from the source.
+		 */
+		public function importToFlow(source:Object):TextFlow
+		{
+			clear();		// empty results of previous imports
+			
+			if (_throwOnError)
+				return importToFlowCanThrow(source);
+			
+			var rslt:TextFlow = null;
+			var savedErrorHandler:Function = Property.errorHandler;
+			try
+			{
+				Property.errorHandler = importPropertyErrorHandler;
+				rslt = importToFlowCanThrow(source);
+			}
+			catch (e:Error)
+			{
+				reportError(e.toString());
+			}
+			Property.errorHandler = savedErrorHandler;
+			return rslt;
+		}
+		
+		/** @private */
+		protected function importPropertyErrorHandler(p:Property,value:Object):void
+		{
+			reportError(Property.createErrorString(p,value));
+		}
+		
+		private function importToFlowCanThrow(source:Object):TextFlow
+		{
+			if (source is String)
+				return importFromString(String(source));
+			else if (source is XML)
+				return importFromXML(XML(source));
+			return null;
+		}
+		
+		/** Parse and convert input data.
+		 * 
+		 * @param source - a string which is in XFL format. String is applied to an XML object then passed
+		 * to importFromXML to be processed.  The source must be capable of being cast as an XML
+		 * object (E4X). 
+		 */
+		protected function importFromString(source:String):TextFlow
+		{
+			var originalSettings:Object = XML.settings();
+			try
+			{
+				XML.ignoreProcessingInstructions = false;		
+				XML.ignoreWhitespace = false;
+				var xmlTree:XML = new XML(source);				
+			}			
+			finally
+			{
+				XML.setSettings(originalSettings);
+			}	
+			
+			return importFromXML(xmlTree);
+		}
+		
+		/** Parse and convert input data.
+		 * 
+		 * xflSource is a XFL formated object which must be capable of being cast as an XML
+		 * object (E4X). 
+		 */
+		protected function importFromXML(xmlSource:XML):TextFlow
+			// Parse an XFL hierarchy into a TextFlow, using the geometry supplied by a TextFrame
+			// to host child containers (e.g. tables). This is the main entry point into this class.
+		{
+			return parseContent(xmlSource[0]);
+		}
+		
+		// This routine imports a TextFlow
+		protected function parseContent(rootStory:XML):TextFlow
+		{
+			// If the root element isn't a textFlow we know how to parse, keep descending the hierarchy.
+			var child:XML = rootStory..*::TextFlow[0];
+			if (child)
+				return parseTextFlow(this, rootStory);
+			return null;
+		}
+		
+		/** Returns the namespace used in for writing XML/XFL
+		 * 
+		 * @return the Namespace being used.
+		 */
+		public function get ns(): Namespace
+		{
+			return _ns;
+		}
+		
+		// Remove double spaces, tabs, and newlines.
+		// If I have a sequence of different sorts of spaces (e.g., en quad, hair space), would I want them converted down to one space? Probably not.
+		// For now, u0020 is the only space character we consider for eliminating duplicates, though u00A0 (non-breaking space) is potentially eligible. 
+		static private const dblSpacePattern:RegExp = /[\u0020]{2,}/g;
+		// Tab, line feed, and carriage return
+		static private const tabNewLinePattern:RegExp = /[\u0009\u000a\u000d]/g;
+		protected static function stripWhitespace(insertString:String):String
+		{
+			// Replace the newlines and tabs inside the element with spaces.
+			return insertString.replace(tabNewLinePattern, " ");
+		}
+
+		/** Parse XML and convert to  TextFlow. 
+		 * @param importFilter	parser object
+		 * @param xmlToParse	content to parse
+		 * @param parent always null - this parameter is only provided to match FlowElementInfo.importer signature
+		 * @return TextFlow	the new TextFlow created as a result of the parse
+		 */
+		static public function parseTextFlow(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:Object=null):TextFlow
+		{
+			return importFilter.createTextFlowFromXML(xmlToParse, null);
+		}		
+		
+		/** Static method to parse the supplied XML into a paragrph. Parse the <p ...> tag and it's children.
+		 * 
+		 * @param importFilter	parser object
+		 * @param xmlToParse	content to parse
+		 * @param parent 		the parent for the new content
+		 */
+		static public function parsePara(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{
+			var paraElem:ParagraphElement = importFilter.createParagraphFromXML(xmlToParse);
+			if (importFilter.addChild(parent, paraElem))
+			{
+				importFilter.parseFlowGroupElementChildren(xmlToParse, paraElem);
+				//if parsing an empty paragraph, create a Span for it.
+				if (paraElem.numChildren == 0)
+					paraElem.addChild(new SpanElement());
+			}
+		}
+		
+		static protected function copyAllStyleProps(dst:FlowLeafElement,src:FlowLeafElement):void
+		{
+			dst.format = src.format;
+			dst.styleName       = src.styleName;
+			dst.userStyles      = src.userStyles;
+			dst.id              = src.id;
+		}
+		
+		/** Static method for constructing a span from XML. Parse the <span> ... </span> tag. 
+		 * Insert the span into its parent
+		 * 
+		 * @param importFilter	parser object
+		 * @param xmlToParse	content to parse
+		 * @param parent 		the parent for the new content
+		 */
+		static public function parseSpan(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{
+			var firstSpan:SpanElement = importFilter.createSpanFromXML(xmlToParse);
+			
+			var elemList:XMLList = xmlToParse[0].children();
+			if(elemList.length() == 0)
+			{
+				// Empty span, but may have formatting, so don't strip it out. 
+				// Note: the normalizer may yet strip it out if it is not the last child, but that's the normalizer's business.
+				importFilter.addChild(parent, firstSpan); 
+				return;
+			}
+	
+			for each (var child:XML in elemList) 
+			{
+				var elemName:String = child.name() ? child.name().localName : null;
+					
+				if (elemName == null) // span text
+				{
+					if (firstSpan.parent == null)	// hasn't been used yet
+					{
+						firstSpan.text = child.toString();
+						importFilter.addChild(parent, firstSpan);
+					}
+					else
+					{
+						var s:SpanElement = new SpanElement();
+						copyAllStyleProps(s,firstSpan);
+						s.text = child.toString();
+						importFilter.addChild(parent, s);
+					}
+				}
+				else if (elemName == "br")
+				{
+					var brElem:BreakElement = importFilter.createBreakFromXML(child);	// may be null
+					if (brElem)
+					{
+						copyAllStyleProps(brElem,firstSpan);
+						importFilter.addChild(parent, brElem);
+					}
+					else
+						importFilter.reportError(GlobalSettings.resourceStringFunction("unexpectedXMLElementInSpan",[ elemName ]));
+				}
+				else if (elemName == "tab")
+				{
+					var tabElem:TabElement = importFilter.createTabFromXML(child);	// may be null
+					if (tabElem)
+					{
+						copyAllStyleProps(tabElem,firstSpan);
+						importFilter.addChild(parent, tabElem);
+					}
+					else
+						importFilter.reportError(GlobalSettings.resourceStringFunction("unexpectedXMLElementInSpan",[ elemName ]));
+				}
+				else
+					importFilter.reportError(GlobalSettings.resourceStringFunction("unexpectedXMLElementInSpan",[ elemName ]));				
+			}
+		}
+		
+		/** Static method for constructing a break element from XML. Validate the <br> ... </br> tag. 
+		 * Use "\u2028" as the text; Insert the new element into its parent 
+		 * 
+		 * @param importFilter	parser object
+		 * @param xmlToParse	content to parse
+		 * @param parent 		the parent for the new content
+		 */
+		static public function parseBreak(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{
+			var breakElem:BreakElement = importFilter.createBreakFromXML(xmlToParse);
+			importFilter.addChild(parent, breakElem);
+		}
+
+		
+		/** Static method for constructing a tab element from XML. Validate the <tab> ... </tab> tag. 
+		 * Use "\t" as the text; Insert the new element into its parent 
+		 * 
+		 * @param importFilter	parser object
+		 * @param xmlToParse	content to parse
+		 * @param parent 		the parent for the new content
+		 */
+		static public function parseTab(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{
+			var tabElem:TabElement = importFilter.createTabFromXML(xmlToParse);	// may be null
+			if (tabElem)
+				importFilter.addChild(parent, tabElem);
+		}
+		
+		protected function checkNamespace(xmlToParse:XML):Boolean
+		{
+			var elementNS:Namespace = xmlToParse.namespace();
+			if (!_textFlowNamespace) // Not set yet; must be parsing the TextFlow element
+			{
+				// TextFlow element: allow only empty namespace and flow namespace
+				if (elementNS != ns) 
+				{
+					reportError(GlobalSettings.resourceStringFunction("unexpectedNamespace", [elementNS.toString()]));
+					return false;
+				}
+				_textFlowNamespace = elementNS;
+			}
+			// Other elements: must match the namespace of the TextFlow element
+			// Specifically, can't be empty unless the TextFlow element's namespace is also empty 
+			else if (elementNS != _textFlowNamespace) 
+			{
+				reportError(GlobalSettings.resourceStringFunction("unexpectedNamespace", [elementNS.toString()]));
+				return false;
+			}
+			
+			return true;
+		}
+		
+		public function parseAttributes(xmlToParse:XML,formatImporters:Array):void
+		{
+			var importer:IFormatImporter;
+			// reset them all
+			for each (importer in formatImporters)
+				importer.reset();
+			
+			for each (var item:XML in xmlToParse.attributes())
+			{
+				var propertyName:String = item.name().localName;
+				var propertyValue:String = item.toString();
+				var imported:Boolean = false;
+				for each (importer in formatImporters)
+				{
+					if (importer.importOneFormat(propertyName,propertyValue))
+					{
+						imported = true;
+						break;
+					}
+				}
+				if (!imported)	// not a supported attribute
+					handleUnknownAttribute (xmlToParse.name().localName, propertyName);}
+		}
+				
+		static protected function extractAttributesHelper(curAttrs:Object, importer:TLFormatImporter):Object
+		{
+			if (curAttrs == null)
+				return importer.result;
+			
+			if (importer.result == null)
+				return curAttrs;
+				
+			var workAttrs:Object = new importer.classType(curAttrs);
+			workAttrs.apply(importer.result);
+			return workAttrs;
+		}	
+		
+		/** Parse XML and convert to  TextFlow.
+		 * @param xmlToParse	content to parse
+		 * @param textFlow 		TextFlow we're parsing. If null, create or find a new TextFlow based on XML content
+		 * @return TextFlow	the new TextFlow created as a result of the parse
+		 */
+		public function createTextFlowFromXML(xmlToParse:XML, newFlow:TextFlow = null):TextFlow
+		{
+			CONFIG::debug { assert(false,"missing override for createTextFlowFromXML"); }
+			return null;
+		}
+		
+		public function createParagraphFromXML(xmlToParse:XML):ParagraphElement
+		{
+			CONFIG::debug { assert(false,"missing override for createParagraphFromXML"); }
+			return null;
+		}
+		
+		public function createSpanFromXML(xmlToParse:XML):SpanElement
+		{
+			CONFIG::debug { assert(false,"missing override for createSpanFromXML"); }
+			return null;
+		}
+		
+		public function createBreakFromXML(xmlToParse:XML):BreakElement
+		{
+			parseAttributes(xmlToParse,null);	// no attributes allowed - reports errors
+			return new BreakElement();
+		}
+		
+		public function createTabFromXML(xmlToParse:XML):TabElement
+		{
+			parseAttributes(xmlToParse,null);	// reports errors
+			return new TabElement();
+		}
+		
+		/** Parse XML, convert to FlowElements and add to the parent.
+		 * @param xmlToParse	content to parse
+		 * @param parent 		the parent for the new content
+		 */
+		public function parseFlowChildren(xmlToParse:XML, parent:FlowGroupElement):void
+		{
+			parseFlowGroupElementChildren(xmlToParse, parent);
+		}
+		
+		/** Parse XML, convert to FlowElements and add to the parent.
+		 * @param xmlToParse	content to parse
+		 * @param parent 		the parent for the new content
+		 * @param chainedParent whether parent actually corresponds to xmlToParse or has been chained (such as when xmlToParse is a formatting element) 
+		 */
+		public function parseFlowGroupElementChildren(xmlToParse:XML, parent:FlowGroupElement, exceptionElements:Object = null, chainedParent:Boolean=false):void
+		{
+			for each (var child:XML in xmlToParse.children())
+			{
+				if (child.nodeKind() == "element")
+				{
+					parseObject(child.name().localName, child, parent, exceptionElements);
+				}
+				// look for mixed content here
+ 				else if (child.nodeKind() == "text") 
+ 				{
+ 					var txt:String = child.toString();
+ 					// Strip whitespace-only text appearing as a child of a container-formatted element
+ 					var strip:Boolean = false;
+ 					if (parent is ContainerFormattedElement)
+ 					{
+						strip = txt.search(anyPrintChar) == -1;
+					}
+					
+ 					if (!strip) 
+ 					{
+						// note, we don't want to set the paraFormat so that we inherit them from the TextFlow
+						var span:SpanElement = new SpanElement();
+						span.text = txt;
+						addChild(parent, span);
+					}
+				}
+			}
+			
+			// no implied paragraph should extend across container elements
+			if (!chainedParent && parent is ContainerFormattedElement)
+				resetImpliedPara();
+		}
+			
+		public function createParagraphFlowFromXML(xmlToParse:XML, newFlow:TextFlow = null):TextFlow
+		{
+			CONFIG::debug { assert(false,"missing override for createParagraphFlowFromXML"); }	// client must override
+			return null;
+		}
+		
+		tlf_internal function parseObject(name:String, xmlToParse:XML, parent:FlowGroupElement, exceptionElements:Object=null):void
+		{
+			if (!checkNamespace(xmlToParse))
+				return;
+
+			var info:FlowElementInfo = _config.lookup(name);
+			if (!info)
+			{
+				if (exceptionElements == null || exceptionElements[name] === undefined)
+					handleUnknownElement (name, xmlToParse, parent);		
+			}
+			else
+				info.parser(this, xmlToParse, parent);
+		}
+		
+		protected function handleUnknownElement(name:String, xmlToParse:XML, parent:FlowGroupElement):void
+		{
+			reportError(GlobalSettings.resourceStringFunction("unknownElement", [ name ]));	
+		}
+		
+		protected function handleUnknownAttribute(elementName:String, propertyName:String):void
+		{
+			reportError(GlobalSettings.resourceStringFunction("unknownAttribute", [ propertyName, elementName ]));	
+		}
+		
+		protected function getElementInfo(xmlToParse:XML):FlowElementInfo
+		{
+			return _config.lookup(xmlToParse.name().localName);
+		}
+		
+		protected function GetClass(xmlToParse:XML):Class
+		{
+			var info:FlowElementInfo = _config.lookup(xmlToParse.name().localName);
+			return info ? info.flowClass : null;
+		}
+		
+		// In the text model, non-FlowParagraphElements (i.e. spans, images, links, TCY) cannot be children of a ContainerElement (TextFlow, Div etc.)
+		// They can only be children of paragraphs or subparagraph blocks. 
+		// In XML, however, <p> elements can be implied (for example, a <span> may appear as a direct child of <flow>).  
+		// So, while parsing the XML, if we enounter a non-FlowParagraphElement child of a ContainerElement 
+		// 1. an explicitly created paragraph is used as the parent instead
+		// 2. such explicitly created paragraphs are shared by adjacent flow elements provided there isn't an intervening FlowParagraphElement		
+		private var _impliedPara:ParagraphElement = null; 
+		
+		/** @private */
+		tlf_internal function createImpliedParagraph():ParagraphElement
+		{
+			return createParagraphFromXML(<p/>);
+		}
+		
+		/**
+		 * @private
+		 * Helper function for adding a child flow element that honors throwOnError setting and uses the parent override
+		 * NOTE: You MUST NOT call addChild directly unless you are sure
+		 * - There is not possibility of an implied paragraph, and
+		 * - Parent is of type that can contain child
+		*/
+		tlf_internal function addChild(parent:FlowGroupElement, child:FlowElement):Boolean
+		{
+			if (child is ParagraphFormattedElement)
+			{
+				// Reset due to possibly intervening FlowParagrahElement; See note 2. above
+				resetImpliedPara();
+			}
+			else if (parent is ContainerFormattedElement)
+			{
+				// See note 1. above
+				if (!_impliedPara)
+				{
+					// Derived classes may have special behavior for <p> tags. Implied paragraphs may need the same behavior.
+					// So call createParagraphFromXML, don't just instantiate a ParagraphElement 
+					_impliedPara = createImpliedParagraph();
+					parent.addChild(_impliedPara);
+				}
+				
+				parent = _impliedPara;
+			}	
+			
+			if (_throwOnError)
+				parent.addChild(child);
+			else
+			{
+				try
+				{
+					parent.addChild(child);
+				}
+				catch (e:*)
+				{
+					reportError(e); 	
+					return false;
+				}
+			}
+			
+			return true;
+		} 
+		
+		tlf_internal function resetImpliedPara():void
+		{
+			if (_impliedPara)
+			{
+				onResetImpliedPara(_impliedPara);
+				_impliedPara = null;
+			}
+		}
+		
+		protected function onResetImpliedPara(para:ParagraphElement):void
+		{
+		}
+
+		/** Errors encountered while parsing. 
+		 * Value is a vector of Strings.
+		 */
+		public function get errors():Vector.<String>
+		{
+			return _errors;
+		}
+		
+		/** Errors will cause exceptions if throwOnError is true. */
+		public function get throwOnError():Boolean
+		{
+			return _throwOnError;
+		}
+		public function set throwOnError(value:Boolean):void
+		{
+			_throwOnError = value;
+		}
+		
+		/** Register an error that was encountered while parsing. If throwOnError
+		 * is true, the error causes an exception. Otherwise it is logged and parsing
+		 * continues.
+		 * @param error	the String that describes the error
+		 */
+		protected function reportError(error:String):void
+		{
+			if (_throwOnError)
+				throw new Error(error);
+			
+			if (!_errors)
+				_errors = new Vector.<String>();
+			_errors.push(error);
+		}
+	}
+}
+
diff --git a/textLayout_conversion/src/flashx/textLayout/conversion/ConversionType.as b/textLayout_conversion/src/flashx/textLayout/conversion/ConversionType.as
new file mode 100755
index 0000000..0139335
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/conversion/ConversionType.as
@@ -0,0 +1,51 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.conversion
+{
+	/**
+	 * Values for the format of exported text.
+	 * The values <code>STRING_TYPE</code> and <code>XML_TYPE</code> 
+	 * can be used for the <code>conversionType</code> parameter for 
+	 * the export() method in the ITextExporter interface and the
+	 * TextConverter class.
+	 *
+	 * @see flashx.textLayout.conversion.ITextExporter#export()
+	 * @see flashx.textLayout.conversion.TextConverter#export()
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public final class ConversionType
+	{
+		/** 
+		 * Export as type String. 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		public static const STRING_TYPE:String = "stringType";		
+		/** 
+		 * Export as type XML.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		public static const XML_TYPE:String = "xmlType";				
+	}
+}
diff --git a/textLayout_conversion/src/flashx/textLayout/conversion/CustomFormatImporter.as b/textLayout_conversion/src/flashx/textLayout/conversion/CustomFormatImporter.as
new file mode 100755
index 0000000..aafa829
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/conversion/CustomFormatImporter.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 flashx.textLayout.conversion
+{
+	import flash.utils.Dictionary;
+	
+	[ExcludeClass]
+	/**
+	 * @private  
+	 */
+	internal class CustomFormatImporter implements IFormatImporter
+	{
+		private var _rslt:Dictionary = null;
+		
+		public function CustomFormatImporter()
+		{ }
+		public function reset():void
+		{ _rslt = null; }
+		public function get result():Object
+		{ return _rslt; }
+		public function importOneFormat(key:String,val:String):Boolean
+		{
+			if (_rslt == null)
+				_rslt = new Dictionary();
+			_rslt[key] = val;
+			return true; 
+		}
+	}
+}
diff --git a/textLayout_conversion/src/flashx/textLayout/conversion/FlowElementInfo.as b/textLayout_conversion/src/flashx/textLayout/conversion/FlowElementInfo.as
new file mode 100755
index 0000000..f570c8f
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/conversion/FlowElementInfo.as
@@ -0,0 +1,82 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.conversion
+{
+	import flash.utils.getQualifiedClassName;
+	
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.ParagraphFormattedElement;
+	
+	[ExcludeClass]
+	/**
+	 * @private  
+	 * Contains configuration data about FlowElement types. 
+	 */
+	internal class FlowElementInfo
+	{
+		/** Class used for the FlowElement sub-type */
+		private var _flowClass:Class;
+		/** Fully qualified class name */
+		private var _flowClassName:String;
+		/** Parsing function used for reading in data on a FlowElement instance */
+		private var _parser:Function;
+		/** Class for the object's XFL import/export interface */
+		private var _exporter:Function;
+		
+		/** is this class a ParagraphFormattedElement */
+		private var _isParagraphFormattedElement:Boolean;
+		
+		/** Construct a FlowElementInfo
+		 * @param	flowClass	Class used to represent the FlowElement
+		 * @param 	parser		Function used for parsing XML description of a FlowElement
+		 * @param 	exporter	Class used to represent the FlowElement's exporter
+		 * @param	isParagraphFormattedElement Boolean indicating if this class is a subclass of ParagraphFormattedElement
+		 */
+		public function FlowElementInfo(flowClass:Class, parser:Function, exporter:Function , isParagraphFormattedElement:Boolean)
+		{
+			this._flowClass = flowClass;
+			this._parser = parser;
+			this._exporter = exporter;
+			this._flowClassName = getQualifiedClassName(flowClass);
+			this._isParagraphFormattedElement = isParagraphFormattedElement;
+			CONFIG::debug {
+				if (flowClass == null)
+					assert(isParagraphFormattedElement == false,"Bad value supplied for isParagraphFormattedElement"); 
+				else
+					assert(isParagraphFormattedElement == ((new flowClass) is ParagraphFormattedElement),"Bad value supplied for isParagraphFormattedElement"); 
+			}
+		}
+		
+		/** Class used for the FlowElement sub-type */
+		public function get flowClass():Class
+		{ return _flowClass; }
+		/** Fully qualified class name */
+		public function get flowClassName():String
+		{ return _flowClassName; }
+		/** Parsing function used for reading in data on a FlowElement instance */
+		public function get parser():Function
+		{ return _parser; }
+		/** Class for the object's XFL import/export interface */
+		public function get exporter():Function
+		{ return _exporter; }
+		/** Boolean indicating if flowClass is a subclass of ParagraphFormattedElement */
+		public function get isParagraphFormattedElement():Boolean
+		{ return _isParagraphFormattedElement; }
+	}
+}
\ No newline at end of file
diff --git a/textLayout_conversion/src/flashx/textLayout/conversion/HtmlExporter.as b/textLayout_conversion/src/flashx/textLayout/conversion/HtmlExporter.as
new file mode 100755
index 0000000..2647a9c
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/conversion/HtmlExporter.as
@@ -0,0 +1,468 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.conversion
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.*;
+	import flashx.textLayout.formats.TabStopFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextAlign;
+	import flashx.textLayout.formats.Direction;
+	import flashx.textLayout.formats.Float;
+	import flashx.textLayout.formats.LeadingModel;
+	import flashx.textLayout.formats.FormatValue;
+	import flash.text.engine.FontWeight;
+	import flash.text.engine.FontPosture;
+	import flash.text.engine.Kerning;
+	import flash.text.engine.TabAlignment;
+	import flash.utils.getQualifiedClassName;
+	import flashx.textLayout.tlf_internal;
+	import flashx.textLayout.formats.FormatValue;
+	use namespace tlf_internal;
+
+	[ExcludeClass]
+	/** 
+	* @private
+	* Export filter for HTML format. 
+	*/
+	internal class HtmlExporter implements ITextExporter	
+	{
+		private static var _config:ImportExportConfiguration;
+		
+		public function HtmlExporter()
+		{
+			if (!_config)
+			{
+				_config = new ImportExportConfiguration();
+				_config.addIEInfo("P", ParagraphElement, null, exportParagraph, true);
+				_config.addIEInfo("A", LinkElement, null, exportLink, false);
+				_config.addIEInfo("TCY" /* only children exported, so name is irrelevant */, TCYElement, null, exportTCY, false);
+				_config.addIEInfo("SPAN"/* only children exported, so name is irrelevant */, SpanElement, null, exportSpan, false);
+				_config.addIEInfo("IMG", InlineGraphicElement, null, exportImage, false);
+				_config.addIEInfo("TAB" /* exported as a span, so name is irrelevant */, TabElement, null, exportTab, false);
+				_config.addIEInfo("BR", BreakElement, null, exportBreak, false);
+
+			}
+		}
+		 
+		/** Export text content
+		 * @param source	the text to export
+		 * @param conversionType 	what type to return
+		 * @return Object	the exported content
+		 */
+		public function export(source:TextFlow, conversionType:String):Object
+		{
+			if (conversionType == ConversionType.STRING_TYPE)
+				return exportToString(source);
+			else if (conversionType == ConversionType.XML_TYPE)
+				return exportToXML(source);
+			return null;
+		}
+		
+		/** Export text content as a string
+		 * @param source	the text to export
+		 * @return String	the exported content
+		 */
+		private function exportToString(textFlow:TextFlow):String
+		{
+			var result:String;
+			// We do some careful type casting here so that leading and trailing spaces in the XML don't
+			// get dropped when it is converted to a string
+			var originalSettings:Object = XML.settings();
+			try
+			{
+				XML.ignoreProcessingInstructions = false;		
+				XML.ignoreWhitespace = false;
+				XML.prettyPrinting = false;
+				result = exportToXML(textFlow).toXMLString();
+				XML.setSettings(originalSettings);
+			}
+			catch(e:Error)
+			{
+				XML.setSettings(originalSettings);
+				throw(e);
+			}		
+			return result;
+		}
+		
+		/** Export text content of a TextFlow into HTML format.
+		 * @param source	the text to export
+		 * @return XML	the exported content
+		 */
+		private function exportToXML(textFlow:TextFlow) : XML
+		{
+			var xml:XML = <BODY/>;
+			
+			var firstLeaf:FlowLeafElement = textFlow.getFirstLeaf();
+			if (firstLeaf)
+			{
+				var para:ParagraphElement = firstLeaf.getParagraph();	
+				var lastPara:ParagraphElement = textFlow.getLastLeaf().getParagraph();
+	
+				for (;;)
+				{
+					xml.appendChild(exportElement(para));
+					if (para == lastPara)
+						break;
+						
+					para = textFlow.findLeaf(para.getAbsoluteStart() + para.textLength).getParagraph();
+				}
+			}
+			
+			var html:XML = <HTML/>;
+			html.appendChild(xml);
+			
+			return html;
+		}
+		
+		/** Export a paragraph
+		 * @param name name for the XML element
+		 * @return XML	the populated XML element
+		 */
+		private function exportParagraph(name:String, para:ParagraphElement):XML
+		{
+			// Exported as a <P/>
+			// Some paragraph-level formats (such as textAlign) are exported as attributes of <P/>, 
+			// Others (such as textIndent) are exported as attributes of the <TEXTFORMAT/> parent of <P/>
+			// Some character-level formats (such as fontSize) are exported as attributes of the <FONT/> child of <P/>
+			// Children of the ParagraphElement are nested inside the <FONT/>
+			
+			var xml:XML = <{name}/>;
+			
+			var fontXML:XML = exportFont(para.computedFormat);
+			CONFIG::debug { assert(fontXML != null, "Expect exportFont to return non-null xml if second parameter (ifDifferentFromFormat) is null"); }
+			exportChildren (fontXML, para);
+			nest(xml, fontXML);
+			
+			return exportParagraphFormat(xml, para);
+		}
+		
+		/** Export a link
+		 * @param name name for the XML element
+		 * @return XML	the populated XML element
+		 */
+		private function exportLink(name:String, link:LinkElement):Object
+		{
+			// Exported as an <A/> with HREF and TARGET attributes
+			// Children of the LinkElement are nested inside the <A/>
+			// If the computed values of certain character-level formats differ from the corresponding computed values for the
+			// containing paragraph, these are exported as attributes of a <FONT/> which (in this case) parents the <A/>.
+			
+			var xml:XML = <{name}/>;
+			
+			if (link.href)
+				xml.@HREF= link.href;
+			if (link.target)
+				xml.@TARGET = link.target;
+			else
+			{
+				// TextField uses _self as the default target  
+				// while TLF uses null (funcionally identical to _blank). Account for this difference.
+				xml.@TARGET = "_blank";
+			}
+						
+			exportChildren(xml, link);
+			
+			var format:ITextLayoutFormat = link.computedFormat;
+			var ifDifferentFromFormat:ITextLayoutFormat = link.getParagraph().computedFormat;
+			
+			var font:XML = exportFont(format, ifDifferentFromFormat);	
+			return font ? nest(font, xml) : xml;
+		}
+		
+		/** Export a tcy element
+		 * @param name ignored
+		 * @return XMLList the exported children
+		 */
+		private function exportTCY(name:String, tcy:TCYElement):XMLList
+		{
+			// Only children are exported
+			
+			var xml:XML = <{name}/>;
+			exportChildren(xml, tcy);
+			return xml.children();
+		}
+		
+		static private const brRegEx:RegExp = /\u2028/;
+		
+		/** Gets the xml element used to represent a character in the export format
+		 */
+		static private function getSpanTextReplacementXML(ch:String):XML
+		{
+			CONFIG::debug {assert(ch == '\u2028', "Did not recognize character to be replaced with XML"); }
+			return <BR/>;
+		}
+		
+		/** Export a span
+		 * @param name name for the XML element
+		 * @return XML	the populated XML element
+		 */
+		private function exportSpan(name:String, span:SpanElement):Object
+		{
+			// Span text is exported as a text node (or text nodes delimited by <BR/> elements for any occurences of U+2028)
+			// These text nodes and <BR/> elements are optionally nested in formatting elements
+			var xml:XML  = <{name}/>; 
+			BaseTextLayoutExporter.exportSpanText(xml, span, brRegEx, getSpanTextReplacementXML);
+			
+			// for brevity, do not export attribute-less <span> tags; export just their children
+			var children:Object = xml.children();
+				
+			// Workaround for bug 1852072 : extraneous tags can appear around a string child added after an XML element 
+			if (children.length() == 1 && children[0].nodeKind() == "text")
+				children = xml.text()[0];
+					
+			return exportSpanFormat (children, span);
+		}
+		
+		/** Export an inline graphic
+		 * @param name name for the XML element
+		 * @return XML	the populated XML element
+		 */
+		private function exportImage(name:String, image:InlineGraphicElement):XML
+		{
+			// Exported as an <IMG/> with SRC, WIDTH, HEIGHT and ALIGN attributes
+			
+			var xml:XML = <{name}/>;
+			if (image.id)
+				xml.@ID = image.id;
+			if (image.source)
+				xml.@SRC = image.source;
+			if (image.width !== undefined && image.width != FormatValue.AUTO) 
+				xml.@WIDTH = image.width;
+			// xml.@WIDTH = image.actualWidth;
+			if (image.height !== undefined && image.height != FormatValue.AUTO) 
+				xml.@HEIGHT = image.height;
+			// xml.@HEIGHT = image.actualHeight;	
+			if (image.float != Float.NONE)
+				xml.@ALIGN = image.float;
+			return xml;
+		}
+	
+		/** Export a break
+		 * Is this ever called: BreakElements are either merged with adjacent spans or become spans? 
+		 * @param name name for the XML element
+		 * @return XML	the populated XML element
+		 */		
+		private function exportBreak(name:String, breakElement:BreakElement):XML
+		{
+			return <{name}/>;
+		}
+		
+		/** Export a tab
+		 * Is this ever called: TabElements are either merged with adjacent spans or become spans? 
+		 * @param name ignored
+		 * @return XML	the populated XML element
+		 */	
+		private function exportTab(name:String, tabElement:TabElement):Object
+		{
+			// Export as a span
+			return exportSpan(name, tabElement);
+		}
+		
+		private function exportTextFormatAttribute (textFormatXML:XML, attrName:String, attrVal:*):XML
+		{
+			if (!textFormatXML)
+				textFormatXML = <TEXTFORMAT/>;
+				
+			textFormatXML.@[attrName] = attrVal;
+			
+			return textFormatXML;	
+		}
+		
+		/** Exports the paragraph-level format for a paragraph  
+		 * @param xml xml to decorate with attributes or add nest in formatting elements
+		 * @para the paragraph
+		 * @return XML	the outermost XML element after exporting 
+		 */	
+		private function exportParagraphFormat(xml:XML, para:ParagraphElement):XML
+		{	
+			var paraFormat:ITextLayoutFormat = para.computedFormat;
+			
+			var textAlignment:String;
+			switch(paraFormat.textAlign)
+			{
+				case TextAlign.START:
+					textAlignment = (paraFormat.direction == Direction.LTR) ? TextAlign.LEFT : TextAlign.RIGHT;
+					break;
+				case TextAlign.END:
+					textAlignment = (paraFormat.direction == Direction.LTR) ? TextAlign.RIGHT : TextAlign.LEFT;
+					break;
+				default:
+					textAlignment = paraFormat.textAlign;
+			}
+			xml.@ALIGN = textAlignment;
+					
+			var textFormat:XML;
+			
+			if (paraFormat.paragraphStartIndent != 0)
+				textFormat = exportTextFormatAttribute (textFormat, paraFormat.direction == Direction.LTR ? "LEFTMARGIN" : "RIGHTMARGIN", paraFormat.paragraphStartIndent);
+			
+			if (paraFormat.paragraphEndIndent != 0)
+				 textFormat = exportTextFormatAttribute (textFormat, paraFormat.direction == Direction.LTR ? "RIGHTMARGIN" : "LEFTMARGIN", paraFormat.paragraphEndIndent);
+			
+			if (paraFormat.textIndent != 0)
+				textFormat = exportTextFormatAttribute(textFormat, "INDENT", paraFormat.textIndent);
+				
+			if (paraFormat.leadingModel == LeadingModel.APPROXIMATE_TEXT_FIELD)
+			{
+				var firstLeaf:FlowLeafElement = para.getFirstLeaf();
+				if (firstLeaf)
+				{
+					var lineHeight:Number = TextLayoutFormat.lineHeightProperty.computeActualPropertyValue(firstLeaf.computedFormat.lineHeight,firstLeaf.getEffectiveFontSize());
+					if (lineHeight != 0)
+						textFormat = exportTextFormatAttribute(textFormat, "LEADING", lineHeight);
+				}
+			}
+			
+			var tabStops:Array = paraFormat.tabStops;
+			if (tabStops)
+			{
+				var tabStopsString:String = "";
+				for each (var tabStop:TabStopFormat in tabStops)
+				{
+					if (tabStop.alignment != TabAlignment.START)
+						break;
+					
+					if (tabStopsString.length)
+						tabStopsString += ", ";
+					
+					tabStopsString += tabStop.position;
+				}
+				
+				if (tabStopsString.length)
+					textFormat = exportTextFormatAttribute(textFormat, "TABSTOPS", tabStopsString);
+			}
+			
+			return textFormat ? nest(textFormat, xml) : xml;
+		}
+		
+		/** Exports the character-level format for a span  
+		 * @param xml xml/xmlList to nest in formatting elements
+		 * @span the span
+		 * @return XML	the outermost XML element after exporting 
+		 */	
+		private function exportSpanFormat(xml:Object, span:SpanElement):Object
+		{
+			// These are optionally nested in a <FONT/> with appopriate attributes ,			 
+			
+			var format:ITextLayoutFormat = span.computedFormat;
+			var outerElement:Object = xml;
+			
+			// Nest in <B/>, <I/>, or <U/> if applicable
+			if (format.textDecoration.toString() == flashx.textLayout.formats.TextDecoration.UNDERLINE)
+				outerElement = nest (<U/>, outerElement);
+			if (format.fontStyle.toString() == flash.text.engine.FontPosture.ITALIC)
+				outerElement = nest (<I/>, outerElement);
+			if (format.fontWeight.toString() == flash.text.engine.FontWeight.BOLD)
+				outerElement = nest (<B/>, outerElement);
+				
+			// Nest in <FONT/> if the computed values of certain character-level formats 
+			// differ from the corresponding computed values for the containing parent that's exported
+			// A span can be contained in a TCY, link, or paragraph. Of these, TCY is not exported, so only
+			// check link and paragraph.
+			var exportedParent:FlowElement = span.getParentByType(LinkElement);
+			if (!exportedParent)
+				exportedParent = span.getParagraph();
+	
+			var font:XML = exportFont(format, exportedParent.computedFormat);	
+			if (font)
+				outerElement = nest(font, outerElement);	
+
+			return outerElement;			   	
+		}	
+		
+		private function exportFontAttribute (fontXML:XML, attrName:String, attrVal:*):XML
+		{
+			if (!fontXML)
+				fontXML = <FONT/>;
+				
+			fontXML.@[attrName] = attrVal;
+			
+			return fontXML;	
+		}
+		
+		/**  
+		 * Exports certain character level formats as a <FONT/> with appropriate attributes
+		 * @param format format to export
+		 * @param ifDifferentFromFormat if non-null, a value in format is exported only if it differs from the corresponding value in ifDifferentFromFormat
+		 * @return XML	the populated XML element
+		 */	
+		private function exportFont(format:ITextLayoutFormat, ifDifferentFromFormat:ITextLayoutFormat=null):XML
+		{
+			var font:XML;
+			if (!ifDifferentFromFormat || ifDifferentFromFormat.fontFamily != format.fontFamily)
+				font = exportFontAttribute(font, "FACE", format.fontFamily);
+			if (!ifDifferentFromFormat || ifDifferentFromFormat.fontSize != format.fontSize)
+				font = exportFontAttribute(font, "SIZE", format.fontSize);
+			if (!ifDifferentFromFormat || ifDifferentFromFormat.color != format.color)
+			{
+				var rgb:String = format.color.toString(16);
+				while (rgb.length < 6) 
+					rgb = "0" + rgb; // pad with leading zeros
+				rgb = "#" + rgb
+				font = exportFontAttribute(font, "COLOR", rgb);
+			}
+			if (!ifDifferentFromFormat || ifDifferentFromFormat.trackingRight != format.trackingRight)
+				font = exportFontAttribute(font, "LETTERSPACING", format.trackingRight); 
+			if (!ifDifferentFromFormat || ifDifferentFromFormat.kerning != format.kerning)
+				font = exportFontAttribute(font, "KERNING", format.kerning == Kerning.OFF ? "0" : "1");
+						
+			return font;				
+		}
+			
+		/** Exports the flow element by finding the appropriate exporter
+		 * @param flowElement	Element to export
+		 * @return Object	XML/XMLList for the flowElement
+		 */
+		private function exportElement(flowElement:FlowElement):Object
+		{
+			var className:String = flash.utils.getQualifiedClassName(flowElement);
+			var info:FlowElementInfo = _config.lookupByClass(className);
+			if (info != null)
+				return info.exporter(_config.lookupName(className), flowElement);
+			return null;
+		}
+		
+		/** Exports the children of a flow group element
+		 * @param xml XML to append children to
+		 * @param flowGroupElement	the flow group element
+		 */
+		private function exportChildren(xml:XML, flowGroupElement:FlowGroupElement):void
+		{
+			for(var i:int=0; i < flowGroupElement.numChildren; ++i)
+			{
+				xml.appendChild(exportElement(flowGroupElement.getChildAt(i)));	
+			}
+		}
+		
+		/** Helper to establish a parent-child relationship between two xml elements
+		 * and return the parent
+		 * @param parent the intended parent
+		 * @param children the intended children (XML or XMLList)
+		 * @return the parent
+		 */
+		private function nest (parent:XML, children:Object):XML
+		{
+			parent.setChildren(children);
+			return parent;
+		}
+		
+ 	}
+}
\ No newline at end of file
diff --git a/textLayout_conversion/src/flashx/textLayout/conversion/HtmlImporter.as b/textLayout_conversion/src/flashx/textLayout/conversion/HtmlImporter.as
new file mode 100755
index 0000000..bbd00d9
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/conversion/HtmlImporter.as
@@ -0,0 +1,1151 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.conversion 
+{
+	import flash.text.engine.Kerning;
+	import flash.utils.Dictionary;
+	
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.BreakElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.GlobalSettings;
+	import flashx.textLayout.elements.IConfiguration;
+	import flashx.textLayout.elements.InlineGraphicElement;
+	import flashx.textLayout.elements.LinkElement;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.SpanElement;
+	import flashx.textLayout.elements.TabElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.LeadingModel;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormatValueHolder;
+	import flashx.textLayout.property.Property;
+	import flashx.textLayout.property.StringProperty;
+	import flashx.textLayout.tlf_internal;
+	use namespace tlf_internal;
+	
+	[ExcludeClass]
+	/** 
+	 * @private
+	 * HtmlImporter converts from HTML to TextLayout data structures
+	 */ 	
+	internal class HtmlImporter extends BaseTextLayoutImporter
+	{
+		// TLF formats to which <font/> attributes map directly
+		static internal var _fontDescription:Object = {
+			color:TextLayoutFormat.colorProperty,
+			trackingRight:TextLayoutFormat.trackingRightProperty,
+			fontFamily:TextLayoutFormat.fontFamilyProperty
+		};
+		
+		// <font/> attributes that require custom logic for mapping to TLF formats
+		static internal const _fontMiscDescription:Object = {
+			size	: new StringProperty("size", null, false, null),
+			kerning	: new StringProperty("kerning", null, false, null)
+		};
+				
+		// TLF formats to which <textformat/> attributes map directly		
+		static internal var _textFormatDescription:Object = {
+			paragraphStartIndent:TextLayoutFormat.paragraphStartIndentProperty,
+			paragraphEndIndent:TextLayoutFormat.paragraphEndIndentProperty,
+			textIndent:TextLayoutFormat.textIndentProperty,
+			lineHeight:TextLayoutFormat.lineHeightProperty,
+			tabStops:TextLayoutFormat.tabStopsProperty
+		};	
+		
+		// <textformat/> attributes that require custom logic for mapping to TLF formats
+		static internal const _textFormatMiscDescription:Object = {
+			blockIndent	: new StringProperty("blockIndent", null, false, null)
+		};
+		
+		static internal var _paragraphFormatDescription:Object = {
+			textAlign:TextLayoutFormat.textAlignProperty
+		};
+		
+		static internal const _linkHrefDescription:Object = {
+			href	: new StringProperty("href",   null, false, null)
+		};
+		
+		static internal const _linkTargetDescription:Object = {
+			target	: new StringProperty("target", null, false, null)
+		};
+		
+		static internal const _imageDescription:Object = {
+			height	: InlineGraphicElement.heightPropertyDefinition,
+			width	: InlineGraphicElement.widthPropertyDefinition,
+			src		: new StringProperty("src", null, false, null)};
+		
+		// Separate description because id value is case-sensitive unlike others
+		static internal const _imageMiscDescription:Object = {
+			id		: new StringProperty("id", null, false, null)};
+			
+		static internal const _classDescription:Object =
+		{
+			// A property named 'class' confuses the compiler. 
+			// class	: new StringProperty("class",   null, false, null)
+			// So, we initialize _classDescription in the constructor 
+		};
+		
+		// For some reason, the following can't be initialized here
+		static private var _fontImporter:FontImporter;
+		static private var _fontMiscImporter:CaseInsensitiveTLFFormatImporter;
+		static private var _textFormatImporter:TextFormatImporter;
+		static private var _textFormatMiscImporter:CaseInsensitiveTLFFormatImporter;		
+		static private var _paragraphFormatImporter:HtmlCustomParaFormatImporter;
+		static private var _linkHrefImporter:CaseInsensitiveTLFFormatImporter;
+		static private var _linkTargetImporter:CaseInsensitiveTLFFormatImporter;
+		static private var _ilgFormatImporter:CaseInsensitiveTLFFormatImporter;
+		static private var _ilgMiscFormatImporter:CaseInsensitiveTLFFormatImporter;
+		static private var _classImporter:CaseInsensitiveTLFFormatImporter;
+		
+		// Formats specified by formatting elements in the ancestry of the element being parsed currently 
+		static private var _activeFormat:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder(); // to be applied to all flow elements
+		static private var _activeParaFormat:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder(); // to be applied to paras only
+		static private var _activeImpliedParaFormat:TextLayoutFormatValueHolder = null;
+		
+		// The basis for relative font size calculation
+		static private var _baseFontSize:Number; 
+		
+		/** Constructor */
+		public function HtmlImporter(textFlowConfiguration:IConfiguration)
+		{
+			super(textFlowConfiguration, null, createConfig());
+		}
+		
+		private static function createConfig():ImportExportConfiguration
+		{
+			var config:ImportExportConfiguration = new ImportExportConfiguration();
+			
+			// inherited	
+			config.addIEInfo("br", BreakElement, BaseTextLayoutImporter.parseBreak, null, false); 
+ 			
+ 			config.addIEInfo("p", ParagraphElement, HtmlImporter.parsePara, null, true);
+ 			config.addIEInfo("span", SpanElement, HtmlImporter.parseSpan, null, false);
+ 			config.addIEInfo("a", LinkElement, HtmlImporter.parseLink, null, false);
+			config.addIEInfo("img", InlineGraphicElement, HtmlImporter.parseInlineGraphic, null, false);
+		
+			// formatting elements
+			config.addIEInfo("font", null, HtmlImporter.parseFont, null, false);
+			config.addIEInfo("textformat", null, HtmlImporter.parseTextFormat, null, false);
+			config.addIEInfo("u", null, HtmlImporter.parseUnderline, null, false);
+			config.addIEInfo("i", null, HtmlImporter.parseItalic, null, false);
+			config.addIEInfo("b", null, HtmlImporter.parseBold, null, false);
+			
+			// create these here - can't be done above
+			if (_classDescription["class"] === undefined)
+			{
+				_classDescription["class"] = new StringProperty("class", null, false, null);
+				_paragraphFormatImporter = new HtmlCustomParaFormatImporter(TextLayoutFormat, _paragraphFormatDescription);
+				_textFormatImporter = new TextFormatImporter(TextLayoutFormat, _textFormatDescription);
+				_fontImporter = new FontImporter(TextLayoutFormat, _fontDescription);
+				_fontMiscImporter = new CaseInsensitiveTLFFormatImporter(Dictionary, _fontMiscDescription);		
+				_textFormatMiscImporter = new CaseInsensitiveTLFFormatImporter(Dictionary, _textFormatMiscDescription);
+				_linkHrefImporter = new CaseInsensitiveTLFFormatImporter(Dictionary,_linkHrefDescription,false);
+				_linkTargetImporter = new CaseInsensitiveTLFFormatImporter(Dictionary,_linkTargetDescription);
+				_ilgFormatImporter = new CaseInsensitiveTLFFormatImporter(Dictionary,_imageDescription);
+				_ilgMiscFormatImporter = new CaseInsensitiveTLFFormatImporter(Dictionary,_imageMiscDescription, false);
+				_classImporter = new CaseInsensitiveTLFFormatImporter(Dictionary,_classDescription);
+			}
+			return config;
+		}
+		
+		
+		/** Parse and convert input data
+		 * 
+		 * @param source - the HTML string
+		 */
+		protected override function importFromString(source:String):TextFlow
+		{	
+			// Use toXML rather than the XML constructor because the latter expects
+			// well-formed XML, which source may not be 
+			var xml:XML = toXML(source);
+			return xml ? importFromXML(xml) : null;
+		}
+
+		/** Parse and convert input XML data
+		 */
+		protected override function importFromXML(xmlSource:XML):TextFlow
+		{
+			var textFlow:TextFlow = new TextFlow(_textFlowConfiguration);
+			
+			// Use font size specified in _textFlowConfiguration.textFlowInitialFormat as the base font size
+			// If not specified, use 12
+			_baseFontSize = textFlow.fontSize === undefined ? 12 : textFlow.fontSize;
+			
+			// Unlike other markup formats, the HTML format for TLF does not have a fixed root XML element.
+			// <html> and <body> are optional, and flow elements may or may not be encapsulated in formatting 
+			// elements like <i> or <textformat>. Use parseObject to handle any (expected) root element.
+			parseObject(xmlSource.name().localName, xmlSource, textFlow);
+			
+			// If the last para is implied, there is nothing following it that'll trigger a reset. 
+			// For most importers, this is fine (clear will eventually reset it), but the HTML importer has 
+			// some special behavior associated with the reset (replacing BreakElements with para splits).
+			// Explicitly do so now (must happen before normalization)
+			resetImpliedPara();
+			
+			CONFIG::debug { textFlow.debugCheckNormalizeAll() ; }
+			textFlow.normalize();
+			textFlow.applyWhiteSpaceCollapse();
+			
+			return textFlow;
+		}		
+
+		protected override function clear():void
+		{
+			// Reset active formats and base font size
+			_activeParaFormat.coreStyles = null;
+			_activeFormat.coreStyles = null;
+			super.clear();
+		}
+		
+		tlf_internal override function createImpliedParagraph():ParagraphElement
+		{
+			var rslt:ParagraphElement;
+			var savedActiveFormat:TextLayoutFormatValueHolder = _activeFormat;
+			if (_activeImpliedParaFormat)
+				_activeFormat = _activeImpliedParaFormat;
+			try
+			{
+				rslt = super.createImpliedParagraph();
+			}
+			finally
+			{
+				_activeFormat = savedActiveFormat;
+			}
+			return rslt;
+		}
+
+		public override function createParagraphFromXML(xmlToParse:XML):ParagraphElement
+		{
+			var paraElem:ParagraphElement = new ParagraphElement();
+				
+			// Parse xml attributes for paragraph format
+			var formatImporters:Array = [_paragraphFormatImporter, _classImporter];
+			parseAttributes(xmlToParse, formatImporters);
+			var paragraphFormat:TextLayoutFormat = new TextLayoutFormat(_paragraphFormatImporter.result as ITextLayoutFormat);
+			
+			// Apply paragraph format inherited from formatting elements
+			if (_activeParaFormat)
+				paragraphFormat.apply(_activeParaFormat);
+			if (_activeFormat)
+				paragraphFormat.apply(_activeFormat);
+			
+			// A <FONT/> that is the only child of a <P/> specifies formats that apply to the paragraph itself
+			// Otherwise (i.e., if it has siblings), the formats apply to the elements nested within the <FONT/>
+			// Check for the former case here
+			var fontFormattingElement:XML = getSingleFontChild (xmlToParse);
+			if (fontFormattingElement)
+				paragraphFormat.apply(parseFontAttributes(fontFormattingElement));
+				
+			if (paragraphFormat.lineHeight !== undefined)
+				paragraphFormat.leadingModel = LeadingModel.APPROXIMATE_TEXT_FIELD;
+			
+			paraElem.format = paragraphFormat;
+			
+			// Use the value of the 'class' attribute (if present) as styleName
+			paraElem.styleName =  _classImporter.getFormatValue("class"); 
+					
+			return paraElem;
+		}
+				
+		/** Parse the supplied XML into a paragraph. Parse the <p/> element and its children.
+		 * 
+		 * @param importFilter	parser object
+		 * @param xmlToParse	content to parse
+		 * @param parent 		the parent for the new content
+		 */
+		static public function parsePara(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{
+			var paraElem:ParagraphElement = (importFilter as HtmlImporter).createParagraphFromXML(xmlToParse);
+			
+			if (importFilter.addChild(parent, paraElem))
+			{
+				// Parse children, but if there is only one child, a <FONT/>, skip to *its* children.
+				// That's because the single <FONT/> chuld has already been parsed in createParagraphFromXML.
+				var fontFormattingElement:XML = getSingleFontChild (xmlToParse);
+				parseChildrenUnderNewActiveFormat (importFilter, fontFormattingElement ? fontFormattingElement : xmlToParse, paraElem, _activeFormat, null);
+				
+				//if parsing an empty paragraph, create a Span for it.
+				if (paraElem.numChildren == 0)
+					paraElem.addChild(new SpanElement());
+			}
+			
+			// Replace break elements with paragraph splits
+			// This must happen before normalization else BreakElements may merge or become spans
+			replaceBreakElementsWithParaSplits(paraElem);
+		}
+		
+		protected override function onResetImpliedPara(para:ParagraphElement):void
+		{
+			// Replacing break elements with paragraph splits, even for implied paras
+			replaceBreakElementsWithParaSplits (para);
+		}
+		
+		/** If the provided xml has a single child <FONT.../>, get it
+		 */
+		static private function getSingleFontChild (xmlToParse:XML):XML
+		{
+			var children:XMLList = xmlToParse.children();
+			if (children.length() == 1)
+			{
+				var child:XML = children[0];
+				if (child.name().localName.toLowerCase() == "font")
+					return child;
+			}
+			
+			return null;
+		}
+			
+		private function createLinkFromXML(xmlToParse:XML):LinkElement
+		{
+			var linkElem:LinkElement = new LinkElement();
+
+			var formatImporters:Array = [ _linkHrefImporter, _linkTargetImporter ];
+			parseAttributes(xmlToParse, formatImporters);
+			
+			linkElem.href = _linkHrefImporter.getFormatValue("href");
+			linkElem.target = _linkTargetImporter.getFormatValue("target");
+			
+			// Handle difference in defaults between TextField and TLF 
+			// target "_self" vs. null (equivalent to "_blank")
+			if (!linkElem.target)
+				linkElem.target = "_self";
+				
+			//  Apply active format
+			linkElem.format = _activeFormat;
+
+			return linkElem;
+		}
+		
+		/** Parse the supplied XML into a LinkElement. Parse the <a/> element and its children.
+		 * 
+		 * @param importFilter	parser object
+		 * @param xmlToParse	content to parse
+		 * @param parent 		the parent for the new content
+		 */
+		static public function parseLink(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{
+			var linkElem:LinkElement = HtmlImporter(importFilter).createLinkFromXML(xmlToParse);
+			
+			if (importFilter.addChild(parent, linkElem))
+			{
+				parseChildrenUnderNewActiveFormat (importFilter, xmlToParse, linkElem, _activeFormat, null);
+				
+				// If parsing an empty link, create a Span for it.
+				if (linkElem.numChildren == 0)
+					linkElem.addChild(new SpanElement());
+			}
+		}	
+		
+		/** Static method for constructing a span from XML. Parse the <span> ... </span> tag. 
+		 * Insert the new content into its parent
+		 * Note: Differs from BaseTextLayoutImporter.parseSpan in that it allows nested <span/> elements. 
+		 * 
+		 * @param importFilter	parser object
+		 * @param xmlToParse	content to parse
+		 * @param parent 		the parent for the new content
+		 */
+		static public function parseSpan(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{
+			var firstSpan:SpanElement = new SpanElement();
+			
+			// Use the value of the 'class' attribute (if present) as styleName
+			var formatImporters:Array = [_classImporter];
+			importFilter.parseAttributes(xmlToParse,formatImporters);
+			firstSpan.styleName = _classImporter.getFormatValue("class");
+			
+			// Apply active format
+			firstSpan.format = _activeFormat;
+			
+			var elemList:XMLList = xmlToParse[0].children();
+			if(elemList.length() == 0)
+			{
+				// Empty span, but may have formatting, so don't strip it out. 
+				// Note: the normalizer may yet strip it out if it is not the last child, but that's the normalizer's business.
+				importFilter.addChild(parent, firstSpan); 
+				return;
+			}
+	
+			for each (var child:XML in elemList) 
+			{
+				var elemName:String = child.name() ? child.name().localName : null;
+					
+				if (elemName == null) // span text
+				{
+					if (firstSpan.parent == null)	// hasn't been used yet
+					{
+						firstSpan.text = child.toString();
+						importFilter.addChild(parent, firstSpan);
+					}
+					else
+					{
+						var s:SpanElement = new SpanElement();
+						copyAllStyleProps(s,firstSpan);
+						s.text = child.toString();
+						importFilter.addChild(parent, s);
+					}
+				}
+				else 
+				{
+					// Anything else: will become siblings of the spans that are (or will be) created for text nodes
+					// (assuming that's valid). For example <span class="A">A quick <span class="B">fox</span></span>
+					// is treated like <span class="A">A quick </span><span class="B">fox</span>. Consequently, any formatting
+					// associated with class "A" will not apply to "fox". This is a shortcoming in the TLF object model: 
+					// SpanElements can't nest.
+					importFilter.parseObject(elemName, child, parent);
+				}
+			}
+		} 
+	
+		private function createInlineGraphicFromXML(xmlToParse:XML):InlineGraphicElement
+		{				
+			var imgElem:InlineGraphicElement = new InlineGraphicElement();
+
+			var formatImporters:Array = [_ilgFormatImporter, _ilgMiscFormatImporter];	
+			parseAttributes(xmlToParse,formatImporters);
+			
+			var source:String = _ilgFormatImporter.getFormatValue("src");
+			imgElem.source = source;
+				
+			// if not defined then let InlineGraphic set its own default
+			imgElem.height = InlineGraphicElement.heightPropertyDefinition.setHelper(imgElem.height,_ilgFormatImporter.getFormatValue("height"));
+			imgElem.width  = InlineGraphicElement.heightPropertyDefinition.setHelper(imgElem.width,_ilgFormatImporter.getFormatValue("width"));
+				
+			/* Not currently supported
+			var floatVal:String = _ilgFormatImporter.getFormatValue("align");
+			// Handle difference in defaults between TextField and TLF 
+			// float "left" vs. "none"
+			imgElem.float = floatVal ? floatVal : Float.LEFT;
+			*/
+			
+			var id:String = _ilgMiscFormatImporter.getFormatValue("id");
+			imgElem.id = id;
+			
+			//  Apply active format
+			imgElem.format = _activeFormat;
+			
+			return imgElem;
+		}
+
+		/** Parse the supplied XML into an InlineGraphicElement. Parse the <img/> element.
+		 * 
+		 * @param importFilter	parser object
+		 * @param xmlToParse	content to parse
+		 * @param parent 		the parent for the new content
+		 */
+		static public function parseInlineGraphic(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{
+			var ilg:InlineGraphicElement = HtmlImporter(importFilter).createInlineGraphicFromXML(xmlToParse);
+			importFilter.addChild(parent, ilg);
+		}
+		
+		public override function createTabFromXML(xmlToParse:XML):TabElement
+		{
+			return null; // no tabs in HTML
+		}
+			
+		/** Parse the attributes of the <Font/> formatting element and returns the corresponding TLF format
+		 */
+		private function parseFontAttributes(xmlToParse:XML):ITextLayoutFormat
+		{
+			var formatImporters:Array = [_fontImporter, _fontMiscImporter];
+			parseAttributes(xmlToParse, formatImporters);
+			
+			var newFormat:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder(_fontImporter.result as ITextLayoutFormat);
+			
+			var kerning:String = _fontMiscImporter.getFormatValue("kerning");
+			if (kerning)
+			{
+				var kerningVal:Number = Number(kerning);
+				newFormat.kerning = kerningVal == 0 ? Kerning.OFF : Kerning.AUTO;
+			}
+			
+			var size:String = _fontMiscImporter.getFormatValue("size");
+			if (size)
+			{
+				var sizeVal:Number = TextLayoutFormat.fontSizeProperty.setHelper(NaN, size);
+				if (!isNaN(sizeVal))
+				{
+					if (size.search(/\s*(-|\+)/) != -1) // leading whitespace followed by + or -
+						sizeVal += _baseFontSize;		// implies relative font sizes
+					newFormat.fontSize = sizeVal;
+				}
+			}
+			
+			return newFormat;
+		}
+		
+		/** Parse the <Font/> formatting element
+		 * Calculates the new format to apply to _activeFormat and continues parsing down the hierarchy
+		 */
+		static public function parseFont(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{
+			var newFormat:ITextLayoutFormat = (importFilter as HtmlImporter).parseFontAttributes (xmlToParse);
+			parseChildrenUnderNewActiveFormatWithImpliedParaFormat(importFilter, xmlToParse, parent, newFormat);
+		}
+		
+		/** Parse the <TextFormat> formatting element
+		 * Calculates the new format to apply to _activeParaFormat and continues parsing down the hierarchy
+		 */
+		static public function parseTextFormat(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{	
+			var formatImporters:Array = [_textFormatImporter, _textFormatMiscImporter];
+			importFilter.parseAttributes(xmlToParse, formatImporters);
+			
+			var newFormat:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder(_textFormatImporter.result as ITextLayoutFormat);
+			
+			var blockIndent:String = _textFormatMiscImporter.getFormatValue("blockIndent");
+			if (blockIndent)
+			{
+				// TODO: Nested <TextFormat/>?
+				var blockIndentVal:Number = TextLayoutFormat.paragraphStartIndentProperty.setHelper(NaN, blockIndent);
+				if (!isNaN(blockIndentVal))
+					newFormat.paragraphStartIndent = newFormat.paragraphStartIndent === undefined ? blockIndentVal : newFormat.paragraphStartIndent + blockIndentVal;
+			}
+
+			parseChildrenUnderNewActiveFormat (importFilter, xmlToParse, parent, _activeParaFormat, newFormat, true);
+		}
+		
+		/** Parse the <b> formatting element
+		 * Calculates the new format to apply to _activeFormat and continues parsing down the hierarchy
+		 */
+		static public function parseBold(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{	
+			var newFormat:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder();
+			newFormat.fontWeight = flash.text.engine.FontWeight.BOLD;
+			
+			parseChildrenUnderNewActiveFormatWithImpliedParaFormat (importFilter, xmlToParse, parent, newFormat);
+		}
+		
+		/** Parse the <i> formatting element
+		 * Calculates the new format to apply to _activeFormat and continues parsing down the hierarchy
+		 */
+		static public function parseItalic(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{	
+			var newFormat:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder();
+			newFormat.fontStyle = flash.text.engine.FontPosture.ITALIC;
+			parseChildrenUnderNewActiveFormatWithImpliedParaFormat (importFilter, xmlToParse, parent, newFormat);
+		}
+		
+		/** Parse the <u> formatting element
+		 * Calculates the new format to apply to _activeFormat and continues parsing down the hierarchy
+		 */
+		static public function parseUnderline(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{	
+			var newFormat:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder();
+			newFormat.textDecoration = flashx.textLayout.formats.TextDecoration.UNDERLINE;
+			parseChildrenUnderNewActiveFormatWithImpliedParaFormat(importFilter, xmlToParse, parent, newFormat);
+
+		}
+		
+		static private function parseChildrenUnderNewActiveFormatWithImpliedParaFormat(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement, newFormat:ITextLayoutFormat):void
+		{
+			var oldActiveImpliedParaFormat:TextLayoutFormatValueHolder = _activeImpliedParaFormat;
+			if (_activeImpliedParaFormat == null)
+				_activeImpliedParaFormat = new TextLayoutFormatValueHolder(_activeFormat);
+			try
+			{
+				parseChildrenUnderNewActiveFormat(importFilter, xmlToParse, parent, _activeFormat, newFormat, true);
+			}
+			finally
+			{
+				_activeImpliedParaFormat = oldActiveImpliedParaFormat;
+			}
+		}
+		
+		/** Updates the current active format and base font size as specified, parses children, and restores the active format and base font size
+		 * There are two different use cases for this method:
+		 * - Parsing children of a formatting XML element like <Font/> or <TextFormat/>. In this case, the TLF format corresponding to the formatting element
+		 * (newFormat) is applied to the currently active format (_activeFormat in the case of <Font/> and _activeParaFormat in the case of <TextFormat/>). 
+		 * Children of the formatting element are parsed under this new active format.
+		 * - Parsing children of a flow XML element like <P/> or <A/>. In this case, newFormat is null and the currently active format (_activeFormat) is reset.
+		 * Children of the flow element are parsed under this newly reset format. This is to avoid redundancy (the format is already applied to the flow element). 
+		 * 
+		 * @param importFilter	parser object
+		 * @param xmlToParse	content to parse
+		 * @param parent 		the parent for the parsed children
+		 * @param currFormat	the active format (_activeFormat or _activeParaFormat)
+		 * @param newFormat		the format to apply to currFormat while the children are being parsed. If null, currFormat is to be reset.
+		 * @param chainedParent whether parent actually corresponds to xmlToParse or has been chained (such as when xmlToParse is a formatting element). See BaseTextLayoutImporter.parseFlowGroupElementChildren
+		 */
+		static private function parseChildrenUnderNewActiveFormat (importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement, currFormat:TextLayoutFormatValueHolder, newFormat:ITextLayoutFormat, chainedParent:Boolean=false):void
+		{
+			// Remember the current state
+			var restoreBaseFontSize:Number = _baseFontSize;
+			var restoreCoreStyles:Object = Property.shallowCopy(currFormat.coreStyles);
+			
+			if (newFormat)
+			{
+				// Update base font size based on the new format
+				if (newFormat.fontSize !== undefined)
+					_baseFontSize = newFormat.fontSize; 
+					
+				// Apply the new format
+				currFormat.apply(newFormat);
+			}
+			else
+			{
+				// Base font size remains unchanged
+				
+				// Reset the new format
+				currFormat.coreStyles = null;
+			}
+			
+			try
+			{
+				importFilter.parseFlowGroupElementChildren(xmlToParse, parent, null, chainedParent);
+			}
+			finally
+			{
+				// Restore 
+				currFormat.coreStyles = restoreCoreStyles;
+				_baseFontSize = restoreBaseFontSize;
+			}
+		}
+		
+		protected override function handleUnknownAttribute(elementName:String, propertyName:String):void
+		{
+			// A toss-up: report error or ignore? Ignore for now
+			// If we do end up reporting error, we should add exceptions for documented attributes that we don't handle
+			// like align on <img/>
+		}
+		
+		protected override function handleUnknownElement(name:String, xmlToParse:XML, parent:FlowGroupElement):void
+		{
+			// Not an error (it may be a styling element like <h1/>); continue parsing children
+			parseFlowGroupElementChildren (xmlToParse, parent, null, true);
+		}										
+		
+		tlf_internal override function  parseObject(name:String, xmlToParse:XML, parent:FlowGroupElement, exceptionElements:Object=null):void
+		{
+			// override to allow upper case tag names
+			super.parseObject(name.toLowerCase(), xmlToParse, parent, exceptionElements);
+		}
+		
+		protected override function checkNamespace(xmlToParse:XML):Boolean
+		{	
+			/* Ignore namespace */
+			return true;
+		}
+		
+		/** Splits the paragraph wherever a break element occurs and removes the latter
+		 * This is to replicate TextField handling of <br/>: splits the containing paragraph (implied or otherwise)
+		 * The <br/> itself doesn't survive.
+		 */
+		static private function replaceBreakElementsWithParaSplits(para:ParagraphElement):void
+		{
+			// performance: when splitting the paragraph into multiple paragraphs take it out of the TextFlow
+			var paraArray:Array;
+			var paraIndex:int;
+			var paraParent:FlowGroupElement;
+	
+			// Find each BreakElement and split into a new paragraph
+			var elem:FlowLeafElement = para.getFirstLeaf();
+			while (elem)
+			{
+				if (!(elem is BreakElement))
+				{
+					elem = elem.getNextLeaf(para);
+					continue;					
+				}
+				if (!paraArray)
+				{
+					paraArray = [ para ];
+					paraParent = para.parent;
+					paraIndex = paraParent.getChildIndex(para);
+					paraParent.removeChildAt(paraIndex);
+				}
+					
+				// Split the para right after the BreakElement
+				//CONFIG::debug { assert(elem.textLength == 1,"Bad TextLength in BreakElement"); }
+				CONFIG::debug {assert( para.getAbsoluteStart() == 0,"Bad paragraph in replaceBreakElementsWithParaSplits"); }
+				para = para.splitAtPosition(elem.getAbsoluteStart()+elem.textLength) as ParagraphElement;
+				paraArray.push(para);
+					
+				// Remove the BreakElement
+				elem.parent.removeChild(elem);	
+				
+				// point elem to the first leaf of the new paragraph
+				elem = para.getFirstLeaf();
+			}
+			
+			if (paraArray)
+				paraParent.replaceChildren(paraIndex,paraIndex,paraArray);
+		}
+		
+		/** HTML parsing code
+		 *  Uses regular expressions for recognizing constructs like comments, tags etc.
+		 *  and a hand-coded parser to recognize the document structure and covert to well-formed xml
+		 *  TODO-1/16/2009:List caveats
+		 */ 
+		
+		/** Regex for stuff to be stripped: a comment, processing instruction, or a declaration
+		 *
+		 * <!--.*?--> - comment
+		 *   <!-- - start comment
+		 *   .*? - anything (including newline character, thanks to the s flag); the ? prevents a greedy match (which could match a --> later in the string) 
+		 *  --> - end comment
+		 *  
+		 * <\?(".*?"|'.*?'|[^>]+)*> - processing instruction
+		 *   <\? - start processing instruction
+		 *   (".*?"|'.*?'|[^>]+)* - 0 or more of the following (interleaved in any order)
+		 *     ".*?" - anything (including >) so long as it is within double quotes; the ? prevents a greedy match (which could match everything until a later " in the string) 
+		 *     '.*?' - anything (including >) so long as it is within single quotes; the ? prevents a greedy match (which could match everything until a later ' in the string)
+		 *     [^>"']+ - one or more characters other than > (because > ends the processing instruction), " (handled above), ' (handled above) 
+		 *   > - end processing instruction
+		 *
+		 * <!(".*?"|'.*?'|[^>"']+)*> - declaration; 
+		 * TODO-1/15/2009:not sure if a declaration can contain > within quotes. Assuming it can, the regex is  
+		 *  is exactly like processing instruction above except it uses a ! instead of a ?
+		 */
+		private static var stripRegex:RegExp = /<!--.*?-->|<\?(".*?"|'.*?'|[^>"']+)*>|<!(".*?"|'.*?'|[^>"']+)*>/sg;
+						
+		/** Regular expression for an HTML tag
+		 * < - open
+		 *
+		 * (\/?) - start modifier; 0 or 1 occurance of one of /
+		 *
+		 * (\w+) - tag name; 1 or more name characters
+		 *
+		 * ((?:\s+\w+(?:\s*=\s*(?:".*?"|'.*?'|[\w\.]+))?)*) - attributes; 0 or more of the following
+		 *   (?:\s+\w+(?:\s*=\s*(?:".*?"|'.*?'|[\w\.]+))?) - attribute; 1 or more space, followed by 1 or more name characters optionally followed by
+		 *      \s*=\s*(?:".*?"|'.*?'|[\w\.]+) - attribute value assignment; optional space followed by = followed by more optional space followed by one of
+		 *         ".*?" - quoted attribute value (using double quotes); the ? prevents a greedy match (which could match everything until a later " in the string)
+		 *         '.*?' - quoted attribute value (using single quotes); the ? prevents a greedy match ((which could match everything until a later ' in the string)
+		 *         [\w\.]+ - unquoted attribute value; can only contain name characters or a period
+		 *  Note: ?: specifies a non-capturing group (i.e., match won't be recorded or used as a numbered back-reference)
+		 *
+		 * \s* - optional space
+		 *
+		 * (\/?) - end modifer (0 or 1 occurance of /)
+		 *
+		 * > - close*/
+		private static var tagRegex:RegExp = /<(\/?)(\w+)((?:\s+\w+(?:\s*=\s*(?:".*?"|'.*?'|[\w\.]+))?)*)\s*(\/?)>/sg;
+		
+		/** Regular expression for an attribute. Except for grouping differences, this regex is the same as the one that appears in tagRegex
+		 */
+		private static var attrRegex:RegExp = /\s+(\w+)(?:\s*=\s*(".*?"|'.*?'|[\w\.]+))?/sg;
+		
+		/** Wrapper for core HTML parsing code that manages XML settings during the process
+		 */
+		private function toXML(source:String):XML
+		{
+			var xml:XML;
+			
+			var originalSettings:Object = XML.settings();
+			try
+			{
+				XML.ignoreProcessingInstructions = false;		
+				XML.ignoreWhitespace = false;	
+
+				xml = toXMLInternal(source);				
+			}			
+			finally
+			{
+				XML.setSettings(originalSettings);
+			}	
+			
+			return xml;
+		}	
+		
+		/** Convert HTML string to well-formed xml, accounting for the following HTML oddities
+		 * 
+		 * 1) Start tags are optional for some elements.
+		 * Optional start tag not specified</html>
+		 * TextField dialect: This is true for all elements. 
+		 * 
+		 * 2) End tags are optional for some elements. Elements with missing end tags may be implicitly closed by
+		 *    a) start-tag for a peer element
+		 *    <p>p element without end tag; closed by next p start tag
+		 *    <p>closes previous p element with missing end tag</p>
+		 * 
+		 *    b) end-tag for an ancestor element 
+		 * 	  <html><p>p element without end tag; closed by next end tag of an ancestor</html>
+		 *     TextField dialect: This is true for all elements. 
+		 * 
+		 * 3) End tags are forbidden for some elements
+		 * <br> and <br/> are valid, but <br></br> is not
+		 * TextField dialect: Does not apply. 
+		 * 
+		 * 4) Element and attribute names may use any case
+		 * <P ALign="left"></p>
+		 * 
+		 * 5) Attribute values may be unquoted
+		 * <p align=left/>
+		 * 
+		 * 6) Boolean attributed may assume a minimized form
+		 * <p selected/> is equivalent to <p selected="selected"/>
+		 * 
+		 */	
+		private function toXMLInternal(source:String):XML
+		{
+			// Strip out comments, processing instructions and declaratins	
+			source = source.replace(stripRegex, "");
+			
+			// Parse the source, looking for tags and interleaved text content, creating an XML hierarchy in the process.
+			// At any given time, there is a chain of 'open' elements corresponding to unclosed tags, the innermost of which is 
+			// tracked by the currElem. Content (element or text) parsed next is added as a child of currElem.
+			
+			// Root of the XML hierarchy (set to <html/> because the html start tag is optional)
+			// Note that source may contain an html start tag, in which case we'll end up with two such elements
+			// This is not quite correct, but handled by the importer  
+			var root:XML = <html/>; 
+			var currElem:XML = root;  
+			
+			var lastIndex:int = tagRegex.lastIndex = 0;
+			var openElemName:String;
+						
+			do
+			{						
+				var result:Object = tagRegex.exec(source);
+				if (!result)
+				{
+					// No more tags: add text (starting at search index) as a child of the innermost open element and break out
+					appendTextChild (currElem, source.substring(lastIndex));
+					break;
+				}
+				
+				if (result.index != lastIndex)
+				{
+					// Add text between tags as a child of the innermost open element
+					appendTextChild (currElem, source.substring(lastIndex, result.index));
+				}
+				
+				var tag:String = result[0]; // entire tag
+				var hasStartModifier:Boolean = (result[1] == "\/"); // modifier after < (/ for end tag)
+				var name:String = result[2].toLowerCase();  // name; use lower case
+				var attrs:String = result[3];  // attributes; including whitespace
+				var hasEndModifier:Boolean = (result[4] == "\/"); // modifier before > (/ for composite start and end tag)
+
+				if (!hasStartModifier) // start tag 
+				{	
+					// Special case for implicit closing of <p>
+					// TODO-12/23/2008: this will need to be handled more generically				
+					if (name == "p" && currElem.name().localName == "p")
+						currElem = currElem.parent();
+						
+					// Create an XML element by constructing a tag that can be fed to the XML constructor. Specifically, ensure
+					// - it is a composite tag (start and end tag together) using the terminating slash shorthand
+					// - element and attribute names are lower case (this is not required, but doesn't hurt)
+					// - attribute values are quoted  	
+					// - boolean attributes are fully specified (e.g., selected="selected" rather than selected)
+					tag = "<" + name;
+					do
+					{
+						var innerResult:Object = attrRegex.exec(attrs);
+						if (!innerResult)
+							break;
+							
+						var attrName:String = innerResult[1].toLowerCase();
+						tag += " " + attrName + "="; 
+						var val:String = innerResult[2] ? innerResult[2] : attrName /* boolean attribute with implied value equal to attribute name */; 
+						var startChar:String = val.charAt(0); 
+						tag += ((startChar == "'" || startChar == "\"") ? val : ("\"" + val + "\""));
+						
+					} while (true);	 
+					tag += "\/>";
+					
+					// Add the corresponding element as a child of the innermost open element 
+					currElem.appendChild(new XML(tag));
+					
+					// The new element becomes the innermost open element unless it is already closed because
+					// - this is a composite start and end tag (i.e., has an end modifier) 
+					// - the start tag itself implies closure
+					if (!hasEndModifier && !doesStartTagCloseElement(name))
+						currElem = currElem.children()[currElem.children().length()-1];	
+				}	
+				else // end tag
+				{	
+					if (hasEndModifier || attrs.length)
+					{
+						reportError(GlobalSettings.resourceStringFunction("malformedTag",[tag]));
+					}
+					else
+					{
+						/*
+						// Does not apply to TextField dialect
+						if (isEndTagForbidden(name))
+						{
+							xxxreportError("End tag is not allowed for element " + name); NOTE : MAKE A LOCALIZABLE ERROR IF THIS COMES BACK
+							return null;
+						}*/
+					
+						// Move up the chain of open elements looking for a matching name
+						// The matching element is closed and its parent becomes the innermost open element
+						// Report error if matching element is not found and it requires a start tag
+						// All intermediate open elements are also closed provided they don't require end tags
+						// Report error if an intermediate element requires end tags
+						var openElem:XML = currElem;
+						do
+						{
+							openElemName = openElem.name().localName; 
+							openElem = openElem.parent();
+							
+							if (openElemName == name)
+							{
+								currElem = openElem;
+								break;
+							}
+							/*
+							// Does not apply to TextField dialect
+							else if (isEndTagRequired(openElemName))
+							{
+								xxxreportError("Missing end tag for element " + openElemName);
+								return null;
+							}*/
+	
+							
+							if (!openElem)
+							{
+								// Does not apply to TextField dialect
+								/*if (isStartTagRequired(name))
+								{
+									xxxreportError("Unexpected end tag " + name);
+									return null;
+								}*/
+								break;
+							}					
+						}
+						while (true);
+					}
+				}
+				
+				lastIndex = tagRegex.lastIndex;
+				if (lastIndex == source.length)
+					break; // string completely parsed
+					
+			} while (currElem); // null currElem means <html/> has been closed, so ignore everything else		
+			
+			// No more string to parse, specifically, no more end tags. 
+			// Validate that remaining open elements do not require end tags.
+			// Does not apply to TextField dialect
+			/* while (currElem)
+			{
+				openElemName = currElem.name().localName; 
+				if (isEndTagRequired(openElemName))
+				{
+					xxxreportError("Missing end tag for element " + openElemName);
+					return null;
+				}
+				currElem = currElem.parent();
+			}*/	
+			
+			return root;
+		}
+		
+		/** TODO-1/16/2009-Evaluate if following code may be better implemented using dictionaries queried at runtime
+		 */
+		/* 
+		// TextField dialect: Not used  
+		private function isStartTagRequired (tagName:String):Boolean
+		{
+			switch (tagName)
+			{
+				case "a":
+				case "b":
+				case "br":
+				case "font":
+				case "i":
+				case "img":
+				case "p":
+				case "span":
+				case "textformat":
+				case "u":
+					return true;
+				default:
+					// html, head, body, and unrecognized elements (which are handled leniently)
+					return false;
+			}
+		}
+		
+		private function isEndTagRequired (tagName:String):Boolean
+		{
+			switch (tagName)
+			{
+				case "a":
+				case "b":
+				case "font":
+				case "i":
+				case "span":
+				case "textformat":
+				case "u":
+					return true;
+				default:
+					// html, head, body, p, br, image and unrecognized elements (which are handled leniently)
+					return false; 	
+			}
+		}
+		
+		private function isEndTagForbidden (tagName:String):Boolean
+		{
+			switch (tagName)
+			{
+				case "br":
+				case "img":
+					return true;
+				default:
+					return false;
+			}
+		}*/
+		
+		private function doesStartTagCloseElement (tagName:String):Boolean
+		{
+			switch (tagName)
+			{
+				case "br":
+				case "img":
+					return true;
+				default:
+					return false;
+			}
+		}
+		
+		private static const anyPrintChar:RegExp = /[^\u0009\u000a\u000d\u0020]/g;	
+
+		/** Adds text as a descendant of the specified XML element. Adds an intermediate <span> element is created if parent is not a <span>
+		 *  No action is taken for whitespace-only text
+		 */
+		private function appendTextChild(parent:XML, text:String):void
+		{
+			// No whitespace collapse
+			// if (text.match(anyPrintChar).length != 0) 
+			{
+				var parentIsSpan:Boolean = (parent.localName() == "span");
+				var elemName:String = parentIsSpan ? "dummy" : "span";
+				
+				//var xml:XML = <{elemName}/>;
+				//xml.appendChild(text);
+				// The commented-out code above doesn't handle character entities like &lt; 
+				// The following lets the XML constructor handle them 
+				var xmlText:String = "<" + elemName + ">" + text + "<\/" + elemName + ">";
+				try
+				{
+					var xml:XML = new XML(xmlText);
+					parent.appendChild(parentIsSpan ? xml.children()[0] : xml);
+				}
+				catch (e:*)
+				{
+					// Report malformed content like "<" instead of "&lt;"
+					reportError(GlobalSettings.resourceStringFunction("malformedMarkup",[text]));
+				}
+					
+			}
+		}	
+	}
+}
+
+import flashx.textLayout.conversion.TLFormatImporter;
+
+/** Specialized to provide case insensitivity (as required by TEXT_FIELD_HTML_FORMAT)
+ *  Keys need to be lower-cased. Values may or may not based on a flag passed to the constructor. 
+ */
+class CaseInsensitiveTLFFormatImporter extends TLFormatImporter
+{
+	public function CaseInsensitiveTLFFormatImporter(classType:Class,description:Object, convertValuesToLowerCase:Boolean=true)
+	{
+		_convertValuesToLowerCase = convertValuesToLowerCase;
+		
+		var lowerCaseDescription:Object = new Object();
+		for (var prop:Object in description)
+		{
+			lowerCaseDescription[prop.toLowerCase()] = description[prop];
+		}
+		
+		super(classType, lowerCaseDescription);
+	}
+	
+	public override function importOneFormat(key:String,val:String):Boolean
+	{
+		return super.importOneFormat(key.toLowerCase(), _convertValuesToLowerCase ? val.toLowerCase() : val);  
+	} 
+	
+	public function getFormatValue (key:String):*
+	{
+		return result ? result[key.toLowerCase()] : undefined;
+	}
+	
+	private var _convertValuesToLowerCase:Boolean;
+}
+
+class HtmlCustomParaFormatImporter extends TLFormatImporter
+{
+	public function HtmlCustomParaFormatImporter(classType:Class,description:Object)
+	{
+		super(classType,description);
+	}
+	
+	public override function importOneFormat(key:String,val:String):Boolean
+	{
+		key = key.toLowerCase();
+		
+		if (key == "align")
+			key = "textAlign";
+		return super.importOneFormat(key,val.toLowerCase()); // covert val to lowercase because TLF won't accept, say, "RIGHT"
+	} 
+}
+
+class TextFormatImporter extends TLFormatImporter
+{
+	public function TextFormatImporter(classType:Class,description:Object)
+	{
+		super(classType,description);
+	}
+	
+	public override function importOneFormat(key:String,val:String):Boolean
+	{
+		key = key.toLowerCase();
+		
+		if (key == "leftmargin")
+			key = "paragraphStartIndent"; // assumed to be left-to-right text since we don't handle DIR attribute
+		else if (key == "rightmargin")
+			key = "paragraphEndIndent";   // assumed to be left-to-right text since we don't handle DIR attribute
+		else if (key == "indent")
+			key = "textIndent";
+		else if (key == "leading")
+			key = "lineHeight";
+		else if (key == "tabstops")
+		{
+			key = "tabStops";
+			// Comma-delimited in TextField HTML format, space delimited in TLF
+			val = val.replace(/,/g, ' '); 
+		}
+		return super.importOneFormat(key,val); // no case-coversion required, values for these formats in TLF are case-insensitive
+	} 
+}
+
+class FontImporter extends TLFormatImporter
+{
+	public function FontImporter(classType:Class,description:Object)
+	{
+		super(classType,description);
+	}
+	
+	public override function importOneFormat(key:String,val:String):Boolean
+	{
+		key = key.toLowerCase();
+		if (key == "letterspacing")
+			key = "trackingRight";
+		else if (key == "face")
+			key = "fontFamily";
+		return super.importOneFormat(key,val);  // no case-coversion required, values for these formats in TLF are case-insensitive
+	} 
+}
+
diff --git a/textLayout_conversion/src/flashx/textLayout/conversion/IFormatImporter.as b/textLayout_conversion/src/flashx/textLayout/conversion/IFormatImporter.as
new file mode 100755
index 0000000..c034126
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/conversion/IFormatImporter.as
@@ -0,0 +1,31 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.conversion
+{
+	import flashx.textLayout.elements.TextFlow;
+	
+	[ExcludeClass]
+	/** Interface for exporting text content from a TextFlow to either a String or XML. */
+	public interface IFormatImporter
+	{	
+		function reset():void;
+		function get result():Object;
+		function importOneFormat(key:String,val:String):Boolean
+	}
+}
diff --git a/textLayout_conversion/src/flashx/textLayout/conversion/ITextExporter.as b/textLayout_conversion/src/flashx/textLayout/conversion/ITextExporter.as
new file mode 100755
index 0000000..7f17699
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/conversion/ITextExporter.as
@@ -0,0 +1,51 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.conversion
+{
+	import flashx.textLayout.elements.TextFlow;
+	
+	/** 
+	 * Interface for exporting text content from a 
+	 * TextFlow instance to either String or XML format. 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public interface ITextExporter
+	{	
+		/** 
+		 * Export text content from a TextFlow instance in String or XML format.
+		 * <p>Set the <code>conversionType</code> parameter to either of the following values:
+		 * <ul>
+		 *   <li><code>flashx.textLayout.conversion.ConversionType.STRING_TYPE</code>;</li>
+		 *   <li><code>flashx.textLayout.conversion.ConversionType.XML_TYPE</code>.</li>
+		 * </ul>
+		 * </p>
+		 * @param source	The TextFlow to export
+		 * @param conversionType 	Return a String (STRING_TYPE) or XML (XML_TYPE).
+		 * @return Object	The exported content
+		 * @includeExample examples\ITextExporterExample.as -noswf
+		 * @see flashx.textLayout.conversion.ConversionType
+	 	 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function export(source:TextFlow, conversionType:String):Object;
+	}
+}
diff --git a/textLayout_conversion/src/flashx/textLayout/conversion/ITextImporter.as b/textLayout_conversion/src/flashx/textLayout/conversion/ITextImporter.as
new file mode 100755
index 0000000..22c74e3
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/conversion/ITextImporter.as
@@ -0,0 +1,60 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.conversion
+{
+	import flashx.textLayout.elements.TextFlow;
+	
+	/** 
+	 * Interface for importing text content into a TextFlow from an external source. 
+	 * @includeExample examples\ITextImporterExample.as -noswf
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public interface ITextImporter
+	{	
+		/** 
+		 * Import text content from an external source and convert it into a TextFlow.
+		 * @param source		Data to convert
+		 * @return TextFlow created from the source.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function importToFlow(source:Object):TextFlow;
+
+		/** 
+		 * Errors encountered while parsing. This will be empty if there were no errors.
+		 * Value is a vector of Strings.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get errors():Vector.<String>;
+		
+		/** 
+		 * Parsing errors during import will cause exceptions if throwOnError is <code>true</code>. 
+	 	 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get throwOnError():Boolean;
+		function set throwOnError(value:Boolean):void;
+	}
+}
\ No newline at end of file
diff --git a/textLayout_conversion/src/flashx/textLayout/conversion/ImportExportConfiguration.as b/textLayout_conversion/src/flashx/textLayout/conversion/ImportExportConfiguration.as
new file mode 100755
index 0000000..a4bb2cd
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/conversion/ImportExportConfiguration.as
@@ -0,0 +1,122 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.conversion
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.BreakElement;
+	import flashx.textLayout.elements.Configuration;
+	import flashx.textLayout.elements.DivElement;
+	import flashx.textLayout.elements.InlineGraphicElement;
+	import flashx.textLayout.elements.LinkElement;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.SpanElement;
+	import flashx.textLayout.elements.TCYElement;
+	import flashx.textLayout.elements.TabElement;
+	import flashx.textLayout.elements.TextFlow;
+
+	/** Configure for import/export of standard components.
+	 * Configures the import/export package so it can export all the standard FlowElements. 
+	 * @see flashx.textLayout.elements.Configuration
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	internal class ImportExportConfiguration 
+	{
+		/** array of FlowElementInfo objects (key = name, value = FlowElementInfo) */	
+		private var flowElementInfoList:Object;	
+
+		/** Constructor.
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+		 */
+		public function ImportExportConfiguration()
+		{
+		}
+		
+		/** Add a parser for a new FlowElement type. This allows FlowElements to be added from outside the main system,
+		 * and still have the main system be able to import them from XML.
+		 * @param name		the name of the FlowElement class, as it appear in the XML
+		 * @param flowClass	the class of the FlowElement
+		 * @param parser	a function capable of parsing the XML into the flow element
+		 * @param	isParagraphFormattedElement Boolean indicating if this class is a subclass of ParagraphFormattedElement
+		 * @private - this should really be tf_internal
+		 */
+		public function addIEInfo(name:String, flowClass:Class, parser:Function, exporter:Function, isParagraphFormattedElement:Boolean):void
+		{
+			if (flowElementInfoList == null)
+				flowElementInfoList = new Object();
+			CONFIG::debug { assert (lookup(name) == null, "FlowElementInfo already exists");}
+			flowElementInfoList[name] = new FlowElementInfo(flowClass, parser, exporter, isParagraphFormattedElement);
+		}
+		
+		/** @private */
+		public function overrideIEInfo(name:String, flowClass:Class, parser:Function, exporter:Function):void
+		{
+			if (flowElementInfoList == null)
+				flowElementInfoList = new Object();
+			
+			CONFIG::debug { assert (lookup(name) != null, "FlowElementInfo doesn't already exist");}
+			flowElementInfoList[name].flowClass = flowClass;
+			flowElementInfoList[name].parser = parser;
+			flowElementInfoList[name].exporter = exporter;
+		}
+		
+		/** Return the information being held about the FlowElement, as a FlowElementInfo.
+		 * @param name				the name of the FlowElement class, as it appears in the XML
+		 * @return FlowElementInfo	the information being held, as it was supplied to addParseInfo
+		 * @private
+		 */
+		public function lookup(name:String):FlowElementInfo
+		{
+			return flowElementInfoList ? flowElementInfoList[name] : null;
+		}
+
+		/** Return the element name for the class
+		 * @param classToMatch		fully qualified class name of the FlowElement
+		 * @return name				export name to use for class
+		 * @private
+		 */
+		public function lookupName(classToMatch:String):String
+		{
+			for (var name:String in flowElementInfoList)
+			{
+				if (flowElementInfoList[name].flowClassName == classToMatch)
+					return name;
+			}
+			return null;
+		}
+
+		/** Return the information being held about the FlowElement, as a FlowElementInfo.
+		 * @param classToMatch		fully qualified class name of the FlowElement
+		 * @return FlowElementInfo	the information being held, as it was supplied to addParseInfo
+		 * @private
+		 */
+		public function lookupByClass(classToMatch:String):FlowElementInfo
+		{
+			for (var name:String in flowElementInfoList)
+			{
+				if (flowElementInfoList[name].flowClassName == classToMatch)
+					return flowElementInfoList[name];
+			}
+			return null;
+		}
+	}
+}
diff --git a/textLayout_conversion/src/flashx/textLayout/conversion/PlainTextExporter.as b/textLayout_conversion/src/flashx/textLayout/conversion/PlainTextExporter.as
new file mode 100755
index 0000000..51183f9
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/conversion/PlainTextExporter.as
@@ -0,0 +1,158 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.conversion
+{
+	import flashx.textLayout.elements.*;
+
+	/** 
+	 * Export filter for plain text format. This class provides an alternative to
+	 * the <code>TextConverter.export()</code> static method for exporting plain text,
+	 * useful if you need to customize the export by changing the paragraphSeparator
+	 * or stripDiscretionaryHyphens options. The PlainTextExporter class's 
+	 * <code>export()</code> method results in the 
+	 * same output string as the <code>TextConverter.export()</code> static method 
+	 * if the two properties of the PlainTextExporter class, the <code>paragraphSeparator</code>
+	 * and the <code>stripDiscretionaryHyphens</code> properties, contain their
+	 * default values of <code>"\n"</code> and <code>true</code>, respectively.
+	 * @includeExample examples\PlainTextExporter_example.as -noswf
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public class PlainTextExporter implements ITextExporter	
+	{
+		private var _stripDiscretionaryHyphens:Boolean;
+		private var _paragraphSeparator:String;
+		
+		static private var _discretionaryHyphen:String = String.fromCharCode(0x00AD);
+		
+		/**
+		 * Constructor 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+
+		public function PlainTextExporter()
+		{
+			_stripDiscretionaryHyphens = true;
+			_paragraphSeparator = "\n";
+		}
+		 
+		/** This flag indicates whether discretionary hyphens in the text should be stripped during the export process.
+		 * Discretionary hyphens, also known as "soft hyphens", indicate where to break a word in case the word must be
+		 * split between two lines. The Unicode character for discretionary hyphens is <code>\u00AD</code>.
+		 * <p>If the <code>stripDiscretionaryHyphens</code> property is set to <code>true</code>, discretionary hyphens that are in the original text will not be in the exported text, 
+		 * even if they are part of the original text. If <code>false</code>, discretionary hyphens will be in the exported text, 
+		 * The default value is <code>true</code>.</p>
+  		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get stripDiscretionaryHyphens():Boolean
+		{
+			return _stripDiscretionaryHyphens;
+			
+		}
+		public function set stripDiscretionaryHyphens(value:Boolean):void
+		{
+			_stripDiscretionaryHyphens = value;
+		}
+
+		/** Specifies the character sequence used (in a text flow's plain-text equivalent) to separate paragraphs.
+	    	 * The paragraph separator is not added after the last paragraph. The default value is "\n". 
+  		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paragraphSeparator():String
+		{ return _paragraphSeparator; }
+		public function set paragraphSeparator(value:String):void
+		{
+			_paragraphSeparator = value;
+		}
+
+		/** 
+		 * Export the contents of a TextFlow object to plain text.
+		 * The values of the <code>paragraphSeparator</code>
+		 * and the <code>stripDiscretionaryHyphens</code> properties
+		 * affect the output produced by this method.
+		 * @param source	the text flow object to export
+		 * @param conversionType 	The type to return (STRING_TYPE). This 
+		 * parameter accepts only one value: <code>ConversionType.STRING_TYPE</code>,
+		 * but is necessary because this class implements the ITextExporter
+		 * interface. The interface method, <code>ITextExporter.export()</code>, requires 
+		 * this parameter.
+		 * @return Object	the exported content
+		 * 
+		 * @see #paragraphSeparator
+		 * @see #stripDiscretionaryHyphens
+		 * @see ConversionType#STRING_TYPE
+  		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function export(source:TextFlow, conversionType:String):Object
+		{
+			if (conversionType == ConversionType.STRING_TYPE)
+				return exportToString(source);
+			return null;
+		}
+		
+		/** Export text content as a string
+		 * @param source	the text to export
+		 * @return String	the exported content
+		 * 
+  		 * @private
+		 */
+		protected function exportToString(source:TextFlow):String
+		{
+			var rslt:String = "";
+			var leaf:FlowLeafElement = source.getFirstLeaf(); 
+			
+			while (leaf)
+			{
+            	var p:ParagraphElement = leaf.getParagraph();
+            	while (true)
+            	{
+            		var curString:String = leaf.text;
+            		
+            		//split out discretionary hyphen and put string back together
+            		if (_stripDiscretionaryHyphens)
+            		{
+						var temparray:Array = curString.split(_discretionaryHyphen);
+						curString = temparray.join("");
+            		}
+					
+	               	rslt += curString;
+					var nextLeaf:FlowLeafElement = leaf.getNextLeaf(p);
+					if (!nextLeaf)
+						break; // end of para
+					
+					leaf = nextLeaf;
+            	}
+            	
+            	leaf = leaf.getNextLeaf();
+            	if (leaf) // not the last para
+                   	rslt += _paragraphSeparator; 
+   			}
+   			return rslt;
+		}
+ 	}
+}
\ No newline at end of file
diff --git a/textLayout_conversion/src/flashx/textLayout/conversion/PlainTextImporter.as b/textLayout_conversion/src/flashx/textLayout/conversion/PlainTextImporter.as
new file mode 100755
index 0000000..e02cee9
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/conversion/PlainTextImporter.as
@@ -0,0 +1,103 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.conversion
+{
+	//import container.TextFrame;
+	import flashx.textLayout.elements.IConfiguration;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.DivElement;
+	import flashx.textLayout.elements.SpanElement;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flash.display.DisplayObjectContainer;
+	
+	[ExcludeClass]
+	/** 
+	 * @private
+	 * PlainText import filter. Use this to import simple unformatted Unicode text.
+	 * Newlines will be converted to paragraphs. Using the PlainTextImporter directly
+	 * is equivalent to calling TextConverter.importToFlow(TextConverter.PLAIN_TEXT_FORMAT).
+	 */
+	internal class PlainTextImporter implements ITextImporter
+	{
+		protected var _config:IConfiguration;
+		
+		/** Constructor */
+		public function PlainTextImporter(config:IConfiguration =  null)
+		{
+			_config = config;
+		}
+		
+		/** Import text content, from an external source, and convert it into a TextFlow.
+		 * @param source		source data to convert, may be string or XML
+		 * @return TextFlow that was created from the source.
+		 */
+		public function importToFlow(source:Object):TextFlow
+		{
+			if (source is String)
+				return importFromString(String(source));
+			return null;
+		}
+		
+		// LF or CR or CR+LF. Equivalently, LF or CR, the latter optionally followed by LF
+		private static const _newLineRegex:RegExp = /\u000A|\u000D\u000A?/g;
+		
+		/** Import text content, from an external source, and convert it into a TextFlow.
+		 * @param source		source data to convert
+		 * @return textFlows[]	an array of TextFlow objects that were created from the source.
+		 */
+		protected function importFromString(source:String):TextFlow
+		{
+			var paragraphStrings:Array = source.split(_newLineRegex);
+
+			var textFlow:TextFlow = new TextFlow(_config);
+			var paraText:String;
+			for each (paraText in paragraphStrings)
+			{
+				var paragraph:ParagraphElement  = new ParagraphElement();
+				var span:SpanElement = new SpanElement();
+				span.replaceText(0, 0, paraText);
+				paragraph.replaceChildren(0, 0, span);			
+				textFlow.replaceChildren(textFlow.numChildren, textFlow.numChildren, paragraph);
+			}
+			return textFlow;			
+		}
+
+		/** Errors encountered while parsing. 
+		 * Value is a vector of Strings.
+		 */
+		public function get errors():Vector.<String>
+		{
+			return null;
+		}
+		
+		/** Errors will cause exceptions if throwOnError is true. */
+		public function get throwOnError():Boolean
+		{
+			return false;
+		}
+		
+		/** Does nothing.  get always returns false */
+		public function set throwOnError(value:Boolean):void
+		{
+			
+		}
+	}
+}
diff --git a/textLayout_conversion/src/flashx/textLayout/conversion/SingletonAttributeImporter.as b/textLayout_conversion/src/flashx/textLayout/conversion/SingletonAttributeImporter.as
new file mode 100755
index 0000000..361caae
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/conversion/SingletonAttributeImporter.as
@@ -0,0 +1,46 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.conversion
+{
+	[ExcludeClass]
+	/**
+	 * @private  
+	 */
+	internal class SingletonAttributeImporter implements IFormatImporter
+	{
+		private var _keyToMatch:String;
+		private var _rslt:String = null;
+		
+		public function SingletonAttributeImporter(key:String)
+		{ _keyToMatch =  key; }
+		public function reset():void
+		{ _rslt = null; }
+		public function get result():Object
+		{ return _rslt; }
+		public function importOneFormat(key:String,val:String):Boolean
+		{
+			if (key == _keyToMatch)
+			{
+				_rslt = val;
+				return true;
+			}
+			return false; 
+		}
+	}
+}
diff --git a/textLayout_conversion/src/flashx/textLayout/conversion/TLFormatImporter.as b/textLayout_conversion/src/flashx/textLayout/conversion/TLFormatImporter.as
new file mode 100755
index 0000000..f9ecbef
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/conversion/TLFormatImporter.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 flashx.textLayout.conversion
+{
+	import flashx.textLayout.property.Property;
+	import flashx.textLayout.debug.assert;
+	[ExcludeClass]
+	/**
+	 * @private  
+	 */
+	public class TLFormatImporter implements IFormatImporter
+	{
+		private var _classType:Class;
+		private var _description:Object;
+		
+		private var _rslt:Object;
+		
+		public function TLFormatImporter(classType:Class,description:Object)
+		{ 
+			_classType = classType;
+			_description = description;
+		}
+		
+		public function get classType():Class
+		{ return _classType; }
+		
+		public function reset():void
+		{ 
+			_rslt = null;
+		}
+		public function get result():Object
+		{ 
+			return _rslt; 
+		}
+		public function importOneFormat(key:String,val:String):Boolean
+		{ 
+			if (_description.hasOwnProperty(key))
+			{
+				if (_rslt == null)
+					_rslt = new _classType();
+	
+				CONFIG::debug { assert((_description[key] as Property) != null,"Bad description in TLFormatImporter"); }
+				_rslt[key] =  _description[key].setHelper(undefined,val);
+				return true;
+			}
+			return false; 
+		}
+	}
+}
diff --git a/textLayout_conversion/src/flashx/textLayout/conversion/TextConverter.as b/textLayout_conversion/src/flashx/textLayout/conversion/TextConverter.as
new file mode 100755
index 0000000..1e71d7f
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/conversion/TextConverter.as
@@ -0,0 +1,499 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.conversion
+{
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.elements.IConfiguration;
+	
+	/** 
+	 * This is the gateway class for handling import and export. It serves as a unified access point to the 
+	 * conversion functionality in the Text Layout Framework.
+	 * @includeExample examples\TextConverter_example.as -noswf
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public class TextConverter
+	{
+		/** 
+		 * HTML format.
+		 * Use this for importing from, or exporting to, a TextFlow using the HTML fomat.
+		 * The Text Layout Framework HTML supports a subset of the tags and attributes supported by
+		 * the TextField class in the <code>flash.text</code> package.
+		 * <p>The following table lists the HTML tags and attributes supported for the import
+		 * and export process (tags and attributes supported by TextField, but not supported by 
+		 * the Text Layout Framework are specifically described as not supported):</p>
+		 * 
+		 * 
+		 * <table class="innertable" width="640">
+		 * 
+		 * <tr>
+		 * 
+		 * <th>
+		 * Tag
+		 * </th>
+		 * 
+		 * <th>
+		 * Description
+		 * </th>
+		 * 
+		 * </tr>
+		 * 
+		 * <tr>
+		 * 
+		 * <td>
+		 * Anchor tag
+		 * </td>
+		 * 
+		 * <td>
+		 * The <code>&lt;a&gt;</code> tag creates a hypertext link and supports the following attributes:
+		 * <ul>
+		 * 
+		 * <li>
+		 * <code>target</code>: Specifies the name of the target window where you load the page. 
+		 * Options include <code>_self</code>, <code>_blank</code>, <code>_parent</code>, and 
+		 * <code>_top</code>. The <code>_self</code> option specifies the current frame in the current window, 
+		 * <code>_blank</code> specifies a new window, <code>_parent</code> specifies the parent of the 
+		 * current frame, and <code>_top</code> specifies the top-level frame in the current window. 
+		 * </li>
+		 *
+		 * <li>
+		 * <code>href</code>: Specifies a URL. The URL can 
+		 * be either absolute or relative to the location of the SWF file that 
+		 * is loading the page. An example of an absolute reference to a URL is 
+		 * <code>http://www.adobe.com</code>; an example of a relative reference is 
+		 * <code>/index.html</code>. Absolute URLs must be prefixed with 
+		 * http://; otherwise, Flash treats them as relative URLs. 
+		 * <strong>Note: Unlike the TextField class, </strong>ActionScript <code>link</code> events 
+		 * are not supported. Neither are
+		 * <code>a:link</code>, <code>a:hover</code>, and <code>a:active</code> styles.
+		 * </li>
+		 * 
+		 * </ul>
+		 * 
+		 * </td>
+		 * </tr>
+		 * 
+		 * <tr>
+		 * 
+		 * <td>
+		 * Bold tag
+		 * </td>
+		 * 
+		 * <td>
+		 * The <code>&lt;b&gt;</code> tag renders text as bold. A bold typeface must be available for the font used.
+		 * </td>
+		 * </tr>
+		 * 
+		 * <tr>
+		 * 
+		 * <td>
+		 * Break tag
+		 * </td>
+		 * <td>
+		 * The <code>&lt;br&gt;</code> tag creates a line break in the text.
+		 * </td>
+		 * </tr>
+		 * 
+		 * <tr>
+		 * 
+		 * <td>
+		 * Font tag
+		 * </td>
+		 * 
+		 * <td>
+		 * The <code>&lt;font&gt;</code> tag specifies a font or list of fonts to display the text.The font tag 
+		 * supports the following attributes:
+		 * <ul>
+		 * 
+		 * <li>
+		 * <code>color</code>: Only hexadecimal color (<code>#FFFFFF</code>) values are supported. 
+		 * </li>
+		 * 
+		 * <li>
+		 * <code>face</code>: Specifies the name of the font to use. As shown in the following example, 
+		 * you can specify a list of comma-delimited font names, in which case Flash Player selects the first available 
+		 * font. If the specified font is not installed on the local computer system or isn't embedded in the SWF file, 
+		 * Flash Player selects a substitute font. 
+		 * </li>
+		 * 
+		 * <li>
+		 * <code>size</code>: Specifies the size of the font. You can use absolute pixel sizes, such as 16 or 18 
+		 * or relative point sizes, such as +2 or -4. 
+		 * </li>
+		 * 
+		 * <li>
+		 * <code>letterspacing</code>: Specifies the tracking (manual kerning) in pixels to be applied to the right of each character. 
+		 * </li>
+		 * 
+		 * <li>
+		 * <code>kerning</code>: Specifies whether kerning is enabled or disabled. A non-zero value enables kerning, while zero disables it.  
+		 * </li>
+		 * 
+		 * </ul>
+		 * 
+		 * </td>
+		 * </tr>
+		 * 
+		 * <tr>
+		 * 
+		 * <td>
+		 * Image tag
+		 * </td>
+		 * 
+		 * <td>
+		 * The <code>&lt;img&gt;</code> tag lets you embed external image files (JPEG, GIF, PNG), SWF files, and 
+		 * movie clips inside text.  
+		 * 
+		 *  <p>The <code>&lt;img&gt;</code> tag supports the following attributes: </p>
+		 * 
+		 * <ul >
+		 * 
+		 * <li>
+		 * <code>src</code>: Specifies the URL to an image or SWF file, or the linkage identifier for a movie clip 
+		 * symbol in the library. This attribute is required; all other attributes are optional. External files (JPEG, GIF, PNG, 
+		 * and SWF files) do not show until they are downloaded completely. 
+		 * </li>
+		 * 
+		 * <li>
+		 * <code>width</code>: The width of the image, SWF file, or movie clip being inserted, in pixels. 
+		 * </li>
+		 * 
+		 * <li>
+		 * <code>height</code>: The height of the image, SWF file, or movie clip being inserted, in pixels. 
+		 * </li>
+		 * </ul>
+		 * <p><strong>Note: </strong> Unlike the TextField class, the following attributes are not supported:
+		 * <code>align</code>, <code>hspace</code>, <code>vspace</code>,  <code>id</code>, and <code>checkPolicyFile</code>.</p>
+		 *
+		 * </td>
+		 * </tr>
+		 * 
+		 * <tr>
+		 * 
+		 * <td>
+		 * Italic tag
+		 * </td>
+		 * 
+		 * <td>
+		 * The <code>&lt;i&gt;</code> tag displays the tagged text in italics. An italic typeface must be available 
+		 * for the font used.
+		 * </td>
+		 * </tr>
+		 * 
+		 * <tr>
+		 * 
+		 * <td>
+		 * <em>List item tag</em>
+		 * </td>
+		 * 
+		 * <td>
+		 * <strong>Note: </strong> Unlike the TextField class, the List item tag is not supported.
+		 * </td>
+		 * </tr>
+		 * 
+		 * <tr>
+		 * 
+		 * <td>
+		 * Paragraph tag
+		 * </td>
+		 * 
+		 * <td>
+		 * The <code>&lt;p&gt;</code> tag creates a new paragraph. 
+		 * 
+		 * The <code>&lt;p&gt;</code> tag supports the following attributes:
+		 * <ul >
+		 * 
+		 * <li>
+		 * align: Specifies alignment of text within the paragraph; valid values are <code>left</code>, <code>right</code>, <code>justify</code>, and <code>center</code>. 
+		 * </li>
+		 * 
+		 * <li>
+		 * class: Specifies a class name that can be used for styling 
+		 * </li>
+		 * 
+		 * </ul>
+		 * 
+		 * </td>
+		 * </tr>
+		 * 
+		 * <tr>
+		 * 
+		 * <td>
+		 * Span tag
+		 * </td>
+		 * 
+		 * <td>
+		 * 
+		 * The <code>&lt;span&gt;</code> tag supports the following attributes:
+		 * 
+		 * <ul>
+		 * 
+		 * <li>
+		 * class: Specifies a class name that can be used for styling. While span tags are often used to set a style defined in a style sheet,
+		 * TLFTextField instances do not support style sheets. The span tag is available for TLFTextField instances to refer to a class with 
+		 * style properties.</li>
+		 * <li> You can also put properties directly in the span tag: 
+		 * <code>&lt;span fontFamily="Arial"&gt;Hi there&lt;/span&gt;</code>. However, nested span tags are not supported.
+		 * </li>
+		 * 
+		 * </ul>
+		 * 
+		 * </td>
+		 * </tr>
+		 * 
+		 * <tr>
+		 * 
+		 * <td>
+		 * Text format tag
+		 * </td>
+		 * 
+		 * <td>
+		 *  <p>The <code>&lt;textformat&gt;</code> tag lets you use a subset of paragraph formatting 
+		 * properties of the TextFormat class within text fields, including line leading, indentation, 
+		 * margins, and tab stops. You can combine <code>&lt;textformat&gt;</code> tags with the 
+		 * built-in HTML tags. </p>
+		 * 
+		 *  <p>The <code>&lt;textformat&gt;</code> tag has the following attributes: </p>
+		 * <ul >
+		 * 
+		 * 
+		 * <li>
+		 * <code>indent</code>: Specifies the indentation from the left margin to the first character 
+		 * in the paragraph; corresponds to <code>TextFormat.indent</code>. Both positive and negative 
+		 * numbers are acceptable. 
+		 * </li>
+		 * 
+		 * <li>
+		 * <code>blockindent</code>: Specifies the indentation applied to all lines of the paragraph.
+		 * </li>
+		 * 
+		 * <li>
+		 * <code>leftmargin</code>: Specifies the left margin of the paragraph, in points; corresponds 
+		 * to <code>TextFormat.leftMargin</code>. 
+		 * </li>
+		 * 
+		 * <li>
+		 * <code>rightmargin</code>: Specifies the right margin of the paragraph, in points; corresponds 
+		 * to <code>TextFormat.rightMargin</code>. 
+		 * </li>
+		 * 
+		 * 	<li>
+		 * <code>leading</code>: Specifies the leading (line height) measured in pixels between a line's ascent and the previous line's descent
+		 * </li>
+		 * 
+		 * 	<li>
+		 * <code>tabstops</code>: Specifies a comma-separated list of tab stop positions for the paragraph. 
+		 * </li>
+		 * </ul>
+		 * 
+		 * </td>
+		 * </tr>
+		 * 
+		 * <tr>
+		 * 
+		 * <td>
+		 * Underline tag
+		 * </td>
+		 * 
+		 * <td>
+		 * The <code>&lt;u&gt;</code> tag underlines the tagged text.
+		 * </td>
+		 * </tr>
+		 * 
+		 * </table>
+
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public static const TEXT_FIELD_HTML_FORMAT:String = "textFieldHTMLFormat";
+
+		/** 
+		 * Plain text format.
+		 * Use this for creating a TextFlow from a simple, unformatted String, 
+		 * or for creating a simple, unformatted String from a TextFlow.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public static const PLAIN_TEXT_FORMAT:String = "plainTextFormat";
+
+		/** 
+		 * TextLayout Format.
+		 * Use this for importing from, or exporting to, a TextFlow using the TextLayout markup format.
+		 * Text Layout format will detect the following errors:
+		 * <ul>
+		 * <li>Unexpected namespace</li>
+		 * <li>Unknown element</li>
+		 * <li>Unknown attribute</li>
+		 * </ul>
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public static const TEXT_LAYOUT_FORMAT:String = "textLayoutFormat";
+	
+		/** 
+		 * Creates a TextFlow from source content in a specified format.
+		 * Supported formats include HTML, plain text, and TextLayout Markup.
+		 * <p>Use one of the four static constants supplied with this class
+		 * to specify the <code>format</code> parameter:
+		 * <ul>
+		 * <li>TextConverter.TEXT_FIELD_HTML_FORMAT</li>
+		 * <li>TextConverter.PLAIN_TEXT_FORMAT</li>
+		 * <li>TextConverter.TEXT_LAYOUT_FORMAT</li>
+		 * </ul>
+		 * </p>
+		 * @param source	Source content
+		 * @param format	Format of source content
+		 * @param config    IConfiguration to use when creating new TextFlows
+		 * @return TextFlow that was created from the source.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 * @see #TEXT_FIELD_HTML_FORMAT
+		 * @see #PLAIN_TEXT_FORMAT
+		 * @see #TEXT_LAYOUT_FORMAT
+		 */
+		public static function importToFlow(source:Object, format:String, config:IConfiguration = null) : TextFlow
+		{
+			var parser:ITextImporter = getImporter(format, config);
+			return parser.importToFlow(source);
+		}
+		
+		/** 
+		 * Exports a TextFlow to a specified format. Supported formats
+		 * include FXG, HTML, plain text, and TextLayout Markup.
+		 * <p>Use one of the four static constants supplied with this class
+		 * to specify the <code>format</code> parameter:
+		 * <ul>
+		 * <li>TextConverter.TEXT_FIELD_HTML_FORMAT</li>
+		 * <li>TextConverter.PLAIN_TEXT_FORMAT</li>
+		 * <li>TextConverter.TEXT_LAYOUT_FORMAT</li>
+		 * </ul>
+		 * </p>
+		 * <p>Specify the type of the exported data in the <code>conversionType</code> parameter 
+		 * with one of the two static constants supplied by the ConversionType class:
+		 * <ul>
+		 * <li>ConversionType.STRING_TYPE</li>
+		 * <li>ConversionType.XML_TYPE</li>
+		 * </ul>
+		 * </p>
+		 * 
+		 * Returns a representation of the TextFlow in the specified format.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 * @param source	Source content
+		 * @param format	Output format
+		 * @param conversionType	Type of exported data
+		 * @return Object	Exported form of the TextFlow
+		 * @see #TEXT_FIELD_HTML_FORMAT
+		 * @see #PLAIN_TEXT_FORMAT
+		 * @see #TEXT_LAYOUT_FORMAT
+		 * @see flashx.textLayout.conversion.ConversionType
+		 */
+		public static function export(source:TextFlow, format:String, conversionType:String) : Object
+		{
+			var exporter:ITextExporter = getExporter(format);
+			return exporter.export(source, conversionType);
+		}
+		
+		/** 
+		 * Creates an import filter. 
+		 * Returns an import filter, which you can then use to import from a 
+		 * source string or XML object to a TextFlow. Use this function
+		 * if you have many separate imports to perform, or if you want to 
+		 * handle errors during import. It is equivalent to calling 
+		 * <code>flashx.textLayout.conversion.TextConverter.importToFlow()</code>.
+		 * <p>Use one of the four static constants supplied with this class
+		 * to specify the <code>format</code> parameter:
+		 * <ul>
+		 * <li>TextConverter.TEXT_FIELD_HTML_FORMAT</li>
+		 * <li>TextConverter.PLAIN_TEXT_FORMAT</li>
+		 * <li>TextConverter.TEXT_LAYOUT_FORMAT</li>
+		 * </ul>
+		 * </p>
+		 * @includeExample examples\getImporter_example.as -noswf
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 * @param format	Format of source content.  Use constants from flashx.textLayout.conversion.TextConverter.TEXT_LAYOUT_FORMAT, PLAIN_TEXT_FORMAT, TEXT_FIELD_HTML_FORMAT etc.
+		 * @param config    configuration to use during this import.  null means take the current default.
+		 * @return ITextImporter	Text filter that can import the source data
+		 * @see #TEXT_FIELD_HTML_FORMAT
+		 * @see #PLAIN_TEXT_FORMAT
+		 * @see #TEXT_LAYOUT_FORMAT
+		 */
+		public static function getImporter(format:String,config:IConfiguration =  null): ITextImporter
+		{
+			switch (format)
+			{
+				case TEXT_LAYOUT_FORMAT:
+					return new TextLayoutImporter(config);
+				case PLAIN_TEXT_FORMAT:
+					return new PlainTextImporter(config);
+				case TEXT_FIELD_HTML_FORMAT:
+					return new HtmlImporter(config);
+			}
+			return null;
+		}
+
+		/** 
+		 * Creates an export filter.
+		 * Returns an export filter, which you can then use to export from 
+		 * a TextFlow to a source string or XML object. Use this function if 
+		 * you have many separate exports to perform. It is equivalent to calling 
+		 * <code>flashx.textLayout.conversion.TextConverter.export()</code>.
+		 * <p>Use one of the four static constants supplied with this class
+		 * to specify the <code>format</code> parameter:
+		 * <ul>
+		 * <li>TextConverter.TEXT_FIELD_HTML_FORMAT</li>
+		 * <li>TextConverter.PLAIN_TEXT_FORMAT</li>
+		 * <li>TextConverter.TEXT_LAYOUT_FORMAT</li>
+		 * </ul>
+		 * </p>
+		 * @includeExample examples\getExporter_example.as -noswf
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 * @param format	Target format for exported data
+		 * @return ITextExporter	Text filter that can export in the specified format
+		 * @see #TEXT_FIELD_HTML_FORMAT
+		 * @see #PLAIN_TEXT_FORMAT
+		 * @see #TEXT_LAYOUT_FORMAT
+		 */
+		public static function getExporter(format:String) : ITextExporter
+		{
+			switch (format)
+			{
+				case TEXT_LAYOUT_FORMAT:
+					return new TextLayoutExporter();
+				case PLAIN_TEXT_FORMAT:
+					return new PlainTextExporter();
+				case TEXT_FIELD_HTML_FORMAT:
+					return new HtmlExporter();
+			}
+			
+			return null;
+		}
+	}
+}
diff --git a/textLayout_conversion/src/flashx/textLayout/conversion/TextLayoutExporter.as b/textLayout_conversion/src/flashx/textLayout/conversion/TextLayoutExporter.as
new file mode 100755
index 0000000..8f24cad
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/conversion/TextLayoutExporter.as
@@ -0,0 +1,251 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.conversion
+{
+	import flash.utils.Dictionary;
+	
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.DivElement;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.FlowValueHolder;
+	import flashx.textLayout.elements.InlineGraphicElement;
+	import flashx.textLayout.elements.LinkElement;
+	import flashx.textLayout.elements.ParagraphFormattedElement;
+	import flashx.textLayout.elements.SpanElement;
+	import flashx.textLayout.elements.TCYElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.WhiteSpaceCollapse;
+	import flashx.textLayout.property.Property;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+	
+	[ExcludeClass]
+	/** 
+	 * @private
+	 * Export filter for TextLayout format. 
+	 */
+	internal class TextLayoutExporter extends BaseTextLayoutExporter
+	{	
+		private static var nameCounter:int = 0;
+		static private var _formatDescription:Object= TextLayoutFormat.description;
+
+		private var queuedExport:Object = null;
+		
+		public function TextLayoutExporter()
+		{
+			super(new Namespace("http://ns.adobe.com/textLayout/2008"), null, TextLayoutImporter.defaultConfiguration);
+		}
+		
+		override protected function clear():void
+		{
+			nameCounter = 0;
+			queuedExport = null;
+		}
+		
+		/** Export text content of a TextFlow into TextLayout format.
+		 * @param source	the text to export
+		 * @return XML	the exported content
+		 */
+		protected override function exportToXML(textFlow:TextFlow) : XML
+		{
+			var result:XML = super.exportToXML(textFlow);
+			var queuedXML:XMLList = exportQueuedObjects();
+			if (queuedXML)
+				result.appendChild(queuedXML);
+			return result;
+		}
+		
+		private function exportQueuedObjects():XMLList
+		{
+			if (!queuedExport)
+				return null;
+			
+			// pump out the queued objects
+			var result:XMLList = new XMLList();
+			for  (var idName:String in queuedExport) {
+				var objectToExport:Object = queuedExport[idName];
+				var output:XMLList = new XMLList();
+				if (objectToExport is FlowValueHolder) {
+					var characterFormatXML:XML = new XML("<format/>");
+					characterFormatXML.setNamespace(flowNS);
+					output += characterFormatXML;
+					output.@id = idName;
+					exportStyles(output, objectToExport.coreStyles, formatDescription);
+					exportStyles(output, objectToExport.userStyles);
+				}
+				result += output;
+			}
+			return result;
+		}
+		
+		/** Get additional objects that are required for export
+		 * The subject may have dependent objects that will need to be exported, in addition
+		 * to the subject itself.
+		 * @return XML	array of Objects to export
+		 */
+		private function queueForExport(object:Object, name:String):void
+		{
+			if (!queuedExport)
+				queuedExport = new Object();
+				
+			queuedExport[name] = object;
+		}
+		
+		static private const brTabRegEx:RegExp = new RegExp("[" + "\u2028" + "\t" + "]"); // Doesn't /\u2028\t/ work?
+		
+		/** Gets the regex that specifies characters to be replaced with XML elements
+		 *  Note: Each match is a single character 
+		 */
+		protected override function get spanTextReplacementRegex():RegExp
+		{
+			return brTabRegEx;
+		}
+		
+		/** Gets the xml element used to represent a character in the export format
+		 */
+		protected override function getSpanTextReplacementXML(ch:String):XML
+		{
+			var replacementXML:XML;
+			if (ch == '\u2028')
+				replacementXML = <br/>;
+			else if (ch == '\t')
+				replacementXML = <tab/>;
+			else
+			{
+				CONFIG::debug {assert(false, "Did not recognize character to be replaced with XML"); }
+				return null;			
+			}
+		
+			replacementXML.setNamespace(flowNS);
+			return replacementXML;	
+		}
+		
+		protected override function exportFlowElement(flowElement:FlowElement):XMLList
+		{
+			var rslt:XMLList = super.exportFlowElement(flowElement);
+			
+			var coreStyles:Object = flowElement.coreStyles;
+			if (coreStyles)
+			{
+				// WhiteSpaceCollapse attribute should never be exported (except on TextFlow -- handled separately)
+				delete coreStyles[TextLayoutFormat.whiteSpaceCollapseProperty.name];
+				exportStyles(rslt, coreStyles, formatDescription);
+			}
+			
+			// export id and styleName
+			if (flowElement.id != null)
+				rslt.@["id"] = flowElement.id;
+			if (flowElement.styleName != null)
+				rslt.@["styleName"] = flowElement.styleName;
+			// export any user defined styles
+			var styles:Object = flowElement.userStyles;
+			if (styles)
+				exportStyles(rslt, styles);
+				
+			return rslt;
+		}
+
+		/** Base functionality for exporting an Image. Exports as a FlowElement,
+		 * and exports image properties.
+		 * @param exporter	Root object for the export
+		 * @param image	Element to export
+		 * @return XMLList	XML for the element
+		 */
+		static public function exportImage(exporter:BaseTextLayoutExporter, image:InlineGraphicElement):XMLList
+		{
+			var output:XMLList = exportFlowElement(exporter, image);
+			
+			// output the img specific values
+			if (image.height !== undefined)
+				output.@height = image.height;
+			if (image.width !== undefined)
+				output.@width = image.width;
+		//	output.@rotation = image.rotation;  don't support rotation yet
+			if (image.source != null)
+				output.@source = image.source;
+			// FUTURE!!! output.@float = image.float;
+						
+			return output;
+		}
+
+		/** Base functionality for exporting a LinkElement. Exports as a FlowGroupElement,
+		 * and exports link properties.
+		 * @param exporter	Root object for the export
+		 * @param link	Element to export
+		 * @return XMLList	XML for the element
+		 */
+		static public function exportLink(exporter:BaseTextLayoutExporter, link:LinkElement):XMLList
+		{
+			var output:XMLList = exportFlowGroupElement(exporter, link);
+
+			if (link.href)
+				output.@href= link.href;
+				
+			if (link.target)
+				output.@target = link.target;
+				
+			return output;
+		}
+		
+		/** Base functionality for exporting a DivElement. Exports as a FlowContainerFormattedElement
+		 * @param exporter	Root object for the export
+		 * @param div	Element to export
+		 * @return XMLList	XML for the element
+		 */
+		static public function exportDiv(exporter:BaseTextLayoutExporter, div:DivElement):XMLList
+		{
+			return exportContainerFormattedElement(exporter, div);
+		}
+		
+		/** Base functionality for exporting a TCYElement. Exports as a FlowGroupElement
+		 * @param exporter	Root object for the export
+		 * @param tcy	Element to export
+		 * @return XMLList	XML for the element
+		 */
+		static public function exportTCY(exporter:BaseTextLayoutExporter, tcy:TCYElement):XMLList
+		{
+			return exportFlowGroupElement(exporter, tcy);
+		}
+		
+		/** Queues the object for export later, generates an ID for it, and returns
+		 * the ID.
+		 * @param exporter	Root object for the export
+		 * @param obj	Element to export
+		 * @return String	ID of the object
+		 */
+		static private function exportToName(exporter:BaseTextLayoutExporter, obj:Object):String
+		{
+			var newName:String = "ObjectID" + nameCounter.toString();
+			TextLayoutExporter(exporter).queueForExport(obj, newName);
+			nameCounter++;
+			return newName;
+		}
+		
+		override protected function get formatDescription():Object
+		{
+			return _formatDescription;
+		}		
+
+	}
+}
diff --git a/textLayout_conversion/src/flashx/textLayout/conversion/TextLayoutImporter.as b/textLayout_conversion/src/flashx/textLayout/conversion/TextLayoutImporter.as
new file mode 100755
index 0000000..c029e88
--- /dev/null
+++ b/textLayout_conversion/src/flashx/textLayout/conversion/TextLayoutImporter.as
@@ -0,0 +1,459 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.conversion 
+{
+	import __AS3__.vec.Vector;
+	
+	import flash.display.Shape;
+	import flash.text.engine.TextRotation;
+	import flash.utils.Dictionary;
+	
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.BreakElement;
+	import flashx.textLayout.elements.DivElement;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.GlobalSettings;
+	import flashx.textLayout.elements.IConfiguration;
+	import flashx.textLayout.elements.InlineGraphicElement;
+	import flashx.textLayout.elements.LinkElement;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.SpanElement;
+	import flashx.textLayout.elements.SubParagraphGroupElement;
+	import flashx.textLayout.elements.TCYElement;
+	import flashx.textLayout.elements.TabElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormatValueHolder;
+	import flashx.textLayout.property.EnumStringProperty;
+	import flashx.textLayout.property.NumberProperty;
+	import flashx.textLayout.property.StringProperty;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+
+	[ExcludeClass]
+	/** 
+	 * @private
+	 * TextLayoutImporter converts from XML to TextLayout data structures and back.
+	 */ 	
+	public class TextLayoutImporter extends BaseTextLayoutImporter 
+	{
+		private static var _defaultConfiguration:ImportExportConfiguration;
+		
+		/** Default ImportExportConfiguration to use when none specified 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0 
+		*/
+		public static function get defaultConfiguration():ImportExportConfiguration
+		{
+			// The first call will force the import/export to include the standard components
+			if (!_defaultConfiguration)
+			{
+				_defaultConfiguration = new ImportExportConfiguration();
+				// shared by TextLayout and FXG markup
+	 			_defaultConfiguration.addIEInfo("TextFlow", TextFlow,        BaseTextLayoutImporter.parseTextFlow, BaseTextLayoutExporter.exportTextFlow, true);
+				_defaultConfiguration.addIEInfo("br", BreakElement,          BaseTextLayoutImporter.parseBreak, BaseTextLayoutExporter.exportFlowElement, false);
+				_defaultConfiguration.addIEInfo("p", ParagraphElement,       BaseTextLayoutImporter.parsePara, BaseTextLayoutExporter.exportParagraphFormattedElement, true);
+				_defaultConfiguration.addIEInfo("span", SpanElement,         BaseTextLayoutImporter.parseSpan, BaseTextLayoutExporter.exportSpan, false);
+				_defaultConfiguration.addIEInfo("tab", TabElement,           BaseTextLayoutImporter.parseTab, BaseTextLayoutExporter.exportFlowElement, false);
+				// shared by TextLayoutMarkup only
+				_defaultConfiguration.addIEInfo("tcy", TCYElement,           TextLayoutImporter.parseTCY, TextLayoutExporter.exportTCY, false);
+				_defaultConfiguration.addIEInfo("a", LinkElement,            TextLayoutImporter.parseLink, TextLayoutExporter.exportLink, false);
+	 			_defaultConfiguration.addIEInfo("div", DivElement,           TextLayoutImporter.parseDivElement, TextLayoutExporter.exportDiv, true);
+				_defaultConfiguration.addIEInfo("img", InlineGraphicElement, TextLayoutImporter.parseInlineGraphic, TextLayoutExporter.exportImage, false);							 
+				// customized link formats
+				_defaultConfiguration.addIEInfo(LinkElement.LINK_NORMAL_FORMAT_NAME,null,TextLayoutImporter.parseLinkNormalFormat,null, false);
+				_defaultConfiguration.addIEInfo(LinkElement.LINK_ACTIVE_FORMAT_NAME,null,TextLayoutImporter.parseLinkActiveFormat,null, false);
+				_defaultConfiguration.addIEInfo(LinkElement.LINK_HOVER_FORMAT_NAME, null,TextLayoutImporter.parseLinkHoverFormat, null, false);
+			}
+			
+			return _defaultConfiguration;
+		}
+		
+		/** Set the default configuration back to its original value 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*/
+		public static function restoreDefaults():void
+		{
+			_defaultConfiguration = null;
+		}
+		
+				
+		protected var bindingsArray:Array;
+		
+		static private const _formatImporter:TLFormatImporter = new TLFormatImporter(TextLayoutFormatValueHolder,TextLayoutFormat.description);
+		static private const _idImporter:SingletonAttributeImporter = new SingletonAttributeImporter("id");
+		static private const _styleNameImporter:SingletonAttributeImporter = new SingletonAttributeImporter("styleName");
+		static private const _customFormatImporter:CustomFormatImporter = new CustomFormatImporter();
+		
+		static private const _flowElementFormatImporters:Array = [ _formatImporter,_idImporter,_styleNameImporter,_customFormatImporter ];
+
+		/** Constructor */
+		public function TextLayoutImporter(textFlowConfiguration:IConfiguration)
+		{
+			super(textFlowConfiguration, flowNS, defaultConfiguration);
+		}
+
+		override protected function clear():void
+		{
+			bindingsArray = null;
+			super.clear();
+		}
+		
+		private static function get flowNS():Namespace
+		{
+			return new Namespace("flow", "http://ns.adobe.com/textLayout/2008");
+		}
+		
+		/**  @private */
+		override protected function parseContent(rootStory:XML):TextFlow
+		{
+			// Capture all the top-level tags of interest that can be "bound"
+			// We have to do this because the attributes are applied at the point
+			// of calling something like:
+			// span.charAttrs = characterAttrs;
+			// At one time, we just set the variable to the parameter (in the setter),
+			// but now we're copying the data into a new object. This change does
+			// not allow for us to parse the bindings in any order. Hence, we
+			// will process the potential bindings objects first, then the
+			// TextFlow objects.
+			//
+			// Also note the use of "..*" below. We are using this to traverse the
+			// XML structure looking for particular tags and at the same time allow for
+			// any namespace. So, you might see something like <flow:TextContainer> or
+			// <TextContainer> and this code will capture both cases.
+			
+			var rootName:String = rootStory.name().localName;
+			var textFlowElement:XML = rootName == "TextFlow" ? rootStory : rootStory..*::TextFlow[0];
+			if (!textFlowElement)
+			{
+				reportError(GlobalSettings.resourceStringFunction("missingTextFlow")); 
+				return null;
+			}
+			if (!checkNamespace(textFlowElement))
+				return null;
+	
+			return parseTextFlow(this, textFlowElement);
+		}
+		
+		private function parseStandardFlowElementAttributes(flowElem:FlowElement,xmlToParse:XML,importers:Array = null):void
+		{
+			if (importers == null)
+				importers = _flowElementFormatImporters;
+			// all the standard ones have to be in importers - some check needed
+			parseAttributes(xmlToParse,importers);
+			flowElem.format = extractTextFormatAttributesHelper(flowElem.format,_formatImporter) as ITextLayoutFormat;
+
+			flowElem.id = _idImporter.result as String;
+			flowElem.styleName = _styleNameImporter.result as String;
+			flowElem.userStyles = _customFormatImporter.result as Dictionary;
+		}
+		
+
+		override public function createTextFlowFromXML(xmlToParse:XML, textFlow:TextFlow = null):TextFlow
+		{
+			// allocate the TextFlow and set the TextContainer's rootElement to it.
+			var newFlow:TextFlow = null;
+			if (xmlToParse.@["id"] != undefined)
+			{
+				var flowName:String = null;
+				flowName = xmlToParse.@["id"];
+				newFlow = getBoundObjNamed(flowName, TextFlow) as TextFlow;
+			}
+
+			if (!checkNamespace(xmlToParse))
+				return newFlow;
+
+			// allocate the TextFlow and initialize the container attributes
+			if (!newFlow)
+				newFlow = new TextFlow(_textFlowConfiguration);
+	
+			parseStandardFlowElementAttributes(newFlow,xmlToParse);
+			
+			// TextFlow can have CharacterFormat, ParagraphFormat and ContainerFormat children.  Filter them out here
+			parseFlowGroupElementChildren(xmlToParse, newFlow);
+			
+			CONFIG::debug { newFlow.debugCheckNormalizeAll() ; }
+			newFlow.tlf_internal::normalize();
+			
+			newFlow.tlf_internal::applyWhiteSpaceCollapse();
+			
+			return newFlow;
+		}
+		
+		public function createDivFromXML(xmlToParse:XML):DivElement
+		{
+			// add the div element to the parent
+			var divElem:DivElement = new DivElement();
+			
+			parseStandardFlowElementAttributes(divElem,xmlToParse);
+
+			return divElem;
+		}
+		
+		public override function createParagraphFromXML(xmlToParse:XML):ParagraphElement
+		{
+			var paraElem:ParagraphElement = new ParagraphElement();
+			parseStandardFlowElementAttributes(paraElem,xmlToParse);
+			return paraElem;
+		}
+		
+		public function createTCYFromXML(xmlToParse:XML):TCYElement
+		{
+			var tcyElem:TCYElement = new TCYElement();
+			parseStandardFlowElementAttributes(tcyElem,xmlToParse);
+			return tcyElem;
+		}
+		
+			
+		static internal const _linkDescription:Object = {
+			href : new StringProperty("href",null, false, null),
+			target : new StringProperty("target",null, false, null)
+		}
+		static private const _linkFormatImporter:TLFormatImporter = new TLFormatImporter(Dictionary,_linkDescription);
+		static private const _linkElementFormatImporters:Array = [ _linkFormatImporter, _formatImporter,_idImporter,_styleNameImporter,_customFormatImporter ];
+
+		/** Parse a LinkElement Block.
+		 * 
+		 * @param - importFilter:BaseTextLayoutImporter - parser object
+		 * @param - xmlToParse:XML - the xml describing the Link
+		 * @param - parent:FlowBlockElement - the parent of the new Link
+		 * @return LinkElement - a new LinkElement and its children
+		 */
+		public function createLinkFromXML(xmlToParse:XML):LinkElement
+		{
+			var linkElem:LinkElement = new LinkElement();
+			parseStandardFlowElementAttributes(linkElem,xmlToParse,_linkElementFormatImporters);
+			if (_linkFormatImporter.result)
+			{
+				linkElem.href = _linkFormatImporter.result["href"] as String;
+				linkElem.target = _linkFormatImporter.result["target"] as String;
+			}
+
+			return linkElem;
+		}
+		
+		public override function createSpanFromXML(xmlToParse:XML):SpanElement
+		{
+			var spanElem:SpanElement = new SpanElement();
+			
+			parseStandardFlowElementAttributes(spanElem,xmlToParse);
+
+			return spanElem;
+		}
+		
+		static private const _imageDescription:Object = {
+			height:InlineGraphicElement.heightPropertyDefinition,
+			width:InlineGraphicElement.widthPropertyDefinition,
+			source: new StringProperty("source", null, false, null),
+			float: new StringProperty("float", null, false, null),
+			rotation: InlineGraphicElement.rotationPropertyDefinition }
+		
+		static private const _ilgFormatImporter:TLFormatImporter = new TLFormatImporter(Dictionary,_imageDescription);
+		static private const _ilgElementFormatImporters:Array = [ _ilgFormatImporter, _formatImporter/*,_boundTextLayoutFormatImporter*/,_idImporter,_styleNameImporter,_customFormatImporter ];
+
+		public function createInlineGraphicFromXML(xmlToParse:XML):InlineGraphicElement
+		{				
+			var imgElem:InlineGraphicElement = new InlineGraphicElement();
+			
+			parseStandardFlowElementAttributes(imgElem,xmlToParse,_ilgElementFormatImporters);
+			
+			if (_ilgFormatImporter.result)
+			{
+				var source:String = _ilgFormatImporter.result["source"];
+				imgElem.source = source;
+				
+				// if not defined then let InlineGraphic set its own default
+				imgElem.height = InlineGraphicElement.heightPropertyDefinition.setHelper(imgElem.height,_ilgFormatImporter.result["height"]);
+				imgElem.width  = InlineGraphicElement.widthPropertyDefinition.setHelper(imgElem.width,_ilgFormatImporter.result["width"]);
+				/*	We don't support rotation yet because of bugs in the player. */		
+				// imgElem.rotation  = InlineGraphicElement.heightPropertyDefinition.setHelper(imgElem.rotation,_ilgFormatImporter.result["rotation"]);
+				imgElem.float = InlineGraphicElement.floatPropertyDefinition.setHelper(imgElem.float,_ilgFormatImporter.result["float"]);
+			}
+			
+			return imgElem;
+		}
+	
+		public function extractTextFormatAttributesHelper(curAttrs:Object, importer:TLFormatImporter):Object
+		{
+			return extractAttributesHelper(curAttrs,importer);
+		}
+
+		protected function parseNamedFormatDefinition(xmlToParse:XML, importer:TLFormatImporter) : void
+		{
+			if (!checkNamespace(xmlToParse))
+				return;
+			
+			var idName:String = xmlToParse.@id.toString();
+			if (idName == null || idName.length == 0)
+				return;
+				
+			importer.reset();
+			for each (var item:XML in xmlToParse.attributes())
+				importer.importOneFormat(item.name().localName,item.toString());
+			
+			if (!bindingsArray)
+				bindingsArray = new Array();
+			bindingsArray[idName] = importer.result ? importer.result : new importer.classType();
+		}
+		
+		// Find string in array
+		static private function arrayHasString(arr:Array, str:String):Boolean
+		{
+			for each (var item:String in arr)
+				if (str == item)
+					return true;
+			return false;
+		}
+		
+		// Return a "bindings" object. This method allows us to encounter a object via a binding
+		// (it appears within "{}" or we can encounter the actual tag (e.g, <CharacterFormat ... >). Either way
+		// this method will allocate an object with the given name, and assign the attributes as they become
+		// available in the BaseTextLayoutImportFilter.
+		internal function getBoundObjNamed(name:String, typeClass:Class):Object
+		{
+			CONFIG::debug {assert(name != null && name.length > 0, "null string for a bound object")}
+			if (!bindingsArray)
+				bindingsArray = new Array();
+			if (bindingsArray[name] == null) 
+			{
+				if (typeClass == TextFlow)
+					bindingsArray[name] = new typeClass(this._textFlowConfiguration);
+				else
+					bindingsArray[name] = new typeClass();
+ 			}
+
+			return bindingsArray[name];
+		}
+
+		/** Parse a TCY Block.
+		 * 
+		 * @param - importFilter:BaseTextLayoutImporter - parser object
+		 * @param - xmlToParse:XML - the xml describing the TCY Block
+		 * @param - parent:FlowBlockElement - the parent of the new TCY Block
+		 * @return TCYBlockElement - a new TCYBlockElement and its children
+		 */
+		static public function parseTCY(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{
+			var tcyElem:TCYElement = TextLayoutImporter(importFilter).createTCYFromXML(xmlToParse);
+			if (importFilter.addChild(parent, tcyElem))
+			{
+				importFilter.parseFlowGroupElementChildren(xmlToParse, tcyElem);
+				//if parsing an empty tcy, create a Span for it.
+				if (tcyElem.numChildren == 0)
+					tcyElem.addChild(new SpanElement());
+			}
+		}
+		
+				
+		/** Parse a LinkElement Block.
+		 * 
+		 * @param - importFilter:BaseTextLayoutImporter - parser object
+		 * @param - xmlToParse:XML - the xml describing the Link
+		 * @param - parent:FlowBlockElement - the parent of the new Link
+		 * @return LinkElement - a new LinkElement and its children
+		 */
+		static public function parseLink(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{
+			var linkElem:LinkElement = TextLayoutImporter(importFilter).createLinkFromXML(xmlToParse);
+			if (importFilter.addChild(parent, linkElem))
+			{
+				importFilter.parseFlowGroupElementChildren(xmlToParse, linkElem);
+				//if parsing an empty link, create a Span for it.
+				if (linkElem.numChildren == 0)
+					linkElem.addChild(new SpanElement());
+			}
+		}
+		
+		public function createDictionaryFromXML(xmlToParse:XML):Dictionary
+		{
+			var formatImporters:Array = [ _customFormatImporter ];
+
+			// parse the TextLayoutFormat child object		
+			var formatList:XMLList = xmlToParse..*::TextLayoutFormat;
+			if (formatList.length() != 1)
+				reportError(GlobalSettings.resourceStringFunction("expectedExactlyOneTextLayoutFormat",[ xmlToParse.name() ]));
+			
+			var parseThis:XML = formatList.length() > 0 ? formatList[0] : xmlToParse;
+			parseAttributes(parseThis,formatImporters);
+			var styleDictionary:Dictionary = _customFormatImporter.result as Dictionary;
+
+			// Link style property values may have been brought through as literal String values. We need to convert
+			// them into typed values, so they get output as canonical translation of the value type into String. 
+			// The color property is an example, where it can get input in 3 different formats, but can only be output in one.
+			var description:Object = TextLayoutFormat.description;
+			for (var prop:String in description)
+			{
+				var val:* = styleDictionary[prop];
+				if (val !== undefined)
+				{
+					val = description[prop].setHelper(undefined,val)
+					if (val !== undefined)
+						styleDictionary[prop] = val;
+				}
+			}
+			
+			return styleDictionary;
+		}
+
+		static public function parseLinkNormalFormat(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{ parent.linkNormalFormat = TextLayoutImporter(importFilter).createDictionaryFromXML(xmlToParse); }
+		static public function parseLinkActiveFormat(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{ parent.linkActiveFormat = TextLayoutImporter(importFilter).createDictionaryFromXML(xmlToParse); }
+		static public function parseLinkHoverFormat(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{ parent.linkHoverFormat = TextLayoutImporter(importFilter).createDictionaryFromXML(xmlToParse); }
+
+		/** Parse the <div ...> tag and all its children
+		 * 
+		 * @param - importFilter:BaseTextLayoutImportFilter - parser object
+		 * @param - xmlToParse:XML - the xml describing the Div
+		 * @param - parent:FlowBlockElement - the parent of the new Div
+		 */
+		static public function parseDivElement(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{
+			var divElem:DivElement = TextLayoutImporter(importFilter).createDivFromXML(xmlToParse);
+			if (importFilter.addChild(parent, divElem))
+			{
+				importFilter.parseFlowGroupElementChildren(xmlToParse, divElem);
+				// we can't have a <div> tag w/no children... so, add an empty paragraph
+				if (divElem.numChildren == 0)
+					divElem.addChild(new ParagraphElement());
+			}
+		}
+
+		/** Parse a leaf element, the <img ...>  tag.
+		 * 
+		 * @param - importFilter:BaseTextLayoutImporter - parser object
+		 * @param - xmlToParse:XML - the xml describing the InlineGraphic FlowElement
+		 * @param - parent:FlowBlockElement - the parent of the new image FlowElement
+		 */
+		static public function parseInlineGraphic(importFilter:BaseTextLayoutImporter, xmlToParse:XML, parent:FlowGroupElement):void
+		{
+			var ilg:InlineGraphicElement = TextLayoutImporter(importFilter).createInlineGraphicFromXML(xmlToParse);
+			importFilter.addChild(parent, ilg);
+		}
+	}
+}
+
diff --git a/textLayout_core/.actionScriptProperties b/textLayout_core/.actionScriptProperties
new file mode 100755
index 0000000..16ab5b0
--- /dev/null
+++ b/textLayout_core/.actionScriptProperties
@@ -0,0 +1,62 @@
+# 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.
+
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<actionScriptProperties mainApplicationPath="textLayout_core.as" projectUUID="674ab66b-95bb-4550-a70c-4569862c3193" version="6">
+  <compiler additionalCompilerArguments="-locale en_US -include-namespaces library://ns.adobe.com/flashx/textLayout -load-config+=../../config.xml" autoRSLOrdering="true" copyDependentFiles="false" generateAccessible="false" htmlExpressInstall="true" htmlGenerate="false" htmlHistoryManagement="false" htmlPlayerVersionCheck="true" includeNetmonSwc="false" outputFolderPath="bin" sourceFolderPath="src" strict="true" targetPlayerVersion="10.0.0" useApolloConfig="false" useDebugRSLSwfs="true" verifyDigests="true" warn="true">
+    <compilerSourcePath/>
+    <libraryPath defaultLinkType="0">
+      <libraryPathEntry kind="4" path="">
+        <excludedEntries>
+          <libraryPathEntry kind="1" linkType="1" path="${PROJECT_FRAMEWORKS}/locale/{locale}"/>
+          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/flex.swc" useDefaultLinkType="false"/>
+          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/sparkskins.swc" useDefaultLinkType="false"/>
+          <libraryPathEntry index="4" kind="3" linkType="4" path="${PROJECT_FRAMEWORKS}/libs/rpc.swc" useDefaultLinkType="true">
+            <crossDomainRsls>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="http://fpdownload.adobe.com/pub/swz/crossdomain.xml" rslUrl="http://fpdownload.adobe.com/pub/swz/flex/4.0.0.10485/rpc_4.0.0.10485.swz"/>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="" rslUrl="rpc_4.0.0.10485.swz"/>
+            </crossDomainRsls>
+          </libraryPathEntry>
+          <libraryPathEntry index="2" kind="3" linkType="4" path="${PROJECT_FRAMEWORKS}/libs/framework.swc" useDefaultLinkType="true">
+            <crossDomainRsls>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="http://fpdownload.adobe.com/pub/swz/crossdomain.xml" rslUrl="http://fpdownload.adobe.com/pub/swz/flex/4.0.0.10485/framework_4.0.0.10485.swz"/>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="" rslUrl="framework_4.0.0.10485.swz"/>
+            </crossDomainRsls>
+          </libraryPathEntry>
+          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/datavisualization.swc" useDefaultLinkType="false"/>
+          <libraryPathEntry index="1" kind="3" linkType="4" path="${PROJECT_FRAMEWORKS}/libs/textLayout.swc" useDefaultLinkType="true">
+            <crossDomainRsls>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="http://fpdownload.adobe.com/pub/swz/crossdomain.xml" rslUrl="http://fpdownload.adobe.com/pub/swz/flex/4.0.0.10485/textLayout_4.0.0.10485.swz"/>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="" rslUrl="textLayout_4.0.0.10485.swz"/>
+            </crossDomainRsls>
+          </libraryPathEntry>
+          <libraryPathEntry index="3" kind="3" linkType="4" path="${PROJECT_FRAMEWORKS}/libs/spark.swc" useDefaultLinkType="true">
+            <crossDomainRsls>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="http://fpdownload.adobe.com/pub/swz/crossdomain.xml" rslUrl="http://fpdownload.adobe.com/pub/swz/flex/4.0.0.10485/spark_4.0.0.10485.swz"/>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="" rslUrl="spark_4.0.0.10485.swz"/>
+            </crossDomainRsls>
+          </libraryPathEntry>
+          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/utilities.swc" useDefaultLinkType="false"/>
+        </excludedEntries>
+      </libraryPathEntry>
+    </libraryPath>
+    <sourceAttachmentPath/>
+  </compiler>
+  <applications>
+    <application path="textLayout_core.as"/>
+  </applications>
+  <modules/>
+  <buildCSSFiles/>
+</actionScriptProperties>
diff --git a/textLayout_core/.flexLibProperties b/textLayout_core/.flexLibProperties
new file mode 100755
index 0000000..9740fb7
--- /dev/null
+++ b/textLayout_core/.flexLibProperties
@@ -0,0 +1,25 @@
+# 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.
+
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<flexLibProperties includeAllClasses="false" version="3">
+  <includeClasses>
+    <classEntry path="flashx.textLayout.CoreClasses"/>
+  </includeClasses>
+  <includeResources/>
+  <namespaceManifests>
+    <namespaceManifestEntry manifest="../manifest.xml" namespace="library://ns.adobe.com/flashx/textLayout"/>
+  </namespaceManifests>
+</flexLibProperties>
diff --git a/textLayout_core/.project b/textLayout_core/.project
new file mode 100755
index 0000000..4941a7c
--- /dev/null
+++ b/textLayout_core/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<projectDescription>
+	<name>textLayout_core</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.adobe.flexbuilder.project.flexbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.adobe.flexbuilder.project.flexlibnature</nature>
+		<nature>com.adobe.flexbuilder.project.actionscriptnature</nature>
+	</natures>
+</projectDescription>
diff --git a/textLayout_core/manifest.xml b/textLayout_core/manifest.xml
new file mode 100755
index 0000000..d72337c
--- /dev/null
+++ b/textLayout_core/manifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<componentPackage>
+  <component id="TextLayoutFormat" class="flashx.textLayout.formats.TextLayoutFormat" />
+  <component id="div" class="flashx.textLayout.elements.DivElement" />
+  <component id="img" class="flashx.textLayout.elements.InlineGraphicElement" />
+  <component id="a" class="flashx.textLayout.elements.LinkElement" />
+  <component id="p" class="flashx.textLayout.elements.ParagraphElement" />
+  <component id="br" class="flashx.textLayout.elements.BreakElement" />
+  <component id="tab" class="flashx.textLayout.elements.TabElement" />
+  <component id="tcy" class="flashx.textLayout.elements.TCYElement" />
+  <component id="span" class="flashx.textLayout.elements.SpanElement" />
+  <component id="TextFlow" class="flashx.textLayout.elements.TextFlow" />
+</componentPackage>
diff --git a/textLayout_core/src/flashx/textLayout/BuildInfo.as b/textLayout_core/src/flashx/textLayout/BuildInfo.as
new file mode 100755
index 0000000..ab59413
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/BuildInfo.as
@@ -0,0 +1,58 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout
+{
+	[ExcludeClass]
+	/**
+	 * Contains identifying information for the current build. 
+	 * This may not be the form that this information is presented in the final API.
+	 */
+	public class BuildInfo
+	{
+		/**
+		 * Contains the current version number. 
+		 */
+		public static const VERSION:String = "1.0";
+		
+		/**
+		 * Contains the current build number. 
+		 * It is static and can be called with <code>BuildInfo.kBuildNumber</code>
+		 * <p>String Format: "BuildNumber (Changelist)"</p>
+		 */
+		public static const kBuildNumber:String = "595 (738907)";
+		
+		/**
+		 * Contains the branch name. 
+		 */
+		public static const kBranch:String = "1.0";
+
+		/**
+		 * @private 
+		 */
+		public static const AUDIT_ID:String = "<AdobeIP 0000486>";
+		
+		/**
+		 * @private 
+		 */
+		public function dontStripAuditID():String
+		{
+			return AUDIT_ID;
+		}
+	}
+}	// package
diff --git a/textLayout_core/src/flashx/textLayout/CoreClasses.as b/textLayout_core/src/flashx/textLayout/CoreClasses.as
new file mode 100755
index 0000000..d86b5cb
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/CoreClasses.as
@@ -0,0 +1,147 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout
+{
+ 	internal class CoreClasses
+	{
+		import flashx.textLayout.tlf_internal; tlf_internal;
+		
+		import flashx.textLayout.accessibility.TextAccImpl; TextAccImpl;
+		
+		import flashx.textLayout.BuildInfo; BuildInfo;
+
+		import flashx.textLayout.compose.BaseCompose; BaseCompose;
+		import flashx.textLayout.compose.ComposeState; ComposeState;
+		import flashx.textLayout.compose.FlowComposerBase; FlowComposerBase;
+		import flashx.textLayout.compose.FlowDamageType; FlowDamageType;
+		import flashx.textLayout.compose.IFlowComposer; IFlowComposer;
+		import flashx.textLayout.compose.ITextLineCreator; ITextLineCreator;
+		import flashx.textLayout.compose.ISWFContext; ISWFContext;
+		import flashx.textLayout.compose.IVerticalJustificationLine; IVerticalJustificationLine;
+		import flashx.textLayout.compose.Parcel; Parcel;
+		import flashx.textLayout.compose.ParcelList; ParcelList;
+		import flashx.textLayout.compose.SimpleCompose; SimpleCompose;
+		import flashx.textLayout.compose.TextFlowLine; TextFlowLine;
+		import flashx.textLayout.compose.TextFlowLineLocation; TextFlowLineLocation;
+		import flashx.textLayout.compose.TextLineRecycler; TextLineRecycler;
+		import flashx.textLayout.compose.StandardFlowComposer; StandardFlowComposer;
+		import flashx.textLayout.compose.VerticalJustifier; VerticalJustifier;
+		
+		import flashx.textLayout.container.ColumnState; ColumnState;		
+		import flashx.textLayout.container.ContainerController; ContainerController;
+		import flashx.textLayout.container.ISandboxSupport; ISandboxSupport;
+		import flashx.textLayout.container.ScrollPolicy; ScrollPolicy;
+				
+		import flashx.textLayout.debug.assert;
+		import flashx.textLayout.debug.Debugging; Debugging;
+		
+		import flashx.textLayout.edit.EditingMode; EditingMode;
+		import flashx.textLayout.edit.IInteractionEventHandler; IInteractionEventHandler;
+		import flashx.textLayout.edit.ISelectionManager; ISelectionManager;
+		import flashx.textLayout.edit.SelectionFormat; SelectionFormat;
+		import flashx.textLayout.edit.SelectionState; SelectionState;
+		import flashx.textLayout.elements.TextRange; TextRange;
+		
+		import flashx.textLayout.elements.BreakElement; BreakElement;
+		import flashx.textLayout.elements.Configuration; Configuration;
+		import flashx.textLayout.elements.ContainerFormattedElement; ContainerFormattedElement;
+		import flashx.textLayout.elements.DivElement; DivElement;
+		import flashx.textLayout.elements.FlowElement; FlowElement;
+		import flashx.textLayout.elements.FlowGroupElement; FlowGroupElement;
+		import flashx.textLayout.elements.FlowLeafElement; FlowLeafElement;
+		import flashx.textLayout.elements.GlobalSettings; GlobalSettings;
+		import flashx.textLayout.elements.IConfiguration; IConfiguration;
+		import flashx.textLayout.elements.IFormatResolver; IFormatResolver;
+		import flashx.textLayout.elements.InlineGraphicElement; InlineGraphicElement;
+		import flashx.textLayout.elements.InlineGraphicElementStatus; InlineGraphicElementStatus;
+		import flashx.textLayout.elements.LinkElement; LinkElement;
+		import flashx.textLayout.elements.LinkState; LinkState;
+		import flashx.textLayout.elements.OverflowPolicy; OverflowPolicy;
+		import flashx.textLayout.elements.ParagraphElement; ParagraphElement;
+		import flashx.textLayout.elements.ParagraphFormattedElement; ParagraphFormattedElement;
+		import flashx.textLayout.elements.SpanElement; SpanElement;
+		import flashx.textLayout.elements.SpecialCharacterElement; SpecialCharacterElement;
+		import flashx.textLayout.elements.SubParagraphGroupElement; SubParagraphGroupElement;
+		import flashx.textLayout.elements.TabElement; TabElement;
+		import flashx.textLayout.elements.TCYElement; TCYElement;
+		import flashx.textLayout.elements.TextFlow; TextFlow;
+		import flashx.textLayout.elements.TextRange; TextRange;
+		
+		import flashx.textLayout.events.CompositionCompleteEvent; CompositionCompleteEvent;
+		import flashx.textLayout.events.DamageEvent; DamageEvent;
+		import flashx.textLayout.events.FlowElementMouseEvent; FlowElementMouseEvent;
+		import flashx.textLayout.events.ModelChange; ModelChange;
+		import flashx.textLayout.events.StatusChangeEvent; StatusChangeEvent;
+		import flashx.textLayout.events.TextLayoutEvent; TextLayoutEvent;
+		
+		import flashx.textLayout.factory.TextLineFactoryBase; TextLineFactoryBase;
+		import flashx.textLayout.factory.StringTextLineFactory; StringTextLineFactory;
+		import flashx.textLayout.factory.TextFlowTextLineFactory; TextFlowTextLineFactory;
+		import flashx.textLayout.factory.TruncationOptions; TruncationOptions;		
+
+		import flashx.textLayout.formats.BaselineOffset; BaselineOffset;
+		import flashx.textLayout.formats.BaselineShift; BaselineShift;
+		import flashx.textLayout.formats.BlockProgression; BlockProgression;
+
+		import flashx.textLayout.formats.Category; Category;
+		import flashx.textLayout.formats.Direction; Direction;
+		import flashx.textLayout.formats.Float; Float;
+		import flashx.textLayout.formats.FlowElementDisplayType; FlowElementDisplayType;
+		import flashx.textLayout.formats.FormatValue; FormatValue;
+		import flashx.textLayout.formats.IMEStatus; IMEStatus;
+		import flashx.textLayout.formats.ITextLayoutFormat; ITextLayoutFormat;
+		import flashx.textLayout.formats.ITabStopFormat; ITabStopFormat;
+		import flashx.textLayout.formats.JustificationRule; JustificationRule;
+		import flashx.textLayout.formats.LeadingModel; LeadingModel;
+		import flashx.textLayout.formats.LineBreak; LineBreak;
+		import flashx.textLayout.formats.TabStopFormat; TabStopFormat;
+		import flashx.textLayout.formats.TextAlign; TextAlign;
+		import flashx.textLayout.formats.TextDecoration; TextDecoration;
+		import flashx.textLayout.formats.TextJustify; TextJustify;
+		import flashx.textLayout.formats.TextLayoutFormat; TextLayoutFormat;		
+		import flashx.textLayout.formats.TextLayoutFormatValueHolder; TextLayoutFormatValueHolder;		
+		import flashx.textLayout.formats.VerticalAlign; VerticalAlign;
+		import flashx.textLayout.formats.WhiteSpaceCollapse; WhiteSpaceCollapse;
+
+		import flashx.textLayout.property.ArrayProperty; ArrayProperty;
+		import flashx.textLayout.property.BooleanProperty; BooleanProperty;
+		import flashx.textLayout.property.EnumStringProperty; EnumStringProperty;
+		import flashx.textLayout.property.IntProperty; IntProperty;
+		import flashx.textLayout.property.IntWithEnumProperty; IntWithEnumProperty;
+		import flashx.textLayout.property.NumberOrPercentOrEnumProperty; NumberOrPercentOrEnumProperty;
+		import flashx.textLayout.property.NumberOrPercentProperty; NumberOrPercentProperty;
+		import flashx.textLayout.property.NumberProperty; NumberProperty;
+		import flashx.textLayout.property.NumberWithEnumProperty; NumberWithEnumProperty;
+		import flashx.textLayout.property.Property; Property;
+		import flashx.textLayout.property.StringProperty; StringProperty;
+		import flashx.textLayout.property.UintProperty; UintProperty;
+		
+		import flashx.textLayout.utils.CharacterUtil; CharacterUtil;
+		import flashx.textLayout.utils.GeometryUtil; GeometryUtil;
+		
+		// Alphabetical list of classes to be included as part of text_model.swc.
+		// This should mirror what's in the .flexLibProperties
+		
+		CONFIG::release public function exportAssert():void
+		{
+			assert();
+		}
+	}
+}
+
diff --git a/textLayout_core/src/flashx/textLayout/accessibility/TextAccImpl.as b/textLayout_core/src/flashx/textLayout/accessibility/TextAccImpl.as
new file mode 100755
index 0000000..c576e72
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/accessibility/TextAccImpl.as
@@ -0,0 +1,428 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.accessibility
+{
+	import flash.accessibility.Accessibility;
+	import flash.accessibility.AccessibilityImplementation;
+	import flash.accessibility.AccessibilityProperties;
+	import flash.display.DisplayObject;
+	import flash.events.Event;
+	
+	import flashx.textLayout.edit.EditingMode;
+	import flashx.textLayout.edit.ISelectionManager;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.GlobalSettings;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.events.CompositionCompleteEvent;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+    //TODO this is in text_edit... which violates MVC yet again... what to do?
+    //import flashx.textLayout.events.SelectionEvent;
+    
+	//TODO handle selectable text when FP implements the new selection API:
+	//     http://frpbugapp.macromedia.com/bugapp/detail.asp?id=217540
+	//     To catch the selection changes reliably, listen for SelectionEvent,
+	//     which is dispatched on the TextFlow whenever the selection changes.
+
+    //TODO handle scrolling? might need to expose scrolling in here
+    
+	//TODO handle hyperlinks? I don't know if MSAA has a concept for this
+	//    (what other text advanced features must be accessible? graphics?)
+	//TODO what if there is HTML in it? strip it, or read it? we don't have an
+	//     htmlText property, do we?
+
+    // TODO Do we want to read the contents of each sprite and stop, even if the
+    // text flows into other sprite, meaning we read text in taborder; or do we
+    // want to read the entire model and not worry about the presentation
+    // (simpler)? Not sure if I can get the contents of each sprite separately.
+    
+    // TODO TESTING:
+    //   * Test that JAWS reads when setting the focus programmatically.
+    //   * Tests for changing every part of the model programmatically -- role
+    //     and state should update accordingly, visibility, and text contents.
+    //   * Test that setting tabOrder reads as expected. What happens if you set
+    //     tabOrder on multiple flowComposers?
+    
+    //TODO update this comment after integration
+	/**
+	 * @private
+	 * The TextAccImpl class adds accessibility for text components.
+	 * This hooks into DisplayObjects when TextFlow.container is set.
+	 */
+	public class TextAccImpl extends AccessibilityImplementation
+	{
+	    //TODO might want to put these constants in a new class if they are
+	    //     used anywhere else.
+	    
+		/** Default state */
+		protected static const STATE_SYSTEM_NORMAL:uint = 0x00000000;
+		
+		/** Read-only text */
+		protected static const STATE_SYSTEM_READONLY:uint = 0x00000040;
+		
+		/** Inivisible text */
+		//TODO unused, but supported state for text in MSAA
+		protected static const STATE_SYSTEM_INVISIBLE:uint = 0x00008000;
+		
+		/** Default role -- read-only, unselectable text. */
+		protected static const ROLE_SYSTEM_STATICTEXT:uint = 0x29;
+		
+		/** Editable OR read-only, selectable text. */
+		protected static const ROLE_SYSTEM_TEXT:uint = 0x2a;
+		
+		/* When the name changes (name is the text conent in STATICTEXT). */
+		protected static const EVENT_OBJECT_NAMECHANGE:uint = 0x800c;
+		
+		/* When the value changes (value is the text content in TEXT). */
+		protected static const EVENT_OBJECT_VALUECHANGE:uint = 0x800e;
+	
+		/**
+		 *  A reference to the DisplayObject that is hosting accessible text.
+		 */
+		//TODO for now this assumes only the first DO in a flow is accessible
+		//     in the future each flow DO should host its own accimpl and read
+		//     the text only for its own box.
+		//
+		//     Or... perhaps we use getChildIDArray to manage all the text
+		//     flows if they are linked below some master component (but I don't
+		//     think this is the way it will happen).
+		protected var textContainer:DisplayObject;
+		
+		/**
+		 *  A reference to the TextFlow where our text originates.
+		 */
+		protected var textFlow:TextFlow;
+		
+		/**
+		 *  Constructor.
+		 * 
+		 *  @param textContainer The DisplayObject instance that this
+		 *                       TextAccImpl instance is making accessible.
+		 *  @param textFlow The TextFlow that is hosting the textContainer.
+		 */
+		public function TextAccImpl(textCont:DisplayObject, textFlow:TextFlow)
+		{
+			super();
+	
+			this.textContainer = textCont;
+			this.textFlow = textFlow;
+			
+			// stub is true when you are NOT providing an acc implementation
+			// reports to reader as graphic
+			stub = false;
+			
+			if (textCont.accessibilityProperties == null)
+			{
+    			textCont.accessibilityProperties =
+    			    new AccessibilityProperties();
+			}
+
+            //TODO
+            // setup event listeners for text selection and model changes
+            //textFlow.addEventListener(SelectionEvent.SELECTION_CHANGE,
+            //                          eventHandler);
+            textFlow.addEventListener(CompositionCompleteEvent.COMPOSITION_COMPLETE, eventHandler);
+		}
+		
+		public function detachListeners():void
+		{
+			textFlow.removeEventListener(CompositionCompleteEvent.COMPOSITION_COMPLETE, eventHandler);
+		}
+		
+		/**
+		 *  Returns the system role for the text.
+		 *
+		 *  @param childID uint.
+		 *  @return Role associated with the text.
+		 */
+		override public function get_accRole(childID:uint):uint
+		{
+		    // trace("get_accRole()");
+		    
+		    const iManager:ISelectionManager = textFlow.interactionManager;
+		    if (iManager == null)
+		    {
+		        // non-selectable, non-editable text is STATICTEXT
+		        return ROLE_SYSTEM_STATICTEXT
+		    }
+		    else // iManager is an IEditManager and/or ISelectionManager
+		    {
+		        // read-only selectable or editable selectable text are TEXT
+		        return ROLE_SYSTEM_TEXT;
+		    }
+		}
+		
+		/**
+		 *  Returns the state of the text.
+		 *
+		 *  @param childID uint.
+		 *  @return Role associated with the text.
+		 */
+		override public function get_accState(childID:uint):uint
+		{
+		    // trace("get_accState()");
+		    
+		    const iManager:ISelectionManager = textFlow.interactionManager;
+		    
+		    //TODO handle STATE_SYSTEM_INVISIBLE for all cases below
+		    //     and add an event to detect changes--does Flash support this?
+		    
+		    //TODO handle STATE_SYSTEM_PROTECTED for all cases below
+		    //     if vellum gets a concept of password fields, then it needs to 
+		    //     emit this value if the field is converted to a password;
+		    //     otherwise the Flex framework will need to be sure to emit
+		    //     this state in a text input component.
+		    
+		    // note: focus-related states are handled by the player
+		    
+		    if (iManager == null)
+		    {
+		        // non-selectable, non-editable text
+		        return STATE_SYSTEM_READONLY;
+		    }
+		    // must check IEditManager before ISelectionManager (it can be both)
+		    else if (iManager.editingMode == EditingMode.READ_WRITE)
+		    {
+		        // editable selectable text
+		        return STATE_SYSTEM_NORMAL;
+		    }
+		    else // if (iManager instanceof ISelectionManager)
+		    {
+		        // read-only selectable text
+		        return STATE_SYSTEM_READONLY;
+		    }
+		}
+		
+		/**
+		 *  Returns the name of the text.
+		 *
+		 *  @param childID uint.
+		 *  @return Name of the text.
+		 */
+		override public function get_accName(childID:uint):String
+		{
+		    // trace("get_accName()");
+		    
+		    switch (get_accRole(childID))
+		    {
+    		    case ROLE_SYSTEM_STATICTEXT:
+    		    {
+        		    //TODO this SHOULD come from TextConverter, but then there is a
+        		    //     circular build dependency since importExport builds
+        		    //     against model, and it probably violates mvc
+        			//return TextConverter.export(textFlow,
+        			//                         TextConverter.PLAIN_TEXT_FORMAT);
+        			
+        			//TODO this is probably expensive. is there a way to cache
+        			//      this and know when dirty?
+        			//TODO  look at the generation and determine when it's dirty
+        			return exportToString(textFlow);
+    		    }
+    		    
+		        case ROLE_SYSTEM_TEXT:
+		        default:
+            		return null;
+    		}
+		}
+		
+		/**
+		 *  Returns the value of the text.
+		 *
+		 *  @param childID uint.
+		 *  @return Name of the text.
+		 */
+		override public function get_accValue(childID:uint):String
+		{
+		    // trace("get_accValue()");
+		    
+		    switch (get_accRole(childID))
+		    {
+		        case ROLE_SYSTEM_TEXT:
+    		    {
+        		    //TODO this SHOULD come from TextConverter, but then there is a
+        		    //     circular build dependency since importExport builds
+        		    //     against model, and it probably violates mvc
+        			//return TextConverter.export(textFlow,
+        			//                         TextConverter.PLAIN_TEXT_FORMAT);
+        			
+        			// TODO this is probably expensive. is there a way to cache
+        			//      this and know when dirty?
+        			//TODO  look at the generation and determine when it's dirty
+        			return exportToString(textFlow);
+    		    }
+    		    
+    		    case ROLE_SYSTEM_STATICTEXT:
+		        default:
+            		return null;
+    		}
+		}
+
+		/**
+		 * Handles COMPOSITION_COMPLETE and SELECTION_CHANGE events,
+		 * updates the MSAA model.
+    	 */
+    	protected function eventHandler(event:Event):void
+    	{
+    		switch (event.type)
+    		{
+                // This updates the entire accessibility DOM.
+                // get_accName is probably expensive here, it happens ONLY if
+                // JAWS is running, otherwise Accessibility.* calls are NOOP.
+                //
+                // Event does NOT fire when interactionManager changes; ideally
+                // we'd want to tell MSAA the role changed, but apparently roles
+                // are typically static and that's not a supported workflow.
+                // instead, Flash occasionally polls the displaylist, e.g. when
+                // you mouseover. calling updateProperties() doesn't necessarily
+                // trigger role updates (calls to get_acc*()).
+    			case CompositionCompleteEvent.COMPOSITION_COMPLETE:
+    			{
+    			    // TODO change childID from 0 if we use getChildIDArray
+    			    //      otherwise delete this comment
+	 				try {
+	    				Accessibility.sendEvent(textContainer, 0,
+    					                        EVENT_OBJECT_NAMECHANGE);
+    					Accessibility.sendEvent(textContainer, 0,
+    					                        EVENT_OBJECT_VALUECHANGE);
+    					Accessibility.updateProperties();
+					} catch (e_err:Error) {
+	 					// generic error occurred.
+                        // this can happen in the SA player since there is no
+                        // Accessibility implementation.
+	 				}
+    				break;
+    			}
+    			
+                //TODO when we have the FP selection APIs
+    			// case SelectionEvent.SELECTION_CHANGE:
+    			// {
+                //   // this is just stubbed code, I don't know what *needs* to
+                //   // be done for SELECTION_CHANGE
+    			// 	Accessibility.sendEvent(textContainer, 0,
+    			//                          EVENT_OBJECT_TEXTSELECTIONCHANGED);
+    			// 	Accessibility.updateProperties();
+    			// 	break;
+    			// }
+    		}
+    	}
+		
+		/**
+		 * TODO HACK, remove and refactor.
+		 * 
+		 * This is copied from PlainTextExportFilter, which I would prefer to
+		 * access through TextConverter.export(textFlow,
+		 *                                  TextConverter.PLAIN_TEXT_FORMAT);
+		 * 
+		 * But, PTEF is in importExport, which builds against text_model,
+		 * which is a circular dependency.
+		 * 
+		 * Also, it seems to be adding a trailing newline, which is bad for
+		 * accessibility unless it is really there.
+		 * 
+		 * Might want to export and strip out hyphens.
+		 * Move it to the model?
+		 */
+		private static function exportToString(source:TextFlow):String
+		{
+			var leaf:FlowLeafElement = source.getFirstLeaf();
+			var rslt:String = "";
+			var curString:String = "";
+			var discretionaryHyphen:String = String.fromCharCode(0x00AD);
+			while (leaf)
+			{
+            	var p:ParagraphElement = leaf.getParagraph();
+            	while (true)
+            	{
+            		curString = leaf.text;
+            		
+            		//split out discretionary hyphen and put string back together
+					var temparray:Array = curString.split(discretionaryHyphen);
+					curString = temparray.join("");
+					
+	               	rslt += curString;
+					leaf = leaf.getNextLeaf(p);
+					if (!leaf)
+                    {
+                        // we want newlines between paragraphs but not at the end
+                    	rslt += "\n";
+						break;
+					}
+            	}
+            	leaf = p.getLastLeaf().getNextLeaf();
+   			}
+   			return rslt;
+		}
+		
+		/** 
+		 * The zero-based character index value of the first character in the current selection.
+		 * Components which wish to support inline IME or Accessibility should call into this method.
+		 *
+		 * @return the index of the character at the anchor end of the selection, or <code>-1</code> if no text is selected.
+		 * 
+		 * @playerversion Flash 10.0
+		 * @langversion 3.0
+		 */
+		public function get selectionActiveIndex():int
+		{
+			var selMgr:ISelectionManager = textFlow.interactionManager;
+			var selIndex:int = -1;
+			if(selMgr && selMgr.editingMode != EditingMode.READ_ONLY)
+			{
+				selIndex = selMgr.activePosition;
+			}
+			
+			return selIndex;
+		}
+		
+		/** 
+		 * The zero-based character index value of the last character in the current selection.
+		 * Components which wish to support inline IME or Accessibility should call into this method.
+		 *
+		 * @return the index of the character at the active end of the selection, or <code>-1</code> if no text is selected.
+		 * 
+		 * @playerversion Flash 10.0
+		 * @langversion 3.0
+		 */
+		public function get selectionAnchorIndex():int
+		{
+			var selMgr:ISelectionManager = textFlow.interactionManager;
+			var selIndex:int = -1;
+			if(selMgr && selMgr.editingMode != EditingMode.READ_ONLY)
+			{
+				selIndex = selMgr.anchorPosition;
+			}
+			
+			return selIndex;
+		}
+		
+		/** Enable search index for Ichabod
+		 * Returns the entire text of the TextFlow, or null if search index is not enabled
+		 * @see GlobalSettings.searchIndexEnabled
+		 */
+		public function get searchText():String
+		{
+			return GlobalSettings.enableSearch ? textFlow.getText() : null;
+		}
+		
+	}
+}
+
diff --git a/textLayout_core/src/flashx/textLayout/compose/BaseCompose.as b/textLayout_core/src/flashx/textLayout/compose/BaseCompose.as
new file mode 100755
index 0000000..3dc4060
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/compose/BaseCompose.as
@@ -0,0 +1,1287 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{
+	import flash.geom.Rectangle;
+	import flash.text.engine.TextBaseline;
+	import flash.text.engine.TextBlock;
+	import flash.text.engine.TextLine;
+	
+	import flashx.textLayout.*;
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.debug.Debugging;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.*;
+	import flashx.textLayout.formats.*;
+	import flashx.textLayout.utils.LocaleUtil;
+	
+	use namespace tlf_internal;
+	
+	
+	[ExcludeClass]
+	/** @private Common composer base class */
+	public class BaseCompose
+	{
+		
+		public static function get globalSWFContext():ISWFContext
+		{ 
+			return GlobalSWFContext.globalSWFContext; 
+		}
+		
+		protected var _parcelList:IParcelList;
+		
+		/** List of areas we're composing into, matches the container's bounding box */
+		public function get parcelList():IParcelList
+		{ return _parcelList; }
+		
+		/** Element of current location */
+		protected var _curElement:FlowLeafElement;		
+		/** Absolute start position of _curElement */
+		protected var _curElementStart:int;		
+		/** Offset from element start to current location */
+		protected var _curElementOffset:int;		
+		/** ParagraphElement that contains the current location */
+		protected var _curParaElement:ParagraphElement;	
+		protected var _curParaFormat:ITextLayoutFormat;
+		/** Absolute start position of _curParaElement */
+		protected var _curParaStart:int;
+		/** leading direction for the current line's para (set when line is being composed and committed to _lastLineLeadingModel when line is finalized) */
+		private var _curLineLeadingModel:String = "";
+		/** leading amount for the current line (set when line is being composed and committed to _lastLineLeading when line is finalized) */
+		private var _curLineLeading:Number;
+		/** leading direction for the last line's para */
+		protected var _lastLineLeadingModel:String = "";
+		/** leading amount for the last line */
+		protected var _lastLineLeading:Number;
+		/** descent of the last line */
+		protected var _lastLineDescent:Number;
+		/** Amount of spaceAfter added to the previous line */
+		protected var _spaceCarried:Number;
+		/** BlockProgression - vertical horizontal etc. @see text.formats.BlockProgression */
+		protected var _blockProgression:String;
+		
+		/** Minimum left edge coordinate across all the parcels in a controller */
+		private var _controllerLeft:Number;
+		/** Minimum top edge across all the parcels in a controller */
+		private var _controllerTop:Number;
+		/** Maximum right edge coordinate across all the parcels in a controller */
+		private var _controllerRight:Number;
+		/** Maximum bottom edge coordinate across all the parcels in a controller */
+		private var _controllerBottom:Number;
+		
+		/** Maximum horizontal extension from left/right edge of the parcel.  Alignment width for the parcel. */
+		protected var _contentLogicalExtent:Number;
+		/* Commited extent any lines needing additional alignment must update this number */
+		protected var _contentCommittedExtent:Number;
+		
+		/** Minimum left edge coordinate across all the parcels in a controller */
+		protected var _parcelLeft:Number;
+		/** Minimum top edge across all the parcels in a controller */
+		protected var _parcelTop:Number;
+		/** Maximum right edge coordinate across all the parcels in a controller */
+		protected var _parcelRight:Number;
+		/** Maximum bottom edge coordinate across all the parcels in a controller */
+		protected var _parcelBottom:Number;
+		
+		/** owning textFlow of current compose */
+		protected var _textFlow:TextFlow;
+		private var _releaseLineCreationData:Boolean;
+		/** flowComposer of current compose */
+		protected var _flowComposer:StandardFlowComposer;
+		/** rootElement of current compose */
+		protected var _rootElement:ContainerFormattedElement;
+		/** position to stop composing at */
+		protected var _stopComposePos:int;
+		
+		/** First damaged controller to begin composing */
+		protected var _startController:ContainerController;
+		/** Beginning composition position.  Note this gets cleared once its been passed */
+		protected var _startComposePosition:int;
+		
+		
+		// scratch line slugs
+		static protected var _candidateLineSlug:Rectangle = new Rectangle();
+		static protected var _lineSlug:Rectangle = new Rectangle();
+		
+		// scratch array for holding lines awaiting alignment
+		static private var _alignLines:Array;
+		
+		/** Parcel we are composing - used for keeping track of when it changes b/c parcelList.parcel may have advanced */
+		protected var _curParcel:Parcel;
+		
+		/** Start position of _curParcel */
+		protected var _curParcelStart:int;
+		
+		/** Constructor. */
+		public function  BaseCompose()
+		{	
+			
+		}
+		
+		protected function createParcelList():IParcelList
+		{ return null; }
+		protected function releaseParcelList(list:IParcelList):void
+		{ }
+		
+		/** Starting controller for skipping ahead */
+		public function get startController():ContainerController
+		{ return _startController; }
+		
+		/** prevent any leaks. @private */
+		tlf_internal function releaseAnyReferences():void
+		{
+			_curElement = null;
+			_curParaElement = null;
+			_curParaFormat = null;
+			_flowComposer = null;
+			_parcelList = null;
+			_rootElement = null;
+			_startController = null;
+			_textFlow = null;
+		}
+		
+		/** Initialize for a composition that will compose up through the controllerEndIndex, or all the way to the end of the flow
+		 * @param composer
+		 * @param composeToPosition 	-1 means not specified.  0 means request to compose nothing, >0 specifies a position to force compose to
+		 * @param controllerEndIndex	index of the last controller to compose for, or -1 to compose through all controllers
+		 */
+		protected function  initializeForComposer(composer:IFlowComposer, composeToPosition:int, controllerEndIndex:int):void
+		{
+			_parcelList = createParcelList();
+			_parcelList.notifyOnParcelChange = parcelHasChanged;
+			
+			_spaceCarried = 0;
+			// TODO: just use the rootElement for table cells
+			_blockProgression = composer.rootElement.computedFormat.blockProgression;
+			// for a non-specified compose position the ParcelList handles the bail out - just set to textLength
+			_stopComposePos = composeToPosition >= 0 ? Math.min(_textFlow.textLength,composeToPosition) : _textFlow.textLength;
+			
+			// this chains through the list - tell it if a "care about" comopseToPosition was specified
+			_parcelList.beginCompose(composer, controllerEndIndex, composeToPosition > 0);	
+			
+			_contentLogicalExtent = 0;
+			_contentCommittedExtent = 0;
+		}
+		
+		/*
+		* Compose an inline-block element, used for tables or other inline-blocks. The
+		* element has a container associated with it, and the container is going to be placed
+		* after the current paragraph if it fits in the text container.
+		* 
+		* @param composeFrame	the text container we're composing into
+		*/
+		protected function composeFloat(elem:ContainerFormattedElement,composeFrame:ContainerController):void
+		{
+			// Should get handled in derived class
+			CONFIG::debug { assert(false, "Floats are not supported in ComposeState"); }
+		}
+		
+		/** Called when we are about to compose a line. Handler for derived classes to override default behavior. */
+		protected function startLine():void
+		{
+			// does nothing
+		}
+		
+		/** Called when we are finished composing a line. Handler for derived classes to override default behavior.  */
+		protected function endLine():void
+		{
+			// does nothing
+		}		
+		
+		private function composeBlockElement(elem:FlowGroupElement,absStart:int):Boolean
+		{	
+			// Compose all the children, until all the containers are filled, or if we're on the last container, we've hit the stop compose text index
+			var idx:int;
+			if (_startComposePosition != 0)
+			{
+				idx = elem.findChildIndexAtPosition(_startComposePosition-absStart);
+				CONFIG::debug { assert(idx != -1,"Bad _startComposePosition to index in composeBlockElement"); }
+				absStart += elem.getChildAt(idx).parentRelativeStart;
+			}
+			else
+				idx = 0;
+			
+			for (; idx < elem.numChildren && (absStart <= _stopComposePos || ! parcelList.atLast()); idx++)
+			{
+				var child:FlowElement = elem.getChildAt(idx);
+				
+				var para:ParagraphElement = child as ParagraphElement;
+				if (para)
+				{
+					var rslt:Boolean = composeParagraphElement(para,absStart);
+					// we need to flush each TextBlock - this saves a lot of memory at the cost of performance during editing	
+					// note that this is a nop on older players.  only newer players implement flush	
+					if (releaseLineCreationData)
+						para.releaseLineCreationData();
+					if (!rslt)
+						return false;	// done
+				}
+				else if (child.display == FlowElementDisplayType.FLOAT)
+				{
+					composeFloat(ContainerFormattedElement(child),_parcelList.controller);
+					if (_parcelList.atEnd())
+						return false;
+					CONFIG::debug { assert(child.getAbsoluteStart() + child.textLength - _parcelList.controller.absoluteStart >= 0, "frame has negative composition"); }
+				}
+				else 
+				{
+					if (!composeBlockElement(FlowGroupElement(child),absStart))
+						return false;
+				}
+				
+				absStart += child.textLength;
+			}
+			return true;
+		}
+		
+		// TODO: move somewhere reasonable
+		
+		private static function doNothingOnParcelChange(newParcel:Parcel):void
+		{ }
+		
+		
+		/**
+		 * Compose the flow into the text container. Starts at the root element,
+		 * and composes elements until either there are no more elements, or the
+		 * text container is full. It will compose only the lines which are
+		 * marked invalid, so that existing lines that are unchanged are not
+		 * recomposed.
+		 */
+		public function composeTextFlow(textFlow:TextFlow, composeToPosition:int, controllerEndIndex:int):int
+		{
+			_textFlow = textFlow;
+			_releaseLineCreationData = textFlow.configuration.releaseLineCreationData && Configuration.playerEnablesArgoFeatures;
+			
+			// must setup _startController and _startComposePosition
+			initializeForComposer(textFlow.flowComposer, composeToPosition, controllerEndIndex);
+			
+			_flowComposer = _textFlow.flowComposer as StandardFlowComposer;
+			_rootElement = textFlow;
+			_curElementOffset = 0;
+			_curElement = _rootElement.getFirstLeaf();	
+			
+			_curElementStart = 0;		// current position in the text (start of current line)
+			
+			_curParcel = null;
+			resetControllerBounds();
+			
+			if (_startController != _flowComposer.getControllerAt(0))
+			{
+				var cacheNotify:Function = _parcelList.notifyOnParcelChange;
+				_parcelList.notifyOnParcelChange =  doNothingOnParcelChange;
+				// skip parcels until the first one in startController
+				while(_parcelList.currentParcel.controller != _startController)
+					_parcelList.next();
+				_parcelList.notifyOnParcelChange =  cacheNotify;
+			}
+			
+			parcelHasChanged(_parcelList.currentParcel);		// force start of composition acccounting initialization
+			
+			composeInternal(_rootElement,0);
+			
+			for (;;)
+			{
+				if (parcelList.atEnd())
+				{
+					parcelHasChanged(null);		// force end of composition accounting for the parcel
+					break;
+				}				
+				parcelList.next();
+			}
+			
+			
+			releaseParcelList(_parcelList);
+			_parcelList = null;
+			
+			return _curElementStart + _curElementOffset;		// Return last composed position
+		}
+		
+		private function resetControllerBounds():void
+		{
+			_controllerLeft = TextLine.MAX_LINE_WIDTH;
+			_controllerTop = TextLine.MAX_LINE_WIDTH;
+			_controllerRight = -TextLine.MAX_LINE_WIDTH;
+			_controllerBottom = -TextLine.MAX_LINE_WIDTH;
+		}
+		
+		/** Release line creation data during this compose */
+		protected function get releaseLineCreationData():Boolean
+		{ return _releaseLineCreationData; }
+		
+		// Create new lines through composition. lines, wrap, etc.
+		protected function composeInternal(composeRoot:FlowGroupElement,absStart:int):void
+		{
+			composeBlockElement(composeRoot,absStart);
+		}
+		
+		protected function composeParagraphElement(elem:ParagraphElement,absStart:int):Boolean
+		{
+			CONFIG::debug { assert(false,"MISSING OVERRIDE"); }
+			return false;
+		}
+		
+		protected function composeParagraphElementIntoLines():Boolean
+		{
+			var curLine:TextFlowLine;
+			
+			// loop creating lines
+			for (;;)
+			{
+				if (_parcelList.atEnd())
+					return false;
+				
+				// Allow derived classes to do processing here
+				startLine();
+				
+				// Get the next line
+				curLine = composeNextLine();
+				if (curLine ==  null)
+					return false;
+				
+				var alignData:AlignData = calculateTextAlign(curLine, curLine.getTextLine());
+				
+				/* {
+				for (var idx:int = 0; idx < curLine.textLine.atomCount; idx++)
+				{
+				trace(idx.toString()+": beginIndex: " + curLine.textLine.getAtomTextBlockBeginIndex(idx)+ " bidiLevel: "+ curLine.textLine.getAtomBidiLevel(idx) + " bounds: " + curLine.textLine.getAtomBounds(idx));
+				}
+				} */
+				
+				if ((curLine.spaceBefore != 0 || _spaceCarried != 0) && !_parcelList.isColumnStart())
+					_parcelList.addTotalDepth(Math.max(curLine.spaceBefore, _spaceCarried));
+				_spaceCarried = 0;
+				_parcelList.addTotalDepth(curLine.height);
+				_curElementOffset += curLine.textLength;
+				// textLength is the first character in the next line
+				
+				var textLine:TextLine = curLine.getTextLine();
+				
+				var lineWidth:Number; 
+				if (_parcelList.explicitLineBreaks)
+				{
+					var isRTL:Boolean = _curParaElement.computedFormat.direction == Direction.RTL;
+					textLine = curLine.getTextLine(true);
+					var lastAtom:int = textLine.atomCount - 1;
+					// If we're at the end of the paragraph, don't count the terminator
+					var endOfParagraph:Boolean = _curElementStart+_curElementOffset == _curParaStart + _curParaElement.textLength;
+					if (endOfParagraph && !isRTL)
+						--lastAtom;	// can go negative if just the terminator.  in that case use left/top of atom zero
+					var bounds:Rectangle = textLine.getAtomBounds(lastAtom >= 0 ? lastAtom : 0);	// get rightmost atom bounds
+					lineWidth = (_blockProgression == BlockProgression.TB) 
+						? (lastAtom >= 0 ? bounds.right : bounds.left)
+						: (lastAtom >= 0 ? bounds.bottom : bounds.top);
+					if (isRTL)	// in right to left, get leftmost atom bounds, that has trailing space
+					{
+						// in RTL strip the width of the paragraph terminator from the front
+						bounds = textLine.getAtomBounds(lastAtom != 0 && endOfParagraph ? 1 : 0);						
+						lineWidth -= (_blockProgression == BlockProgression.TB) ? bounds.left : bounds.top;
+					}
+					textLine.flushAtomData();
+				}
+				else
+					lineWidth = textLine.textWidth;
+				
+				var rightSidePadding:Number =  _curParaFormat.direction == Direction.LTR ? _curParaFormat.paragraphEndIndent : _curParaFormat.paragraphStartIndent;
+				var textIndent:Number = 0;
+				var rightSideIndent:Number = 0;
+				var leftSideIndent:Number = 0;
+				if (_curParaFormat.direction == Direction.RTL && (curLine.location & TextFlowLineLocation.FIRST))
+				{
+					// the textIndent isn't applied on left aligned paragraphs in measured RTL mode
+					// need to be careful because leftaligned paragraphs need to be exactly right coming out of this routine
+					if (alignData && (_blockProgression == BlockProgression.TB && !curLine.controller.measureWidth || _blockProgression == BlockProgression.RL && !curLine.controller.measureHeight))
+						rightSideIndent = _curParaFormat.textIndent;
+				}
+				var leftSidePadding:Number =  _curParaFormat.direction == Direction.LTR ? _curParaFormat.paragraphStartIndent : _curParaFormat.paragraphEndIndent;
+				if (_curParaFormat.direction == Direction.LTR && (curLine.location & TextFlowLineLocation.FIRST))
+				{
+					// recording leftSideIndent is here because there is an extra alignment step for non-left aligned paragraphs
+					leftSideIndent = _curParaFormat.textIndent;
+				}					
+				
+				if (alignData)
+				{
+					alignData.rightSidePadding = rightSidePadding;
+					alignData.leftSidePadding  = leftSidePadding;
+					alignData.lineWidth = lineWidth;
+					alignData.rightSideIndent = rightSideIndent;
+					alignData.leftSideIndent = leftSideIndent;
+					
+					// trace("AlignData",alignData.leftSidePadding,alignData.rightSidePadding,alignData.lineWidth,alignData.leftSideIndent,alignData.rightSideIndent);
+				}
+				
+				// extent from the left margin
+				var lineExtent:Number = lineWidth + leftSidePadding+leftSideIndent + rightSidePadding+rightSideIndent;
+				_contentLogicalExtent = Math.max(_contentLogicalExtent, lineExtent);
+				if (!alignData)
+					_contentCommittedExtent = Math.max(_contentCommittedExtent, lineExtent);
+				
+				CONFIG::debug { assert(_parcelList.controller.textLength >= 0, "frame has negative composition"); }
+				
+				if (_parcelList.atEnd())
+					return false;
+				
+				endLine();
+				
+				// advance to the next element, using the rootElement of the container as a limitNode
+				// to prevent going past the content bound to this container
+				if (_curElementOffset >= _curElement.textLength)
+				{
+					// We may have composed ahead over several spans; skip until we match up
+					// Loop until we use catch up to where the line we just composed ended (pos).
+					// Stop if we run out of elements. Skip empty inline elements, and skip floats
+					// that came at the start of the line before any text -- they've already been 
+					// processed.
+					do{
+						_curElementOffset -= _curElement.textLength;
+						_curElementStart  += _curElement.textLength;
+						if (_curElementStart == _curParaStart+_curParaElement.textLength)
+						{
+							_curElement = null;
+							break;
+						}
+						_curElement = _curElement.getNextLeaf();
+						CONFIG::debug { assert(_curElement && _curElement.getParagraph() == _curParaElement,"composeParagraphElement: bad textLength in TextLine"); }
+					} while (_curElementOffset >= _curElement.textLength || _curElement.textLength == 0 );
+				}
+				
+				_spaceCarried = curLine.spaceAfter;
+				
+				
+				if (_curElement == null)
+					break;
+			}
+			return true;
+		}
+		
+		protected function composeNextLine():TextFlowLine
+		{
+			CONFIG::debug { throw new Error("composeNextLine requires override"); }		
+			return null;
+		}
+		
+		// fills in _lineSlug
+		protected function fitLineToParcel(curLine:TextFlowLine, isNewLine:Boolean):TextFlowLine
+		{
+			// Try to place the line in the current parcel.
+			// get a zero height parcel. place the line there and then test if it still fits.
+			// if it doesn't place it in the new result parcel
+			// still need to investigate because the height used on the 2nd getLineSlug call may be too big.
+			for (;;)
+			{
+				if (_parcelList.getLineSlug(_candidateLineSlug,0))
+					break;
+				_parcelList.next();
+				if (_parcelList.atEnd())
+					return null;
+				_spaceCarried = 0;
+			}
+			
+			curLine.setController(_parcelList.controller,_parcelList.columnIndex);
+			
+			// If we are at the last parcel, we let text be clipped if that's specified in the configuration. At the point where no part of text can be accommodated, we go overset.
+			// If we are not at the last parcel, we let text flow to the next parcel instead of getting clipped.
+			var spaceBefore:Number = Math.max(curLine.spaceBefore, _spaceCarried);
+			for (;;)
+			{
+				finishComposeLine(curLine, _candidateLineSlug, isNewLine);	
+				if (_parcelList.getLineSlug(_lineSlug, spaceBefore + (_parcelList.atLast() && _textFlow.configuration.overflowPolicy != OverflowPolicy.FIT_DESCENDERS ? curLine.height-curLine.ascent : curLine.height+curLine.descent)))
+				{
+					CONFIG::debug { assert(_parcelList.getComposeXCoord(_candidateLineSlug) == _parcelList.getComposeXCoord(_lineSlug) && _parcelList.getComposeYCoord(_candidateLineSlug) == _parcelList.getComposeYCoord(_lineSlug),"fitLineToParcel: slug mismatch"); }
+					break;
+				}
+				spaceBefore = curLine.spaceBefore;
+				for (;;)
+				{
+					_parcelList.next();
+					if (_parcelList.atEnd())
+						return null;
+					if (_parcelList.getLineSlug(_candidateLineSlug,0))
+						break;
+				}
+				curLine.setController(_parcelList.controller,_parcelList.columnIndex);
+			}						
+			
+			// check to see if we got a good line
+			return (_parcelList.getComposeWidth(_lineSlug) == curLine.outerTargetWidth) ? curLine : null;
+		}
+		
+		
+		protected function finishComposeLine(curLine:TextFlowLine, lineSlug:Rectangle, isNewLine:Boolean):void
+		{      	
+			var curTextLine:TextLine = curLine.getTextLine();
+			var lineHeight:Number = 0;
+			//replace X and Y with rise and run.  
+			//	rise - the offset within a line relative to block progressiong.  For RL this is X, for TB Y
+			//	run - the indentation of the line.  For RL this is Y, TB X
+			var rise:Number = _blockProgression != BlockProgression.RL ? parcelList.getComposeYCoord(lineSlug) : _parcelList.getComposeXCoord(lineSlug);
+			var run:Number = _blockProgression != BlockProgression.RL ? parcelList.getComposeXCoord(lineSlug) : _parcelList.getComposeYCoord(lineSlug);
+			
+			if (_curParaFormat.direction == Direction.LTR)
+			{
+				run += curLine.lineOffset;
+			} 
+			else 
+			{
+				run += curLine.outerTargetWidth-curLine.lineOffset-curLine.targetWidth;
+				
+				if (curLine.outerTargetWidth == TextLine.MAX_LINE_WIDTH && curLine.location&TextFlowLineLocation.FIRST)	// doing measurement ignore 
+				{
+					run += curLine.paragraph.computedFormat.textIndent;
+				}
+			}
+			
+			_curLineLeading = curLine.getLineLeading(_blockProgression,_curElement,_curElementStart);
+			_curLineLeadingModel = _curParaElement.getEffectiveLeadingModel();
+			
+			var containerAttrs:ITextLayoutFormat = _parcelList.controller.computedFormat;		
+			var baselineType:Object = BaselineOffset.LINE_HEIGHT;
+			if (_parcelList.isColumnStart())
+			{
+				// If we're at the top of the column, we need to check the container properties to see
+				// what the firstBaselineOffset should be. This tells us how to treat the line.
+				// However, when vertical alignment is center or bottom, ignore the firstBaselineOffset setting
+				// and treat them as the BaselineOffset.AUTO case
+				if (containerAttrs.firstBaselineOffset != BaselineOffset.AUTO && containerAttrs.verticalAlign != VerticalAlign.BOTTOM && containerAttrs.verticalAlign != VerticalAlign.MIDDLE) 
+				{
+					baselineType = containerAttrs.firstBaselineOffset;
+					// The first line's offset is specified relative firstBaselineOffsetBasis, which used to be, but no longer is, a container-level property
+					// Now it is implicitly deduced based on the container-level locale in the following manner: 
+					// IDEOGRAPHIC_BOTTOM for ja and zh locales (this is the same locale set for which the default LeadingModel is IDEOGRAPHIC_TOP_DOWN)
+					// ROMAN for all other locales
+					var firstBaselineOffsetBasis:String = LocaleUtil.leadingModel(containerAttrs.locale) == LeadingModel.IDEOGRAPHIC_TOP_DOWN ?  flash.text.engine.TextBaseline.IDEOGRAPHIC_BOTTOM : flash.text.engine.TextBaseline.ROMAN;
+					lineHeight -= curTextLine.getBaselinePosition(firstBaselineOffsetBasis);		
+				}
+				else
+				{
+					if (_curLineLeadingModel == LeadingModel.APPROXIMATE_TEXT_FIELD)
+					{
+						// Reinterpret AUTO when APPROXIMATE_TEXT_FIELD leading model is used. 
+						// Align the "enhanced ascent" (an approximation of TextField's notion of ascent baseline, 
+						// which differs from FTEs notion of the same by an amount equal to the line's descent) with the container top inset
+						lineHeight += Math.round(curTextLine.descent) + Math.round(curTextLine.ascent)
+						
+						// Ensure Roman baseline will fall at an integer position. This is desirable for all leading models, 
+						// but only APPROXIMATE_TEXT_FIELD requires it now. In a future release, this code can be moved below and lineX/lineY rounded off directly. 
+						if (_blockProgression == BlockProgression.TB)
+							lineHeight = Math.round(rise + lineHeight) - rise;
+						else
+							lineHeight = rise - Math.round(rise - lineHeight);
+						
+						baselineType = 0; // No further adjustments    
+					}
+					else
+					{
+						// The AUTO case requires aligning line top to container top inset. This efect can be achieved by using firstBaselineOffset=ASCENT
+						// and firstBaselineOffsetBasis=ROMAN 
+						baselineType = BaselineOffset.ASCENT;
+						
+						if(curTextLine.hasGraphicElement)
+						{
+							var firstLineAdjustment:LeadingAdjustment = getLineAdjustmentForInline(curLine, _curLineLeadingModel, true);
+							if(firstLineAdjustment != null)
+							{
+								if(_blockProgression == BlockProgression.RL)
+								{
+									firstLineAdjustment.rise = -(firstLineAdjustment.rise);
+								}
+								_curLineLeading += firstLineAdjustment.leading;
+								rise += firstLineAdjustment.rise;
+							}
+						}
+						
+						lineHeight -= curTextLine.getBaselinePosition(flash.text.engine.TextBaseline.ROMAN);
+					}
+				}
+			}
+			else
+			{
+				// handle space before by adjusting y position of line
+				if (curLine.spaceBefore != 0 || _spaceCarried != 0)
+				{
+					var spaceAdjust:Number = Math.max(curLine.spaceBefore, _spaceCarried);
+					
+					rise += _blockProgression == BlockProgression.RL ? -spaceAdjust :spaceAdjust;
+				}
+			}
+			//getTextLineTypographicAscent
+			if (baselineType == BaselineOffset.ASCENT)
+			{
+				//	CONFIG::debug { assert(_curElement == _textFlow.findLeaf(curLine.absoluteStart),"Bad _curElement"); }
+				CONFIG::debug { assert(_curElementStart == _textFlow.findLeaf(curLine.absoluteStart).getAbsoluteStart(), "Bad _curElementStart"); }
+				lineHeight += curLine.getLineTypographicAscent(_curElement,_curElementStart);
+			}
+			else 
+			{
+				if (baselineType == BaselineOffset.LINE_HEIGHT)
+				{
+					if (_curLineLeadingModel == LeadingModel.APPROXIMATE_TEXT_FIELD)
+					{
+						// Position the "enhanced ascent" (see above) at a distance of leading from the previous line's descent
+						lineHeight += Math.round(_lastLineDescent) + Math.round(curTextLine.ascent) + Math.round(curTextLine.descent) + Math.round(_curLineLeading);
+					}
+					else if (_curLineLeadingModel == LeadingModel.ASCENT_DESCENT_UP)
+					{
+						lineHeight += _lastLineDescent + curTextLine.ascent + _curLineLeading;
+					} 
+					else
+					{
+						// Leading direction is irrelevant for the first line. Treat it as (UP, UP)
+						// TODO-9/3/2008-It may be better to handle Middle/Last lines separately because we know that the previous line also belongs in the same para 
+						var curLeadingDirectionUp:Boolean = _parcelList.isColumnStart() ? true : ParagraphElement.useUpLeadingDirection(_curLineLeadingModel);
+						
+						var prevLeadingDirectionUp:Boolean = _parcelList.isColumnStart() || _lastLineLeadingModel == "" ? true : 
+							ParagraphElement.useUpLeadingDirection(_lastLineLeadingModel);
+						
+						var prevLineFirstElement:FlowLeafElement;
+						
+						if (curLeadingDirectionUp)
+						{	
+							//TODO-9/12/2008-The above behavior is the InDesign behavior but raises some questions about selection shapes.
+							//Should selection code associate leading with the influencing line? That would be weird. InDesign only
+							//supports alternate leading directions in the J feature set, where leading is never included in selection,
+							//so this question does not arise. We take the unambiguous route: ignore leading DOWN at the end of a para
+							lineHeight += _curLineLeading;
+						}
+						else
+						{
+							if (!prevLeadingDirectionUp)
+							{
+								// Same leading directions; use previous line's leading setting.
+								lineHeight += _lastLineLeading;
+							}
+							else
+							{
+								// Make NO leading adjustments. Set lines solid.
+								lineHeight += _lastLineDescent + curTextLine.ascent;
+							}
+						}	
+					}
+				}
+				else
+					lineHeight += Number(baselineType);		// fixed offset
+			}
+			
+			//don't know why, but ascent only needs to be removed from horizontal text.  Hmm, that seems
+			//odd to me - gak 12.15.09
+			rise += _blockProgression == BlockProgression.RL ? -(lineHeight) : lineHeight - curTextLine.ascent;
+			
+			//baselineType will be BaselineOffset.ASCENT for fixed leading
+			if(curTextLine.hasGraphicElement && baselineType != BaselineOffset.ASCENT)
+			{
+				var adjustment:LeadingAdjustment = getLineAdjustmentForInline(curLine, _curLineLeadingModel, false);
+				if(adjustment != null)
+				{	
+					if(_blockProgression == BlockProgression.RL)
+					{
+						adjustment.rise = -(adjustment.rise);
+					}
+					_curLineLeading += adjustment.leading;
+					rise += adjustment.rise;
+				}
+			}
+			
+			
+			if(_blockProgression == BlockProgression.TB)
+				curLine.setXYAndHeight(run,rise,lineHeight);
+			else
+				curLine.setXYAndHeight(rise,run,lineHeight);
+			
+			if(isNewLine)
+				curLine.createAdornments(_blockProgression,_curElement,_curElementStart);
+		}	
+		
+		// Calculate the text alignment of the current line we're composing. If alignment is required, the adjustment will be made in
+		// applyTextAlign, after we've calculated the width of the parcel (it may be based on measurement).
+		// TODO: optimization possibility - do the alignment here when not doing measurement
+		private function calculateTextAlign(curLine:TextFlowLine, curTextLine:TextLine):AlignData
+		{
+			// Adjust the coordinates of the line for center/right.  The line is always left aligned.  TextBlock handles justified cases
+			// If we're on the last line of a justified paragraph, use the textAlignLast value 
+			var textAlignment:String = _curParaFormat.textAlign;
+			if (textAlignment == TextAlign.JUSTIFY && _curParaFormat.textAlignLast != null)
+			{
+				var location:int = curLine.location;
+				if (location == TextFlowLineLocation.LAST || location == TextFlowLineLocation.ONLY)
+					textAlignment = _curParaFormat.textAlignLast;
+			}
+			switch(textAlignment)
+			{
+				case TextAlign.START:
+					textAlignment = (_curParaFormat.direction == Direction.LTR) ? TextAlign.LEFT : TextAlign.RIGHT;
+					break;
+				case TextAlign.END:
+					textAlignment = (_curParaFormat.direction == Direction.LTR) ? TextAlign.RIGHT : TextAlign.LEFT;
+					break; 
+			}
+			
+			var createAlignData:Boolean = textAlignment == TextAlign.CENTER || textAlignment == TextAlign.RIGHT;
+			
+			// in argo lines that have tabs must be either START or JUSTIFY
+			if (Configuration.playerEnablesArgoFeatures)
+			{
+				if (curTextLine["hasTabs"])
+				{
+					if (_curParaFormat.direction == Direction.LTR)
+					{
+						createAlignData = false;	// don't align it - let it be left align
+					}
+					else
+					{
+						createAlignData = true;
+						textAlignment = TextAlign.RIGHT;
+					}
+				}
+			}
+			
+			
+			if (createAlignData)
+			{
+				var alignData:AlignData = new AlignData();
+				alignData.textLine = curTextLine;
+				alignData.center = (textAlignment == TextAlign.CENTER);
+				if (!_alignLines)
+					_alignLines = [];
+				_alignLines.push(alignData);
+				return alignData;
+			}
+			return null;
+		}
+		
+		private function applyTextAlign(effectiveParcelWidth:Number):void
+		{
+			var textLine:TextLine;
+			var line:TextFlowLine;
+			var alignData:AlignData;
+			
+			var coord:Number;
+			var delta:Number;
+			var adjustedLogicalRight:Number;
+			var extraSpace:Number;
+			var leftSideGap:Number;
+			var rightSideGap:Number;
+			
+			if (_blockProgression == BlockProgression.TB)
+			{
+				for each (alignData in _alignLines) 
+				{
+					textLine = alignData.textLine;
+					
+					rightSideGap = alignData.rightSidePadding;
+					leftSideGap = alignData.leftSidePadding;
+					leftSideGap += alignData.leftSideIndent;
+					rightSideGap += alignData.rightSideIndent;
+					
+					line = textLine.userData as TextFlowLine;
+					extraSpace = effectiveParcelWidth - leftSideGap - rightSideGap -  textLine.textWidth;
+					delta = leftSideGap + (alignData.center ? extraSpace / 2 : extraSpace);
+					coord = _curParcel.left + delta;
+					if (line)
+						line.x = coord;
+					textLine.x = coord;
+					
+					adjustedLogicalRight = alignData.lineWidth + coord + Math.max(rightSideGap, 0);
+					_parcelRight = Math.max(adjustedLogicalRight , _parcelRight);
+				}
+			}
+			else
+			{
+				for each (alignData in _alignLines) 
+				{
+					textLine = alignData.textLine;
+					
+					rightSideGap = alignData.rightSidePadding;
+					leftSideGap = alignData.leftSidePadding;
+					leftSideGap += alignData.leftSideIndent;
+					rightSideGap += alignData.rightSideIndent;
+					
+					line = textLine.userData as TextFlowLine;
+					extraSpace = effectiveParcelWidth - leftSideGap - rightSideGap -  textLine.textWidth;
+					delta = leftSideGap + (alignData.center ? extraSpace / 2 : extraSpace);
+					coord = _curParcel.top + delta;
+					if (line)
+						line.y = coord;
+					textLine.y = coord;
+					
+					adjustedLogicalRight = alignData.lineWidth + coord + Math.max(rightSideGap, 0);
+					_parcelBottom = Math.max(adjustedLogicalRight,_parcelBottom);
+				}
+			}
+			_alignLines.length = 0;
+		}
+		
+		protected function commitLastLineState(curLine:TextFlowLine):void
+		{
+			// Remember leading-related state that may be used for laying out the next line
+			_lastLineDescent = curLine.descent;
+			_lastLineLeading = _curLineLeading;
+			_lastLineLeadingModel = _curLineLeadingModel;
+		}
+		
+		protected function doVerticalAlignment(canVerticalAlign:Boolean,nextParcel:Parcel):Boolean
+		{
+			// stub for required override
+			CONFIG::debug { assert(false, "override in derived class"); }
+			return false;
+		}
+		
+		protected function finalParcelAdjustment(controller:ContainerController):void
+		{
+			// stub for required override
+			CONFIG::debug { assert(false, "finalParcelAdjustment missing override in derived class"); }
+		}
+		
+		protected function finishParcel(controller:ContainerController,nextParcel:Parcel):Boolean
+		{
+			if (_curParcelStart == _curElementStart+_curElementOffset)		// empty parcel -- nothing composed into it
+			{
+				CONFIG::debug { assert(_contentLogicalExtent == 0,"bad contentlogicalextent on empty container"); }
+				return false;
+			}
+			
+			// We're only going to align the lines in measurement mode if there's only one parcel
+			var doTextAlign:Boolean = (_alignLines && _alignLines.length > 0); 
+			
+			// Figure out the contents bounds information for the parcel we just finished composing
+			
+			// Content logical height is parcel depth, plus descenders of last line
+			var totalDepth:Number = _parcelList.totalDepth;
+			if (_textFlow.configuration.overflowPolicy == OverflowPolicy.FIT_DESCENDERS && !isNaN(_lastLineDescent))
+				totalDepth += _lastLineDescent;
+			
+			// Initialize the parcel bounds
+			// note we can later optimize away the adjustements
+			if (_blockProgression == BlockProgression.TB)
+			{
+				_parcelLeft = _curParcel.left;
+				_parcelTop = _curParcel.top;
+				_parcelRight = _contentCommittedExtent+_curParcel.left;
+				_parcelBottom = totalDepth+_curParcel.top;
+			}
+			else
+			{
+				// Push the values up to the controller running min/max, if they are bigger
+				_parcelLeft = _curParcel.right-totalDepth;
+				_parcelTop = _curParcel.top;
+				_parcelRight = _curParcel.right;
+				_parcelBottom = _contentCommittedExtent+_curParcel.top;
+			}			
+			if (doTextAlign)
+			{
+				var effectiveParcelWidth:Number;
+				if (_blockProgression == BlockProgression.TB)
+					effectiveParcelWidth = controller.measureWidth ? _contentLogicalExtent : _curParcel.width;
+				else
+					effectiveParcelWidth = controller.measureHeight ? _contentLogicalExtent : _curParcel.height;
+				applyTextAlign(effectiveParcelWidth);
+			}
+			
+			// If we're measuring, then don't do vertical alignment
+			var canVerticalAlign:Boolean = false;
+			if (_blockProgression == BlockProgression.TB)
+			{
+				if (!controller.measureHeight && (!_curParcel.fitAny || _curElementStart + _curElementOffset >= _textFlow.textLength))
+					canVerticalAlign = true;
+			}
+			else
+			{
+				if (!controller.measureWidth && (!_curParcel.fitAny || _curElementStart + _curElementOffset >= _textFlow.textLength))
+					canVerticalAlign = true;
+			}
+			
+			// need to always call this function because internal variables may need resetting
+			if (doVerticalAlignment(canVerticalAlign,nextParcel))
+				doTextAlign = true;
+			// This last adjustment is for two issues
+			// 1) inline graphics that extend above the top (any ILGS I expect)
+			// 2) negative first line indents (stil a worry here?)
+			// If neither of these are present it can be skipped - TODO optimization
+			// trace("BEF finalParcelAdjustment",_parcelLeft,_parcelRight,_parcelTop,_parcelBottom);
+			finalParcelAdjustment(controller);
+			// trace("AFT finalParcelAdjustment",_parcelLeft,_parcelRight,_parcelTop,_parcelBottom);
+			_contentLogicalExtent = 0;
+			_contentCommittedExtent = 0;
+			
+			return true;
+		}
+		
+		/** apply vj and adjust the parcel bounds */
+		protected function applyVerticalAlignmentToColumn(controller:ContainerController,vjType:String,lines:Array,beginIndex:int,numLines:int):void
+		{
+			var firstLine:IVerticalJustificationLine = lines[beginIndex];
+			var lastLine:IVerticalJustificationLine = lines[beginIndex+numLines-1]
+			var firstLineCoord:Number;
+			var lastLineCoord:Number
+			if (_blockProgression == BlockProgression.TB)
+			{
+				firstLineCoord = firstLine.y;
+				lastLineCoord  = lastLine.y;
+			}
+			else
+			{
+				firstLineCoord = firstLine.x;
+				lastLineCoord = lastLine.x;
+			}
+			
+			VerticalJustifier.applyVerticalAlignmentToColumn(controller,vjType,lines,beginIndex,numLines);
+			
+			if (_blockProgression == BlockProgression.TB)
+			{
+				_parcelTop += firstLine.y-firstLineCoord;
+				_parcelBottom += lastLine.y-lastLineCoord;
+			}
+			else
+			{
+				_parcelRight += firstLine.x-firstLineCoord;
+				_parcelLeft += lastLine.x-lastLineCoord;
+			}
+		}
+		
+		private function finishController(controller:ContainerController):void
+		{
+			var controllerTextLength:int = _curElementStart + _curElementOffset - controller.absoluteStart;
+			
+			if (controllerTextLength != 0)
+			{
+				// Leave room for the padding. If the content overlaps the padding, don't count the padding twice.
+				var paddingLeft:Number = controller.effectivePaddingLeft;
+				var paddingTop:Number = controller.effectivePaddingTop;
+				var paddingRight:Number = controller.effectivePaddingRight;
+				var paddingBottom:Number = controller.effectivePaddingBottom;
+				if (_blockProgression == BlockProgression.TB)
+				{
+					if (_controllerLeft > 0)
+					{
+						if (_controllerLeft < paddingLeft)
+							_controllerLeft = 0;
+						else 
+							_controllerLeft -= paddingLeft;
+					}
+					
+					if (_controllerTop > 0)
+					{
+						if (_controllerTop < paddingTop)
+							_controllerTop = 0;
+						else 
+							_controllerTop -= paddingTop;
+					}
+					
+					if (isNaN(controller.compositionWidth))
+						_controllerRight += paddingRight;		 				
+					else if (_controllerRight < controller.compositionWidth)
+					{
+						if (_controllerRight > controller.compositionWidth - paddingRight)
+							_controllerRight = controller.compositionWidth;
+						else 
+							_controllerRight += paddingRight;
+					}
+					_controllerBottom += paddingBottom;	
+				}
+				else
+				{
+					_controllerLeft -= paddingLeft;
+					if (_controllerTop > 0)
+					{
+						if (_controllerTop < paddingTop)
+							_controllerTop = 0;
+						else 
+							_controllerTop -= paddingTop;
+					}
+					if (_controllerRight < 0)
+					{
+						if (_controllerRight > -paddingRight)
+						{
+							_controllerRight = 0;
+						}
+						else
+							_controllerRight += paddingRight;
+					}
+					if (isNaN(controller.compositionHeight))
+						_controllerBottom += paddingBottom;
+					else if (_controllerBottom < controller.compositionHeight)
+					{
+						if (_controllerBottom > controller.compositionHeight - paddingBottom)
+							_controllerBottom = controller.compositionHeight;
+						else 
+							_controllerBottom += paddingBottom;
+					}
+				}
+				controller.setContentBounds(_controllerLeft, _controllerTop, _controllerRight-_controllerLeft, _controllerBottom-_controllerTop);
+			}
+			else
+				controller.setContentBounds(0,0,0,0);
+			
+			controller.setTextLength(controllerTextLength);
+		}
+		
+		private function clearControllers(oldController:ContainerController, newController:ContainerController):void
+		{
+			// any controller between oldController and up to and including newController gets cleared
+			var firstToClear:int = oldController ? _flowComposer.getControllerIndex(oldController)+1 : 0;
+			var lastToClear:int  = newController ? _flowComposer.getControllerIndex(newController) : _flowComposer.numControllers-1;
+			while (firstToClear <= lastToClear)
+			{
+				var controllerToClear:ContainerController = ContainerController(_flowComposer.getControllerAt(firstToClear));
+				controllerToClear.setContentBounds(0, 0, 0, 0);
+				controllerToClear.setTextLength(0);
+				firstToClear++;
+			}
+		}
+		
+		/** This is called when the parcel has changed 
+		 * @param oldParcel - the parcel we had before (you can get the new parcel from the parcel list)
+		 */
+		protected function parcelHasChanged(newParcel:Parcel):void
+		{
+			var oldController:ContainerController = _curParcel ? ContainerController(_curParcel.controller) : null;
+			var newController:ContainerController = newParcel  ? ContainerController(newParcel.controller)  : null;
+			
+			/* if (newParcel)
+			trace("parcelHasChanged newParcel: ",newParcel.clone().toString()); */
+			
+			if (_curParcel != null)
+			{
+				if (finishParcel(oldController,newParcel))
+				{
+					if (_parcelLeft < _controllerLeft)
+						_controllerLeft = _parcelLeft;
+					if (_parcelRight > _controllerRight)
+						_controllerRight = _parcelRight;
+					if (_parcelTop < _controllerTop)
+						_controllerTop = _parcelTop;
+					if (_parcelBottom > _controllerBottom)
+						_controllerBottom = _parcelBottom;
+				}
+			}
+			
+			// update parcel data			
+			if (oldController != newController)		// we're going on to the next controller in the chain
+			{
+				if (oldController)
+					finishController(oldController);
+				
+				resetControllerBounds();
+				
+				if (_flowComposer.numControllers > 1)
+				{
+					if (oldController == null && _startController)
+						clearControllers(_startController, newController);
+					else
+						clearControllers(oldController, newController);
+				}
+				// Parcel list will set totalDepth to newController's paddingTop
+			}
+			_curParcel = newParcel;
+			_curParcelStart = _curElementStart;
+		}
+		/** @private */
+		private function getLineAdjustmentForInline(curLine:TextFlowLine, curLeadingDir:String, isFirstLine:Boolean):LeadingAdjustment
+		{
+			var adjustment:LeadingAdjustment = null;
+			var curTextLine:TextLine = curLine.getTextLine();
+			var para:ParagraphElement = curLine.paragraph;
+			var flowElem:FlowLeafElement = _curElement; //the first element included in this line
+			var curPos:int = flowElem.getAbsoluteStart();
+			var largestPointSize:Number = flowElem.getEffectiveFontSize();
+			var largestImg:Number = 0;
+			
+			//walk
+			while(flowElem && curPos < curLine.absoluteStart + curLine.textLength)
+			{
+				if(curPos >= curLine.absoluteStart || curPos + flowElem.textLength >= curLine.absoluteStart)
+				{	
+					if(flowElem is InlineGraphicElement)
+					{
+						var inlineImg:InlineGraphicElement = flowElem as InlineGraphicElement;
+						//we can ignore TCY for leading adjustments
+						if(!(_blockProgression == BlockProgression.RL && (flowElem.parent is TCYElement)))
+						{
+							//if the largest found img is smaller than the current image, we need new data
+							if(largestImg < inlineImg.getEffectiveFontSize())
+							{
+								largestImg = inlineImg.getEffectiveFontSize();
+								//only get this if the img is as large or larger than the largest found text
+								if(largestImg >= largestPointSize)
+								{
+									largestImg = largestImg;
+									var domBaseline:String = flowElem.computedFormat.dominantBaseline;
+									if(domBaseline == FormatValue.AUTO)
+										domBaseline = LocaleUtil.dominantBaseline(para.computedFormat.locale);
+									
+									//we are only making the adjustment for ideo-center, all others are to be ignored...
+									if(domBaseline == TextBaseline.IDEOGRAPHIC_CENTER)
+									{
+										var elemLeading:Number = TextLayoutFormat.lineHeightProperty.computeActualPropertyValue(inlineImg.computedFormat.lineHeight, inlineImg.getEffectiveFontSize());	
+										var curAdjustment:LeadingAdjustment = calculateLinePlacementAdjustment(curTextLine, domBaseline, curLeadingDir, inlineImg, isFirstLine);
+										if(!adjustment || Math.abs(curAdjustment.rise) > Math.abs(adjustment.rise) || Math.abs(curAdjustment.leading) > Math.abs(adjustment.leading))
+										{
+											if(adjustment)
+											{
+												adjustment.rise = curAdjustment.rise;
+												adjustment.leading = curAdjustment.leading;
+											}
+											else
+												adjustment = curAdjustment;
+										}
+									}
+								}
+							}
+						}
+					}
+					else
+					{
+						var tempSize:Number = flowElem.getEffectiveFontSize();
+						if(largestPointSize <= tempSize)
+						{
+							largestPointSize = tempSize;
+						}
+						
+						//if the largest image is smaller than this element, zero out the adjustment
+						if(adjustment && largestImg < largestPointSize)
+						{
+							adjustment.leading = 0;
+							adjustment.rise = 0;
+						}
+					}
+				}
+				
+				//advance the position and get the next element
+				curPos += flowElem.textLength;
+				flowElem = flowElem.getNextLeaf(para);
+			}
+			return adjustment;
+		}
+
+
+		public function get swfContext():ISWFContext
+		{ 
+			var composerContext:ISWFContext = _flowComposer.swfContext;
+			return composerContext ? composerContext : GlobalSWFContext.globalSWFContext; 
+		}
+
+		/** @private */
+		private function calculateLinePlacementAdjustment(curTextLine:TextLine, domBaseline:String, curLeadingDir:String, inlineImg:InlineGraphicElement, isFirstLine:Boolean):LeadingAdjustment
+		{
+			var curAdjustment:LeadingAdjustment = new LeadingAdjustment();
+			//get the leading height for the img
+			var imgHeight:Number = TextLayoutFormat.lineHeightProperty.computeActualPropertyValue(inlineImg.computedFormat.lineHeight, inlineImg.getEffectiveFontSize());
+			//get the leading as if the line contains no imgs.  We'll need this to adjust the total adjustments
+			var lineLeading:Number = TextLayoutFormat.lineHeightProperty.computeActualPropertyValue(inlineImg.computedFormat.lineHeight, curTextLine.textHeight)
+			
+			//this is a redundant check, but will be needed in the future, so we're leaving it in. - gak 12.16.09
+			if(domBaseline == TextBaseline.IDEOGRAPHIC_CENTER)
+			{
+				if(!isFirstLine)
+				{
+					//for non-first lines, we want to offset the rise of the line
+					curAdjustment.rise += (imgHeight - lineLeading)/2;
+				}
+				else
+				{
+					//for the first line, the offset will be right, but hte leading wrong.
+					curAdjustment.leading -= (imgHeight - lineLeading)/2;
+				}
+			}
+			
+			return curAdjustment;
+		}
+	}
+}
+
+import flash.text.engine.TextLine;
+import flashx.textLayout.compose.ISWFContext;
+import flashx.textLayout.debug.Debugging;
+import flashx.textLayout.tlf_internal;
+
+use namespace tlf_internal;
+
+class AlignData 
+{
+	public var textLine:TextLine;
+	public var lineWidth:Number;
+	public var leftSidePadding:Number;
+	public var rightSidePadding:Number;
+	public var center:Boolean;
+	public var leftSideIndent:Number;
+	public var rightSideIndent:Number;
+}
+
+
+class GlobalSWFContext implements ISWFContext
+{
+	static public const globalSWFContext:GlobalSWFContext = new GlobalSWFContext();
+
+	public function GlobalSWFContext()
+	{ }
+	
+	public function callInContext(fn:Function, thisArg:Object, argsArray:Array, returns:Boolean=true):*
+	{
+		CONFIG::debug
+		{
+			var rslt:*
+			try
+			{
+				if (returns)
+					rslt = fn.apply(thisArg, argsArray);
+
+				else
+					fn.apply(thisArg, argsArray);
+					
+				if (thisArg)
+				{
+					var traceArgs:Array;
+					// later make this table driven
+					if (thisArg.hasOwnProperty("createTextLine") && fn == thisArg["createTextLine"])
+					{
+						traceArgs = [rslt,thisArg,"createTextLine"]
+						traceArgs.push.apply(traceArgs, argsArray);
+						Debugging.traceFTECall.apply(null,traceArgs);
+					}
+					else if (thisArg.hasOwnProperty("recreateTextLine") && fn == thisArg["recreateTextLine"])
+					{
+						traceArgs = [rslt,thisArg,"recreateTextLine"]
+						traceArgs.push.apply(traceArgs, argsArray);
+						Debugging.traceFTECall.apply(null,traceArgs);
+					}
+				}
+			}
+			catch(e:Error)
+			{
+				// trace(e);
+				throw(e);
+			}
+			return rslt;
+		}
+		CONFIG::release
+		{
+			if (returns)
+				return fn.apply(thisArg, argsArray);
+			fn.apply(thisArg, argsArray);
+		}
+	}
+}
+
+class LeadingAdjustment
+{
+	public var rise:Number = 0;
+	public var leading:Number = 0;
+	public var lineHeight:Number = 0;
+}
+
+
diff --git a/textLayout_core/src/flashx/textLayout/compose/ComposeState.as b/textLayout_core/src/flashx/textLayout/compose/ComposeState.as
new file mode 100755
index 0000000..3cf15fb
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/compose/ComposeState.as
@@ -0,0 +1,406 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{
+	import flash.events.Event;
+	import flash.geom.Rectangle;
+	import flash.text.engine.TextBlock;
+	import flash.text.engine.TextLine;
+	import flash.text.engine.TextLineValidity;
+	
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.debug.Debugging;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.OverflowPolicy;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.SubParagraphGroupElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.formats.BaselineOffset;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.formats.Direction;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextAlign;
+	import flashx.textLayout.formats.VerticalAlign;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+
+	[ExcludeClass]
+	/** Keeps track of internal state during composition. 
+	 * 
+	 * This is the simpler version, used when there are no floats, no wraps, no columns.
+	 * @private
+	 */
+	public class ComposeState extends BaseCompose 
+	{
+		/** Index of current line */
+		protected var _curLineIndex:int;	
+		
+		// for figuring out when to do VJ
+		protected var vjBeginLineIndex:int;
+		protected var vjDisableThisParcel:Boolean;
+		
+		// a single ComposeState that is checked out and checked in
+		static private var _sharedComposeState:ComposeState;
+
+		/** @private */
+		static tlf_internal function getComposeState():ComposeState
+		{
+			var rslt:ComposeState = _sharedComposeState ? _sharedComposeState : new ComposeState();
+			_sharedComposeState = null;
+			return rslt;
+		}
+		
+		/** @private */
+		static tlf_internal function releaseComposeState(state:ComposeState):void
+		{
+			if (_sharedComposeState == null)
+			{
+				_sharedComposeState = state;
+				if (_sharedComposeState)
+					_sharedComposeState.releaseAnyReferences();
+			}
+		}
+
+		/** Constructor. */
+		public function  ComposeState()
+		{	
+			super();	
+		}				
+
+		/** @private */
+		protected override function createParcelList():IParcelList
+		{
+			return ParcelList.getParcelList();
+		}
+		/** @private */
+		protected override function releaseParcelList(list:IParcelList):void
+		{
+			ParcelList.releaseParcelList(list);
+		}
+		
+		/** @private */
+		public override function composeTextFlow(textFlow:TextFlow, composeToPosition:int, controllerEndIndex:int):int
+		{
+			_curLineIndex    = 0;
+					
+			vjBeginLineIndex = 0;
+			vjDisableThisParcel = false;
+			
+			return super.composeTextFlow(textFlow, composeToPosition, controllerEndIndex);
+		}
+		
+		protected override function initializeForComposer(composer:IFlowComposer,composeToPosition:int,controllerEndIndex:int):void
+		{
+			super.initializeForComposer(composer,composeToPosition,controllerEndIndex);
+			           
+			var controllerIndex:int = composer.findControllerIndexAtPosition(composer.damageAbsoluteStart);
+			if (controllerIndex == -1)
+			{
+				controllerIndex = composer.numControllers-1;
+				// if off the end in the overflow - find the last non-zero controller
+				while (controllerIndex != 0 && composer.getControllerAt(controllerIndex).textLength == 0)
+					controllerIndex--;
+			}
+			// if damage is in overflow after last controller we could get smart about that
+			_startController = composer.getControllerAt(controllerIndex);
+			CONFIG::debug { assert(_startController != null,"Bad start start controller"); }
+			_startComposePosition = _startController.absoluteStart;
+		}
+		
+		/** @private */
+		protected override function composeInternal(composeRoot:FlowGroupElement,absStart:int):void
+		{
+			super.composeInternal(composeRoot,absStart);
+			
+			// mark all overflow lines as not being in any container or column
+			if (_curElement)
+			{
+				CONFIG::debug { assert(_curLineIndex == _flowComposer.findLineIndexAtPosition(_curElementStart + _curElementOffset),"bad _curLineIndex"); }
+				while (_curLineIndex < _flowComposer.numLines)
+					_flowComposer.getLineAt(_curLineIndex++).setController(null,-1);
+			}
+		}
+
+ 		override protected function doVerticalAlignment(canVerticalAlign:Boolean,nextParcel:Parcel):Boolean
+		{
+			var result:Boolean = false;
+			if (canVerticalAlign && _curParcel && vjBeginLineIndex != _curLineIndex &&  !vjDisableThisParcel && _curParcel.columnCoverage == Parcel.FULL_COLUMN)
+			{
+				var controller:ContainerController = _curParcel.controller;
+				var vjtype:String = controller.computedFormat.verticalAlign;
+				if (vjtype != VerticalAlign.TOP)
+				{	
+					// Exclude overset lines
+					var end:int = _flowComposer.findLineIndexAtPosition(_curElementStart + _curElementOffset)
+
+					if (vjBeginLineIndex < end)
+					{
+						applyVerticalAlignmentToColumn(controller,vjtype,_flowComposer.lines,vjBeginLineIndex,end-vjBeginLineIndex);
+						result = true;	// lines were moved
+					}
+				}
+			}
+			
+			// always reset these variables
+			vjDisableThisParcel = false;
+			vjBeginLineIndex = _curLineIndex;	
+			
+			return result;
+		}
+		
+		/** Final adjustment on the content bounds. */
+ 		override protected function finalParcelAdjustment(controller:ContainerController):void
+ 		{
+ 			var minX:Number = TextLine.MAX_LINE_WIDTH;
+ 			var minY:Number = TextLine.MAX_LINE_WIDTH;
+ 			var maxX:Number = -TextLine.MAX_LINE_WIDTH;
+ 			var maxY:Number = -TextLine.MAX_LINE_WIDTH;
+ 			
+ 			var verticalText:Boolean = _blockProgression == BlockProgression.RL;
+
+            var lineIndex:int = _flowComposer.findLineIndexAtPosition(controller.absoluteStart); 
+            while (lineIndex < _curLineIndex)
+            {
+            	var line:TextFlowLine = _flowComposer.getLineAt(lineIndex);
+
+            	// Check the logical vertical dimension first
+            	// If the lines have children, they may be inlines. The origin of the TextFlowLine is the baseline - ascent, 
+            	// which does not include the ascent of the inlines. So we have to factor that in.
+				if (verticalText)
+				{
+	      	 		maxX = Math.max(line.x + line.ascent, maxX);
+	      	 		minX = Math.min(line.x, minX);
+	   			}	
+	      	 	else
+	      	 		minY = Math.min(line.y, minY);
+	       		var textLine:TextLine = line.getTextLine();
+	       		
+	       		// this is a test for an inline graphic
+	       		if (textLine.hasGraphicElement)
+	       		{
+	       			var leafElement:FlowLeafElement = _textFlow.findLeaf(line.absoluteStart);
+	       			var adjustedAscent:Number = line.getLineTypographicAscent(leafElement, leafElement.getAbsoluteStart());
+					if (!verticalText)
+	       				minY = Math.min(line.y + line.ascent - adjustedAscent, minY);
+	       			else
+	       				maxX = Math.max(line.x + adjustedAscent, maxX);
+	       		}
+
+
+				// Now check the logical horizontal dimension
+				var edgeAdjust:Number;
+				var curParaFormat:ITextLayoutFormat = line.paragraph.computedFormat;
+				if (curParaFormat.direction == Direction.LTR)
+					edgeAdjust = Math.max(line.lineOffset, 0);
+				else
+					edgeAdjust = curParaFormat.paragraphEndIndent;
+             	if (verticalText)
+           			minY = Math.min(line.y - edgeAdjust, minY);
+             	else 
+           			minX = Math.min(line.x - edgeAdjust, minX);
+            	++lineIndex;
+            }
+            
+            if (_blockProgression == BlockProgression.RL)
+            	minX -= _lastLineDescent;
+            
+            // Don't make adjustments for tiny fractional values.
+            if (minX != TextLine.MAX_LINE_WIDTH && Math.abs(minX-_parcelLeft) >= 1)
+         		_parcelLeft = minX;
+            if (maxX != -TextLine.MAX_LINE_WIDTH && Math.abs(maxX-_parcelRight) >= 1)
+         		_parcelRight = maxX;
+         	if (minY != TextLine.MAX_LINE_WIDTH && Math.abs(minY-_parcelTop) >= 1)
+           		_parcelTop = minY;
+         	if (maxY != -TextLine.MAX_LINE_WIDTH && Math.abs(maxY-_parcelBottom) >= 1)
+           		_parcelBottom = maxY;
+ 		}
+ 				
+		private function finalizeLine(useExistingLine:Boolean,curLine:TextFlowLine):void
+		{
+			if ( !useExistingLine ) 		
+			{	
+				_flowComposer.addLine(curLine,_curLineIndex);
+			}
+			_curLineIndex++;
+			
+			commitLastLineState (curLine);
+		}
+		
+		protected override function composeParagraphElement(elem:ParagraphElement, absStart:int):Boolean
+		{
+			_curParaElement  = elem;
+			_curParaStart    = absStart;
+			_curParaFormat = elem.computedFormat;
+			CONFIG::debug { assert(_curParaStart == elem.getAbsoluteStart(),"composeParagraphElement: bad start"); }
+			if (_startComposePosition == 0)
+			{
+				_curElement 	 = elem.getFirstLeaf();
+				_curElementStart = _curParaStart;
+			}
+			else 
+			{
+				CONFIG::debug { assert(absStart <= _startComposePosition && absStart+elem.textLength > _startComposePosition,"bad call to composeParagraphElement"); }
+				_curElement = elem.findLeaf(_startComposePosition-absStart);
+				_curElementStart = _curElement.getAbsoluteStart();
+				_curElementOffset = _startComposePosition-_curElementStart;
+				_curLineIndex = _flowComposer.findLineIndexAtPosition(_curElementStart + _curElementOffset);
+				// next time we are all postioned
+				_startComposePosition = 0;
+			}
+
+			return composeParagraphElementIntoLines();
+		}
+		
+		/** @private */
+		protected override function composeNextLine():TextFlowLine
+		{
+			CONFIG::debug { assert(_curLineIndex == _flowComposer.findLineIndexAtPosition(_curElementStart + _curElementOffset),"bad _curLineIndex"); }
+
+			// Check to see if there's an existing line that is composed up-to-date
+			var line:TextFlowLine = _curLineIndex < _flowComposer.numLines ? _flowComposer.lines[_curLineIndex] : null;
+			var useExistingLine:Boolean = line && (!line.isDamaged() || line.validity == FlowDamageType.GEOMETRY);
+			var curLine:TextFlowLine = useExistingLine ? line : null;
+			var startCompose:int = _curElementStart + _curElementOffset - _curParaStart;
+			var prevLine:TextFlowLine;
+			if (startCompose != 0)
+			{
+				prevLine = _flowComposer.lines[_curLineIndex - 1];
+				if (prevLine.absoluteStart < _curParaStart)		// is the previous line in the previous paragraph?
+					prevLine = null;
+			}
+			var finishLineSlug:Rectangle = _parcelList.currentParcel;
+			
+			for (;;) 
+			{
+				while (!curLine)
+				{	
+					useExistingLine = false;
+					// generate new line
+					CONFIG::debug { assert(!_parcelList.atEnd(), "failing to stop"); }
+					CONFIG::debug { assert(_curElement is FlowLeafElement, "element must be leaf before calling composeLine"); }
+					
+					curLine = createTextLine(prevLine,	startCompose, _parcelList.getComposeXCoord(finishLineSlug), _parcelList.getComposeYCoord(finishLineSlug),	_parcelList.getComposeWidth(finishLineSlug));
+					if (curLine != null)
+						break;
+					// force advance to the next parcel
+					if (!_parcelList.next())
+						return null;
+				}
+				
+				// updates _lineSlug
+				curLine = fitLineToParcel(curLine, !useExistingLine);
+				if (curLine)
+					break;
+				if (_parcelList.atEnd())
+					return null;
+				finishLineSlug = _lineSlug;
+			}
+			
+			// Clear up user_invalid
+			if (curLine.validity == FlowDamageType.GEOMETRY)
+				curLine.clearDamage(); 
+								
+			finalizeLine(useExistingLine,curLine);
+
+			CONFIG::debug { assert(curLine != null, "curLine != null"); }			
+			return curLine;
+		}
+		
+		/** @private */
+		protected function createTextLine(prevLine:TextFlowLine,	// previous line
+			lineStart:int, 		// text index of position to start from, relative to start of paragraph
+			x:Number,			// left edge of the line
+			y:Number, 			// top of the line
+			targetWidth:Number	// target width we're composing into
+			):TextFlowLine
+        {
+        //	trace("lineBreak: start", prevLine ? (prevLine.start+prevLine.textLength) : 0, "paraEnd", paraEnd, "(", x, y, ")", "targetWidth", targetWidth);
+         	
+        	CONFIG::debug { validateLineStart(prevLine, lineStart, _curParaElement); }
+        	
+ 			var lineOffset:Number = Number(_curParaFormat.paragraphStartIndent);  	// indent to "beginning" of the line.  Direction dependent (as is paragraphStartIndent)    		
+     		if (prevLine == null) 	// first line indent
+     			lineOffset += Number(_curParaFormat.textIndent);
+     		
+     		var outerTargetWidth:Number = targetWidth;
+     		targetWidth -= (Number(_curParaFormat.paragraphEndIndent) + lineOffset);		// make room for offset and end indent
+     		
+     		// TargetWidth must be between 0 and TextLine.MAX_LINE_WIDTH
+     		if (targetWidth < 0)
+     			targetWidth = 0;
+     		else if (targetWidth > TextLine.MAX_LINE_WIDTH)
+     			targetWidth = TextLine.MAX_LINE_WIDTH;
+	   		
+	   		var textLine:TextLine = TextLineRecycler.getLineForReuse();
+	   		var textBlock:TextBlock = _curParaElement.getTextBlock();
+	   		if (textLine)
+	   		{
+				CONFIG::debug { assert(_textFlow.backgroundManager == null || _textFlow.backgroundManager.lineDict[textLine] === undefined,"Bad TextLine in recycler cache"); }
+	        	textLine = swfContext.callInContext(textBlock["recreateTextLine"],textBlock,[textLine, prevLine?prevLine.getTextLine(true):null, targetWidth, lineOffset, true]);
+      		}
+	   		else
+	   		{
+	        	textLine = swfContext.callInContext(textBlock.createTextLine,textBlock,[prevLine?prevLine.getTextLine(true):null, targetWidth, lineOffset, true]);
+      		}
+        	// Unable to fit a new line
+        	if (textLine == null)
+        		return null;
+        	//trace("LineBreak prevLineLength:",prevLine?prevLine.textLine.rawTextLength:0,"nextLineLength:",line?line.textLine.rawTextLength:0);
+ 			// outerTargetWidth, targetWidth, textIndent, start, textLength, textLine
+ 			CONFIG::debug { assert(_curParaStart == _curParaElement.getAbsoluteStart(),"bad _curParaStart"); }
+ 			var line:TextFlowLine = new TextFlowLine(textLine, _curParaElement, outerTargetWidth, lineOffset, lineStart + _curParaStart, textLine.rawTextLength);
+ 			CONFIG::debug { assert(line.targetWidth == targetWidth,"Bad targetWidth"); }
+ 			textLine.doubleClickEnabled = true;		// allow line to be the target oif a double click event
+ 			
+			// update spaceBefore & spaceAfter		
+			var linePos:uint = line.location;
+			if (linePos & TextFlowLineLocation.FIRST)
+				line.setSpaceBefore(Number(_curParaFormat.paragraphSpaceBefore));
+			if (linePos & TextFlowLineLocation.LAST)
+	     		line.setSpaceAfter(Number(_curParaFormat.paragraphSpaceAfter)); 			
+ 			
+ 			return line;
+        }
+        
+        /** @private */
+		CONFIG::debug private static function validateLineStart(prevLine:TextFlowLine, lineStart:int, paraNode:ParagraphElement):void
+		{
+			// If the lines have been released, don't validate
+			if (lineStart != 0 && paraNode.getTextBlock().firstLine == null)
+				return;
+				
+	       	var testStart:int = 0;
+	    	var testLine:TextLine = prevLine ? prevLine.getTextLine(true) : null;
+	    	while (testLine)
+	    	{
+	    		testStart += testLine.rawTextLength;
+	    		testLine = testLine.previousLine;
+	    	}
+	    	assert(testStart == lineStart, "Bad lines");
+			
+      		assert(paraNode is ParagraphElement,"composeLine: paraNode must be a para"); 
+      		assert(!prevLine || !(prevLine.location & TextFlowLineLocation.LAST),"prevLine may not be from a different para"); 
+		} 
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/compose/FlowComposerBase.as b/textLayout_core/src/flashx/textLayout/compose/FlowComposerBase.as
new file mode 100755
index 0000000..0ab0cf4
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/compose/FlowComposerBase.as
@@ -0,0 +1,637 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{	
+	import flash.text.engine.TextBlock;
+	import flash.text.engine.TextLine;
+	import flash.text.engine.TextLineValidity;
+	
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.elements.BackgroundManager;
+	import flashx.textLayout.debug.Debugging;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+	
+	[Exclude(name="initializeLines",kind="method")]
+	[Exclude(name="addLine",kind="method")]
+	[Exclude(name="lines",kind="property")]
+	[Exclude(name="debugCheckTextFlowLines",kind="method")]
+	[Exclude(name="checkFirstDamage",kind="method")]
+	
+	/** 
+	 * The FlowComposerBase class is the base class for Text Layout Framework flow composer classes, which control the 
+	 * composition of text lines in ContainerController objects.
+	 *
+	 * <p>FlowComposerBase is a utility class that implements methods and properties that are common
+	 * to several types of flow composer. Application code would not typically instantiate or use this class
+	 * (unless extending it to create a custom flow composer).</p>
+	 * 
+	 * @see flashx.textLayout.elements.TextFlow#flowComposer
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	 
+	public class FlowComposerBase
+	{
+				// Composition data
+		[ ArrayElementType("text.elements.TextFlowLine") ]
+		private var _lines:Array;	
+		
+		/** @private */
+		protected var _textFlow:TextFlow;
+		
+		/** Absolute start of the damage area -- first character in the flow that is dirty and needs to be recomposed. @private */
+		protected var _damageAbsoluteStart:int;
+		
+		/** @private */
+		protected var _swfContext:ISWFContext;
+		
+		/** Constructor. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public function FlowComposerBase():void
+		{
+			_lines = new Array();
+			_swfContext = null;
+		}
+		
+		/** Returns the array of lines. @private */
+		public function get lines():Array
+		{ return _lines; }
+		
+		/** 
+		 * @copy IFlowComposer#getLineAt()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function getLineAt(index:int):TextFlowLine
+		{ return _lines[index]; }
+		
+		/** @copy IFlowComposer#numLines 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public function get numLines():int
+		{ return _lines.length; }
+		
+		/** 
+		* The TextFlow object to which this flow composer is attached. 
+		*
+		* @see flashx.textLayout.elements.TextFlow
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*/
+	 	
+		public function get textFlow():TextFlow
+		{ return _textFlow; }
+		
+		/**
+		 * The absolute position immediately preceding the first element in the text
+		 * flow that requires composition and updating.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		public function get damageAbsoluteStart():int
+		{
+			return _damageAbsoluteStart;
+		}
+		
+		/**
+		 * Initialize the lines for the TextFlow.  Creates a single TextFlowLine with no content. @private
+		 */ 
+		protected function initializeLines():void
+		{
+			var backgroundManager:BackgroundManager = _textFlow ? _textFlow.backgroundManager : null;
+			// remove all the lines we have now - cache for reuse
+			if (TextLineRecycler.textLineRecyclerEnabled)
+			{
+				for each (var line:TextFlowLine in _lines)
+				{
+					var textLine:TextLine = line.peekTextLine();
+					if (textLine && !textLine.parent)
+					{
+						// releasing all textLines so release each still connected textBlock
+						if (textLine.validity != TextLineValidity.INVALID)
+						{
+							var textBlock:TextBlock = textLine.textBlock;
+							CONFIG::debug { Debugging.traceFTECall(null,textBlock,"releaseLines",textBlock.firstLine,textBlock.lastLine); }
+							textBlock.releaseLines(textBlock.firstLine,textBlock.lastLine);
+						}
+						textLine.userData = null;
+						TextLineRecycler.addLineForReuse(textLine);
+						if (backgroundManager)
+							backgroundManager.removeLineFromCache(textLine);
+					}
+				}
+			}
+			_lines.splice(0);
+			_damageAbsoluteStart = 0;
+			
+			CONFIG::debug { checkFirstDamaged(); }
+		}
+		
+		/** Make sure that there is a TextFlowLine for all the content - even if compose has stopped early. @private */
+		protected function finalizeLinesAfterCompose():void
+		{
+			var line:TextFlowLine;
+			if (_lines.length == 0)
+			{
+				// create a new line, with damage, that covers the entire area
+				line = new TextFlowLine(null,null);
+				line.setTextLength(textFlow.textLength);
+				_lines.push(line);
+			}
+			else
+			{
+				line = _lines[_lines.length-1];
+				var lineEnd:int = line.absoluteStart + line.textLength;
+				if (lineEnd < textFlow.textLength)
+				{
+					line = new TextFlowLine(null,null);
+					line.setAbsoluteStart(lineEnd);
+					line.setTextLength(textFlow.textLength-lineEnd);
+					_lines.push(line);
+				}
+			}			
+		}
+		
+		/** 
+		 * @copy IFlowComposer#updateLengths()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		public function updateLengths(startPosition:int,deltaLength:int):void
+		{
+			// no lines yet - skip it
+			if (numLines == 0)
+				return;
+				
+			var line:TextFlowLine;	// sratch line variable
+			var lineIdx:int = findLineIndexAtPosition(startPosition);
+				
+			var damageStart:int = int.MAX_VALUE;			
+			if (deltaLength > 0)
+			{
+				if (lineIdx == _lines.length)
+				{
+					line = _lines[_lines.length-1];
+					CONFIG::debug { assert(line.absoluteStart+line.textLength == startPosition,"updateLengths bad startIdx"); }
+					line.setTextLength(line.textLength + deltaLength);
+				}
+				else
+				{
+					line = _lines[lineIdx++];
+					line.setTextLength(line.textLength + deltaLength);
+				}
+				damageStart = line.absoluteStart;
+			}
+			else
+			{
+				var lenToDel:int = -deltaLength;
+				var curPos:int = 0;
+				
+				while (true)
+				{
+					line = _lines[lineIdx];
+					line.setAbsoluteStart(line.absoluteStart + lenToDel + deltaLength);
+					curPos = (startPosition > line.absoluteStart ? startPosition : line.absoluteStart);
+					
+					var lineEndIdx:int = line.absoluteStart + line.textLength;
+					var deleteChars:int = 0;
+					
+					if (curPos + lenToDel <= lineEndIdx)		
+					{
+						if (curPos == line.absoluteStart)
+							deleteChars = lenToDel;				//delete from begin of line to end of selection
+						else if (curPos == startPosition)
+							deleteChars = lenToDel;				//delete is all included in one line
+						else
+						{
+							CONFIG::debug { assert(false, "insertText: should never happen");  }
+						}								
+					}
+					else //(curPos + lenToDel > lineEndIdx)		//multiline delete
+					{
+						if (curPos == line.absoluteStart)
+							deleteChars = line.textLength; 		//delete the whole line
+						else
+							deleteChars = lineEndIdx-curPos;	//delete from middle of line to end of line
+					}		
+						
+					if (curPos == line.absoluteStart && curPos + deleteChars == lineEndIdx)		//the whole line is selected
+					{
+						lenToDel -= deleteChars;
+						_lines.splice(lineIdx,1);			//lineIdx now points to the next line
+					}
+					else 									//partial line
+					{
+						if (damageStart > line.absoluteStart)
+							damageStart = line.absoluteStart;
+						line.setTextLength(line.textLength - deleteChars);
+						lenToDel -= deleteChars;
+						lineIdx++;
+					}
+					CONFIG::debug { assert(lenToDel >= 0,"updateLengths deleted too much"); }
+					if (lenToDel <= 0)
+							break;						
+				}
+			}
+			
+			for ( ; lineIdx < _lines.length; lineIdx++)
+			{
+				line = _lines[lineIdx];
+				if (deltaLength >= 0)
+					line.setAbsoluteStart(line.absoluteStart  + deltaLength);
+				else
+					line.setAbsoluteStart(line.absoluteStart > -deltaLength ? line.absoluteStart+deltaLength : 0);
+			}
+			
+			if (_damageAbsoluteStart > damageStart)
+				_damageAbsoluteStart = damageStart;
+		}
+		
+		/** 
+		 * @copy IFlowComposer#damage()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		public function damage(startPosition:int, damageLength:int, damageType:String):void
+		{
+			// find the line at damageStart
+			if (_lines.length == 0 || textFlow.textLength == 0)
+				return;
+				
+			// This case the damageStart is at the end of the text.  This can happen if the last paragraph is deleted
+			if (startPosition == textFlow.textLength)
+				return;
+				
+			CONFIG::debug { assert(startPosition + damageLength <= textFlow.textLength, "Damaging past end of flow!"); }
+			
+			// Start damaging one line before the startPosition location in case some of the first "damaged" line will fit on the previous line.
+			// We do this only if we're not on the first line of the paragraph -- figuring this out is expensive but otherwise we could damage
+			// back while we're composing because we damaged in the process of constructing a textBlock.
+			var lineIndex:int = findLineIndexAtPosition(startPosition);
+			var leaf:FlowLeafElement = textFlow.findLeaf(startPosition);
+			if (leaf && lineIndex > 0 && leaf.getParagraph().getAbsoluteStart() != startPosition)
+				lineIndex--;
+
+			if (lines[lineIndex].absoluteStart < _damageAbsoluteStart)
+				_damageAbsoluteStart = _lines[lineIndex].absoluteStart;
+				
+			CONFIG::debug { assert(lineIndex < _lines.length && _lines[lineIndex].absoluteStart <= startPosition + damageLength, "Missing line"); }
+			
+			while (lineIndex < _lines.length)
+			{
+				var line:TextFlowLine = _lines[lineIndex];
+				
+				// Changed to >= from >, as > seemed to damage too
+				// many lines when editing tables. 
+				// Should verify the correctness of this.
+				if (line.absoluteStart >= startPosition+damageLength)
+					break;
+				
+				line.damage(damageType);
+				lineIndex++;
+			}
+		}
+		
+		/**
+		 * @copy IFlowComposer#isDamaged()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function isDamaged(absolutePosition:int):Boolean
+		{
+			// Returns true if any text from _damageAbsoluteStart through absolutePosition needs to be recomposed
+			
+			// no lines - damaged
+			if (_lines.length == 0)
+				return true;
+				
+			CONFIG::debug { checkFirstDamaged(); }
+
+			return _damageAbsoluteStart <= absolutePosition && _damageAbsoluteStart != textFlow.textLength;
+		}
+
+		/** @private */
+		CONFIG::debug public function checkFirstDamaged():void
+		{
+			// find the line at start
+			if (_lines.length == 0)
+				return;
+				
+			var lineIndex:int = findLineIndexAtPosition(0);
+			while (lineIndex < _lines.length)
+			{
+				if (_lines[lineIndex].isDamaged())
+				{
+				//	trace("is damaged");
+					CONFIG::debug { assert(_lines[lineIndex].absoluteStart >= _damageAbsoluteStart, "_damageAbsoluteStart doesn't match actual line value"); } 
+					return;
+				}
+				++lineIndex;				
+			}
+		//	trace("not damaged");
+			return;
+		}
+		/** 
+		 * @copy IFlowComposer#findLineIndexAtPosition()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public function findLineIndexAtPosition(absolutePosition:int,preferPrevious:Boolean = false):int
+		{	
+			var lo:int = 0;
+			var hi:int = _lines.length-1;
+			while (lo <= hi)
+			{
+				var mid:int = (lo+hi)/2;
+				var line:TextFlowLine = _lines[mid];
+				if (line.absoluteStart <= absolutePosition)
+				{
+					if (preferPrevious)
+					{
+						if (line.absoluteStart + line.textLength >= absolutePosition)
+							return mid;
+					}
+					else
+					{
+						if (line.absoluteStart + line.textLength > absolutePosition)
+							return mid;
+					}
+					lo = mid+1;
+				}
+				else
+					hi = mid-1;
+			}
+			return _lines.length;
+		}
+		
+		/**
+		 * @copy IFlowComposer#findLineAtPosition()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function findLineAtPosition(absolutePosition:int,preferPrevious:Boolean = false):TextFlowLine
+		{
+			return _lines[findLineIndexAtPosition(absolutePosition,preferPrevious)];
+		}
+		
+		/**
+		 * add a new line 
+		 * Add a new line to the list of composed lines for the frame. Lines are sorted
+		 * by the start location, and each line has a span. The start of the next line
+		 * has to match the start of the previous line + the span of the previous line.
+		 * The last line needs to end at the end of the text. Therefore, when we add a
+		 * new line, we may need to adjust the span and/or start locations of other lines 
+		 * in the text.
+		 * @private
+		 */
+		public function addLine(newLine:TextFlowLine,workIndex:int):void
+		{
+			CONFIG::debug { assert(workIndex == findLineIndexAtPosition(newLine.absoluteStart),"bad workIndex to TextFlow.addLine"); };
+			CONFIG::debug { assert (!newLine.isDamaged(), "adding damaged line"); }
+			var workLine:TextFlowLine = _lines[workIndex];
+			var afterLine:TextFlowLine;
+			var damageStart:int = int.MAX_VALUE;
+			if (_damageAbsoluteStart == newLine.absoluteStart)
+				_damageAbsoluteStart = newLine.absoluteStart + newLine.textLength;
+				
+			if (workLine == null)
+				lines.push(newLine);				
+			else if (workLine.absoluteStart != newLine.absoluteStart)
+			{
+				if (workLine.absoluteStart + workLine.textLength > newLine.absoluteStart + newLine.textLength)
+				{
+					// Making a new line in the middle of an old one. Need to split the old one.
+					afterLine = new TextFlowLine(null,newLine.paragraph);
+					afterLine.setAbsoluteStart(newLine.absoluteStart + newLine.textLength);
+					var oldCharCount:int = workLine.textLength;
+					workLine.setTextLength(newLine.absoluteStart - workLine.absoluteStart);
+					CONFIG::debug { assert(workLine.textLength != 0, "0 width line"); }
+					afterLine.setTextLength((oldCharCount - newLine.textLength) - workLine.textLength);
+					CONFIG::debug { assert(afterLine.textLength != 0, "0 width line"); }
+					_lines.splice(workIndex + 1, 0, newLine, afterLine);
+				}
+				else
+				{
+					// We're composing ahead, so we need to split the line where we're at
+					// This can happen if a table is getting composed, some cells can be composed before 
+					// others that go before. 
+					CONFIG::debug { assert(workLine.isDamaged(), "Uneven line boundary, but lines marked up to date"); }
+					workLine.setTextLength(newLine.absoluteStart - workLine.absoluteStart);
+					CONFIG::debug { assert(workLine.textLength != 0, "0 width line"); }
+					afterLine = _lines[workIndex+1];
+					afterLine.setTextLength((newLine.absoluteStart + newLine.textLength) - afterLine.absoluteStart);
+					CONFIG::debug { assert(_lines[workIndex + 1].textLength != 0, "0 width line"); }
+					afterLine.setAbsoluteStart(newLine.absoluteStart + newLine.textLength);
+					_lines.splice(workIndex + 1, 0, newLine);
+				}
+				damageStart = workLine.absoluteStart;
+			}
+			else if (workLine.textLength > newLine.textLength)
+			{
+				// New line partially overlaps old line.
+				// Keep the old line, but resize it so it comes after the new line.
+				// Insert the new line at the old line's position
+				workLine.setTextLength(workLine.textLength - newLine.textLength);
+				CONFIG::debug { assert(workLine.textLength != 0, "0 width line"); }
+				workLine.setAbsoluteStart(newLine.absoluteStart + newLine.textLength);
+				workLine.damage(TextLineValidity.INVALID);
+				_lines.splice(workIndex, 0, newLine);
+				damageStart = workLine.absoluteStart;
+			}
+			else 
+			{
+				var deleteCount:int = 1;
+				// The new line completely overlaps the old line.
+				// Insert the new line over the old line. If the line extents don't match,
+				// fix-up the starting position & extent of the following line.
+				if (workLine.textLength != newLine.textLength)
+				{
+					var amtRemaining:int = (newLine.textLength - workLine.textLength);
+					var nextLine:int = workIndex + 1;
+					while (amtRemaining > 0)
+					{
+						afterLine = _lines[nextLine];
+						if (amtRemaining < afterLine.textLength)
+						{
+							afterLine.setTextLength(afterLine.textLength - amtRemaining);
+							afterLine.damage(TextLineValidity.INVALID);
+							break;
+						}
+						else
+						{
+							deleteCount++;
+							amtRemaining -= afterLine.textLength;
+							nextLine++;
+							afterLine = nextLine < _lines.length ? _lines[nextLine] : null
+						}
+					}
+					if (afterLine && afterLine.absoluteStart != newLine.absoluteStart + newLine.textLength)
+					{
+						afterLine.setAbsoluteStart(newLine.absoluteStart + newLine.textLength);
+						afterLine.damage(TextLineValidity.INVALID);
+						CONFIG::debug { assert(afterLine.textLength != 0, "0 width line"); }
+					}
+					damageStart = newLine.absoluteStart + newLine.textLength;
+				}
+				// remove userData on the deleted lines so they can be recycled
+				if (TextLineRecycler.textLineRecyclerEnabled)
+				{
+					var backgroundManager:BackgroundManager = textFlow.backgroundManager;
+					for (var recycleIdx:int = workIndex; recycleIdx < workIndex+deleteCount; recycleIdx++)
+					{
+						var textLine:TextLine = TextFlowLine(_lines[recycleIdx]).peekTextLine();
+						if (textLine && !textLine.parent)
+						{
+							// lines shouldn't be valid here but lets check anyhow
+							CONFIG::debug { assert(textLine.validity != TextLineValidity.VALID,"caught a bug here"); }
+							if (textLine.validity != TextLineValidity.VALID)	// recycle immediately if not parented
+							{
+								textLine.userData = null;
+								TextLineRecycler.addLineForReuse(textLine);
+								if (backgroundManager)
+									backgroundManager.removeLineFromCache(textLine);
+							}
+						}
+					}
+				}
+				_lines.splice(workIndex, deleteCount, newLine);
+			}
+	
+			if (_damageAbsoluteStart > damageStart)
+				_damageAbsoluteStart = damageStart;
+			// CONFIG::debug { debugCheckTextFlowLines(false); }
+	//		CONFIG::debug { checkFirstDamaged(); }	 enabling this will cause false positives due to _damageAbsoluteStart during composition not updated	when GEOMETRY_DAMAGE lines are cleared
+		}
+		
+		/** @private - helper function for finding a base swf context from a swf context */
+		tlf_internal static function computeBaseSWFContext(context:ISWFContext):ISWFContext
+		{
+			return context && Object(context).hasOwnProperty("getBaseSWFContext") ? context["getBaseSWFContext"]() : context;
+		}
+		/** 
+		* The ISWFContext instance used to make FTE calls as needed. 
+		*
+		* <p>By default, the ISWFContext implementation is this FlowComposerBase object.
+		* Applications can provide a custom implementation to use fonts
+		* embedded in a different SWF file or to cache and reuse text lines.</p>
+		* 
+		* @see flashx.textLayout.compose.ISWFContext
+		* 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*/
+ 	
+		public function get swfContext():ISWFContext
+		{
+			return _swfContext;
+		}
+		public function set swfContext(context:ISWFContext):void
+		{
+			if (context != _swfContext)
+			{
+				// swf contexts can be wrappers for other swf contexts - we're going to let the swfcontext give us a hint here
+				if (textFlow)
+				{
+					var newBaseContext:ISWFContext =  computeBaseSWFContext(context);
+					var oldBaseContext:ISWFContext =  computeBaseSWFContext(_swfContext);
+	
+					_swfContext = context;
+
+					if (newBaseContext != oldBaseContext)
+					{
+						damage(0,textFlow.textLength,FlowDamageType.INVALID);
+						textFlow.invalidateAllFormats();
+					}
+				}
+				else
+					_swfContext = context;				
+			}
+		}
+		
+		/**
+		 * Validate that the lines associated with the flow are internally consistent. 
+		 * @private
+		 * The start of the next line has to match the start of the previous line + the 
+		 * span of the previous line. The last line needs to end at the end of the flow,
+		 * and the first line must be at the start of the text.
+		 */
+		CONFIG::debug public function debugCheckTextFlowLines(validateControllers:Boolean=true):int
+		{
+			var rslt:int = 0;
+			var position:int = 0;
+			var overflow:Boolean = false;
+			for each (var line:TextFlowLine in _lines)
+			{
+				// trace("validateLines:",lines.indexOf(line).toString()," ",line.start," ",line.textLength);
+				rslt += assert(line.absoluteStart == position, "Line start incorrect");
+				rslt += assert(line.textLength >= 0,"Invalind length");
+				if (validateControllers)
+				{
+					var lineController:ContainerController = line.controller;
+					if (lineController != null)
+					{
+						rslt += assert(overflow == false,"non overflow line after overflow line?");
+						rslt += assert(line.absoluteStart >= line.controller.absoluteStart,"bad container mapping");
+						rslt += assert(line.absoluteStart+line.textLength<= lineController.absoluteStart+lineController.textLength,"bad container mapping");
+					}
+					else
+						overflow = true;
+				}
+				position += line.textLength;
+			}
+			return rslt;
+		}		
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/compose/FlowDamageType.as b/textLayout_core/src/flashx/textLayout/compose/FlowDamageType.as
new file mode 100755
index 0000000..a70e39a
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/compose/FlowDamageType.as
@@ -0,0 +1,60 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{
+	/**
+	 *  The FlowDamageType class is an enumeration class that defines types of damage for damage methods and events.
+	 * When the text content is updated, these changes are reflected in the TextLines after an update. TextLines are 
+	 * marked with a flag that specifies whether or not they are valid, or up to date with all text
+	 * changes. When the text is first updated, all lines are marked valid or static. After the text has been changed,
+	 * and before the next update, lines will be marked with a FlowDamageType that specifies what about the line
+	 * is invalid. Once the update is done, lines will again be marked as valid or static.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public class FlowDamageType
+	{
+		/** 
+		 * Value is used to set the <code>validity</code> property if the text content has changed since the
+		 * line was originally created. Invalid lines needs to be recreated before they are used for selection
+		 * or to display the text content changes.
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see flashx.textLayout.compose.TextFlowLine#validity	 	 */
+		static public const INVALID:String = "invalid";
+		
+		/**
+		 * Value is used to set the <code>validity</code> property if the line has been invalidated by other lines 
+		 * moving around. For instance, a line above may have been created, so this line needs to be moved down.
+		 * The text line might or might not need recreating at the next compose operation. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see flashx.textLayout.compose.TextFlowLine#validity
+	 	 */
+		static public const GEOMETRY:String = "geometry";
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/compose/IFlowComposer.as b/textLayout_core/src/flashx/textLayout/compose/IFlowComposer.as
new file mode 100755
index 0000000..f88d29f
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/compose/IFlowComposer.as
@@ -0,0 +1,498 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{
+	import flashx.textLayout.compose.ISWFContext;
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.edit.ISelectionManager;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.compose.TextFlowLine;
+
+	/**
+	 * IFlowComposer defines the interface for managing the layout and display of a text flow.
+	 * 
+	 * <p>Text flows displayed with a flow composer implementation can be dynamic and interactive.
+	 * A flow composer manages one or more display controller. Each controller is associated with
+	 * a display object container (such as a Sprite) through which the lines created for the text
+	 * flow are ultimately displayed. The following diagram illustrates the relationship between TextFlow,
+	 * IFlowComposer, ContainerController, and DisplayObjectContainer objects:</p>
+	 * 
+	 * <p><img src="../../../images/textLayout_singleController.gif" alt="IFlowComposer"></img></p>
+	 *
+	 * <p>A flow composer calculates which portion of a text flow fits in each container and 
+	 * adds the appropriate text lines to the container's display object. The IFlowComposer interface 
+	 * defines separate methods for layout calculations and for updating the display. IFlowComposer also 
+	 * defines methods for incrementally composing and updating a text flow. These methods can be used 
+	 * to avoid blocking the user interface when updating long text flows.</p>
+	 * 
+	 * <p>In addition to managing text composition and display, a flow composer controls which container has focus, 
+	 * manages the display of the selection highlight (which can cross container boundaries), and provides
+	 * direct access to all the TextLine objects in the flow.</p>
+	 * 
+	 * <p>To use an IFlowComposer implementation, assign an instance of that implementation to the
+	 * <code>flowComposer</code> property of a TextFlow object. Call the <code>updateAllControllers()</code>
+	 * method to lay out and display the text in the containers attached to the flow composer.</p>
+	 * 
+	 * <p><b>Note:</b> For simple, static text flows, you can also use the one of the text line factory classes.
+	 * These factory classes will typically create lines with less overhead than a flow composer, but do not
+	 * support editing, dynamic changes, or user interaction.</p>
+	 * 
+	 * @see flashx.textLayout.container.ContainerController ContainerController
+	 * @see FlowComposerBase
+	 * @see StandardFlowComposer
+	 * @see flashx.textLayout.elements.TextFlow TextFlow
+	 * @see flashx.textLayout.factory.StringTextLineFactory StringTextLineFactory
+	 * @see flashx.textLayout.factory.TextFlowTextLineFactory TextFlowTextLineFactory
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public interface IFlowComposer
+	{
+		/** 
+		 * The root element associated with this IFlowComposer instance. 
+		 * 
+		 * <p>Only a TextFlow object can be a root element.</p>
+		 *  
+		 * @see flashx.textLayout.elements.ContainerFormattedElement ContainerFormattedElement
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 function get rootElement():ContainerFormattedElement;
+		 function setRootElement(newRootElement:ContainerFormattedElement):void;
+			
+		/** 
+		 * The first invalid position in the root element, as an absolute position from the start of the flow.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		function get damageAbsoluteStart():int;
+		
+		/** 
+		 * Composes the content of the root element and updates the display.  
+		 *
+		 * <p>Text layout is typically conducted in two phases: composition and display. In the composition phase,
+		 * the flow composer calculates how many lines are necesary to display the content as well as the position of these 
+		 * lines in the flow's display containers. In the display phase, 
+		 * the flow composer updates the display object children of its containers. The <code>updateAllControllers()</code>
+		 * method is expected to carry out both phases. An efficient implementation will keep track of changes to content
+		 * so that a full cycle of composition and display is only performed when necessary.</p>
+		 * 
+		 * <p>This method updates all the text lines and the display list immediately and synchronously.</p>
+		 *
+		 * <p>If the contents of any container is changed, the method must return <code>true</code>.</p>
+		 * 
+		 * @return true if anything changed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 * 
+		 */
+		function updateAllControllers():Boolean;
+		
+		/** 
+		 * Composes and updates the display up to and including the container at the specified index.
+		 * 
+		 * <p>The <code>updateToController()</code> method is expected to both compose the content and 
+		 * update the display so that all containers up to and including the container at the specified index are current.
+		 * For example, if you have a chain of twenty containers and specify an index of 10, 
+		 * <code>updateToController()</code> must ensures that the first through the tenth (indexes 0-9) containers
+		 * are composed and displayed. Composition can stop at that point. If <code>controllerIndex</code> 
+		 * is -1 (or not specified), then all containers should be updated.</p>
+		 *
+		 * <p>This method updates all the text lines and the display list immediately and synchronously.</p>
+		 * 
+		 * <p>If the contents of any container is changed, the method must return <code>true</code>.</p>
+		 * 
+		 * @param controllerIndex index of the last container to update, by default will update all containers
+		 * @return true if anything changed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+		 */
+		 
+		function updateToController(index:int = int.MAX_VALUE):Boolean;
+		
+		/** 
+		 * Sets the focus to the container that contains the location specified by the <code>absolutePosition</code>
+		 * parameter. 
+		 *
+		 * <p>It is the responsibility of the implementation to define what setting the focus means. For example, an 
+		 * implementation could use the built-in <code>focus</code> property of the Stage object (as long as the
+		 * containers were InteractiveObjects) or the implementation could manage the focus some other way.</p>
+		 * 
+		 * @param absolutePosition Specifies the position in the text flow of the container to receive focus.
+		 * @param preferPrevious If true and the position is the before the first character in a container, sets focus to the end of 
+		 *  the previous container.
+		 * 
+		 * @see flash.display.Stage#focus
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		function setFocus(absolutePosition:int,preferPrevious:Boolean=false):void
+
+		/** 
+		 * Calculates how many lines are necessary to display the content in the root element of the flow and the positions of these 
+		 * lines in the flow's display containers.
+		 * 
+		 * <p>Implementations of this method should not update the display, but should save the results so that subsequent
+		 * calls to <code>compose()</code> or <code>updateAllControllers()</code> do not perform an additional recomposition
+		 * if the flow content has not changed.</p>
+		 * 
+		 * <p>If the contents of any container have changed, the method must return <code>true</code>.</p>
+		 * 
+		 * @return true if anything changed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see #updateAllControllers()
+	 	 * @see #updateToController()
+		 */
+		 
+		function compose():Boolean;
+		
+		/** 
+		 * Composes the content of the root element up to the specified position.
+		 * 
+		 * <p>If the contents of any container up to and including the container holding the content at the specified
+		 * position has changed, the method returns <code>true</code>. If <code>absolutePosition</code> is greater than the length of the TextFlow 
+		 * (or not specified), then the entire flow is composed.</p>
+		 * 
+		 * @param absolutePosition compose at least up to this position in the TextFlow. By default or if absolutePosition is past the end of the flow compose to the end of the flow.
+		 * @return true if anything changed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see #updateAllControllers()
+	 	 * @see #updateToController()
+		 */
+		 
+		function composeToPosition(absolutePosition:int = int.MAX_VALUE):Boolean;
+		
+		/** 
+		 * Composes the content of the root element up to and including the container at the specified index.
+		 * 
+		 * <p>If the contents of any container up to and including the container at the specified
+		 * index has changed, the method returns <code>true</code>. If <code>index</code> is greater than the number of controllers
+		 * (or not specified), then all containers are composed.</p>
+		 * 
+		 * @param controllerIndex compose at least up to this container in the TextFlow. If controllerIndex is greater than the number of controllers, compose to the end of the last container.
+		 * @return true if anything changed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see #updateAllControllers()
+	 	 * @see #updateToController()
+		 */
+		 
+		function composeToController(index:int = int.MAX_VALUE):Boolean;
+
+		/** 
+		 * The number of containers assigned to this IFlowComposer instance. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		function get numControllers():int;
+		
+		/** 
+		 * Adds a controller to this IFlowComposer instance.
+		 *
+		 * <p>The container is added to the end of the container list.</p>
+		 * 
+		 * @param controller The ContainerController object to add.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		function addController(controller:ContainerController):void;
+		
+		/** 
+		 * Adds a controller to this IFlowComposer instance at the specified index.
+		 *
+		 * <p>The list of controllers is 0-based (the first controller has an index of 0).</p>
+		 * 
+		 * @param controller The ContainerController object to add.
+		 * @param index A numeric index that specifies the position in the controller list at which to insert the ContainerController object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		function addControllerAt(controller:ContainerController, index:int):void;
+		
+		/** 
+		 * Removes a controller from this IFlowComposer instance. 
+		 * 
+		 * @param controller The ContainerController instance to remove.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		function removeController(controller:ContainerController):void;
+		
+		/** 
+		 * Removes the controller at the specified index from this IFlowComposer instance.
+		 *
+		 * @param index The index of the ContainerController object to remove.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		function removeControllerAt(index:int):void
+
+		/** 
+		 * Removes all controllers from this IFlowComposer instance. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		function removeAllControllers():void;
+
+		/** 
+		 * Returns the ContainerController object at the specified index. 
+		 * 
+		 * @param index The index of the ContainerController object to return.
+		 * @return 	the ContainerController object at the specified position.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	
+		function getControllerAt(index:int):ContainerController;
+		
+		/** 
+		 * Returns the index of the specified ContainerController object. 
+		 * 
+		 * @param controller A reference to the ContainerController object to find.
+		 * @return the index of the specified ContainerController object or -1 if the controller is not attached to this flow composer.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	
+		function getControllerIndex(controller:ContainerController):int;
+		
+		/** 
+		 * Returns the index of the controller containing the content at the specified position. 
+		 * 
+		 * <p>A position can be considered to be the division between two characters or other elements of a text flow. If 
+		 * the value in <code>absolutePosition</code> is a position between the last character of one 
+		 * container and the first character of the next, then the preceding container is returned if
+		 * the <code>preferPrevious</code> parameter is set to <code>true</code> and the later container is returned if
+		 * the <code>preferPrevious</code> parameter is set to <code>false</code>.</p>
+		 *
+		 * <p>The method must return -1 if the content at the specified position is not in any container or is outside
+		 * the range of positions in the text flow.</p>
+		 * 
+		 * @param absolutePosition The position of the content for which the container index is sought.
+		 * @param preferPrevious Specifies which container index to return when the position is between the last element in 
+		 * one container and the first element in the next.
+		 * 
+		 * @return 	the index of the container controller or -1 if not found.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */ 
+	 	 
+		function findControllerIndexAtPosition(absolutePosition:int,preferPrevious:Boolean=false):int;
+
+		/** 
+		 * Returns the sequential line number of the TextFlowLine object that contains the content at the specified position. 
+		 * 
+		 * <p>The number of the first line is 0 and the number of the last line is equal to the number of lines minus one.
+		 * If the position specified in <code>absolutePosition</code> is past the end of the text flow, this method must return
+		 * the number that will be assigned to the next new line added to the text flow (which is equal to the number of current lines).</p>
+		 *
+		 * <p>A position can be considered to be the division between two characters or other elements of a text flow. If 
+		 * the value in <code>absolutePosition</code> is a position between the last line of one 
+		 * container and the first line of the next, then the preceding container is returned if
+		 * the <code>preferPrevious</code> parameter is set to <code>true</code> and the later container is returned if
+		 * the <code>preferPrevious</code> parameter is set to <code>false</code>.</p>
+		 * 
+		 * @param absolutePosition	The position of the content for which you want the text line.
+		 * @param preferPrevious Specifies which container index to return when the position is between the last line in 
+		 * one container and the first line in the next.
+		 *
+		 * @return the index of the text line at the specified position. If not found, treats as past the end and returns the
+		 * number of lines.
+		 * 	 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		function findLineIndexAtPosition(absolutePosition:int,preferPrevious:Boolean = false):int;
+		
+		/** 
+		* Returns the TextFlowLine object containing the content at the specified position.
+		*
+		* <p>A position can be considered to be the division between two characters or other elements of a text flow. If 
+		* the value in <code>absolutePosition</code> is a position between the last element of one 
+		* line and the first element of the next, then the preceding line is returned if
+		* the <code>preferPrevious</code> parameter is set to <code>true</code> and the later line is returned if
+		* the <code>preferPrevious</code> parameter is set to <code>false</code>.</p>
+		* 
+		* @param absolutePosition	The position of the content for which you want the TextFlowLine object.
+		* @param preferPrevious		Specifies which line to return when the position is between the last element of 
+		* one line and the first element of the next.
+		*
+		* @return	the TextFlowLine containing the content at the specified position, or null if not found.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*/
+	 	
+		function findLineAtPosition(absolutePosition:int,preferPrevious:Boolean = false):TextFlowLine;
+		
+		/** 
+		 * Returns the line with the specified line number. 
+		 *
+		 * <p>The list of lines is numbered from zero to the number of lines minus one. If the value in <code>index</code>
+		 * is outside the bounds of the list of lines, then this function returns <code>null</code>.</p>
+		 * 
+		 * @param index		The line number of the TextFlowLine object to return.
+		 * @return	the TextFlowLine with the specified line number, or <code>null</code>, if not found.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		function getLineAt(index:int):TextFlowLine;
+		
+		/** 
+		 * The total number of lines in the flow. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		function get numLines():int;
+		
+		/** 
+		 * Indicates whether any TextFlowLine objects between the beginning of the flow and the line containing the content at 
+		 * the specified position are marked as damaged. 
+		 *
+		 * @param absolutePosition the last position in the area of interest
+		 * @return 	true if any of the TextFlowLine objects from the start of the flow up to the line containing the content at
+		 * <code>absolutePosition</code> are marked as damaged.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		function isDamaged(absolutePosition:int):Boolean;
+		
+		
+		/** 
+		 * True, if the flow composer is currently performing a composition operation.
+		 *  
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		function get composing():Boolean;
+		
+		/** 
+		 * The ISWFContext instance to be used for calls that must be made in a specific SWF context  
+		 * 
+		 * <p>Implementations of IFlowComposer should allow this property to be set so that users
+		 * of the interface can create lines in a different SWF context than the one containing the 
+		 * implementation.  A default implementation of ISWFContext should also be supplied.</p>
+		 * 
+		 * @see flashx.elements.ISWFContext ISWFContext
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		function get swfContext():ISWFContext;
+		function set swfContext(creator:ISWFContext):void;
+		
+		/**
+		 * Called by the TextFlow when the interaction manager changes. 
+		 * 
+		 * <p>Implementations of IFlowComposer should update event listeners and properties
+		 * that reference the interaction manager.</p>
+		 * 
+		 * @param newInteractionManager The new ISelectionManager instance.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+
+		function interactionManagerChanged(newInteractionManager:ISelectionManager):void
+		
+		/** Update the lengths in the lines to maintain mapping to the TextFlow. 
+		 * 
+		 * @param startPosition beginning of change in length
+		 * @param deltaLength change in number of characters.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function updateLengths(startPosition:int,deltaLength:int):void;
+		
+		/** Mark lines as damaged and needing a recompose.
+		 * @param damageStart beginning of range to damage
+		 * @param damageLength number of characters to damage
+		 * @param damageType type of damage.  One of flashx.textLayout.compose.FlowDamageType
+		 * @see flashx.textLayout.compose.FlowDamageType
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function damage(startPosition:int, damageLength:int, damageType:String):void;
+	}
+
+}
diff --git a/textLayout_core/src/flashx/textLayout/compose/IParcelList.as b/textLayout_core/src/flashx/textLayout/compose/IParcelList.as
new file mode 100755
index 0000000..c7191ab
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/compose/IParcelList.as
@@ -0,0 +1,150 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{
+	import flash.geom.Rectangle;
+	
+	import flashx.textLayout.container.ContainerController;
+		
+	[ExcludeClass]
+	/** @private
+	 * The area inside a text container is sub-divided into smaller areas available for
+	 * text layout. These smaller areas within the container are called Parcels. The 
+	 * ParcelList manages the parcels associated with a TextFlow during composition.
+	 * 
+	 * A container will always have at least one parcel, which corresponds to the container's
+	 * bounding box. If the container has more than one column, each column appears as
+	 * a parcel in the parcel list. If the container has wrap applied, the area around the
+	 * wrap that is available for layout is divided into rectangular-shaped parcels.
+	 * Lastly, parcels may be created during composition for use by flow elements that require
+	 * layout within a specific geometry that may not be the same as the columns: for instance, 
+	 * a straddle head, a table, or a sidehead.
+	 */
+	public interface IParcelList  
+	{
+		/** Initialize the parcel list from the flow composer. The parcel list will
+		 * have the bounding box of the controller(s). If the controller has multiple
+		 * columns, the parcel list will have a parcel for each column. If the 
+		 * controller has wraps, the parcel list may have more parcels to work around
+		 * the wrap areas.
+		 * @param composer	composer we're using
+		 * @param controllerEndIndex	compose through the end of this controller
+		 * @param forceComposeToEnd		force composition to compose all lines of the last controller, even if it's scrollable (will not compose overset text)
+		 */
+		function beginCompose(composer:IFlowComposer, controllerEndIndex:int, forceComposeToEnd:Boolean):void;
+		
+		/** Callback function to notify clients that we're advancing forward to the next parcel. */
+		function get notifyOnParcelChange():Function;
+		function set notifyOnParcelChange(val:Function):void
+		
+		/** Return the left side coordinate of the current parcel.
+		 */
+		function get left():Number;
+		
+		/** Return the right side coordinate of the current parcel.
+		 */
+		function get right():Number;
+		
+		/** Return the top edge coordinate of the current parcel.
+		 */
+		function get top():Number;
+		
+		/** Return the bottom edge coordinate of the current parcel.
+		 */
+		function get bottom():Number;
+		
+		/** Return the width of the current parcel.
+		 */
+		function get width():Number;
+		
+		/** Return the height of the current parcel.
+		 */
+		function get height():Number;
+		
+		/** Returns the column number of the current parcel. */
+		function get columnIndex():int;
+		
+		/** Vertical location within the parcel, as an offset from the top
+		 * of the parcel.
+		 */
+		function get totalDepth():Number;
+		function addTotalDepth(value:Number):Number;
+		
+		/** Return the controller associated with the current parcel.
+		 */
+		function get controller():ContainerController;
+		
+		/** Return the current parcel. Null if we're at the end of the parcel list.
+		 */
+		function get currentParcel():Parcel;
+
+		/** Advance to the next parcel; it will now be the current parcel.
+		 * @return Boolean	false if there is no next parcel.
+		 */
+		function next():Boolean;
+		
+		/** Returns true if the current parcel is the last.
+		 */
+		function atLast():Boolean;
+		
+		/** Returns true if all parcels have been iterated: current parcel is past the last.
+		 */
+		function atEnd():Boolean;
+
+		/** True if the current parcel is at the top of the column */
+		function isColumnStart():Boolean;
+		
+		/** True if we are not wrapping to the composition logical width */
+		function get explicitLineBreaks():Boolean;
+		
+		/** Create a new parcel within the parcel list, for an item with the
+		 * specified geometry. The new parcel is set to the current parcel.
+		 * @param parcel	geometry of the new parcel
+		 * @param blockProgression direction of the text (horizontal or vertical)
+		 * @param verticalJump	true if next parcel goes below this, false if it goes to the right or left
+		 * @return Boolean	true if parcel could be create, false if it doesn't fit
+		 * @see text.formats.BlockProgression
+		 */
+		function createParcel(parcel:Rectangle, blockProgression:String, verticalJump:Boolean):Boolean;
+
+		/** Create a new parcel within the parcel list, for an item with the
+		 * specified geometry. The new parcel is set to the current parcel.
+		 * @param parcel	geometry of the new parcel
+		 * @param blockProgression direction of the text (horizontal or vertical)
+		 * @param verticalJump	true if next parcel goes below this, false if it goes to the right or left
+		 * @return Boolean	true if parcel could be create, false if it doesn't fit
+		 * @see text.formats.BlockProgression
+		 */
+		function createParcelExperimental(parcel:Rectangle, wrapType:String):Boolean;
+
+		/**Return the width for a line that goes at the current vertical location,
+		 * and could extend down for at least height pixels. Note that this function
+		 * can change the current parcel, and the location within the parcel.
+		 * @param height	amount of contiguous vertical space that must be available
+		 * @param minWidth	amount of contiguous horizontal space that must be available 
+		 * @return amount of contiguous horizontal space actually available
+		 */
+		function getLineSlug(slugRect:Rectangle,height:Number, minWidth:Number = 0):Boolean;
+		
+		function getComposeXCoord(slug:Rectangle):Number;
+		function getComposeYCoord(slug:Rectangle):Number;
+		function getComposeWidth(slug:Rectangle):Number;
+		function getComposeHeight(slug:Rectangle):Number;
+	}	//end interface
+} //end package
diff --git a/textLayout_core/src/flashx/textLayout/compose/ISWFContext.as b/textLayout_core/src/flashx/textLayout/compose/ISWFContext.as
new file mode 100755
index 0000000..10c1028
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/compose/ISWFContext.as
@@ -0,0 +1,78 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{
+	/** 
+	 * The ISWFContext interface allows a SWF file to share its context with other SWF files that load it.
+	 * An application that loads a SWF file of type ISWFContext can call methods in the context of the loaded SWF file.
+	 * The main usage is for calling the FTE TextLine creation methods.
+	 * 
+	 * <p>There are two reasons for an application to use 
+	 * this interface to control TextLine creation: </p>
+	 * <ul>
+	 *   <li><strong>Reuse an embedded font: </strong> if an application wants to use a font embedded in a loaded SWF file,
+	 * the application can access the font if a TextLine
+	 * is created in the context of the loaded SWF file.</li>
+	 *   <li><strong>Reuse existing TextLine instances</strong>: reusing existing TextLine instances can result in faster recompose times. 
+	 * TLF reuses existing TextLine instances internally. TLF reuses 
+	 * a TextLine by calling <code>TextBlock.recreateTextLine()</code>
+	 * instead of <code>TextBlock.createTextLine()</code> when TLF recognizes that a TextLine is extant.</li>
+	 * </ul>
+	 *
+	 * 
+	 * <p>Your application may have additional TextLine instances that can be reused. 
+	 * To manually reuse existing TextLine instances:</p>
+	 * <ol>
+	 *   <li>trap calls to <code>TextBlock.createTextLine()</code>, then</li>
+	 *   <li>call <code>TextBlock.recreateTextLine()</code> with the extant TextLine instance instead 
+	 * of <code>TextBlock.createTextLine()</code>.</li>
+	 * </ol>
+	 * <p>Please note, however, that the <code>TextBlock.recreateTextLine()</code> is available
+	 * only in Flash Player 10.1 and later.</p>
+	 *
+	 * @see flash.text.engine.TextBlock#createTextLine()
+	 * @see flash.text.engine.TextBlock#recreateTextLine()
+	 * @includeExample examples\EmbeddedFontLineCreator.as -noswf
+	 * @includeExample examples\FontConsumer.as -noswf
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public interface ISWFContext
+	{
+	    /**
+	     *  A way to call a method in a client controlled context.
+	     *
+	     *  @param fn The function or method to call
+	     *  @param thisArg The this pointer for the function
+	     *  @param argArray The arguments for the function
+	     *  @param returns If true, the function returns a value
+	     *
+	     *  @return Whatever the function returns, if anything.
+	     *
+	     *  @see Function#apply()
+	
+	     *  @langversion 3.0
+	     *  @playerversion Flash 10
+	     *  @playerversion AIR 1.5
+	     */
+	    function callInContext(fn:Function, thisArg:Object, argArray:Array, returns:Boolean=true):*;
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/compose/ITextLineCreator.as b/textLayout_core/src/flashx/textLayout/compose/ITextLineCreator.as
new file mode 100755
index 0000000..a6246ed
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/compose/ITextLineCreator.as
@@ -0,0 +1,101 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{
+	import flash.text.engine.TextBlock;
+	import flash.text.engine.TextLine;
+	
+	/** 
+	 * ITextLineCreator defines an interface for creating TextLine objects for an IFlowComposer instance.
+	 * 
+	 * <p>The ITextLineCreator interface wraps the FTE line creation methods.
+	 * There are basically two reasons why an application might want to use 
+	 * this interface to control the line creation. First,
+	 * if the application has a SWF that contains a font, and you want to 
+	 * use that font from a different SWF, you can reuse the
+	 * font if the TextLine was created from the same SWF that has the font. 
+	 * Second, you can get a faster recompose time by reusing 
+	 * existing TextLines. TLF does that internally, and when it is reusing 
+	 * it will call recreateTextLine instead of createTextLine.
+	 * Your application may have additional TextLines that it knows can be reused. 
+	 * If so, in your implementation of createTextLine,
+	 * you may call TextBlock.recreateTextLine with the line to be reused instead 
+	 * of TextBlock.createTextLine.</p>
+	 *
+	 * @see flast.text.engine.TextLine
+	 * @see flashx.textLayout.compose.IFlowComposer
+	 * @see flashx.textLayout.elements.TextFlow TextFlow
+	 * 
+	 * @includeExample examples\ITextLineCreator_ClassExample.as -noswf
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public interface ITextLineCreator
+	{
+		/** 
+		 * Creates a TextLine object for a flow composer.
+		 * 
+		 * <p>Called by a flow composer when a text line must be created.</p>
+		 * 
+		 * @param textBlock The TextBlock object for which the line is to be created.
+		 * @param previousLine The previous line created for the TextBlock, if any.
+		 * @param width The maximum width of the line.
+		 * @param lineOffset An optional offset value.
+		 * @param fitSomething If <code>true</code>, at least one character or inline graphic must be fit on the line
+		 * even if that element causes the line to exceed the value in the <code>width</code> parameter.
+		 * 
+		 * @return TextLine the created TextLine object
+		 *  
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		function createTextLine(textBlock:TextBlock, previousLine:TextLine = null, width:Number = 1000000, lineOffset:Number = 0.0, fitSomething:Boolean = false):TextLine
+
+		/** 
+		 * Recreates a TextLine object for a flow composer.
+		 * 
+		 * <p>Called by a flow composer when a text line must be recreated.</p>
+		 * 
+		 * <p><b>Note:</b> The TextBlock <code>recreateTextLine()</code> method is available starting in
+		 * Flash Player 10.1 and AIR 2.0. To implement this method so that it is compatible with
+		 * earlier runtimes, test for the existence of the <code>recreateTextLine()</code> method 
+		 * on the TextBlock object before calling it.</p>
+		 *  
+		 * @param textBlock The TextBlock object for which the line is to be created.
+		 * @param previousLine The previous line created for the TextBlock, if any.
+		 * @param width The maximum width of the line.
+		 * @param lineOffset An optional offset value.
+		 * @param fitSomething If <code>true</code>, at least one character or inline graphic must be fit on the line
+		 * even if that element causes the line to exceed the value in the <code>width</code> parameter.
+		 * 
+		 * @return TextLine the recreated TextLine object
+		 * 
+		 * @includeExample examples\ITextLineCreator_recreateTextLine.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		function recreateTextLine(textBlock:TextBlock, textLine:TextLine, previousLine:TextLine = null, width:Number = 1000000, lineOffset:Number = 0.0, fitSomething:Boolean = false):TextLine
+
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/compose/IVerticalJustificationLine.as b/textLayout_core/src/flashx/textLayout/compose/IVerticalJustificationLine.as
new file mode 100755
index 0000000..6ca2b59
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/compose/IVerticalJustificationLine.as
@@ -0,0 +1,93 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.tlf_internal;
+	
+	/** 
+	 * The IVerticalJustificationLine interface defines the methods and properties required to allow
+	 * the vertical justification of text lines.
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */
+	public interface IVerticalJustificationLine
+	{
+		/** 
+		 * The horizontal position of the line relative to its container, expressed as the offset in pixels from the 
+		 * left of the container.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see #y
+		 */
+		function get x():Number;
+		
+		/** Set X location for the line.  Used only during vertical justification. @private */
+		function set x(val:Number):void;
+		
+		/** 
+		 * The vertical position of the line relative to its container, expressed as the offset in pixels from the top 
+		 * of the container.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 * 
+	 	 * @see #x
+		 */
+		function get y():Number;
+		
+		/** Set Y location for the line.  Used only during vertical justification. @private */
+		function set y(val:Number):void;
+		
+		/** 
+		 * @copy flash.text.engine.TextLine#ascent
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		function get ascent():Number;
+		
+		/** 
+		 * @copy flash.text.engine.TextLine#descent
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		function get descent():Number;
+		
+		/** The height of the line in pixels.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+		 */
+		function get height():Number;
+	}
+
+}
diff --git a/textLayout_core/src/flashx/textLayout/compose/Parcel.as b/textLayout_core/src/flashx/textLayout/compose/Parcel.as
new file mode 100755
index 0000000..f9a6266
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/compose/Parcel.as
@@ -0,0 +1,114 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{
+	import flash.geom.Rectangle;
+	
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+		
+	[ExcludeClass]
+	/** Helper class for implementations of IParcelList
+	 * 
+	 * @private
+	 */
+	public class Parcel extends Rectangle
+	{
+		public static const TOP_OF_COLUMN:int = 1;
+		public static const BOT_OF_COLUMN:int = 2;
+		public static const FULL_COLUMN:int = 3;
+		
+		/** Constructor. */
+		public function Parcel(x:Number, y:Number, width:Number, height:Number, cont:ContainerController, col:int, colCoverage:int)
+		{
+			super(x,y,width,height);
+			_controller   = cont;
+			_column       =  col;
+			_columnCoverage = colCoverage;
+			_fitAny	  = false;
+			_composeToPosition = false;
+		}
+		
+		public function initialize(x:Number, y:Number, width:Number, height:Number, cont:ContainerController, col:int, colCoverage:int):Parcel
+		{
+			this.x = x;
+			this.y = y;
+			this.width = width;
+			this.height = height;
+			
+			_controller   = cont;
+			_column       =  col;
+			_columnCoverage = colCoverage;
+			_fitAny	  = false;
+			_composeToPosition = false;
+			
+			return this;
+		}
+		
+		private var _controller:ContainerController;
+		private var _columnCoverage:int;
+		private var _column:int;
+		private var _fitAny:Boolean;
+		private var _composeToPosition:Boolean;
+		
+		/** prevent any leaks. @private */
+		tlf_internal function releaseAnyReferences():void
+		{
+			_controller = null;
+		}
+		
+		public function replaceBounds(r:Rectangle):void
+		{
+			this.x = r.x;
+			this.y = r.y;
+			this.width = r.width;
+			this.height = r.height;
+		}
+		
+		public function get controller():ContainerController
+		{ return _controller; }
+
+		public function get topOfColumn():Boolean
+		{ return (_columnCoverage&TOP_OF_COLUMN) == TOP_OF_COLUMN; }
+		/** describes how this parcel covers its source column */
+		public function get columnCoverage():int
+		{ return _columnCoverage; }
+		public function set columnCoverage(val:int):void
+		{ _columnCoverage = val; }
+		/** column number in the container */
+		public function get column():int
+		{ return _column; }
+		public function get fitAny():Boolean
+		{ return _fitAny; }
+		public function set fitAny(value:Boolean):void
+		{ _fitAny = value; }
+		public function get composeToPosition():Boolean
+		{ return _composeToPosition; }
+		public function set composeToPosition(value:Boolean):void
+		{ _composeToPosition = value; }
+		/** Do explicit line breaking (no wrapping) */
+		public function get measureWidth():Boolean
+		{ return controller.measureWidth; }
+		public function get measureHeight():Boolean
+		{ return controller.measureHeight; }
+
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/compose/ParcelList.as b/textLayout_core/src/flashx/textLayout/compose/ParcelList.as
new file mode 100755
index 0000000..7257392
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/compose/ParcelList.as
@@ -0,0 +1,509 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{
+	import flash.geom.Rectangle;
+	import flash.text.engine.TextLine;
+	
+	import flashx.textLayout.container.ColumnState;
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.container.ScrollPolicy;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.LineBreak;
+	import flashx.textLayout.formats.VerticalAlign;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+			
+	[ExcludeClass]
+	/** @private
+	 * Implementation of IParcelList used for composing text containers that have single
+	 * column, no wraps, and no floats.
+	 * 
+	 * ParcelList will always have one parcel, which corresponds to the container's
+	 * bounding box. 
+	 */
+	public class ParcelList implements IParcelList  
+	{
+		protected var _flowComposer:IFlowComposer;
+		
+		/** Current vertical position in the parcel. */
+		protected var _totalDepth:Number;
+		
+		/** whether the current parcel has any content */
+		protected var _hasContent:Boolean;
+		
+		/** The list of parcels that are available for text layout.
+			They are appear in the array in reading order: the first text goes in the
+			first parcel, when it gets filled later text is flowed into the second 
+			parcel, and so on.  */
+		private var _parcelArray:Array;	/* of Parcel */
+		private var _numParcels:int;
+		private var _singleParcel:Parcel;
+		
+		/** Index of the "current" parcel. These next two variables must be kept in sync. */
+		protected var _currentParcelIndex:int;
+		protected var _currentParcel:Parcel;
+		
+		/** Callback to notify that we're going to the next parcel */
+		protected var _notifyOnParcelChange:Function;
+		
+		/** Column number of the current parcel */
+		private var _columnIndex:int;
+		private var _columnController:ContainerController;
+		
+		private var _explicitLineBreaks:Boolean;
+		
+		/** true if we should include the last line if any part of it fits */
+	//	protected var _includePartialLine:Boolean;
+		
+		
+	//	private var parcel:Parcel;
+	
+		private static const MAX_HEIGHT:Number = 900000000;		// vertical scroll max - capped to prevent loss of precision - what should it be?
+		private static const MAX_WIDTH:Number =  900000000;		// horizontal scroll max - capped to prevent loss of precision - what should it be?
+
+			/** minimum allowable width of a line */
+			
+		/** Writing mode for vertical, left to right and left to right. @see text.formats.BlockProgression */
+		protected var _blockProgression:String;
+		
+		// a single parcellist that is checked out and checked in
+		static private var _sharedParcelList:ParcelList;
+
+		/** @private */
+		static tlf_internal function getParcelList():ParcelList
+		{
+			var rslt:ParcelList = _sharedParcelList ? _sharedParcelList : new ParcelList();
+			_sharedParcelList = null;
+			return rslt;
+		}
+		
+		/** @private */
+		static tlf_internal function releaseParcelList(list:IParcelList):void
+		{
+			if (_sharedParcelList == null)
+			{
+				_sharedParcelList = list as ParcelList;
+				if (_sharedParcelList)
+					_sharedParcelList.releaseAnyReferences();
+			}
+		}
+
+		/** Constructor. */
+		public function ParcelList()
+		{ _numParcels = 0;	}
+		
+		/** prevent any leaks. @private */
+		tlf_internal function releaseAnyReferences():void
+		{
+			this._flowComposer = null;
+			this._columnController = null;
+			
+			_numParcels = 0;
+			_parcelArray = null;
+			
+			if (_singleParcel)
+				_singleParcel.releaseAnyReferences();
+		}
+		
+		CONFIG::debug public function getBounds():Array
+		{
+			var boundsArray:Array = [];
+			for (var i:int = 0; i < _numParcels; ++i)
+				boundsArray.push(getParcelAtIndex(i));
+			return boundsArray;
+		}
+		
+		protected function get numParcels():int
+		{ return _numParcels; }
+		
+		protected function getParcelAtIndex(idx:int):Parcel
+		{ return _numParcels == 1 ? _singleParcel : _parcelArray[idx]; }
+		
+		protected function insertParcel(startIdx:int, parcel:Parcel):void
+		{
+			if (_numParcels == 0)
+				_singleParcel = parcel;
+			else
+			{
+				if (_numParcels == 1)
+					_parcelArray = [ _singleParcel ];
+				_parcelArray.splice(startIdx, 0, parcel);
+			}
+			_numParcels++;
+		}
+		
+		protected function set parcels(newParcels:Array):void
+		{
+			_numParcels = newParcels.length;
+			if (_numParcels == 0)
+				_parcelArray = null;
+			else if (_numParcels == 1)
+			{
+				_parcelArray = null;
+				_singleParcel = newParcels[0];
+			}
+			else
+				_parcelArray = newParcels;
+		}
+		
+		public function get left():Number
+		{
+			return _currentParcel.left;
+		}
+		
+		public function get right():Number
+		{
+			return _currentParcel.right;
+		}
+		
+		public function get top():Number
+		{
+			return _currentParcel.top;
+		}
+		
+		public function get bottom():Number
+		{
+			return _currentParcel.bottom;
+		}
+		
+		public function get width():Number
+		{
+			return _currentParcel.width;
+		}
+		
+		public function get height():Number
+		{
+			return _currentParcel.height;
+		}
+		
+		public function get fitAny():Boolean
+		{
+			return _currentParcel.fitAny;
+		}
+				
+		public function get controller():ContainerController
+		{
+			return _columnController;
+		}
+		
+		public function get columnIndex():int
+		{ return _columnIndex; }
+		
+		public function get explicitLineBreaks():Boolean
+		{ 
+			return _explicitLineBreaks;
+		}
+		
+		private function get measureWidth():Boolean
+		{
+			if (_explicitLineBreaks)
+				return true;
+			if (!_currentParcel)
+				return false;
+			if (_blockProgression == BlockProgression.TB)
+				return _currentParcel.measureWidth;
+			else
+				return _currentParcel.measureHeight;
+		}
+
+		private function get measureHeight():Boolean
+		{
+			if (!_currentParcel)
+				return false;
+			if (_blockProgression == BlockProgression.TB)
+				return _currentParcel.measureHeight;
+			else
+				return _currentParcel.measureWidth;
+		}
+		
+		public function get totalDepth():Number
+		{
+			return _totalDepth;
+		}
+		
+		public function get notifyOnParcelChange():Function
+		{
+			return _notifyOnParcelChange;
+		}
+		
+		public function set notifyOnParcelChange(val:Function):void
+		{
+			_notifyOnParcelChange = val;
+		}
+		
+		public function addTotalDepth(value:Number):Number
+		{
+			_hasContent = true;
+			_totalDepth += value;	
+		//	trace("addTotalDepth", value, "newDepth", totalDepth);
+			return _totalDepth;
+		}
+		
+		protected function reset():void
+		{
+			_totalDepth = 0;
+			_hasContent = false;
+			_columnIndex = 0;
+			_currentParcelIndex = 0;
+			
+			if (_numParcels != 0)
+			{
+				_currentParcel    = getParcelAtIndex(_currentParcelIndex);
+				_columnController =  _currentParcel.controller;
+				_columnIndex      = 0;
+			}
+			else
+			{
+				_currentParcel = null;
+				_columnController =  null;
+				_columnIndex = -1;
+			}
+		}
+		
+		private function addParcel(column:Rectangle, cont:ContainerController, col:int, colCoverage:int):void
+		{
+			var newParcel:Parcel = _numParcels == 0 && _singleParcel 
+				? _singleParcel.initialize(column.x,column.y,column.width,column.height,cont,col,colCoverage) 
+				: new Parcel(column.x, column.y, column.width, column.height, cont, col, colCoverage)
+			if (_numParcels == 0)
+				_singleParcel = newParcel;
+			else if (numParcels == 1)
+				_parcelArray = [  _singleParcel, newParcel ];
+			else
+				_parcelArray.push(newParcel);
+			_numParcels++;
+		}
+		
+		protected function addOneControllerToParcelList(controllerToInitialize:ContainerController):void
+		{
+			// Initialize new parcels for columns
+			var columnState:ColumnState = controllerToInitialize.columnState;
+			for (var columnIndex:int = 0; columnIndex < columnState.columnCount; columnIndex++)
+			{
+				var column:Rectangle = columnState.getColumnAt(columnIndex);
+				if (!column.isEmpty())
+					addParcel(column, controllerToInitialize, columnIndex, Parcel.FULL_COLUMN);
+			}
+		}
+		
+		public function beginCompose(composer:IFlowComposer, controllerEndIndex:int, composeToPosition:Boolean):void
+		{
+			_flowComposer = composer;
+			
+			var rootFormat:ITextLayoutFormat = composer.rootElement.computedFormat;
+			_explicitLineBreaks = rootFormat.lineBreak == LineBreak.EXPLICIT;
+			_blockProgression   = rootFormat.blockProgression;
+			
+			if (composer.numControllers != 0)
+			{
+				// if controllerEndIndex is not specified then assume we are composing to position and add all controllers
+				if (controllerEndIndex < 0)
+					controllerEndIndex = composer.numControllers-1;
+				else
+					controllerEndIndex = Math.min(controllerEndIndex,composer.numControllers-1);
+				var idx:int = 0;
+				do
+				{
+					addOneControllerToParcelList(ContainerController(composer.getControllerAt(idx)));
+				} while (idx++ != controllerEndIndex)
+				// adjust the last container for scrolling
+				if (controllerEndIndex == composer.numControllers-1)
+					adjustForScroll(ContainerController(ContainerController(composer.getControllerAt(composer.numControllers-1))), composeToPosition);
+			}
+			reset();
+		}
+		
+		/** Adjust the size of the parcel corresponding to the last column of the containter, in 
+		 * order to account for scrolling.
+		 */
+		private function adjustForScroll(containerToInitialize:ContainerController, composeToPosition:Boolean):void
+		{			
+			// Expand the last parcel if scrolling could be enabled. Expand to twice what would fit in available space. 
+			// We will start composing from the top, so if we've scrolled down there will be more to compose.
+			// We turn on fitAny, so that lines will be included in the container even if only a tiny portion of the line
+			// fits. This makes lines that are only partially scrolling in appear. We turn on composeToPosition if we're
+			// forcing composition to go through a given position -- this will make all lines fit, and composition will
+			// continue until it is past the supplied position.
+			if (_blockProgression != BlockProgression.RL)
+			{
+				if (containerToInitialize.verticalScrollPolicy != ScrollPolicy.OFF)
+				{
+					var p:Parcel = getParcelAtIndex(_numParcels-1);
+					if (p)
+					{
+						var verticalPaddingAmount:Number = containerToInitialize.effectivePaddingBottom + containerToInitialize.effectivePaddingTop;
+						p.bottom = containerToInitialize.verticalScrollPosition + p.height + verticalPaddingAmount;
+						p.fitAny = true;
+						p.composeToPosition = composeToPosition;
+					}
+				}
+			}
+			else	// vertical text case
+			{
+				if (containerToInitialize.horizontalScrollPolicy != ScrollPolicy.OFF)
+				{
+					p = getParcelAtIndex(_numParcels-1);
+					if (p)
+					{
+						var horizontalPaddingAmount:Number = containerToInitialize.effectivePaddingRight + containerToInitialize.effectivePaddingLeft;
+						p.left = containerToInitialize.horizontalScrollPosition - p.width - horizontalPaddingAmount;
+						p.fitAny = true;
+						p.composeToPosition = composeToPosition;
+					}
+				}
+			}
+		}
+
+		public		function getComposeXCoord(o:Rectangle):Number
+		{ 
+			// trace("LPL: getComposeXCoord");
+			return _blockProgression == BlockProgression.RL ? o.right : o.left;
+		}
+		public		function getComposeYCoord(o:Rectangle):Number
+		{ 
+			// trace("LPL: getComposeYCoord");
+			return o.top;
+		}
+
+		public function getComposeWidth(o:Rectangle):Number
+		{ 
+			// trace("LPL: getComposeWidth");
+			if (measureWidth)
+				return TextLine.MAX_LINE_WIDTH;
+			return _blockProgression == BlockProgression.RL ? o.height : o.width; 
+		}
+		public function getComposeHeight(o:Rectangle):Number
+		{ 
+			// trace("LPL: getComposeHeight");
+			if (measureHeight)
+				return TextLine.MAX_LINE_WIDTH;
+			return _blockProgression == BlockProgression.RL ? o.width : o.height; 
+		}		
+		/** True if the current parcel is at the top of the column */
+		public function isColumnStart():Boolean
+		{
+			return (!_hasContent && _currentParcel.topOfColumn);
+		}
+		
+		/** Returns true if the current parcel is the last.
+		*/
+		public function atLast():Boolean
+		{
+			return _numParcels == 0 || _currentParcelIndex == _numParcels -1;
+		}
+		
+		public function atEnd():Boolean
+		{
+			return _numParcels == 0 || _currentParcelIndex >= _numParcels;
+		}
+		
+		public function next():Boolean
+		{
+			CONFIG::debug { assert(_currentParcelIndex >= 0 && _currentParcelIndex < _numParcels, "invalid _currentParcelIndex in ParcelList"); }			
+			var nextParcelIsValid:Boolean = (_currentParcelIndex + 1) < _numParcels;
+
+			_notifyOnParcelChange(nextParcelIsValid ? getParcelAtIndex(_currentParcelIndex + 1) : null)
+			
+			_currentParcelIndex += 1;
+			_totalDepth = 0;
+			_hasContent = false;
+			
+			if (nextParcelIsValid)
+			{
+				_currentParcel = getParcelAtIndex(_currentParcelIndex);
+				var nextController:ContainerController = _currentParcel.controller;
+				if (nextController == _columnController)
+					_columnIndex++;
+				else
+				{
+					_columnIndex = 0;
+					_columnController = nextController;
+				}
+			}
+			else
+			{
+				_currentParcel = null;
+				_columnIndex = -1;
+				_columnController = null;
+			}
+	
+			return nextParcelIsValid;
+		}
+		
+		public function createParcel(parcel:Rectangle, blockProgression:String, verticalJump:Boolean):Boolean
+			// If we can get the requested parcel to fit, create it in the parcels list
+		{
+			return false;
+		}
+		
+		public function createParcelExperimental(parcel:Rectangle, wrapType:String):Boolean
+			// If we can get the requested parcel to fit, create it in the parcels list
+		{
+			return false;
+		}
+		
+		public function get currentParcel():Parcel
+		{ return _currentParcel; }
+
+		/**Return the width for a line that goes at the current vertical location,
+		 * and could extend down for at least height pixels. Note that this function
+		 * can change the current parcel, and the location within the parcel.
+		 * @param height	amount of contiguous vertical space that must be available
+		 * @param minWidth	amount of contiguous horizontal space that must be available 
+		 * @return amount of contiguous horizontal space actually available
+		 */
+		public function getLineSlug(slugRect:Rectangle, height:Number, minWidth:Number = 0):Boolean
+		{
+			// trace("getLineSlug",slugRect,height,minWidth);
+			if (_currentParcelIndex < _numParcels) 
+			{
+				var tileWidth:Number = getComposeWidth(_currentParcel);
+				if (tileWidth > minWidth)
+				{
+					// Fit the line if any part of the line fits in the height. Observe the cast to int!
+					if (currentParcel.composeToPosition || _totalDepth + (_currentParcel.fitAny ? 1 : int(height)) <= getComposeHeight(_currentParcel))
+					{
+						if (_blockProgression != BlockProgression.RL)
+						{
+							slugRect.x = left;
+							slugRect.y = _currentParcel.top + _totalDepth;
+							slugRect.width = tileWidth;
+							slugRect.height = height;
+						}
+						else
+						{
+							slugRect.x = left;
+							slugRect.y = _currentParcel.top;
+							slugRect.width = _currentParcel.width-_totalDepth;
+							slugRect.height = tileWidth;
+						}
+						return true;
+					}
+				}
+			} 
+			return false;
+		}
+	
+
+	}	//end class
+} //end package
diff --git a/textLayout_core/src/flashx/textLayout/compose/SimpleCompose.as b/textLayout_core/src/flashx/textLayout/compose/SimpleCompose.as
new file mode 100755
index 0000000..7368c05
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/compose/SimpleCompose.as
@@ -0,0 +1,372 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{
+	import flash.events.Event;
+	import flash.geom.Rectangle;
+	import flash.text.engine.TextBlock;
+	import flash.text.engine.TextLine;
+	import flash.text.engine.TextLineValidity;
+	
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.debug.Debugging;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.OverflowPolicy;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.SubParagraphGroupElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.compose.TextFlowLine;
+	import flashx.textLayout.compose.TextFlowLineLocation;
+	import flashx.textLayout.formats.BaselineOffset;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.formats.Direction;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextAlign;
+	import flashx.textLayout.formats.VerticalAlign;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+
+	[ExcludeClass]
+	/** Keeps track of internal state during composition. 
+	 * 
+	 * This is the simpler version, used when there are no floats, no wraps, no columns.
+	 * @private
+	 */
+	public class SimpleCompose extends BaseCompose
+	{
+		// reusable scratch TextFlowLine
+		protected var workingLine:TextFlowLine = new TextFlowLine(null, null);
+		
+		// resulting TextLines
+		public var _lines:Array;
+		
+		// scratch aligns for VJ
+		private var _vjLines:Array;
+		
+		// for figuring out when to do VJ
+		private var vjBeginLineIndex:int = 0;
+		private var vjDisableThisParcel:Boolean = false;
+		private var vjParcel:Parcel;
+		private var vjType:String;
+		
+		// accumulator for absolute start computation to support truncation 
+		private var _totalLength:Number;
+		
+		/** Constructor. */
+		public function  SimpleCompose()
+		{	
+			super();
+			_lines = new Array();
+			_vjLines = new Array();
+		}
+		
+		/** @private */
+		protected override function createParcelList():IParcelList
+		{
+			return ParcelList.getParcelList();
+		}
+		/** @private */
+		protected override function releaseParcelList(list:IParcelList):void
+		{
+			ParcelList.releaseParcelList(list);
+		}	
+
+		protected override function  initializeForComposer(composer:IFlowComposer, composeToPosition:int, controllerEndIndex:int):void
+		{
+			super.initializeForComposer(composer, composeToPosition, controllerEndIndex);
+			
+			// vj support
+			_vjLines.splice(0);
+			vjBeginLineIndex = 0;
+			vjParcel = parcelList.currentParcel;	
+			vjDisableThisParcel = false;
+			vjType = vjParcel ? vjParcel.controller.computedFormat.verticalAlign : VerticalAlign.TOP;
+			
+			_startController = composer.getControllerAt(0);
+            _startComposePosition = 0;
+		}
+
+		/** @private */
+		public override function composeTextFlow(textFlow:TextFlow, composeToPosition:int, controllerEndIndex:int):int
+		{
+			_flowComposer = textFlow.flowComposer as StandardFlowComposer;
+			
+			// empty out lines array
+			_lines.splice(0);
+			
+			// accumulator initialization
+			_totalLength = 0;
+			
+			return super.composeTextFlow(textFlow, composeToPosition, controllerEndIndex);
+		}
+		
+ 		override protected function doVerticalAlignment(canVerticalAlign:Boolean,nextParcel:Parcel):Boolean
+ 		{
+			var result:Boolean = false;
+
+			if (canVerticalAlign && vjType != VerticalAlign.TOP && vjBeginLineIndex != _lines.length &&  !vjDisableThisParcel && vjParcel.columnCoverage == Parcel.FULL_COLUMN)
+			{						
+				applyVerticalAlignmentToColumn(vjParcel.controller,vjType,_vjLines,0,_vjLines.length);
+				result = true;	// lines were moved
+			}
+
+			_vjLines.splice(0);
+			vjBeginLineIndex = _lines.length;
+			vjParcel = nextParcel;	// next parcel
+			vjDisableThisParcel = false;
+			if (nextParcel)
+				vjType = vjParcel.controller.computedFormat.verticalAlign;
+			return result;
+ 		}
+ 		
+		private function finalizeLine(curLine:TextFlowLine):void
+		{
+			var line:TextLine = curLine.createShape(_blockProgression);
+			
+			if (textFlow.backgroundManager)
+				textFlow.backgroundManager.finalizeLine(curLine);
+				
+			line.userData = _totalLength; 		// store absolute start position in the userData field
+			_totalLength += line.rawTextLength; // update length accumulator
+			_lines.push(line);
+			if (vjType != VerticalAlign.TOP)
+				_vjLines.push(new VJHelper(line,curLine.height));
+				
+			commitLastLineState (curLine);	
+		}
+
+		public function get textFlow():TextFlow
+		{
+			return _textFlow;
+		}
+		
+		/** @private */
+		protected override function composeParagraphElement(elem:ParagraphElement, absStart:int):Boolean
+		{
+			_curParaElement  = elem;
+			_curParaStart    = absStart;
+			_curParaFormat = elem.computedFormat;
+			CONFIG::debug { assert(_curParaStart == elem.getAbsoluteStart(),"composeParagraphElement: bad start"); }
+			_curElement 	 = elem.getFirstLeaf();
+			_curElementStart = _curParaStart;
+			return composeParagraphElementIntoLines();
+		}		
+		/** @private */
+		protected override function composeNextLine():TextFlowLine
+		{
+			// Check to see if there's an existing line that is composed up-to-date
+
+			var startCompose:int = _curElementStart + _curElementOffset - _curParaStart;
+			var prevLine:TextLine = startCompose != 0 ? workingLine.getTextLine() : null;
+			CONFIG::debug { assert(!prevLine || prevLine.validity == "valid","Bad prevline: "+Debugging.getIdentity(prevLine)); }
+			var finishLineSlug:Rectangle = _parcelList.currentParcel;
+			var curLine:TextFlowLine;
+			
+			for (;;) 
+			{
+				for (;;)
+				{	
+					// generate new line
+					CONFIG::debug { assert(!_parcelList.atEnd(), "failing to stop"); }
+					CONFIG::debug { assert(_curElement is FlowLeafElement, "element must be leaf before calling composeLine"); }
+					
+					curLine = createTextLine(prevLine,	startCompose, _parcelList.getComposeXCoord(finishLineSlug), _parcelList.getComposeYCoord(finishLineSlug),	_parcelList.getComposeWidth(finishLineSlug));
+					if (curLine != null)
+						break;
+					// force advance to the next parcel
+					if (!_parcelList.next())
+						return null;
+				}
+				
+				// updates _lineSlug
+				curLine = fitLineToParcel(curLine, true);
+				if (curLine)
+					break;
+				if (_parcelList.atEnd())
+					return null;
+				finishLineSlug = _lineSlug;
+			}
+			
+			finalizeLine(curLine);
+
+			CONFIG::debug { assert(curLine != null, "curLine != null"); }			
+			return curLine;
+		}
+
+		/** @private */
+		protected function createTextLine(prevLine:TextLine,	// previous line
+			lineStart:int, 		// text index of position to start from, relative to start of paragraph
+			x:Number,			// left edge of the line
+			y:Number, 			// top of the line
+			targetWidth:Number	// target width we're composing into
+			):TextFlowLine
+        {     		    		
+			// adjust target width for text indent, start and end indent 			
+ 			var lineOffset:Number = Number(_curParaFormat.paragraphStartIndent);  	// indent to "beginning" of the line.  Direction dependent (as is paragraphStartIndent)    		
+     		if (prevLine == null) 	// first line indent
+     			lineOffset += Number(_curParaFormat.textIndent);
+     		
+     		var outerTargetWidth:Number = targetWidth;
+     		targetWidth -= (Number(_curParaFormat.paragraphEndIndent) + lineOffset);		// make room for offset and end indent
+     		targetWidth = (targetWidth < 0) ? 0 : targetWidth;		// no negative targetwidth allowed
+     		if (targetWidth > TextLine.MAX_LINE_WIDTH)
+     			targetWidth = TextLine.MAX_LINE_WIDTH;
+	   		
+        	//var textLine:TextLine = _flowComposer.textLineCreator.createTextLine(_curParaElement.getTextBlock(), prevLine, targetWidth, lineOffset, true);
+        	var textLine:TextLine = TextLineRecycler.getLineForReuse();
+        	var textBlock:TextBlock = _curParaElement.getTextBlock();
+	   		if (textLine)
+	   		{
+	   			CONFIG::debug { assert(_textFlow.backgroundManager == null || _textFlow.backgroundManager.lineDict[textLine] === undefined,"Bad TextLine in recycler cache"); }
+	        	textLine = swfContext.callInContext(textBlock["recreateTextLine"], textBlock, [ textLine, prevLine, targetWidth, lineOffset, true ]);
+      		}
+	   		else
+	   		{
+	        	textLine = swfContext.callInContext(textBlock.createTextLine, textBlock, [prevLine, targetWidth, lineOffset, true ]);
+      		}
+        	// Unable to fit a new line
+        	if (textLine == null)
+        		return null;
+
+ 			CONFIG::debug { assert(_curParaStart == _curParaElement.getAbsoluteStart(),"bad _curParaStart"); }
+ 			workingLine.initialize(_curParaElement, outerTargetWidth, lineOffset, lineStart + _curParaStart, textLine.rawTextLength, textLine);
+ 			CONFIG::debug { assert(workingLine.targetWidth == targetWidth,"Bad targetWidth"); }
+ 			
+			// update spaceBefore & spaceAfter		
+			var linePos:uint = workingLine.location;
+			workingLine.setSpaceBefore((linePos & TextFlowLineLocation.FIRST) ? Number(_curParaFormat.paragraphSpaceBefore) : 0);
+			workingLine.setSpaceAfter((linePos & TextFlowLineLocation.LAST) ? Number(_curParaFormat.paragraphSpaceAfter) : 0); 
+
+ 			return workingLine;
+        }
+        
+        /** @private */
+        tlf_internal function swapLines(lines:Array):Array
+        {
+        	var current:Array = _lines;
+        	_lines = lines;
+        	return current;
+        }
+
+		/** Final adjustment on the content bounds. */
+ 		override protected function finalParcelAdjustment(controller:ContainerController):void
+ 		{
+ 			var minX:Number = TextLine.MAX_LINE_WIDTH;
+ 			var minY:Number = TextLine.MAX_LINE_WIDTH;
+ 			var maxX:Number = -TextLine.MAX_LINE_WIDTH;
+ 			var maxY:Number = -TextLine.MAX_LINE_WIDTH;
+ 			
+ 			var textLine:TextLine;
+ 			var verticalText:Boolean = _blockProgression == BlockProgression.RL;
+ 			var startPos:int = controller.absoluteStart;
+
+			for each (textLine in _lines)
+			{
+				var leaf:FlowLeafElement = controller.textFlow.findLeaf(startPos);
+				var para:ParagraphElement = leaf.getParagraph();
+
+            	// Check the logical vertical dimension first
+            	// If the lines have children, they may be inlines. The origin of the TextLine is the baseline, 
+            	// which does not include the ascent of the inlines or the text. So we have to factor that in.
+				// var verticalAdjust:Number = verticalText ? textLine.descent : textLine.ascent;
+				var inlineAscent:Number = 0;
+				if (textLine.numChildren > 0)		// adjustjust logical vertical coord to take into account inlines
+				{
+					var leafStart:int = leaf.getAbsoluteStart();
+					inlineAscent = TextFlowLine.getTextLineTypographicAscent(textLine, leaf, leafStart, startPos + textLine.rawTextLength, para);
+				}
+
+				// Figure out the logical horizontal adjustment
+				var edgeAdjust:Number = 0;
+				var curParaFormat:ITextLayoutFormat = para.computedFormat;
+				if (curParaFormat.direction == Direction.LTR)
+					edgeAdjust = curParaFormat.paragraphStartIndent + Math.max(curParaFormat.textIndent, 0);
+				else
+					edgeAdjust = curParaFormat.paragraphEndIndent;
+				
+				if (verticalText)
+				{
+		            minX = Math.min(textLine.x - textLine.descent, minX);
+		            maxX = Math.max(textLine.x + Math.max(inlineAscent,textLine.ascent), maxX);
+		           	minY = Math.min(textLine.y - edgeAdjust, minY);
+				}
+				else
+				{
+					if (inlineAscent < textLine.ascent)
+						inlineAscent = textLine.ascent;
+		            minX = Math.min(textLine.x - edgeAdjust, minX);
+		           	minY = Math.min(textLine.y - inlineAscent, minY);
+		  		}
+		  		startPos += textLine.rawTextLength;
+   			}
+            // Don't make adjustments for tiny fractional values.
+            if (minX != TextLine.MAX_LINE_WIDTH && Math.abs(minX-_parcelLeft) >= 1)
+         		_parcelLeft = minX;
+            if (maxX != -TextLine.MAX_LINE_WIDTH && Math.abs(maxX-_parcelRight) >= 1)
+         		_parcelRight = maxX;
+         	if (minY != TextLine.MAX_LINE_WIDTH && Math.abs(minY-_parcelTop) >= 1)
+           		_parcelTop = minY;
+         	if (maxY != -TextLine.MAX_LINE_WIDTH && Math.abs(maxY-_parcelBottom) >= 1)
+           		_parcelBottom = maxY;
+ 		}		
+		
+		tlf_internal override function releaseAnyReferences():void
+		{
+			super.releaseAnyReferences();
+			workingLine.initialize(null,0,0,0,0,null);
+			// parcelList.releaseAnyReferences();
+		}
+	}
+}
+import flash.text.engine.TextLine;
+import flashx.textLayout.compose.IVerticalJustificationLine;
+import flash.text.engine.TextLineCreationResult;
+
+class VJHelper implements IVerticalJustificationLine
+{
+	private var _line:TextLine;
+	private var _height:Number;
+
+	public function VJHelper(line:TextLine,h:Number)
+	{
+		_line = line;
+		_height = h;
+	}
+	public function get x():Number
+	{ return _line.x; }
+	public function set x(val:Number):void
+	{ _line.x = val; }
+		
+	public function get y():Number
+	{ return _line.y; }
+	public function set y(val:Number):void
+	{ _line.y = val; }
+		
+	public function get ascent():Number
+	{ return _line.ascent; }
+	public function get descent():Number
+	{ return _line.descent; }
+	public function get height():Number
+	{ return _height; }
+}
diff --git a/textLayout_core/src/flashx/textLayout/compose/StandardFlowComposer.as b/textLayout_core/src/flashx/textLayout/compose/StandardFlowComposer.as
new file mode 100755
index 0000000..4f68684
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/compose/StandardFlowComposer.as
@@ -0,0 +1,896 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{	
+	import flash.display.Sprite;
+	import flash.system.Capabilities;
+	import flash.text.engine.TextLine;
+	
+	import flashx.textLayout.accessibility.TextAccImpl;
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.container.ScrollPolicy;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.edit.ISelectionManager;
+	import flashx.textLayout.elements.BackgroundManager;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.events.CompositionCompleteEvent;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+	
+	[Exclude(name="createBackgroundManager",kind="method")]
+	
+	/** 
+	* The StandardFlowComposer class provides a standard composer and container manager. 
+	*
+	* <p>Each call to <code>compose()</code> or <code>updateAllControllers()</code> normalizes the text flow as a first step.  
+	* The normalizing process checks the parts of the TextFlow object that were modified and takes the following steps:
+	* <ol>
+	* <li> Deletes empty FlowLeafElement and SubParagraphGroupElement objects.</li>
+	* <li> Merges sibling spans that have identical attributes.</li>
+	* <li> Adds an empty paragraph if a flow is empty.</li>
+ 	* </ol>
+ 	* </p>
+	*
+	* <p>To use a StandardFlowComposer, assign it to the
+	* <code>flowComposer</code> property of a TextFlow object. Call the <code>updateAllControllers()</code>
+	* method to lay out and display the text in the containers attached to the flow composer.</p>
+	* 
+	* <p><b>Note:</b> For simple, static text flows, you can also use one of the text line factory classes.
+	* These factory classes will typically create lines with less overhead than a flow composer, but do not
+	* support editing, dynamic changes, or user interaction.</p>
+	* 
+	* @see flashx.textLayout.elements.TextFlow#flowComposer
+	* @includeExample examples\StandardFlowComposer_ClassExample.as -noswf
+	* @playerversion Flash 10
+	* @playerversion AIR 1.5
+	* @langversion 3.0
+	*/
+	
+	public class StandardFlowComposer extends FlowComposerBase implements IFlowComposer
+	{
+		/** @private */
+		tlf_internal var _rootElement:ContainerFormattedElement;
+		private var _controllerList:Array;
+		private var _composing:Boolean;
+
+		
+		/** 
+		* Creates a StandardFlowComposer object. 
+		*
+		* <p>To use an StandardFlowComposer object, assign it to the
+		* <code>flowComposer</code> property of a TextFlow object. Call the <code>updateAllControllers()</code>
+		* method to lay out and display the text in the containers attached to the flow composer.</p>
+		* 
+		* @includeExample examples\StandardFlowComposer_constructor.as -noswf
+		* 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*/
+	 	
+		public function StandardFlowComposer():void
+		{
+			super();
+			_controllerList = new Array();
+			_composing = false;
+		}
+
+		/** 
+		 * True, if the flow composer is currently performing a composition operation. 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get composing():Boolean
+		{ return _composing; }
+		
+		/** 
+		 * Returns the absolute position of the first content element in the specified ContainerController object.
+		 *
+		 * <p>A position is calculated by counting the division between two characters or other elements of a text flow. 
+		 * The position preceding the first element of a flow is zero. An absolute position is the position
+		 * counting from the beginning of the flow.</p>
+		 * 
+		 * @param controller A ContainerController object associated with this flow composer.
+		 * @return the position before the first character or graphic in the ContainerController.
+		 *
+		 * @includeExample examples\StandardFlowComposer_getAbsoluteStart.as -noswf
+		 *  
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		 
+		public function getAbsoluteStart(controller:ContainerController):int
+		{
+			// don't look at controller's relativeStart property - it uses this method.  hmmmm 
+			// TODO: that does seem odd - clean the above implementation up.
+			var stopIdx:int = getControllerIndex(controller);
+			CONFIG::debug { assert(stopIdx != -1,"bad controller to LayoutFlowComposer.getRelativeStart"); }
+			var rslt:int = _rootElement.getAbsoluteStart();
+			for (var idx:int = 0; idx < stopIdx; idx++)
+				rslt += _controllerList[idx].textLength;
+				
+			return rslt;
+		}
+		
+		/** @copy IFlowComposer#rootElement
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		
+		public function get rootElement():ContainerFormattedElement
+		{ return _rootElement; }
+		
+		
+		/** @copy IFlowComposer#setRootElement()
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		public function setRootElement(newRootElement:ContainerFormattedElement):void
+		{
+
+			if (_rootElement != newRootElement)
+			{
+				if (newRootElement is TextFlow && TextFlow(newRootElement).flowComposer != this)
+					TextFlow(newRootElement).flowComposer = this;
+				else
+				{
+					clearCompositionResults();
+
+					detachAllContainers();
+					_rootElement = newRootElement;
+					_textFlow = _rootElement ? _rootElement.getTextFlow() :  null;
+					attachAllContainers();
+				}
+			}
+		}
+		
+		/** @private */
+		tlf_internal function detachAllContainers():void
+		{
+			
+			// detatch accessibility from the containers
+			// Why only the first container?
+			if (_controllerList.length > 0 && _textFlow)
+			{
+				var firstContainerController:ContainerController = getControllerAt(0);
+				var firstContainer:Sprite = firstContainerController.container;
+				if (firstContainer)
+					clearContainerAccessibilityImplementation(firstContainer);
+		  	}
+		  	
+		  	var cont:ContainerController;
+			for each (cont in _controllerList)
+			{
+				cont.clearSelectionShapes();
+				cont.setRootElement(null);
+			}
+		}
+		
+		static private function clearContainerAccessibilityImplementation(cont:Sprite):void
+		{
+			if (cont.accessibilityImplementation)
+			{
+				if (cont.accessibilityImplementation is TextAccImpl)
+					TextAccImpl(cont.accessibilityImplementation).detachListeners();
+				cont.accessibilityImplementation = null;
+			}
+		}
+		
+		/** @private */
+		tlf_internal function attachAllContainers():void
+		{
+			var cont:ContainerController;
+			for each (cont in _controllerList)
+				ContainerController(cont).setRootElement(_rootElement);
+			
+
+			if (_controllerList.length > 0 && _textFlow)
+			{
+				// attach accessibility to the containers
+				// Why only the first container?  There are workflows that this will fail
+				// for example: a pagination workflow that has a composed chain of containers but only displays one at a time.
+				if (textFlow.configuration.enableAccessibility && flash.system.Capabilities.hasAccessibility)
+				{
+					var firstContainer:Sprite = getControllerAt(0).container;
+					if (firstContainer)
+					{
+						clearContainerAccessibilityImplementation(firstContainer);
+						firstContainer.accessibilityImplementation = new TextAccImpl(firstContainer, _textFlow);
+					}
+				}
+				
+				var curContainer:Sprite;
+				// turn off focusRect on all containers
+				for (var i:int = 0; i < _controllerList.length; ++i)
+				{
+					curContainer = getControllerAt(i).container;
+					if (curContainer)
+						curContainer.focusRect = false;
+				} 
+		  	}
+
+			// TODO: can be more efficient? - just damage all
+			clearCompositionResults();				
+		}
+		
+		/** @copy IFlowComposer#numControllers
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+		*/
+		
+		public function get numControllers():int
+		{ return _controllerList ? _controllerList.length : 0; }
+		
+		/** @copy IFlowComposer#addController()
+		 *
+		 * @includeExample examples\StandardFlowComposer_addController.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function addController(controller:ContainerController):void
+		{
+			CONFIG::debug { assert (_controllerList.indexOf(controller) < 0, "adding controller twice"); }
+			_controllerList.push(ContainerController(controller));
+			if (this.numControllers == 1)
+			{				
+				attachAllContainers();
+			}
+			else
+			{
+				controller.setRootElement(_rootElement)
+				var curContainer:Sprite = controller.container;
+				if (curContainer)
+					curContainer.focusRect = false;
+				if (textFlow)
+				{
+					// mark the previous container as geometry damaged - this is more than is needed
+					controller = this.getControllerAt(this.numControllers-2);
+					var damageStart:int = controller.absoluteStart;
+					var damageLen:int = controller.textLength;
+					// watch out for an empty previous container
+					if (damageLen == 0)
+					{
+						if (damageStart != textFlow.textLength)
+							damageLen++;
+						else if (damageStart != 0)
+						{
+							damageStart--;
+							damageLen++;
+						}
+					}
+					if (damageLen)
+						textFlow.damage(damageStart,damageLen,FlowDamageType.GEOMETRY,false);
+				}
+			}
+		}
+		/** @copy IFlowComposer#addControllerAt()
+		 *
+		 * @includeExample examples\StandardFlowComposer_addControllerAt.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function addControllerAt(controller:ContainerController, index:int):void
+		{
+			CONFIG::debug { assert (_controllerList.indexOf(controller) == -1, "adding controller twice"); }
+			detachAllContainers();
+			_controllerList.splice(index,0,ContainerController(controller));
+			attachAllContainers();
+		}
+		
+		/** Removes a trailing controller with no content without doing any damage */
+		private function fastRemoveController(index:int):Boolean
+		{
+			if (index == -1)
+				return true;
+			var cont:ContainerController = _controllerList[index];
+			if (!cont)
+				return true;
+			if (!_textFlow || cont.absoluteStart == _textFlow.textLength)
+			{
+				if (index == 0)
+				{
+					var firstContainer:Sprite = cont.container;
+					if (firstContainer)
+						clearContainerAccessibilityImplementation(firstContainer);				
+				}
+				cont.setRootElement(null);
+				_controllerList.splice(index,1);
+				return true;
+			} 	
+			return false;
+		}
+		
+		/** @copy IFlowComposer#removeController()
+		 *
+		 * @includeExample examples\StandardFlowController_removeController.as -noswf
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function removeController(controller:ContainerController):void
+		{ 
+			var index:int = getControllerIndex(controller);
+			if (!fastRemoveController(index))
+			{
+				detachAllContainers();
+				_controllerList.splice(index,1);
+				attachAllContainers();
+			}
+		}
+		/** @copy IFlowComposer#removeControllerAt()
+		 *
+		 * @includeExample examples\StandardFlowController_removeControllerAt.as -noswf
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		 
+		public function removeControllerAt(index:int):void
+		{ 
+			if (!fastRemoveController(index))
+			{
+				detachAllContainers();
+				_controllerList.splice(index,1);
+				attachAllContainers();
+			}
+		}
+		/** @copy IFlowComposer#removeAllControllers()
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function removeAllControllers():void
+		{
+			detachAllContainers();
+			_controllerList.splice(0,_controllerList.length);
+		}
+		
+		/** @copy IFlowComposer#getControllerAt()  
+		 * 
+		 * @includeExample examples\StandardFlowComposer_getControllerAt.as -noswf
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		
+		public function getControllerAt(index:int):ContainerController
+		{
+			return _controllerList[index];
+		}
+		
+		/** @copy IFlowComposer#getControllerIndex()  
+		 *
+		 * @includeExample examples\StandardFlowComposer_getControllerIndex.as -noswf
+		 * @playerversion Flash 10
+		 * @player version AIR 1.5
+	 	 * @langversion 3.0
+	 	 * @playerversion AIR 1.5
+	 	 */
+	 	 
+		public function getControllerIndex(controller:ContainerController):int
+		{
+			// TODO: binary search? 
+			for (var idx:int = 0; idx < _controllerList.length; idx++)
+			{
+				if (_controllerList[idx] == controller)
+					return idx;
+			}
+			return -1; 
+		}
+		
+		/** 
+		 * Returns the index of the controller containing the content at the specified position. 
+		 * 
+		 * <p>A position can be considered to be the division between two characters or other elements of a text flow. If 
+		 * the value in <code>absolutePosition</code> is a position between the last character of one 
+		 * container and the first character of the next, then the preceding container is returned if
+		 * the <code>preferPrevious</code> parameter is set to <code>true</code> and the later container is returned if
+		 * the <code>preferPrevious</code> parameter is set to <code>false</code>.</p>
+		 *
+		 * <p>The method returns -1 if the content at the specified position is not in any container or is outside
+		 * the range of positions in the text flow.</p>
+		 * 
+		 * @param absolutePosition The position of the content for which the container index is sought.
+		 * @param preferPrevious Specifies which container index to return when the position is between the last element in 
+		 * one container and the first element in the next.
+		 * 
+		 * @return 	the index of the container controller or -1 if not found.
+		 *
+		 * @includeExample examples\StandardFlowComposer_findControllerIndexAtPosition.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		
+		public function findControllerIndexAtPosition(absolutePosition:int,preferPrevious:Boolean=false):int
+		{
+			
+			var lo:int = 0;
+			var hi:int = _controllerList.length-1;
+			while (lo <= hi)
+			{
+				var mid:int = (lo+hi)/2;
+				var cont:ContainerController = _controllerList[mid];
+				if (cont.absoluteStart <= absolutePosition)
+				{
+					if (preferPrevious)
+					{
+						if (cont.absoluteStart + cont.textLength >= absolutePosition)
+						{
+							// find first container or first one with non-zero textLength
+							while (mid != 0 && cont.absoluteStart == absolutePosition)
+							{
+								mid--;
+								cont = _controllerList[mid];
+							}
+							return mid;
+						}
+					}
+					else
+					{
+
+						if (cont.absoluteStart == absolutePosition && cont.textLength != 0)
+						{
+							while (mid != 0)
+							{
+								cont = _controllerList[mid-1];
+								if (cont.textLength != 0)
+									break;
+								mid--;
+							}
+							return mid;
+						}
+						if (cont.absoluteStart + cont.textLength > absolutePosition)
+							return mid;
+					}
+					lo = mid+1;
+				}
+				else
+					hi = mid-1;
+			}
+			return -1;
+		}
+
+		/** Clear whatever computed values are left from the last composition, in the flow composer and
+		 * in each of its controllers. @private
+		 */
+		 
+		tlf_internal function clearCompositionResults():void
+		{
+			initializeLines();
+			for each (var cont:ContainerController in _controllerList)
+				cont.clearCompositionResults();
+		}
+
+		/** 
+		 * Composes the content of the root element and updates the display.  
+		 *
+		 * <p>Text layout is conducted in two phases: composition and display. In the composition phase,
+		 * the flow composer calculates how many lines are necessary to display the content as well as the position of these 
+		 * lines in the flow's display containers. In the display phase, 
+		 * the flow composer updates the display object children of its containers. The <code>updateAllControllers()</code>
+		 * method initiates both phases in sequence. The StandardFlowComposer keeps track of changes to content
+		 * so that a full cycle of composition and display is only performed when necessary.</p>
+		 * 
+		 * <p>This method updates all the text lines and the display list immediately and synchronously.</p>
+		 *
+		 * <p>If the contents of any container is changed, the method returns <code>true</code>.</p>
+		 * 
+		 * @return true if anything changed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 * 
+		 */
+		 
+		public function updateAllControllers():Boolean
+		{
+			return updateToController();
+		}
+		
+		/** 
+		 * Composes and updates the display up to and including the container at the specified index.
+		 * 
+		 * <p>The <code>updateToController()</code> method composes the content and 
+		 * updates the display of all containers up to and including the container at the specified index.
+		 * For example, if you have a chain of 20 containers and specify an index of 10, 
+		 * <code>updateToController()</code> ensures that the first through the tenth (indexes 0-9) 
+		 * containers are composed and displayed. Composition stops at that point. If <code>controllerIndex</code> 
+		 * is -1 (or not specified), then all containers are updated.</p>
+		 *
+		 * <p>This method updates all the text lines and the display list immediately and synchronously.</p>
+		 * 
+		 * <p>If the contents of any container is changed, the method returns <code>true</code>.</p>
+		 * 
+		 * @param controllerIndex index of the last container to update (by default updates all containers)
+		 * @return <code>true</code>, if anything changed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+		 */
+		 
+		public function updateToController(index:int = int.MAX_VALUE):Boolean
+		{
+			//CONFIG::debug { assert(!_composing,"updateToController: compose in process"); }
+			if (_composing)
+				return false;
+				
+			//note that this will always update the display AND update the
+			//selection.  So, even if nothing has changed that would cause
+			//a recompose, the selection would still be redrawn.
+			var sm:ISelectionManager = textFlow.interactionManager;
+			if (sm)
+				sm.flushPendingOperations();
+			var startController:ContainerController = _composing ? null : internalCompose(-1, index);	
+			var shapesDamaged:Boolean = areShapesDamaged();
+			if (shapesDamaged)
+				updateCompositionShapes();
+
+			if (sm)
+				sm.refreshSelection();
+			releaseLines(startController);
+			return shapesDamaged;
+		}
+		
+		/** 
+		 * Sets the focus to the container that contains the location specified by the <code>absolutePosition</code>
+		 * parameter. 
+		 *
+		 * <p>The StandardFlowComposer calls the <code>setFocus()</code> method of the ContainerController object
+		 * containing the specified text flow position.</p>
+		 * 
+		 * @param absolutePosition Specifies the position in the text flow of the container to receive focus.
+		 * @param preferPrevious If true and the position is before the first character in a container, sets focus to the end of 
+		 *  the previous container.
+		 * 
+		 * @see flash.display.Stage#focus
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public function setFocus(absolutePosition:int,leanLeft:Boolean=false):void
+		{
+			var idx:int = findControllerIndexAtPosition(absolutePosition,leanLeft);
+			if (idx == -1)
+				idx = this.numControllers-1;
+			if (idx != -1)
+				_controllerList[idx].setFocus();
+		}
+		
+		/**
+		 * Called by the TextFlow when the interaction manager changes. 
+		 * 
+		 * <p>This function is called automatically. Your code does not typically need to call this
+		 * method. Classes that extend StandardFlowComposer can override this method to update
+		 * event listeners and other properties that depend on the interaction manager.</p>
+		 * 
+		 * @param newInteractionManager The new ISelectionManager instance.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public	function interactionManagerChanged(newInteractionManager:ISelectionManager):void
+		{
+			for each (var controller:ContainerController in _controllerList)
+				controller.interactionManagerChanged(newInteractionManager);
+		}
+
+		
+		private function updateCompositionShapes():void
+		{
+			for each (var controller:ContainerController in _controllerList)
+				controller.updateCompositionShapes(); 
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Composition
+		//
+		//--------------------------------------------------------------------------
+		
+		/** @private Override required because we may be damaged if the last container has scrolling */
+		public override function isDamaged(absolutePosition:int):Boolean
+		{
+			// Returns true if any text from _damageAbsoluteStart through absolutePosition needs to be recomposed
+			if (!super.isDamaged(absolutePosition))
+			{	
+				if (absolutePosition == _textFlow.textLength)
+				{
+					var container:ContainerController = getControllerAt(numControllers-1);
+					if (container && (container.verticalScrollPolicy != ScrollPolicy.OFF || container.horizontalScrollPolicy != ScrollPolicy.OFF))
+						return true;
+				}
+				return false;
+			}
+				
+			return true;
+		}
+
+		/** Returns true if composition is necessary, false otherwise */
+		protected function preCompose():Boolean
+		{
+			CONFIG::debug { checkFirstDamaged(); }
+			rootElement.preCompose();
+			
+			// No content, nothing to compose - TextFlow isn't loaded  or connected
+			CONFIG::debug { assert(rootElement.textLength != 0,"bad TextFlow after normalize"); }
+			
+			// brand new content
+			if (numLines == 0)
+				initializeLines();
+				
+			return isDamaged(rootElement.getAbsoluteStart() + rootElement.textLength);
+		}
+		
+		/** @private */
+		tlf_internal function getComposeState():ComposeState
+		{ return ComposeState.getComposeState(); }
+		
+		/** @private */
+		tlf_internal function releaseComposeState(state:ComposeState):void
+		{ ComposeState.releaseComposeState(state); }
+		
+		/** @private Return the first damaged controller */
+		tlf_internal function callTheComposer(composeToPosition:int, controllerEndIndex:int):ContainerController
+		{
+			
+			if (_damageAbsoluteStart == rootElement.getAbsoluteStart()+rootElement.textLength)
+				return getControllerAt(numControllers-1);;
+				
+			var state:ComposeState = getComposeState();
+			
+			var lastComposedPosition:int = state.composeTextFlow(textFlow, composeToPosition, controllerEndIndex);
+			if (_damageAbsoluteStart < lastComposedPosition)
+				_damageAbsoluteStart = lastComposedPosition;
+			CONFIG::debug { checkFirstDamaged(); }
+			
+			// make sure there is an empty TextFlowLine covering any trailing content
+			finalizeLinesAfterCompose();
+			var startController:ContainerController = state.startController;
+			
+			releaseComposeState(state);
+							
+			textFlow.dispatchEvent(new CompositionCompleteEvent(CompositionCompleteEvent.COMPOSITION_COMPLETE,false,false,textFlow, 0,lastComposedPosition));
+
+			CONFIG::debug { textFlow.debugCheckTextFlow(); }
+			return startController;
+		}
+		
+		private var lastBPDirectionScrollPosition:Number = Number.NEGATIVE_INFINITY;
+		
+		static private function getBPDirectionScrollPosition(bp:String,cont:ContainerController):Number
+		{
+			return bp == BlockProgression.TB ? cont.verticalScrollPosition : cont.horizontalScrollPosition;
+		}
+		
+		/** Bottleneck function for all types of compose. Does the work of compose, no matter how it is called. @private 
+		 * @return first controller with changed shapes
+		 */
+		private function internalCompose(composeToPosition:int = -1, composeToControllerIndex:int = -1):ContainerController
+		{
+			var sm:ISelectionManager = textFlow.interactionManager;
+			if (sm)
+				sm.flushPendingOperations();
+			
+			if (numControllers == 0)
+				return null;
+
+			if (composeToControllerIndex < 0)
+			{
+				if (composeToPosition >= 0 && damageAbsoluteStart >= composeToPosition)
+					return null;
+			}
+			else
+			{
+				var controller:ContainerController = getControllerAt(Math.min(composeToControllerIndex,numControllers-1));
+				if (damageAbsoluteStart > controller.absoluteStart+controller.textLength)
+					return null;
+			}
+				
+			// trace("internalCompose: damageAbsoluteStart",damageAbsoluteStart);
+			
+			var lastController:ContainerController;
+			var bp:String;
+			if (composeToControllerIndex == numControllers-1)
+			{
+				lastController = this.getControllerAt(numControllers-1);
+				// skip it if damageAbsoluteStart is past the end of the controller.  are there risks here? AND scrollpositions haven't changed since last composeToControllerIndex
+				var a:Array = lastController.findFirstAndLastVisibleLine();
+				var lastVisibleLine:TextFlowLine = a[1];
+				if (lastVisibleLine)
+				{
+					bp = rootElement.computedFormat.blockProgression
+					if (getBPDirectionScrollPosition(bp,lastController) == this.lastBPDirectionScrollPosition && damageAbsoluteStart >= lastVisibleLine.absoluteStart+lastVisibleLine.textLength)
+						return null;
+				}
+			}
+			lastBPDirectionScrollPosition = Number.NEGATIVE_INFINITY;
+			
+			CONFIG::debug { assert(_composing == false,"internalCompose: Recursive call"); }
+				
+			_composing = true;
+			
+			var startController:ContainerController;
+			
+			try
+			{	
+				var cont:ContainerController;	// scratch
+				if (textFlow && numControllers != 0)
+				{
+					if (preCompose())
+					{
+						startController = callTheComposer(composeToPosition, composeToControllerIndex);
+						if (startController)
+						{
+							var idx:int = this.getControllerIndex(startController);
+							while (idx < numControllers)
+								getControllerAt(idx++).shapesInvalid = true;
+						}
+					}
+				}
+			}
+			catch (e:Error)
+			{
+				_composing = false;
+				throw(e);
+			}
+			_composing = false;
+			
+			if (lastController)
+			{
+				lastBPDirectionScrollPosition = getBPDirectionScrollPosition(bp,lastController);
+			}
+			
+			return startController;
+		}
+		
+		
+		/** @private */
+		tlf_internal function areShapesDamaged():Boolean
+		{
+			var cont:ContainerController;	// scratch
+			// TODO: a flag on this?
+			for each (cont in _controllerList)
+			{
+				if (cont.shapesInvalid)
+					return true;
+			}
+			return false;
+		}
+		
+		/** 
+		 * Calculates how many lines are necessary to display the content in the root element of the flow and the positions of these 
+		 * lines in the flow's display containers.
+		 * 
+		 * <p>The <code>compose()</code> method only composes content if it has changed since the last composition operation. 
+		 * Results are saved so that subsequent
+		 * calls to <code>compose()</code> or <code>updateAllControllers()</code> do not perform an additional recomposition
+		 * if the flow content has not changed.</p>
+		 * 
+		 * <p>If the contents of any container have changed, the method returns <code>true</code>.</p>
+		 * 
+		 * @return true if anything changed.
+		 *
+		 * @includeExample examples\StandardFlowComposer_compose.as -noswf
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see #updateAllControllers()
+	 	 * @see #updateToController()
+		 */
+		public function compose():Boolean
+		{
+			//CONFIG::debug { assert(!_composing,"compose: compose in process"); }
+			return _composing ? false : internalCompose() != null;
+		}
+		
+		/** @copy IFlowComposer#composeToPosition()
+		 *
+		 * @includeExample examples\StandardFlowComposer_composeToPosition.as -noswf
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		public function composeToPosition(absolutePosition:int = int.MAX_VALUE):Boolean
+		{
+			//CONFIG::debug { assert(!_composing,"composeToPosition: compose in process"); }
+			return _composing ? false : internalCompose(absolutePosition, -1) != null;
+		}
+		
+		/** @copy IFlowComposer#composeToController()
+		 *
+		 * @includeExample examples\StandardFlowComposer_composeToController.as -noswf
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		public function composeToController(index:int = int.MAX_VALUE):Boolean
+		{
+			//CONFIG::debug { assert(!_composing,"composeToController: compose in process"); }
+			return _composing ? false : internalCompose(-1, index) != null;
+		}
+		
+		/** Release lines in paragraphs that aren't referenced externally, so that they can be garbage collected
+		 * if necessary. Iterates through the lines, looking for lines that do not have a valid parent. If all the
+		 * lines in a paragraph have no parent, we call the paragraph's TextBlock.releaseLines(). 
+		 */
+		private function releaseLines(startController:ContainerController):void
+		{
+			var currentParagraph:ParagraphElement = null;
+			var inUse:Boolean = false;
+			var lastLine:int = lines.length;
+			for (var lineIndex:int = startController ? findLineIndexAtPosition(startController.absoluteStart) : 0; lineIndex < lastLine; lineIndex++)
+			{
+				var line:TextFlowLine = lines[lineIndex];
+				var paragraph:ParagraphElement = line.paragraph;
+				if (paragraph != currentParagraph)		
+				{
+					// We're on a new paragraph. Release the lines from the old para, if they weren't used,
+					// and set up the new para.
+					if (!inUse && currentParagraph)
+						currentParagraph.releaseTextBlock();
+					currentParagraph = paragraph;
+					inUse = false;
+				}
+				if (!inUse && !line.isDamaged())
+				{
+					var textLine:TextLine = line.getTextLine();
+					if (textLine != null && textLine.parent != null)
+						inUse = true;
+				}
+			}
+			// Release the lines from the last para, if they weren't used.
+			if (!inUse && currentParagraph && currentParagraph.hasBlockElement())
+				currentParagraph.releaseTextBlock();
+		}
+		
+		/** @private */
+		public function createBackgroundManager():BackgroundManager
+		{ return new BackgroundManager(); }
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/compose/TextFlowLine.as b/textLayout_core/src/flashx/textLayout/compose/TextFlowLine.as
new file mode 100755
index 0000000..a3c41aa
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/compose/TextFlowLine.as
@@ -0,0 +1,2169 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{
+	import flash.display.DisplayObject;
+	import flash.display.GraphicsPathCommand;
+	import flash.display.GraphicsPathWinding;
+	import flash.display.Shape;
+	import flash.geom.Point;
+	import flash.geom.Rectangle;
+	import flash.text.engine.TextBlock;
+	import flash.text.engine.TextLine;
+	import flash.text.engine.TextLineValidity;
+	import flash.text.engine.TextRotation;
+	import flash.utils.Dictionary;
+	
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.debug.Debugging;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.edit.ISelectionManager;
+	import flashx.textLayout.edit.SelectionFormat;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.FlowValueHolder;
+	import flashx.textLayout.elements.InlineGraphicElement;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.SpanElement;
+	import flashx.textLayout.elements.SubParagraphGroupElement;
+	import flashx.textLayout.elements.TCYElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.external.WeakRef;
+	import flashx.textLayout.formats.BackgroundColor;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.formats.Direction;
+	import flashx.textLayout.formats.Float;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.JustificationRule;
+	import flashx.textLayout.formats.LeadingModel;
+	import flashx.textLayout.formats.LineBreak;
+	import flashx.textLayout.formats.TextDecoration;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.tlf_internal;
+	import flashx.textLayout.utils.CharacterUtil;
+	
+	use namespace tlf_internal;
+	
+	
+	/** 
+	 * The TextFlowLine class represents a single line of text in a text flow.
+	 * 
+	 * <p>Use this class to access information about how a line of text has been composed: its position, 
+	 * height, width, and so on. When the text flow (TextFlow) is modified, the lines immediately before and at the  
+	 * site of the modification are marked as invalid because they need to be recomposed. Lines after
+	 * the site of the modification might not be damaged immediately, but they might be regenerated once the
+	 * text is composed. You can access a TextFlowLine that has been damaged, but any values you access
+	 * reflect the old state of the TextFlow. When the TextFlow is recomposed, it generates new lines and you can 
+	 * get the new line for a given position by calling <code>TextFlow.flowComposer.findLineAtPosition()</code>.</p>
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	 
+	public final class TextFlowLine implements IVerticalJustificationLine 
+	{
+
+		 
+		
+		/** @private */
+				
+		private var _absoluteStart:int;		// text-offset of start of line - from beginning of the TextFlow
+		private var _textLength:int;	// number of chars to next line (incl trailing spaces, etc.)
+		private var _height:Number = 0;		// y advance
+		private var _spaceBefore:Number = 0;	// amount of vertical space to leave at the top of the line
+		private var _spaceAfter:Number = 0;	// amount of vertical space to leave at the bottom of the line
+		private var _x:Number = 0;			// left edge of line
+		private var _y:Number = 0;			// top edge of line
+		private var _outerTargetWidth:Number = 0; // width line is composed to, excluding indents
+		private var _para:ParagraphElement;			// owning paragraph
+		private var _controller:ContainerController;	// what frame the line was composed into
+		private var _columnIndex:int;			// column number in the container
+		
+		private var _adornCount:int = 0;
+		
+		// added to support TextFlowLine when TextLine not available
+		private var _ascent:Number;
+		private var _descent:Number;
+		private var _targetWidth:Number;
+		private var _validity:String;
+		private var _unjustifiedTextWidth:Number;
+		private var _textWidth:Number;
+		private var _textHeight:Number;
+		private var _lineOffset:Number;
+		private var _released:Boolean;	// True if line has been released from the TextBlock
+		
+		private var _textLineCache:WeakRef;
+		
+		 /**
+		 * The height of the text line, which is equal to <code>ascent</code> plus <code>descent</code>. The 
+		 * value is calculated based on the difference between the baselines that bound the line, either 
+		 * ideographic top and bottom or ascent and descent depending on whether the baseline at y=0 
+		 * is ideographic (for example, TextBaseline.IDEOGRAPHIC_TOP) or not. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @see flash.text.engine.TextBaseline TextBaseline
+	 	 */
+		
+		public function get textHeight():Number 
+		{ return _textHeight; }
+		
+		/** @private - the selection block cache */
+		static private var _selectionBlockCache:Dictionary = new Dictionary(true);
+		
+		private static const EMPTY_LINE_WIDTH:Number = 2;		// default size of empty line selection
+
+		/** Constructor - creates a new TextFlowLine instance. 
+		 *  <p><strong>Note</strong>: No client should call this. It's exposed for writing your own composer.</p>
+		 *
+		 * @param textLine The TextLine display object to use for this line.
+		 * @param paragraph The paragraph (ParagraphElement) in which to place the line.
+		 * @param outerTargetWidth The width the line is composed to, excluding indents.
+		 * @param lineOffset The line's offset in pixels from the appropriate container inset (as dictated by paragraph direction and container block progression), prior to alignment of lines in the paragraph. 
+		 * @param absoluteStart	The character position in the text flow at which the line begins.
+		 * @param numChars	The number of characters in the line.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see flash.text.engine.TextLine
+	 	 * @see flashx.textLayout.elements.ParagraphElement
+	 	 * @see #absoluteStart
+	 	 */
+	 	 
+		public function TextFlowLine(textLine:TextLine, paragraph:ParagraphElement, outerTargetWidth:Number = 0, lineOffset:Number = 0, absoluteStart:int = 0, numChars:int = 0)
+		{
+			initialize(paragraph, outerTargetWidth, lineOffset, absoluteStart,numChars,textLine);		
+		}
+		
+		/** @private */
+		tlf_internal function initialize(paragraph:ParagraphElement, outerTargetWidth:Number = 0, lineOffset:Number = 0, absoluteStart:int = 0, numChars:int = 0, textLine:TextLine = null):void
+		{
+			_para = paragraph;
+			_outerTargetWidth = outerTargetWidth;
+			_absoluteStart = absoluteStart;
+			_textLength = numChars;
+			_released = (textLine == null);
+			if (textLine)
+			{
+				_textLineCache = new WeakRef(textLine);
+				textLine.userData = this;
+				_targetWidth = textLine.specifiedWidth;
+				_ascent = textLine.ascent;
+				_descent = textLine.descent;
+				_unjustifiedTextWidth = textLine.unjustifiedTextWidth;
+				_textWidth = textLine.textWidth;
+				_textHeight = textLine.textHeight;
+				_lineOffset = lineOffset;
+				_validity = TextLineValidity.VALID;
+			}
+			else 
+				_validity = TextLineValidity.INVALID;
+		}
+		
+		/** @private */
+		tlf_internal function releaseTextLine():void
+		{ _textLineCache = null; }
+
+		/** @private */
+		tlf_internal function peekTextLine():TextLine
+		{ return _textLineCache ? _textLineCache.get() : null; }
+				
+		/** 
+		 * The horizontal position of the line relative to its container, expressed as the offset in pixels from the 
+		 * left of the container.
+		 * <p><strong>Note: </strong>Although this property is technically <code>read-write</code>, 
+		 * you should treat it as <code>read-only</code>. The setter exists only to satisfy the
+		 * requirements of the IVerticalJustificationLine interface that defines both a getter and setter for this property.
+		 * Use of the setter, though possible, will lead to unpredictable results.
+		 * </p>
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see #y
+		 */
+		public function get x():Number
+		{ return _x; }
+		
+		/** 
+		 * This comment is ignored, but the setter should not be used and exists only to satisfy
+		 * the IVerticalJustificationLine interface.
+		 * @see flashx.textLayout.compose.IVerticalJustificationLine 
+		 * @private 
+		 */
+		public function set x(lineX:Number):void
+		{ _x = lineX; }
+		
+		/** 
+		 * The vertical position of the line relative to its container, expressed as the offset in pixels from the top 
+		 * of the container.
+		 * <p><strong>Note: </strong>Although this property is technically <code>read-write</code>, 
+		 * you should treat it as <code>read-only</code>. The setter exists only to satisfy the
+		 * requirements of the IVerticalJustificationLine interface that defines both a getter and setter for this property.
+		 * Use of the setter, though possible, will lead to unpredictable results.
+		 * </p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 * 
+	 	 * @see #x
+		 */
+		public function get y():Number
+		{ return _y; }
+		
+		/** This comment is ignored, but the setter should not be used and exists only to satisfy
+		 * the IVerticalJustificationLine interface.
+		 * @see flashx.textLayout.compose.IVerticalJustificationLine
+		 * @private
+		 */
+		public function set y(lineY:Number):void
+		{ _y = lineY; }
+		
+		/** @private */
+		tlf_internal function setXYAndHeight(lineX:Number,lineY:Number,lineHeight:Number):void
+		{
+			_x = lineX;
+			_y = lineY;
+			_height = lineHeight
+		}
+		
+		/** 
+		 * One of the values from TextFlowLineLocation for specifying a line's location within a paragraph.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see flashx.textLayout.elements.ParagraphElement
+	 	 * @see TextFlowLineLocation
+		 */
+		 
+		public function get location():int
+		{
+			if (_para)
+			{
+				var lineStart:int = _absoluteStart - _para.getAbsoluteStart();
+				
+				// Initialize settings for location
+				if (lineStart == 0)		// we're at the start of the paragraph
+					return _textLength == _para.textLength ? TextFlowLineLocation.ONLY : TextFlowLineLocation.FIRST;
+				if (lineStart + _textLength == _para.textLength)	// we're at the end of the para
+					return TextFlowLineLocation.LAST;
+			}
+			return TextFlowLineLocation.MIDDLE;
+		}
+		
+		/** 
+		 * The controller (ContainerController object) for the container in which the line has been placed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 * 
+	 	 * @see flashx.textLayout.container.ContainerController 
+		 */
+		 
+		public function get controller():ContainerController
+		{ return _controller; }
+		
+		/** The number of the column in which the line has been placed, with the first column being 0.
+		 *		
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public function get columnIndex():int
+		{ return _columnIndex; }
+		
+		/** @private */
+		tlf_internal function setController(cont:ContainerController,colNumber:int):void
+		{ 
+			_controller = cont as ContainerController;
+			_columnIndex = colNumber;
+		}
+		
+		/** The height of the line in pixels.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+		 */
+		 
+		public function get height():Number
+		{ return _height; }
+		
+		/** 
+		 * @copy flash.text.engine.TextLine#ascent
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function get ascent():Number
+		{ return _ascent; }
+		
+		/** 
+		 * @copy flash.text.engine.TextLine#descent
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function get descent():Number
+		{ return _descent; }
+		
+		/** 
+		 * The line's offset in pixels from the appropriate container inset (as dictated by paragraph direction and container block progression), 
+		 * prior to alignment of lines in the paragraph.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get lineOffset():Number
+		{
+			return _lineOffset;
+		}
+		
+				
+		/** 
+		 * The paragraph (ParagraphElement) in which the line resides.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 * 
+	 	 * @see flashx.textLayout.elements.ParagraphElement
+	 	 */
+	 	 
+		public function get paragraph():ParagraphElement
+		{ return _para; }
+		
+		/** 
+		 * The location of the line as an absolute character position in the TextFlow object.
+		 * 
+		 * @return 	the character position in the text flow at which the line begins.
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+ 		 *
+ 		 * @see flashx.textLayout.elements.TextFlow
+		 */
+		 
+		public function get absoluteStart():int
+		{ return _absoluteStart; }
+		/** @private */
+		tlf_internal function setAbsoluteStart(val:int):void
+		{ _absoluteStart = val; }
+				
+		/** 
+		 * The number of characters to the next line, including trailing spaces. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	
+		public function get textLength():int
+		{ return _textLength; }
+		/** @private */
+		tlf_internal function setTextLength(val:int):void
+		{ 
+			_textLength = val; 
+		//	assert(_validity == TextLineValidity.INVALID, "not already damaged");
+			damage(TextLineValidity.INVALID);
+		}
+		
+		/** 
+		 * The amount of space to leave before the line.
+		 * <p>If the line is the first line of a paragraph that has a space-before applied, the line will have
+		 * a <code>spaceBefore</code> value. If the line comes at the top of a column, <code>spaceBefore</code> is ignored. 
+		 * Otherwise, the line follows another line in the column, and it is positioned vertically to insure that there is
+		 * at least this much space left between this line and the last line of the preceding paragraph.</p> 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see flashx.textLayout.formats.TextLayoutFormat#paragraphSpaceBefore TextLayoutFormat.paragraphSpaceBefore
+		 */
+		 
+		public function get spaceBefore():Number
+		{ return _spaceBefore; }
+		/** @private */
+		tlf_internal function setSpaceBefore(val:Number):void
+		{ _spaceBefore = val; }
+		
+		/** 
+		 * The amount of space to leave after the line.
+		 * <p>If the line is the last line of a paragraph that has a space-after, the line will have
+		 * a <code>spaceAfter</code> value. If the line comes at the bottom of a column, then the <code>spaceAfter</code>
+		 * is ignored. Otherwise, the line comes before another line in the column, and the following line must be positioned vertically to
+		 * insure that there is at least this much space left between this last line of the paragraph and the first
+		 * line of the following paragraph.</p> 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+		 * @see flashx.textLayout.formats.TextLayoutFormat#paragraphSpaceAfter TextLayoutFormat.paragraphSpaceAfter
+		 */
+		 
+		public function get spaceAfter():Number
+		{ return _spaceAfter; }
+		/** @private */
+		tlf_internal function setSpaceAfter(val:Number):void
+		{ _spaceAfter = val; }
+		
+		/** @private 
+		 * Target width not including paragraph indents @private */
+		 
+		tlf_internal function get outerTargetWidth():Number
+		{ return _outerTargetWidth; }
+		
+		/** @private */
+		tlf_internal function set outerTargetWidth(val:Number):void
+		{ _outerTargetWidth = val; }
+		
+		/** @private  
+		 * Amount of space used to break the line
+		 * <p>The target width is the amount of space allowed for the line, including the space required for indents.</p>
+		 */
+		tlf_internal function get targetWidth():Number
+		{ return _targetWidth; }
+										
+		/** 
+		 * Returns the bounds of the line as a rectangle.
+		 *
+		 * @return a rectangle that represents the boundaries of the line.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function getBounds():Rectangle
+		{	
+			var textLine:TextLine = getTextLine(true);
+			if (!textLine)
+				return new Rectangle();
+
+			// TODO: just use the textLine.x and textLine.y - after all getTextLine now sets them.
+			// not going to change this right now though
+			var bp:String = paragraph.getAncestorWithContainer().computedFormat.blockProgression;
+			var shapeX:Number = createShapeX();
+			var shapeY:Number = createShapeY(bp);
+			if (bp == BlockProgression.TB)
+				shapeY += descent-textLine.height;
+			return new Rectangle(shapeX, shapeY, textLine.width, textLine.height);			
+		}
+								
+		/** The validity of the line. 
+		 * <p>A line can be invalid if the text, the attributes applied to it, or the controller settings have
+		 * changed since the line was created. An invalid line can still be displayed, and you can use it, but the values
+		 * used will be the values at the time it was created. The line returned by <code>getTextLine()</code> also will be in an
+		 * invalid state. </p>
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see #getTextLine()
+	 	 * @see flash.text.engine.TextLine#validity TextLine.validity
+	 	 * @see FlowDamageType#GEOMETRY
+		 */
+		 
+		public function get validity():String
+		{ 
+			// A TextLine may be invalidated separately from the TextFlowLine, when the invalidation is driven from the Player (e.g. changes have been made directly). 
+			// If the TextFlowLine is marked valid, the line may still be invalid if the TextLine has been marked invalid.
+			// If the line has been released (TextBlock.releaseLines called), then it may have an existing TextLine that got marked invalid by the Player 
+			// when it was released. We want to ignore that invalid marking.
+			if (!_released)
+			{
+				var textLine:TextLine = peekTextLine();
+				if (textLine && (_validity == FlowDamageType.GEOMETRY || _validity == TextLineValidity.VALID) && textLine.validity != TextLineValidity.VALID)
+					_validity = textLine.validity;
+			}
+			return _validity; 
+		}
+		
+		/** 
+		 * The width of the line if it was not justified. For unjustified text, this value is the same as <code>textLength</code>. 
+		 * For justified text, this value is what the length would have been without justification, and <code>textLength</code> 
+		 * represents the actual line width. For example, when the following String is justified and assigned a width of 500, it 
+		 * has an actual width of 500 but an unjustified width of 268.9921875. 
+		 *
+		 * @internal TBD: add graphic of justified line
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function get unjustifiedTextWidth():Number
+		{ 
+			// hack - outerTargetWidth holds value from the factory
+			return _unjustifiedTextWidth + (_outerTargetWidth - targetWidth); 
+		}
+		
+		/** @private 
+		 * True if the line needs composing. */
+		tlf_internal function isDamaged():Boolean
+		{ 
+			if (_validity != TextLineValidity.VALID)
+				return true;
+			if (!_released)
+			{
+				var textLine:TextLine = peekTextLine(); 
+				if (textLine && textLine.validity != TextLineValidity.VALID)
+					return true;
+			}
+			return false;
+		}
+		
+		/** @private
+		 * Mark the line as valid */
+		tlf_internal function clearDamage():void
+		{ 
+			CONFIG::debug { assert(_validity == FlowDamageType.GEOMETRY, "can't clear damage other than geometry"); }
+			if (_validity == TextLineValidity.VALID)		// already is valid
+				return;	
+			_validity = TextLineValidity.VALID; 
+			
+			//CONFIG::debug { assert(_textLineCache != null, "bad call to clearDamage"); }
+
+			var textLine:TextLine =  peekTextLine();
+
+			// The line in the cache, if there is one, is either invalid because its been released, or its geometry_damaged, or its already valid.
+			CONFIG::debug { assert(!textLine || _released || textLine.validity == TextLineValidity.VALID || textLine.validity == FlowDamageType.GEOMETRY, "can't clear TextLine damage other than geometry"); }
+
+			if (textLine && !_released)	// mark the TextLine as well
+			{
+				textLine.validity = TextLineValidity.VALID;
+				CONFIG::debug { Debugging.traceFTEAssign(textLine,"validity",TextLineValidity.VALID);  }
+			}
+		}
+		
+		/** @private
+		 * Mark the line as damaged */
+		 
+		tlf_internal function damage(damageType:String):void
+		{
+			// trace("TextFlowLine.damage ", this.start.toString(), this.textLength.toString());
+			if (_validity == damageType || _validity == TextLineValidity.INVALID)
+				return;	// totally damaged
+			_validity = damageType;
+			
+			var textLine:TextLine = peekTextLine();
+			if (textLine && textLine.validity != TextLineValidity.INVALID)
+			{
+				textLine.validity = _validity;
+				CONFIG::debug { Debugging.traceFTEAssign(textLine,"validity",damageType);  }
+			}
+		}
+		
+		/** @private */
+		CONFIG::debug public function toString():String
+		{
+			return "x:" + x + " y: " + y + " absoluteStart:" + absoluteStart + " textLength:" + textLength +  " location: " + location + " validity: " + _validity;
+		}
+	
+		/** 
+		 * Indicates whether the <code>flash.text.engine.TextLine</code> object for this TextFlowLine exists.  
+		 * The value is <code>true</code> if the TextLine object has <em>not</em> been garbage collected and 
+		 * <code>false</code> if it has been.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+	 	 * @see flash.text.engine.TextLine TextLine
+		 */
+		 
+		public function get textLineExists():Boolean
+		{
+			return peekTextLine() != null;			
+		}
+
+		/** 
+		 * Returns the <code>flash.text.engine.TextLine</code> object for this line, which might be recreated 
+		 * if it does not exist due to garbage collection. Set <code>forceValid</code> to <code>true</code>
+		 * to cause the TextLine to be regenerated. Returns null if the TextLine cannot be recreated.
+		 *.
+		 * @param forceValid	if true, the TextLine is regenerated, if it exists but is invalid.
+		 *
+		 * @return object for this line or <code>null</code> if the TextLine object cannot be 
+		 * recreated.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see flash.text.engine.TextLine TextLine
+		 */
+		 
+		public function getTextLine(forceValid:Boolean = false):TextLine
+		{ 				
+			var textLine:TextLine = peekTextLine();
+			if (!textLine || (textLine.validity != TextLineValidity.VALID && forceValid))
+			{
+				if (isDamaged() && validity != FlowDamageType.GEOMETRY)
+					return null;
+				
+				var textBlock:TextBlock = paragraph.getTextBlock();
+
+				// regenerate the whole paragraph at once, up to current position. The TextBlock may already contain valid
+				// lines that got generated on a prior call to getTextLine but couldn't be added to the cache (e.g., because
+				// the cache contains an invalid line that is in the display list), so we check for that before making a new line.
+				var previousLine:TextLine;
+				var currentLine:TextLine = textBlock.firstLine;
+				var flowComposer:IFlowComposer = paragraph.getTextFlow().flowComposer;
+				var lineIndex:int = flowComposer.findLineIndexAtPosition(paragraph.getAbsoluteStart());
+				do
+				{
+					var line:TextFlowLine = flowComposer.getLineAt(lineIndex);
+					CONFIG::debug { assert (line.paragraph == paragraph, "Expecting line in same paragraph"); }
+					if (currentLine != null && currentLine.validity == TextLineValidity.VALID)
+					{
+						textLine = currentLine;
+						currentLine = currentLine.nextLine;
+						
+						line.updateTextLineCache(textLine);
+					}
+					else
+					{
+						textLine = line.recreateTextLine(textBlock, previousLine);
+						currentLine = null;
+					}
+					previousLine = textLine;
+					++lineIndex;
+				} while (line != this);			
+			}
+			
+			if(textLine != null && textLine.numChildren == 0 && _adornCount > 0)
+			{
+				var para:ParagraphElement = this.paragraph;
+				var paraStart:int = para.getAbsoluteStart();
+				var elem:FlowLeafElement = para.findLeaf(this.absoluteStart - paraStart);
+				var elemStart:int = elem.getAbsoluteStart();
+				
+				createAdornments(para.getAncestorWithContainer().computedFormat.blockProgression,elem, elemStart);		
+			}
+			
+			return textLine;
+		}
+		
+		/** @private Regenerate the TextLine -- called when textLine has been gc'ed */
+		tlf_internal function recreateTextLine(textBlock:TextBlock, previousLine:TextLine):TextLine
+		{
+			var textLine:TextLine;
+			
+			// If we already have a valid text line, just return it.
+			if (!_released)
+			{
+				textLine = peekTextLine();
+				if (textLine)
+					return textLine;
+			}
+			
+			var textFlow:TextFlow = paragraph.getTextFlow();
+			var flowComposer:IFlowComposer = textFlow.flowComposer;
+			var swfContext:ISWFContext = flowComposer.swfContext ? flowComposer.swfContext : BaseCompose.globalSWFContext;
+			
+			textLine = TextLineRecycler.getLineForReuse();
+			if (textLine)
+			{
+				CONFIG::debug { assert(textFlow.backgroundManager == null || textFlow.backgroundManager.lineDict[textLine] === undefined,"Bad TextLine in recycler cache"); }
+				textLine = swfContext.callInContext(textBlock["recreateTextLine"], textBlock, [ textLine, previousLine, _targetWidth, _lineOffset, true ]);
+			}
+			else
+				textLine = swfContext.callInContext(textBlock.createTextLine, textBlock, [ previousLine, _targetWidth, _lineOffset, true ]);
+			
+			textLine.x = createShapeX();
+			CONFIG::debug { Debugging.traceFTEAssign(textLine,"x", createShapeX());  }
+			textLine.y = createShapeY(textFlow.computedFormat.blockProgression);
+			CONFIG::debug { Debugging.traceFTEAssign(textLine,"y", createShapeY(textFlow.computedFormat.blockProgression));  }
+			textLine.doubleClickEnabled = true;
+
+			updateTextLineCache(textLine);
+			
+			return textLine;
+		}
+		
+		/** the rule is that all "displayed" lines must be in the TextFlowLine textLineCache.  Put this new line in the cache iff there isn't already a displayed line */
+		private function updateTextLineCache(textLine:TextLine):void
+		{
+			textLine.userData = this;	
+			var existingTextLine:TextLine = peekTextLine();
+			// If there is an existing, released line, and it is currently being displayed, we can't replace it in the cache.
+			if (!existingTextLine || existingTextLine.parent == null)
+			{
+				if (existingTextLine != textLine)
+					_textLineCache = new WeakRef(textLine);	
+				_released = false;		
+			}
+		}
+		
+		/** @private */
+		tlf_internal function markReleased():void
+		{
+			_released = true;
+		}
+		
+		/** @private */
+		tlf_internal function createShape(bp:String):TextLine
+		{
+			var textLine:TextLine = getTextLine();
+			
+			var newX:Number = createShapeX();
+			//if (int(newX*20) != int(textLine.x*20))
+			{
+				textLine.x = newX;
+				CONFIG::debug { Debugging.traceFTEAssign(textLine,"x", newX);  }
+			}
+			var newY:Number = createShapeY(bp);
+			//if (int(newY*20) != int(textLine.y*20))
+			{
+				textLine.y = newY;
+				CONFIG::debug { Debugging.traceFTEAssign(textLine,"y", newY);  }
+			}
+			return textLine;
+		}
+		
+		private function createShapeX():Number
+		{ return x; }
+		
+		private function createShapeY(bp:String):Number
+		{ return bp == BlockProgression.RL ? y : y + _ascent; }
+        
+         /** @private 
+         * Scan through the format runs within the line, and draw any underline or strikethrough that might need it
+		 */
+		 
+		tlf_internal function createAdornments(blockProgression:String,elem:FlowLeafElement,elemStart:int):void
+		{
+			CONFIG::debug { assert(elemStart == elem.getAbsoluteStart(),"bad elemStart passed to createAdornments"); } 
+			var endPos:int = _absoluteStart + _textLength;
+			
+			//init adornments back to 0
+			_adornCount = 0;
+
+			for (;;)
+			{
+				var format:ITextLayoutFormat = elem.computedFormat;
+
+				_adornCount += elem.updateAdornments(this, blockProgression);
+				
+				var fvh:FlowValueHolder = elem.format as FlowValueHolder;
+				if(fvh && fvh.userStyles && fvh.userStyles.imeStatus)
+				{
+					elem.updateIMEAdornments(this, blockProgression, fvh.userStyles.imeStatus as String);
+				}
+				elemStart += elem.textLength;
+				if (elemStart >= endPos)
+					break;
+				elem = elem.getNextLeaf(_para);
+				CONFIG::debug { assert(elem != null,"bad nextLeaf"); }
+			}
+		}
+        
+       /** @private 
+         * Scan through the format runs within the line, and figure out what the leading for the overall line is.
+		 * The line's leading is equal to the maximum leading of any individual run within the line.
+		 * The leading in an individual format run is calculated by looking at the leading attribute in the
+		 * CharacterFormat. If it is set to a value, we just use that value. Otherwise, if it is set to AUTO,
+		 * we calculate the leading based on the point size and the auto leading percentage from the ParagraphFormat.
+		 */
+		 
+		tlf_internal function getLineLeading(bp:String,elem:FlowLeafElement,elemStart:int):Number
+		{
+			CONFIG::debug { assert(elemStart == elem.getAbsoluteStart(),"bad elemStart passed to getLineLeading"); } 
+			var endPos:int = _absoluteStart + _textLength;
+			var totalLeading:Number = 0;
+			CONFIG::debug { assert(elem.getAncestorWithContainer() != null,"element with no container"); }
+			for (;;)
+			{
+				//this is kinda bunk and really shouldn't be here, but I'm loath to find a better way....
+				//ignore the leading on a TCY Block.
+				//if the elem is in a TCYBlock, AND it is not the only block in the line, "skip" it
+				if (!(bp == BlockProgression.RL && (elem.parent is TCYElement) &&  (!isNaN(totalLeading) || (elem.textLength != this.textLength))))
+				{
+					var elemLeading:Number = TextLayoutFormat.lineHeightProperty.computeActualPropertyValue(elem.computedFormat.lineHeight,elem.getEffectiveFontSize());
+					totalLeading = Math.max(totalLeading, elemLeading);
+				}
+				elemStart += elem.textLength;
+				if (elemStart >= endPos)
+					break;
+				elem = elem.getNextLeaf(_para);
+				CONFIG::debug { assert(elem != null,"bad nextLeaf"); }
+			}
+			return totalLeading;
+		}
+        
+		/** @private 
+		 * Scan through the format runs within the line, and figure out what the typographic ascent (i.e. ascent relative to the 
+		 * Roman baseline) for the overall line is. Normally it is the distance between the Roman and Ascent baselines, 
+		 * but it may be adjusted upwards by the width/height of the GraphicElement.
+		 */
+		tlf_internal function getLineTypographicAscent(elem:FlowLeafElement,elemStart:int):Number
+		{
+			CONFIG::debug { assert(elemStart == elem.getAbsoluteStart(),"bad elemStart passed to getLineTypographicAscent"); } 
+			return getTextLineTypographicAscent(getTextLine(), elem, elemStart, absoluteStart+textLength, _para);
+		}
+        
+		/** @private 
+		 * Scan through the format runs within the line, and figure out what the typographic ascent (i.e. ascent relative to the 
+		 * Roman baseline) for the overall line is. Normally it is the distance between the Roman and Ascent baselines, 
+		 * but it may be adjusted upwards by the width/height of the GraphicElement.
+		 */
+		static tlf_internal function getTextLineTypographicAscent(textLine:TextLine, elem:FlowLeafElement,elemStart:int, textLineEnd:int, para:ParagraphElement):Number
+		{
+			CONFIG::debug { assert(elemStart == elem.getAbsoluteStart(),"bad elemStart passed to getTextLineTypographicAscent"); } 
+			var rslt:Number = textLine.getBaselinePosition(flash.text.engine.TextBaseline.ROMAN) - textLine.getBaselinePosition(flash.text.engine.TextBaseline.ASCENT);
+				
+			for (;;) 
+			{
+				if (elem is InlineGraphicElement)
+					rslt = Math.max(rslt,InlineGraphicElement(elem).getTypographicAscent(textLine));
+				elemStart += elem.textLength;
+				if (elemStart >= textLineEnd)
+					break;
+				elem = elem.getNextLeaf(para);
+				CONFIG::debug { assert(elem != null,"bad nextLeaf"); }
+			}
+			return rslt;
+		}
+        
+        //helper method to determine which subset of line is underlined
+        //I believe this will be replaced by the eventSink mechanism
+        private function isTextlineSubsetOfSpan(element:FlowLeafElement): Boolean
+        { 
+        	var spanStart:int = element.getAbsoluteStart();
+        	var spanEnd:int = spanStart + element.textLength;
+        	
+        	var lineStart:int = this.absoluteStart;
+        	var lineEnd:int = this.absoluteStart + this._textLength;
+          	
+        	return spanStart <= lineStart && spanEnd >= lineEnd;
+        }
+        
+       
+        
+ 		/** Create a rectangle for selection */
+		static private function createSelectionRect(selObj:Shape, color:uint, x:Number, y:Number, width:Number, height:Number):DisplayObject
+		{
+ 			selObj.graphics.beginFill(color);
+ 			var cmds:Vector.<int> = new Vector.<int>();
+ 			var pathPoints:Vector.<Number> = new Vector.<Number>();
+ 			
+ 			//set the start point - topLeft
+ 			cmds.push(GraphicsPathCommand.MOVE_TO);
+ 			pathPoints.push(x);
+ 			pathPoints.push(y);
+ 			
+ 			//line to topRight
+ 			cmds.push(GraphicsPathCommand.LINE_TO);
+ 			pathPoints.push(x + width);
+ 			pathPoints.push(y);
+ 			
+ 			//line to botRight
+ 			cmds.push(GraphicsPathCommand.LINE_TO);
+ 			pathPoints.push(x + width);
+ 			pathPoints.push(y + height);
+ 			
+ 			//line to botLeft
+ 			cmds.push(GraphicsPathCommand.LINE_TO);
+ 			pathPoints.push(x);
+ 			pathPoints.push(y + height);
+ 			
+ 			//line to close the path - topLeft
+ 			cmds.push(GraphicsPathCommand.LINE_TO);
+ 			pathPoints.push(x);
+ 			pathPoints.push(y);
+ 			
+ 			selObj.graphics.drawPath(cmds, pathPoints, flash.display.GraphicsPathWinding.NON_ZERO);
+ 			
+			return selObj;			
+		}
+	
+		/** @private getSelectionShapesCacheEntry
+		 * 
+		 * creates and adds block selection(s) to the text container.  In most circumstances,
+		 * this method will produce and add a single DisplayObject, but in certain circumstances,
+		 * such as TCY in TTB text, will need to make multiple selection rectangles.
+		 * 
+		 * Examples:
+		 * 1) horizontal - ABCDE
+		 * 2) vertical - ABCDE
+		 * 3) horizontal - ABcdE
+		 * 4) vertical:		A
+		 * 					B
+		 * 				   cde
+		 * 					F
+		 * 
+		 */
+		private function getSelectionShapesCacheEntry(begIdx:int, endIdx:int, prevLine:TextFlowLine, nextLine:TextFlowLine, blockProgression:String):SelectionCache
+		{
+			if (isDamaged())
+				return null;
+			
+			// CONFIG::debug { assert(_textLineCache != null, "bad call to getSelectionShapesCacheEntry"); }
+			
+			//get the absolute start of the paragraph.  Calculation is expensive, so just do this once.
+			var paraAbsStart:int = _para.getAbsoluteStart();
+			
+			//if the indexes are identical and are equal to the start of the line, then
+			//don't draw anything.  This prevents a bar being drawn on a following line when
+			//selecting accross line boundaries
+			//with exception for a selection that includes just the first character of an empty last line in the TextFlow
+			if (begIdx == endIdx && paraAbsStart + begIdx == absoluteStart)
+			{
+				if (absoluteStart != _para.getTextFlow().textLength-1)
+					return null;
+				endIdx++;
+			}
+			
+			//the cached selection bounds and rects
+			var selectionCache:SelectionCache = _selectionBlockCache[this];
+			if (selectionCache && selectionCache.begIdx == begIdx && selectionCache.endIdx == endIdx)
+				return selectionCache;			
+			
+			var drawRects:Array = new Array();
+			//an array to store any tcy rectangles which need separate processing and may not exist
+			var tcyDrawRects:Array = new Array();
+			
+			if(selectionCache == null)
+			{
+				selectionCache = new SelectionCache();
+				_selectionBlockCache[this] = selectionCache;
+			}	
+			else
+			{
+				selectionCache.clear();
+			}
+			selectionCache.begIdx = begIdx;
+			selectionCache.endIdx = endIdx;
+			
+			var textLine:TextLine = getTextLine();
+			var heightAndAdj:Array = getRomanSelectionHeightAndVerticalAdjustment(prevLine, nextLine);
+			calculateSelectionBounds(textLine, drawRects, begIdx, endIdx, blockProgression, heightAndAdj);
+			
+			//iterate the blocks and create DisplayObjects to draw...
+			for each(var drawRect:Rectangle in drawRects)
+			{
+				CONFIG::debug{ assert(selectionCache != null, "If we're caching, selectionArray should never be null!"); }
+				//we have to make new rectangles or the convertLineRectToGlobal will alter the cached ones!
+				selectionCache.pushSelectionBlock(drawRect);
+			}
+			
+
+			//allow the atoms to be garbage collected.
+			if (textLine)
+				textLine.flushAtomData();
+			
+			return selectionCache;
+		}
+		
+		
+		/** @private - helper method to calculate all selection blocks within a line.*/
+		tlf_internal function calculateSelectionBounds(textLine:TextLine, rectArray:Array, begIdx:int, endIdx:int, blockProgression:String, heightAndAdj:Array):void
+		{
+			//the direction of the text
+			var direction:String = _para.computedFormat.direction;
+			//get the absolute start of the paragraph.  Calculation is expensive, so just do this once.
+			var paraAbsStart:int = _para.getAbsoluteStart();
+			//the current index.  used to iterate to the next element
+			var curIdx:int = begIdx;
+			//the current FlowLeafElement as determined by curIdx
+			var curElem:FlowLeafElement = null;
+			//the hightest glyph.  Needed to normalize the rectangles we'll be building
+			var largestRise:Number = 0;
+			
+			//blockRectArray holds each leaf's blocks which could be 1 or more
+			var blockRectArray:Array = new Array();
+			//floatRectArray holds the selection rects for any floats in the range.
+			var floatRectArray:Array = null;
+			//tcyDrawRects:Array
+			var tcyDrawRects:Array = null;
+			
+			//do this loop and only afterwards perform the normalization and addition to the rectArr
+			while(curIdx < endIdx)
+			{
+				curElem = _para.findLeaf(curIdx);
+				//if we somehow got a 0 length element, then increment the index and continue
+				if(curElem.textLength == 0)
+				{
+					++curIdx;
+					continue;
+				}
+				else if(curElem is InlineGraphicElement && (curElem as InlineGraphicElement).float != Float.NONE)
+				{
+					if(floatRectArray == null)
+						floatRectArray = new Array();
+						
+					var tempFloatArray:Array = makeSelectionBlocks(curIdx, curIdx+1, paraAbsStart, blockProgression, direction, heightAndAdj);
+					CONFIG::debug{ assert(tempFloatArray.length == 1, "How can a single floated InlineGraph have multiple shapes!"); }
+					floatRectArray.push(tempFloatArray[0]);
+					++curIdx;
+					continue;
+				}
+				//the number of potential glyphs to hilite.  Could larger than needs be if we are only selecting part of it.
+				var numCharsSelecting:int = curElem.textLength + curElem.getElementRelativeStart(_para) - curIdx;
+				//the index of the last glyph to hilite.  If a partial selection, use endIdx
+				var endPos:int = (numCharsSelecting + curIdx) > endIdx ? endIdx : (numCharsSelecting + curIdx);
+				
+				//if this is not a TCY in vertical, the blocks should all be running in the same direction
+				if (blockProgression != BlockProgression.RL || 
+					(textLine.getAtomTextRotation(textLine.getAtomIndexAtCharIndex(curIdx)) != TextRotation.ROTATE_0))
+				{
+					var leafBlockArray:Array = makeSelectionBlocks(curIdx, endPos, paraAbsStart, blockProgression, direction, heightAndAdj);
+					//copy all the blocks into the blockRectArray - we'll normalize them later
+					for(var leafBlockIter:int = 0; leafBlockIter < leafBlockArray.length; ++leafBlockIter)
+					{
+						blockRectArray.push(leafBlockArray[leafBlockIter]);
+					}
+				}
+				else
+				{
+					var tcyBlock:FlowElement = curElem.getParentByType(TCYElement);
+					CONFIG::debug{ assert(tcyBlock != null, "What kind of object is this that is ROTATE_0, but not TCY?");}
+					
+					//if this element is still encompassed by a SubParagraphGroupElement of some kind (either a link or a TCYBlock)
+                	//keep moving up to the parent.  Otherwise, the below code will go into an infinite loop.  bug 1905734
+                	var tcyParentRelativeEnd:int = tcyBlock.parentRelativeEnd;
+                	var subParBlock:SubParagraphGroupElement = tcyBlock.getParentByType(SubParagraphGroupElement) as SubParagraphGroupElement;
+                	while (subParBlock)
+                	{
+                		tcyParentRelativeEnd += subParBlock.parentRelativeStart;
+                		subParBlock = subParBlock.getParentByType(SubParagraphGroupElement) as SubParagraphGroupElement;
+                	}
+					
+					var largestTCYRise:Number = 0;
+                    var lastTCYIdx:int = endIdx < tcyParentRelativeEnd ? endIdx : tcyParentRelativeEnd;
+                    var tcyRects:Array = new Array();
+
+			
+					while(curIdx < lastTCYIdx)
+					{
+						curElem = _para.findLeaf(curIdx);
+						numCharsSelecting = curElem.textLength + curElem.getElementRelativeStart(_para) - curIdx;
+						endPos = numCharsSelecting + curIdx > endIdx ? endIdx : numCharsSelecting + curIdx;
+						var tcyRectArray:Array =  makeSelectionBlocks(curIdx, endPos, paraAbsStart, blockProgression, direction, heightAndAdj);
+						
+						for(var tcyBlockIter:int = 0; tcyBlockIter < tcyRectArray.length; ++tcyBlockIter)
+						{
+							var tcyRect:Rectangle = tcyRectArray[tcyBlockIter];
+							
+							if(tcyRect.height > largestTCYRise)
+							{
+								largestTCYRise = tcyRect.height;
+							}
+								
+							tcyRects.push(tcyRect);
+						}
+						curIdx = endPos;
+					}
+					
+					if(!tcyDrawRects)
+						tcyDrawRects = new Array();
+						
+					normalizeRects(tcyRects, tcyDrawRects, largestTCYRise, BlockProgression.TB, direction);
+					continue;
+				
+				}
+				
+				//set the curIdx to the last char in the block
+				curIdx = endPos;
+			}
+			
+			
+			
+			//adding check for an empty set of draw rects.  If there are not recangles, skip this.
+			//this can happen is there are ONLY TCY blocks and the whole line is selected.
+			//Watson 2273832. - gak 02.09.09
+			//if the whole line is selected
+			if(blockRectArray.length > 0 && (paraAbsStart + begIdx) == absoluteStart && (paraAbsStart + endIdx) == (absoluteStart + textLength))
+			{
+				curElem = _para.findLeaf(begIdx);
+				//if we have the entire line selected, but the first element is NOT the last, then
+				//we will land up with a selection which is 1 character wider than it should be.
+				if(((curElem.getAbsoluteStart() + curElem.textLength) < (absoluteStart + textLength)) && endPos >= 2)
+				{
+					//make sure that this is a white char and that we aren't deselecting the last
+					//char in a line - esp important for scripts which don't use spaces ie Japanese
+					var charCode:int = _para.getCharCodeAtPosition(endPos - 1);
+					if(charCode != SpanElement.kParagraphTerminator.charCodeAt(0) && CharacterUtil.isWhitespace(charCode))
+					{
+						var lastElemBlockArray:Array = makeSelectionBlocks(endPos - 1, endPos - 1, paraAbsStart, blockProgression, direction, heightAndAdj);
+						var lastRect:Rectangle = lastElemBlockArray[lastElemBlockArray.length - 1];
+						var modifyRect:Rectangle = blockRectArray[blockRectArray.length - 1] as Rectangle;
+						
+						if (blockProgression != BlockProgression.RL)
+						{
+							//if they have the same width, simply remove the last block
+							if(modifyRect.width == lastRect.width)
+							{
+								blockRectArray.pop();
+							}
+							else
+							{
+								modifyRect.width -= lastRect.width;
+								
+								//if this is RTL, we need to shift the selection block over by the amount
+								//we reduced it.
+								if(direction == Direction.RTL)
+									modifyRect.left -= lastRect.width;
+							}
+						}
+						else
+						{
+							//if they have the same height, simply remove the last block
+							if(modifyRect.height == lastRect.height)
+							{
+								blockRectArray.pop();
+							}
+							else
+							{
+								modifyRect.height -= lastRect.height;
+								
+								//if this is RTL, we need to shift the selection block down by the amount
+								//we reduced it.
+								if(direction == Direction.RTL)
+									modifyRect.top += lastRect.height;
+							}
+						}
+					}
+				}
+			}
+			
+			normalizeRects(blockRectArray, rectArray, largestRise, blockProgression, direction);
+			//add in the TCY Rects
+			if(tcyDrawRects && tcyDrawRects.length > 0)
+			{
+				for(var tcyIter:int = 0; tcyIter < tcyDrawRects.length; ++tcyIter)
+				{
+					rectArray.push(tcyDrawRects[tcyIter]);
+				}
+			}
+			
+			//float selections do not normalize, put them into the rect array now
+			if(floatRectArray)
+			{
+				for(var floatIter:int = 0; floatIter < floatRectArray.length; ++floatIter)
+				{
+					rectArray.push(floatRectArray[floatIter]);
+				}
+			}
+			
+		}
+
+		private function createSelectionShapes(selObj:Shape, selFormat:SelectionFormat, container:DisplayObject, begIdx:int, endIdx:int, prevLine:TextFlowLine, nextLine:TextFlowLine):void
+		{
+			var contElement:ContainerFormattedElement = _para.getAncestorWithContainer();
+			CONFIG::debug { assert(contElement != null,"para with no container"); }
+			var blockProgression:String = contElement.computedFormat.blockProgression;
+			
+			var selCache:SelectionCache = getSelectionShapesCacheEntry(begIdx, endIdx, prevLine, nextLine, blockProgression);
+			if (!selCache)
+				return;
+		
+			//iterate the blocks and create DisplayObjects to draw...
+			var drawRect:Rectangle;
+			var color:uint = selFormat.rangeColor;
+			
+			if (_para && _para.getTextFlow()) {
+				var selMgr:ISelectionManager = _para.getTextFlow().interactionManager;
+				if (selMgr && (selMgr.anchorPosition == selMgr.activePosition))
+					color = selFormat.pointColor;
+			}
+			
+			for each (drawRect in selCache.selectionBlocks)
+			{
+				drawRect = drawRect.clone();
+				convertLineRectToContainer(drawRect, true);
+				createSelectionRect(selObj, color, drawRect.x, drawRect.y, drawRect.width, drawRect.height);
+			}
+		}
+		
+ 		/** @private 
+		 * Get the height and vertical adjustment for the line's selection shape, assuming Western typographic rules
+		 * where leading is included in selection.
+		 * @return An array with two elements
+		 * [0] height
+		 * [1] vertical adjustment to counter 'align bottom' behavior. The remainder of the selection code assumes selection shape
+		 * bottom is to be aligned with line descent. If this is not the case, vertical adjustment is set to an appropriate non-zero value. 
+		 */
+ 		tlf_internal function getRomanSelectionHeightAndVerticalAdjustment (prevLine:TextFlowLine, nextLine:TextFlowLine):Array
+ 		{	
+ 			var rectHeight:Number = 0;
+ 			var verticalAdj:Number = 0; //  Default to 'align bottom'.
+ 			
+			//This code erroneously assumed that it would only be called with a SPACE justifier and that AUTO would be up.  That is incorrect
+			//because some scripts, like Korean, use an up leading model and the EAST_ASIAN justifier.  New code just performs the check
+ 			if(ParagraphElement.useUpLeadingDirection(_para.getEffectiveLeadingModel()))
+ 			{			
+ 				// "Space above, align bottom" 
+ 				// 1) Space above as dictated by first baseline offset for the first line or line leading otherwise (both obtained from the 'height' data member)
+ 				// 2) Selection rectangle must at least include all of the text area
+ 				rectHeight = height > _textHeight ? height : _textHeight;
+ 				
+ 				// 3) Selection rectangle's bottom aligned with line descent; verticalAdj remains 0
+ 			}
+ 			else
+ 			{
+ 				// TODO-9/4/08-Is this the right way to check for first/last lines? 
+				var isFirstLine:Boolean = !prevLine || prevLine.controller != controller || prevLine.columnIndex != columnIndex;
+				var isLastLine:Boolean  = !nextLine || nextLine.controller != controller || nextLine.columnIndex != columnIndex
+						|| nextLine.paragraph.getEffectiveLeadingModel() == LeadingModel.ROMAN_UP;
+ 					//I'm removing this line as it makes the assumption that AUTO leading dir is UP only for Roman text, which is incorrect.
+ 					//Korean also uses UP leading but uses the EastAsian justifier. - gak 01.22.09
+ 					//||(nextLine.paragraph.computedFormat.leadingDirection == LeadingDirection.AUTO && nextLine.paragraph.computedFormat.justificationRule == JustificationRule.SPACE); 
+
+ 				if (isLastLine)
+ 				{
+ 					// There is no line after this one, or there is one which uses leading UP, so leading DOWN does not apply
+ 							
+ 					if (!isFirstLine)
+ 					{
+ 						// "Space above None, align bottom" (eqivalently, "Space below None, align top"): 
+ 						// 1) Only the text area should be selected
+ 						rectHeight = _textHeight;
+ 		
+ 						// 2) Selection rectangle's bottom aligned with line descent; verticalAdj remains 0
+ 					}
+ 					else
+ 					{
+ 						// "Space above, align bottom" 
+ 						// 1) Space above as dictated by first baseline offset 
+ 						// 2) Selection rectangle must at least include all of the text area
+ 						rectHeight = height > _textHeight ? height : _textHeight;
+ 						// 3) Selection rectangle's bottom aligned with line descent; verticalAdj remains 0
+ 					}
+ 				}
+ 				else
+ 				{
+ 					 // There is a line after this one, so leading DOWN applies
+ 					 
+ 					if (!isFirstLine)
+ 					{
+ 						// "Space below, align top" 
+ 						// 1) Space below as dictated by line leading (obtained from 'height' member of next line) 
+ 						// 2) Selection rectangle must at least include all of the text area
+ 						rectHeight = nextLine.height > _textHeight ? nextLine.height : _textHeight;
+ 						
+ 						// 3) Selection rectangle's top to be aligned with line ascent, so its bottom to be at rectHeight - textLine.ascent,
+ 						// not textLine.descent, set verticalAdj accordingly 
+ 						verticalAdj = rectHeight - _textHeight; // same as rectHeight - textLine.ascent - textLine.descent
+ 					}
+ 					else
+ 					{
+ 						// Union of 
+ 						// 1) first line, leading up: In this case, rectangle height is the larger of line height and text height,
+ 						// and the rectangle is shifted down by descent amount to align bottoms. So, top of rectangle is at:
+ 						var top:Number = _descent - (height > _textHeight ? height : _textHeight);
+ 						
+ 						// 2) interior line, leading down: In this case, rectangle height is the larger of line leading and text height,
+ 						// and the rectangle is shifted up by ascent amount to align tops. So, bottom of rectangle is at:
+ 						var bottom:Number = (nextLine.height > _textHeight ? nextLine.height : _textHeight) - _ascent;
+ 						
+ 						rectHeight = bottom - top;
+ 						
+ 						// 3) Selection rectangle's bottom to be at 'bottom', not the line's descent; set verticalAdj accordingly
+ 						verticalAdj = bottom - _descent;
+ 					}
+ 				}
+ 			}
+ 			
+ 			//If we don't have a line above us, then we need to pad the line a bit as well as make it shift up.
+ 			//If we don't, then it overlaps the line below too much OR clips the top of the glyphs.
+ 			if(!prevLine || prevLine.columnIndex != this.columnIndex || prevLine.controller != this.controller)
+ 			{
+ 				//make it taller - this is kinda a fudge, but we have no info to determine a good top.
+ 				//if we don't do this, the selection rectangle will clip to the top of the glyphs and even
+ 				//let parts stick out a bit.  So, re-add the descent and offset the rect by 50% so that
+ 				//it appears to balance the top and bottom.
+ 				rectHeight += this.descent;
+ 				verticalAdj = Math.floor(this.descent/2);
+ 			}
+ 			return [rectHeight, verticalAdj];
+ 		}
+		
+		/** @private 
+		 * 
+		 * 
+		 */
+		 private function makeSelectionBlocks(begIdx:int, endIdx:int, paraAbsStart:int, blockProgression:String, direction:String, heightAndAdj:Array):Array
+		 {
+		 	CONFIG::debug{ assert(begIdx <= endIdx, "Selection indexes are reversed!  How can this happen?!"); }
+		 	
+		 	var blockArray:Array = new Array();
+		 	var blockRect:Rectangle = new Rectangle();
+		 	var startElem:FlowLeafElement = _para.findLeaf(begIdx);
+			var startMetrics:Rectangle = startElem.getComputedFontMetrics().emBox;
+			
+			var textLine:TextLine = getTextLine(true);
+
+			//++makeBlockPassCounter;
+		 	//trace(makeBlockPassCounter + ") direction = " + direction + " blockProgression = " + blockProgression);
+				 	
+		 	//if this is the whole line, then we should use line data to perform the selection
+			if(paraAbsStart + begIdx == absoluteStart && paraAbsStart + endIdx == absoluteStart + textLength)
+			{
+				var globalStart:Point = new Point(0,0);
+				var justRule:String = _para.getEffectiveJustificationRule();
+				
+				//use the textLine info if we're not using J justification
+				if(justRule != JustificationRule.EAST_ASIAN)
+				{
+					if(blockProgression == BlockProgression.RL)
+					{
+						globalStart.x -= heightAndAdj[1];
+						blockRect.width = heightAndAdj[0];
+						blockRect.height = textLine.textWidth == 0 ? EMPTY_LINE_WIDTH : textLine.textWidth;
+					}
+					else 
+					{
+						globalStart.y += heightAndAdj[1];
+						blockRect.height = heightAndAdj[0];
+						blockRect.width = textLine.textWidth == 0 ? EMPTY_LINE_WIDTH : textLine.textWidth;
+					}	
+					
+				}
+				else
+				{
+					var eaStartElem:int  = textLine.getAtomIndexAtCharIndex(begIdx);
+					var eaStartRect:Rectangle = textLine.getAtomBounds(eaStartElem);
+					
+					if(blockProgression == BlockProgression.RL)
+					{
+						blockRect.width = eaStartRect.width;
+						blockRect.height = textLine.textWidth;
+					}
+					else
+					{
+						blockRect.height =  eaStartRect.height;
+						blockRect.width = textLine.textWidth;
+					}
+				}
+				
+				blockRect.x = globalStart.x;
+				blockRect.y = globalStart.y;
+				
+				if(blockProgression == BlockProgression.RL)
+				{
+					blockRect.x -= textLine.descent;
+				}
+				else
+				{
+					blockRect.y += (textLine.descent - blockRect.height)
+				}
+				
+				//handle rotation
+				if(startElem.computedFormat.textRotation == TextRotation.ROTATE_180 || 
+					startElem.computedFormat.textRotation == TextRotation.ROTATE_90)
+				{
+					if(blockProgression != BlockProgression.RL)
+						blockRect.y += blockRect.height / 2;
+					else
+						blockRect.x -= blockRect.width;
+				}
+				//push it onto array
+				blockArray.push(blockRect);
+			}
+			else //we only have part of the line.  Get the start and end TC bounds
+			{
+				//trace(makeBlockPassCounter + ") begIdx = " + begIdx.toString() + " endIdx = " +  endIdx.toString());
+				var begElementIndex:int = textLine.getAtomIndexAtCharIndex(begIdx); 
+				var endElementIndex:int = adjustEndElementForBidi(begIdx, endIdx, begElementIndex, direction);
+				
+				//trace(makeBlockPassCounter + ") begElementIndex = " + begElementIndex.toString() + " endElementIndex = " +  endElementIndex.toString());
+				CONFIG::debug{ assert(begElementIndex >= 0, "Invalid start index! begIdx = " + begIdx)};
+				CONFIG::debug{ assert(endElementIndex >= 0, "Invalid end index! begIdx = " + endIdx)};
+				
+				if(direction == Direction.RTL && textLine.getAtomBidiLevel(endElementIndex)%2 != 0)
+				{
+					//if we are in RTL, anchoring the LTR text gets tricky.  Because the endElement is before the first
+					//element - which is why we're in this code - the result can be a zero-width rectangle if the span of LTR
+					//text breaks across line boundaries.  If that is the case, then the endElementIndex value will be 0.  As
+					//this is the less common case, assume that it isn't and make all other cases come first
+					if (endElementIndex == 0 && begIdx < endIdx-1)
+					{
+						//since the endElementIndex is 0, meaning that the LTR spans lines,
+						//we want to grab the glyph before the endIdx which represents the last LTR glyph for the selection. 
+						//Make a recursive call into makeSelectionBlocks using and endIdx decremented by 1.
+						blockArray = makeSelectionBlocks(begIdx, endIdx - 1, paraAbsStart, blockProgression, direction, heightAndAdj);
+						var bidiBlock:Array = makeSelectionBlocks(endIdx - 1, endIdx - 1, paraAbsStart, blockProgression, direction, heightAndAdj)
+						var bidiBlockIter:int = 0;
+						while(bidiBlockIter < bidiBlock.length)
+						{
+							blockArray.push(bidiBlock[bidiBlockIter]);
+							++bidiBlockIter;
+						}
+						return blockArray;
+					}
+				}
+				
+				var begIsBidi:Boolean = begElementIndex != -1 ? isAtomBidi(begElementIndex, direction) : false;
+				var endIsBidi:Boolean = endElementIndex != -1 ? isAtomBidi(endElementIndex, direction) : false;
+				
+			 	//trace("begElementIndex is bidi = " + begIsBidi.toString());
+				//trace("endElementIndex is bidi = " + endIsBidi.toString());	
+				
+				if(begIsBidi || endIsBidi)
+				{	
+					//this code needs to iterate over the glyphs starting at the begElementIndex and going forward.
+					//It doesn't matter is beg is bidi or not, we need to find a boundary, create a rect on it, then proceded.
+					//use the value of begIsBidi for testing the consistency of the selection.
+					
+					//Example bidi text.  Note that the period comes at the left end of the line:
+					//
+					//	Bidi state:		f f t t t t t	(true/false)
+					//	Element Index:0 1 2 3 4 5 6		(0 is the para terminator)
+					//	Chars:			. t o _ b e
+					//  Flow Index:	   6 0 1 2 3 4 (5) 	Note that these numbers represent the space between glyphs AND
+					//					 5(f)			that index 5 is both the space after the e and before the period.
+					//									but, the position 5 is not a valid cursor location.
+					
+					//the original code I implemented used the beg and endElement indexes however that fails because when the text
+					//is mixed bidi/non-bidi, the indexes are only 1 char apart. This resulted in, for example, only the period in 
+					//a line getting selected when the text was bidi.   Instead, we're going to use the begIdx and endIdx and 
+					//recalculate the element indexes each time.  This is expensive, but I don't see an alternative. - gak 09.05.08
+					var curIdx:int = begIdx;
+					var incrementor:int = (begIdx != endIdx ? 1 : 0);
+					
+					//the indexes used to draw the seleciton.  activeStart/End represent the
+					//beginning of the selection shape atoms, while cur is the one we are testing.
+					var activeStartIndex:int = begElementIndex;
+					var activeEndIndex:int = begElementIndex;
+					var curElementIndex:int = begElementIndex;
+					
+					//when activeEndIsBidi no longer matches the bidi setting for the activeStartIndex, we will create the shape
+					var activeEndIsBidi:Boolean = begIsBidi;
+					
+					do
+					{
+						//increment the index
+						curIdx += incrementor;
+						//get the next atom index
+						curElementIndex = textLine.getAtomIndexAtCharIndex(curIdx);
+						
+						//calculate the bidi level for the - kinda cludgy, but if the bidi-text wraps, curElementIndex == -1
+						//so just set it to false if this is the case.  It will get ignored in the subsequent check and curIdx
+						//will == endIdx as this is the last glyph in the line - which is why the next is -1 - gak 09.12.08
+						var curIsBidi:Boolean = (curElementIndex != -1) ? isAtomBidi(curElementIndex, direction) : false;
+							
+						if(curElementIndex != -1 && curIsBidi != activeEndIsBidi)
+						{
+							blockRect = makeBlock(activeStartIndex, activeEndIndex, startMetrics, blockProgression, direction, heightAndAdj);
+							blockArray.push(blockRect);
+							
+							//shift the activeStart/End indexes to the current
+							activeStartIndex = curElementIndex;
+							activeEndIndex = curElementIndex;
+							//update the bidi setting
+							activeEndIsBidi = curIsBidi;
+						}
+						else
+						{
+							//we don't get another chance to make a block, so if this is the last char, make the block before we bail out.
+							//we have to check both equality and equality plus the incrementor because if we don't, then we'll miss a
+							//character in the selection.
+							if(curIdx == endIdx)
+							{
+								blockRect = makeBlock(activeStartIndex, activeEndIndex, startMetrics, blockProgression, direction, heightAndAdj);
+								blockArray.push(blockRect);
+							}
+							
+							activeEndIndex = curElementIndex;
+						}
+					}while(curIdx < endIdx)
+					
+				}
+				else
+				{
+					var testILG:InlineGraphicElement = startElem as InlineGraphicElement;
+					if(!testILG || testILG.float == Float.NONE)
+					{
+						blockRect = makeBlock(begElementIndex, endElementIndex, startMetrics, blockProgression, direction, heightAndAdj);
+					}
+					else
+					{
+						blockRect = testILG.graphic.getBounds(textLine);
+					}
+					
+					blockArray.push(blockRect);
+				}
+				
+			}
+			
+			return blockArray;
+		 }	
+		 
+		/** @private 
+		 * 
+		 * 
+		 */
+		 private function makeBlock(begElementIndex:int, endElementIndex:int, startMetrics:Rectangle, blockProgression:String, direction:String, heightAndAdj:Array):Rectangle
+		 {
+		 	var blockRect:Rectangle = new Rectangle();
+			var globalStart:Point = new Point(0,0);
+			var heightAndAdj:Array;
+			
+			if(begElementIndex > endElementIndex)
+			{
+				// swap the start and end
+				var tempEndIdx:int = endElementIndex;
+				endElementIndex = begElementIndex;
+				begElementIndex = tempEndIdx;
+			}
+			var textLine:TextLine = getTextLine(true);
+			
+			//now that we have elements and they are in the right order for drawing, get their rectangles
+			var begCharRect:Rectangle = textLine.getAtomBounds(begElementIndex);
+			//trace(makeBlockPassCounter + ") begCharRect = " + begCharRect.toString());
+			
+			var endCharRect:Rectangle = textLine.getAtomBounds(endElementIndex);
+			//trace(makeBlockPassCounter + ") endCharRect = " + endCharRect.toString());
+			
+			//Calculate the justificationRule value
+			var justRule:String = _para.getEffectiveJustificationRule();
+			//If this is TTB text and NOT TCY, as indicated by TextRotation.rotate0...
+			if(blockProgression == BlockProgression.RL && textLine.getAtomTextRotation(begElementIndex) != TextRotation.ROTATE_0)
+			{
+				globalStart.y = begCharRect.y;
+				blockRect.height = begElementIndex != endElementIndex ? endCharRect.bottom - begCharRect.top : begCharRect.height;
+				
+				//re-ordered this code.  EAST_ASIAN is more common in vertical and should be the first option.
+				if(justRule == JustificationRule.EAST_ASIAN)
+				{
+					blockRect.width = begCharRect.width;
+				}
+				else
+				{
+					blockRect.width = heightAndAdj[0];
+					globalStart.x -= heightAndAdj[1];
+				}
+			}
+			else
+			{
+				//given bidi text alternations, the endCharRect could be left of the begCharRect,
+				//use whichever is farther left.
+				globalStart.x = (begCharRect.x < endCharRect.x ? begCharRect.x : endCharRect.x);
+				//if we're here and the BlockProgression is TTB, then we're TCY.  Less frequent case, so make non-TCY
+				//the first option...
+				//NB - Never use baseline adjustments for TCY.  They don't make sense here.(I think) - gak 06.03.08
+				if(blockProgression == BlockProgression.RL)
+					globalStart.y = begCharRect.y + (startMetrics.width /2); // TODO-9/5/8:Behavior for leading down TBD
+				
+				
+				if(justRule != JustificationRule.EAST_ASIAN)
+				{
+					blockRect.height = heightAndAdj[0];
+					if(blockProgression == BlockProgression.RL)
+						globalStart.x -= heightAndAdj[1];
+					else 
+						globalStart.y += heightAndAdj[1];
+					//changed the width from a default of 2 to use the begCharRect.width so that point seletion
+					//can choose to use the right or left side of the glyph when drawing a caret Watson 1876415/1876953- gak 08.19.09
+					blockRect.width = begElementIndex != endElementIndex ? Math.abs(endCharRect.right - begCharRect.left) : begCharRect.width;
+				}
+				else
+				{
+					blockRect.height =  begCharRect.height;
+						
+					//changed the width from a default of 2 to use the begCharRect.width so that point seletion
+					//can choose to use the right or left side of the glyph when drawing a caret Watson 1876415/1876953- gak 08.19.09
+					blockRect.width = begElementIndex != endElementIndex ? Math.abs(endCharRect.right - begCharRect.left) : begCharRect.width;
+				}
+			}
+			
+			blockRect.x = globalStart.x;
+			blockRect.y = globalStart.y;
+			if(blockProgression == BlockProgression.RL)
+			{
+				if(textLine.getAtomTextRotation(begElementIndex) != TextRotation.ROTATE_0)
+					blockRect.x -= textLine.descent;
+				else //it's TCY
+					blockRect.y -= (blockRect.height / 2)
+			}
+			else
+			{
+				blockRect.y += (textLine.descent - blockRect.height);
+			}
+			
+			var tfl:TextFlowLine = textLine.userData as TextFlowLine;
+			var curElem:FlowLeafElement = _para.findLeaf(textLine.textBlockBeginIndex + begElementIndex);
+			var rotation:String = curElem.computedFormat.textRotation;
+			
+			//handle rotation.  For horizontal text, rotations of 90 or 180 cause the text
+			//to draw under the baseline in a cosistent location.  Vertical text is a bit more complicated
+			//in that a 90 rotation puts it immediately to the left of the Em Box, whereas 180 is one quarter
+			//of the way in the Em Box. Fix for Watson 1915930 - gak 02.17.09
+			if(rotation == TextRotation.ROTATE_180 || 
+				rotation == TextRotation.ROTATE_90)
+			{
+				if(blockProgression != BlockProgression.RL)
+					blockRect.y += (blockRect.height / 2);
+				else
+				{
+					if(curElem.getParentByType(TCYElement) == null)
+					{	
+						if(rotation == TextRotation.ROTATE_90)
+							blockRect.x -= blockRect.width;
+						else
+							blockRect.x -= (blockRect.width * .75);
+					}
+					else
+					{
+						if(rotation == TextRotation.ROTATE_90)
+							blockRect.y += blockRect.height;
+						else
+							blockRect.y += (blockRect.height * .75);
+					}
+				}
+			}
+			
+			
+			return blockRect;
+		 }
+		 
+		/** @private
+		 * 
+		 * 
+		 */
+		tlf_internal function convertLineRectToContainer(rect:Rectangle, constrainShape:Boolean):void
+		{
+			var textLine:TextLine = getTextLine();
+			
+			/* var globalStart:Point = new Point(rect.x, rect.y);
+
+		 	//convert to controller coordinates...
+			////trace(makeBlockPassCounter + ") globalStart = " + globalStart.toString());
+			globalStart = textLine.localToGlobal(globalStart);
+			////trace(makeBlockPassCounter + ") localToGlobal.globalStart = " + globalStart.toString());
+			globalStart = container.globalToLocal(globalStart);
+			////trace(makeBlockPassCounter + ") globalToLocal.globalStart = " + globalStart.toString());
+			rect.x = globalStart.x;
+			rect.y = globalStart.y; */
+			
+			// this is much simpler and actually more accurate - localToGlobal/globalToLocal does some rounding
+			rect.x += textLine.x;
+			rect.y += textLine.y;
+			
+			if (constrainShape)
+			{
+				var tf:TextFlow = _para.getTextFlow();
+				var columnRect:Rectangle = controller.columnState.getColumnAt(this.columnIndex);
+				constrainRectToColumn(tf,rect,columnRect,controller.horizontalScrollPosition,controller.verticalScrollPosition,controller.compositionWidth,controller.compositionHeight);
+			}
+		}
+		
+		/** @private */
+		static tlf_internal function constrainRectToColumn(tf:TextFlow,rect:Rectangle,columnRect:Rectangle,hScrollPos:Number,vScrollPos:Number,compositionWidth:Number,compositionHeight:Number):void
+		{		
+			if(tf.computedFormat.lineBreak == LineBreak.EXPLICIT)
+				return;
+					
+			var bp:String = tf.computedFormat.blockProgression;
+			var direction:String = tf.computedFormat.direction;
+
+			if(bp == BlockProgression.TB && !isNaN(compositionWidth))
+			{	
+				if(direction == Direction.LTR)
+				{
+					//make sure is doesn't go past the end of the container
+					if(rect.left > (columnRect.x + columnRect.width + hScrollPos))
+						rect.left = (columnRect.x + columnRect.width + hScrollPos);
+					
+					//make sure that if this is a selection and not a point selection, that 
+					//we don't go beyond the end of the container...
+					if(rect.right > (columnRect.x + columnRect.width + hScrollPos))
+						rect.right = (columnRect.x + columnRect.width + hScrollPos);
+				}
+				else
+				{
+					if(rect.right < (columnRect.x + hScrollPos))
+						rect.right = (columnRect.x + hScrollPos);
+						
+					if(rect.left < (columnRect.x + hScrollPos))
+						rect.left = (columnRect.x + hScrollPos);
+				}
+			}
+			else if (bp == BlockProgression.RL && !isNaN(compositionHeight))
+			{
+				if(direction == Direction.LTR)
+				{
+					//make sure is doesn't go past the end of the container
+					if(rect.top > (columnRect.y + columnRect.height + vScrollPos))
+						rect.top = (columnRect.y + columnRect.height + vScrollPos);
+					
+					//make sure that if this is a selection and not a point selection, that 
+					//we don't go beyond the end of the container...
+					if(rect.bottom > (columnRect.y + columnRect.height + vScrollPos))
+						rect.bottom = (columnRect.y + columnRect.height + vScrollPos);
+				}
+				else
+				{
+					if(rect.bottom < (columnRect.y + vScrollPos))
+						rect.bottom = (columnRect.y + vScrollPos);
+						
+					if(rect.top < (columnRect.y + vScrollPos))
+						rect.top = (columnRect.y + vScrollPos);
+				}
+			}
+		}
+		 
+		/** @private
+		 * Helper method to hilight the portion of a block selection on this TextLine.  A selection display is created and added to the line's TextFrame with ContainerController addSelectionShape.
+		 * @param begIdx absolute index of start of selection on this line.
+		 * @param endIdx absolute index of end of selection on this line.
+		 */
+		tlf_internal function hiliteBlockSelection(selObj:Shape, selFormat:SelectionFormat, container:DisplayObject, begIdx:int,endIdx:int, prevLine:TextFlowLine, nextLine:TextFlowLine):void
+		{
+			// no container for overflow lines, or lines scrolled out 
+			if (isDamaged() || !_controller)
+				return;
+
+			// CONFIG::debug { assert(_textLineCache != null, "bad call to hiliteBlockSelection"); }
+	
+			var textLine:TextLine = peekTextLine();
+			if (!textLine || !textLine.parent)
+				return;
+								
+			var paraStart:int = _para.getAbsoluteStart();
+			begIdx -= paraStart;
+			endIdx -= paraStart;
+			
+			createSelectionShapes(selObj, selFormat, container, begIdx, endIdx, prevLine, nextLine);
+		} 
+		
+		/** @private
+		 * Helper method to hilight a point selection on this TextLine.  x,y,w,h of the selection are calculated and ContainerController.drawPointSelection is called 
+		 * @param idx absolute index of the point selection.
+		 */
+		tlf_internal function hilitePointSelection(selFormat:SelectionFormat, idx:int, container:DisplayObject, prevLine:TextFlowLine, nextLine:TextFlowLine):void
+		{
+			var rect:Rectangle = computePointSelectionRectangle(idx,container,prevLine,nextLine, true);
+			if (rect)
+				_controller.drawPointSelection(selFormat, rect.x, rect.y, rect.width, rect.height)
+		}
+		
+		static private function setRectangleValues(rect:Rectangle,x:Number,y:Number,width:Number,height:Number):void
+		{
+			rect.x = x;
+			rect.y = y;
+			rect.width = width;
+			rect.height = height;
+		}
+		/** @private */		
+		tlf_internal function computePointSelectionRectangle(idx:int, container:DisplayObject, prevLine:TextFlowLine, nextLine:TextFlowLine, constrainSelRect:Boolean):Rectangle
+		{
+			if (isDamaged() || !_controller)
+				return null;
+
+			// CONFIG::debug { assert(_textLineCache != null, "bad call to hiliteBlockSelection"); }
+	
+			// no container for overflow lines, or lines scrolled out 
+			var textLine:TextLine = peekTextLine();
+			if (!textLine || !textLine.parent)
+				return null;			
+			// adjust to this paragraph's TextBlock
+			idx -= _para.getAbsoluteStart();
+
+			textLine = getTextLine(true);
+			
+			//endIdx will only differ if idx is altered when detecting TCY bounds
+			var endIdx:int = idx;
+			var elementIndex:int = textLine.getAtomIndexAtCharIndex(idx);
+			CONFIG::debug{ assert(elementIndex != -1, "Invalid point selection index! idx = " + idx); }
+			
+			var isTCYBounds:Boolean = false;
+			var paraLeadingTCY:Boolean = false;
+			
+			var contElement:ContainerFormattedElement = _para.getAncestorWithContainer();
+			CONFIG::debug { assert(contElement != null,"para with no container"); }
+			var blockProgression:String = contElement.computedFormat.blockProgression;
+			var direction:String = _para.computedFormat.direction;
+			
+			//need to check for TCY.  TCY cannot take input into it's head, but can in it's tail.
+			if(blockProgression == BlockProgression.RL)
+			{
+				if (idx == 0)
+				{ 
+					if(textLine.getAtomTextRotation(0) == TextRotation.ROTATE_0)
+						paraLeadingTCY = true;
+				}
+				else
+				{
+					var prevElementIndex:int = textLine.getAtomIndexAtCharIndex(idx - 1);
+					if(prevElementIndex != -1)
+					{
+						//if this elem is TCY, then we need to back up one space and use the right bounds
+						if(textLine.getAtomTextRotation(elementIndex) == TextRotation.ROTATE_0 && 
+							textLine.getAtomTextRotation(prevElementIndex) != TextRotation.ROTATE_0)
+						{
+							elementIndex = prevElementIndex;
+							--idx;
+							isTCYBounds = true;
+						}
+						else if(textLine.getAtomTextRotation(prevElementIndex) == TextRotation.ROTATE_0)
+						{
+							elementIndex = prevElementIndex;
+							--idx;
+							isTCYBounds = true;
+						}
+					}
+				}
+			}
+			
+			var heightAndAdj:Array = getRomanSelectionHeightAndVerticalAdjustment(prevLine, nextLine);
+			var blockRectArray:Array = makeSelectionBlocks(idx, endIdx, _para.getAbsoluteStart(), blockProgression, direction, heightAndAdj);
+			CONFIG::debug{ assert(blockRectArray.length == 1, "A point selection should return a single selection rectangle!"); }
+			var rect:Rectangle = blockRectArray[0];
+			
+			convertLineRectToContainer(rect, constrainSelRect);
+			
+			var drawOnRight:Boolean = (direction == Direction.RTL);
+				
+			if((drawOnRight && textLine.getAtomBidiLevel(elementIndex) % 2 == 0) || 
+				(!drawOnRight && textLine.getAtomBidiLevel(elementIndex) % 2 != 0))
+			{
+				drawOnRight = !drawOnRight;
+			}
+			
+			if(blockProgression == BlockProgression.RL && textLine.getAtomTextRotation(elementIndex) != TextRotation.ROTATE_0)
+			{
+				if(!drawOnRight)
+					setRectangleValues(rect, rect.x, !isTCYBounds ? rect.y : rect.y + rect.height,rect.width,1);
+				else
+					setRectangleValues(rect, rect.x, !isTCYBounds ? rect.y + rect.height : rect.y ,rect.width,1);
+			}
+			else
+			{
+				//choose to use the right or left side of the glyph based on Direction when drawing a caret Watson 1876415/1876953
+				//if the direction is ltr, then the cursor should be on the left side
+				if(!drawOnRight)
+					setRectangleValues(rect, !isTCYBounds ? rect.x : rect.x + rect.width, rect.y, 1, rect.height);
+				else //otherwise, it should be on the right, unless it is TCY
+					setRectangleValues(rect, !isTCYBounds ? rect.x + rect.width : rect.x, rect.y, 1, rect.height);
+			}
+				
+			//allow the atoms to be garbage collected.
+			textLine.flushAtomData();
+			
+			return rect;
+  		}
+  		
+  		/** @private
+  		 * Three states.  Disjoint(0), Intersects(1), HeightContainedIn(2),  
+  		 */
+  		 
+  		tlf_internal function selectionWillIntersectScrollRect(scrollRect:Rectangle, begIdx:int, endIdx:int, prevLine:TextFlowLine, nextLine:TextFlowLine):int
+  		{
+  			var contElement:ContainerFormattedElement = _para.getAncestorWithContainer();
+			CONFIG::debug { assert(contElement != null,"para with no container"); }
+			var blockProgression:String = contElement.computedFormat.blockProgression;
+			var textLine:TextLine = getTextLine(true);
+			
+  			if (begIdx == endIdx)
+  			{
+  				var pointSelRect:Rectangle = computePointSelectionRectangle(begIdx, DisplayObject(controller.container), prevLine, nextLine, false);
+  				if (pointSelRect)
+  				{
+  					if (scrollRect.containsRect(pointSelRect))
+  						return 2;
+	  				if (scrollRect.intersects(pointSelRect))
+	  					return 1;
+	  			}
+  			}
+  			else
+  			{
+				var paraStart:int = _para.getAbsoluteStart();
+  				var selCache:SelectionCache = this.getSelectionShapesCacheEntry(begIdx-paraStart,endIdx-paraStart,prevLine,nextLine,blockProgression);
+  				if (selCache)
+  				{
+  					//iterate the blocks and check for intersections
+					var drawRect:Rectangle;
+					for each (drawRect in selCache.selectionBlocks)
+					{
+						drawRect = drawRect.clone();
+						// convertLineRectToContainer(container, drawRect);
+						drawRect.x += textLine.x; 
+						drawRect.y += textLine.y; 
+						if (scrollRect.intersects(drawRect))
+						{
+							if(blockProgression == BlockProgression.RL)
+							{
+								// see if width is entirely contained in scrollRect
+								if (drawRect.left >= scrollRect.left && drawRect.right <= scrollRect.right)
+									return 2;
+							}
+							else
+							{
+								if (drawRect.top >= scrollRect.top && drawRect.bottom <= scrollRect.bottom)
+									return 2;
+							}
+							return 1;
+						}
+					}
+  				}
+  			}
+  			return 0;
+  		}
+  		
+
+		/** @private */
+		CONFIG::debug private static function dumpAttribute(result:String, attributeName:String, attributeValue:Object):String
+		{
+			if (attributeValue)
+			{
+				result += " ";
+				result += attributeName;
+				result += "=\"";
+				result += attributeValue.toString();
+				result += "\""	
+			}
+			return result;		
+		}
+		
+		/** @private
+		 */
+		private function normalizeRects(srcRects:Array, dstRects:Array, largestRise:Number, blockProgression:String, direction:String):void
+		{
+			//the last rectangle in the list with a potential to merge
+			var lastRect:Rectangle = null;
+			var rectIter:int = 0;
+			while(rectIter < srcRects.length)
+			{
+				//get the current rect and advance the iterator
+				var rect:Rectangle = srcRects[rectIter++];
+				
+				//apply a new height if needed.
+				if(blockProgression == BlockProgression.RL)
+				{
+					if(rect.width < largestRise)
+					{
+						rect.width = largestRise;
+					}
+				}
+				else
+				{
+					if(rect.height < largestRise)
+					{
+						rect.height = largestRise;
+					}
+				}
+				//if the lastRect is null, no need to perform calculation
+				if(lastRect == null)
+				{
+					lastRect = rect;
+				}
+				else
+				{
+					//TCY has already been excluded, so no need to worry about it here...
+					if(blockProgression == BlockProgression.RL)
+					{
+						//trace(normalCounter + ") lastRect = " + lastRect.toString());
+						//trace(normalCounter + ") rect = " + rect.toString());
+						
+						//merge it in to the last rect
+						if(lastRect.y < rect.y && (lastRect.y + lastRect.height) >= rect.top && lastRect.x == rect.x)
+						{
+							lastRect.height += rect.height;
+						}
+						else if(rect.y < lastRect.y && lastRect.y <= rect.bottom && lastRect.x == rect.x)
+						{
+							lastRect.height += rect.height;
+							lastRect.y = rect.y;
+						}
+						else
+						{
+							//we have a break in the rectangles and should push last rect onto the draw list before continuing
+							dstRects.push(lastRect);
+							lastRect = rect;
+						}
+					}
+					else
+					{
+						if(lastRect.x < rect.x && (lastRect.x + lastRect.width) >= rect.left && lastRect.y == rect.y)
+						{
+							lastRect.width += rect.width;
+						}
+						else if(rect.x < lastRect.x && lastRect.x <= rect.right && lastRect.y == rect.y)
+						{
+							lastRect.width += rect.width;
+							lastRect.x = rect.x;
+						}
+						else
+						{
+							//we have a break in the rectangles and should push last rect onto the draw list before continuing
+							dstRects.push(lastRect);
+							lastRect = rect;
+						}
+					}
+				}
+				//if this is the last rectangle, we haven't added it, do so now.
+				if(rectIter == srcRects.length)
+					dstRects.push(lastRect);
+			}
+		}
+		
+		/** @private */
+		private function adjustEndElementForBidi(begIdx:int, endIdx:int, begElementIndex:int, direction:String):int
+		{
+			var endElementIndex:int = begElementIndex;
+			
+			var textLine:TextLine = getTextLine(true);
+			
+			if(endIdx != begIdx)
+			{
+				if(((direction == Direction.LTR && textLine.getAtomBidiLevel(begElementIndex)%2 != 0)
+					|| (direction == Direction.RTL && textLine.getAtomBidiLevel(begElementIndex)%2 == 0))
+					&& textLine.getAtomTextRotation(begElementIndex) != TextRotation.ROTATE_0)
+					endElementIndex = textLine.getAtomIndexAtCharIndex(endIdx);
+				else
+				{
+					endElementIndex = textLine.getAtomIndexAtCharIndex(endIdx - 1);
+				}
+			}
+			
+			if(endElementIndex == -1 && endIdx > 0)
+			{
+				return adjustEndElementForBidi(begIdx, endIdx - 1, begElementIndex, direction);
+			}
+			return endElementIndex;
+		}
+		
+		/** @private */
+		private function isAtomBidi(elementIdx:int, direction:String):Boolean
+		{
+			var textLine:TextLine = getTextLine(true);
+			
+			return (textLine.getAtomBidiLevel(elementIdx)%2 != 0 && direction == Direction.LTR) || (textLine.getAtomBidiLevel(elementIdx)%2 == 0 && direction == Direction.RTL);
+		}
+		
+		/** @private */
+		tlf_internal function get adornCount():int 
+		{ return _adornCount; }
+		
+		/** @private */
+		CONFIG::debug public function dumpToXML():String
+		{
+			var result:String = new String("<line");
+		
+			result = dumpAttribute(result, "absoluteStart", absoluteStart);
+			result = dumpAttribute(result, "textLength", textLength);
+			result = dumpAttribute(result, "height", height);
+			result = dumpAttribute(result, "spaceBefore", spaceBefore);
+
+			result = dumpAttribute(result, "spaceAfter", spaceAfter);
+			result = dumpAttribute(result, "location", location);
+			result = dumpAttribute(result, "x", x);
+			result = dumpAttribute(result, "y", y);
+			result = dumpAttribute(result, "targetWidth", targetWidth);
+			result = dumpAttribute(result, "lineOffset", _lineOffset);
+			result += ">\n";
+			
+			
+			var textLine:TextLine = getTextLine(true);
+			
+			result += "<TextBlock>";
+			result += textLine.textBlock.dump(); 
+			result += "</TextBlock>";
+			result += "<TextLine>"
+			result += textLine.dump();
+			result += "</TextLine>"
+			
+			result += "</line>";
+			return result;
+		}
+		
+	};
+}
+
+import flash.geom.Rectangle;
+
+import flashx.textLayout.edit.ISelectionManager;
+
+/** @private - I would have defined this as tlf_internal, but that is not an option, so
+ * making it private.
+ * 
+ * The SelectionCache is a structure designed to hold a few key data points needed to quickly
+ * reconstruct a selection on a line:
+ * 
+ * a) the beginning and end indicies of the selection on the line
+ * b) the regular selection rectangles
+ * c) the irregular selection rectangles, such as TCY selection rects in vertical text
+ * 
+ **/
+final class SelectionCache
+{
+	private var _begIdx:int = -1;
+	private var _endIdx:int = -1;
+	
+	private var _selectionBlocks:Array = null;
+	
+	public function SelectionCache()
+	{
+	}
+	
+	public function get begIdx():int 
+	{ return _begIdx; }
+	public function set begIdx(val:int):void	
+	{ _begIdx = val; }
+	
+	public function get endIdx():int 
+	{ return _endIdx; }
+	public function set endIdx(val:int):void	
+	{ _endIdx = val; }
+	
+	public function pushSelectionBlock(drawRect:Rectangle):void 
+	{
+		if(!_selectionBlocks)
+			_selectionBlocks = new Array();
+			
+		_selectionBlocks.push(drawRect.clone());
+	}
+	
+	public function get selectionBlocks():Array 
+	{ return _selectionBlocks; }
+	
+	
+	public function clear():void
+	{
+		_selectionBlocks = null;
+		_begIdx = -1;
+		_endIdx = -1;
+	}
+	
+}
diff --git a/textLayout_core/src/flashx/textLayout/compose/TextFlowLineLocation.as b/textLayout_core/src/flashx/textLayout/compose/TextFlowLineLocation.as
new file mode 100755
index 0000000..60e96e5
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/compose/TextFlowLineLocation.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 flashx.textLayout.compose
+{	
+	/** 
+	 * The TextFlowLineLocation class is an enumeration class that defines constants for specifying the location
+	 * of a line within a paragraph.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 *
+	 * @see ParagraphElement
+	 * @see TextFlow
+	 */
+	 
+	public final class TextFlowLineLocation
+	{ 
+		/** Specifies the first line in a paragraph. 
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public static const FIRST:uint = 1;
+		
+		/** Specifies a middle line in a paragraph - neither the first nor the last line. 
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public static const MIDDLE:uint = 2;
+		
+		/** Specifies the last line in a paragraph.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public static const LAST:uint = 4;
+		
+		/** Specifies both the first and last lines in a paragraph.
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public static const ONLY:uint = 5;
+	};
+}
diff --git a/textLayout_core/src/flashx/textLayout/compose/TextLineRecycler.as b/textLayout_core/src/flashx/textLayout/compose/TextLineRecycler.as
new file mode 100755
index 0000000..2b9f118
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/compose/TextLineRecycler.as
@@ -0,0 +1,129 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{	
+	import flash.text.engine.TextLine;
+	import flash.text.engine.TextLineValidity;
+	import flash.utils.Dictionary;
+	
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.Configuration;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+	
+	/** 
+	 * The TextLineRecycler class provides support for recycling of TextLines.  Some player versions support a recreateTextLine.  Passing TextLines
+	 * to the recycler makes them available for reuse.  This improves Player performance.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */ 
+	public class TextLineRecycler
+	{
+		static private var _textLineRecyclerEnabled:Boolean = Configuration.playerEnablesArgoFeatures;
+		
+		/** Controls if the TLF recycler enabled.   It can only be enabled in 10.1 or later players.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		static public function get textLineRecyclerEnabled():Boolean
+		{ return _textLineRecyclerEnabled; }
+		static public function set textLineRecyclerEnabled(value:Boolean):void
+		{ _textLineRecyclerEnabled = value ? Configuration.playerEnablesArgoFeatures : false; }
+		
+		// manage a cache of TextLine's that can be reused
+		// This version uses a dictionary that holds the TextLines as weak references
+		static private var reusableLineCache:Dictionary = new Dictionary(true);
+		
+		/**
+		 * Add a TextLine to the pool for reuse. TextLines for reuse should have null userData and null parent. 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+
+		static public function addLineForReuse(textLine:TextLine):void
+		{
+			CONFIG::debug { assert(textLine.parent == null && textLine.userData == null && (textLine.validity == TextLineValidity.INVALID || textLine.validity == TextLineValidity.STATIC),"textLine not ready for reuse"); }
+			if (_textLineRecyclerEnabled)
+			{
+				CONFIG::debug 
+				{
+					for each (var line:TextLine in reusableLineCache)
+					{
+						 assert(line != textLine,"READDING LINE TO CACHE");
+					}
+				}
+				CONFIG::debug { cacheTotal++; }
+				reusableLineCache[textLine] = null;
+			}
+		} 
+		CONFIG::debug
+		{
+			/** @private */
+			static tlf_internal var cacheTotal:int = 0;
+			/** @private */
+			static tlf_internal var fetchTotal:int = 0;
+			/** @private */
+			static tlf_internal var hitTotal:int = 0;		
+			
+			static private function recordFetch(hit:int):void
+			{
+				fetchTotal++;
+				hitTotal += hit;
+				
+				/*if ((fetchTotal%100) == 0)
+					trace(fetchTotal,hitTotal,cacheTotal);*/
+			}
+		}
+		
+		/**
+		 * Return a TextLine from the pool for reuse. 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+
+		static public function getLineForReuse():TextLine
+		{
+			if (_textLineRecyclerEnabled)
+			{
+				for (var obj:Object in reusableLineCache)
+				{
+					// remove from the cache
+					delete reusableLineCache[obj];
+					CONFIG::debug { assert(reusableLineCache[obj] === undefined,"Bad delete"); }
+					CONFIG::debug { recordFetch(1); }
+					return obj as TextLine;
+				}
+				CONFIG::debug { recordFetch(0); }
+			}
+			return null;
+		}
+		
+		/** @private empty the reusableLineCache */
+		static tlf_internal function emptyReusableLineCache():void
+		{
+			reusableLineCache = new Dictionary(true);
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/compose/VerticalJustifier.as b/textLayout_core/src/flashx/textLayout/compose/VerticalJustifier.as
new file mode 100755
index 0000000..7b59ee6
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/compose/VerticalJustifier.as
@@ -0,0 +1,303 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.formats.VerticalAlign;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+	
+	/** @private
+	 * Adjust line positions according to verticalAlign settings.  Vertical alignment is perpendicular
+	 * to the linebreak direction.
+	 */
+	public final class VerticalJustifier
+	{
+		[ ArrayElementType("text.IVerticalJustificationLine") ] 
+		/** Vertical justify the subset of lines from startIndext to startIndex to numLines according to the rule specified by verticalAlignAttr.  
+		 * The assumption is that they are all the lines in a single column of cont. 
+		 * @see text.formats.VerticalAlign
+		 * */
+		static public function applyVerticalAlignmentToColumn(cont:ContainerController, verticalAlignAttr:String, lines:Array, startIndex:int, numLines:int):void
+		{
+			// TODO: This function doesn't work if there are any tables.
+			
+			var helper:IVerticalAdjustmentHelper;
+			if (cont.rootElement.computedFormat.blockProgression == BlockProgression.RL)
+				helper = new RL_VJHelper(ContainerController(cont));
+			else
+				helper = new TB_VJHelper(ContainerController(cont));
+				
+			CONFIG::debug { assert(startIndex + numLines <= lines.length && numLines > 0,"applyVerticalAlignmentToColumn: bad indices"); }
+									
+			var i:int;
+			
+			switch(verticalAlignAttr) 
+			{
+				case VerticalAlign.MIDDLE:
+					helper.computeMiddleAdjustment(lines[(startIndex + numLines) - 1]);
+					for (i = startIndex; i < startIndex + numLines; i++)
+						helper.applyMiddleAdjustment(lines[i]);
+					break;
+				case VerticalAlign.BOTTOM:
+					helper.computeBottomAdjustment(lines[(startIndex + numLines) - 1]);
+					for (i = startIndex; i < startIndex + numLines; i++)
+						helper.applyBottomAdjustment(lines[i]);
+					break;
+				case VerticalAlign.JUSTIFY:
+					helper.computeJustifyAdjustment(lines, startIndex, numLines);
+					helper.applyJustifyAdjustment(lines, startIndex, numLines);
+					break;
+			}
+
+			//for (i = startIndex; i < startIndex + numLines; i++)
+			//	trace("x=", sc[i].x, "y=", sc[i].y, "yAdj=", yAdj);
+		}
+	}
+}
+import flash.text.engine.TextLine;
+import flashx.textLayout.compose.IVerticalJustificationLine;
+import flashx.textLayout.container.ContainerController;
+import flashx.textLayout.compose.TextFlowLine;
+import flashx.textLayout.compose.TextFlowLine;
+
+
+interface IVerticalAdjustmentHelper
+{
+	function computeMiddleAdjustment(lastLine:IVerticalJustificationLine):void;
+	function applyMiddleAdjustment(line:IVerticalJustificationLine):void;
+	
+	function computeBottomAdjustment(lastLine:IVerticalJustificationLine):void;
+	function applyBottomAdjustment(line:IVerticalJustificationLine):void;
+	
+	function computeJustifyAdjustment(lineArray:Array, firstLine:int, numLines:int):void;
+	function applyJustifyAdjustment(lineArray:Array, firstLine:int, numLines:int):void;
+}
+
+class TB_VJHelper implements IVerticalAdjustmentHelper
+{
+	import flashx.textLayout.tlf_internal;	
+	use namespace tlf_internal;
+	
+	private var _textFrame:ContainerController;
+	private var adj:Number;
+	
+	public function TB_VJHelper(tf:ContainerController):void
+	{
+		_textFrame = tf;
+	}
+	
+	private function getBottomOfLine(line:IVerticalJustificationLine):Number
+	{
+		return getBaseline(line) + line.descent;
+	}
+	
+	private function getBaseline(line:IVerticalJustificationLine):Number
+	{
+		if (line is TextFlowLine)
+			return line.y + line.ascent;
+		else
+			return line.y;
+	}
+	
+	private function setBaseline(line:IVerticalJustificationLine, pos:Number):void
+	{
+		if (line is TextFlowLine)
+			line.y = pos - line.ascent;
+		else
+			line.y = pos;
+	}
+	
+	// half of the available adjustment added to each y to shift the lines half way down the frame
+	public function computeMiddleAdjustment(lastLine:IVerticalJustificationLine):void
+	{
+		var frameBottom:Number = _textFrame.compositionHeight - Number(_textFrame.effectivePaddingBottom);
+		adj = (frameBottom - getBottomOfLine(lastLine)) / 2;
+		if (adj < 0)
+			adj = 0; // no space available to redistribute
+	}
+	public function applyMiddleAdjustment(line:IVerticalJustificationLine):void
+	{
+		line.y = line.y + adj;
+	}
+	
+	// the baseline of the last line should be at the bottom of the frame - paddingBottom.
+	public function computeBottomAdjustment(lastLine:IVerticalJustificationLine):void
+	{
+		var frameBottom:Number = _textFrame.compositionHeight - Number(_textFrame.effectivePaddingBottom);
+		adj = frameBottom - getBottomOfLine(lastLine);
+		if (adj < 0)
+			adj = 0; // no space available to redistribute
+	}
+	public function applyBottomAdjustment(line:IVerticalJustificationLine):void
+	{
+		line.y = line.y + adj;
+	}
+	
+	// one line: untouched, two lines: first line untouched and descent of last line at the bottom of the frame, 
+	// and more than two lines: line spacing increased proportionally, with first line untouched and descent of last line at the bottom of the frame
+	[ ArrayElementType("text.compose.IVerticalJustificationLine") ]
+	public function computeJustifyAdjustment(lineArray:Array, firstLineIndex:int, numLines:int):void
+	{
+		adj = 0;
+		
+		if (numLines == 1)
+			return;	// do nothing
+			
+		// first line unchanged	
+		var firstLine:IVerticalJustificationLine = lineArray[firstLineIndex];
+		var firstBaseLine:Number =  getBaseline(firstLine);
+
+		// descent of the last line on the bottom of the frame	
+		var lastLine:IVerticalJustificationLine = lineArray[firstLineIndex + numLines - 1];
+		var frameBottom:Number = _textFrame.compositionHeight - Number(_textFrame.effectivePaddingBottom);
+		var allowance:Number = frameBottom - getBottomOfLine(lastLine);
+		if (allowance < 0)
+			return; // Some text scrolled out; don't justify
+		var lastBaseLine:Number = getBaseline(lastLine); 
+	
+		adj = allowance/(lastBaseLine - firstBaseLine); // multiplicative factor by which the space between consecutive lines is increased 
+	}
+	
+	[ ArrayElementType("text.compose.IVerticalJustificationLine") ]
+	public function applyJustifyAdjustment(lineArray:Array, firstLineIndex:int, numLines:int):void
+	{ 
+		if (numLines == 1 || adj == 0)
+			return;	// do nothing
+			
+		var firstLine:IVerticalJustificationLine = lineArray[firstLineIndex];
+		var prevBaseLine:Number = getBaseline(firstLine);
+		var prevBaseLineUnjustified:Number = prevBaseLine;
+		
+		var line:IVerticalJustificationLine;
+		var currBaseLine:Number;
+		var currBaseLineUnjustified:Number;
+		
+		for (var i:int = 1; i < numLines; i++)
+		{
+			line = lineArray[i + firstLineIndex];
+			currBaseLineUnjustified = getBaseline(line);
+			
+			// Space between consecutive baselines scaled up by the calculated factor
+			currBaseLine = prevBaseLine  + (currBaseLineUnjustified - prevBaseLineUnjustified)*(1 + adj);
+			setBaseline(line, currBaseLine);
+			
+			prevBaseLineUnjustified = currBaseLineUnjustified;
+			prevBaseLine = currBaseLine;
+		}
+	}
+}
+
+class RL_VJHelper implements IVerticalAdjustmentHelper
+{
+	import flashx.textLayout.tlf_internal;	
+	use namespace tlf_internal;
+
+	private var _textFrame:ContainerController;
+	private var adj:Number = 0;
+	
+	public function RL_VJHelper(tf:ContainerController):void
+	{
+		_textFrame = tf;
+	}
+	
+	// half of the available adjustment added to each x to shift the lines half way left across the frame
+	public function computeMiddleAdjustment(lastTextLine:IVerticalJustificationLine):void
+	{
+		// ignore paddingRight its already offset
+		var frameWidth:Number = _textFrame.compositionWidth-Number(_textFrame.effectivePaddingLeft);
+		adj = (frameWidth + lastTextLine.x - lastTextLine.descent) / 2;
+		if (adj < 0)
+			adj = 0; // no space available to redistribute
+	}
+	public function applyMiddleAdjustment(line:IVerticalJustificationLine):void
+	{
+		line.x = (line.x - adj);
+	}
+	
+	// the baseline of the last line should be at the bottom of the frame - paddingLeft.
+	public function computeBottomAdjustment(lastTextLine:IVerticalJustificationLine):void
+	{
+		var frameWidth:Number = _textFrame.compositionWidth-Number(_textFrame.effectivePaddingLeft);
+		adj = frameWidth + lastTextLine.x - lastTextLine.descent;
+		if (adj < 0)
+			adj = 0; // no space available to redistribute
+	}
+	public function applyBottomAdjustment(line:IVerticalJustificationLine):void
+	{
+		line.x = (line.x - adj);
+	}
+	
+	// one line: untouched, two lines: first line untouched and descent of last line at the bottom of the frame, 
+	// and more than two lines: line spacing increased proportionally, with first line untouched and descent of last line at the bottom of the frame
+	[ ArrayElementType("text.compose.IVerticalJustificationLine") ]
+	public function computeJustifyAdjustment(lineArray:Array, firstLineIndex:int, numLines:int):void
+	{ 
+		adj = 0;
+		
+		if (numLines == 1)
+			return;	// do nothing
+			
+		// first line unchanged
+		var firstLine:IVerticalJustificationLine = lineArray[firstLineIndex];
+		var firstBaseLine:Number =  firstLine.x;
+		
+		// descent of the last line on the left of the frame	
+		var lastLine:IVerticalJustificationLine = lineArray[firstLineIndex + numLines - 1];
+		var frameLeft:Number =  Number(_textFrame.effectivePaddingLeft) - _textFrame.compositionWidth;
+		var allowance:Number = (lastLine.x - lastLine.descent) - frameLeft;
+		if (allowance < 0)
+			return; // Some text scrolled out; don't justify
+		var lastBaseLine:Number = lastLine.x;  
+		
+		adj = allowance/(firstBaseLine - lastBaseLine);  // multiplicative factor by which the space between consecutive lines is increased 
+	}
+	
+	[ ArrayElementType("text.IVerticalJustificationLine") ]
+	public function applyJustifyAdjustment(lineArray:Array, firstLineIndex:int, numLines:int):void
+	{
+		if (numLines == 1 || adj == 0)
+			return;	// do nothing
+			
+		var firstLine:IVerticalJustificationLine = lineArray[firstLineIndex];
+		var prevBaseLine:Number = firstLine.x;
+		var prevBaseLineUnjustified:Number = prevBaseLine;
+		
+		var line:IVerticalJustificationLine;
+		var currBaseLine:Number;
+		var currBaseLineUnjustified:Number;
+		
+		for (var i:int = 1; i < numLines; i++)
+		{
+			line = lineArray[i + firstLineIndex];
+			currBaseLineUnjustified = line.x;
+			
+			// Space between consecutive baselines scaled up by the calculated factor
+			currBaseLine = prevBaseLine - (prevBaseLineUnjustified - currBaseLineUnjustified)*(1 + adj);
+			line.x = currBaseLine;
+			
+			prevBaseLineUnjustified = currBaseLineUnjustified;
+			prevBaseLine = currBaseLine;
+		}		
+	}
+	
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/container/ColumnState.as b/textLayout_core/src/flashx/textLayout/container/ColumnState.as
new file mode 100755
index 0000000..6e982ef
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/container/ColumnState.as
@@ -0,0 +1,392 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.container
+{
+	import flash.geom.Rectangle;
+	
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.formats.Direction;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.LineBreak;
+	import flashx.textLayout.tlf_internal;
+		
+	use namespace tlf_internal;
+
+	/** 
+	 * The ColumnState class calculates the sizes and locations of columns using
+	 * the width of the container and the container attributes. You can create instances of this class 
+	 * independently to calculate column values, or you can get the column values that 
+	 * were used for the text after the container has been composed or updated (redrawn).
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 *
+	 * @see ContainerController
+	 */
+
+	public class ColumnState 
+	{
+		// input information
+		private var _inputsChanged:Boolean;
+		private var _blockProgression:String;
+		private var _columnDirection:String;
+		private var _paddingTop:Number;
+		private var _paddingBottom:Number;
+		private var _paddingLeft:Number;
+		private var _paddingRight:Number;
+		private var _compositionWidth:Number;
+		private var _compositionHeight:Number;
+		private var _forceSingleColumn:Boolean;
+		
+		private var _inputColumnWidth:Object;
+		private var _inputColumnGap:Number;
+		private var _inputColumnCount:Object
+		
+		// Generated column information		
+		private var _columnWidth:Number;	
+		private var _columnCount:int;		
+		private var _columnGap:Number;	
+		private var _inset:Number;
+		
+		// and the array of columns
+		private var _columnArray:Array;
+		private var _singleColumn:Rectangle;
+		
+		/**
+		 * Constructor function - creates a ColumnState object.
+		 *
+		 * If the values of <code>controller.compositionWidth</code> and <code>controller.compositionHeight</code> equal
+		 * <code>NaN</code> (not a number), the constructor measures the container's contents to determine the actual 
+		 * composition width and height that feed into ColumnState.
+		 *
+		 * Use the constants defined by the <code>flashx.textLayout.formats.BlockProgression</code> class to 
+		 * specify the value of the <code>blockProgression</code> parameter. Use the constants defined by
+		 * <code>flashx.textLayout.formats.Direction</code> to specify the value of the <code>columnDirection</code> 
+		 * parameter.
+		 *
+		 * @param blockProgression The direction of lines for the textflow, either BlockProgression.TB (top-to-bottom) or 
+		 * 		BlockProgression.RL (right-to-left).
+		 * @param columnDirection The direction of column layout for the text flow, either Direction.RTL (right-to-left) or 
+		 * 		Direction.LTR (left-to-right).
+		 * @param controller A ContainerController instance whose attributes are used to calculate the column values.
+		 * @param compositionWidth The horizontal extent, in pixels, allowed for text inside the container.
+		 * @param compositionHeight The vertical extent, in pixels, allowed for text inside the container.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * 
+		 * @see flashx.textLayout.formats.BlockProgression BlockProgression
+		 * @see flashx.textLayout.formats.Direction Direction
+	 	 */
+		
+		public function ColumnState(blockProgression:String, columnDirection:String, controller:ContainerController, compositionWidth:Number, compositionHeight:Number)
+		{
+			_inputsChanged = true;
+			_columnCount = 0;
+
+			if (blockProgression != null)		// if values are legit, recalculate now. They might not be, if this is called from a containerController constructor.
+			{		
+				updateInputs(blockProgression, columnDirection, controller, compositionWidth, compositionHeight);
+				computeColumns();
+			}
+		}
+		
+		/** 
+		 * The width of columns, in pixels, in the container. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public function get columnWidth():Number
+		{ return _columnWidth; }
+
+		/** 
+		 * The number of columns in the container. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public function get columnCount():int
+		{ return _columnCount; }
+
+		/** 
+		 * The amount of space, in pixels, left between columns in the container.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public function get columnGap():Number
+		{ return _columnGap; }
+		
+		/** 
+		 * Returns the area that a column takes within the container. Allows you to access the area for a 
+		 * specific column.
+		 *
+		 * @param index The relative position of the column among all columns in the container, with the first
+		 * 	column at position 0.
+		 *
+		 * @return The area of the specified column.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		 
+		public function getColumnAt(index:int):Rectangle
+		{
+			return _columnCount == 1 ? _singleColumn : _columnArray[index];
+		}
+
+		/** Recalculate actual column settings based on attributes and width
+		 * from the container. Call this after either the attributes or the
+		 * width has been changed to get the new values.
+		 *
+		 * @param newBlockProgression block progression for the textflow
+		 * @param newColumnDirection column layout direction for the textflow
+		 * @param containerAttr		Formatting attributes from the container
+		 * @param containerWidth		Width of the container
+		 * @return Boolean			true if the actual column settings have changed
+		 * @private 
+		 */
+		tlf_internal function updateInputs(newBlockProgression:String, newColumnDirection:String, controller:ContainerController, newCompositionWidth:Number, newCompositionHeight:Number ):void
+		{
+			var newPaddingTop:Number = controller.effectivePaddingTop;
+			var newPaddingBottom:Number = controller.effectivePaddingBottom;
+			var newPaddingLeft:Number = controller.effectivePaddingLeft;
+			var newPaddingRight:Number = controller.effectivePaddingRight;
+			
+			var containerAttr:ITextLayoutFormat = controller.computedFormat;
+			
+			var newColumnWidth:Object = containerAttr.columnWidth;
+			var newColumnGap:Number = containerAttr.columnGap;
+			var newColumnCount:Object = containerAttr.columnCount;;
+			
+			var newForceSingleColumn:Boolean = ((containerAttr.columnCount == FormatValue.AUTO && (containerAttr.columnWidth == FormatValue.AUTO || Number(containerAttr.columnWidth) == 0)) ||
+				controller.rootElement.computedFormat.lineBreak == LineBreak.EXPLICIT)
+			
+			if (_inputsChanged == false) 
+				_inputsChanged = newCompositionWidth != _compositionHeight || newCompositionHeight != _compositionHeight
+				|| _paddingTop != newPaddingTop || _paddingBottom != newPaddingBottom || _paddingLeft != newPaddingLeft || _paddingRight != newPaddingRight
+				|| _blockProgression != _blockProgression || _columnDirection != newColumnDirection || _forceSingleColumn != newForceSingleColumn
+				|| _inputColumnWidth != newColumnWidth || _inputColumnGap != newColumnGap || _inputColumnCount != newColumnCount;
+				
+			if (_inputsChanged)
+			{
+				_blockProgression = newBlockProgression;
+				_columnDirection = newColumnDirection;
+				_paddingTop = newPaddingTop;
+				_paddingBottom = newPaddingBottom;
+				_paddingLeft = newPaddingLeft;
+				_paddingRight = newPaddingRight;
+				_compositionWidth = newCompositionWidth;
+				_compositionHeight = newCompositionHeight;
+				_forceSingleColumn = newForceSingleColumn;
+				
+				_inputColumnWidth = newColumnWidth;
+				_inputColumnGap = newColumnGap;
+				_inputColumnCount = newColumnCount;
+			}
+		}
+
+		/** Compute the actual columns based on the input values @private */
+		tlf_internal function computeColumns():void
+		{
+			if (!_inputsChanged)
+				return;
+				
+			// Recalculate all the column settings. Returns true if settings have changed as a result.
+			// See http://www.w3.org/TR/2005/WD-css3-multicol-20051215/#the-number
+			var newColumnGap:Number;
+			var newColumnCount:int;
+			var newColumnWidth:Number;
+			
+			// calculate the width to divy the columns up among
+			var totalColumnWidth:Number = _blockProgression == BlockProgression.RL ? _compositionHeight : _compositionWidth;
+			// inset to use
+			var newColumnInset:Number   = _blockProgression == BlockProgression.RL ? _paddingTop + _paddingBottom : _paddingLeft + _paddingRight;
+				
+			totalColumnWidth = (totalColumnWidth > newColumnInset && !isNaN(totalColumnWidth)) ? totalColumnWidth - newColumnInset : 0;
+			
+			// columnCount is auto && columnWidth is auto || 0 --> one column
+			if (_forceSingleColumn)
+			{
+				// This case deviates from the spec.  Spec is no columns.  
+				// TextLayout does either one auto full width column or a zero width column
+				newColumnCount = 1;
+				newColumnWidth = totalColumnWidth; 
+				newColumnGap = 0;
+			}
+			else
+			{
+				newColumnGap   = _inputColumnGap;
+				
+				if (_inputColumnWidth == FormatValue.AUTO)		// auto
+				{
+					newColumnCount = Number(_inputColumnCount);
+					// Column width is not specified, we'll use columnCount and columnGap to figure it out
+					if ((newColumnCount-1)*newColumnGap < totalColumnWidth)
+					{
+						newColumnWidth = (totalColumnWidth - (newColumnCount-1)*newColumnGap) / newColumnCount;
+					}
+					else if (newColumnGap > totalColumnWidth)
+					{
+						newColumnCount = 1;
+						newColumnWidth = totalColumnWidth;
+						newColumnGap = 0;
+					}
+					else
+					{
+						newColumnCount = Math.floor(totalColumnWidth/newColumnGap);
+						newColumnWidth = (totalColumnWidth-(newColumnCount-1)*newColumnGap)/newColumnCount;
+						// newColumnGap = newColumnCount == 1 ? 0 : (totalColumnWidth - newColumnWidth*newColumnCount) / (newColumnCount-1);
+					}
+				}
+				else if (_inputColumnCount == FormatValue.AUTO)	// auto
+				{
+					newColumnWidth = Number(_inputColumnWidth);
+					if (newColumnWidth >= totalColumnWidth)
+					{
+						newColumnCount = 1;
+						newColumnWidth = totalColumnWidth;
+						newColumnGap   = 0;
+					}
+					else
+					{
+						newColumnCount = Math.floor((totalColumnWidth+newColumnGap)/(newColumnWidth+newColumnGap));
+						newColumnWidth = ((totalColumnWidth+newColumnGap)/newColumnCount) - newColumnGap;
+					}
+				}
+				else
+				{
+					newColumnCount = Number(_inputColumnCount);
+					newColumnWidth = Number(_inputColumnWidth);
+					if (newColumnCount*newColumnWidth+(newColumnCount-1)*newColumnGap <= totalColumnWidth)
+					{
+						// done
+					}
+					else if (newColumnWidth >= totalColumnWidth)
+					{
+						newColumnCount = 1;
+						newColumnGap = 0;
+						// use newColumnWidth
+					}
+					else
+					{
+						newColumnCount = Math.floor( (totalColumnWidth+newColumnGap) / (newColumnWidth+newColumnGap) );
+						newColumnWidth = ((totalColumnWidth+newColumnGap) / newColumnCount) - newColumnGap;
+					}
+				}
+			}
+				
+			_columnWidth = newColumnWidth;
+			_columnCount = newColumnCount;
+			_columnGap = newColumnGap;
+			_inset = newColumnInset;			
+	
+			// setup these values for each case
+			var xPos:Number;
+			var yPos:Number;
+			var delX:Number;
+			var delY:Number;
+			var colH:Number;
+			var colW:Number;
+			
+			// scratch vars
+			var insetHeight:Number;
+			
+			// TODO: USE DIRECTION!!!
+			if (_blockProgression == BlockProgression.TB)
+			{
+				if (_columnDirection == Direction.LTR)
+				{
+					xPos = _paddingLeft;
+					delX = _columnWidth + _columnGap;
+					colW = _columnWidth;
+				}
+				else
+				{
+					CONFIG::debug { assert(_columnDirection == Direction.RTL,"bad columndirection in ColumnState.computeColumns"); }
+					xPos = isNaN(_compositionWidth) ? 0 : _compositionWidth-_paddingRight-_columnWidth;
+					delX = -(_columnWidth + _columnGap);
+					colW = _columnWidth;
+				}
+				yPos = _paddingTop;
+				delY = 0;
+				insetHeight = _paddingTop + _paddingBottom;
+				colH = (_compositionHeight > insetHeight && !isNaN(_compositionHeight)) ? (_compositionHeight - insetHeight) : 0;
+			}
+			else if (_blockProgression == BlockProgression.RL)
+			{
+				xPos = isNaN(_compositionWidth) ? -_paddingRight : _paddingLeft -_compositionWidth;
+				yPos = _paddingTop;
+				delX = 0;
+				delY = _columnWidth + _columnGap;
+				insetHeight = _paddingLeft + _paddingRight;
+				colW = (_compositionWidth > insetHeight) ? (_compositionWidth - insetHeight) : 0;
+				colH = _columnWidth;
+			}
+			
+			// make colW and colH just off zero so that we don't get empties
+			if (colW == 0)
+			{
+				colW = .001;
+				if (_blockProgression == BlockProgression.RL)
+					xPos -= colW;
+			}
+			if (colH == 0)
+				colH = .001;
+			
+			if (_columnCount == 1)
+			{
+				_singleColumn = new Rectangle(xPos, yPos, colW, colH);
+				_columnArray = null;
+			}
+			else if (_columnCount == 0)
+			{
+				_singleColumn = null;
+				_columnArray = null;
+			}
+			else
+			{
+				if (_columnArray)
+					_columnArray.splice(0);
+				else
+					_columnArray = new Array();
+				for (var i:int = 0; i < _columnCount; ++i)
+				{
+					_columnArray.push(new Rectangle(xPos, yPos, colW, colH));
+					xPos += delX;
+					yPos += delY;
+				}
+			}	
+		}
+	}
+		
+
+} // end package
diff --git a/textLayout_core/src/flashx/textLayout/container/ContainerController.as b/textLayout_core/src/flashx/textLayout/container/ContainerController.as
new file mode 100755
index 0000000..b3a34b5
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/container/ContainerController.as
@@ -0,0 +1,3389 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.container 
+{
+	import flash.display.BlendMode;
+	import flash.display.DisplayObject;
+	import flash.display.DisplayObjectContainer;
+	import flash.display.InteractiveObject;
+	import flash.display.Shape;
+	import flash.display.Sprite;
+	import flash.events.ContextMenuEvent;
+	import flash.events.Event;
+	import flash.events.FocusEvent;
+	import flash.events.IMEEvent;
+	import flash.events.KeyboardEvent;
+	import flash.events.MouseEvent;
+	import flash.events.TextEvent;
+	import flash.events.TimerEvent;
+	import flash.geom.Point;
+	import flash.geom.Rectangle;
+	import flash.text.engine.TextLine;
+	import flash.text.engine.TextLineValidity;
+	import flash.ui.ContextMenu;
+	import flash.ui.ContextMenuClipboardItems;
+	import flash.utils.Timer;
+	
+	import flashx.textLayout.compose.FlowDamageType;
+	import flashx.textLayout.compose.IFlowComposer;
+	import flashx.textLayout.compose.TextFlowLine;
+	import flashx.textLayout.compose.TextLineRecycler;
+	import flashx.textLayout.debug.Debugging;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.edit.EditingMode;
+	import flashx.textLayout.edit.IInteractionEventHandler;
+	import flashx.textLayout.edit.ISelectionManager;
+	import flashx.textLayout.edit.SelectionFormat;
+	import flashx.textLayout.elements.BackgroundManager;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.FlowValueHolder;
+	import flashx.textLayout.elements.InlineGraphicElement;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.events.TextLayoutEvent;
+	import flashx.textLayout.events.UpdateCompleteEvent;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.formats.Float;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormatValueHolder;
+	import flashx.textLayout.property.Property;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+		
+	/** 
+	 * The  ContainerController class defines the relationship between a TextFlow object and a container.
+	 * A TextFlow may have one or more rectangular areas that can hold text; the text is said to be flowing
+	 * through the containers. Each container is a Sprite that is the parent DisplayObject for the TextLines.
+	 * Each container has a ContainerController that manages the container; the controller holds the target 
+	 * width and height for the text area, populates the container with TextLines, and handles scrolling. A
+	 * controller also has a format associated with it that allows some formatting attributes to be applied 
+	 * to the text in the container. This allows, for instance, a TextFlow to have one container where the
+	 * text appears in a single column, and a second container in the same TextFlow with two column text. Not
+	 * all formatting attributes that can be applied to the container will affect the text; only the ones that
+	 * affect container-level layout. The diagram below illustrates the relationship between the TextFlow,
+	 * its flowComposer, and the display list.
+	 *
+	 * <p><img src="../../../images/textLayout_multiController.gif" alt="IContainerController"></img></p>
+	 *
+	 * @includeExample examples\ContainerControllerExample1.as -noswf
+	 * @includeExample examples\ContainerControllerExample2.as -noswf
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 *
+	 * @see flashx.textLayout.compose.IFlowComposer
+	 * @see flashx.textLayout.elements.TextFlow
+	 * @see flashx.textLayout.container.TextContainerController
+	 */
+	public class ContainerController implements IInteractionEventHandler, ITextLayoutFormat, ISandboxSupport
+	{		
+		private var _textFlowCache:TextFlow;
+		private var _rootElement:ContainerFormattedElement;
+		
+		private var _absoluteStart:int;
+		private var _textLength:int;
+		
+		private var _container:Sprite;
+		
+		// note must be protected - subclass sets or gets this variable but can't be public
+		/** computed container attributes.  @private */
+		protected var _computedFormat:ITextLayoutFormat;
+		
+		// Generated column information
+		// Generated column information
+		private var _columnState:ColumnState;
+		
+		/** Container size to be composed */
+		private var _compositionWidth:Number = 0;
+		private var _compositionHeight:Number = 0;
+		private var _measureWidth:Boolean; // true if we're measuring (isNaN(compositionWidth) optimization so we don't call isNaN too much
+		private var _measureHeight:Boolean; // true if we're measuring (isNaN(compositionHeight) optimization so we don't call isNaN too much
+		
+		/* Text bounds after composition */
+		private var _contentLeft:Number;
+		private var _contentTop:Number;
+		private var _contentWidth:Number;
+		private var _contentHeight:Number;
+		
+		private var _composeCompleteRatio:Number;	// 1 if composition was complete when contentHeight, etc registered, greater than one otherwise
+
+		// Scroll policy -- determines whether scrolling is enabled or not
+		private var _horizontalScrollPolicy:String;
+		private var _verticalScrollPolicy:String;
+		
+		// x, y location of the text in the container relative to the underlying scrollable area
+		private var _xScroll:Number;
+		private var _yScroll:Number;
+		
+		/** Are event listeners attached to the container */
+		private var _minListenersAttached:Boolean = false;
+		private var _allListenersAttached:Boolean = false;
+		private var _selectListenersAttached:Boolean = false;
+		
+		/** @private */
+		tlf_internal function get allListenersAttached():Boolean
+		{ return _allListenersAttached; }
+	
+		/** Are the displayed shapes out of date? */
+		private var _shapesInvalid:Boolean = false;
+
+		private var _backgroundShape:Shape;
+		
+		private var _scrollTimer:Timer = null;
+		
+		/**
+		 * @private use this boolean to determine if container.scrollRect is set.  Accessing scrollRect when null changes the rendering behavior of flash player.	
+		*/
+		protected var _hasScrollRect:Boolean;
+		
+		/** 
+		 * @private
+		 * 
+		 * <p>This property enables a client to test for a ScrollRect object without accessing 
+		 * the DisplayObject.scrollRect property, which can have side effects in some cases.</p> 
+		 *
+		 * @return true if the controller has attached a ScrollRect instance.
+		 */
+		tlf_internal function get hasScrollRect():Boolean
+		{ return _hasScrollRect; }
+		
+		CONFIG::debug
+		{
+			protected var id:String;
+			private static var contCount:int = 0;
+		}
+		
+		private var _shapeChildren:Array;
+
+		private var _formatValueHolder:FlowValueHolder;
+		
+		private var _containerRoot:DisplayObject;
+		
+		/* Controller have a non-zero default width and height so that if you construct a text example with a container and don't
+		 * specify width and height you will still see some text so that you can then have a clue what to do to correct its appearance.
+		 */
+		 
+		/** 
+		 * Constructor - creates a ContainerController instance. The ContainerController has a default <code>compositionWidth</code>
+		 * and <code>compositionHeight</code> so that some text appears in the container if you don't specify its width
+		 * height.
+		 *
+		 * @param container The DisplayObjectContainer in which to manage the text lines.
+		 * @param compositionWidth The initial width for composing text in the container.
+		 * @param compositionHeight The initial height for composing text in the container.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		 
+		public function ContainerController(container:Sprite,compositionWidth:Number=100,compositionHeight:Number=100)
+		{
+			initialize(container,compositionWidth,compositionHeight);
+		}
+		
+		private function initialize(container:Sprite,compositionWidth:Number,compositionHeight:Number):void
+		{
+			_container = container;
+			_containerRoot =  null;
+			
+			_textLength = 0;
+			_absoluteStart = -1;
+		
+			_columnState = new ColumnState(null/*blockProgression*/, null/*columnDirection*/, null/*controller*/, 0/*compositionWidth*/, 0/*compositionHeight*/);
+			//_visibleRect = new Rectangle();
+			_xScroll = _yScroll = 0;
+			_contentWidth = _contentHeight = 0;
+			_composeCompleteRatio = 1;
+
+			// We have to set the flag so that we will get double click events. This
+			// is a change to the container we are given, but a minor one.
+			if (_container is InteractiveObject)
+				InteractiveObject(_container).doubleClickEnabled = true;
+
+			_horizontalScrollPolicy = _verticalScrollPolicy = String(ScrollPolicy.scrollPolicyPropertyDefinition.defaultValue);
+			_hasScrollRect = false;
+
+			CONFIG::debug { id = contCount.toString(); ++contCount; }
+
+			_shapeChildren = [ ];
+			
+			setCompositionSize(compositionWidth, compositionHeight);
+			format = _containerControllerInitialFormat;
+		}
+
+		/** @private */
+		tlf_internal function get effectiveBlockProgression():String
+		{
+			return _rootElement ? _rootElement.computedFormat.blockProgression : BlockProgression.TB;
+		}
+		
+		/** @private  Determine containerRoot in case the stage is not accessible. Normally the root is the stage. */
+		tlf_internal function getContainerRoot():DisplayObject
+		{
+			// safe to test for stage existence
+			if (_containerRoot == null && _container && _container.stage)
+			{
+				// if the stage is accessible lets use it.
+				// trace("BEFORE COMPUTING CONTAINERROOT");
+				try
+				{
+					var x:int = _container.stage.numChildren;
+					_containerRoot = _container.stage;
+				}
+				catch(e:Error)
+				{
+					// TODO: some way to find the highest level accessible root???
+					_containerRoot = _container.root;
+				}
+				// trace("AFTER COMPUTING CONTAINERROOT");
+			}
+			return _containerRoot;
+		}
+		
+		/** 
+		 * Returns the flow composer object that composes and highlights text into the container that this 
+		 * controller manages. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 * 
+	 	 * @see flashx.textLayout.compose.IFlowComposer
+	 	 */
+
+		public function get flowComposer():IFlowComposer
+		{ return textFlow ? textFlow.flowComposer : null; }
+		
+		/** @private */
+		tlf_internal function get shapesInvalid():Boolean
+		{ return _shapesInvalid; }
+		/** @private */
+		tlf_internal function set shapesInvalid(val:Boolean):void
+		{ _shapesInvalid = val;	}
+		
+		/** 
+		 * Returns a ColumnState object, which describes the number and characteristics of columns in
+		 * the container. These values are updated when the text is recomposed, either as a result
+		 * of <code>IFlowComposer.compose()</code> or <code>IFlowComposer.updateAllControllers()</code>.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see ColumnState
+	 	 */
+		 
+		public function get columnState():ColumnState
+		{
+			if (_rootElement == null)
+				return null;
+			
+			if (_computedFormat == null)
+				computedFormat;
+				
+			_columnState.computeColumns();
+
+			return _columnState; 
+		}
+		
+		/** 
+		 * Returns the container display object that holds the text lines for this ContainerController instance. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see #ContainerController()
+	 	 */
+	 	 		 
+		public function get container():Sprite
+		{ return _container; }
+		
+		/** 
+		 * Returns the horizontal extent allowed for text inside the container. The value is specified in pixels.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see #setCompositionSize()
+		 */
+		 
+		public function get compositionWidth():Number
+		{ return _compositionWidth; }
+		
+		/** 
+		 * Returns the vertical extent allowed for text inside the container. The value is specified in pixels.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see #setCompositionSize()
+	 	 */
+ 		 
+		public function get compositionHeight():Number
+		{ return _compositionHeight; }
+		
+		/** @private */
+		tlf_internal function get measureWidth():Boolean
+		{ return _measureWidth; }
+				
+		/** @private */
+		tlf_internal function get measureHeight():Boolean
+		{ return _measureHeight; }
+			
+		/** 
+		 * Sets the width and height allowed for text in the container. 
+		 *
+		 * @param w The width in pixels that's available for text in the container.
+		 * @param h The height in pixels that's available for text in the container.
+		 *
+		 * @includeExample examples\ContainerController_setCompositionSizeExample.as -noswf
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		
+		public function setCompositionSize(w:Number,h:Number):void
+		{
+			// note: NaN == NaN is always false
+			var widthChanged:Boolean  =  !(_compositionWidth == w || (isNaN(_compositionWidth) && isNaN(w)));
+			var heightChanged:Boolean =  !(_compositionHeight == h || (isNaN(_compositionHeight) && isNaN(h)));
+			
+			if (widthChanged || heightChanged)
+			{
+				_compositionHeight = h;
+				_measureHeight = isNaN(_compositionHeight);
+				_compositionWidth = w;
+				_measureWidth = isNaN(_compositionWidth);
+				// otherwise the reset will happen when the cascade is done
+				if (_computedFormat)
+					resetColumnState();
+				invalidateContents();
+				attachTransparentBackgroundForHit(false);
+			}
+		}
+		
+		/** 
+		 * Returns the TextFlow object whose content appears in the container. Either the <code>textFlow</code> and  
+		 * <code>rootElement</code> values are the same, or this is the root element's TextFlow object. For example,
+		 * if the container's root element is a DivElement, the value would be the TextFlow object to which the
+		 * DivElement belongs.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 * 
+	 	 * @see flashx.textLayout.elements.TextFlow TextFlow
+	 	 */
+		 
+		public function get textFlow():TextFlow
+		{ 
+			if (!_textFlowCache && _rootElement)
+				_textFlowCache = _rootElement.getTextFlow();
+			return _textFlowCache;
+		}
+		
+		 // Reserve possibility for future use as a ContainerFormattedElement within the TextFlow.
+		 
+		/** 
+		 * Returns the root element that appears in the container. The root element could be a DivElement or TextFlow
+		 * instance, for example.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 * 
+	 	 * @see flashx.textLayout.elements.ContainerFormattedElement
+	 	 * @see flashx.textLayout.elements.DivElement
+	 	 * @see flashx.textLayout.elements.TextFlow
+	 	 */
+		 
+		public function get rootElement():ContainerFormattedElement
+		{ return _rootElement; }
+		
+		/** Protected method used when updating the rootElement. 
+		 * @param value new container to be controlled
+		 * 
+		 * @private
+		 */
+		tlf_internal function setRootElement(value:ContainerFormattedElement):void
+		{
+			if (_rootElement != value)
+			{
+				clearCompositionResults();
+				detachContainer();
+				_rootElement = value;
+				_textFlowCache = null;
+				_textLength = 0;
+				_absoluteStart = -1;
+				attachContainer();
+				if (_rootElement)
+					formatChanged();
+			}
+		}
+
+		/** 
+		 * @copy flashx.textLayout.elements.TextFlow#interactionManager
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * 
+		 * @see flashx.textLayout.elements.TextFlow#interactionManager
+		 */
+		 
+		public function get interactionManager():ISelectionManager
+		{
+			return textFlow ? textFlow.interactionManager : null;
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Start and length
+		//
+		//--------------------------------------------------------------------------
+		
+		/** 
+		 * Returns the first character in the container. If this is not the first container in the flow,
+		 * this value is updated when the text is composed, that is when the IFlowComposer's <code>compose()</code> or 
+ 		 * <code>updateAllControllers()</code> methods are called.
+		 * 
+	 	 * @see flashx.textLayout.compose.IFlowComposer
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		 
+		public function get absoluteStart():int
+		{
+			if (_absoluteStart != -1)
+				return _absoluteStart;
+				
+			var rslt:int = 0;
+			var composer:IFlowComposer = flowComposer;
+			if (composer)
+			{
+				var stopIdx:int = composer.getControllerIndex(this);
+				if (stopIdx != 0)
+				{
+					var prevController:ContainerController = composer.getControllerAt(stopIdx-1);
+					rslt = prevController.absoluteStart + prevController.textLength;
+				}
+			}
+			_absoluteStart = rslt;
+				
+			return rslt;
+		}
+		
+		/** Returns the total number of characters in the container. This can include text that is not currently in view,
+		 * if the container is scrollable. This value is updated when the text is composed (when the IFlowComposer's <code>compose()</code> 
+		 * or <code>updateAllControllers()</code> methods are called).
+		 * 
+	 	 * @see flashx.textLayout.compose.IFlowComposer
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		 
+		public function get textLength():int
+		{
+			return _textLength;
+		}
+		/** @private */
+		tlf_internal function setTextLengthOnly(numChars:int):void
+		{ 
+			if (_textLength != numChars)
+			{
+				_textLength = numChars; 
+				// all following containers must have absoluteStart invalidated
+				if (_absoluteStart != -1)
+				{
+					var composer:IFlowComposer = flowComposer;
+					if (composer)
+					{
+						var idx:int = composer.getControllerIndex(this)+1;
+						while (idx < flowComposer.numControllers)
+						{
+							var controller:ContainerController = composer.getControllerAt(idx++);
+							if (controller._absoluteStart == -1)
+								break;
+							controller._absoluteStart = -1;
+						}
+					}
+				}
+			}
+		}
+		
+		/** @private */
+		tlf_internal function setTextLength(numChars:int):void
+		{
+			CONFIG::debug { assert(numChars >= 0,"bad set textLength"); }
+
+			// If its a scrollable container, and it is the last one, then it gets all the characters even though we might not have composed them all
+			_composeCompleteRatio = 1;
+			if (textFlow)
+			{
+				var verticalText:Boolean = effectiveBlockProgression == BlockProgression.RL;
+				var flowComposer:IFlowComposer = textFlow.flowComposer;
+				if (numChars != 0 && flowComposer.getControllerIndex(this) == flowComposer.numControllers - 1 &&
+					((!verticalText && _verticalScrollPolicy != ScrollPolicy.OFF)||
+					(verticalText && _horizontalScrollPolicy != ScrollPolicy.OFF)))
+				{
+					var containerAbsoluteStart:int = absoluteStart;
+					CONFIG::debug { assert(textFlow.textLength >= containerAbsoluteStart,"ContainerController.setTextLength bad absoluteStart"); }
+					_composeCompleteRatio = (textFlow.textLength-containerAbsoluteStart) / numChars;
+					// _composeCompleteRatio = (textFlow.textLength-containerAbsoluteStart) == numChars ? 1 : 1.1;
+					// var scaledContentHeight:Number = _composeCompleteRatio * _contentHeight;
+					// trace("composeCompleteRatio:",_composeCompleteRatio,"composedContentHeight",_contentHeight,"scaledContentHeight",scaledContentHeight,"textLength",textFlow.textLength,"numChars",numChars);
+					// include all remaining characters in this container when scroll enabled
+					numChars = textFlow.textLength - containerAbsoluteStart;
+				}
+			}
+
+			setTextLengthOnly(numChars); 
+			CONFIG::debug
+			{
+				if (Debugging.debugOn && textFlow)
+					assert(Math.min(textFlow.textLength, absoluteStart)+_textLength <= textFlow.textLength, "container textLength may not extend past end of root element!");
+			}			
+		}
+		
+		/** Updates the text within the container.
+		 * Called after an editing change or composition to keep absoluteStart and textLength up to date.
+		 * @private
+		 */
+		tlf_internal function updateLength(pos:int, lengthToAdd:int):void
+		{
+			CONFIG::debug { assert(_textLength+lengthToAdd >= 0,"bad set textLength"); }
+			setTextLengthOnly(_textLength + lengthToAdd);
+		}
+
+		/** 
+		 * Determines whether the container has text that requires composing. 
+		 *
+		 * @return 	true if the container requires composing.
+		 *
+		 * @includeExample examples\ContainerController_isDamagedExample.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		
+		public function isDamaged():Boolean
+		{
+			return flowComposer.isDamaged(absoluteStart + _textLength);
+		}
+
+		/** called whenever the container attributes are changed.  Mark computed attributes and columnstate as out of date. 
+		 * @private
+		 */
+		tlf_internal function formatChanged():void
+		{
+			// The associated container, if there is one, inherits its container
+			// attributes from here. So we need to tell it that these attributes
+			// have changed.
+			_computedFormat = null;
+			invalidateContents();
+		}
+		
+		/**
+		 *  Removes inlines that should no longer be on the display list and
+		 *  adds inlines that are new to the display list.
+		 *  @private
+		 */
+		 
+		tlf_internal function updateInlineChildren():void
+		{
+		}
+		
+		/** determines the shapechildren in the container and applies VJ. @private */
+		protected function fillShapeChildren(sc:Array,tempSprite:Sprite):void
+		{ 
+			if (_textLength == 0)
+				return;	// none				
+			
+			var wmode:String = effectiveBlockProgression;
+
+			var width:Number = _measureWidth ? _contentWidth : _compositionWidth;
+			var height:Number = _measureHeight ? _contentHeight : _compositionHeight;
+			var scrollAdjustRect:Rectangle;
+			if (wmode == BlockProgression.RL)
+				scrollAdjustRect = new Rectangle(_xScroll - width, _yScroll, width, height);
+			else
+				scrollAdjustRect = new Rectangle(_xScroll, _yScroll, width, height);
+			
+			// If scrolling is turned off, and flow is vertical, then we need to adjust the positions of all the lines. With
+			// scrolling turned on, we don't need to do this because the adjustment is done in the Player when the scrollRect
+			// is set up correctly. But with the scrollRect, we also get clipping, and if scrolling is turned off we want to
+			// have the clipping turned off as well. So in this case we do the adjustment manually so the scrollRect can be null.
+			// NOTE: similar adjustments are made in TextContainerManager
+			var adjustLines:Boolean = (wmode == BlockProgression.RL) &&
+				(_horizontalScrollPolicy == ScrollPolicy.OFF && 
+				_verticalScrollPolicy == ScrollPolicy.OFF);
+				
+			// Iterate over the lines in the container, setting the x and y positions and 
+			// adding them to the list to go into the container. Keep track of the width 
+			// and height of the actual text in the container.
+			var firstLine:int = flowComposer.findLineIndexAtPosition(absoluteStart);
+			var lastLine:int = flowComposer.findLineIndexAtPosition(absoluteStart + _textLength - 1);
+			// Build the list in reverse order and than reverse it at the end.
+			// This fixes bug 2509360 ARGO: Unselectable lines appear while scrolling
+			// new bug filed because this is a small performance hit on the reverse - but this is the safest thing to do late in dev cycle
+			for (var lineIndex:int = firstLine; lineIndex <= lastLine; lineIndex++)
+			{
+				var curLine:TextFlowLine = flowComposer.getLineAt(lineIndex);	
+				if (curLine == null || curLine.controller != this)
+					continue;
+
+				var textLine:TextLine = curLine.createShape(wmode);
+				if (!textLine)
+					continue;
+				
+				CONFIG::debug { assert(textLine == curLine.peekTextLine(),"Bad textLine in fillShapeChildren "+Debugging.getIdentity(textLine)+" "+Debugging.getIdentity(curLine)); }
+					
+				var curBounds:Rectangle = getPlacedTextLineBounds(textLine); 
+				
+				// trace("fillShapeChildren:",lineIndex.toString(),curBounds.toString(),textLine.x.toString(),textLine.y.toString(),scrollRect.toString());
+				if ((wmode == BlockProgression.RL) ? curBounds.x + curBounds.width >= scrollAdjustRect.left && curBounds.x < scrollAdjustRect.x + scrollAdjustRect.width :
+					curBounds.y + curBounds.height >= scrollAdjustRect.top && curBounds.y < scrollAdjustRect.y + scrollAdjustRect.height)	
+				{
+					if (adjustLines)
+					{
+						textLine.x -= scrollAdjustRect.x;
+						textLine.y -= scrollAdjustRect.y;
+					}
+					sc.push(textLine);
+					if (textLine.parent == null)
+						tempSprite.addChild(textLine);
+				}
+			}
+			
+			if (adjustLines)
+			{
+				_contentLeft -= scrollAdjustRect.x;
+				_contentTop  -= scrollAdjustRect.y;
+			}
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Scrolling
+		//
+		//--------------------------------------------------------------------------
+	
+		/** 
+		 * Specifies the horizontal scrolling policy, which you can set by assigning one of the constants of
+		 * the ScrollPolicy class: ON, OFF, or AUTO.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 * 
+	 	 * @see ScrollPolicy
+	 	 */
+	 	 
+		public function get horizontalScrollPolicy():String
+		{
+			return _horizontalScrollPolicy;
+		}
+		public function set horizontalScrollPolicy(scrollPolicy:String):void
+		{
+			var newScrollPolicy:String = ScrollPolicy.scrollPolicyPropertyDefinition.setHelper(_horizontalScrollPolicy, scrollPolicy) as String;
+
+			if (newScrollPolicy != _horizontalScrollPolicy)
+			{
+				_horizontalScrollPolicy = newScrollPolicy;
+				if (_horizontalScrollPolicy == ScrollPolicy.OFF)
+					horizontalScrollPosition = 0;
+				formatChanged();	// scroll policy affects composition
+			}
+		}
+		
+		/** Specifies the vertical scrolling policy, which you can set by assigning one of the constants of the ScrollPolicy
+		 * class: ON, OFF, or, AUTO.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see ScrollPolicy
+		 */
+	 	 
+		public function get verticalScrollPolicy():String
+		{
+			return _verticalScrollPolicy;
+		}
+		public function set verticalScrollPolicy(scrollPolicy:String):void
+		{
+			var newScrollPolicy:String = ScrollPolicy.scrollPolicyPropertyDefinition.setHelper(_verticalScrollPolicy, scrollPolicy) as String;
+			if (newScrollPolicy != _verticalScrollPolicy)
+			{
+				_verticalScrollPolicy = newScrollPolicy;
+				if (_verticalScrollPolicy == ScrollPolicy.OFF)
+					verticalScrollPosition = 0;
+				formatChanged();	// scroll policy affects composition
+			}
+		}
+		
+		/** Specifies the current horizontal scroll location on the stage. The value specifies the number of
+		 * pixels from the left.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+
+		public function get horizontalScrollPosition():Number
+		{
+			return _xScroll;
+		}
+		
+		public function set horizontalScrollPosition(x:Number):void
+		{
+			if (!_rootElement)
+				return;
+				
+			if (_horizontalScrollPolicy == ScrollPolicy.OFF)
+			{
+				_xScroll = 0;
+				return;
+			}
+			var oldScroll:Number = _xScroll;
+			var newScroll:Number = computeHorizontalScrollPosition(x,true);
+			
+			if (newScroll != oldScroll)
+			{	
+				_shapesInvalid = true;
+				_xScroll = newScroll;
+				updateForScroll();
+			}
+		}
+		
+		static private function pinValue(value:Number, minimum:Number, maximum:Number):Number
+		{
+			return Math.min(Math.max(value, minimum), maximum);						
+		}
+		
+		private function computeHorizontalScrollPosition(x:Number,okToCompose:Boolean):Number
+		{
+			var wmode:String = effectiveBlockProgression;
+			var curEstimatedWidth:Number = contentWidth;
+			var newScroll:Number = 0;
+			
+			if (curEstimatedWidth > _compositionWidth && !_measureWidth)
+			{
+				// Pin the lower and upper bounds of _x. If we're doing vertical text, then the right edge is 0 and the left edge is negative
+				// We may not have composed all the way to the indicated position. If not, force composition so that we can be sure we're at
+				// a legal position.
+				if (wmode == BlockProgression.RL)
+				{
+					newScroll = pinValue(x, _contentLeft + _compositionWidth, _contentLeft + curEstimatedWidth);
+					if (okToCompose && _composeCompleteRatio != 1 && newScroll != _xScroll)
+					{
+						// in order to compose have to set _xScroll
+						_xScroll = x;
+						if (_xScroll > _contentLeft + _contentWidth)
+							_xScroll = _contentLeft + _contentWidth;
+						flowComposer.composeToController(flowComposer.getControllerIndex(this));
+						newScroll = pinValue(x, _contentLeft + _compositionWidth, _contentLeft + _contentWidth);
+					}
+				}
+				else
+					newScroll = pinValue(x, _contentLeft, (_contentLeft + curEstimatedWidth) - _compositionWidth);
+			}
+			return newScroll;
+		}
+
+		
+		/** Specifies the current vertical scroll location on the stage. The value specifies the number of 
+		 * pixels from the top.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+
+		public function get verticalScrollPosition():Number
+		{
+			return _yScroll;
+		}
+
+		public function set verticalScrollPosition(y:Number):void
+		{
+			if (!_rootElement)
+				return;
+				
+			if (_verticalScrollPolicy == ScrollPolicy.OFF)
+			{
+				_yScroll = 0;
+				return;
+			}
+			
+			var oldScroll:Number = _yScroll;
+			var newScroll:Number = computeVerticalScrollPosition(y,true);
+			
+			if (newScroll != oldScroll)
+			{			
+				_shapesInvalid = true;
+				_yScroll = newScroll;
+				updateForScroll();
+			}
+		}	
+		
+		private function computeVerticalScrollPosition(y:Number,okToCompose:Boolean):Number
+		{
+			var newScroll:Number = 0;
+			var curcontentHeight:Number = contentHeight;
+			var wmode:String = effectiveBlockProgression;
+			
+			// Only try to scroll if the content height is greater than the composition height, then there is text that is not visible to scroll to
+			if (curcontentHeight > _compositionHeight)
+			{
+				// new scroll value is somewhere between the topmost content, and the top of the last containerfull
+				newScroll = pinValue(y, _contentTop, _contentTop + (curcontentHeight - _compositionHeight));
+
+				// if we're not composed to the end, compose further so we can scroll to it. Sets the scroll position and then 
+				// recomposes the container, which will compose through the end of the screenfull that starts at the requested position.
+				if (okToCompose && _composeCompleteRatio != 1 && wmode == BlockProgression.TB)
+				{
+					_yScroll = y;
+					if (_yScroll < _contentTop)
+						_yScroll = _contentTop;
+					flowComposer.composeToController(flowComposer.getControllerIndex(this));
+					newScroll = pinValue(y, _contentTop, _contentTop + (curcontentHeight - _compositionHeight));
+				}
+			}
+			return newScroll;
+		}
+		
+		/** 
+		 * Returns the area that the text occupies, as reflected by the last compose or update operation. 
+		 * The width and the height might be estimated, if the container is scrollable and the text exceeds the 
+		 * visible area.
+		 * 
+		 * @return describes the area that the text occupies.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @includeExample examples\ContainerController_getContentBoundsExample.as -noswf
+	 	 *
+	 	 * @see flash.geom.Rectangle Rectangle
+	 	 */
+		public function getContentBounds():Rectangle
+		{
+			return new Rectangle(_contentLeft, _contentTop, contentWidth, contentHeight);
+		}
+		
+		/**
+		 * @private
+		 */
+		
+		tlf_internal function get contentLeft():Number
+		{
+			return _contentLeft;
+		}
+		
+		/**
+		 * @private
+		 */
+		
+		tlf_internal function get contentTop():Number
+		{
+			return _contentTop;
+		}
+		
+		/** 
+		 * @private
+		 *
+		 * Returns the vertical extent of the text. For horizontal text, it includes space taken for descenders on the last line. 
+		 * If not all the text is composed, this returns an estimated value based on how much text is already composed; the
+		 * more text that is composed, the more accurate s the estimate. To get a completely accurate value, recompose
+		 * with the rootElement's flowComposer before accessing contentHeight.
+		 * You can get the composed bounds of the text by getting the contentLeft, contentTop, contentWidth, contentHeight properties.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		 
+		tlf_internal function get contentHeight():Number
+		{
+			return (effectiveBlockProgression == BlockProgression.TB) ? _contentHeight * _composeCompleteRatio : _contentHeight;
+		}
+		
+		/** 
+		 * @private
+		 *
+		 * Returns the horizontal extent of the text. For vertical text, it includes space taken for descenders on the last line. 
+		 * If not all the text is composed, this returns an estimated value based on how much text is already composed; the
+		 * more text that is composed, the more accurate is the estimate. To get a completely accurate value, recompose
+		 * with the rootElement's flowComposer before accessing contentWidth.
+		 * You can get the composed bounds of the text by getting the contentLeft, contentTop, contentWidth, contentHeight properties.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		 
+		tlf_internal function get contentWidth():Number
+		{			
+			return (effectiveBlockProgression == BlockProgression.RL) ? _contentWidth * _composeCompleteRatio : _contentWidth;
+		}
+
+		/** @private */
+		tlf_internal function setContentBounds(contentLeft:Number, contentTop:Number, contentWidth:Number, contentHeight:Number):void
+		{
+			_contentWidth = contentWidth;
+			_contentHeight = contentHeight;
+			_contentLeft = contentLeft;
+			_contentTop = contentTop;
+		}
+
+		private function updateForScroll():void
+		{
+			var flowComposer:IFlowComposer = textFlow.flowComposer;
+			flowComposer.updateToController(flowComposer.getControllerIndex(this));
+	
+			attachTransparentBackgroundForHit(false);
+			
+			// notify client that we scrolled.
+			textFlow.dispatchEvent(new TextLayoutEvent(TextLayoutEvent.SCROLL));
+			
+		//	trace("contentHeight", contentHeight, "contentWidth", contentWidth);
+		//	trace("contentHeight", contentHeight, "contentWidth", contentWidth);
+		}
+				
+		/** @private */
+		CONFIG::debug tlf_internal function validateLines():void
+		{
+			if (!Debugging.containerLineValidation)
+				return;
+			
+			var flowComposer:IFlowComposer = textFlow.flowComposer;
+			var textLine:TextLine;
+			
+			/*for (var ii:int = 0; ii < flowComposer.numLines; ii++)
+			{
+				textLine = flowComposer.getLineAt(ii).peekTextLine()
+				trace("    // flowComposer",ii,textLine ? Debugging.getIdentity(textLine) : "null");
+			}*/
+			
+			// find first textline
+			var numContainerChildren:int = _container.numChildren;
+			for (var containerIndex:int = 0; containerIndex < numContainerChildren; containerIndex++)
+			{
+				textLine = _container.getChildAt(containerIndex) as TextLine;
+				if (textLine)
+					break;
+			}	
+			
+			if (textLine == null)
+				return;	// no lines in this container
+
+			var textFlowLine:TextFlowLine;
+			// find the index of the first line
+			for (var flowComposerIndex:int = 0; flowComposerIndex < flowComposer.numLines; flowComposerIndex++)
+			{
+				textFlowLine = flowComposer.getLineAt(flowComposerIndex);
+				if (textFlowLine.peekTextLine() == textLine)
+					break;
+			}
+			
+			assert(flowComposerIndex != flowComposer.numLines,"BAD FIRST LINE IN CONTAINER");
+			
+			while (containerIndex < numContainerChildren)
+			{
+				textLine = _container.getChildAt(containerIndex) as TextLine;
+				if (textLine == null)
+				{
+					// the very last thing can be the selection sprite
+					assert(containerIndex == numContainerChildren-1,"Wrong location for selectionsprite");
+					assert(_container.getChildAt(containerIndex) == getSelectionSprite(false),"expected selectionsprite but not found");
+					break;
+				}
+				textFlowLine = flowComposer.getLineAt(flowComposerIndex);
+				assert(textLine == textFlowLine.peekTextLine(),"BAD TEXTLINE IN TEXTFLOWLINE");
+				containerIndex++;
+				flowComposerIndex++;
+			}
+		}
+		
+		private function get containerScrollRectLeft():Number
+		{
+			var rslt:Number;
+			if (horizontalScrollPolicy == ScrollPolicy.OFF && verticalScrollPolicy == ScrollPolicy.OFF)
+				rslt = 0;
+			else
+				rslt= effectiveBlockProgression == BlockProgression.RL ? horizontalScrollPosition - compositionWidth : horizontalScrollPosition;
+			//CONFIG::debug { assert(container.scrollRect == null && rslt == 0 || int(rslt) == container.scrollRect.left,"Bad containerScrollRectLeft"); }
+			return rslt;
+		}
+		
+		private function get containerScrollRectRight():Number
+		{
+			var rslt:Number = containerScrollRectLeft+compositionWidth;
+			//CONFIG::debug { assert(container.scrollRect == null && rslt == compositionWidth || int(rslt) == container.scrollRect.right,"Bad containerScrollRectRight"); }
+			return rslt;
+		}
+				
+		private function get containerScrollRectTop():Number
+		{
+			var rslt:Number;
+			if (horizontalScrollPolicy == ScrollPolicy.OFF && verticalScrollPolicy == ScrollPolicy.OFF)
+				rslt = 0;
+			else
+				rslt = verticalScrollPosition;;
+			//CONFIG::debug { assert(container.scrollRect == null && rslt == 0 || int(rslt) == container.scrollRect.top,"Bad containerScrollRectTop"); }
+			return rslt;
+		}
+		
+		private function get containerScrollRectBottom():Number
+		{
+			var rslt:Number = containerScrollRectTop+compositionHeight;
+			//CONFIG::debug { assert(container.scrollRect == null && rslt == compositionHeight || int(rslt) == container.scrollRect.bottom,"Bad containerScrollRectBottom"); }
+			return rslt;
+		}
+							
+		/** 
+		 * Scrolls so that the text range is visible in the container.
+		 *
+		 * @param activePosition	The end of the selection that is changed when you extend the selection. It can be
+		 * 	either the start or the end of the selection, expressed as an offset from the start of the text flow.
+		 * @param anchorPosition   	The stable end of the selection when you extend the selection. It can be either 
+		 * 	the start or the end of the selection.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+
+		public function scrollToRange(activePosition:int,anchorPosition:int):void
+		{
+
+			// return if we're not scrolling, or if it's not the last controller
+			if (!_hasScrollRect || !flowComposer || flowComposer.getControllerAt(flowComposer.numControllers-1) != this)
+				return;
+			
+			// clamp values to range absoluteStart,absoluteStart+_textLength
+			var controllerStart:int = absoluteStart;
+			var lastPosition:int = Math.min(controllerStart+_textLength, textFlow.textLength - 1);
+			activePosition = Math.max(controllerStart,Math.min(activePosition,lastPosition));
+			anchorPosition = Math.max(controllerStart,Math.min(anchorPosition,lastPosition));
+								
+			var verticalText:Boolean = effectiveBlockProgression == BlockProgression.RL;
+			var begPos:int = Math.min(activePosition,anchorPosition);
+			var endPos:int = Math.max(activePosition,anchorPosition);
+			
+			// is part of the selection in view?
+			var begLineIndex:int = flowComposer.findLineIndexAtPosition(begPos,(begPos == textFlow.textLength));
+			var endLineIndex:int = flowComposer.findLineIndexAtPosition(endPos,(endPos == textFlow.textLength));
+			
+			// no scrolling if any part of the selection is in view
+			var prevLine:TextFlowLine = begLineIndex == 0 ? null : flowComposer.getLineAt(begLineIndex-1);
+			var currLine:TextFlowLine = flowComposer.getLineAt(begLineIndex);
+			var accumulatedIntersection:int = 0;
+			
+			var scrollRectLeft:Number = containerScrollRectLeft;
+			var scrollRectTop:Number  = containerScrollRectTop;
+			var scrollRectRight:Number = containerScrollRectRight;
+			var scrollRectBottom:Number = containerScrollRectBottom;
+			var scrollRect:Rectangle = new Rectangle(scrollRectLeft, scrollRectTop, scrollRectRight-scrollRectLeft, scrollRectBottom-scrollRectTop);
+			
+			for (var lineIndex:int = begLineIndex; lineIndex <= endLineIndex; lineIndex++)
+			{
+				var nextLine:TextFlowLine = lineIndex+1 == flowComposer.numLines ? null : flowComposer.getLineAt(lineIndex+1);
+				var lineEnd:int = currLine.absoluteStart+currLine.textLength;
+				if (currLine.controller == this)
+				{
+					accumulatedIntersection += currLine.selectionWillIntersectScrollRect(scrollRect,begPos,Math.min(lineEnd,endPos),prevLine,nextLine);
+					if (accumulatedIntersection >= 2)
+						return;	// dont scroll
+				}
+				if (lineIndex == endLineIndex)
+					break;
+				prevLine = currLine;
+				currLine = nextLine;
+				begPos = lineEnd;
+			}
+			
+			var rect:Rectangle = posToRectangle(activePosition);
+			if (!rect)
+			{
+				flowComposer.composeToPosition(activePosition);
+				rect = posToRectangle(activePosition);
+			} 
+			if (rect) 
+			{
+				var firstVisibleLine:TextFlowLine;
+				var lastVisibleLine:TextFlowLine;
+
+				// vertical scroll
+				if (rect.top < scrollRectTop)
+					verticalScrollPosition = rect.top;
+				if (verticalText) {					
+					// horizontal scroll
+					if (rect.left < scrollRectLeft)
+						horizontalScrollPosition = rect.left + _compositionWidth;
+					if (rect.right > scrollRectRight)
+						horizontalScrollPosition = rect.right;
+					// set the rect to the previous character for the test on the bottom of the scrollRect.
+					// Note, when dealing with the "bottommost" character (t-to-b), we actually need to position
+					// pos at pos-1 because pos is looking at the character following the insertion point.
+					// However, we can only look at the previous character if we're not on the first character in
+					// a line.
+					// This tests for pos being the first char on a line. If not, reset rect.
+					if (flowComposer.findLineAtPosition(activePosition).absoluteStart != activePosition)
+						rect = posToRectangle(activePosition-1);
+					// If we're showing a blinking insertion point, we need to scroll far enough that
+					// we can see the insertion point, and it comes just after the character.
+					if (activePosition == anchorPosition)
+						rect.bottom += 2;							
+					// vertical scroll
+					if (rect && rect.bottom > scrollRectBottom)
+						verticalScrollPosition = rect.bottom - _compositionHeight;
+					// now, we need to determine if the scrollRect is full or only partially full.
+					// A partially full scrollRect can happen when you're deleting text at the end of the
+					// container. When that happens, the bottomExtreme line in the scrollRect has space between
+					// it and the left edge of the scrollRect. So, if it's partially full, then we need to scroll
+					// to bring more of the Flow into view.
+					var a:Array = findFirstAndLastVisibleLine();
+					firstVisibleLine = a[0];
+					lastVisibleLine = a[1];
+					if (lastVisibleLine && lastVisibleLine.x - lastVisibleLine.descent - lastVisibleLine.spaceAfter > scrollRectLeft)
+						horizontalScrollPosition = lastVisibleLine.x - lastVisibleLine.descent + _compositionWidth;
+				}
+				else 
+				{
+					// vertical scroll
+					if (rect.bottom > scrollRectBottom)
+						verticalScrollPosition = rect.bottom - _compositionHeight;
+					// horizontal scroll
+					if (rect.left < scrollRectLeft)
+						horizontalScrollPosition = rect.left;
+					// set the rect to the previous character for the test on the right side of the scrollRect.
+					// Note, when dealing with the "rightmost" character (l-to-r), we actually need to position
+					// pos at pos-1 because pos is looking at the character following the insertion point.
+					// However, we can only look at the previous character if we're not on the first character in
+					// a line.
+					// This tests for pos being the first char on a line. If not, reset rect.
+					if (flowComposer.findLineAtPosition(activePosition).absoluteStart != activePosition)
+						rect = posToRectangle(activePosition-1);
+					// If we're showing a blinking insertion point, we need to scroll far enough to see the
+					// insertion point, and it comes up to the right
+					if (activePosition == anchorPosition)
+						rect.right += 2;
+					if (rect && rect.right > scrollRectRight)
+						horizontalScrollPosition = rect.right - _compositionWidth;
+					// now, we need to determine if the scrollRect is full or only partially full.
+					// A partially full scrollRect can happen when you're deleting text at the end of the
+					// container. When that happens, the bottomExtreme line in the scrollRect has space between
+					// it and the bottom edge of the scrollRect. So, if it's partially full, then we need to scroll
+					// to bring more of the Flow into view.
+					var b:Array = findFirstAndLastVisibleLine();
+					firstVisibleLine = b[0];
+					lastVisibleLine = b[1];
+					if (rect.top > scrollRectTop && lastVisibleLine && lastVisibleLine.y + lastVisibleLine.height + lastVisibleLine.spaceAfter < scrollRectBottom)
+						verticalScrollPosition = lastVisibleLine.y + lastVisibleLine.height;
+				}
+			}
+		}		
+
+		private function posToRectangle(pos:int):Rectangle
+		{
+			var line:TextFlowLine = flowComposer.findLineAtPosition(pos);
+			// should the textLine ever be null? It is after some operations -- dunno why (rlw)
+			if (!line.textLineExists || line.isDamaged())
+				return null;
+
+
+			var textLine:TextLine = line.getTextLine(true);
+			var atomBounds:Rectangle;
+			var atomIdx:int = textLine.getAtomIndexAtCharIndex(pos-line.paragraph.getAbsoluteStart());
+			CONFIG::debug { assert(atomIdx > -1, "How'd we get here?"); }
+			if (atomIdx > -1) 
+				atomBounds = textLine.getAtomBounds(atomIdx);
+	
+			// special handling for TCY - no line height adjustments TCY is perpendicular to the height direction
+			if (effectiveBlockProgression == BlockProgression.RL)
+			{
+				var leafElement:FlowLeafElement = _rootElement.getTextFlow().findLeaf(pos);
+				if (leafElement.getParentByType(flashx.textLayout.elements.TCYElement) != null)
+					return new Rectangle(line.x+atomBounds.x+line.y+atomBounds.y+atomBounds.width,atomBounds.height);
+			}
+				
+			return effectiveBlockProgression == BlockProgression.RL ? 
+				new Rectangle(line.x, line.y + atomBounds.y, line.height, atomBounds.height) :
+				new Rectangle(line.x + atomBounds.x, line.y-line.height+line.ascent, atomBounds.width, line.height+textLine.descent);
+
+		}
+		
+		/**
+		 * @private
+		 */
+
+		tlf_internal function resetColumnState():void
+		{
+			if (_rootElement)
+				_columnState.updateInputs(effectiveBlockProgression, _rootElement.computedFormat.direction, this, _compositionWidth, _compositionHeight);
+		}
+		
+		/** 
+		 * Marks all the text in this container as needing composing. 
+		 *
+		 * @includeExample examples\ContainerController_invalidateContentsExample.as -noswf
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 */
+		 
+		public function invalidateContents():void
+		{
+			if (textFlow && _textLength)
+				textFlow.damage(absoluteStart, _textLength, FlowDamageType.GEOMETRY, false);
+		}
+		
+		/** @private */
+		private var _transparentBGX:Number;
+		/** @private */
+		private var _transparentBGY:Number;
+		/** @private */
+		private var _transparentBGWidth:Number;
+		/** @private */
+		private var _transparentBGHeight:Number;
+				
+		/** No mouse clicks or moves will be generated for the container unless it has a background covering its area.  Text Layout Framework
+		 * wants those events so that clicking on a container will select the text in it.  This code
+		 * adds or updates (on size change) that background for Sprite containers only. This may cause clients problems 
+		 * - definitely no hits is a problem - add this code to explore the issues - expect feedback.  
+		 * We may have to make this configurable. @private */
+		
+
+		tlf_internal function attachTransparentBackgroundForHit(justClear:Boolean):void
+		{
+			if (_minListenersAttached && attachTransparentBackground)
+			{
+				var s:Sprite = _container as Sprite;
+				if (s)
+				{
+					if (justClear)
+					{
+						s.graphics.clear();
+						CONFIG::debug { Debugging.traceFTECall(null,s,"clearTransparentBackground()"); }
+						_transparentBGX = _transparentBGY = _transparentBGWidth = _transparentBGHeight = NaN;
+					}
+					else
+					{		
+						var bgwidth:Number = _measureWidth ? _contentWidth : _compositionWidth;
+						var bgheight:Number = _measureHeight ? _contentHeight : _compositionHeight;
+						
+						var adjustHorizontalScroll:Boolean = effectiveBlockProgression == BlockProgression.RL && _horizontalScrollPolicy != ScrollPolicy.OFF;
+						var bgx:Number = adjustHorizontalScroll ? _xScroll - bgwidth : _xScroll;
+						var bgy:Number = _yScroll;
+
+						CONFIG::debug { assert(!isNaN(bgx) && !isNaN(bgy) && !isNaN(bgwidth) && ! isNaN(bgheight),"Bad background rectangle"); }
+						
+						if (bgx != _transparentBGX || bgy != _transparentBGY || bgwidth != _transparentBGWidth || bgheight != _transparentBGHeight)
+						{
+							s.graphics.clear();
+							CONFIG::debug { Debugging.traceFTECall(null,s,"clearTransparentBackground()"); }
+							if (bgwidth != 0 && bgheight != 0 )
+							{
+								s.graphics.beginFill(0, 0);
+								s.graphics.drawRect(bgx, bgy, bgwidth, bgheight);
+								s.graphics.endFill();
+								CONFIG::debug { Debugging.traceFTECall(null,s,"drawTransparentBackground",bgx, bgy, bgwidth, bgheight); }
+							}
+							_transparentBGX = bgx;
+							_transparentBGY = bgy;
+							_transparentBGWidth = bgwidth;
+							_transparentBGHeight = bgheight;
+						}
+					}
+				}
+			} 
+		}
+		
+		/** @private */
+		tlf_internal	function interactionManagerChanged(newInteractionManager:ISelectionManager):void
+		{
+			if (newInteractionManager)
+				attachContainer();
+			else
+				detachContainer();
+		}
+				
+		//--------------------------------------------------------------------------
+		//  Event handlers for editing
+		//  Listeners are attached on first compose
+		//--------------------------------------------------------------------------
+				
+		/** @private */
+		tlf_internal function attachContainer():void
+		{
+			if (!_minListenersAttached && textFlow && textFlow.interactionManager)
+			{
+				_minListenersAttached = true;
+				
+				if (_container)
+				{
+		   			_container.addEventListener(FocusEvent.FOCUS_IN, requiredFocusInHandler);
+		   			_container.addEventListener(MouseEvent.MOUSE_OVER, requiredMouseOverHandler);
+	    			
+	    			attachTransparentBackgroundForHit(false);
+					
+					// If the container already has focus, we have to attach all listeners
+					if (_container.stage && _container.stage.focus == _container)
+						attachAllListeners();
+				}
+			}
+	 	}
+	 	
+	 	/** @private */
+		tlf_internal function attachInteractionHandlers():void
+		{
+			// the receiver is either this or another class that is going to handle the methods.
+			var receiver:IInteractionEventHandler = getInteractionHandler();
+			
+			// the required handlers are implemented here and forwarded to the receiver
+			_container.addEventListener(MouseEvent.MOUSE_DOWN, requiredMouseDownHandler);
+		   	_container.addEventListener(FocusEvent.FOCUS_OUT, requiredFocusOutHandler);
+			_container.addEventListener(MouseEvent.DOUBLE_CLICK, receiver.mouseDoubleClickHandler);
+			_container.addEventListener(Event.ACTIVATE, receiver.activateHandler);
+		   	_container.addEventListener(FocusEvent.MOUSE_FOCUS_CHANGE, receiver.focusChangeHandler);
+		   	_container.addEventListener(FocusEvent.KEY_FOCUS_CHANGE, receiver.focusChangeHandler);
+		   	_container.addEventListener(TextEvent.TEXT_INPUT, receiver.textInputHandler);
+		   	_container.addEventListener(MouseEvent.MOUSE_OUT, receiver.mouseOutHandler);
+			_container.addEventListener(MouseEvent.MOUSE_WHEEL, receiver.mouseWheelHandler);
+			_container.addEventListener(Event.DEACTIVATE, receiver.deactivateHandler);
+			// attach by literal event name to avoid Argo dependency
+			// normally this would be IMEEvent.START_COMPOSITION
+			_container.addEventListener("imeStartComposition", receiver.imeStartCompositionHandler);
+
+			if (_container.contextMenu)
+	        	_container.contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, receiver.menuSelectHandler);
+		   	_container.addEventListener(Event.COPY, receiver.editHandler);
+		   	_container.addEventListener(Event.SELECT_ALL, receiver.editHandler);
+		   	_container.addEventListener(Event.CUT, receiver.editHandler);
+		   	_container.addEventListener(Event.PASTE, receiver.editHandler);
+		   	_container.addEventListener(Event.CLEAR, receiver.editHandler);
+		}
+		
+	 	/** @private */
+		tlf_internal function removeInteractionHandlers():void
+		{
+			var receiver:IInteractionEventHandler = getInteractionHandler();
+
+			_container.removeEventListener(MouseEvent.MOUSE_DOWN, requiredMouseDownHandler);
+			_container.removeEventListener(FocusEvent.FOCUS_OUT, requiredFocusOutHandler);
+			_container.removeEventListener(MouseEvent.DOUBLE_CLICK, receiver.mouseDoubleClickHandler);
+			_container.removeEventListener(Event.ACTIVATE, receiver.activateHandler);
+			_container.removeEventListener(FocusEvent.MOUSE_FOCUS_CHANGE, receiver.focusChangeHandler);
+			_container.removeEventListener(FocusEvent.KEY_FOCUS_CHANGE, receiver.focusChangeHandler);
+			_container.removeEventListener(TextEvent.TEXT_INPUT, receiver.textInputHandler);
+ 			_container.removeEventListener(MouseEvent.MOUSE_OUT, receiver.mouseOutHandler);
+			_container.removeEventListener(MouseEvent.MOUSE_WHEEL, receiver.mouseWheelHandler);
+			_container.removeEventListener(Event.DEACTIVATE, receiver.deactivateHandler);
+		//	_container.removeEventListener(IMEEvent.IME_START_COMPOSITION, receiver.imeStartCompositionHandler); 
+			// attach by literal event name to avoid Argo dependency
+			_container.removeEventListener("imeStartComposition", receiver.imeStartCompositionHandler); 
+
+	        if (_container.contextMenu) 
+	        	_container.contextMenu.removeEventListener(ContextMenuEvent.MENU_SELECT, receiver.menuSelectHandler);
+			_container.removeEventListener(Event.COPY, receiver.editHandler); 
+			_container.removeEventListener(Event.SELECT_ALL, receiver.editHandler);
+			_container.removeEventListener(Event.CUT, receiver.editHandler);
+			_container.removeEventListener(Event.PASTE, receiver.editHandler);
+			_container.removeEventListener(Event.CLEAR, receiver.editHandler);
+			
+			clearSelectHandlers();	
+		}
+		
+		/** @private */
+		tlf_internal function detachContainer():void
+		{
+			if (_minListenersAttached)
+			{
+				if (_container)
+				{
+		   			_container.removeEventListener(FocusEvent.FOCUS_IN, requiredFocusInHandler);
+		   			_container.removeEventListener(MouseEvent.MOUSE_OVER, requiredMouseOverHandler);
+
+					if(_allListenersAttached)
+					{
+						removeInteractionHandlers();				
+						_container.contextMenu = null;
+						
+						attachTransparentBackgroundForHit(true);
+						_allListenersAttached = false;
+					}
+	  			 }
+	  			 _minListenersAttached = false;
+	  		}
+ 	 	}
+		
+		private function attachAllListeners():void
+		{	
+			if (!_allListenersAttached && textFlow && textFlow.interactionManager)
+			{
+				CONFIG::debug { assert(_minListenersAttached,"Bad call to attachAllListeners - won't detach"); }
+				_allListenersAttached = true;
+				if (_container)
+				{
+					_container.contextMenu = createContextMenu();
+					attachInteractionHandlers();
+				}
+			}
+		}
+		
+		/** @private  
+		 *
+		 * Shared so that TextContainerManager can create the same ContextMenu. 
+		 */
+		static tlf_internal function createDefaultContextMenu():ContextMenu
+		{
+			var contextMenu:ContextMenu = new ContextMenu();
+			contextMenu.clipboardMenu = true;
+			contextMenu.clipboardItems.clear = true;
+			contextMenu.clipboardItems.copy = true;
+			contextMenu.clipboardItems.cut = true;
+			contextMenu.clipboardItems.paste = true;
+			contextMenu.clipboardItems.selectAll = true;
+			return contextMenu;
+		}
+		
+		/** 
+		 * Creates a context menu for the ContainerController. Use the methods of the ContextMenu class to 
+		 * add items to the menu.
+		 * <p>You can override this method to define a custom context menu.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see flash.ui.ContextMenu ContextMenu
+	 	 */
+		protected function createContextMenu():ContextMenu
+		{
+			return createDefaultContextMenu();
+		}
+		
+		/** @private */
+		tlf_internal function scrollTimerHandler(event:Event):void
+		{
+			// trace("BEGIN scrollTimerHandler");
+			if (!_scrollTimer)
+				return;
+
+			// shut it down if not in this container
+			if (textFlow.interactionManager == null || textFlow.interactionManager.activePosition < absoluteStart || textFlow.interactionManager.activePosition > absoluteStart+textLength)
+				event = null;
+				
+						
+			// We're listening for MOUSE_UP so we can cancel autoscrolling
+			if (event is MouseEvent)
+			{
+				_scrollTimer.stop();
+				_scrollTimer.removeEventListener(TimerEvent.TIMER, scrollTimerHandler);
+				CONFIG::debug { assert(_container.stage ==  null || getContainerRoot() == event.currentTarget,"scrollTimerHandler bad target"); }
+				event.currentTarget.removeEventListener(MouseEvent.MOUSE_UP, scrollTimerHandler);
+				_scrollTimer = null;
+			}
+			else if (!event)
+			{
+				_scrollTimer.stop();
+				_scrollTimer.removeEventListener(TimerEvent.TIMER, scrollTimerHandler);
+				if (getContainerRoot())
+					getContainerRoot().removeEventListener(	MouseEvent.MOUSE_UP, scrollTimerHandler);	
+				_scrollTimer = null;
+			}
+			else if (_container.stage)
+			{
+				var containerPoint:Point = new Point(_container.stage.mouseX, _container.stage.mouseY);
+				containerPoint = _container.globalToLocal(containerPoint);
+				var scrollChange:int = autoScrollIfNecessaryInternal(containerPoint);
+				if (scrollChange != 0 && interactionManager)		// force selection update if we actually scrolled and we have a selection manager
+				{
+					var mouseEvent:MouseEvent = new PsuedoMouseEvent(MouseEvent.MOUSE_MOVE,false,false,_container.stage.mouseX, _container.stage.mouseY,_container.stage,false,false,false,true);
+					var stashedScrollTimer:Timer = _scrollTimer;	
+					try
+					{
+						_scrollTimer =  null;
+						interactionManager.mouseMoveHandler(mouseEvent);
+					}
+					catch (e:Error)
+					{
+						throw(e);
+					}
+					finally
+					{
+						_scrollTimer = stashedScrollTimer;
+					}
+				}
+			}
+			// trace("AFTER scrollTimerHandler");
+		}
+
+		/** 
+		 * Handle a scroll event during a "drag" selection. 
+		 *
+		 * @param mouseX	The horizontal position of the mouse cursor on the stage.
+		 * @param mouseY	The vertical position of the mouse cursor  on the stage.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		 
+		public function autoScrollIfNecessary(mouseX:int, mouseY:int):void
+		{ 			
+ 			if (flowComposer.getControllerAt(flowComposer.numControllers-1) != this)
+ 			{
+ 				var verticalText:Boolean = (effectiveBlockProgression == BlockProgression.RL);
+ 				var lastController:ContainerController = flowComposer.getControllerAt(flowComposer.numControllers - 1);
+ 				if ((verticalText && _horizontalScrollPolicy == ScrollPolicy.OFF) ||
+ 					(!verticalText && _verticalScrollPolicy == ScrollPolicy.OFF))
+					return;
+				var r:Rectangle = lastController.container.getBounds(_container.stage);
+				if (verticalText)
+				{
+					if (mouseY >= r.top && mouseY <= r.bottom)
+						lastController.autoScrollIfNecessary(mouseX, mouseY);
+				}
+				else
+				{
+					if (mouseX >= r.left && mouseX <= r.right)
+						lastController.autoScrollIfNecessary(mouseX, mouseY);
+				}
+ 			}
+			
+			// even if not the last container - may scroll if there are explicit linebreaks
+			if (!_hasScrollRect)
+				return;
+			var containerPoint:Point = new Point(mouseX, mouseY);
+			containerPoint = _container.globalToLocal(containerPoint); 			
+			autoScrollIfNecessaryInternal(containerPoint);
+		}
+
+		/** 
+		 * Handle a scroll event during a "drag" selection. 
+		 *
+		 * @param mouseX	The horizontal position of the mouse cursor on the stage.
+		 * @param mouseY	The vertical position of the mouse cursor  on the stage.
+		 * @returns positive number if scroll went forward in reading order, negative number if it went backwards, and 0 if no scroll
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		 
+		private function autoScrollIfNecessaryInternal(extreme:Point):int
+		{
+			CONFIG::debug 
+			{ 
+				assert(_hasScrollRect, "internal scrolling function called on non-scrollable container");
+			}
+				
+			
+			var scrollDirection:int = 0;
+			
+			if (extreme.y - containerScrollRectBottom > 0) {
+				verticalScrollPosition += textFlow.configuration.scrollDragPixels;
+				scrollDirection = 1;
+			}
+			else if (extreme.y - containerScrollRectTop < 0) {
+				verticalScrollPosition -= textFlow.configuration.scrollDragPixels;
+				scrollDirection = -1;
+			}
+				
+			if (extreme.x - containerScrollRectRight > 0) {
+				horizontalScrollPosition += textFlow.configuration.scrollDragPixels;
+				scrollDirection = -1;
+			}
+			else if (extreme.x - containerScrollRectLeft < 0) {
+				horizontalScrollPosition -= textFlow.configuration.scrollDragPixels;
+				scrollDirection = 1;
+			}
+
+			// we need a timer so that the mouse doesn't have to continue moving when the mouse is outside the content area
+			if (scrollDirection != 0 && !_scrollTimer) 
+			{
+				_scrollTimer = new Timer(textFlow.configuration.scrollDragDelay);	// 35 ms is the default auto-repeat interval for ScrollBars.
+				_scrollTimer.addEventListener(TimerEvent.TIMER, scrollTimerHandler, false, 0, true);
+				if (getContainerRoot())
+				{
+					getContainerRoot().addEventListener(MouseEvent.MOUSE_UP, scrollTimerHandler, false, 0, true);
+					beginMouseCapture(); // TELL CLIENTS WE WANT mouseUpSomewhere events
+				}
+				_scrollTimer.start();
+			}
+			
+			return scrollDirection;
+		}
+
+		/** @private */
+		tlf_internal function findFirstAndLastVisibleLine():Array
+		{
+			var firstLine:int = flowComposer.findLineIndexAtPosition(absoluteStart);
+			var lastLine:int = flowComposer.findLineIndexAtPosition(absoluteStart + _textLength - 1);
+			var lastColumn:int = _columnState.columnCount - 1;
+			var firstVisibleLine:TextFlowLine;
+			var lastVisibleLine:TextFlowLine;
+			
+			// no visible lines?
+			if (firstLine == flowComposer.numLines)
+				return [null,null];
+				
+			for (var lineIndex:int = firstLine; lineIndex <= lastLine; lineIndex++) 
+			{
+				var curLine:TextFlowLine = flowComposer.getLineAt(lineIndex);	
+				if (curLine.controller != this)
+					continue;
+			
+				// skip until we find the lines in the last column
+				if (curLine.columnIndex != lastColumn)
+					continue;
+			
+				if (curLine.textLineExists)
+				{
+					var curTextLine:TextLine = curLine.getTextLine();
+					if (curTextLine && curTextLine.parent)
+					{
+						if (!firstVisibleLine)
+							firstVisibleLine = curLine;
+							
+						lastVisibleLine = curLine;
+					}
+				}		
+			}
+			
+			return [firstVisibleLine, lastVisibleLine];
+		}
+		
+		/** 
+		* Figure out the scroll distance required to scroll up or down by the specified number of lines.
+		* Negative numbers scroll upward, bringing more of the top of the TextFlow into view. Positive numbers 
+		* scroll downward, bringing the next line from the bottom into full view.
+		* 
+		* <p>When scrolling up, for example, the method makes the next line fully visible. If the next line is partially
+		* obscured and the number of lines specified is 1, the partially obscured line becomes fully visible.</p>
+		*
+		* @param nLines	The number of lines to scroll.
+		*
+		* @return 	the delta amount of space to scroll
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*/
+		 
+		public function getScrollDelta(numLines:int):Number
+		{
+			if (flowComposer.numLines == 0)
+				return 0;
+
+			// Now we want to calculate the top & bottom lines within the scrollRect. It's ok if they're just partially
+			// visible. Once we determine these lines, we figure out how much we need to scroll in order to bring the
+			// lines completely into view.
+			
+			var a:Array = findFirstAndLastVisibleLine();
+			var firstVisibleLine:TextFlowLine = a[0];
+			var lastVisibleLine:TextFlowLine = a[1];
+			// trace("    // findFirstAndLastVisibleLine ",flowComposer.findLineIndexAtPosition(firstVisibleLine.absoluteStart),flowComposer.findLineIndexAtPosition(lastVisibleLine.absoluteStart));
+						
+			var newLineIndex:int;
+			var lineIndex:int;
+			if (numLines > 0) 
+			{
+				lineIndex = flowComposer.findLineIndexAtPosition(lastVisibleLine.absoluteStart);
+				// If the last visible line is only partly visible, don't count it as visible. But make sure it overlaps by
+				// at least two pixels, otherwise it doesn't look like its clipped.
+				if (lastVisibleLine)
+				{
+					var lastTextLine:TextLine = lastVisibleLine.getTextLine(true);
+					if (effectiveBlockProgression == BlockProgression.TB)
+					{
+						if ((lastTextLine.y + lastTextLine.descent) - containerScrollRectBottom > 2)
+							--lineIndex;
+					}
+					else if (containerScrollRectLeft - (lastTextLine.x - lastTextLine.descent)  > 2)
+						--lineIndex;
+				}
+
+				// if we hit the end, force composition so that we get more lines - I picked a random amount to scroll forward, if its not enough, it will keep going
+				while (lineIndex + numLines > flowComposer.numLines - 1 && flowComposer.damageAbsoluteStart < textFlow.textLength)	
+					flowComposer.composeToPosition(flowComposer.damageAbsoluteStart + 1000);
+				newLineIndex = Math.min(flowComposer.numLines-1, lineIndex + numLines);
+			}
+			if (numLines < 0) 
+			{
+				lineIndex = flowComposer.findLineIndexAtPosition(firstVisibleLine.absoluteStart);
+
+				// If the first visible line is only partly visible, don't count it as visible. But make sure it overlaps by
+				// at least two pixels, otherwise it doesn't look like its clipped.
+				if (firstVisibleLine)
+				{
+					if (effectiveBlockProgression == BlockProgression.TB)
+					{
+						if (firstVisibleLine.y + 2 < containerScrollRectTop)
+							++lineIndex;
+					}
+					else if (firstVisibleLine.x + firstVisibleLine.ascent > containerScrollRectRight + 2)
+						++lineIndex;
+				} 
+
+				newLineIndex = Math.max(0, lineIndex + numLines);
+			}
+			
+			var line:TextFlowLine = flowComposer.getLineAt(newLineIndex);
+			if (line.absoluteStart < absoluteStart)		// don't scroll past the start of this controller -- previous text is in previous controller
+				return 0;
+			if (line.validity != TextLineValidity.VALID)
+			{
+				var leaf:FlowLeafElement = textFlow.findLeaf(line.absoluteStart);
+				var paragraph:ParagraphElement = leaf.getParagraph();
+				textFlow.flowComposer.composeToPosition(paragraph.getAbsoluteStart() + paragraph.textLength);
+				line = flowComposer.getLineAt(newLineIndex);
+				CONFIG::debug { assert(line.validity == TextLineValidity.VALID, "expected valid line after recomposing"); }
+			}
+			
+			var verticalText:Boolean = effectiveBlockProgression == BlockProgression.RL;
+
+			var newScrollPosition:Number;
+			if (verticalText)
+			{
+				
+				newScrollPosition =  numLines < 0 ? line.x + line.textHeight : line.x - line.descent + _compositionWidth;
+				return newScrollPosition - horizontalScrollPosition;
+			}
+
+			newScrollPosition = numLines < 0 ? line.y : line.y + line.textHeight - _compositionHeight;
+			return newScrollPosition - verticalScrollPosition;
+		}
+		
+		/** 
+		 * Processes the <code>MouseEvent.MOUSE_OVER</code> event when the client manages events. 
+		 *
+		 * @param event The MouseEvent object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @includeExample examples\ContainerController_mouseOverHandlerExample.as -noswf
+		 *
+		 * @see flash.events.MouseEvent#MOUSE_OVER MouseEvent.MOUSE_OVER
+		 */
+		 
+		public function mouseOverHandler(event:MouseEvent):void
+		{
+			if (interactionManager)
+				interactionManager.mouseOverHandler(event);
+		}
+
+		/** @private Does required mouseOver handling.  Calls mouseOverHandler.  @see #mouseOverHandler */
+		tlf_internal function requiredMouseOverHandler(event:MouseEvent):void
+		{
+			attachAllListeners();
+			getInteractionHandler().mouseOverHandler(event);
+		}
+
+		/** Processes the <code>MouseEvent.MOUSE_OUT</code> event when the client manages events.
+		 *
+		 * @param event The MouseEvent object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @see flash.events.MouseEvent#MOUSE_OUT MouseEvent.MOUSE_OUT
+		 */				
+		public function mouseOutHandler(event:MouseEvent):void
+		{
+			if (interactionManager)
+				interactionManager.mouseOutHandler(event);
+		}
+		
+		/** Processes the <code>MouseEvent.MOUSE_WHEEL</code> event when the client manages events.
+		 *
+		 * @param event The MouseEvent object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @see flash.events.MouseEvent#MOUSE_WHEEL MouseEvent.MOUSE_WHEEL
+		 */
+		public function mouseWheelHandler(event:MouseEvent):void
+		{
+			// Do the scroll and call preventDefault only if the there is enough text to scroll. Otherwise
+			// we let the event bubble up and cause scrolling at the next level up in the client's container hierarchy.
+			var verticalText:Boolean = effectiveBlockProgression == BlockProgression.RL;
+			if (verticalText)
+			{
+				if (contentWidth > _compositionWidth && !_measureWidth)
+				{
+					horizontalScrollPosition += event.delta * textFlow.configuration.scrollMouseWheelMultiplier;
+					event.preventDefault();
+				}
+			}
+			else if (contentHeight > _compositionHeight && !_measureHeight)
+			{
+				verticalScrollPosition -= event.delta * textFlow.configuration.scrollMouseWheelMultiplier;
+				event.preventDefault();
+			}
+		}
+		
+		
+		/** Processes the <code>MouseEvent.MOUSE_DOWN</code> event when the client manages events. 
+		 *
+		 * @param event The MouseEvent object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @see flash.events.MouseEvent#MOUSE_DOWN MouseEvent.MOUSE_DOWN
+		 */
+		 
+		public function mouseDownHandler(event:MouseEvent):void
+		{
+			if (interactionManager)
+			{
+				interactionManager.mouseDownHandler(event);
+				// grab the focus - alternative is to listen to keyevents on the Application
+				// is this necessary?
+				if ( interactionManager.hasSelection())
+					setFocus();
+			}
+		}
+
+		/** @private Does required mouseDown handling.  Calls mouseDownHandler.  @see #mouseDownHandler */
+		tlf_internal function requiredMouseDownHandler(event:MouseEvent):void
+		{
+			if (!_selectListenersAttached)
+			{
+				var containerRoot:DisplayObject = getContainerRoot();
+				if (containerRoot)
+				{
+		   			containerRoot.addEventListener(MouseEvent.MOUSE_MOVE, rootMouseMoveHandler, false, 0, true); 
+					containerRoot.addEventListener(MouseEvent.MOUSE_UP,   rootMouseUpHandler, false, 0, true);
+					
+					beginMouseCapture(); // TELL CLIENTS THAT WE WANT moueUpSomewhere EVENTS
+					
+	
+					_selectListenersAttached = true;
+				}
+			}
+			getInteractionHandler().mouseDownHandler(event); 
+		}
+		
+		/** 
+		 * Processes the <code>MouseEvent.MOUSE_UP</code> event when the client manages events.
+		 *
+		 * @param event The MouseEvent object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @see flash.events.MouseEvent#MOUSE_UP MouseEvent.MOUSE_UP
+		 *
+		 */
+		public function mouseUpHandler(event:MouseEvent):void
+		{
+			if (interactionManager)
+			{
+				interactionManager.mouseUpHandler(event);
+			}
+		}		
+		
+		/** @private */
+		tlf_internal function rootMouseUpHandler(event:MouseEvent):void
+		{
+			clearSelectHandlers();
+			getInteractionHandler().mouseUpHandler(event);
+		}
+		
+				
+		private function clearSelectHandlers():void
+		{	
+			if (_selectListenersAttached)
+			{
+				CONFIG::debug { assert(getContainerRoot() != null,"No container root"); }
+   				getContainerRoot().removeEventListener(MouseEvent.MOUSE_MOVE, rootMouseMoveHandler); 					
+				getContainerRoot().removeEventListener(MouseEvent.MOUSE_UP,   rootMouseUpHandler);
+				endMouseCapture(); // TELL CLIENTS WE NO LONGER WANT mouseUpSomewhere EVENTS
+				_selectListenersAttached = false;
+			}
+		}
+
+		/** 
+		 * Called to request clients to begin the forwarding of mouseup and mousemove events from outside a security sandbox.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 */
+		public function beginMouseCapture():void
+		{
+			// trace("BEGIN MOUSECAPTURE");
+			var sandboxManager:ISandboxSupport = getInteractionHandler() as ISandboxSupport
+			if (sandboxManager && sandboxManager != this)
+				sandboxManager.beginMouseCapture();
+		}
+		/** 
+		 * Called to inform clients that the the forwarding of mouseup and mousemove events from outside a security sandbox is no longer needed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 */
+		 public function endMouseCapture():void
+		{
+			// trace("END MOUSECAPTURE");
+			var sandboxManager:ISandboxSupport = getInteractionHandler() as ISandboxSupport
+			if (sandboxManager && sandboxManager != this)
+				sandboxManager.endMouseCapture();
+		}
+		/** Client call to forward a mouseUp event from outside a security sandbox.  Coordinates of the mouse up are not needed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 */
+		public function mouseUpSomewhere(event:Event):void
+		{
+			rootMouseUpHandler(null);
+			scrollTimerHandler(null);
+		}
+		/** Client call to forward a mouseMove event from outside a security sandbox.  Coordinates of the mouse move are not needed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 */
+		public function mouseMoveSomewhere(event:Event):void
+		{
+			return;	// do nothing right now
+		}
+
+		// What'd I hit???
+		private function hitOnMyFlowExceptLastContainer(event:MouseEvent):Boolean
+		{
+			if (event.target is TextLine)
+			{
+				var tfl:TextFlowLine = TextLine(event.target).userData as TextFlowLine;
+				if (tfl)
+				{
+					var para:ParagraphElement = tfl.paragraph;
+					if(para.getTextFlow() == textFlow)
+						return true;
+				}
+			}
+			else if (event.target is Sprite)
+			{
+				// skip the last container in the chain
+				for (var idx:int = 0; idx < textFlow.flowComposer.numControllers-1; idx++)
+					if (textFlow.flowComposer.getControllerAt(idx).container == event.target)
+						return true;
+			}
+			return false;
+		}
+		/** 
+		 * Processes the <code>MouseEvent.MOUSE_MOVE</code> event when the client manages events.
+		 *
+		 * @param event The MouseEvent object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @see flash.events.MouseEvent#MOUSE_MOVE MouseEvent.MOUSE_MOVE
+		 */
+		 
+		public function mouseMoveHandler(event:MouseEvent):void
+		{
+			if (interactionManager)
+			{
+				// only autoscroll if we haven't hit something on the stage related to this particular TextFlow
+				if (event.buttonDown && !hitOnMyFlowExceptLastContainer(event))
+					autoScrollIfNecessary(event.stageX, event.stageY);
+				interactionManager.mouseMoveHandler(event);
+			}
+		}
+		
+		/** @private */
+		tlf_internal function rootMouseMoveHandler(event:MouseEvent):void
+		{   
+			getInteractionHandler().mouseMoveHandler(event); 
+		}
+		
+		/** Processes the <code>MouseEvent.DOUBLE_CLICK</code> event when the client manages events.
+		 *
+		 * @param event The MouseEvent object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @includeExample examples\ContainerController_mouseDoubleClickHandlerExample.as -noswf
+		 *
+		 * @see flash.events.MouseEvent#DOUBLE_CLICK MouseEvent.DOUBLE_CLICK
+		 */
+		public function mouseDoubleClickHandler(event:MouseEvent):void
+		{
+			if (interactionManager)
+			{
+				interactionManager.mouseDoubleClickHandler(event);
+				// grab the focus - alternative is to listen to keyevents on the Application
+				// is this necessary?
+				if ( interactionManager.hasSelection())
+					setFocus();
+			}
+		}
+		
+		/** Give focus to the text container. @private */
+		tlf_internal function setFocus():void
+		{
+			//trace("setFocus container", id);
+			if (_container.stage)
+				_container.stage.focus = _container; 
+		}
+		
+		private function getContainerController(container:DisplayObject):ContainerController
+		{
+			while (container)
+			{
+				var flowComposer:IFlowComposer = flowComposer;
+				for (var i:int = 0; i < flowComposer.numControllers; i++)
+				{
+					var controller:ContainerController = flowComposer.getControllerAt(i);
+					if (controller.container == container)
+						return controller;
+				}
+				container = container.parent;
+			}
+			return null;
+		}
+		
+		/** 
+		 * Processes the <code>FocusEvent.KEY_FOCUS_CHANGE</code> and <code>FocusEvent.MOUSE_FOCUS_CHANGE</code> events
+		 * when the client manages events.
+		 *
+		 * @param event The FocusEvent object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @see flash.events.FocusEvent#KEY_FOCUS_CHANGE FocusEvent.KEY_FOCUS_CHANGE
+		 * @see flash.events.FocusEvent#MOUSE_FOCUS_CHANGE FocusEvent.MOUSE_FOCUS_CHANGE
+		 */
+		
+		public function focusChangeHandler(event:FocusEvent):void
+		{
+			// Figure out which controllers, if any, correspond to the DisplayObjects passed in the event.
+			// Disallow the focus change if it comes back to this controller again -- this prevents
+			// a focusOut followed by a focusIn, which we would otherwise get after clicking in the 
+			// container that already has focus.
+			
+				// This is the controller that currently has the focus
+			var focusController:ContainerController = getContainerController(DisplayObject(event.target));
+			
+				// This is the controller that is about to get the focus
+			var newFocusController:ContainerController = getContainerController(event.relatedObject);
+
+			/*trace("focusChange from controller", 
+				focusController is ContainerControllerBase ? ContainerControllerBase(focusController).id : "unknownType", 
+				newFocusController is ContainerControllerBase ? ContainerControllerBase(newFocusController).id : "unknownType");
+		*/
+			if (newFocusController == focusController)
+			{
+			//	trace("prevent focus change");
+				event.preventDefault();
+			}
+		}
+		
+		/** Processes the <code>FocusEvent.FOCUS_IN</code> event when the client manages events.
+		 *
+		 * @param event The FocusEvent object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @includeExample examples\ContainerController_focusInHandlerExample.as -noswf
+		 *
+		 * @see flash.events.FocusEvent#FOCUS_IN FocusEvent.FOCUS_IN
+		 */
+		public function focusInHandler(event:FocusEvent):void
+		{
+			var blinkRate:int = 0;
+		//	trace("container", id, "focusIn");
+			if (interactionManager)
+			{
+				interactionManager.focusInHandler(event);
+
+				if (interactionManager.editingMode == EditingMode.READ_WRITE)
+					blinkRate = interactionManager.focusedSelectionFormat.pointBlinkRate;				
+			} 
+			setBlinkInterval(blinkRate);
+		}
+		
+		/** @private - does whatever focusIn handling is required and cannot be overridden */
+		tlf_internal function requiredFocusInHandler(event:FocusEvent):void
+		{
+			attachAllListeners();
+			// trace("ContainerController requiredFocusInHandler adding key handlers");
+  			_container.addEventListener(KeyboardEvent.KEY_DOWN, getInteractionHandler().keyDownHandler);
+   			_container.addEventListener(KeyboardEvent.KEY_UP,   getInteractionHandler().keyUpHandler);		
+   			_container.addEventListener(FocusEvent.KEY_FOCUS_CHANGE,   getInteractionHandler().keyFocusChangeHandler);		
+			getInteractionHandler().focusInHandler(event);
+		}
+		
+		/** Processes the <code>FocusEvent.FOCUS_OUT</code> event when the client manages events.
+		 *
+		 * @param event The FocusEvent object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @see flash.events.FocusEvent#FOCUS_OUT FocusEvent.FOCUS_OUT
+		 */
+		 
+		public function focusOutHandler(event:FocusEvent):void
+		{
+			if (interactionManager)
+			{
+				interactionManager.focusOutHandler(event);
+				setBlinkInterval(interactionManager.unfocusedSelectionFormat.pointBlinkRate);
+			}
+			else
+				setBlinkInterval(0);
+		}
+
+		/** @private Does required focusOut handling.  Calls focusOutHandler.  @see #focusOutHandler */
+		tlf_internal function requiredFocusOutHandler(event:FocusEvent):void
+		{
+			// trace("ContainerController requiredFocusOutHandler removing key handlers");
+ 			_container.removeEventListener(KeyboardEvent.KEY_DOWN, getInteractionHandler().keyDownHandler);
+   			_container.removeEventListener(KeyboardEvent.KEY_UP,   getInteractionHandler().keyUpHandler);   			
+   			_container.removeEventListener(FocusEvent.KEY_FOCUS_CHANGE,   getInteractionHandler().keyFocusChangeHandler);   			
+			getInteractionHandler().focusOutHandler(event);
+		}
+		
+		/** Processes the <code>Event.ACTIVATE</code> event when the client manages events.
+		 *
+		 * @param event The Event object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @includeExample examples\ContainerController_activateHandlerExample.as -noswf
+		 *
+		 * @see flash.events.Event#ACTIVATE Event.ACTIVATE
+		 */						
+		public function activateHandler(event:Event):void
+		{
+			if (interactionManager)
+				interactionManager.activateHandler(event);
+		}
+		
+		/** Processes the <code>Event.DEACTIVATE</code> event when the client manages events. 
+		 *
+		 * @param event The Event object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * 
+		 * @see flash.events.Event#DEACTIVATE Event.DEACTIVATE
+		 */
+		 
+		public function deactivateHandler(event:Event):void
+		{
+			if (interactionManager)
+				interactionManager.deactivateHandler(event);
+		}		
+		
+		/** Processes the <code>KeyboardEvent.KEY_DOWN</code> event when the client manages events.
+		 *
+		 * @param The KeyboardEvent object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @see flash.events.KeyboardEvent#KEY_DOWN KeyboardEvent.KEY_DOWN
+		 */
+		public function keyDownHandler(event:KeyboardEvent):void
+		{
+			if (interactionManager)
+				interactionManager.keyDownHandler(event);
+		}
+		
+		/** Processes the <code>Keyboard.KEY_UP</code> event when the client manages events.
+		 *
+		 * @param event The KeyboardEvent object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @includeExample examples\ContainerController_keyUpHandlerExample.as -noswf
+		 *
+		 * @see flash.events.KeyboardEvent#KEY_UP KeyboardEvent.KEY_UP
+		 */
+		 
+		public function keyUpHandler(event:KeyboardEvent):void
+		{
+			if (interactionManager)
+				interactionManager.keyUpHandler(event);
+		}
+
+		/** Processes the <code>FocusEvent.KEY_FOCUS_CHANGE</code> event when the client manages events.
+		 *
+		 * @param event The FocusEvent object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @see flash.events.FocusEvent#KEY_FOCUS_CHANGE FocusEvent.KEY_FOCUS_CHANGE
+		 */
+		public function keyFocusChangeHandler(event:FocusEvent):void
+		{
+			if (interactionManager)
+				interactionManager.keyFocusChangeHandler(event);
+		}		
+		/** Processes the <code>TextEvent.TEXT_INPUT</code> event when the client manages events.
+		 *
+		 * @param event  The TextEvent object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * 
+		 * @includeExample examples\ContainerController_textInputHandlerExample.as -noswf
+		 *
+		 * @see flash.events.TextEvent#TEXT_INPUT TextEvent.TEXT_INPUT
+		 */
+		 
+		public function textInputHandler(event:TextEvent):void
+		{
+			if (interactionManager)
+				interactionManager.textInputHandler(event);
+		}
+		
+		/** Processes the <code>IMEEvent.IME_START_COMPOSITION</code> event when the client manages events.
+		 *
+		 * @param event  The IMEEvent object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * 
+		 * @see flash.events.IMEEvent.IME_START_COMPOSITION
+		 */
+		 
+		public function imeStartCompositionHandler(event:IMEEvent):void
+		{
+			if (interactionManager)
+				interactionManager.imeStartCompositionHandler(event);
+		}
+		
+		
+		/** 
+		 * Processes the <code>ContextMenuEvent.MENU_SELECT</code> event when the client manages events.
+		 * 
+		 * @param The ContextMenuEvent object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @includeExample examples\ContainerController_menuSelectHandlerExample.as -noswf
+		 * 
+		 * @see flash.events.ContextMenuEvent#MENU_SELECT ContextMenuEvent.MENU_SELECT
+		 */						
+		public function menuSelectHandler(event:ContextMenuEvent):void
+		{
+			var tf:DisplayObjectContainer = _container as DisplayObjectContainer;
+
+			if (interactionManager)
+			{
+				interactionManager.menuSelectHandler(event);
+			}
+    		else
+    		{
+				var cbItems:ContextMenuClipboardItems = tf.contextMenu.clipboardItems
+				cbItems.copy = false;
+				cbItems.cut = false;
+				cbItems.paste = false;
+				cbItems.selectAll = false;
+				cbItems.clear = false;
+			}
+		}
+		
+		/**
+		 * Processes an edit event (CUT, COPY, PASTE, SELECT_ALL) when the client manages events.
+		 * 
+		 * @param The Event object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @includeExample examples\ContainerController_editHandlerExample.as -noswf
+		 * 
+		 * @see flash.events.Event Event
+		 */	
+			    
+	    	public function editHandler(event:Event):void
+	    	{
+	    		if (interactionManager)
+	    			interactionManager.editHandler(event);
+
+	    		// re-enable context menu so following keyboard shortcuts will work
+	    		var contextMenu:ContextMenu = _container.contextMenu;
+	    		if (contextMenu)
+	    		{
+					contextMenu.clipboardItems.clear = true;
+					contextMenu.clipboardItems.copy = true;
+					contextMenu.clipboardItems.cut = true;
+					contextMenu.clipboardItems.paste = true;
+					contextMenu.clipboardItems.selectAll = true;
+	    		}
+	    	}
+	    
+		 /** 
+		 * Sets the range of selected text in a component implementing ITextSupport.
+		 * If either of the arguments is out of bounds the selection should not be changed.
+		 * Components which wish to support inline IME should call into this method.
+		 * 
+		 * @param anchorIndex The zero-based index value of the character at the anchor end of the selection
+		 *
+		 * @param activeIndex The zero-based index value of the character at the active end of the selection.
+		 * 
+		 * @playerversion Flash 10.0
+		 * @langversion 3.0
+		 */
+	    public function selectRange(anchorIndex:int, activeIndex:int):void
+	    {
+	    	if(interactionManager && interactionManager.editingMode != EditingMode.READ_ONLY)
+	    	{
+		    	interactionManager.selectRange(anchorIndex, activeIndex);
+	    	}
+	    }
+	    
+		//--------------------------------------------------------------------------
+		//
+		//  Cursor blinking code
+		//
+		//--------------------------------------------------------------------------
+		
+		// TODO Want to evaluate whether there's a cleaner way to do this
+		
+		private var blinkTimer:Timer;
+		private var blinkObject:DisplayObject;
+
+		/**
+		 * Starts a DisplayObject cursor blinking by changing its alpha value
+		 * over time.
+		 * 
+		 * @param obj The DisplayObject to use as the cursor.
+		 * 
+		 */
+		private function startBlinkingCursor(obj:DisplayObject, blinkInterval:int):void
+		{
+			if (!blinkTimer)
+				blinkTimer = new Timer(blinkInterval,0);
+			blinkObject = obj;
+			blinkTimer.addEventListener(TimerEvent.TIMER,blinkTimerHandler, false, 0, true);
+			blinkTimer.start();
+		}
+
+		/**
+		 * Stops cursor from blinking
+		 * @private
+		 */
+		protected function stopBlinkingCursor():void
+		{
+			if (blinkTimer)
+				blinkTimer.stop();
+			blinkObject = null;
+		}	
+		
+		private function blinkTimerHandler(event:TimerEvent):void
+		{
+			blinkObject.alpha = (blinkObject.alpha == 1.0) ? 0.0 : 1.0;
+		}
+		
+		/** 
+		 * Set the blink interval.
+		 * 
+		 * @param intervalMS - number of microseconds between blinks
+		 * @private
+		 */
+		protected function setBlinkInterval(intervalMS:int):void
+		{
+			var blinkInterval:int = intervalMS;
+			if (blinkInterval == 0)
+			{
+				// turn off the blinking
+				if (blinkTimer)
+					blinkTimer.stop();
+				if (blinkObject)
+					blinkObject.alpha = 1.0;
+			}
+			else if (blinkTimer)
+			{
+				blinkTimer.delay = blinkInterval;
+				if (blinkObject)
+					blinkTimer.start();
+			}
+		}
+		
+		/** Draw the caret for a selection 
+		 * @param x	x-location where caret is drawn
+		 * @param y y-location where caret is drawn
+		 * @param w	width of caret
+		 * @param h	height of caret
+		 * @private
+		 */
+		tlf_internal function drawPointSelection(selFormat:SelectionFormat, x:Number,y:Number,w:Number,h:Number):void
+        {
+            var selObj:Shape = new Shape();
+            
+            if (interactionManager.activePosition == interactionManager.anchorPosition)
+				selObj.graphics.beginFill(selFormat.pointColor)
+			else
+				selObj.graphics.beginFill(selFormat.rangeColor);
+				
+			// Oh, this is ugly. If we are in right aligned text, and there is no padding, and the scrollRect is set, 
+			// then in an empty line (or if the point is at the right edge of the line), the blinking cursor is not
+			// visible because it is clipped out. Move it in so we can see it. 
+			if (_hasScrollRect)
+			{
+				if (effectiveBlockProgression == BlockProgression.TB)
+				{
+					if (x >= containerScrollRectRight)
+						x -= w;
+				} 
+				else
+					if (y >= containerScrollRectBottom)
+						y -= h;
+			}
+				
+			selObj.graphics.drawRect(int(x),int(y),w,h);
+			selObj.graphics.endFill();
+			
+			// make it blink
+			if (selFormat.pointBlinkRate != 0 && interactionManager.editingMode == EditingMode.READ_WRITE)
+				startBlinkingCursor(selObj, selFormat.pointBlinkRate);
+
+			addSelectionChild(selObj);
+        }
+        
+        /** Add selection shapes to the displaylist. @private */
+        tlf_internal function addSelectionShapes(selFormat:SelectionFormat, selectionAbsoluteStart:int, selectionAbsoluteEnd:int): void
+		{
+			if (!interactionManager || _textLength == 0 || selectionAbsoluteStart == -1 || selectionAbsoluteEnd == -1)
+				return;
+						
+			var prevLine:TextFlowLine;
+			var nextLine:TextFlowLine;
+			
+			if (selectionAbsoluteStart != selectionAbsoluteEnd)
+			{
+				// adjust selectionAbsoluteStart and selectionAbsoluteEnd to be within this controller
+				var absoluteControllerStart:int = this.absoluteStart;
+				var absoluteControllerEnd:int = this.absoluteStart+this._textLength;
+				
+				if (selectionAbsoluteStart < absoluteControllerStart)
+					selectionAbsoluteStart = absoluteControllerStart;
+				else if (selectionAbsoluteStart >= absoluteControllerEnd)
+					return;	// nothing to do
+					
+				// backup one so that 
+				if (selectionAbsoluteEnd > absoluteControllerEnd)
+					selectionAbsoluteEnd = absoluteControllerEnd;
+				else if (selectionAbsoluteEnd < absoluteControllerStart)
+					return;	// nothing to do
+					
+				CONFIG::debug { assert(selectionAbsoluteStart <= selectionAbsoluteEnd,"addSelectionShapes: bad range"); }
+				CONFIG::debug { assert(selectionAbsoluteStart >= absoluteControllerStart,"addSelectionShapes: bad range"); }
+				CONFIG::debug { assert(selectionAbsoluteEnd <= absoluteControllerEnd,"addSelectionShapes: bad range"); }
+					
+				var begLine:int = flowComposer.findLineIndexAtPosition(selectionAbsoluteStart);
+				var endLine:int = selectionAbsoluteStart == selectionAbsoluteEnd ? begLine : flowComposer.findLineIndexAtPosition(selectionAbsoluteEnd);
+				// watch for going past the end
+				if (endLine >= flowComposer.numLines)
+					endLine = flowComposer.numLines-1;
+					
+				var selObj:Shape = new Shape();
+				prevLine = begLine ? flowComposer.getLineAt(begLine-1) : null;
+				var line:TextFlowLine = flowComposer.getLineAt(begLine); 
+					
+				for (var idx:int = begLine; idx <= endLine; idx++)
+				{
+					nextLine = idx != flowComposer.numLines - 1 ? flowComposer.getLineAt(idx+1) : null;
+						
+					line.hiliteBlockSelection(selObj, selFormat, DisplayObject(this._container),
+						selectionAbsoluteStart < line.absoluteStart ? line.absoluteStart : selectionAbsoluteStart,
+						selectionAbsoluteEnd > line.absoluteStart+line.textLength ? line.absoluteStart+line.textLength : selectionAbsoluteEnd, prevLine, nextLine);
+							
+					var temp:TextFlowLine = line;
+					line = nextLine;
+					prevLine = temp;
+				}
+
+				addSelectionChild(selObj);		
+			}
+			else
+			{
+				var lineIdx:int = flowComposer.findLineIndexAtPosition(selectionAbsoluteStart);
+				// TODO: there is ambiguity - are we at the end of the currentLine or the beginning of the next one?
+				// however must stick to the end of the last line
+				if (lineIdx == flowComposer.numLines)
+					lineIdx--;
+				if (flowComposer.getLineAt(lineIdx).controller == this)
+				{
+					prevLine = lineIdx != 0 ? flowComposer.getLineAt(lineIdx-1) : null;
+					nextLine = lineIdx != flowComposer.numLines-1 ? flowComposer.getLineAt(lineIdx+1) : null
+					flowComposer.getLineAt(lineIdx).hilitePointSelection(selFormat, selectionAbsoluteStart, DisplayObject(this._container), prevLine, nextLine);
+				}
+			}
+		}
+
+		/** Remove all selection shapes. @private */
+		tlf_internal function clearSelectionShapes(): void
+		{
+			stopBlinkingCursor();
+			
+			var selectionSprite:DisplayObjectContainer = getSelectionSprite(false);
+			if (selectionSprite != null)
+			{
+				if (selectionSprite.parent)
+					removeSelectionContainer(selectionSprite);
+				while (selectionSprite.numChildren > 0)
+					selectionSprite.removeChildAt(0);
+				return;
+			}
+		}
+	
+		/** Add a selection child. @private */
+		tlf_internal function addSelectionChild(child:DisplayObject):void
+		{
+			// If there's no selectionSprite on this controller, we use the parent's.
+			// That means we have to translate the coordinates.
+			// TODO: this only supports one level of ntesting
+			var selectionSprite:DisplayObjectContainer = getSelectionSprite(true);
+			
+			if (selectionSprite == null)
+			{
+				return;
+			}
+
+			var selFormat:SelectionFormat = interactionManager.currentSelectionFormat;
+			var curBlendMode:String = (interactionManager.activePosition == interactionManager.anchorPosition) ? selFormat.pointBlendMode : selFormat.rangeBlendMode;
+			var curAlpha:Number = (interactionManager.activePosition == interactionManager.anchorPosition) ? selFormat.pointAlpha : selFormat.rangeAlpha;
+			if (selectionSprite.blendMode != curBlendMode)
+				selectionSprite.blendMode = curBlendMode;
+				
+			if (selectionSprite.alpha != curAlpha)
+				selectionSprite.alpha = curAlpha;
+			
+			if (selectionSprite.numChildren == 0)
+				addSelectionContainer(selectionSprite);
+				
+			selectionSprite.addChild(child);
+		}
+		
+		/** Test for a selection child. @private */
+		tlf_internal function containsSelectionChild(child:DisplayObject):Boolean
+		{ 
+			var selectionSprite:DisplayObjectContainer = getSelectionSprite(false);
+			if (selectionSprite == null)
+			{
+				return false;
+			}
+			return selectionSprite.contains(child); 
+		}
+
+		/** @private */
+		tlf_internal function getBackgroundShape():Shape
+		{
+			if(!_backgroundShape)
+			{
+				_backgroundShape = new Shape();
+				addBackgroundShape(_backgroundShape);
+			}
+			
+			return _backgroundShape;
+		}
+		
+		CONFIG::debug private function containsFloats(textFlow:TextFlow):Boolean
+ 		{
+ 			if (textFlow)
+ 				for (var leaf:FlowLeafElement = textFlow.getFirstLeaf(); leaf != null; leaf = leaf.getNextLeaf())
+ 					if (leaf is InlineGraphicElement && InlineGraphicElement(leaf).float != Float.NONE)
+ 						return true;
+ 			return false;
+		}
+		/**
+		 * @private
+		 */
+		tlf_internal function get effectivePaddingLeft():Number
+		{ return computedFormat.paddingLeft + (_rootElement ? _rootElement.computedFormat.paddingLeft : 0); }
+		/**
+		 * @private
+		 */
+		 tlf_internal function get effectivePaddingRight():Number
+		{ return computedFormat.paddingRight + (_rootElement ? _rootElement.computedFormat.paddingRight : 0); }
+		/**
+		 * @private
+		 */
+		 tlf_internal function get effectivePaddingTop():Number
+		{ return computedFormat.paddingTop + (_rootElement ? _rootElement.computedFormat.paddingTop : 0); }
+		/**
+		 * @private
+		 */
+		 tlf_internal function get effectivePaddingBottom():Number
+		{ return computedFormat.paddingBottom + (_rootElement ? _rootElement.computedFormat.paddingBottom : 0); }
+
+		private var _selectionSprite:Sprite;
+		
+		/** @private */
+		tlf_internal function getSelectionSprite(createIfNull:Boolean):DisplayObjectContainer
+		{
+			if (_selectionSprite == null && createIfNull)
+			{
+				_selectionSprite = new Sprite();
+				_selectionSprite.mouseEnabled = false;
+				_selectionSprite.mouseChildren = false;
+			}
+			return _selectionSprite;
+		}
+		
+		static private function createContainerControllerInitialFormat():ITextLayoutFormat
+		{
+			var ccif:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder();
+			ccif.columnCount = FormatValue.INHERIT;
+			ccif.columnGap = FormatValue.INHERIT;
+			ccif.columnWidth = FormatValue.INHERIT;
+			ccif.verticalAlign = FormatValue.INHERIT;
+			return ccif;
+		}
+		
+		static private var _containerControllerInitialFormat:ITextLayoutFormat = createContainerControllerInitialFormat();
+		
+		/** 
+		* @private
+		* Specifies the initial format (ITextLayoutFormat instance) for a new ContainerController. The runtime
+		* applies this to the format property of all new containers on creation.
+		*
+		* By default, sets the column format values to "inherit"; all other format values are inherited.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*
+		* @see flashx.textLayout.elements.TextFlow TextFlow
+		*/
+		
+		static public function get containerControllerInitialFormat():ITextLayoutFormat
+		{ return _containerControllerInitialFormat; }
+		static public function set containerControllerInitialFormat(val:ITextLayoutFormat):void
+		{ _containerControllerInitialFormat = val; }
+		
+		
+		/** @private */
+		protected function get attachTransparentBackground():Boolean
+		{ return true; }
+		
+		/** @private */
+		tlf_internal function clearCompositionResults():void
+		{
+			setTextLength(0); 
+
+			for each (var textLine:TextLine in _shapeChildren)
+			{
+				removeTextLine(textLine);
+				CONFIG::debug { Debugging.traceFTECall(null,_container,"removeTextLine",textLine); }
+			}
+			_shapeChildren.length = 0;
+		}
+		
+		/** The TextLines being added to the array in fillShapeChildren are added to tempSprite because they are about to be displayed
+		 * and the TextFlowLine code needs to know that as it keeps all displayed lines in the TextFlowLine textLineCache.  This tells them that.
+		 */
+		static private var tempLineHolder:Sprite = new Sprite();
+		
+		/** Add DisplayObjects that were created by composition to the container. @private */
+		tlf_internal function updateCompositionShapes():void
+		{
+			if(!shapesInvalid)
+			{
+				return;
+			}			
+			
+			// reclamp vertical/horizontal scrollposition - addresses Watson 2380962
+			var scrolled:Boolean = false;	// true if scroll values were changed - we need to notify in this case
+			var tmp:Number = _yScroll;
+			if (verticalScrollPolicy != ScrollPolicy.OFF && !_measureHeight)
+				_yScroll = computeVerticalScrollPosition(_yScroll,false);
+			scrolled = (tmp != _yScroll);
+			tmp = _xScroll;
+			if (horizontalScrollPolicy != ScrollPolicy.OFF && !_measureWidth)
+				_xScroll = computeHorizontalScrollPosition(_xScroll,false);
+			scrolled = scrolled || (tmp != _xScroll);
+
+			// Post all the new TextLines to the display list, and remove any old TextLines left from last time. Do this
+			// in a non-destructive way so that lines that have not been changed are not touched. This reduces redraw time.
+			var newShapeChildren:Array = [ ];
+			fillShapeChildren(newShapeChildren,tempLineHolder);
+			
+			var childIdx:int = getFirstTextLineChildIndex(); // index where the first text line must appear at in its container  
+			var oldIdx:int = 0;		// offset into shapeChildren
+			var newIdx:int = 0;		// offset into newShapeChildren
+
+			while (newIdx != newShapeChildren.length)
+			{
+				var newChild:TextLine = newShapeChildren[newIdx];
+				if (newChild == _shapeChildren[oldIdx])
+				{
+					// Same shape is in both lists, no change necessary, advance to next item in each list
+					childIdx++;
+					newIdx++;
+					oldIdx++;
+					continue;
+				}
+
+				var newChildIdx:int = _shapeChildren.indexOf(newChild);
+				if (newChildIdx == -1)
+				{
+					// Shape is in the new list, but not in the old list, add it to the display list at the current location, and advance to next item
+					addTextLine(newChild, childIdx++);
+					CONFIG::debug { Debugging.traceFTECall(null,_container,"addTextLine",newChild); }
+					newIdx++;
+				}
+				else
+				{
+					// The shape is on both lists, but there are several intervening "old" shapes in between. We'll remove the old shapes that
+					// come before the new one we want to insert.
+					removeAndRecycleTextLines (oldIdx, newChildIdx);
+					oldIdx = newChildIdx;
+				}
+			}
+
+			// remove any trailing children no longer displayed
+			removeAndRecycleTextLines (oldIdx, _shapeChildren.length);
+
+			_shapeChildren = newShapeChildren;
+			shapesInvalid = false;
+									
+			// TODO: support for inline children (tables)
+			// synchronize the inline shapes beginning at childIdx 
+			updateInlineChildren();
+			
+			// _textFrame.updateVisibleRectangle(this._visibleRect);
+			updateVisibleRectangle();
+			
+			// If we're measuring, then the measurement values may have changed since last time.
+			// Force the transparent background to redraw, so that mouse events will work for the 
+			// entire content area.
+			if (_measureWidth || _measureHeight)
+				attachTransparentBackgroundForHit(false);
+			
+			var tf:TextFlow = this.textFlow;
+			if (tf.backgroundManager)
+			{
+				tf.backgroundManager.onUpdateComplete(this);
+			}
+			
+			// If we updated the scroll values, we need to send an event
+			if (scrolled && tf.hasEventListener(TextLayoutEvent.SCROLL))
+			{
+				tf.dispatchEvent(new TextLayoutEvent(TextLayoutEvent.SCROLL));
+			}
+
+			if (tf.hasEventListener(UpdateCompleteEvent.UPDATE_COMPLETE))
+			{
+				tf.dispatchEvent(new UpdateCompleteEvent(UpdateCompleteEvent.UPDATE_COMPLETE,false,false,tf, this));
+			}
+			
+			CONFIG::debug { assert(tempLineHolder.numChildren == 0,"Uh oh"); }
+			CONFIG::debug { validateLines(); }
+			// prevent leaks here - this code should't be needed
+			while (tempLineHolder.numChildren)
+				tempLineHolder.removeChildAt(0);
+		}
+		
+		private function removeAndRecycleTextLines (beginIndex:int, endIndex:int):void
+		{
+			var backgroundManager:BackgroundManager = textFlow.backgroundManager;
+			
+			var child:TextLine;
+			while (beginIndex < endIndex)
+			{
+				child = _shapeChildren[beginIndex++];
+				
+				removeTextLine(child);
+				CONFIG::debug { Debugging.traceFTECall(null,_container,"removeTextLine",child); }
+				
+				// Recycle if its not displayed and not connected to the textblock
+				if (TextLineRecycler.textLineRecyclerEnabled && !child.parent)
+				{
+					if (child.userData == null)
+					{
+						TextLineRecycler.addLineForReuse(child);
+						if (backgroundManager)
+							backgroundManager.removeLineFromCache(child);
+					}
+					else if (child.validity == TextLineValidity.INVALID)
+					{
+						if (child.nextLine == null && child.previousLine == null && (!child.textBlock || child.textBlock.firstLine != child))
+						{
+							child.userData.releaseTextLine();
+							child.userData = null;
+							TextLineRecycler.addLineForReuse(child);
+							if (backgroundManager)
+								backgroundManager.removeLineFromCache(child);
+						}
+					}
+				}
+			}
+		} 
+		
+		/**
+		 * Gets the index at which the first text line must appear in its parent.
+		 * The default implementation of this method, which may be overriden, returns the child index 
+		 * of the first <code>flash.text.engine.TextLine</code> child of <code>container</code>
+		 * if one exists, and that of the last child of <code>container</code> otherwise. 
+		 * 
+		 * @return the index at which the first text line must appear in its parent.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * 
+		 * @see flash.text.engine.TextLine
+		 * @see #container
+		 */	
+		protected function getFirstTextLineChildIndex():int
+		{			
+			// skip past any non-TextLine children below the text in the container,
+			// This also means that in a container devoid of text, we will always
+			// populate the text starting at index container.numChildren, which is intentional.
+			var firstTextLine:int;
+			for(firstTextLine = 0; firstTextLine<_container.numChildren; ++firstTextLine)
+			{
+				if(_container.getChildAt(firstTextLine) is TextLine)
+				{
+					break;
+				}
+			}
+			return firstTextLine;
+		}
+			 
+		/**
+		 * Adds a <code>flash.text.engine.TextLine</code> object as a descendant of <code>container</code>.
+		 * The default implementation of this method, which may be overriden, adds the object
+		 * as a direct child of <code>container</code> at the specified index.
+		 * 
+		 * @param textLine the <code>flash.text.engine.TextLine</code> object to add
+		 * @param index insertion index of the text line in its parent 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * 
+		 * @see flash.text.engine.TextLine
+		 * @see #container
+		 * 
+		 */	
+		protected function addTextLine(textLine:TextLine, index:int):void
+		{
+			_container.addChildAt(textLine, index);
+		}
+		
+		/**
+		 * Removes a <code>flash.text.engine.TextLine</code> object from its parent. 
+		 * The default implementation of this method, which may be overriden, removes the object
+		 * from <code>container</code> if it is a direct child of the latter.
+		 * 
+		 * This method may be called even if the object is not a descendant of <code>container</code>.
+		 * Any implementation of this method must ensure that no action is taken in this case.
+		 * 
+		 * @param textLine the <code>flash.text.engine.TextLine</code> object to remove 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * 
+		 * @see flash.text.engine.TextLine
+		 * @see #container
+		 * 
+		 */	
+		protected function removeTextLine(textLine:TextLine):void
+		{
+			if (_container.contains(textLine))
+  				_container.removeChild(textLine);
+		}
+
+		/**
+		 * Adds a <code>flash.display.Shape</code> object on which background shapes (such as background color) are drawn.
+		 * The default implementation of this method, which may be overriden, adds the object to <code>container</code>
+		 * just before the first <code>flash.text.engine.TextLine</code> child, if one exists, and after the last exisiting
+		 * child otherwise. 
+		 * 
+		 * @param shape <code>flash.display.Shape</code> object to add
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * 
+		 * @see flash.display.Shape
+		 * @see flash.text.engine.TextLine
+		 * @see #container
+		 * 
+		 */
+		protected function addBackgroundShape(shape:Shape):void
+		{
+			_container.addChildAt(_backgroundShape, getFirstTextLineChildIndex());
+		}
+		
+		/**
+		 * Adds a <code>flash.display.DisplayObjectContainer</code> object to which selection shapes (such as block selection highlight, cursor etc.) are added.
+		 * The default implementation of this method, which may be overriden, has the following behavior:
+		 * The object is added just before first <code>flash.text.engine.TextLine</code> child of <code>container</code> if one exists 
+		 * and the object is opaque and has normal blend mode. 
+		 * In all other cases, it is added as the last child of <code>container</code>.
+		 * 
+		 * @param selectionContainer <code>flash.display.DisplayObjectContainer</code> object to add
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * 
+		 * @see flash.display.DisplayObjectContainer
+		 * @see flash.text.engine.TextLine
+		 * @see #container
+		 */
+		protected function addSelectionContainer(selectionContainer:DisplayObjectContainer):void
+		{
+			if (selectionContainer.blendMode == BlendMode.NORMAL && selectionContainer.alpha == 1)
+			{
+				// don't put selection behind background color or existing content in container, put it behind first text line
+				_container.addChildAt(selectionContainer, getFirstTextLineChildIndex());
+			}
+			else
+				_container.addChild(selectionContainer);
+		}
+		
+		/**
+		 * Removes the <code>flash.display.DisplayObjectContainer</code> object which contains selection shapes (such as block selection highlight, cursor etc.).
+		 * The default implementation of this method, which may be overriden, removes the object from its parent if one exists.
+		 * 
+		 * @param selectionContainer <code>flash.display.DisplayObjectContainer</code> object to remove
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * 
+		 * @see flash.display.DisplayObjectContainer
+		 * @see #container
+		 * 
+		 */
+		protected function removeSelectionContainer(selectionContainer:DisplayObjectContainer):void
+		{	
+			selectionContainer.parent.removeChild(selectionContainer);
+		}
+		
+		/**
+		 * @private
+		 */
+		tlf_internal function get textLines():Array
+		{
+			return _shapeChildren;
+		}
+		
+		/** 
+		 * If scrolling, sets the scroll rectangle to the container rectangle so that any lines that are 
+		 * halfway in view are clipped to the scrollable region. If not scrolling, clear the
+		 * scroll rectangle so that no clipping occurs.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		 
+		protected function updateVisibleRectangle() :void
+		{
+			if (horizontalScrollPolicy == ScrollPolicy.OFF && verticalScrollPolicy == ScrollPolicy.OFF)
+			{
+				if (_hasScrollRect)
+				{
+					_container.scrollRect = null;
+					_hasScrollRect = false;
+					
+				}
+			}
+			else
+			{
+				var contentRight:Number = _contentLeft+contentWidth;
+				var contentBottom:Number = _contentTop+contentHeight;
+				var width:Number;
+				var compositionRight:Number;
+				if (_measureWidth)
+				{
+					width = contentWidth;
+					compositionRight = _contentLeft + width
+				}
+				else
+				{
+					width = _compositionWidth;
+					compositionRight = width;
+				}
+				var height:Number;
+				var compositionBottom:Number;
+				if (_measureHeight)
+				{
+					height = contentHeight;
+					compositionBottom = _contentTop + height;
+				}
+				else
+				{
+					height = _compositionHeight;
+					compositionBottom = height;
+				}
+				var xOrigin:Number = (effectiveBlockProgression == BlockProgression.RL) ? -width : 0;
+				var xpos:int = horizontalScrollPosition + xOrigin;
+				var ypos:int = verticalScrollPosition;
+				
+				if (textLength == 0 || xpos == 0 && ypos == 0 && _contentLeft >= xOrigin && _contentTop >= 0 && contentRight <= compositionRight && contentBottom <= compositionBottom)
+				{
+					if(_hasScrollRect)
+					{
+						_container.scrollRect = null;
+						CONFIG::debug { Debugging.traceFTECall(null,_container,"clearContainerScrollRect()"); }
+						_hasScrollRect = false;
+					}
+				}
+				else 
+				{
+					// don't look at hasScrollRect but do look at scrollRect - client may have messed with it; okay to touch it because about to set it
+					var rect:Rectangle = _container.scrollRect;
+					if (!rect || rect.x != xpos || rect.y != ypos || rect.width != width || rect.height != height)
+					{
+						_container.scrollRect = new Rectangle(xpos, ypos, width, height);
+						CONFIG::debug { Debugging.traceFTECall(null,_container,"setContainerScrollRect",xpos, ypos, width, height); }
+						_hasScrollRect = true;
+					}
+				}
+			}
+			
+			//Fix for Watson 2347938 - re-add the transparent background as the dimension of the
+			//container are altered by sutting down the scrolls in vertical text.
+			this.attachTransparentBackgroundForHit(false);
+		}
+		
+		include "../formats/TextLayoutFormatInc.as";
+		
+		/** 
+		 * The <code>userStyles</code> object for a ContainerController instance.  The getter makes a copy of the 
+		 * <code>userStyles</code> object, which is an array of <em>stylename-value</em> pairs.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		public function get userStyles():Object
+		{
+			var styles:Object = _formatValueHolder == null ? null : _formatValueHolder.userStyles;
+			return styles ? Property.shallowCopy(styles) : null;
+		}
+		public function set userStyles(styles:Object):void
+		{
+			var newStyles:Object = new Object();
+			for (var val:Object in styles)
+				newStyles[val] = styles[val];
+			writableTextLayoutFormatValueHolder().userStyles = newStyles;
+			formatChanged(); // modelChanged(ModelChange.USER_STYLE_CHANGED,0,this.textLength,true);
+		}
+
+		/** Returns the <code>coreStyles</code> on this ContainerController.  Note that the getter makes a copy of the core 
+		 * styles dictionary. The coreStyles object encapsulates those formats that are defined by TextLayoutFormat. The
+		 * <code>coreStyles</code> object consists of an array of <em>stylename-value</em> pairs.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function get coreStyles():Object
+		{
+			var styles:Object = _formatValueHolder == null ? null : _formatValueHolder.coreStyles;
+			return styles ? Property.shallowCopy(styles) : null;
+		}		
+		
+		/** 
+		 * Stores the ITextLayoutFormat object that contains the attributes for this container. 
+		 * The controller inherits the container properties from the TextFlow of which it is part. 
+		 * This property allows different controllers in the same text flow to have, for example, 
+		 * different column settings or padding.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see flashx.textLayout.formats.ITextLayoutFormat
+	 	 */
+		public function get format():ITextLayoutFormat
+		{ return _formatValueHolder; }
+		public function set format(value:ITextLayoutFormat):void
+		{
+			formatInternal = value;
+			formatChanged();
+		}
+		
+		private function writableTextLayoutFormatValueHolder():FlowValueHolder
+		{
+			if (_formatValueHolder == null)
+				_formatValueHolder = new FlowValueHolder();
+			return _formatValueHolder;
+		}
+
+		/** Sets the _format data member. No side effects.
+		 * @private
+		 */
+		tlf_internal function set formatInternal(value:ITextLayoutFormat):void
+		{	
+			if (value == null)
+			{
+				if (_formatValueHolder == null || _formatValueHolder.coreStyles == null)
+					return; // no change
+				_formatValueHolder.coreStyles = null;
+			}
+			else
+				writableTextLayoutFormatValueHolder().format = value;
+		}
+
+		/** Returns the value of the style specified by the <code>styleProp</code> parameter.
+		 *
+		 * @param styleProp The name of the style property whose value you want.
+		 *
+		 * @return	The current value for the specified style.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		public function getStyle(styleProp:String):*
+		{
+			if (TextLayoutFormat.description.hasOwnProperty(styleProp))
+				return computedFormat[styleProp];
+			return getUserStyleWorker(styleProp);
+		}
+		
+		/** 
+		* Sets the value of the style specified by the <code>styleProp</code> parameter to the value
+		* specified by the <code>newValue</code> parameter.
+		*
+		* @param styleProp The name of the style property whose value you want to set.
+		* @param newValue The value that you want to assign to the style.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+		*/
+		
+		public function setStyle(styleProp:String,newValue:*):void
+		{
+			if (TextLayoutFormat.description[styleProp] !== undefined)
+				this[styleProp] = newValue;
+			else
+			{
+				_formatValueHolder.setUserStyle(styleProp,newValue);
+				formatChanged(); // modelChanged(ModelChange.USER_STYLE_CHANGED,0,this.textLength,true);
+			}
+		}
+		
+		/** Clears the style specified by <code>styleProp</code> from this FlowElement. Sets the value to
+		 * <code>undefined</code>.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		public function clearStyle(styleProp:String):void
+		{ setStyle(styleProp,undefined); }
+		
+		/** @private worker function - any styleProp */
+		tlf_internal function getUserStyleWorker(styleProp:String):*
+		{
+			CONFIG::debug { assert(TextLayoutFormat.description[styleProp] === undefined,"bad call to getUserStyleWorker"); }
+				
+			var userStyle:* = _formatValueHolder.getUserStyle(styleProp)
+			if (userStyle !== undefined)
+				return userStyle;
+				
+			var tf:TextFlow = _rootElement ? _rootElement.getTextFlow() : null;
+			if (tf && tf.formatResolver)
+			{
+				userStyle = tf.formatResolver.resolveUserFormat(this,styleProp);
+				if (userStyle !== undefined)
+					return userStyle;
+			}
+			// or should it go to the container?
+			return _rootElement ? _rootElement.getUserStyleWorker(styleProp) : undefined;
+		}
+		
+		/** 
+		 * Returns an ITextLayoutFormat instance with the attributes applied to this container, including the attributes inherited from its
+   		 * root element.
+		 * 
+		 * @return 	object that describes the container's attributes.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see #rootElement
+	 	 */
+		public function get computedFormat():ITextLayoutFormat
+		{
+			if (!_computedFormat)
+			{
+				FlowElement._scratchTextLayoutFormat.format = formatForCascade;
+				var element:FlowElement = _rootElement;
+				if (element)
+				{
+					while (1)
+					{
+						var attrs:ITextLayoutFormat = ContainerFormattedElement(element).formatForCascade;
+						if (attrs)
+							FlowElement._scratchTextLayoutFormat.concatInheritOnly(attrs);
+						if (element.parent == null)
+							break;
+						element = element.parent;
+					}
+				}
+				var defaultFormat:ITextLayoutFormat;
+				var defaultFormatHash:uint;
+				var tf:TextFlow = element as TextFlow;
+				if (tf)
+				{
+					defaultFormat = tf.getDefaultFormat();
+					defaultFormatHash = tf.getDefaultFormatHash();
+				}
+				_computedFormat= TextFlow.getCanonical(FlowElement._scratchTextLayoutFormat,defaultFormat,defaultFormatHash);
+				
+				resetColumnState();
+			}
+			return _computedFormat;
+		}
+		
+		/** @private */
+		tlf_internal function get formatForCascade():ITextLayoutFormat
+		{
+			if (_rootElement)
+			{
+				var tf:TextFlow = _rootElement.getTextFlow();
+				if (tf)
+				{
+					var elemStyle:ITextLayoutFormat  = tf.getTextLayoutFormatStyle(this);
+					if (elemStyle)
+					{
+						var localFormat:ITextLayoutFormat = format;
+						if (localFormat == null)
+							return elemStyle;
+							
+						var rslt:TextLayoutFormat = new TextLayoutFormat(elemStyle);
+						rslt.apply(localFormat);
+						return rslt;
+					}
+				}
+			}
+			return format;
+		}
+		
+		/** @private */
+		tlf_internal function getPlacedTextLineBounds(textLine:TextLine):Rectangle
+		{
+			var curBounds:Rectangle;
+			if (!textLine.parent)
+			{
+				// Has to be in the container to get the bounds
+				addTextLine(textLine,0);
+				curBounds = textLine.getBounds(_container);
+				removeTextLine(textLine);
+			}
+			else
+			{
+				// Note: Relative to its parent, which may not be _container
+				// but in all reasonable cases, should share its origin with _container -- really???
+				curBounds = textLine.getBounds(textLine.parent);
+			}
+				
+			return curBounds;
+		}
+			
+		/** @private */
+		tlf_internal function getInteractionHandler():IInteractionEventHandler
+		{ return this; }
+	}
+
+}
+import flash.events.MouseEvent;
+import flash.display.InteractiveObject;
+	
+class PsuedoMouseEvent extends MouseEvent
+{
+	public function PsuedoMouseEvent(type:String, bubbles:Boolean = true, cancelable:Boolean = false, localX:Number = NaN, localY:Number = NaN, relatedObject:InteractiveObject = null, ctrlKey:Boolean = false, altKey:Boolean = false, shiftKey:Boolean = false, buttonDown:Boolean = false)
+	{
+		super(type,bubbles,cancelable,localX,localY,relatedObject,ctrlKey,altKey,shiftKey,buttonDown);
+	}
+	public override function get currentTarget():Object
+	{ return relatedObject; }
+	public override function get target():Object
+	{ return relatedObject; }
+}
diff --git a/textLayout_core/src/flashx/textLayout/container/ISandboxSupport.as b/textLayout_core/src/flashx/textLayout/container/ISandboxSupport.as
new file mode 100755
index 0000000..87394c2
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/container/ISandboxSupport.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 flashx.textLayout.container
+{
+	import flash.events.Event;
+	/** Interface to support TLF content in a sub-application. When an application is loaded in an untrusted context,
+	 * mouse events that occur outside of the untrusted application's bounds are not delivered. Clients can handle this
+	 * by implementing ISandboxSupport. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 * 
+	 * @see flashx.textLayout.container.ContainerController
+	 * @see flashx.textLayout.container.TextContainerManager
+	 * @see flashx.textLayout.edit.SelectionManager
+	 * @see flash.system.SecurityDomain
+	 */
+	public interface ISandboxSupport
+	{
+		/** 
+		 * Called to request clients to begin the forwarding of mouseup and mousemove events from outside a security sandbox.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 */
+		function beginMouseCapture():void;
+		/** 
+		 * Called to inform clients that the the forwarding of mouseup and mousemove events from outside a security sandbox is no longer needed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 */
+		function endMouseCapture():void;
+		/** Client call to forward a mouseUp event from outside a security sandbox.  Coordinates of the mouse up are not needed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 */
+		function mouseUpSomewhere(event:Event):void;
+		/** Client call to forward a mouseMove event from outside a security sandbox.  Coordinates of the mouse move are not needed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 */
+		function mouseMoveSomewhere(event:Event):void;
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/container/ScrollPolicy.as b/textLayout_core/src/flashx/textLayout/container/ScrollPolicy.as
new file mode 100755
index 0000000..462455d
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/container/ScrollPolicy.as
@@ -0,0 +1,83 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.container
+{
+	import flashx.textLayout.property.EnumStringProperty;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+
+	/**
+	 *  The ScrollPolicy class is an enumeration class that defines values for setting the <code>horizontalScrollPolicy</code> and 
+	 *  <code>verticalScrollPolicy</code> properties of the ContainerController class, which defines a text flow 
+	 *  container. 
+	 *
+	 *  @see ContainerController#horizontalScrollPolicy
+	 *  @see ContainerController#verticalScrollPolicy
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public final class ScrollPolicy
+	{
+		/** 
+		 * Specifies that scrolling is to occur if the content exceeds the container's dimension. The runtime calculates 
+		 * the number of lines that overflow the container and the user can navigate to them with cursor keys, by drag selecting,
+		 * or by rotating the mouse wheel. You can also cause scrolling to occur by setting the corresponding position value, 
+		 * either <code>ContainerController.horizontalScrollPosition</code> or <code>ContainerController.verticalScrollPosition</code>. Also, the runtime can automatically 
+		 * scroll the contents of the container during editing.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public static const AUTO:String = "auto";
+		
+		/** 
+		 * Causes the runtime to not display overflow lines, which means that the user cannot navigate to them. 
+		 * In this case, setting the corresponding <code>ContainerController.horizontalScrollPosition</code> and 
+		 * <code>ContainerController.verticalScrollPosition</code> properties have no effect. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public static const OFF:String = "off";
+		
+		/** 
+		 * Specifies that scrolling is available to access content that exceeds the container's dimension. The runtime calculates the 
+		 * number of lines that overflow the container and allows the user to scroll them into view with the cursor keys, by drag selecting, 
+		 * or by rotating the mouse wheel. You can also scroll by setting the corresponding position value, either 
+		 * <code>ContainerController.horizontalScrollPosition</code> or <code>ContainerController.verticalScrollPosition</code>. Also, the runtime can automatically scroll the contents 
+		 * of the container during editing.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public static const ON:String = "on";		
+		
+		/** Shared definition of the scrollPolicy property. @private */
+		static tlf_internal const scrollPolicyPropertyDefinition:EnumStringProperty = new EnumStringProperty("scrollPolicy", ScrollPolicy.AUTO, false, null, 
+			ScrollPolicy.AUTO, ScrollPolicy.OFF, ScrollPolicy.ON);	
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/debug/Debugging.as b/textLayout_core/src/flashx/textLayout/debug/Debugging.as
new file mode 100755
index 0000000..6548256
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/debug/Debugging.as
@@ -0,0 +1,206 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.debug 
+{
+	[ExcludeClass]
+	/** @private */
+	public class Debugging 
+	{
+		import flash.utils.Dictionary;
+		import flashx.textLayout.tlf_internal;
+		
+		use namespace tlf_internal;
+		
+		CONFIG::debug 
+		{
+			static tlf_internal var debugOn:Boolean = true;
+			static tlf_internal var traceFlag:Boolean = false;	
+			static tlf_internal var verbose:Boolean = false;	
+			static tlf_internal var throwOnAssert:Boolean = false;
+			static tlf_internal var containerLineValidation:Boolean = false;
+			
+			static private var traceOutString:String;
+			static private var traceChanged:Function = null;
+			
+			
+			static public function traceOut(str:String, ...rest):void
+			{
+				if (!traceOutString)
+					traceOutString = new String();
+				for each (var obj:Object in rest)
+				{
+					str += obj.toString();
+					str += " ";
+				}
+
+				traceOutString += str + "\n";
+				if (traceChanged != null)
+					traceChanged(traceOutString);
+				else
+					trace(str);
+			}
+			
+			static public function setTraceChanged(listener:Function):void
+			{
+				traceChanged = listener;
+			}
+
+			// ///////////////////////////////
+			// support creating a log of calls 
+			// //////////////////////////////
+			
+			static tlf_internal var generateDebugTrace:Boolean = false;
+			static private var idDictionary:Dictionary = new Dictionary(true);
+			static private var nextKey:int = 1;
+			static private var callCount:int = 1;
+		
+			static private const vectPrefix:String = "__AS3__.vec::Vector";
+			static private function getClassForIdentity(o:Object):String
+			{
+				var s:String = flash.utils.getQualifiedClassName(o);
+				if (s.substr(0,vectPrefix.length) == vectPrefix)
+				{
+					s = s.substr( s.lastIndexOf(":")+1);
+					return "VectorOf" + s.substr(0,s.length-1);
+				}
+				return s.substr( s.lastIndexOf(":")+1);
+			}
+			
+			static tlf_internal function getIdentity(o:Object):String
+			{
+				if (idDictionary[o] == null)
+				{
+					var s:String = getClassForIdentity(o);
+					idDictionary[o] = "my" + s + nextKey.toString();
+					nextKey++;
+				}
+				return idDictionary[o];
+			}
+			
+			static tlf_internal function getClassForType(o:Object):String
+			{
+				var s:String = flash.utils.getQualifiedClassName(o);
+				if (s.substr(0,vectPrefix.length) == vectPrefix)
+				{
+					s = s.substr( s.lastIndexOf(":")+1);
+					return "Vector.<" + s ;
+				}
+				return s.substr( s.lastIndexOf(":")+1);
+			}
+			
+			static tlf_internal function makeParameter(obj:Object):String
+			{
+				var str:String;
+				if (obj == null)
+					str = "null"
+				else if (obj is String)
+				{
+					var tempString:String = String(obj);
+					var idx:int;
+					
+					// any out of bounds characters?
+					var allokay:Boolean = true;
+					for (idx = 0; idx < tempString.length; idx++)
+					{
+						if (tempString.charCodeAt(idx) > 0xFF)
+						{
+							allokay = false;
+							break;
+						}
+					}
+					if (allokay)
+						str = "\"" + tempString +  "\"";
+					else
+					{
+						str = "String.fromCharCode("
+						for (idx = 0; idx < tempString.length; idx++)
+						{
+							if (idx != 0)
+								str += ", ";
+							str += "0x" + tempString.charCodeAt(idx).toString(16);
+						}
+						str += ")";
+					}
+				}
+				else if (obj is Number || obj is int)
+					str = obj.toString();
+				else if (obj is Boolean)
+					str = Boolean(obj) ? "true" : "false";
+				else 
+					str = getIdentity(obj);
+				return str;
+			}
+			
+			/** @private Trace a function call */
+			static tlf_internal function traceFTECall(rslt:Object,target:Object,method:String,...rest):void
+			{
+				if (!generateDebugTrace)
+					return;
+					
+				// if result already exists then null it out - its a side effect
+				if (idDictionary[rslt] != null)
+					rslt = null;
+				var str:String = "	";
+				var rsltType:String;
+				if (rslt)
+				{
+					rsltType = getClassForType(rslt);
+					str += "var " + getIdentity(rslt) + ":" + getClassForType(rslt) + " = ";
+				}
+				
+				if (target)
+					str += getIdentity(target) + ".";
+				
+				if (rest.length == 0)
+				{
+					str += method + ";";
+				}
+				else
+				{
+					str += method + "(";
+					for (var i:int =0; i<rest.length; i++)
+					{
+						if (i != 0)
+							str += ","
+						str += makeParameter(rest[i]);
+					}
+	
+					if (rslt)
+						str += ") as " + rsltType + ";"; 
+					else
+						str += ");"
+				}
+				str += " // " + callCount.toString();
+				trace(str);
+				callCount++;
+			}
+			
+			/** @private Trace a property assignment */
+			static tlf_internal function traceFTEAssign(target:Object,prop:String,val:Object):void
+			{
+				if (!generateDebugTrace)
+					return;
+					
+				var str:String = "	" + getIdentity(target) + "." + prop + " = " + makeParameter(val) + ";" +  "// " + callCount.toString();
+				trace(str);
+				callCount++;
+			}
+		}
+	}
+} // end package
diff --git a/textLayout_core/src/flashx/textLayout/debug/assert.as b/textLayout_core/src/flashx/textLayout/debug/assert.as
new file mode 100755
index 0000000..4aa2738
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/debug/assert.as
@@ -0,0 +1,46 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.debug 
+{
+	import flashx.textLayout.tlf_internal;
+		
+	use namespace tlf_internal;
+
+	/** @private
+	 *  Debug only function that prints a trace message if condition is false.
+	 *  @return count of errors reported this assert: 1 or 0.
+	 * */
+	CONFIG::debug public function assert(condition:Boolean, warning:String):int
+	{
+		if (!condition)
+		{
+			trace("ERROR: " + warning);
+			// throw if the bit is set
+			if (Debugging.throwOnAssert)
+				throw(new Error("TextLayoutAssert: " + warning));
+			return 1;
+		}
+		return 0;
+	}
+	/** @private */
+	CONFIG::release 
+	public function assert():void 
+	{
+	} 
+} // end package
diff --git a/textLayout_core/src/flashx/textLayout/edit/EditingMode.as b/textLayout_core/src/flashx/textLayout/edit/EditingMode.as
new file mode 100755
index 0000000..34eaeb6
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/edit/EditingMode.as
@@ -0,0 +1,60 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.edit
+{
+	/** 
+	 * The EditingMode class defines constants used with EditManager class to represent the 
+	 * read, select, and edit permissions of a document.
+	 * 
+	 * @see flashx.textLayout.edit.EditManager
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */
+	public final class EditingMode
+	{
+		/** 
+		 * The document is read-only.
+		 * 
+		 * <p>Neither selection nor editing is allowed.</p> 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public static const READ_ONLY:String = "readOnly";
+		/** 
+		 * The document can be edited.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public static const READ_WRITE:String = "readWrite";
+		/** 
+		 * The text in the document can be selected and copied, but not edited. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public static const READ_SELECT:String = "readSelect";			
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/edit/IInteractionEventHandler.as b/textLayout_core/src/flashx/textLayout/edit/IInteractionEventHandler.as
new file mode 100755
index 0000000..b9c558e
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/edit/IInteractionEventHandler.as
@@ -0,0 +1,212 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.edit
+{
+	import flash.events.ContextMenuEvent;
+	import flash.events.Event;
+	import flash.events.FocusEvent;
+	import flash.events.IMEEvent;
+	import flash.events.KeyboardEvent;
+	import flash.events.MouseEvent;
+	import flash.events.TextEvent;
+	
+	/**
+	 * The IInteractionEventHandler interface defines the event handler functions that
+	 * are handled by a Text Layout Framework selection or edit manager.
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public interface IInteractionEventHandler
+	{
+		/** 
+		 * Processes an edit event.
+		 * 
+		 * <p>Edit events are dispatched for cut, copy, paste, and selectAll commands.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */	
+		function editHandler(event:Event):void;
+		
+		/** 
+		* Processes a keyDown event.
+		*  
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+		*/	
+		function keyDownHandler(event:KeyboardEvent):void;
+		
+		/** 
+		* Processes a keyUp event.
+		* 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+		*/	
+		function keyUpHandler(event:KeyboardEvent):void;		
+		
+		/** 
+		* Processes a keyFocusChange event.
+		* 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+		*/	
+		function keyFocusChangeHandler(event:FocusEvent):void;
+		
+		/** 
+		 * Processes a TextEvent.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function textInputHandler(event:TextEvent):void;
+
+		/** 
+		 * Processes an imeStartComposition event
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function imeStartCompositionHandler(event:IMEEvent):void;
+		
+		/** 
+		 * Processes a mouseDown event.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */	
+		function mouseDownHandler(event:MouseEvent):void;
+
+		/** 
+		 * Processes a mouseMove event.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */	
+		function mouseMoveHandler(event:MouseEvent):void;
+		
+		/** 
+		 * Processes a mouseUp event.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */	
+		function mouseUpHandler(event:MouseEvent):void;		
+		
+		/** 
+		 * Processes a mouseDoubleClick event.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */	
+		function mouseDoubleClickHandler(event:MouseEvent):void;
+
+		/** 
+		 * Processes a mouseOver event.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */			
+		function mouseOverHandler(event:MouseEvent):void;
+
+		/** 
+		 * Processes a mouseOut event.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */					
+		function mouseOutHandler(event:MouseEvent):void;
+		
+		/** 
+		 * Processes a focusIn event.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function focusInHandler(event:FocusEvent):void;
+		 
+		/** 
+		 * Processes a focusOut event.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function focusOutHandler(event:FocusEvent):void;
+
+		/** 
+		 * Processes an activate event.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */				
+		function activateHandler(event:Event):void;
+		
+		/** 
+		 * Processes a deactivate event.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */				
+		function deactivateHandler(event:Event):void;
+		
+		/** 
+		 * Processes a focusChange event.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */				
+		function focusChangeHandler(event:FocusEvent):void
+		
+		/** 
+		 * Processes a menuSelect event.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */				
+		function menuSelectHandler(event:ContextMenuEvent):void
+		
+		/** 
+		 * Processes a mouseWheel event.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */				
+		function mouseWheelHandler(event:MouseEvent):void
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/edit/ISelectionManager.as b/textLayout_core/src/flashx/textLayout/edit/ISelectionManager.as
new file mode 100755
index 0000000..debf89f
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/edit/ISelectionManager.as
@@ -0,0 +1,384 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.edit
+{
+	import flash.display.InteractiveObject;
+	import flash.events.Event;
+	import flash.events.FocusEvent;
+	import flash.events.KeyboardEvent;
+	import flash.events.MouseEvent;
+	import flash.events.TextEvent;
+	
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.elements.TextRange;
+
+	/** 
+	 * The ISelectionManager interface defines the interface for handling text selection.
+	 * 
+	 * <p>A SelectionManager keeps track of the selected text range and handles events for a TextFlow.</p>
+	 * 
+	 * <p>A selection can be either a point selection or a range selection. A point selection is the insertion point
+	 * and is indicated visually by drawing a cursor. A range
+	 * selection includes the text between an anchor point and an active point.</p>
+	 * 
+	 * @see flashx.textLayout.edit.SelectionManager
+	 * @see flashx.textLayout.edit.TextScrap
+	 * @see flashx.textLayout.elements.TextFlow
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */
+	public interface ISelectionManager extends IInteractionEventHandler
+	{		
+		/** 
+		 * The TextFlow object managed by this selection manager. 
+		 * 
+		 * <p>A selection manager manages a single text flow. A selection manager can also be
+		 * assigned to a text flow by setting the <code>interactionManager</code> property of the
+		 * TextFlow object.</p>
+		 * 
+		 * @see flashx.textLayout.elements.TextFlow#interactionManager
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function get textFlow():TextFlow;
+		function set textFlow(flow:TextFlow):void;
+		
+		/** 
+		 * The text position of the start of the selection, as an offset from the start of the text flow.
+		 *  
+		 * <p>The absolute start is the same as either the active or the anchor point of the selection, whichever comes
+		 * first in the text flow.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function get absoluteStart() : int;
+		/** 
+		 * The text position of the end of the selection, as an offset from the start of the text flow.
+		 *  
+		 * <p>The absolute end is the same as either the active or the anchor point of the selection, whichever comes
+		 * last in the text flow.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function get absoluteEnd() : int;
+
+		/**
+		 * Selects a range of text.
+		 * 
+		 * <p>If a negative number is passed as either of the parameters, then any existing selection is
+		 * removed.</p>
+		 * 
+		 * @param anchorPosition	The anchor point for the new selection, as an absolute position in the TextFlow 
+		 * @param activePosition	The active end of the new selection, as an absolute position in the TextFlow
+		 * 
+		 * @includeExample examples\SelectionManager_setSelection.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function selectRange(anchorPosition:int, activePosition:int) : void
+		
+		/**
+		 * Selects the entire flow
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function selectAll() : void
+		
+		/** 
+		 * The anchor point of the selection. 
+		 * 
+		 * <p>An <em>anchor</em> point is the stable end of the selection. When the selection
+		 * is extended, the anchor point does not change. The anchor point can be at either the beginning 
+		 * or the end of the selection.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */								
+		function get anchorPosition() : int;
+
+		/** 
+		 * The active point of the selection.
+		 * 
+		 * <p>The <em>active</em> point is the volatile end of the selection. The active point is changed 
+		 * when the selection is modified. The active point can be at either the beginning 
+		 * or the end of the selection.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */										
+		function get activePosition() : int;
+		
+		/**
+		 * Indicates whether there is a selection. 
+		 * 
+		 * <p>Returns <code>true</code> if there is either a range selection or a point selection. 
+		 * By default, when a selection manager is first set up, there is no selection (the start and end are -1).</p>
+		 * 
+		 * @includeExample examples\SelectionManager_hasSelection.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function hasSelection():Boolean;
+		
+		/**
+		 * Indicates whether the selection covers a range of text.
+		 * 
+		 * <p>Returns <code>true</code> if there is a selection that extends past a single position.</p> 
+		 * 
+		 * @includeExample examples\SelectionManager_isRangeSelection.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function isRangeSelection():Boolean;
+		
+		/**
+		 * Gets the SelectionState object of the current selection.
+		 * 
+		 * @includeExample examples\SelectionManager_getSelectionState.as -noswf
+		 * 
+		 * @see flashx.textLayout.edit.SelectionState
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function getSelectionState():SelectionState;
+		
+		/**
+		 * Sets the SelectionState object of the current selection.
+		 * 
+		 * @see flashx.textLayout.edit.SelectionState
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function setSelectionState(state:SelectionState):void;
+
+		/** 
+		 * Redisplays the selection shapes. 
+		 * 
+		 * <p><b>Note:</b> You do not need to call this method directly. It is called automatically.</p>	
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */	
+		function refreshSelection():void;
+
+
+		/** 
+		 * Gives the focus to the first container in the selection.
+		 *  
+		 * @includeExample examples\SelectionManager_setFocus.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+ 		 */
+		function setFocus():void;
+		
+		/** 
+		 * Indicates whether a container in the text flow has the focus.
+		 * 
+		 * <p>The <code>focused</code> property is <code>true</code> 
+		 * if any of the containers in the text flow has key focus.</p> 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function get focused():Boolean;
+		
+		/** 
+		 * Indicates whether the window associated with the text flow is active.
+		 * 
+		 * <p>The <code>windowActive</code> property is <code>true</code> if the window 
+		 * displaying with the text flow is the active window.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function get windowActive():Boolean;
+		
+		/** 
+		 * The current SelectionFormat object.
+		 * 
+		 * <p>The current SelectionFormat object is chosen from the SelectionFormat objects assigned to the 
+		 * <code>unfocusedSelectionFormat</code>, <code>inactiveSelectionFormat</code> and <code>focusedSelectionFormat</code> 
+		 * properties based on the current state of the <code>windowActive</code> and <code>focused</code> properties.</p> 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function get currentSelectionFormat():SelectionFormat;
+
+		/**
+		 * Gets the character format attributes that are common to all characters in the specified text range or current selection.
+		 * 
+		 * <p>Format attributes that do not have the same value for all characters in the specified element range or selection are set to 
+		 * <code>null</code> in the returned ITextLayoutFormat instance.</p>
+		 * 
+		 * @param range The optional range of text for which common attributes are requested. If null, the current selection is used. 
+		 * @return The common character style settings
+		 * 
+		 * @includeExample examples\SelectionManager_getCommonCharacterFormat.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function getCommonCharacterFormat (range:TextRange=null):ITextLayoutFormat;
+		 
+		 /**
+		 * Gets the paragraph format attributes that are common to all paragraphs in the specified text range or current selection.
+		 * 
+		 * <p>Format attributes that do not have the same value for all paragraphs in the specified element range or selection are set to 
+		 * <code>null</code> in the returned ITextLayoutFormat instance.</p>
+		 * 
+		 * @param range The optional range of text for which common attributes are requested. If null, the current selection is used. 
+		 * @return The common paragraph style settings
+		 * 
+		 * @includeExample examples\SelectionManager_getCommonParagraphFormat.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function getCommonParagraphFormat (range:TextRange=null):ITextLayoutFormat;
+		 
+		/**
+		 * Gets the container format attributes that are common to all containers in the specified text range or current selection.
+		 * 
+		 * <p>Format attributes that do not have the same value for all containers in the specified element range or selection are set to 
+		 * <code>null</code> in the returned ITextLayoutFormat instance.</p>
+		 * 
+		 * @param range The optional range of text for which common attributes are requested. If null, the current selection is used. 
+		 * @return The common container style settings
+		 * 
+		 * @includeExample examples\SelectionManager_getCommonContainerFormat.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function getCommonContainerFormat (range:TextRange=null):ITextLayoutFormat;
+
+		/**
+		 * The editing mode. 
+		 * 
+		 * <p>The editing mode indicates whether the text flow supports selection, editing, or only reading.
+		 * A text flow is made selectable by assigning a selection manager and editable by assigning an edit manager.
+		 * Constants representing the editing modes are defined in the EditingMode class.</p>
+		 * 
+		 * @see flashx.textLayout.EditingMode
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		 function get editingMode():String;		
+		
+		/**
+		 * The SelectionFormat object used to draw the selection in a focused container. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */		 
+		 function get focusedSelectionFormat():SelectionFormat;
+		 function set focusedSelectionFormat(val:SelectionFormat):void;
+		 
+		/**
+		 * The SelectionFormat object used to draw the selection when it is not in a focused container, but is in
+		 * the active window.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */		 		 
+		 function get unfocusedSelectionFormat():SelectionFormat;
+		 function set unfocusedSelectionFormat(val:SelectionFormat):void;
+		 
+		/**
+		 * The SelectionFormat object used to draw the selection when it is not in the active window.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */		 		 
+		 function get inactiveSelectionFormat():SelectionFormat;
+		 function set inactiveSelectionFormat(val:SelectionFormat):void;		 		 
+		
+		/**
+		 * Executes any pending FlowOperations. 
+		 * 
+		 * <p>The execution of some editing operations, such as text insertion, is delayed 
+		 * until the next enterFrame event. Calling <code>flushPendingOperations()</code> causes any deferred operations to be executed 
+		 * immediately.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 * 
+		 */
+		function flushPendingOperations():void;
+
+		/** 
+		 * Updates the selection manager when text is inserted or deleted.
+		 * 
+		 * <p>Operations must call <code>notifyInsertOrDelete</code> when changing the text in the text flow. 
+		 * The selection manager adjusts index-based position indicators accordingly. If you create a new Operation
+		 * class that changes text in a text flow directly (not using another operation) your operation must call this function 
+		 * to keep the selection up to date.</p>
+		 * 
+		 * @param absolutePosition	The point in the text where the change was made.
+		 * @param length A positive or negative number indicating how many characters were inserted or deleted.
+		 * 
+		 * @includeExample examples\SelectionManager_notifyInsertOrDelete.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function notifyInsertOrDelete(absolutePosition:int, length:int):void		 
+		 	
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/edit/SelectionFormat.as b/textLayout_core/src/flashx/textLayout/edit/SelectionFormat.as
new file mode 100755
index 0000000..efe5bd7
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/edit/SelectionFormat.as
@@ -0,0 +1,207 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.edit
+{
+	import flash.display.BlendMode;
+	
+	/**
+	 * The SelectionFormat class defines the properties of a selection highlight.
+	 * 
+	 * @see flashx.textLayout.edit.ISelectionManager
+	 * @see flashx.textLayout.edit.SelectionManager
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */
+	public class SelectionFormat
+	{
+		private var _rangeColor:uint;
+		private var _rangeAlpha:Number;
+		private var _rangeBlendMode:String;
+		
+		private var _pointColor:uint;
+		private var _pointAlpha:Number;
+		private var _pointBlendMode:String;
+		private var _pointBlinkRate:Number;
+		
+		/** 
+		 * Creates a SelectionFormat object with the specified properties.
+		 * 
+		 * <p>A SelectionFormat created with the default values will use black for
+		 * the highlight colors, 1.0 for the alphas, and BlendMode.DIFFERENCE for the blending modes.
+		 * The cursor blink rate is 500 milliseconds.</p>
+		 *
+		 * <p>Setting the <code>pointAlpha</code> and <code>rangeAlpha</code> properties to zero disables selection highlighting.</p>
+		 * 
+		 * @param rangeColor The color for drawing the highlight.
+		 * @param rangeAlpha The transparency value for drawing the highlight. Valid values are between 0
+		 * (completely transparent) and 1 (completely opaque, which is the default).
+		 * @param rangeBlendMode The blend mode for drawing the highlight. Use constants defined in the BlendMode class
+		 * to set this parameter.
+		 * @param pointColor The color for the drawing cursor.
+		 * @param pointAlpha The transparency value for drawing the cursor. Valid values are between 0
+		 * (completely transparent) and 1 (completely opaque, which is the default).
+		 * @param pointBlendMode The blend mode for drawing the cursor. Use constants defined in the BlendMode class
+		 * to set this parameter.
+		 * @param pointBlinkRate The rate at which the cursor blinks, in milliseconds.
+		 * 
+		 * @see flash.display.BlendMode
+		 * @see #pointAlpha
+		 * @see #rangeAlpha
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function SelectionFormat(rangeColor:uint=0xffffff, rangeAlpha:Number=1.0, rangeBlendMode:String="difference", pointColor:uint=0xffffff, pointAlpha:Number=1.0, pointBlendMode:String="difference", pointBlinkRate:Number = 500)
+		{ 
+			_rangeColor = rangeColor;
+			_rangeAlpha = rangeAlpha;
+			_rangeBlendMode = rangeBlendMode;
+			
+			_pointColor = pointColor;
+			_pointAlpha = pointAlpha;
+			_pointBlendMode = pointBlendMode;
+			_pointBlinkRate = pointBlinkRate;
+		}
+		
+		/**
+		 * The color for drawing the highlight of a range selection. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */		
+		public function get rangeColor():uint
+		{
+			return _rangeColor;
+		}
+
+		/**
+		 * The alpha for drawing the highlight of a range selection. Valid values are between 0
+		 * (completely transparent) and 1 (completely opaque, which is the default).
+		 *
+		 * <p>Setting the <code>pointAlpha</code> and <code>rangeAlpha</code> properties to zero disables selection highlighting.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 	 	 *
+ 	 	 * @see #pointAlpha
+		 */						
+		public function get rangeAlpha():Number
+		{
+			return _rangeAlpha;
+		}
+
+		/**
+		 * The blending mode for drawing the highlight of a range selection. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 * @see flash.display.BlendMode
+		 */						
+		public function get rangeBlendMode():String
+		{
+			return _rangeBlendMode;
+		}
+		
+		/**
+		 * The color for drawing the cursor.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */		
+		public function get pointColor():uint
+		{
+			return _pointColor;
+		}
+
+		/**
+		 * The alpha for drawing the cursor. Valid values are between 0
+		 * (completely transparent) and 1 (completely opaque, which is the default).
+		 *
+		 * <p>Setting the <code>pointAlpha</code> and <code>rangeAlpha</code> properties to zero disables selection highlighting.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 	 	 *
+ 	 	 * @see #rangeAlpha
+		 */						
+		public function get pointAlpha():Number
+		{
+			return _pointAlpha;
+		}
+		
+		/**
+		 * The rate at which the cursor blinks, in milliseconds.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */						
+		public function get pointBlinkRate():Number
+		{
+			return _pointBlinkRate;
+		}		
+
+		/**
+		 * The blend mode for drawing the cursor.
+		 * 
+		 * @see flash.display.BlendMode
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */						
+		public function get pointBlendMode():String
+		{
+			return _pointBlendMode;
+		}
+
+		/**
+		 * Determines whether this SelectionFormat object has the same property values
+		 * as another SelectionFormat object.
+		 *  
+		 * @return <code>true</code>, if the property values are identical; <code>false</code>, otherwise.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 * 
+		 * @param selectionFormat	the SelectionFormat to compare against.
+		 */								
+		public function equals(selectionFormat:SelectionFormat):Boolean
+		{
+			if ((_rangeBlendMode == selectionFormat.rangeBlendMode) &&
+				(_rangeAlpha == selectionFormat.rangeAlpha) &&
+				(_rangeColor == selectionFormat.rangeColor) &&
+				(_pointColor == selectionFormat.pointColor) &&
+				(_pointAlpha == selectionFormat.pointAlpha) &&
+				(_pointBlendMode == selectionFormat.pointBlendMode) &&
+				(_pointBlinkRate == selectionFormat.pointBlinkRate))
+				return true;
+			return false;
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/edit/SelectionState.as b/textLayout_core/src/flashx/textLayout/edit/SelectionState.as
new file mode 100755
index 0000000..0044250
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/edit/SelectionState.as
@@ -0,0 +1,130 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.edit
+{
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.elements.TextRange;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+	
+	import flashx.textLayout.tlf_internal;
+	use namespace tlf_internal;
+	/**
+	 * The SelectionState class represents a selection in a text flow.  
+	 * 
+	 * <p>A selection range has an anchor point, representing the point at which the selection of text began, and an
+	 * active point, representing the point to which the selection is extended. The active point can be before or after 
+	 * the anchor point in the text. If a selection is modified (for example, by a user shift-clicking with the mouse),
+	 * the active point changes while the anchor point always remains in the same position.</p>
+	 *
+	 * @see flashx.textLayout.edit.ISelectionManager#getSelectionState()
+	 * @see flashx.textLayout.elements.TextFlow
+	 * @see flashx.textLayout.elements.TextRange
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+ 	 */
+	public class SelectionState extends TextRange
+	{		
+		/** Format that are associated with the caret position & will be applied to inserted text */
+		private var _pointFormat:ITextLayoutFormat;
+		
+		private var _selectionManagerOperationState:Boolean;
+
+		/** 
+		 * Creates a SelectionState object.
+		 * 
+		 * <p><b>Note:</b> Do not construct a SelectionState object in order to create a selection. To
+		 * create a selection in a text flow, call the <code>setSelection()</code> method of the relevant
+		 * ISelectionManager instance (which is the SelectionManager or EditManager object assigned 
+		 * to the <code>interactionManager</code> property of the text flow).</p>
+		 * 
+		 * @param	root	The TextFlow associated with the selection.
+		 * @param anchorPosition	The anchor index of the selection.
+		 * @param activePosition	The active index of the selection.
+		 * @param	format	The TextLayoutFormat to be applied on next character typed when a point selection
+		 * 
+		 * @see flashx.textLayout.edit.ISelectionManager#getSelectionState()
+		 * @see flashx.textLayout.edit.SelectionManager
+		 * @see flashx.textLayout.edit.EditManager
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */		
+		public function SelectionState(root:TextFlow,anchorPosition:int,activePosition:int,format:ITextLayoutFormat = null)
+		{
+			super(root, anchorPosition, activePosition);
+			if (format && !TextLayoutFormat.isEqual(format, TextLayoutFormat.emptyTextLayoutFormat))
+				_pointFormat = format;
+		}
+		
+		/** 
+		 * Updates the selection range with new anchor or active position values.  
+		 * 
+		 * <p>The <code>pointFormat</code> styles are cleared if the selection is changed.</p>
+		 * 
+		 * @param newAnchorPosition	the anchor index of the selection.
+		 * @param newActivePosition	the active index of the selection.
+		 * @return true if selection is changed
+		 * 
+		 */
+		public override function updateRange(newAnchorPosition:int,newActivePosition:int):Boolean
+		{
+			if (super.updateRange(newAnchorPosition,newActivePosition) )
+			{
+				_pointFormat = null;
+				return true;
+			}
+			return false;
+		}
+		
+		/** 
+		 * The format attributes applied to inserted text. 
+		 * 
+		 * <p><b>Note:</b> The <code>pointFormat</code> object does not include inherited styles. To
+		 * get all the applicable style definitions, use the <code>getCommonCharacterFormat()</code>
+		 * method of the ISelectionManager class.</p>
+		 * 
+		 * @see ISelectionManager#getCommonCharacterFormat()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */												
+		public function get pointFormat():ITextLayoutFormat
+		{ return _pointFormat; }
+		public function set pointFormat(format:ITextLayoutFormat):void
+		{ _pointFormat = format; } 
+		
+		/** @private used to tell an operation that the SelectionState is from the SelectionManager and that the SelectionManager pointFormat should be updated. */
+		tlf_internal function get selectionManagerOperationState():Boolean
+		{ return _selectionManagerOperationState; }
+		/** @private */		
+		tlf_internal function set selectionManagerOperationState(val:Boolean):void
+		{ _selectionManagerOperationState = val; }
+		/** @private */
+		tlf_internal function clone():SelectionState
+		{ return new SelectionState(textFlow,anchorPosition,activePosition,pointFormat); }
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/elements/BackgroundManager.as b/textLayout_core/src/flashx/textLayout/elements/BackgroundManager.as
new file mode 100755
index 0000000..6695725
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/BackgroundManager.as
@@ -0,0 +1,176 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements
+{
+	import flash.display.DisplayObject;
+	import flash.display.DisplayObjectContainer;
+	import flash.display.Shape;
+	import flash.geom.Point;
+	import flash.geom.Rectangle;
+	import flash.text.engine.TextLine;
+	import flash.utils.Dictionary;
+	
+	import flashx.textLayout.compose.TextFlowLine;
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.events.DamageEvent;
+	import flashx.textLayout.formats.BackgroundColor;
+	import flashx.textLayout.tlf_internal;
+	import flashx.textLayout.utils.GeometryUtil;
+	
+	use namespace tlf_internal;
+	
+	[ExcludeClass]
+	/** @private Manages bounds calculation and rendering of backgroundColor character format. */
+	public class BackgroundManager
+	{
+		private var _textFlow:TextFlow;
+		private var _lineDict:Dictionary;
+
+		public function BackgroundManager():void
+		{
+			_lineDict = new Dictionary(true);
+		}	
+			
+		public function set textFlow(t:TextFlow):void
+		{
+			_textFlow = t;
+		}
+		
+		public function get textFlow():TextFlow
+		{
+			return _textFlow;
+		}
+		
+		public function addRect(line:TextFlowLine, fle:FlowLeafElement, r:Rectangle, color:uint, alpha:Number):void
+		{
+			var tl:TextLine = line.getTextLine();
+			
+			if(_lineDict[tl] == null)
+			{
+				_lineDict[tl] = new Array();
+			}
+			var obj:Object = new Object();
+			obj.rect = r;
+			obj.fle = fle;
+			obj.color = color;
+			obj.alpha = alpha;
+			var insert:Boolean = true;
+			var fleAbsoluteStart:int = fle.getAbsoluteStart();
+			
+			for(var i:int = 0; i < _lineDict[tl].length; ++i)
+			{
+				if(_lineDict[tl][i].fle.getAbsoluteStart() == fleAbsoluteStart)
+				{
+					_lineDict[tl][i] = obj;
+					insert = false;
+				}
+			}
+			if(insert)
+			{
+				_lineDict[tl].push(obj);
+			}
+		}
+		
+		public function finalizeLine(line:TextFlowLine):void
+		{ return; }	// nothing to do here
+		
+		/** @private */
+		tlf_internal function get lineDict():Dictionary
+		{
+			return _lineDict;
+		}
+		
+		// This version is used for the TextLineFactory
+		public function drawAllRects(bgShape:Shape,controller:ContainerController):void
+		{
+			for (var line:Object in _lineDict)
+			{
+				var a:Array = _lineDict[line];
+				if(a.length)
+				{
+					var columnRect:Rectangle = a[0].columnRect;	// set in TextLineFactoryBase.finalizeLine
+					var r:Rectangle;
+					var obj:Object;
+					for(var i:int = 0; i<a.length; ++i)
+					{
+						obj = a[i];
+						r = obj.rect;
+						r.x += line.x;
+						r.y += line.y;
+						TextFlowLine.constrainRectToColumn(textFlow, r, columnRect, 0, 0, controller.compositionWidth, controller.compositionHeight)						
+						
+						bgShape.graphics.beginFill(obj.color, obj.alpha);
+						bgShape.graphics.moveTo(r.left, r.top);
+						bgShape.graphics.lineTo(r.right, r.top);
+						bgShape.graphics.lineTo(r.right, r.bottom);
+						bgShape.graphics.lineTo(r.left, r.bottom);
+						bgShape.graphics.endFill();
+					}
+				}
+			}
+		}		
+		
+		public function removeLineFromCache(tl:TextLine):void
+		{
+			delete _lineDict[tl];
+		}
+
+		// This version is used for the TextFlow/flowComposer standard model
+		public function onUpdateComplete(controller:ContainerController):void
+		{
+			var container:DisplayObjectContainer = controller.container as DisplayObjectContainer;
+			var bgShape:Shape;
+			
+			if(container && container.numChildren)
+			{
+				bgShape = controller.getBackgroundShape();
+				bgShape.graphics.clear();
+				
+				for(var childIdx:int = 0; childIdx<controller.textLines.length; ++childIdx)
+				{
+					var tl:TextLine = controller.textLines[childIdx];
+		
+					if(_lineDict[tl])
+					{
+						if(!_lineDict[tl].length) 
+						{
+							continue;
+						}	
+						
+						for(var i:int = 0; i<_lineDict[tl].length; ++i)
+						{
+							var r:Rectangle = _lineDict[tl][i].rect.clone();
+							var tfl:TextFlowLine = tl.userData as TextFlowLine;
+							//make sure we actually got a tlf from the userData
+							if(tfl)
+								tfl.convertLineRectToContainer(r, true);
+							
+							bgShape.graphics.beginFill(_lineDict[tl][i].color, _lineDict[tl][i].alpha);
+							bgShape.graphics.moveTo(r.left, r.top);
+							bgShape.graphics.lineTo(r.right, r.top);
+							bgShape.graphics.lineTo(r.right, r.bottom);
+							bgShape.graphics.lineTo(r.left, r.bottom);
+							bgShape.graphics.endFill();
+						}
+					}
+				}
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/elements/BreakElement.as b/textLayout_core/src/flashx/textLayout/elements/BreakElement.as
new file mode 100755
index 0000000..86929b3
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/BreakElement.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 flashx.textLayout.elements
+{
+	import flash.text.engine.TextElement;
+	
+	import flashx.textLayout.debug.assert;
+	
+	/** 
+	* The BreakElement class defines a line break, which provides for creating a line break in the text without 
+	* creating a new paragraph. It inserts a U+2028 character in the text of the paragraph.
+	*
+	* <p><strong>Note</strong>: This class exists primarily to support break <br/> tags in MXML markup. To create line breaks, 
+	* you can add newline characters (\n) directly into the text like this:</p>
+	*
+	* <listing version="3.0" >
+	* spanElement1.text += '\n';
+	* </listing>
+	*
+	* In markup, either FXG, TEXT_LAYOUT_FORMAT or MXML, you can simply insert a <br/> where you want the break.
+	*
+	* @playerversion Flash 10
+	* @playerversion AIR 1.5
+	* @langversion 3.0
+	*
+	* @see ParagraphElement
+	* @see SpanElement
+	*/
+	public final class BreakElement extends SpecialCharacterElement
+	{
+		/** Constructor. 
+		*
+		* @playerversion Flash 10 
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*/
+		public function BreakElement()
+		{
+			super();
+			this.text = '\u2028';
+		}
+		
+		/** @private */
+		override protected function get abstract():Boolean
+		{
+			return false;
+		}		
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/elements/Configuration.as b/textLayout_core/src/flashx/textLayout/elements/Configuration.as
new file mode 100755
index 0000000..d2958b4
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/Configuration.as
@@ -0,0 +1,536 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements
+{
+	import flash.display.BlendMode;
+	import flash.system.Capabilities;
+	import flash.text.engine.TextBlock;
+	
+	import flashx.textLayout.compose.StandardFlowComposer;
+	import flashx.textLayout.edit.SelectionFormat;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextDecoration;
+	import flashx.textLayout.formats.TextLayoutFormatValueHolder;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+	
+	/** 
+	* The Configuration class is a primary point of integration between the Text Layout Framework and an application. You can 
+	* include a Configuration object as a parameter to the <code>TextFlow()</code> constructor when you create a new TextFlow
+	* instance. It allows the application to initially control how the Text Layout Framework behaves.
+	* 
+	* <p>The Configuration class allows you to specify initial, paragraph and container formats for the text flow 
+	* through the <code>textFlowInitialFormat</code> property. It also allows you to specify initial format attributes for links, selection,
+	* scrolling, and for handling the Tab and Enter keys.</p>
+	*
+	* @includeExample examples\ConfigurationExample.as -noswf
+	*
+	* @playerversion Flash 10
+	* @playerversion AIR 1.5
+	* @langversion 3.0
+	* 
+	* @see flashx.textLayout.formats.ITextLayoutFormat ITextLayoutFormat
+	* @see flashx.textLayout.edit.SelectionFormat SelectionFormat
+	* @see TextFlow
+	*/
+	
+	public class Configuration implements IConfiguration
+	{
+		/** @private */
+		static tlf_internal function versionIsAtLeast(major:int,minor:int):Boolean
+		{ 
+			var versionData:Array = Capabilities.version.split(" ")[1].split(","); 
+			return int(versionData[0]) > major || (int(versionData[0]) == major && int(versionData[1]) >= minor);
+		}
+		
+		/** @private The player may disable the feature for older swfs.  */
+		static tlf_internal const playerEnablesArgoFeatures:Boolean = versionIsAtLeast(10,1) && (new TextBlock).hasOwnProperty("recreateTextLine"); 
+		
+		/** If manageTabKey and manageEnterKey are false, the client must handle those keys on their own. */
+		private var _manageTabKey:Boolean;
+		private var _manageEnterKey:Boolean;
+		
+		private var _overflowPolicy:String;
+		
+		private var _enableAccessibility:Boolean;
+		private var _releaseLineCreationData:Boolean;
+		
+		// TODO: make me into dictionaries
+		private var _defaultLinkNormalFormat:ITextLayoutFormat;
+		private var _defaultLinkActiveFormat:ITextLayoutFormat;
+		private var _defaultLinkHoverFormat:ITextLayoutFormat;
+		
+		private var _textFlowInitialFormat:ITextLayoutFormat;
+		
+		private var _focusedSelectionFormat:SelectionFormat;
+		private var _unfocusedSelectionFormat:SelectionFormat;
+		private var _inactiveSelectionFormat:SelectionFormat;	
+		
+		// scrolling vars
+		private var _scrollDragDelay:Number;
+		private var _scrollDragPixels:Number;
+		private var _scrollPagePercentage:Number;
+		private var _scrollMouseWheelMultiplier:Number;
+		
+		private var _flowComposerClass:Class;
+		private var _inlineGraphicResolverFunction:Function;
+				
+		/** Constructor - creates a default configuration. 
+		*
+		* @param initializeWithDefaults Specifies whether to initialize the configuration with
+		* the default values. Default is <code>true</code>. If set to <code>false</code>, initializes
+		* without default values, thereby saving some objects. The <code>clone()</code> method sets this
+		* to <code>false</code> and copies the properties from the original object.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	* 
+		* @see flashx.textLayout.edit.SelectionFormat SelectionFormat
+		* @see flashx.textLayout.compose.StandardFlowComposer StandardFlowComposer
+		*/
+		public function Configuration(initializeWithDefaults:Boolean = true)
+		{
+			if (initializeWithDefaults)
+				initialize()
+		}
+		
+		private function initialize():void
+		{
+			var scratchFormat:TextLayoutFormatValueHolder;
+	
+			_manageTabKey = false;
+			_manageEnterKey = true;
+			_overflowPolicy = OverflowPolicy.FIT_DESCENDERS;
+			_enableAccessibility = false;
+			_releaseLineCreationData = false;
+			
+			_focusedSelectionFormat = new SelectionFormat(0xffffff, 1.0, BlendMode.DIFFERENCE);
+			_unfocusedSelectionFormat = new SelectionFormat(0xffffff, 0, BlendMode.DIFFERENCE, 0xffffff, 0.0, BlendMode.DIFFERENCE, 0);
+			_inactiveSelectionFormat  = _unfocusedSelectionFormat;
+				
+			scratchFormat = new TextLayoutFormatValueHolder();
+			scratchFormat.textDecoration = TextDecoration.UNDERLINE;
+			scratchFormat.color = 0x0000FF;//default link color is blue
+			_defaultLinkNormalFormat = scratchFormat;
+				
+			scratchFormat = new TextLayoutFormatValueHolder();
+			scratchFormat.lineBreak = FormatValue.INHERIT;
+			scratchFormat.paddingLeft = FormatValue.INHERIT;
+			scratchFormat.paddingRight = FormatValue.INHERIT;
+			scratchFormat.paddingTop = FormatValue.INHERIT;
+			scratchFormat.paddingBottom = FormatValue.INHERIT;
+			scratchFormat.verticalAlign = FormatValue.INHERIT;
+			scratchFormat.columnCount = FormatValue.INHERIT;
+			scratchFormat.columnCount = FormatValue.INHERIT;
+			scratchFormat.columnGap = FormatValue.INHERIT;
+			scratchFormat.columnWidth = FormatValue.INHERIT;
+			_textFlowInitialFormat = scratchFormat;
+					
+			_scrollDragDelay = 35;
+			_scrollDragPixels = 20;
+			_scrollPagePercentage = 7.0/8.0;
+			_scrollMouseWheelMultiplier = 20;
+				
+			_flowComposerClass = StandardFlowComposer;
+		}
+		
+		private var _immutableClone:IConfiguration;
+		
+		/** TextFlows are configured with an immutable clone of a Configuration.  Once a TextFlow is create it uses an immutable configuration. @private */
+		tlf_internal function getImmutableClone():IConfiguration
+		{
+			if (!_immutableClone)
+			{
+				var clonedConifg:Configuration = clone();
+				_immutableClone = clonedConifg;
+				// an immutable clone is its own immutable clone
+				clonedConifg._immutableClone = clonedConifg;
+			}
+			return _immutableClone; 
+		}
+		
+		/** Creates a clone of the Configuration object.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*/
+		public function clone():Configuration
+		{
+			var config:Configuration = new Configuration(false);
+			// must copy all values
+			config.defaultLinkActiveFormat = defaultLinkActiveFormat;
+			config.defaultLinkHoverFormat  = defaultLinkHoverFormat;
+			config.defaultLinkNormalFormat = defaultLinkNormalFormat;
+			config.textFlowInitialFormat = _textFlowInitialFormat;
+			config.focusedSelectionFormat = _focusedSelectionFormat;
+			config.unfocusedSelectionFormat = _unfocusedSelectionFormat;
+			config.inactiveSelectionFormat = _inactiveSelectionFormat;
+			
+			config.manageTabKey = _manageTabKey;
+			config.manageEnterKey = _manageEnterKey;
+			config.overflowPolicy = _overflowPolicy;
+			config.enableAccessibility = _enableAccessibility;
+			config.releaseLineCreationData = _releaseLineCreationData;
+			
+			config.scrollDragDelay = _scrollDragDelay;
+			config.scrollDragPixels = _scrollDragPixels;
+			config.scrollPagePercentage = _scrollPagePercentage;
+			config.scrollMouseWheelMultiplier = _scrollMouseWheelMultiplier;
+			
+			config.flowComposerClass = _flowComposerClass;
+			config._inlineGraphicResolverFunction = _inlineGraphicResolverFunction;
+			return config; 
+		}
+		
+		/** @copy IConfiguration#manageTabKey
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+		*/
+		
+		public function get manageTabKey():Boolean
+		{ return _manageTabKey; }
+		public function set manageTabKey(val:Boolean):void
+		{ _manageTabKey = val; _immutableClone = null; }
+
+		/** 
+		* @copy IConfiguration#manageEnterKey
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+		*/
+		
+		public function get manageEnterKey():Boolean
+		{ return _manageEnterKey; }
+		public function set manageEnterKey(val:Boolean):void
+		{ _manageEnterKey = val; _immutableClone = null; }
+		
+
+		
+		/** 
+		* @copy IConfiguration#overflowPolicy
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+		* @see OverflowPolicy
+		*/
+
+		public function get overflowPolicy():String
+		{ 	return _overflowPolicy; }
+		public function set overflowPolicy(value:String):void
+		{ 	_overflowPolicy = value; }
+				
+		/** 
+		* @copy IConfiguration#defaultLinkNormalFormat
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+		* @see FlowElement#linkNormalFormat
+		* @see flashx.textLayout.formats.ITextLayoutFormat ITextLayoutFormat
+		* @see LinkElement
+		*/
+		
+		public function get defaultLinkNormalFormat():ITextLayoutFormat
+		{ return _defaultLinkNormalFormat; }
+		public function set defaultLinkNormalFormat(val:ITextLayoutFormat):void
+		{ _defaultLinkNormalFormat = val; _immutableClone = null; }
+		
+		/** 
+		* @copy IConfiguration#defaultLinkHoverFormat  
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+		* @see  FlowElement#linkHoverFormat
+		* @see flashx.textLayout.formats.ITextLayoutFormat ITextLayoutFormat
+		* @see LinkElement
+		*/
+		
+		public function get defaultLinkHoverFormat():ITextLayoutFormat
+		{ return _defaultLinkHoverFormat; }	
+		public function set defaultLinkHoverFormat(val:ITextLayoutFormat):void
+		{ _defaultLinkHoverFormat = val; _immutableClone = null; }
+			
+		/** 
+		* @copy IConfiguration#defaultLinkActiveFormat
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+		* @see FlowElement#linkActiveFormat 
+		* @see flashx.textLayout.formats.ITextLayoutFormat ITextLayoutFormat
+		* @see LinkElement
+		*/
+		
+		public function get defaultLinkActiveFormat():ITextLayoutFormat
+		{ return _defaultLinkActiveFormat; }
+		public function set defaultLinkActiveFormat(val:ITextLayoutFormat):void
+		{ _defaultLinkActiveFormat = val; _immutableClone = null; }
+		
+		/** 
+		* @copy IConfiguration#textFlowInitialFormat
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+		* @see TextFlow
+		* @see flashx.textLayout.formats.ITextLayoutFormat ITextLayoutFormat
+		*/
+		
+		public function get textFlowInitialFormat():ITextLayoutFormat
+		{ return _textFlowInitialFormat; }
+		public function set textFlowInitialFormat(val:ITextLayoutFormat):void
+		{ _textFlowInitialFormat = val; _immutableClone = null; }
+		
+
+		
+		/** 
+		* @copy IConfiguration#focusedSelectionFormat 
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+	 	* @see flashx.textLayout.edit.SelectionFormat SelectionFormat
+		* @see flashx.textLayout.edit.SelectionManager#focusedSelectionFormat SelectionManager.focusedSelectionFormat
+		* @see TextFlow
+		*/
+		
+		public function get focusedSelectionFormat():SelectionFormat
+		{ return _focusedSelectionFormat; }
+		public function set focusedSelectionFormat(val:SelectionFormat):void
+		{	if (val != null)
+			{	
+				_focusedSelectionFormat = val; 
+				_immutableClone = null;
+			} 
+		}
+		
+		/** 
+		* @copy IConfiguration#unfocusedSelectionFormat
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+	 	* @see flashx.textLayout.edit.SelectionFormat SelectionFormat
+		* @see flashx.textLayout.edit.SelectionManager#unfocusedSelectionFormat SelectionManager.unfocusedSelectionFormat
+		* @see TextFlow
+		*/
+		
+		public function get unfocusedSelectionFormat():SelectionFormat
+		{ return _unfocusedSelectionFormat; }
+		public function set unfocusedSelectionFormat(val:SelectionFormat):void
+		{	if (val != null)
+			{	
+				_unfocusedSelectionFormat = val; 
+				_immutableClone = null;
+			} 
+		}		
+		
+		/** 
+		* @copy IConfiguration#inactiveSelectionFormat
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+	 	* @see flashx.textLayout.edit.SelectionFormat SelectionFormat
+		* @see flashx.textLayout.edit.SelectionManager#inactiveSelectionFormat SelectionManager.inactiveSelectionFormat
+		* @see TextFlow
+		*/
+		
+		public function get inactiveSelectionFormat():SelectionFormat
+		{ return _inactiveSelectionFormat; }
+		public function set inactiveSelectionFormat(val:SelectionFormat):void
+		{	
+			if (val != null)
+			{
+				_inactiveSelectionFormat = val; 
+				_immutableClone = null; 
+			}
+		}												
+		
+		/** 
+		* @copy IConfiguration#scrollDragDelay
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+		*/
+		
+		public function get scrollDragDelay():Number
+		{ return _scrollDragDelay; }
+		public function set scrollDragDelay(val:Number):void
+		{
+			if (val > 0) {
+				_scrollDragDelay = val;
+				_immutableClone = null;
+			}
+		}
+		
+		/** 
+		* @copy IConfiguration#scrollDragPixels
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+		*/
+		
+		public function get scrollDragPixels():Number
+		{ return _scrollDragPixels; }
+		public function set scrollDragPixels(val:Number):void
+		{
+			if (val > 0) {
+				_scrollDragPixels = val;
+				_immutableClone = null;
+			}
+		}
+
+		/**
+		* @copy IConfiguration#scrollPagePercentage
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+		*/
+		
+		public function get scrollPagePercentage(): Number
+		{ return _scrollPagePercentage; }
+		public function set scrollPagePercentage(val:Number):void
+		{
+			if (val > 0) {
+				_scrollPagePercentage = val;
+				_immutableClone = null;
+			}
+		}
+		
+		/** 
+		* @copy IConfiguration#scrollMouseWheelMultiplier
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+		*/
+		
+		public function get scrollMouseWheelMultiplier(): Number
+		{ return _scrollMouseWheelMultiplier; }
+		public function set scrollMouseWheelMultiplier(val:Number):void
+		{
+			if (val > 0) {
+				_scrollMouseWheelMultiplier = val;
+				_immutableClone = null;
+			}
+		}
+		
+		/** 
+		* @copy IConfiguration#flowComposerClass
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+	 	* @see flashx.textLayout.compose.StandardFlowComposer StandardFlowComposer
+		* @see flashx.textLayout.elements.TextFlow TextFlow
+		*/
+		
+		public function get flowComposerClass(): Class
+		{ return _flowComposerClass; }
+		public function set flowComposerClass(val:Class):void
+		{
+			_flowComposerClass = val;
+			_immutableClone = null;
+		}
+	
+		/** 
+		* @copy IConfiguration#enableAccessibility
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+	 	* @see TextFlow
+		*/
+		
+		public function get enableAccessibility():Boolean
+		{ return _enableAccessibility; }
+		public function set enableAccessibility(val:Boolean):void
+		{
+			_enableAccessibility = val;
+			_immutableClone = null;
+		}
+		
+		/** 
+		* @copy IConfiguration#releaseLineCreationData
+		* 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*
+		* @see flashx.textLayout.compose.StandardFlowComposer StandardFlowComposer
+		* @see flash.text.engine.TextBlock#releaseLineCreationData() TextBlock.releaseLineCreationData()
+		*/
+		
+		public function get releaseLineCreationData():Boolean
+		{ return _releaseLineCreationData; }
+		public function set releaseLineCreationData(val:Boolean):void
+		{
+			_releaseLineCreationData = val;
+			_immutableClone = null;
+		}
+					
+		/** Returns true if the ActionScript text engine was built with debugging code enabled. @private */
+		static tlf_internal function get debugCodeEnabled():Boolean
+		{
+			CONFIG::debug   { return true; }
+			CONFIG::release { return false; }
+		}
+		
+		/** 
+		* @copy IConfiguration#inlineGraphicResolverFunction
+		* 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*
+		* @see flashx.textLayout.elements.InlineGraphicElement InlineGraphicElement
+		*/		
+		public function get inlineGraphicResolverFunction():Function
+		{ 
+			return _inlineGraphicResolverFunction; 
+		}
+		public function set inlineGraphicResolverFunction(val:Function):void
+		{
+			_inlineGraphicResolverFunction = val;
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/ContainerFormattedElement.as b/textLayout_core/src/flashx/textLayout/elements/ContainerFormattedElement.as
new file mode 100755
index 0000000..452a149
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/ContainerFormattedElement.as
@@ -0,0 +1,127 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements
+{
+	import flash.display.DisplayObjectContainer;
+	
+	import flashx.textLayout.compose.IFlowComposer;
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.FlowElementDisplayType;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+
+	/** 
+	* ContainerFormattedElement is the root class for all container-level block elements, such as DivElement
+	* and TextFlow objects. Container-level block elements are grouping elements for other FlowElement objects.
+	*
+	* @playerversion Flash 10
+	* @playerversion AIR 1.5
+	* @langversion 3.0
+	*
+	* @see DivElement
+	* @see TextFlow
+	*/	
+	public class ContainerFormattedElement extends ParagraphFormattedElement
+	{
+		private var _display:String;	// FlowElementDisplayType
+
+		/** @private */
+		public override function shallowCopy(startPos:int = 0, endPos:int = -1):FlowElement
+		{
+			if (endPos == -1)
+				endPos = textLength;
+				
+			var retFlow:ContainerFormattedElement = super.shallowCopy(startPos, endPos) as ContainerFormattedElement;
+			retFlow._display = _display;	
+			return retFlow;						
+		}
+
+		/** @private */
+		public override function get display():String
+		{
+			return _display;
+		} 
+		/** @private */
+		public function set display(value:String):void
+		{
+			CONFIG::debug { assert(value == FlowElementDisplayType.INLINE || value == FlowElementDisplayType.FLOAT, "Illegal value for display"); }
+			_display = value;
+		}
+		
+		/** @private */
+		public function get flowComposer():IFlowComposer
+		{ 
+			// TODO: this is here for legacy purposes.  What we really want to do is determine if a given element has its own physical representation
+			// That used to be the containerController and may be again.  This is all intermediate for now.  Reinvestigate when Tables are enabled and Div's with containers are implemented.
+			return null; 
+		}
+		
+		/** @private */
+		tlf_internal override function formatChanged(notifyModelChanged:Boolean = true):void
+		{
+			super.formatChanged(notifyModelChanged);
+			// The associated container, if there is one, inherits its container
+			// attributes from here. So we need to tell it that these attributes
+			// have changed.
+			if (flowComposer)
+			{
+				for (var idx:int = 0; idx < flowComposer.numControllers; idx++)
+					flowComposer.getControllerAt(idx).formatChanged();
+			}
+		}
+		
+		/** @private */
+		tlf_internal function preCompose():void
+		{ return; }
+		
+		/** @private */
+		CONFIG::debug public override function debugCheckFlowElement(depth:int = 0, extraData:String = ""):int
+		{
+			// debugging function that asserts if the flow element tree is in an invalid state
+			if (flowComposer && flowComposer.numControllers)
+			{
+				var controller:ContainerController = flowComposer.getControllerAt(0);
+				extraData = getDebugIdentity(controller.container)+" b:"+controller.absoluteStart+" l:" +controller.textLength+extraData;
+				extraData = extraData+" w:"+controller.compositionWidth+" h:"+controller.compositionHeight;
+			}
+			return super.debugCheckFlowElement(depth,extraData);
+		}
+		
+		
+		/** @private */
+		tlf_internal override function normalizeRange(normalizeStart:uint,normalizeEnd:uint):void
+		{
+			super.normalizeRange(normalizeStart,normalizeEnd);
+			
+			// is this an absolutely element?
+			if (this.numChildren == 0)
+			{
+				var p:ParagraphElement = new ParagraphElement();
+				p.replaceChildren(0,0,new SpanElement());
+				replaceChildren(0,0,p);	
+				CONFIG::debug { assert(textLength == 1,"bad textlength"); }
+				p.normalizeRange(0,p.textLength);	
+			}
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/DivElement.as b/textLayout_core/src/flashx/textLayout/elements/DivElement.as
new file mode 100755
index 0000000..1eb2cd0
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/DivElement.as
@@ -0,0 +1,56 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements
+{
+	import flashx.textLayout.debug.assert;	
+	
+	/** 
+	 * The DivElement class defines an element for grouping paragraphs (ParagraphElement objects). If you want a group of paragraphs
+	 * to share the same formatting attributes, you can group them in a DivElement object and apply the attributes to it. The paragraphs
+	 * will inherit the attributes from the DivElement object.
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 *
+	 * @includeExample examples\DivElementExample.as -noswf
+	 *
+	 * @see ParagraphElement
+	 * @see TextFlow
+	 */
+	public final class DivElement extends ContainerFormattedElement
+	{
+		/** Constructor - creates a new DivElement object.
+		*		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*/
+		public function DivElement()
+		{
+			super();
+		}
+		
+		/** @private */
+		override protected function get abstract():Boolean
+		{
+			return false;
+		}		
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/FlowElement.as b/textLayout_core/src/flashx/textLayout/elements/FlowElement.as
new file mode 100755
index 0000000..32cb1ed
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/FlowElement.as
@@ -0,0 +1,1401 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements
+{
+	import flash.display.DisplayObjectContainer;
+	import flash.utils.Dictionary;
+	import flash.utils.getDefinitionByName;
+	import flash.utils.getQualifiedClassName;
+	
+	import flashx.textLayout.compose.IFlowComposer;
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.debug.Debugging;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.events.ModelChange;
+	import flashx.textLayout.formats.FlowElementDisplayType;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormatValueHolder;
+	import flashx.textLayout.property.Property;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+	
+	[IMXMLObject]	
+
+/**
+ * The text in a flow is stored in tree form with the elements of the tree representing logical
+ * divisions within the text. The FlowElement class is the abstract base class of all the objects in this tree.
+ * FlowElement objects represent paragraphs, spans of text within paragraphs, and
+ * groups of paragraphs.
+ *
+ * <p>The root of a composable FlowElement tree is always a TextFlow object. Leaf elements of the tree are always 
+ * subclasses of the FlowLeafElement class. All leaves arranged in a composable TextFlow have a ParagraphElement ancestor.
+ * </p> 
+ *
+ * <p>You cannot create a FlowElement object directly. Invoking <code>new FlowElement()</code> throws an error 
+ * exception.</p>
+ *
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ * 
+ * @see FlowGroupElement
+ * @see FlowLeafElement
+ * @see InlineGraphicElement
+ * @see ParagraphElement
+ * @see SpanElement
+ * @see TextFlow
+ */
+	public class FlowElement implements ITextLayoutFormat
+	{
+		/** every FlowElement has at most one parent */
+		private var _parent:FlowGroupElement;
+		
+		/** format settings on this FlowElement */
+		private var _formatValueHolder:FlowValueHolder;
+		
+		/** @private computed formats applied to the element */
+		protected var _computedFormat:ITextLayoutFormat;
+		
+		/** start, _start of element, relative to parent.  */
+		private var _parentRelativeStart:int = 0;		
+		
+		/** _textLength (number of chars) in the element, including child content */
+		private var _textLength:int = 0;	
+	
+		/** Base class - invoking <code>new FlowElement()</code> throws an error exception.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*/
+		public function FlowElement()
+		{
+			// not a valid FlowElement class
+			if (abstract)
+				throw new Error(GlobalSettings.resourceStringFunction("invalidFlowElementConstruct"));
+		}
+		
+		/** Called for MXML objects after the implementing object has been created and all component properties specified on the MXML tag have been initialized. 
+		 * @param document The MXML document that created the object.
+		 * @param id The identifier used by document to refer to this object.
+		 **/
+		public function initialized(document:Object, id:String):void
+		{
+			this.id = id;
+		}
+
+		/** Returns true if the class is an abstract base class,
+		 * false if its OK to construct. Attempting to instantiate an
+		 * abstract FlowElement class will cause an exception.
+		 * @return Boolean 	true if this is an abstract class
+		 * @private
+		 */
+		protected function get abstract():Boolean
+		{
+			return true;
+		}
+		
+		/** Allows you to read and write user styles on a FlowElement object.  Note that reading this property
+		* makes a copy of the user-styles dictionary. 
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+		*
+		*/
+		public function get userStyles():Object
+		{
+			var styles:Object = _formatValueHolder == null ? null : _formatValueHolder.userStyles;
+			return styles ? Property.shallowCopy(styles) : null;
+		}
+		public function set userStyles(styles:Object):void
+		{
+			var newStyles:Object;
+			if (styles)
+			{
+				newStyles = new Object();
+				for (var val:Object in styles)
+					newStyles[val] = styles[val];
+			}
+			writableTextLayoutFormatValueHolder().userStyles = newStyles;
+			modelChanged(ModelChange.USER_STYLE_CHANGED,0,this.textLength,true);
+		}
+		
+		/** Returns the core styles on a FlowElement instance. Returns a copy of the core styles. 
+		 *  
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 *
+		 */
+		 
+		public function get coreStyles():Object
+		{
+			var styles:Object = _formatValueHolder == null ? null : _formatValueHolder.coreStyles;
+			return styles ? Property.shallowCopy(styles) : null;
+		}
+		
+		/** @private */
+		tlf_internal function setCoreStylesInternal(styles:Object):void
+		{
+			var newStyles:Object;
+			if (styles)
+			{
+				newStyles = new Object();
+				for (var val:Object in styles)
+				{
+					var value:* = styles[val];
+					if (value != undefined)
+						newStyles[val] = value;
+				}
+			}
+			writableTextLayoutFormatValueHolder().coreStyles = newStyles;
+			formatChanged();		
+		}
+		
+
+		public function set linkNormalFormat(value:*):void
+		{ setStyle(LinkElement.LINK_NORMAL_FORMAT_NAME,value); }
+		/** Defines the formatting attributes used for links in normal state. This value will cascade down the hierarchy and apply to any links that are descendants.
+		 * Equivalent to setStyle(linkNormalFormat,value).  Expects a dictionary of properties.  Converts an array of objects with key and value as members to a dictionary. */
+		public function get linkNormalFormat():*
+		{ return getStyle(LinkElement.LINK_NORMAL_FORMAT_NAME); }
+		
+
+		public function set linkActiveFormat(value:*):void
+		{ setStyle(LinkElement.LINK_ACTIVE_FORMAT_NAME,value); }
+		/** Defines the formatting attributes used for links in active state, when the mouse is down on a link. This value will cascade down the hierarchy and apply to any links that are descendants.
+		 * Equivalent to setStyle(linkActiveFormat,value).  Expects a dictionary of properties.  Converts an array of objects with key and value as members to a dictionary. */
+		public function get linkActiveFormat():*
+		{ return getStyle(LinkElement.LINK_ACTIVE_FORMAT_NAME); }
+		
+
+		public function set linkHoverFormat(value:*):void
+		{ setStyle(LinkElement.LINK_HOVER_FORMAT_NAME,value); }
+		/** Defines the formatting attributes used for links in hover state, when the mouse is within the bounds (rolling over) a link. This value will cascade down the hierarchy and apply to any links that are descendants.
+		 * Equivalent to setStyle(linkHoverFormat,value).  Expects a dictionary of properties.  Converts an array of objects with key and value as members to a dictionary. */
+		public function get linkHoverFormat():*
+		{ return getStyle(LinkElement.LINK_HOVER_FORMAT_NAME); }
+		
+		/** Compare the userStyles of this with otherElement's userStyles. 
+		 *
+		 * @param otherElement the FlowElement object with which to compare user styles
+		 *
+		 * @return 	true if the user styles are equal; false otherwise.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+	 	 * @includeExample examples\FlowElement_equalUserStylesExample.as -noswf
+	 	 * 
+	 	 * @see #getStyle()
+	 	 * @see #setStyle()
+	 	 * @see #userStyles
+		 */
+		public function equalUserStyles(otherElement:FlowElement):Boolean
+		{
+			var myStyles:Object = _formatValueHolder ? _formatValueHolder.userStyles : null;
+			var elemStyles:Object = otherElement._formatValueHolder ? otherElement._formatValueHolder.userStyles : null;
+			return Property.equalStyleObjects(myStyles,elemStyles);
+		}
+		
+		/** @private Compare the styles of two elements for merging.  Return true if they can be merged. */
+		tlf_internal function equalStylesForMerge(elem:FlowElement):Boolean
+		{
+			return this.id == elem.id && this.styleName == elem.styleName && TextLayoutFormat.isEqual(elem.format,format) && equalUserStyles(elem);
+		}
+		
+		/**
+		 * Makes a copy of this FlowElement object, copying the content between two specified character positions.
+		 * It returns the copy as a new FlowElement object. Unlike <code>deepCopy()</code>, <code>shallowCopy()</code> does
+		 * not copy any of the children of this FlowElement object. 
+		 * 
+		 * <p>With no arguments, <code>shallowCopy()</code> defaults to copying all of the content.</p>
+		 *
+		 * @param relativeStart	The relative text position of the first character to copy. First position is 0.
+		 * @param relativeEnd	The relative text position of the last character to copy. A value of -1 indicates copy to end.
+		 *
+		 * @return 	the object created by the copy operation.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @includeExample examples\FlowElement_shallowCopyExample.as -noswf
+		 *
+	 	 * @see #deepCopy()
+	 	 */
+		 
+		public function shallowCopy(relativeStart:int = 0, relativeEnd:int = -1):FlowElement
+		{
+			if (relativeEnd == -1)
+				relativeEnd = textLength;
+				
+			var retFlow:FlowElement = new (getDefinitionByName(getQualifiedClassName(this)) as Class);
+			retFlow.styleName = styleName;
+			retFlow.id = id;	// ???? copy me ?????
+			if (_formatValueHolder !=  null)
+				retFlow._formatValueHolder = new FlowValueHolder(_formatValueHolder);
+			return retFlow;
+		}
+
+		/**
+		 * Makes a deep copy of this FlowElement object, including any children, copying the content between the two specified
+		 * character positions and returning the copy as a FlowElement object.
+		 * 
+		 * <p>With no arguments, <code>deepCopy()</code> defaults to copying the entire element.</p>
+		 * 
+		 * @param relativeStart	relative text position of the first character to copy. First position is 0.
+		 * @param relativeEnd	relative text position of the last character to copy. A value of -1 indicates copy to end.
+		 *
+		 * @return 	the object created by the deep copy operation.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @includeExample examples\FlowElement_deepCopyExample.as -noswf
+	 	 * 
+	 	 * @see #shallowCopy()
+		 */
+		 
+		public function deepCopy(relativeStart:int = 0, relativeEnd:int = -1):FlowElement
+		{
+			if (relativeEnd == -1)
+				relativeEnd = textLength;
+				
+			return shallowCopy(relativeStart, relativeEnd);
+		}
+		
+		/** 
+		 * Gets the specified range of text from a flow element.
+		 * 
+		 * @param relativeStart The starting position of the range of text to be retrieved, relative to the start of the FlowElement
+		 * @param relativeEnd The ending position of the range of text to be retrieved, relative to the start of the FlowElement, -1 for up to the end of the element
+		 * @param paragraphSeparator character to put between paragraphs
+		 * 
+		 * @return The requested text.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		public function getText(relativeStart:int=0, relativeEnd:int=-1, paragraphSeparator:String="\n"):String
+		{
+			return "";
+		}
+
+		/** 
+		 * Splits this FlowElement object at the position specified by the <code>relativePosition</code> parameter, which is
+		 * a relative position in the text for this element. This method splits only SpanElement and FlowGroupElement 
+		 * objects.
+		 *
+		 * @param relativePosition the position at which to split the content of the original object, with the first position being 0.
+		 * 
+		 * @return	the new object, which contains the content of the original object, starting at the specified position.
+		 *
+		 * @throws RangeError if <code>relativePosition</code> is greater than <code>textLength</code>, or less than 0.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function splitAtPosition(relativePosition:int):FlowElement
+		{
+			if ((relativePosition < 0) || (relativePosition > textLength))
+				throw RangeError(GlobalSettings.resourceStringFunction("invalidSplitAtPosition"));
+			return this;
+		}
+		
+		/** @private Set to indicate the element may be "bound" in Flex - only used on FlowLeafElement and SubParagraphBlock elements. */
+		tlf_internal function get bindableElement():Boolean
+		{ return getPrivateStyle("bindable") == true; }
+		
+		/** @private */
+		tlf_internal function set bindableElement(value:Boolean):void
+		{ setPrivateStyle("bindable", value); }
+
+		
+		/** Merge flow element into previous flow element if possible. @private
+		 * @Return true--> did the merge
+		 */
+		 
+		tlf_internal function mergeToPreviousIfPossible():Boolean
+		{
+			return false;
+		}
+		
+		/** @private 
+		 * Create and initialize the FTE data structure that corresponds to the FlowElement
+		 */
+		tlf_internal function createContentElement():void
+		{
+			// overridden in the base class -- we should not get here
+			CONFIG::debug { assert(false,"invalid call to createContentElement"); }
+		}
+		
+		/** @private 
+		 * Release the FTE data structure that corresponds to the FlowElement, so it can be gc'ed
+		 */
+		tlf_internal function releaseContentElement():void
+		{
+			// overridden in the base class -- we should not get here
+			CONFIG::debug { assert(false,"invalid call to createContentElement"); }
+		}
+
+		/** @private 
+		 * True if it is safe to release the corresponding FTE data structure.
+		 */
+		tlf_internal function canReleaseContentElement():Boolean
+		{
+			return true;
+		}
+		
+		/** Returns the parent of this FlowElement object. Every FlowElement has at most one parent.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*/
+	 	
+		public function get parent():FlowGroupElement
+		{ return _parent; }
+		
+		/** @private parent setter. */
+		
+		tlf_internal function setParentAndRelativeStart(newParent:FlowGroupElement,newStart:int):void
+		{ _parent = newParent; _parentRelativeStart = newStart; attributesChanged(false); }
+		
+				
+		/** @private Used when the textBlock.content is already correctly configured. */
+		tlf_internal function setParentAndRelativeStartOnly(newParent:FlowGroupElement,newStart:int):void
+		{ _parent = newParent;  _parentRelativeStart = newStart; }
+			
+		/**
+		 * Returns the total length of text owned by this FlowElement object and its children.  If an element has no text, the 
+		 * value of <code>textLength</code> is usually zero. 
+		 * 
+		 * <p>ParagraphElement objects have a final span with a paragraph terminator character for the last 
+		 * SpanElement object.The paragraph terminator is included in the value of the <code>textLength</code> of that 
+		 * SpanElement object and all its parents.  It is not included in <code>text</code> property of the SpanElement
+		 * object.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see #textLength
+		 */
+		 
+		public function get textLength():int
+		{ return _textLength; }
+		
+		/** @private textLength setter.  */
+		tlf_internal function setTextLength(newLength:int):void
+		{ _textLength = newLength; }	
+		
+		/** Returns the relative start of this FlowElement object in the parent. If parent is null, this value is always zero.  
+		 * If parent is not null, the value is the sum of the text lengths of all previous siblings.
+		 *
+		 * @return offset
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 * 
+	 	 * @see #textLength
+		 */
+		 
+		public function get parentRelativeStart():int
+		{ return _parentRelativeStart; }
+		
+		/** @private start setter. */
+		tlf_internal function setParentRelativeStart(newStart:int):void
+		{ _parentRelativeStart = newStart; }
+		
+		/** Returns the relative end of this FlowElement object in the parent. If the parent is null this is always equal to <code>textLength</code>.  If 
+		 * the parent is not null, the value is the sum of the text lengths of this and all previous siblings, which is effectively
+		 * the first character in the next FlowElement object.
+		 *
+		 * @return offset
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see FlowGroupElement
+	 	 * @see #textLength
+		 */
+		 
+		public function get parentRelativeEnd():int
+		{ return _parentRelativeStart + _textLength; }
+				
+		/**
+		 * Tag for the item, used for debugging.
+		 */
+		CONFIG::debug public function get name():String
+		{
+			return flash.utils.getQualifiedClassName(this);
+		}
+		
+		/** Returns the ContainerFormattedElement that specifies its containers for filling. This ContainerFormattedElement
+		 * object has its own columns and can control ColumnDirection and BlockProgression. 
+		 *
+		 * @return 	the ancestor, with its container, of this FlowElement object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 * 
+	 	 * @private
+		 */
+		 
+		tlf_internal function getAncestorWithContainer():ContainerFormattedElement
+		{
+			var elem:FlowElement = this;
+			while (elem)
+			{
+				var contElement:ContainerFormattedElement = elem as ContainerFormattedElement;
+				if (contElement)
+				{
+					if (!contElement._parent || contElement.flowComposer)
+						return contElement;
+				}
+				elem = elem._parent; 
+			}
+			return null;
+		}
+		
+		
+		/**
+		 * @private
+		 * Generic mechanism for fetching private data from the element.
+		 * @param styleName	name of the property
+		 */
+		tlf_internal function getPrivateStyle(styleName:String):*
+		{ return _formatValueHolder ? _formatValueHolder.getPrivateData(styleName) : undefined; }
+
+		/**
+		 * @private
+		 * Generic mechanism for adding private data to the element.
+		 * @param styleName	name of the property
+		 * @param val value of the property
+		 */
+		tlf_internal function setPrivateStyle(styleName:String, val:*):void
+		{
+			if (getPrivateStyle(styleName) != val)
+			{
+				writableTextLayoutFormatValueHolder().setPrivateData(styleName,val);
+				modelChanged(ModelChange.STYLE_SELECTOR_CHANGED,0,this.textLength);
+			}
+		}
+		
+		private static const idString:String ="id";
+
+		/**
+		 * Assigns an identifying name to the element, making it possible to set a style for the element
+		 * by referencing the <code>id</code>. For example, the following line sets the color for
+		 * a SpanElement object that has an id of span1:
+		 *
+		 * <listing version="3.0" >
+		 * textFlow.getElementByID("span1").setStyle("color", 0xFF0000);
+		 * </listing>
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @see TextFlow#getElementByID()
+		 */
+		public function get id():String
+		{ return getPrivateStyle(idString); }
+		public function set id(val:String):void
+		{ return setPrivateStyle(idString, val);	}
+		
+		private static const styleNameString:String ="styleName";
+
+		/**
+		 * Assigns an identifying class to the element, making it possible to set a style for the element
+		 * by referencing the <code>styleName</code>. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get styleName():String
+		{ return getPrivateStyle(styleNameString); }
+		public function set styleName(val:String):void
+		{ return setPrivateStyle(styleNameString, val);	}
+		
+		private static const impliedElementString:String = "impliedElement";
+		/** @private */
+		tlf_internal function get impliedElement():Boolean
+		{
+			return getPrivateStyle(impliedElementString) !== undefined;
+		}
+		/** @private */		
+		tlf_internal function set impliedElement(value:Boolean):void
+		{
+			setPrivateStyle(impliedElementString, "true");
+		}
+				
+		// **************************************** 
+		// Begin TLFFormat Related code
+		// ****************************************
+		include "../formats/TextLayoutFormatInc.as"
+		
+		/** TextLayoutFormat properties applied directly to this element.
+		 * <p>Each element may have properties applied to it as part of its format. Properties applied to this element override properties inherited from the parent. Properties applied to this element will in turn be inherited by element's children if they are not overridden on the child. If no properties are applied to the element, this will be null.</p>
+		 * @see flashx.textLayout.formats.ITextLayoutFormat
+		 */
+		public function get format():ITextLayoutFormat
+		{ return _formatValueHolder; }
+		public function set format(value:ITextLayoutFormat):void
+		{
+			if (value == null)
+			{
+				if (_formatValueHolder == null || _formatValueHolder.coreStyles == null)
+					return; // no change
+				_formatValueHolder.coreStyles = null;
+			}
+			else
+				writableTextLayoutFormatValueHolder().format = value;
+			formatChanged();
+		}
+		
+		private function writableTextLayoutFormatValueHolder():FlowValueHolder
+		{
+			if (_formatValueHolder == null)
+				_formatValueHolder = new FlowValueHolder();
+			return _formatValueHolder;
+		}
+
+		/** This gets called when an element has changed its attributes. This may happen because an
+		 * ancestor element changed it attributes.
+		 * @private 
+		 */
+		tlf_internal function formatChanged(notifyModelChanged:Boolean = true):void
+		{
+			if (notifyModelChanged)
+				modelChanged(ModelChange.TEXTLAYOUT_FORMAT_CHANGED,0,textLength);
+			// wipe out whatever values were cached
+			_computedFormat = null;
+		}
+		
+		/** 
+		 * Concatenates tlf attributes with any other tlf attributes
+		 * 
+		 * Return the concatenated result
+		 * 
+		 * @private
+		 */
+		tlf_internal function get formatForCascade():ITextLayoutFormat
+		{
+			var tf:TextFlow = getTextFlow();
+			if (tf)
+			{
+				var elemStyle:ITextLayoutFormat  = tf.getTextLayoutFormatStyle(this);
+				if (elemStyle)
+				{
+					var localFormat:ITextLayoutFormat = format;
+					if (localFormat == null)
+						return elemStyle;
+						
+					var rslt:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder();
+					rslt.apply(elemStyle);
+					rslt.apply(localFormat);
+					return rslt;
+				}
+			}
+			return format;
+		}
+		
+		/** @private  Shared scratch element for use in computedFormat methods only */
+		static tlf_internal var _scratchTextLayoutFormat:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder();
+		
+		/** 
+		 * Returns the computed format attributes that are in effect for this element.
+		 * Takes into account the inheritance of attributes from parent elements.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+		 * @see flashx.textLayout.formats.ITextLayoutFormat ITextLayoutFormat
+		 */
+
+		public function get computedFormat():ITextLayoutFormat
+		{		
+			if (!_computedFormat)
+				doComputeTextLayoutFormat(formatForCascade);
+			return _computedFormat;
+		}
+		
+		/** @private */
+		tlf_internal function doComputeTextLayoutFormat(formatForCascade:ITextLayoutFormat):void
+		{
+			var element:FlowElement = parent;
+			var parentFormatForCascade:ITextLayoutFormat;
+			
+			if (element)
+			{
+				parentFormatForCascade = element.formatForCascade;
+				if (TextLayoutFormat.isEqual(formatForCascade,TextLayoutFormat.emptyTextLayoutFormat) && TextLayoutFormat.isEqual(parentFormatForCascade,TextLayoutFormat.emptyTextLayoutFormat))
+				{
+					_computedFormat = element.computedFormat;
+					return;
+				}
+			}
+			
+			var tf:TextFlow;
+			// compute the cascaded attributes	
+			_scratchTextLayoutFormat.format = formatForCascade;
+			if (element)
+			{
+				if (parentFormatForCascade)
+					_scratchTextLayoutFormat.concatInheritOnly(parentFormatForCascade);
+				while (element.parent)
+				{
+					element = element.parent;
+					var concatAttrs:ITextLayoutFormat = element.formatForCascade;
+					if (concatAttrs)
+						_scratchTextLayoutFormat.concatInheritOnly(concatAttrs);
+				}
+				tf = element as TextFlow;
+			}
+			else
+				tf = this as TextFlow;
+			var defaultFormat:ITextLayoutFormat;
+			var defaultFormatHash:uint;
+			if (tf)
+			{
+				defaultFormat = tf.getDefaultFormat();
+				defaultFormatHash = tf.getDefaultFormatHash();
+			}
+			_computedFormat = TextFlow.getCanonical(_scratchTextLayoutFormat,defaultFormat,defaultFormatHash);
+		}
+
+		// **************************************** 
+		// End CharacterFormat Related code
+		// ****************************************
+
+		
+		/** @private */
+		tlf_internal function attributesChanged(notifyModelChanged:Boolean = true):void
+		{
+			// TODO: REMOVE ME???
+			formatChanged(notifyModelChanged);
+		}
+		
+		/** Returns the value of the style specified by the <code>styleProp</code> parameter, which specifies
+		 * the style name and can include any user style name. Accesses an existing span, paragraph, text flow,
+		 * or container style. Searches the parent tree if the style's value is <code>undefined</code> on a 
+		 * particular element.
+		 *
+		 * @param styleProp The name of the style whose value is to be retrieved.
+		 *
+		 * @return The value of the specified style. The type varies depending on the type of the style being
+		 * accessed. Returns <code>undefined</code> if the style is not set.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @includeExample examples\FlowElement_getStyleExample.as -noswf
+	 	 *
+	 	 * @see #clearStyle()
+		 * @see #setStyle()
+		 * @see #userStyles
+		 */
+		public function getStyle(styleProp:String):*
+		{
+			if (TextLayoutFormat.description.hasOwnProperty(styleProp))
+				return computedFormat[styleProp];
+			return getUserStyleWorker(styleProp);
+		}
+		
+		/** Sets the style specified by the <code>styleProp</code> parameter to the value specified by the
+		* <code>newValue</code> parameter. You can set a span, paragraph, text flow, or container style, including
+		* any user name-value pair.
+		*
+		* <p><strong>Note:</strong> If you assign a custom style, Text Layout Framework can import and export it but
+		* compiled MXML cannot support it.</p>
+		*
+		* @param styleProp The name of the style to set.
+		* @param newValue The value to which to set the style.
+		*.
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*
+		* @includeExample examples\FlowElement_setStyleExample.as -noswf
+		*		
+		* @see #clearStyle()
+		* @see #getStyle()
+		* @see #userStyles
+		*/
+		public function setStyle(styleProp:String,newValue:*):void
+		{
+			if (TextLayoutFormat.description[styleProp] !== undefined)
+				this[styleProp] = newValue;
+			else
+			{
+				writableTextLayoutFormatValueHolder().setUserStyle(styleProp,newValue);
+				modelChanged(ModelChange.USER_STYLE_CHANGED,0,this.textLength,true);
+			}
+		}
+		
+		/** Clears the style specified by the <code>styleProp</code> parameter from this FlowElement object. Sets 
+		 * the value to <code>undefined</code>.
+		 *
+		 * @param styleProp The name of the style to clear.
+		 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @includeExample examples\FlowElement_clearStyleExample.as -noswf
+		 *
+		 * @see #getStyle()
+		 * @see #setStyle()
+		 * @see #userStyles
+		 * 
+		 */
+		public function clearStyle(styleProp:String):void
+		{ setStyle(styleProp,undefined); }
+		
+		/** @private worker function - any styleProp */
+		tlf_internal function getUserStyleWorker(styleProp:String):*
+		{
+			CONFIG::debug { assert(TextLayoutFormat.description[styleProp] === undefined,"bad call to getUserStyleWorker"); }
+			
+			if (_formatValueHolder != null)
+			{
+				var userStyle:* = _formatValueHolder.getUserStyle(styleProp)
+				if (userStyle !== undefined)
+					return userStyle;
+			}
+				
+			var tf:TextFlow = getTextFlow();
+			if (tf && tf.formatResolver)
+			{
+				userStyle = tf.formatResolver.resolveUserFormat(this,styleProp);
+				if (userStyle !== undefined)
+					return userStyle;
+			}
+			// TODO: does TextFlow need to ask a "psuedo parent"				
+			return parent ? parent.getUserStyleWorker(styleProp) : undefined;
+		}
+		
+		/**
+		 * Called whenever the model is modified.  Updates the TextFlow and notifies the selection manager - if it is set.
+		 * This method has to be called while the element is still in the flow
+		 * @param changeType - type of change
+		 * @param start - elem relative offset of start of damage
+		 * @param len - length of damage
+		 * @see flow.model.ModelChange
+		 * @private
+		 */
+		tlf_internal function modelChanged(changeType:String, changeStart:int, changeLen:int, needNormalize:Boolean = true, bumpGeneration:Boolean = true):void
+		{
+			var tf:TextFlow = this.getTextFlow();
+			if (tf)
+				tf.processModelChanged(changeType, this, changeStart, changeLen, needNormalize, bumpGeneration);
+		}
+		
+		/** @private */
+		tlf_internal function appendElementsForDelayedUpdate(tf:TextFlow):void
+		{ }
+		
+		/** @private */
+		tlf_internal function applyDelayedElementUpdate(textFlow:TextFlow,okToUnloadGraphics:Boolean,hasController:Boolean):void
+		{ }
+						
+		// **************************************** 
+		// Begin display property Related code
+		// ****************************************
+		/**
+		 * Indicates how the element should be composed. It may be either inline, and appear as part of a line, or be float, 
+		 * in which case it appears in a container of its own.
+		 * 
+		 * @see text.elements.FlowElementDisplayType#INLINE
+		 * @see text.elements.FlowElementDisplayType#FLOAT
+		 * 
+		 * This feature still in prototype phase - has to be the main namespace so it is accessible through mxml
+		 * @private
+		 */
+		public function get display():String
+		{
+			return FlowElementDisplayType.INLINE;
+		}
+		
+		// **************************************** 
+		// End display property Related code
+		// ****************************************	
+
+ 		// **************************************** 
+		// Begin tracking property Related code
+		// ****************************************
+
+		/**
+		 * Sets the tracking and is synonymous with the <code>trackingRight</code> property. Specified as a number of
+		 * pixels or a percent of <code>fontSize</code>.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see #trackingRight
+		 */
+		public function set tracking(trackingValue:Object):void
+		{
+			trackingRight = trackingValue;
+		}
+		
+		// **************************************** 
+		// End tracking property Related code
+		// ****************************************	
+
+		// **************************************** 
+		// Begin import helper code
+		// ****************************************			
+
+		/**
+		 *  @private Create the default container for the element.
+		 */
+		tlf_internal function createGeometry(parentToBe:DisplayObjectContainer):void
+		{
+			return;
+		}
+		
+		/** Strips white space from the element and its children, according to the whitespaceCollaspse
+		 *  value that has been applied to the element or inherited from its parent.
+		 *  If a FlowLeafElement's attrs are set to WhiteSpaceCollapse.PRESERVE, then collapse is
+		 *  skipped.
+		 *  @see text.formats.WhiteSpaceCollapse
+		 * @private 
+		 */
+		tlf_internal function applyWhiteSpaceCollapse():void
+		{
+			if (_formatValueHolder && _formatValueHolder.whiteSpaceCollapse !== undefined)
+				whiteSpaceCollapse = undefined;
+			
+			setPrivateStyle(impliedElementString, undefined);
+		}
+				
+		// **************************************** 
+		// End import helper code
+		// ****************************************	
+
+		// **************************************** 
+		// Begin helper code for tables
+		// ****************************************			
+		
+		/** Determines whether a particular FlowElement should be treated as a single selection.
+		 * @private
+		 */
+		tlf_internal function isReadOnlyFlowElement():Boolean
+		{
+			return false;
+		}
+
+		/** Gets the highest parent that is a read only flow element
+		 * @private
+		 */		
+		tlf_internal function getHighestReadOnlyFlowElement():FlowElement
+		{
+			var highestReadOnlyFlowElement:FlowElement = null;
+			if (this.isReadOnlyFlowElement())
+			{
+				highestReadOnlyFlowElement = this;
+			}
+			
+			var curFlowElement:FlowElement = parent;
+			while (curFlowElement != null)
+			{
+				if (curFlowElement.isReadOnlyFlowElement())
+				{
+					highestReadOnlyFlowElement = curFlowElement;
+				}
+				curFlowElement = curFlowElement.parent;
+			}
+			return highestReadOnlyFlowElement;
+		}
+		
+		// **************************************** 
+		// End helper code for tables
+		// ****************************************							
+
+		// **************************************** 
+		// Begin tree navigation code
+		// ****************************************
+		
+		 /**
+		 * Returns the start location of the element in the text flow as an absolute index. The first character in the flow
+		 * is position 0.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 * 
+		 * @includeExample examples\FlowElement_getAbsoluteStartExample.as -noswf
+		 *
+ 		 * @return The index of the start of the element from the start of the TextFlow object.
+ 		 *
+ 		 * @see #parentRelativeStart
+ 		 * @see TextFlow
+	 	 */
+	 	 
+		public function getAbsoluteStart():int
+		{
+			var rslt:int = parentRelativeStart;
+			for (var elem:FlowElement = parent; elem; elem = elem.parent)
+				rslt += elem.parentRelativeStart;
+			return rslt;
+		}
+		
+		/**
+		 * Returns the start of this element relative to an ancestor element. Assumes that the
+		 * ancestor element is in the parent chain. If the ancestor element is the parent, this is the
+		 * same as <code>this.parentRelativeStart</code>.  If the ancestor element is the grandparent, this is the same as 
+		 * <code>parentRelativeStart</code> plus <code>parent.parentRelativeStart</code> and so on.
+		 * 
+		 * @param ancestorElement The element from which you want to find the relative start of this element.
+		 *
+		 * @return  the offset of this element.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @includeExample examples\FlowElement_getElementRelativeStartExample.as -noswf
+		 * 
+		 * @see #getAbsoluteStart()
+		 */
+		 
+		public function getElementRelativeStart(ancestorElement:FlowElement):int
+		{
+			var rslt:int = parentRelativeStart;
+			for (var elem:FlowElement = parent; elem && elem != ancestorElement; elem = elem.parent)
+				rslt += elem.parentRelativeStart;
+			return rslt;
+		}
+		
+		/**
+		 * Climbs the text flow hierarchy to return the root TextFlow object for the element.
+		 *
+		 * @return	The root TextFlow object for this FlowElement object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @includeExample examples\FlowElement_getTextFlowExample.as -noswf
+	 	 *
+	 	 * @see TextFlow
+		 */
+		 
+		public function getTextFlow():TextFlow
+		{
+			// find the root element entry and either return null or the containing textFlow
+			var elem:FlowElement = this;
+			while (elem.parent != null)
+				elem = elem.parent;
+			return elem as TextFlow;		
+		}	
+
+		/**
+		 * Returns the ParagraphElement object associated with this element. It looks up the text flow hierarchy and returns 
+		 * the first ParagraphElement object.
+		 *
+		 * @return	the ParagraphElement object that's associated with this FlowElement object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @includeExample examples\FlowElement_getParagraphExample.as -noswf
+	 	 * 
+	 	 * @see #getTextFlow()
+	 	 * @see ParagraphElement
+		 */
+		 
+		public function getParagraph():ParagraphElement
+		{
+			var rslt:FlowElement = this;
+			while (rslt)
+			{
+				if (rslt is ParagraphElement)
+					return rslt as ParagraphElement;
+				rslt = rslt.parent;
+			}
+			return null;
+		}
+		
+		
+		/** 
+		 * Returns the FlowElement object that contains this FlowElement object, if this element is contained within 
+		 * an element of a particular type. 
+		 * 
+		 * Returns the FlowElement it is contained in. Otherwise, it returns null.
+		 * 
+		 * @private
+		 *
+		 * @param elementType	type of element for which to check
+		 */
+		public function getParentByType(elementType:Class):FlowElement
+		{
+			var curElement:FlowElement = parent;
+			while (curElement)
+			{
+				if (curElement is elementType)
+					return curElement;
+				curElement = curElement.parent;
+			}
+			return null;
+		}
+		
+		/** Returns the previous FlowElement sibling in the text flow hierarchy. 
+		*
+		* @includeExample examples\FlowElement_getPreviousSiblingExample.as -noswf
+		*
+		* @return 	the previous FlowElement object of the same type, or null if there is no previous sibling.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+	 	* @see #getNextSibling()
+		*/
+		public function getPreviousSibling():FlowElement
+		{
+			//this can happen if FE is on the scrap and doesn't have a parent. - gak 06.25.08
+			if(!parent)
+				return null;
+				
+			var idx:int = parent.getChildIndex(this);
+			return idx == 0 ? null : parent.getChildAt(idx-1);
+		}
+		
+		/** Returns the next FlowElement sibling in the text flow hierarchy. 
+		*
+		* @return the next FlowElement object of the same type, or null if there is no sibling.
+		*
+		* @includeExample examples\FlowElement_getNextSiblingExample.as -noswf
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+	 	* @see #getPreviousSibling()
+	 	*/
+	 	
+		public function getNextSibling():FlowElement
+		{
+			if (!parent)
+				return null;
+
+			var idx:int = parent.getChildIndex(this);
+			return idx == parent.numChildren-1 ? null : parent.getChildAt(idx+1);
+		}
+		
+		/** 
+		* Returns the character at the specified position, relative to this FlowElement object. The first
+		* character is at relative position 0.
+		* 
+		* @param relativePosition	The relative position of the character in this FlowElement object.
+		* @return String containing the character.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+	 	* @includeExample examples\FlowElement_getCharAtPositionExample.as -noswf
+	 	* 
+	 	* @see #getCharCodeAtPosition()
+	 	*/
+		
+		public function getCharAtPosition(relativePosition:int):String
+		{
+			return null;
+		}
+		
+		/** Returns the character code at the specified position, relative to this FlowElement. The first
+		* character is at relative position 0.
+		*
+		* @param relativePosition 	The relative position of the character in this FlowElement object.
+		*
+		* @return	the Unicode value for the character at the specified position.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+	 	* @includeExample examples\FlowElement_getCharCodeAtPositionExample.as -noswf
+	 	*
+	 	* @see #getCharAtPosition()
+	 	*/
+	 	
+		public function getCharCodeAtPosition(relativePosition:int):int
+		{
+			var str:String = getCharAtPosition(relativePosition);
+			return str && str.length > 0 ? str.charCodeAt(0) : 0;
+		}
+		
+		/** @private return an element or matching idName. */
+		tlf_internal function getElementByIDHelper(idName:String):FlowElement
+		{
+			if (this.id == idName)
+				return this;
+			return null;
+		}
+		
+		/** @private return adding elements with matching styleName to an array. */
+		tlf_internal function getElementsByStyleNameHelper(a:Array,styleName:String):void
+		{
+			if (this.styleName == styleName)
+				a.push(this);
+		}
+		
+		// **************************************** 
+		// End tree navigation code
+		// ****************************************	
+		
+		// **************************************** 
+		// Begin tree modification support code
+		// ****************************************	
+
+		/**
+		 * Update the FlowElement to account for text added before it.
+		 *
+		 * @param len	number of characters added (may be negative if deletion)
+		 */
+		private function updateRange(len:int): void
+		{
+			setParentRelativeStart(parentRelativeStart + len);
+		}
+		
+		/** Update the FlowElements in response to an insertion or deletion.
+		 *  The length of the element inserted to is updated, and the length of 
+		 *  each of its ancestor element. Each of the elements following siblings
+		 *  start index is updated (start index is relative to parent).
+		 * @private
+		 * @param startIdx		absolute index in flow where text was inserted
+		 * @param len			number of characters added (negative if removed)
+		 * updateLines			?? true if lines should be damaged??
+		 * @private 
+		 */
+		tlf_internal function updateLengths(startIdx:int,len:int,updateLines:Boolean):void
+		{
+			setTextLength(textLength + len);		
+			var p:FlowGroupElement = parent;	
+			if (p)
+			{
+				// update the elements following this in parent's children				
+				var idx:int = p.getChildIndex(this)+1;
+				CONFIG::debug { assert(idx != -1,"bad parent in FlowElement.updateLengths"); }
+				
+				var pElementCount:int = p.numChildren;
+				while (idx < pElementCount)
+				{
+					var child:FlowElement = p.getChildAt(idx++);
+					child.updateRange(len);
+				}
+				
+				// go up the tree to the root and update ancestor's lengths
+				p.updateLengths(startIdx,len,updateLines);
+			}
+		}
+		
+		/** @private */
+		tlf_internal function getEnclosingController(relativePos:int) : ContainerController
+		{
+			// CONFIG::debug { assert(pos <= length,"getEnclosingController - bad pos"); }
+			
+			var textFlow:TextFlow = getTextFlow();
+			
+			//more than likely, we are building up spans for the very first time.
+			//the container has not yet been created
+			if (textFlow == null || textFlow.flowComposer == null || textFlow.flowComposer.numLines == 0)
+				return null;
+			
+			var curItem:FlowElement = this;
+			while (curItem && (!(curItem is ContainerFormattedElement) || ContainerFormattedElement(curItem).flowComposer == null))
+			{
+				curItem = curItem.parent;
+			}
+			
+			var flowComposer:IFlowComposer = ContainerFormattedElement(curItem).flowComposer;
+			if (!flowComposer)
+				return null;
+				
+			var controllerIndex:int = ContainerFormattedElement(curItem).flowComposer.findControllerIndexAtPosition(getAbsoluteStart() + relativePos,false);
+			return controllerIndex != -1 ? flowComposer.getControllerAt(controllerIndex) : null;
+		}
+
+		
+		/** @private */
+		tlf_internal function deleteContainerText(endPos:int,deleteTotal:int):void
+		{
+			// update container counts
+					
+			if (getTextFlow())		// update container lengths only for elements that are attached to the rootElement
+			{
+				var absoluteEndPos:int = getAbsoluteStart() + endPos;
+				var absStartIdx:int = absoluteEndPos-deleteTotal;
+				
+				while (deleteTotal > 0)
+				{
+					var charsDeletedFromCurContainer:int;
+					var enclosingController:ContainerController = getEnclosingController(endPos-1);
+					if (!enclosingController)
+					{
+						// The end of the deleted text may be overset, so it doesn't appear in a container.
+						// Find the last container that contains the deleted text.
+						enclosingController = getEnclosingController(endPos - deleteTotal);
+						if (enclosingController)
+						{
+							var flowComposer:IFlowComposer = enclosingController.flowComposer;
+							var myIdx:int = flowComposer.getControllerIndex(enclosingController);
+							CONFIG::debug { assert(myIdx >= 0,"FlowElement.deleteContainerText: bad return from getContainerControllerIndex"); }
+							while (myIdx+1 < flowComposer.numControllers && enclosingController.absoluteStart + enclosingController.textLength < endPos)
+							{
+								enclosingController = flowComposer.getControllerAt(myIdx+1);
+								if (enclosingController.textLength)
+									break;
+								myIdx++;
+							}
+						}
+						if (!enclosingController)
+							break;
+					}
+					var enclosingControllerBeginningPos:int = enclosingController.absoluteStart;
+					if (absStartIdx < enclosingControllerBeginningPos)
+					{
+						charsDeletedFromCurContainer = absoluteEndPos - enclosingControllerBeginningPos + 1;
+					}
+					else if (absStartIdx < enclosingControllerBeginningPos + enclosingController.textLength)
+					{
+						charsDeletedFromCurContainer = deleteTotal;
+					} 
+					// Container textFlowLength may contain fewer characters than the those to be deleted in case of overset text. 
+					var containerTextLengthDelta:int = enclosingController.textLength < charsDeletedFromCurContainer ? enclosingController.textLength : charsDeletedFromCurContainer;
+					if (containerTextLengthDelta <= 0)
+						break;		// overset text is not in the last container -- we've deleted the container count, so exit
+					// working backwards - can't call setTextLength as it examines previous controllers and gets confused in the composeCompleteRatio logic
+					ContainerController(enclosingController).setTextLengthOnly(enclosingController.textLength -  containerTextLengthDelta);
+					deleteTotal -= containerTextLengthDelta;
+					absoluteEndPos -= containerTextLengthDelta;
+					endPos -= containerTextLengthDelta;
+				}
+			}
+		}
+		
+		/** @private */
+		tlf_internal function normalizeRange(normalizeStart:uint,normalizeEnd:uint):void
+		{
+			// default is do nothing
+		}
+		
+		/** Support for splitting FlowLeafElements.  Does a quick copy of _characterFormat if necessary.  @private */
+		tlf_internal function quickCloneTextLayoutFormat(sibling:FlowElement):void
+		{
+			_formatValueHolder = sibling._formatValueHolder ? new FlowValueHolder(sibling._formatValueHolder) : null;
+		}
+			
+		// **************************************** 
+		// End tree modification support code
+		// ****************************************	
+		
+		/** @private This API supports the inputmanager */
+		tlf_internal function updateForMustUseComposer(textFlow:TextFlow):Boolean
+		{ return false; }
+
+		// **************************************** 
+		// Begin debug support code
+		// ****************************************	
+		
+		CONFIG::debug static private var debugDictionary:Dictionary = new Dictionary(true);
+		CONFIG::debug static private var nextKey:int = 1;
+		
+		CONFIG::debug static public function getDebugIdentity(o:Object):String
+		{
+			if (debugDictionary[o] == null)
+			{
+				var s:String = flash.utils.getQualifiedClassName(o);
+				if (s)
+					s = s.substr( s.lastIndexOf(":")+1);
+				else
+					s = "";
+				debugDictionary[o] = s + "." + nextKey.toString();
+				nextKey++;
+			}
+			return debugDictionary[o];
+		}
+		
+		/**
+		 * Check FlowElement for internal consistency.
+		 * @private
+		 * Lots of internal checks are done on FlowElements, some are dependent
+		 * on the type of element. 
+		 * @return Number of errors found
+		 */
+		CONFIG::debug public function debugCheckFlowElement(depth:int = 0, extraData:String = ""):int
+		{
+			if (Debugging.verbose)
+			{			
+				if (depth == 0)
+					trace("----------------------------------");
+
+				trace("FlowElement:",depth.toString(),getDebugIdentity(this),"start:",parentRelativeStart.toString(),"length:",textLength.toString(),extraData);
+			}
+			return 0;
+		}
+		
+		CONFIG::debug public static function elementPath(element:FlowElement):String
+		{
+			var result:String;
+			
+			if (element != null)
+			{
+				if (element.parent != null)
+					result = elementPath(element.parent) + "." + element.name + "[" + element.parent.getChildIndex(element) + "]";
+				else
+					result = element.name;
+			}
+			return result;
+		}
+
+		/**
+		 * debugging only - show element as string
+		 */
+		CONFIG::debug public function toString():String
+		{
+			return "flowElement:" + name + " start:" + parentRelativeStart.toString() + " absStart:" + this.getAbsoluteStart().toString() + " textLength:" + textLength.toString();			
+		}
+		// **************************************** 
+		// End debug support code
+		// ****************************************	
+
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/FlowGroupElement.as b/textLayout_core/src/flashx/textLayout/elements/FlowGroupElement.as
new file mode 100755
index 0000000..1f9c889
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/FlowGroupElement.as
@@ -0,0 +1,1165 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements 
+{
+	import flash.display.DisplayObjectContainer;
+	import flash.text.engine.ContentElement;
+	import flash.text.engine.GroupElement;
+	import flash.utils.getQualifiedClassName;
+	
+	import flashx.textLayout.compose.FlowDamageType;
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.events.ModelChange;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+
+	[DefaultProperty("mxmlChildren")]
+
+	/** 
+	 * The FlowGroupElement class is the base class for FlowElement objects that can have an array of children. These classes include
+	 * TextFlow, ParagraphElement, DivElement, and LinkElement.
+	 *
+	 * <p>You cannot create a FlowGroupElement object directly. Invoking <code>new FlowGroupElement()</code> throws an error 
+ 	 * exception.</p>
+ 	 *
+ 	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 *
+	 * @see DivElement
+	 * @see LinkElement
+	 * @see ParagraphElement
+	 * @see TextFlow
+	 */ 
+	public class FlowGroupElement extends FlowElement
+	{
+		/** children of the FlowGroupElement.  They must all be FlowElements. Depending on _numChildren either store a single child in _singleChild or multiple children in the array. */
+		private var _childArray:Array;
+		private var _singleChild:FlowElement;
+		private var _numChildren:int;
+		
+		/** Base class - invoking <code>new FlowGroupElement()</code> throws an error exception.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function FlowGroupElement()
+		{
+			_numChildren = 0;
+		}
+		
+		/** @private */
+		public override function deepCopy(startPos:int = 0, endPos:int = -1):FlowElement
+		{
+			if (endPos == -1)
+				endPos = textLength;
+				
+			var retFlow:FlowGroupElement = shallowCopy(startPos, endPos) as FlowGroupElement;
+			var newFlowElement:FlowElement;
+			for (var idx:int = 0; idx < _numChildren; idx++)
+			{
+				var child:FlowElement = getChildAt(idx);
+				if (((startPos - child.parentRelativeStart) < child.textLength) && ((endPos - child.parentRelativeStart) > 0))			
+				{
+					//child is in Selected area
+					newFlowElement = child.deepCopy(startPos - child.parentRelativeStart, endPos - child.parentRelativeStart);
+					retFlow.replaceChildren(retFlow.numChildren,retFlow.numChildren,newFlowElement);	
+					if (retFlow.numChildren > 1)
+					{
+						var possiblyEmptyFlowElement:FlowElement = retFlow.getChildAt(retFlow.numChildren - 2);
+						if (possiblyEmptyFlowElement.textLength == 0)
+						{
+							retFlow.replaceChildren(retFlow.numChildren - 2, retFlow.numChildren - 1);
+						}
+					}									
+				}
+			}
+			return retFlow;
+		}
+		
+		/* @private */
+		public override function getText(relativeStart:int=0, relativeEnd:int=-1, paragraphSeparator:String="\n"):String
+		{
+			var text:String = super.getText();
+			
+			if (relativeEnd == -1)
+				relativeEnd = textLength;
+
+			var pos:int = relativeStart;
+			for (var idx:int = findChildIndexAtPosition(relativeStart); idx < _numChildren && pos < relativeEnd; idx++)
+			{
+				var child:FlowElement = getChildAt(idx);
+				var copyStart:int = pos - child.parentRelativeStart;
+				var copyEnd:int = Math.min(relativeEnd - child.parentRelativeStart, child.textLength);
+				text += child.getText(copyStart, copyEnd, paragraphSeparator);
+				pos += copyEnd - copyStart;
+				if (paragraphSeparator && child is ParagraphFormattedElement && pos < relativeEnd)
+					text += paragraphSeparator;
+			}
+			return text;
+		}
+		
+		// **************************************** 
+		// Begin TextLayoutFormat Related code
+		// ****************************************
+		/** @private */
+		tlf_internal override function formatChanged(notifyModelChanged:Boolean = true):void
+		{
+			super.formatChanged(notifyModelChanged);
+			for (var idx:int = 0; idx < _numChildren; idx++)
+			{
+				var child:FlowElement = getChildAt(idx);
+				child.formatChanged(false);
+			}			
+		}
+		// **************************************** 
+		// End TLFFormat Related code
+		// ****************************************
+	
+		// **************************************** 
+		// Begin import helper code 
+		// ****************************************	
+		[RichTextContent]
+		/** 
+		 * Appends an array of children to this object. Uses the <code>replaceChildren()</code> method to append each 
+		 * element in the array. Intended for use during an mxml compiled import.
+		 * 
+		 * @throws TypeError if array element is not a FlowElement or String
+		 * @param array - array of children to attach.  Each element of the array must be a FlowElement object or a String.
+		 * @see FlowGroupElement#replaceChildren()
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function get mxmlChildren():Array
+		{
+			return _numChildren == 0 ? null : (_numChildren == 1 ? [ this._singleChild ] : _childArray.slice() );
+		}
+		public function set mxmlChildren(array:Array):void
+		{
+			/* NOTE: all FlowElement implementers and overrides of mxmlChildren must specify [RichTextContent] metadata */
+
+			// remove all existing children
+			this.replaceChildren(0,_numChildren);
+			
+			// In the text model, non-ParagraphFormattedElements (i.e. spans, images, links, TCY) cannot be children of a ContainerFormattedElement (TextFlow, DivElement etc.)
+			// They can only be children of paragraphs or subparagraph blocks. 
+			// In XML, however, <p> elements can be implied (for example, a <span> may appear as a direct child of <flow>).  
+			// So, while parsing the XML, if we enounter a non-ParagraphFormattedElement child of a ContainerFormattedElement 
+			// 1. an explicitly created paragraph is used as the parent instead
+			// 2. such explicitly created paragraphs are shared by adjacent flow elements provided there isn't an intervening ParagraphFormattedElement
+			var effectiveParent:FlowGroupElement = this; 
+			
+			// append them on the end		
+			for each (var child:Object in array)
+			{
+				if (child is FlowElement)
+				{
+					if (child is ParagraphFormattedElement)
+					{
+						// Reset due to possibly intervening FlowParagrpahElement; See note 2. above
+						effectiveParent = this; 
+					}
+					else if (effectiveParent is ContainerFormattedElement)
+					{
+						// See note 1. above
+						effectiveParent = new ParagraphElement();
+						effectiveParent.impliedElement = true;
+						replaceChildren(_numChildren, _numChildren, effectiveParent);
+					}
+					if ( (child is SpanElement) || (child is SubParagraphGroupElement))
+						child.bindableElement = true;
+					effectiveParent.replaceChildren(effectiveParent.numChildren, effectiveParent.numChildren, FlowElement(child) );
+				}
+				else if (child is String)
+				{
+					var s:SpanElement = new SpanElement();
+					s.text = String(child);
+					s.bindableElement = true;
+					s.impliedElement = true;
+					
+					if (effectiveParent is ContainerFormattedElement)
+					{
+						// See note 1. above
+	 					effectiveParent = new ParagraphElement();
+						replaceChildren(_numChildren, _numChildren, effectiveParent);
+						effectiveParent.impliedElement = true;
+					}
+					effectiveParent.replaceChildren(effectiveParent.numChildren, effectiveParent.numChildren, s);
+				}
+				else if (child != null)
+					throw new TypeError(GlobalSettings.resourceStringFunction("badMXMLChildrenArgument",[ getQualifiedClassName(child) ]));
+			}
+		}
+
+		/** @private */
+		override tlf_internal function createGeometry(parentToBe:DisplayObjectContainer):void
+		{
+			for (var idx:int = 0; idx < _numChildren; idx++)
+			{
+				var child:FlowElement = getChildAt(idx);
+				child.createGeometry(parentToBe);
+			}
+		}
+				
+		// **************************************** 
+		// End import helper code
+		// ****************************************	
+		// **************************************** 
+		// Begin tree navigation code
+		// ****************************************	
+		
+		/** 
+		* Returns the number of FlowElement children that this FlowGroupElement object has.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*/
+	 	
+		public function get numChildren(): int
+		{
+			return _numChildren;
+		}
+		
+		/** 
+		 * Searches in children for the specified FlowElement object and returns its index position.
+		 *
+		 * @param child	The FlowElement object item to locate among the children.
+		 * @return The index position of the specified chilc.  If <code>child</code> is not found, returns -1.
+		 *  
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public function getChildIndex(child:FlowElement):int
+		{
+			var hi:int = _numChildren-1;
+			// one hole here - if child is null and this has no children then we'll return 0
+			if (hi <= 0)
+				return _singleChild == child ? 0 : -1;
+			
+			var lo:int = 0;
+			while (lo <= hi)
+			{
+				var mid:int = (lo+hi)/2;
+				var p:FlowElement = _childArray[mid];
+				if (p.parentRelativeStart == child.parentRelativeStart)
+				{
+					// during intermediate caluclations there are zero length elements lurking about
+					if (p == child)
+					{
+						CONFIG::debug { assert(_childArray.indexOf(child) == mid,"Bad getChildIndex"); }
+						return mid;
+					}
+					var testmid:int;
+					if (p.textLength == 0)
+					{
+						// look forward for a match
+						for (testmid = mid; testmid < _numChildren; testmid++)
+						{
+							p = _childArray[testmid];
+							if (p == child)
+							{
+								CONFIG::debug { assert(_childArray.indexOf(child) == testmid,"Bad getChildIndex"); }
+								return testmid;
+							}
+							if (p.textLength != 0)
+								break;
+						}
+					}
+					
+					// look backwards
+					while (mid > 0)
+					{
+						mid--;
+						p = _childArray[mid];
+						if (p == child)
+						{
+							CONFIG::debug { assert(_childArray.indexOf(child) == mid,"Bad getChildIndex"); }
+							return mid;
+						}
+						if (p.textLength != 0)
+							break;
+					}
+					CONFIG::debug { assert(_childArray.indexOf(child) == -1,"Bad getChildIndex"); }
+					return -1;
+				}
+				if (p.parentRelativeStart < child.parentRelativeStart)
+					lo = mid+1;
+				else
+					hi = mid-1;
+			}
+			CONFIG::debug { assert(_childArray.indexOf(child) == -1,"Bad getChildIndex"); }
+			return -1;
+		}
+		/** 
+		 * Returns the FlowElement child at the specified index.
+		 * 
+		 * @param index the position at which to find the FlowElement object.
+		 *
+		 * @return  the child FlowElement object at the specified position.
+		 * @includeExample examples\FlowGroupElement_getChildAtExample.as -noswf
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public function getChildAt(index:int):FlowElement
+		{
+			if (_numChildren > 1)
+				return _childArray[index];
+			return index == 0 ? _singleChild : null;
+		}
+	
+		/** @private */
+		tlf_internal function getNextLeafHelper(limitElement:FlowGroupElement,child:FlowElement):FlowLeafElement
+		{
+			var idx:int = getChildIndex(child);
+			if (idx == -1)
+				return null;	// bug?
+			
+			if (idx == _numChildren-1)
+			{
+				if (limitElement == this || !parent)
+					return null;
+				
+				return parent.getNextLeafHelper(limitElement,this);
+			}
+			
+			var child:FlowElement = getChildAt(idx+1);
+			return (child is FlowLeafElement) ? FlowLeafElement(child) : FlowGroupElement(child).getFirstLeaf();
+		}
+				
+		/** @private */
+		tlf_internal function getPreviousLeafHelper(limitElement:FlowGroupElement,child:FlowElement):FlowLeafElement
+		{
+			var idx:int = getChildIndex(child);
+			if (idx == -1)
+				return null;	// bug?
+			
+			if (idx == 0)
+			{
+				if (limitElement == this || !parent)
+					return null;
+				
+				return parent.getPreviousLeafHelper(limitElement,this);
+			}
+			
+			var child:FlowElement = getChildAt(idx-1);
+			return (child is FlowLeafElement) ? FlowLeafElement(child) : FlowGroupElement(child).getLastLeaf();
+		}
+	
+		/**
+		 * Given a relative text position, find the leaf element that contains the position. 
+		 *
+		 * <p>Looks down the flow element hierarchy to find the FlowLeafElement that 
+		 * contains the specified position. The specified position 
+		 * is relative to this FlowElement object.</p>
+		 *
+		 * @param relativePosition	relative text index to look up.
+		 * @return	the leaf element containing the relative position.
+		 *
+		 * @includeExample examples\FlowGroupElement_findLeafExample.as -noswf
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function findLeaf(relativePosition:int):FlowLeafElement
+		{
+			var found:FlowLeafElement = null;
+			var childIdx:int = findChildIndexAtPosition(relativePosition);
+			if (childIdx != -1)
+			{
+				// childIdx is index of the first child containing pos. Many of its following siblings
+				// may also contain pos if their respective previous siblings are zero-length. 
+				// Check them all until a leaf containing pos is found.
+				do
+				{
+					var child:FlowElement = this.getChildAt(childIdx++);
+					if (!child)
+						break;
+					
+					var childRelativePos: int = relativePosition - child.parentRelativeStart;
+					if (child is FlowGroupElement)
+						found = FlowGroupElement(child).findLeaf(childRelativePos);
+					else
+					{
+						// if its not a FlowGroupElement than it must be a FlowLeafElement
+						CONFIG::debug { assert(child is FlowLeafElement,"Invalid child in FlowGroupElement.findLeaf"); }
+						if (childRelativePos >= 0 && childRelativePos < child.textLength || (child.textLength == 0 && _numChildren == 1))
+							found = FlowLeafElement(child);
+					}
+				} while (!found && !child.textLength);
+				
+			}
+			return found;
+		}
+		
+		/**
+		 * Given a relative text position, find the index of the first child FlowElement that contains the relative position. 
+		 * More than one child can contain relative position because of zero length FlowElements.
+		 *  
+		 * <p>Examine the children to find the FlowElement that contains the relative position. The supplied relative position 
+		 * is relative to this FlowElement.</p>
+		 *
+		 * @param relativePosition 	the position relative to this element
+		 * @return 	index of first child element containing <code>relativePosition</code>
+		 *
+		 * @includeExample examples\FlowGroupElement_findChildIndexAtPositionExample.as -noswf
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function findChildIndexAtPosition(relativePosition:int):int
+		{
+			var lo:int = 0;
+			var hi:int = _numChildren-1;
+			while (lo <= hi)
+			{
+				var mid:int = (lo+hi)/2;
+				var child:FlowElement = getChildAt(mid);
+				if (child.parentRelativeStart <= relativePosition)
+				{
+					// always return the first zero length element in the list
+					if (child.parentRelativeStart == relativePosition)
+					{
+						while (mid != 0)
+						{
+							child = getChildAt(mid-1);
+							if (child.textLength != 0)
+								break;
+							mid--;
+						}
+						return mid;
+					}
+					if (child.parentRelativeStart + child.textLength > relativePosition)
+						return mid;
+					lo = mid+1;
+				}
+				else
+					hi = mid-1;
+			}
+			return -1;
+		}
+		
+		/**
+		 * Returns the first FlowLeafElement descendant of this group.
+		 *
+		 * @return the first FlowLeafElement object.
+		 *
+		 * @includeExample examples\FlowGroupElement_getFirstLeafExample.as -noswf
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function getFirstLeaf(): FlowLeafElement
+		{
+			if (_numChildren > 1)
+			{
+				for (var idx:int = 0; idx < _numChildren; idx++)
+				{
+					var child:FlowElement = _childArray[idx];
+					var leaf:FlowLeafElement = (child is FlowGroupElement) ? FlowGroupElement(child).getFirstLeaf() : FlowLeafElement(child);
+					if (leaf)
+						return leaf;
+				}
+				return null;
+			}
+			return _numChildren == 0 ? null : ((_singleChild is FlowGroupElement) ? FlowGroupElement(_singleChild).getFirstLeaf() : FlowLeafElement(_singleChild));
+		}
+		
+		/**
+		 * Returns the last FlowLeafElement descendent of this group.
+		 *
+		 * @return the last FlowLeafElement object.
+		 *
+		 * @includeExample examples\FlowGroupElement_getLastLeafExample.as -noswf
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function getLastLeaf(): FlowLeafElement
+		{
+			if (_numChildren > 1)
+			{
+				for (var idx:int = _numChildren; idx != 0; idx--)
+				{
+					var child:FlowElement = _childArray[idx-1];
+					var leaf:FlowLeafElement = (child is FlowGroupElement) ? FlowGroupElement(child).getLastLeaf() : FlowLeafElement(child) ;
+					if (leaf)
+						return leaf;
+				}
+				return null;
+			}
+			return _numChildren == 0 ? null : ((_singleChild is FlowGroupElement) ? FlowGroupElement(_singleChild).getLastLeaf() : FlowLeafElement(_singleChild));
+		}
+		
+		/** @private */
+		public override function getCharAtPosition(relativePosition:int):String
+		{
+			var leaf:FlowLeafElement = findLeaf(relativePosition);
+			return leaf ? leaf.getCharAtPosition(relativePosition-leaf.getElementRelativeStart(this)) : "";
+		} 
+		
+		/** @private return an element or matching idName. */
+		tlf_internal override function getElementByIDHelper(idName:String):FlowElement
+		{
+			var rslt:FlowElement = super.getElementByIDHelper(idName);
+			if (rslt == null)
+			{
+				for (var idx:int = 0; idx < _numChildren; idx++)
+				{
+					var child:FlowElement = getChildAt(idx);
+					rslt = child.getElementByIDHelper(idName);
+					if (rslt != null)
+						break;
+				}
+			}
+			return rslt;
+		}
+		
+		/** @private return adding elements with matching styleName to an array. */
+		tlf_internal override function getElementsByStyleNameHelper(a:Array,styleName:String):void
+		{
+			super.getElementsByStyleNameHelper(a,styleName);
+			for (var idx:int = 0; idx < _numChildren; idx++)
+			{
+				var child:FlowElement = getChildAt(idx);
+				child.getElementsByStyleNameHelper(a,styleName);
+			}
+
+		}
+		// **************************************** 
+		// End tree navigation code
+		// ****************************************			
+		// **************************************** 
+		// Begin tree modification support code
+		// ****************************************	
+		
+		/** @private */
+		tlf_internal function removeBlockElement(child:FlowElement, block:ContentElement):void
+		{
+			// when Image's are moved into ParagraphElement's this assertion should always fire
+			CONFIG::debug { assert(child is InlineGraphicElement,"invalid call to removeBlockElement"); }
+		}
+		
+		/** @private */
+		tlf_internal function insertBlockElement(child:FlowElement, block:ContentElement):void
+		{
+			// when Image's are moved into ParagraphElement's this assertion should always fire
+			CONFIG::debug { assert(child is InlineGraphicElement,"invalid call to insertBlockElement"); }
+		}
+		
+		/** @private 
+		 * True if there is a corresponding FTE data structure currently instantiated.
+		 */
+		tlf_internal function hasBlockElement():Boolean
+		{
+			CONFIG::debug { assert(false,"invalid call to hasBlockElement"); }
+			return false;
+		}
+		
+		/** @private */
+		tlf_internal function createContentAsGroup():GroupElement
+		{
+			CONFIG::debug { assert(false,"invalid call to createContentAsGroup"); }
+			return null;
+		}
+				
+		/** @private This is only called from SpanElement.splitAtPosition */
+		tlf_internal function addChildAfterInternal(child:FlowElement, newChild:FlowElement):void
+		{
+			//this function was kept for efficiency purposes. It is used by splitForChange
+			//which in turn is used by applyCharacterFormat, when changing the
+			//attributes applied to characters.  In the end, the length of the document
+			//will be the same. So, without this fnction, we would be creating a new
+			//span, updating the lengths, and then removing a part of the span and updating
+			//the lengths again (getting the same exact lengths we had before). This can be
+			//inefficient. So, this function does everything addChildAfter does, without
+			//updating the lengths. This is an internal function since the user really has
+			//to know what they're doing and will not be exposed as a public API
+			CONFIG::debug { assert(_numChildren != 0, "addChildAfter must have children"); }
+			CONFIG::debug { assert(getChildIndex(child) != -1, "addChildAfter: before child must be in array"); }
+			if (_numChildren > 1)
+			{
+				// TODO: binary search for indexOf child
+				CONFIG::debug { assert(_childArray.indexOf(child) != -1,"Bad call to addChildAfterInternal"); }
+				_childArray.splice(_childArray.indexOf(child)+1,0,newChild);
+			}
+			else
+			{
+				// not found returns above returns -1 so behave the same
+				CONFIG::debug { assert(_singleChild == child,"Bad call to addChildAfterInternal"); }
+				_childArray = [ _singleChild, newChild ];
+				_singleChild = null;
+			}
+			_numChildren++;
+			newChild.setParentAndRelativeStartOnly(this,child.parentRelativeEnd);
+		}
+		
+		/**
+		 * Helper for replaceChildren.  Determines if elem can legally be a child of this.
+		 * @return true --> ok, false--> not a legal child
+		 * @private 
+		 */
+		tlf_internal function canOwnFlowElement(elem:FlowElement):Boolean
+		{
+			return !(elem is TextFlow) && !(elem is FlowLeafElement) && !(elem is SubParagraphGroupElement);
+		}
+		
+		/** @private */	
+		private static function getNestedArgCount(obj:Object):uint
+		{
+			return (obj is Array) ? obj.length : 1;
+		}		
+		
+		/** @private */	
+		private static function getNestedArg(obj:Object, index:uint):FlowElement
+		{
+			CONFIG::debug { assert(index < getNestedArgCount(obj),"bad index to getNestedArg"); }; 
+			return ((obj is Array) ? obj[index] : obj) as FlowElement;
+		}
+				
+		/**
+		 * Replaces child elements in the group with the specified new elements. Use the <code>beginChildIndex</code> and
+		 * <code>endChildIndex</code> parameters to govern the operation as follows:
+		 * <p><ul>
+		 * <li>To delete elements, do not pass any replacement elements.</li>
+		 * <li>To insert elements, pass the same value for <code>beginChildIndex</code> and <code>endChildIndex</code>.  
+		 * The new elements is inserted before the specified index.</li>
+		 * <li>To append elements, pass <code>numChildren</code> for <code>beginChildIndex</code> and <code>endChildIndex</code>.</li>
+		 * </ul></p>
+		 * <p>Otherwise, this method replaces the specified elements, starting with the element at <code>beginChildIndex</code> 
+		 * and up to but not including <code>endChildIndex</code>.</p>
+		 * 
+		 * @param beginChildIndex The index value for the start position of the replacement range in the children array.
+		 * @param endChildIndex The index value following the end position of the replacement range in the children array.
+		 * @param rest The elements to replace the specified range of elements. Can be a sequence containing flow elements or
+		 * arrays or vectors thereof.
+		 *	 
+	     * @throws RangeError The <code>beginChildIndex</code> or <code>endChildIndex</code> specified is out of range.
+	     * 
+	     * @includeExample examples\FlowGroupElement_replaceChildrenExample.as -noswf
+		 *
+	     * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function replaceChildren(beginChildIndex:int, endChildIndex:int, ...rest):void
+		{
+			if (beginChildIndex > _numChildren || endChildIndex > _numChildren)
+				throw RangeError(GlobalSettings.resourceStringFunction("badReplaceChildrenIndex"));	
+			
+			var thisAbsStart:int = getAbsoluteStart();
+			var absStartIdx:int =  thisAbsStart + (beginChildIndex == _numChildren ? textLength : getChildAt(beginChildIndex).parentRelativeStart);
+			var relStartIdx:int = beginChildIndex == _numChildren ? textLength : getChildAt(beginChildIndex).parentRelativeStart;
+			
+			// deletion phase
+			if (beginChildIndex < endChildIndex)
+			{
+				var child:FlowElement;	// scratch variable
+				var len:int = 0;
+
+				while (beginChildIndex < endChildIndex)
+				{
+					child = this.getChildAt(beginChildIndex);
+					child.modelChanged(ModelChange.ELEMENT_REMOVAL, 0, child.textLength);
+					len += child.textLength;
+					
+					child.setParentAndRelativeStart(null,0);
+					if (_numChildren == 1)
+					{
+						_singleChild = null;
+						_numChildren = 0;
+					}
+					else
+					{
+						_childArray.splice(beginChildIndex,1);
+						_numChildren--;
+						if (_numChildren == 1)
+						{
+							_singleChild = _childArray[0];
+							_childArray = null;
+						}
+					}
+					endChildIndex--;
+				}
+				if (len)
+				{
+					// TODO: this code should move into updateLengths.  updateLengths needs a rewrite
+					// as it assumes that any element that is removed has its length set to zero and updateLengths
+					// is called on that element first.  replaceChildren doesn't do that - it just removes the element
+					
+					// until rewrite reuse endChildIndex and update start of all following elements
+					while (endChildIndex < _numChildren)
+					{
+						child = getChildAt(endChildIndex);
+						child.setParentRelativeStart(child.parentRelativeStart-len);
+						endChildIndex++;
+					}
+				
+					// update lengths
+					updateLengths(absStartIdx,-len,true);
+					
+					deleteContainerText(relStartIdx + len,len);
+				}
+			}
+			CONFIG::debug { assert(thisAbsStart == getAbsoluteStart(),"replaceChildren: Bad thisAbsStart"); }
+			var childrenToAdd:int = 0;		// number of children to add
+			var flatNewChildList:Array;		// stores number of children when > 1
+			var newChildToAdd:FlowElement;	// stores a single child to add - avoids creating an Array for the 99% case
+			 
+			var newChild:FlowElement; 		// scratch
+			var idx:int;					// scratch
+			
+			for each (var obj:Object in rest)
+			{
+				if (!obj)
+					continue;
+				
+				var numNestedArgs:int = getNestedArgCount(obj);
+				for (idx = 0; idx<numNestedArgs; idx++)
+				{
+					newChild = getNestedArg(obj, idx);
+					if (newChild)
+					{
+						if (newChild.parent)
+						{
+							if (newChild.parent == this)
+							{
+								// special handling in this case
+								var childIndex:int = getChildIndex(newChild);
+								newChild.parent.removeChild(newChild);
+								thisAbsStart = getAbsoluteStart();	// is it in the same flow?
+								if (childIndex <= beginChildIndex)
+								{
+									beginChildIndex--;
+									absStartIdx =  thisAbsStart + (beginChildIndex == _numChildren ? textLength : getChildAt(beginChildIndex).parentRelativeStart);
+									relStartIdx = beginChildIndex == _numChildren ? textLength : getChildAt(beginChildIndex).parentRelativeStart;
+								}
+							}
+							else
+							{
+								thisAbsStart = getAbsoluteStart();	// is it in the same flow?
+								newChild.parent.removeChild(newChild);
+							}
+						}
+						if (!canOwnFlowElement(newChild))
+							throw ArgumentError(GlobalSettings.resourceStringFunction("invalidChildType"));
+						
+						// manage as an array or a single child
+						if (childrenToAdd == 0)
+							newChildToAdd = newChild
+						else if (childrenToAdd == 1)
+							flatNewChildList = [ newChildToAdd, newChild ];
+						else
+							flatNewChildList.push(newChild);
+						childrenToAdd++;
+					}
+				}
+			}			
+
+			if (childrenToAdd)
+			{
+				// TODO-9/18/2008-ideally, do the following in one shot, but insertBlockElement
+				// called from setParentAndRelativeStart in the loop below has different behavior
+				// based on the size of _children (zero vs. non-zero)
+				//_children.splice(beginChildIndex,0,flatNewChildList);
+				var addedTextLength:uint = 0;
+				for (idx = 0; idx < childrenToAdd; idx++)
+				{
+					newChild = childrenToAdd == 1 ? newChildToAdd : flatNewChildList[idx];
+					
+					if (_numChildren == 0)
+						_singleChild = newChild;
+					else if (_numChildren > 1)
+						_childArray.splice(beginChildIndex,0,newChild);
+					else
+					{
+						_childArray = beginChildIndex == 0 ? [ newChild, _singleChild ] : [ _singleChild, newChild ];
+						_singleChild = null;
+					}
+					_numChildren++;
+					newChild.setParentAndRelativeStart(this,relStartIdx+addedTextLength);
+					addedTextLength += newChild.textLength;
+					beginChildIndex++;	// points to the next slot
+				}
+				CONFIG::debug { assert(thisAbsStart == getAbsoluteStart(),"replaceChildren: Bad thisAbsStart"); }
+				if (addedTextLength)
+				{
+					// update following elements - see comment above.
+					// it would be best if this loop only ran once
+					while (beginChildIndex < _numChildren)
+					{
+						child = getChildAt(beginChildIndex++);
+						child.setParentRelativeStart(child.parentRelativeStart+addedTextLength);
+					}
+					updateLengths(absStartIdx,addedTextLength,true);
+					var enclosingContainer:ContainerController = getEnclosingController(relStartIdx);
+					if (enclosingContainer)
+						ContainerController(enclosingContainer).setTextLength(enclosingContainer.textLength + addedTextLength);
+				}
+				for (idx = 0; idx < childrenToAdd; idx++)
+				{
+					newChild = childrenToAdd == 1 ? newChildToAdd : flatNewChildList[idx];
+					newChild.modelChanged(ModelChange.ELEMENT_ADDED, 0, newChild.textLength);
+				}
+			}
+			else 
+			{	
+				var tFlow:TextFlow = getTextFlow();
+				if (tFlow != null)
+				{
+					// beginChildIndex points to the next element
+					// use scratch idx as "damageStart"
+					if (beginChildIndex < _numChildren)
+            		{
+            			// first, look for the next element and damage the beginning.
+						idx = thisAbsStart + getChildAt(beginChildIndex).parentRelativeStart;
+            		} 
+            		else if (beginChildIndex > 1)
+            		{
+            			// damage the end of the previous element
+						newChild = getChildAt(beginChildIndex-1);
+						idx = thisAbsStart + newChild.parentRelativeStart + newChild.textLength - 1;
+            		} 
+					else
+					{
+						// damage the very end of the textFlow
+						idx = thisAbsStart;
+						if (idx >= tFlow.textLength)
+							idx--;
+     				}
+     				tFlow.damage(idx, 1, FlowDamageType.GEOMETRY, false);
+   				}   				
+			}
+		}
+		
+		/** 
+		 * Appends a child FlowElement object. The new child is added to the end of the children list.
+		 * 
+		 * @param child The child element to append.
+		 *
+		 * @return  the added child FlowElement 
+		 * 
+		 * @includeExample examples\FlowGroupElement_addChildExample.as -noswf
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function addChild(child:FlowElement):FlowElement
+		{
+			replaceChildren(_numChildren, _numChildren, child);
+			return child;
+		}
+		
+		/** 
+		 * Adds a child FlowElement object at the specified index position.
+		 *
+		 * @param The index of the position at which to add the child element, with the first position being 0.
+		 * @param child The child element to add.
+		 * @throws RangeError The <code>index</code> is out of range.
+		 *
+		 * @return  the added child FlowElement 
+		 *
+		 * @includeExample examples\FlowGroupElement_addChildAtExample.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+		 */
+		 
+		public function addChildAt(index:uint, child:FlowElement):FlowElement
+		{
+			replaceChildren(index, index, child);
+			return child;
+		}
+		
+		/** 
+		 * Removes the specified child FlowElement object from the group.
+		 *
+		 * @param child The child element to remove.
+		 * @throws ArgumentError The <code>child</code> is not found.
+		 *
+		 * @return  the removed child FlowElement object 
+		 *
+		 * @includeExample examples\FlowGroupElement_removeChildExample.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 *
+		 */
+		 
+		public function removeChild(child:FlowElement):FlowElement
+		{
+			var index:int = getChildIndex(child);
+			if (index == -1)
+				throw ArgumentError(GlobalSettings.resourceStringFunction("badRemoveChild"));
+				
+			removeChildAt(index);
+			return child;
+		}
+		
+		/** 
+		 * Removes the child FlowElement object at the specified index position.
+		 *
+		 * @param index position at which to remove the child element.
+		 * @throws RangeError The <code>index</code> is out of range.
+		 *
+		 * @return  the child FlowElement object removed from the specified position.
+		 *
+		 * @includeExample examples\FlowGroupElement_removeChildAtExample.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function removeChildAt(index:uint):FlowElement
+		{
+			var childToReplace:FlowElement = getChildAt(index);
+			replaceChildren(index, index+1);
+			return childToReplace;
+		}
+		
+		/** 
+		 * Splits this object at the position specified by the <code>childIndex</code> parameter. If this group element has 
+		 * a parent, creates a shallow copy of this object and replaces its children with the elements up to the index. Moves 
+		 * elements following <code>childIndex</code> into the copy.
+		 * 
+		 * @return the new FlowGroupElement object.
+		 * @throws RangeError if <code>childIndex</code> is greater than the length of the children.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function splitAtIndex(childIndex:int):FlowGroupElement
+		{
+			if (childIndex > _numChildren)
+				throw RangeError(GlobalSettings.resourceStringFunction("invalidSplitAtIndex"));
+					
+			var newSibling:FlowGroupElement = shallowCopy() as FlowGroupElement;
+
+			var numChildrenToMove:int = _numChildren-childIndex;
+			if (numChildrenToMove == 1)
+				newSibling.addChild(removeChildAt(childIndex));
+			else if (numChildrenToMove != 0)
+			{
+				var childArray:Array = _childArray.slice(childIndex);
+				this.replaceChildren(childIndex,_numChildren-1);
+				newSibling.replaceChildren(0, 0, childArray);		
+			}
+			
+			if (parent)
+			{
+				var myidx:int = parent.getChildIndex(this);
+				parent.replaceChildren(myidx+1,myidx+1,newSibling);
+			}
+
+			return newSibling;
+		}
+
+		/** 
+		 * Splits this object at the position specified by the <code>relativePosition</code> parameter, where 
+		 * the relative position is a relative text position in this element.
+		 * 
+		 * @throws RangeError if relativePosition is greater than textLength, or less than 0.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 * 
+	 	 * @private
+		 */
+		 
+		public override function splitAtPosition(relativePosition:int):FlowElement
+		{
+			// Creates a shallowCopy of this and adds it to parent after this.  
+			// Moves elements from characterIndex forward into the copy
+		 	// returns the new shallowCopy
+			if ((relativePosition < 0) || (relativePosition > textLength))
+				throw RangeError(GlobalSettings.resourceStringFunction("invalidSplitAtPosition"));
+			
+			var curElementIdx:int;
+			
+			if (relativePosition == textLength)
+				curElementIdx = _numChildren;
+			else
+			{
+				curElementIdx = findChildIndexAtPosition(relativePosition);
+				var curFlowElement:FlowElement = getChildAt(curElementIdx);
+				
+				if (curFlowElement.parentRelativeStart != relativePosition)
+				{										
+					if (curFlowElement is FlowGroupElement)
+					{
+						FlowGroupElement(curFlowElement).splitAtPosition(relativePosition - curFlowElement.parentRelativeStart);
+					} 
+					else
+					{
+						//I would imagine that it has to be a span.  That's the only non-FlowGroupElement
+						//type that can take up more than a textLength of 1.
+						CONFIG::debug { assert(curFlowElement is SpanElement, "SpanElements are the only leaf elements that can currently have > 1 textLength");	}			
+						SpanElement(curFlowElement).splitAtPosition(relativePosition - curFlowElement.parentRelativeStart);
+					}
+					//increase by one. It's the new element that we want to move over.
+					curElementIdx++;
+				}
+			}
+			
+			//increase by one. It's the new element that we want to move over.
+			return splitAtIndex(curElementIdx);
+		} 		 
+		
+		/** @private */
+		tlf_internal override function normalizeRange(normalizeStart:uint,normalizeEnd:uint):void
+		{
+			var idx:int = findChildIndexAtPosition(normalizeStart);
+			if (idx != -1 && idx < _numChildren)
+			{
+				// backup over zero length children
+				var child:FlowElement = getChildAt(idx);
+				normalizeStart = normalizeStart-child.parentRelativeStart;
+				
+				CONFIG::debug { assert(normalizeStart >= 0, "bad normalizeStart in normalizeRange"); }
+				for (;;)
+				{
+					// watch out for changes in the length of the child
+					var origChildEnd:int = child.parentRelativeStart+child.textLength;
+					child.normalizeRange(normalizeStart,normalizeEnd-child.parentRelativeStart);
+					var newChildEnd:int = child.parentRelativeStart+child.textLength;
+					normalizeEnd += newChildEnd-origChildEnd;	// adjust
+					
+					// no zero length children
+					if (child.textLength == 0 && !child.bindableElement)
+						replaceChildren(idx,idx+1);
+					else
+						idx++;
+
+					if (idx == _numChildren)
+						break;
+					
+					// next child
+					child = getChildAt(idx);
+					
+					if (child.parentRelativeStart > normalizeEnd)
+						break;
+						
+					normalizeStart = 0;		// for the next child	
+				}
+			}
+
+
+		}
+		
+		/** @private */
+		tlf_internal override function applyWhiteSpaceCollapse():void
+		{
+			for (var idx:int = 0; idx < _numChildren;)
+			{
+				var child:FlowElement = getChildAt(idx);
+				child.applyWhiteSpaceCollapse();
+				if (child.parent == this)	// check to see if child was removed (could have been 
+					++idx;
+			}
+				
+			// If the element was added automatically, it may now have no content and needs to be removed
+			// This can happen with whitespace between paragraphs that is added by set mxmlChildren
+			if (textLength == 0  && impliedElement && parent != null)
+				parent.removeChild(this);
+
+			super.applyWhiteSpaceCollapse();
+		}
+		
+		/** @private */
+		tlf_internal override function appendElementsForDelayedUpdate(tf:TextFlow):void
+		{ 
+			for (var idx:int = 0; idx < _numChildren; idx++)
+			{
+				var child:FlowElement = getChildAt(idx);
+				child.appendElementsForDelayedUpdate(tf);
+			}
+		}
+		
+
+		
+			
+		// **************************************** 
+		// End tree modification support code
+		// ****************************************	
+		// **************************************** 
+		// Begin debug support code
+		// ****************************************	
+		/** @private */
+		CONFIG::debug public override function debugCheckFlowElement(depth:int = 0, extraData:String = ""):int
+		{
+			
+			var rslt:int = super.debugCheckFlowElement(depth,extraData);
+			
+			// debugging function that asserts if the flow element is in an invalid state
+			var totalChildLength:int = 0;
+			if (_numChildren)
+			{
+				for (var childIndex:int = 0; childIndex < _numChildren; ++childIndex)
+				{
+					var child:FlowElement = getChildAt(childIndex);
+					rslt += assert(child.parent == this, "child doesn't point to parent");
+
+					// totalChildLength is relative offset to child
+					rslt += assert(child.parentRelativeStart == totalChildLength, "child start offset wrong");
+					rslt += child.debugCheckFlowElement(depth+1);
+					totalChildLength += child.textLength;				
+				}
+			}
+			else	
+			{
+				// only spans may own text
+				rslt += assert(this is SpanElement || textLength == 0, "only spans may have text");	
+				totalChildLength = textLength;	
+			}
+			assert(totalChildLength == textLength, "child total textLength wrong");
+			return rslt;
+		}		
+		// **************************************** 
+		// End debug support code
+		// ****************************************	
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/FlowLeafElement.as b/textLayout_core/src/flashx/textLayout/elements/FlowLeafElement.as
new file mode 100755
index 0000000..a16e118
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/FlowLeafElement.as
@@ -0,0 +1,992 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements
+{
+	import flash.display.Shape;
+	import flash.events.EventDispatcher;
+	import flash.geom.Rectangle;
+	import flash.text.engine.ContentElement;
+	import flash.text.engine.ElementFormat;
+	import flash.text.engine.FontDescription;
+	import flash.text.engine.FontMetrics;
+	import flash.text.engine.TextBaseline;
+	import flash.text.engine.TextElement;
+	import flash.text.engine.TextLine;
+	import flash.text.engine.TextRotation;
+	import flash.text.engine.TypographicCase;
+	import flash.utils.Dictionary;
+	
+	import flashx.textLayout.compose.FlowComposerBase;
+	import flashx.textLayout.compose.IFlowComposer;
+	import flashx.textLayout.compose.StandardFlowComposer;
+	import flashx.textLayout.compose.TextFlowLine;
+	import flashx.textLayout.debug.Debugging;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.BackgroundColor;
+	import flashx.textLayout.formats.BaselineShift;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.formats.IMEStatus;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TLFTypographicCase;
+	import flashx.textLayout.formats.TextDecoration;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.tlf_internal;
+	import flashx.textLayout.utils.CharacterUtil;
+	import flashx.textLayout.utils.LocaleUtil;
+	
+	use namespace tlf_internal;
+		
+	
+	/** Base class for FlowElements that appear at the lowest level of the flow hierarchy. FlowLeafElement objects have
+	* no children and include InlineGraphicElement objects and SpanElement objects.
+	*
+	* @playerversion Flash 10
+	* @playerversion AIR 1.5
+	* @langversion 3.0
+	*
+	* @see InlineGraphicElement
+	* @see SpanElement
+	*/
+	public class FlowLeafElement extends FlowElement
+	{				
+		/** Holds the content of the leaf @private */
+		protected var _blockElement:ContentElement;
+		
+		/** @private
+		 * Holds the text for the leaf element - unless there's a valid blockElement, 
+		 * in which case the text is in the rawText field of the blockElement.
+		 */
+		protected var _text:String;	// holds the text property if the blockElement is null
+		private var _hasAttachedListeners:Boolean;	// true if FTE eventMirror may be in use
+		
+		/** 
+		 * Base class - invoking new FlowLeafElement() throws an error exception. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * 
+		 */
+		public function FlowLeafElement()
+		{
+			_hasAttachedListeners = false;
+			super();
+		}
+		
+		/** @private */
+		override tlf_internal function createContentElement():void
+		{
+			CONFIG::debug { assert(_blockElement != null, "_blockElement not allocated in derived class"); }
+			if (_computedFormat)
+			{
+				_blockElement.elementFormat = getCanonicalElementFormat();
+				CONFIG::debug { Debugging.traceFTEAssign(_blockElement,"elementFormat",_blockElement.elementFormat); }
+			}
+			if (parent)
+				parent.insertBlockElement(this,_blockElement);
+		}
+		/** @private */
+		override tlf_internal function releaseContentElement():void
+		{
+			if (!canReleaseContentElement() || _blockElement == null)
+				return;
+				
+			_blockElement = null;
+		}
+		/** @private */
+		override tlf_internal function canReleaseContentElement():Boolean
+		{
+			return !_hasAttachedListeners;
+		}
+		
+		private function blockElementExists():Boolean
+		{
+			return _blockElement != null;
+		}
+
+		/** @private */
+		tlf_internal function getBlockElement():ContentElement
+		{ 
+			if (!_blockElement)
+				createContentElement();
+			return _blockElement; 
+		}
+		
+		
+		/**
+		 * The text associated with the FlowLeafElement:
+		 * <p><ul>
+		 * <li>The value for SpanElement subclass will be one character less than <code>textLength</code> if this is the last span in a ParagraphELement.</li>
+		 * <li>The value for BreakElement subclass is a U+2028</li>
+		 * <li>The value for TabElement subclass is a tab</li>
+		 * <li>The value for InlineGraphicElement subclass is U+FDEF</li>
+		 * </ul></p>
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see flashx.textLayout.elements.SpanElement#replaceText()
+		 */
+		public function get text():String
+		{
+			return _blockElement ?  _blockElement.rawText : _text;
+		}
+		
+		/** @private */
+		tlf_internal function getElementFormat():ElementFormat
+		{ 			
+			if (!_blockElement)
+				createContentElement();
+			return _blockElement.elementFormat; 
+ 		}
+		
+		/** @private */
+		tlf_internal override function setParentAndRelativeStart(newParent:FlowGroupElement,newStart:int):void
+		{
+			if (newParent == parent)
+				return;
+		
+			var hasBlock:Boolean = _blockElement != null;
+			
+			if (_blockElement && parent && parent.hasBlockElement())	// remove textElement from the parent content
+				parent.removeBlockElement(this,_blockElement);
+			if (newParent && !newParent.hasBlockElement() && _blockElement)
+				newParent.createContentElement();
+					
+			super.setParentAndRelativeStart(newParent,newStart);
+			
+			// Update the FTE ContentElement structure. If the parent has FTE elements, then create FTE elements for the leaf node 
+			// if it doesn't already have them, and add them in. If the parent does not have FTE elements, release the leaf's FTE
+			// elements also so they match.
+			if (parent)
+			{
+				if (parent.hasBlockElement())
+				{
+					if (!_blockElement)
+						createContentElement();
+					else if (hasBlock)	// don't do this if the _blockElement was constructed as side-effect of setParentAndRelativeStart; in that case, it's already attached
+						parent.insertBlockElement(this,_blockElement);
+				}
+				else if (_blockElement)
+					releaseContentElement();
+			}
+		}
+	
+		/** @private */
+		protected function quickInitializeForSplit(sibling:FlowLeafElement,newSpanLength:int,newSpanTextElement:TextElement):void
+		{
+			setTextLength(newSpanLength);
+			_blockElement = newSpanTextElement;
+			quickCloneTextLayoutFormat(sibling);
+			var tf:TextFlow = sibling.getTextFlow();
+			if (tf == null || tf.formatResolver == null)
+			{
+				_computedFormat = sibling._computedFormat;
+				if (_blockElement)
+					_blockElement.elementFormat = sibling.getElementFormat();
+			}
+		}
+		
+		/** @private */
+		tlf_internal function addParaTerminator():void
+		{
+			// some FlowLeafElement types have RO text and can't have a paragraph terminator
+			CONFIG::debug { assert(false,"TODO: para terminator in non-span leaves"); }
+		}
+		/** @private */
+		tlf_internal function removeParaTerminator():void
+		{
+			// some FlowLeafElement types have RO text and can't have a paragraph terminator
+			CONFIG::debug { assert(false,"TODO: para terminator in non-span leaves"); }
+		}
+		
+		/**
+		 * Returns the next FlowLeafElement object.  
+		 * 
+		 * @param limitElement	Specifies FlowGroupElement on whose last leaf to stop looking. A value of null (default) 
+		 * 	means search till no more elements.
+		 * @return 	next FlowLeafElement or null if at the end
+		 *
+		 * @includeExample examples\FlowLeafElement_getNextLeafExample.as -noswf
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+		 */
+		 
+		 public function getNextLeaf(limitElement:FlowGroupElement=null):FlowLeafElement
+		{
+			if (!parent)
+				return null;
+			return parent.getNextLeafHelper(limitElement,this);
+		}
+		
+		/**
+		 * Returns the previous FlowLeafElement object.  
+		 * 
+		 * @param limitElement	Specifies the FlowGroupElement on whose first leaf to stop looking.   null (default) means search till no more elements.
+		 * @return 	previous leafElement or null if at the end
+		 *
+		 * @includeExample examples\FlowLeafElement_getPreviousLeafExample.as -noswf
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+		 */
+		 
+		public function getPreviousLeaf(limitElement:FlowGroupElement=null):FlowLeafElement
+		{
+			if (!parent)
+				return null;
+			return parent.getPreviousLeafHelper(limitElement,this);
+		}
+		
+		/** @private */
+		public override function getCharAtPosition(relativePosition:int):String
+		{
+			var textValue:String = _blockElement ? _blockElement.rawText : _text;
+			if (textValue)
+				return textValue.charAt(relativePosition);
+			return String("");
+		} 
+		
+		/** @private */
+		tlf_internal override function normalizeRange(normalizeStart:uint,normalizeEnd:uint):void
+		{
+			// this does the cascade - potential optimization to skip it if the _blockElement isn't attached
+			computedFormat;
+		}
+		
+		/** Returns the FontMetrics object for the span. The properties of the FontMetrics object describe the 
+		 * emBox, strikethrough position, strikethrough thickness, underline position, 
+		 * and underline thickness for the specified font. 
+		 *
+ 		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+		 * @see flash.text.engine.FontMetrics
+		 * @see flash.text.engine.ElementFormat#getFontMetrics()
+		 *
+		 * @return font metrics associated with the span
+		 */
+		public function getComputedFontMetrics():FontMetrics
+		{
+			if (!_blockElement)
+				createContentElement();
+			var ef:ElementFormat = _blockElement.elementFormat;
+			if (!ef)
+				return null;
+				
+			var tf:TextFlow = getTextFlow()
+			if (tf && tf.flowComposer && tf.flowComposer.swfContext)
+				return tf.flowComposer.swfContext.callInContext(ef.getFontMetrics,ef,null,true);
+
+			return ef.getFontMetrics();
+		}
+	
+		static private var _elementFormats:Dictionary = new Dictionary(true);
+		
+		/** @private 
+		 */
+		tlf_internal static function clearElementFormatsCache():void
+		{ 
+			for each (var elementFormat:ElementFormat in _elementFormats)
+			{
+				// At least one entry exists. Create a new dictionary and return.
+				// This may be cheaper than deleting all entries one by one.
+				_elementFormats = new Dictionary(true);
+				return;
+			}
+		}
+		
+		/** @private */
+		private function resolveDomBaseline():String
+		{
+			CONFIG::debug { assert(_computedFormat != null,"bad call to resolveDomBaseline"); }
+			
+			var domBase:String = _computedFormat.dominantBaseline;
+			if(domBase == FormatValue.AUTO)
+			{
+				if(this.computedFormat.textRotation == TextRotation.ROTATE_270 /*|| 
+					this.computedFormat.blockProgression == BlockProgression.RL*/)
+					domBase = TextBaseline.IDEOGRAPHIC_CENTER;
+				else
+				{
+					var para:ParagraphElement = getParagraph();
+					//otherwise, avoid using the locale of the element and use the paragraph's locale
+					if(para != null)
+						domBase = para.getEffectiveDominantBaseline();
+					else
+						domBase = LocaleUtil.dominantBaseline(_computedFormat.locale);
+				}
+			}
+			
+			return domBase;
+		}
+		
+		/** @private */
+		private function getCanonicalElementFormat():ElementFormat
+		{
+			CONFIG::debug { assert(_computedFormat != null,"bad call to getCanonicalElementFormat"); }
+			
+			var domBase:String = resolveDomBaseline();
+			
+			// the fontLookup may be override by the resolveFontLookupFunction
+			var fontLookup:String;
+			if (GlobalSettings.resolveFontLookupFunction == null)
+				fontLookup = _computedFormat.fontLookup
+			else
+			{
+				var flowComposer:IFlowComposer = getTextFlow().flowComposer;
+				fontLookup = GlobalSettings.resolveFontLookupFunction(flowComposer ? FlowComposerBase.computeBaseSWFContext(flowComposer.swfContext) : null,_computedFormat);
+			}
+			
+			var format:ElementFormat = _elementFormats[_computedFormat] as ElementFormat;
+			if (!format || format.dominantBaseline != domBase || format.fontDescription.fontLookup != fontLookup)
+			{
+				// compute the cascaded elementFormat
+				format = new ElementFormat();
+				CONFIG::debug { Debugging.traceFTECall(format,null,"new ElementFormat()"); }
+				
+				format.alignmentBaseline	= _computedFormat.alignmentBaseline;
+				format.alpha				= Number(_computedFormat.textAlpha);
+				format.breakOpportunity		= _computedFormat.breakOpportunity;
+				format.color				= uint(_computedFormat.color);
+				format.dominantBaseline		= domBase;
+				
+				format.digitCase			= _computedFormat.digitCase;
+				format.digitWidth			= _computedFormat.digitWidth;
+				format.ligatureLevel		= _computedFormat.ligatureLevel;
+				format.fontSize				= Number(_computedFormat.fontSize);
+				format.kerning				= _computedFormat.kerning;
+				format.locale				= _computedFormat.locale;
+				format.trackingLeft			= TextLayoutFormat.trackingLeftProperty.computeActualPropertyValue(_computedFormat.trackingLeft,format.fontSize);
+				format.trackingRight		= TextLayoutFormat.trackingRightProperty.computeActualPropertyValue(_computedFormat.trackingRight,format.fontSize);
+				format.textRotation			= _computedFormat.textRotation;
+				format.baselineShift 		= -(TextLayoutFormat.baselineShiftProperty.computeActualPropertyValue(_computedFormat.baselineShift, format.fontSize));
+				switch (_computedFormat.typographicCase)
+				{
+					case TLFTypographicCase.LOWERCASE_TO_SMALL_CAPS:
+						format.typographicCase = TypographicCase.CAPS_AND_SMALL_CAPS;
+						break;
+					case TLFTypographicCase.CAPS_TO_SMALL_CAPS:
+						format.typographicCase = TypographicCase.SMALL_CAPS;
+						break;
+					/* These map directly so we handle it in the default case
+					case TLFTypographicCase.LOWERCASE:
+						format.typographicCase = TypographicCase.LOWERCASE;
+						break;
+					case TLFTypographicCase.DEFAULT:
+						format.typographicCase = TypographicCase.DEFAULT;
+						break;
+					case TLFTypographicCase.UPPERCASE:
+						format.typographicCase = TypographicCase.UPPERCASE;
+						break;
+					*/
+					default:
+						format.typographicCase = _computedFormat.typographicCase;
+						break;
+				}
+				
+				CONFIG::debug { Debugging.traceFTEAssign(format,"alignmentBaseline",format.alignmentBaseline); }
+				CONFIG::debug { Debugging.traceFTEAssign(format,"alpha",format.alpha); }
+				CONFIG::debug { Debugging.traceFTEAssign(format,"breakOpportunity",format.breakOpportunity); }
+				CONFIG::debug { Debugging.traceFTEAssign(format,"color",format.color); }
+				CONFIG::debug { Debugging.traceFTEAssign(format,"dominantBaseline",format.dominantBaseline); }
+				CONFIG::debug { Debugging.traceFTEAssign(format,"digitCase",format.digitCase); }
+				CONFIG::debug { Debugging.traceFTEAssign(format,"digitWidth",format.digitWidth); }
+				CONFIG::debug { Debugging.traceFTEAssign(format,"ligatureLevel",format.ligatureLevel); }
+				CONFIG::debug { Debugging.traceFTEAssign(format,"fontSize",format.fontSize); }
+				CONFIG::debug { Debugging.traceFTEAssign(format,"kerning",format.kerning); }
+				CONFIG::debug { Debugging.traceFTEAssign(format,"locale",format.locale); }
+				CONFIG::debug { Debugging.traceFTEAssign(format,"trackingLeft",format.trackingLeft); }
+				CONFIG::debug { Debugging.traceFTEAssign(format,"trackingRight",format.trackingRight); }
+				CONFIG::debug { Debugging.traceFTEAssign(format,"typographicCase",format.typographicCase); }
+				CONFIG::debug { Debugging.traceFTEAssign(format,"textRotation",format.textRotation); }
+				CONFIG::debug { Debugging.traceFTEAssign(format,"baselineShift",format.baselineShift);	 }	
+								
+				// set the fontDesription in the cascadedFormat
+				var fd:FontDescription = new FontDescription();
+				fd.fontWeight = _computedFormat.fontWeight;
+				fd.fontPosture = _computedFormat.fontStyle;
+				fd.fontName = _computedFormat.fontFamily;
+				fd.renderingMode = _computedFormat.renderingMode;
+				fd.cffHinting = _computedFormat.cffHinting;
+				fd.fontLookup = fontLookup;
+				var fontMapper:Function = GlobalSettings.fontMapperFunction;
+				if (fontMapper != null)
+					fontMapper(fd);
+				CONFIG::debug { Debugging.traceFTECall(fd,null,"new FontDescription()"); }
+				CONFIG::debug { Debugging.traceFTEAssign(fd,"fontWeight",fd.fontWeight);	 }
+				CONFIG::debug { Debugging.traceFTEAssign(fd,"fontPosture",fd.fontPosture);	 }
+				CONFIG::debug { Debugging.traceFTEAssign(fd,"fontName",fd.fontName);	 }
+				CONFIG::debug { Debugging.traceFTEAssign(fd,"renderingMode",fd.renderingMode);	 }
+				CONFIG::debug { Debugging.traceFTEAssign(fd,"cffHinting",fd.cffHinting);	 }
+				CONFIG::debug { Debugging.traceFTEAssign(fd,"fontLookup",fd.fontLookup);	 }
+				
+				format.fontDescription = fd;
+				CONFIG::debug { Debugging.traceFTEAssign(format,"fontDescription",fd); }
+				
+				//Moved code here because original code tried to access fontMetrics prior to setting the elementFormat.
+				//Since getFontMetrics returns the value of blockElement.elementFormat.getFontMetrics(), we cannot call this
+				//until after the element has been set. Watson 1820571 - gak 06.11.08
+				// Adjust format for superscript/subscript
+				if (_computedFormat.baselineShift == BaselineShift.SUPERSCRIPT || 
+					_computedFormat.baselineShift == BaselineShift.SUBSCRIPT)
+				{
+					var fontMetrics:FontMetrics;
+					var tf:TextFlow = getTextFlow();
+					if (tf.flowComposer && tf.flowComposer.swfContext)
+						fontMetrics = tf.flowComposer.swfContext.callInContext(format.getFontMetrics,format,null,true);
+					else	
+						fontMetrics = format.getFontMetrics();	
+					if (_computedFormat.baselineShift == BaselineShift.SUPERSCRIPT)
+					{
+						format.baselineShift = (fontMetrics.superscriptOffset * format.fontSize);
+						format.fontSize = fontMetrics.superscriptScale * format.fontSize;
+					}
+					else // it's subscript
+					{
+						format.baselineShift = (fontMetrics.subscriptOffset * format.fontSize);
+						format.fontSize = fontMetrics.subscriptScale * format.fontSize;
+					}
+					CONFIG::debug { Debugging.traceFTEAssign(format,"baselineShift",format.baselineShift); }
+					CONFIG::debug { Debugging.traceFTEAssign(format,"fontSize",format.fontSize); }
+				}
+				
+				_elementFormats[_computedFormat] = format;
+			}
+			
+			return format;
+		}
+
+		/** 
+		 * The computed text format attributes that are in effect for this element.
+		 * Takes into account the inheritance of attributes.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+		 * @see flashx.textLayout.formats.ITextLayoutFormat
+		 */
+		public override function get computedFormat():ITextLayoutFormat
+		{		
+			if (!_computedFormat)
+			{
+				doComputeTextLayoutFormat(formatForCascade);
+
+				if (_blockElement)
+				{
+					_blockElement.elementFormat = getCanonicalElementFormat();
+					CONFIG::debug { Debugging.traceFTEAssign(_blockElement,"elementFormat",_blockElement.elementFormat); }
+				}
+
+			}
+			return _computedFormat;
+		}
+		
+		/** Returns the fontSize from this element's properties.  @private */
+		tlf_internal function getEffectiveFontSize():Number
+		{
+			return Number(computedFormat.fontSize);
+		}
+		/** @private */
+		tlf_internal function getSpanBoundsOnLine(textLine:TextLine, blockProgression:String):Array
+		{
+			var line:TextFlowLine = TextFlowLine(textLine.userData);
+			var paraStart:int = line.paragraph.getAbsoluteStart();
+			var lineEnd:int = (line.absoluteStart + line.textLength) - paraStart;
+			var spanStart:int = getAbsoluteStart() - paraStart;		// get start pos relative to the paragraph (which might not be the parent)
+			var endPos:int = spanStart + text.length;		// so we don't include the paragraph terminator character, if present
+		
+			// Clip to start of line	
+			var startPos:int = Math.max(spanStart, line.absoluteStart - paraStart);
+			
+			// Clip to end of line	
+			// Heuristic for detecting spaces at the end of the line and eliminating them from the range so they won't be underlined.
+			if (endPos >= lineEnd)
+			{
+				endPos = lineEnd;
+				var spanText:String = text;
+				while (endPos > startPos && CharacterUtil.isWhitespace(spanText.charCodeAt(endPos - spanStart - 1)))
+					--endPos;
+			}
+
+			var mainRects:Array = [];
+			line.calculateSelectionBounds(textLine, mainRects, startPos, endPos, blockProgression, [ line.textHeight,0]);
+			return mainRects;
+		}
+		
+		/** @private */
+		tlf_internal function updateIMEAdornments(line:TextFlowLine, blockProgression:String, imeStatus:String):void
+		{
+			var tLine:TextLine = line.getTextLine();
+			var metrics:FontMetrics = getComputedFontMetrics();
+			var spanBoundsArray:Array = getSpanBoundsOnLine(tLine, blockProgression);
+			//this is pretty much always going to have a length of 1, but just to be sure...
+			for (var i:int = 0; i < spanBoundsArray.length; i++)
+			{
+				//setup ime variables
+				var imeLineThickness:int = 1;
+				var imeLineColor:uint = 0x000000;
+				var imeLineStartX:Number = 0;
+				var imeLineStartY:Number = 0;
+				var imeLineEndX:Number = 0;
+				var imeLineEndY:Number = 0;
+				
+				//selected text draws with 2 px
+				if(imeStatus == IMEStatus.SELECTED_CONVERTED || imeStatus == IMEStatus.SELECTED_RAW)
+				{
+					imeLineThickness = 2;
+				}
+				//Raw or deadkey text draws with grey
+				if(imeStatus == IMEStatus.SELECTED_RAW || imeStatus == IMEStatus.NOT_SELECTED_RAW
+					|| imeStatus == IMEStatus.DEAD_KEY_INPUT_STATE)
+				{
+					imeLineColor = 0xA6A6A6;
+				}
+				
+				var spanBounds:Rectangle = spanBoundsArray[i] as Rectangle;
+				var stOffset:Number = calculateStrikeThrough(tLine, blockProgression, metrics);
+				var ulOffset:Number = calculateUnderlineOffset(stOffset, blockProgression, metrics, tLine);
+				
+				if (blockProgression != BlockProgression.RL)
+				{
+					imeLineStartX = spanBounds.topLeft.x + 1;
+					imeLineEndX = spanBounds.topLeft.x + spanBounds.width - 1;
+					imeLineStartY = ulOffset;
+					imeLineEndY = ulOffset;
+				}
+				else
+				{
+					//is this TCY?
+					var elemIdx:int = this.getAbsoluteStart() - line.absoluteStart;
+					imeLineStartY = spanBounds.topLeft.y + 1;
+					imeLineEndY = spanBounds.topLeft.y + spanBounds.height - 1;
+					
+					//elemIdx can sometimes be negative if the text is being wrapped due to a
+					//resize gesture - in which case the tLine has not necessarily been updated.
+					//If the elemIdx is invalid, just treat it like it's normal ttb text - gak 07.08.08
+					if(elemIdx < 0 || tLine.atomCount <= elemIdx || tLine.getAtomTextRotation(elemIdx) != TextRotation.ROTATE_0)
+					{
+						imeLineStartX = ulOffset;
+						imeLineEndX = ulOffset;
+					}
+					else
+					{
+						//it is TCY!
+						var tcyParent:TCYElement =  this.getParentByType(TCYElement) as TCYElement;
+						CONFIG::debug{ assert(tcyParent != null, "What kind of object is this that is ROTATE_0, but not TCY?");}
+						
+						//only perform calculations for TCY adornments when we are on the last leaf.  ONLY the last leaf matters
+						if((this.getAbsoluteStart() + this.textLength) == (tcyParent.getAbsoluteStart() + tcyParent.textLength))
+						{
+							var tcyAdornBounds:Rectangle = new Rectangle();
+							tcyParent.calculateAdornmentBounds(tcyParent, tLine, blockProgression, tcyAdornBounds);
+							var baseULAdjustment:Number = metrics.underlineOffset + (metrics.underlineThickness/2);
+							
+							imeLineStartY = tcyAdornBounds.top + 1;
+							imeLineEndY = tcyAdornBounds.bottom - 1;
+							imeLineStartX = spanBounds.bottomRight.x + baseULAdjustment;
+							imeLineEndX = spanBounds.bottomRight.x + baseULAdjustment;
+						}
+					}
+				}
+				
+				//Build the shape
+				var selObj:Shape = new Shape();
+				//TODO - this is probably going to need to be overridable in the full implementation
+				selObj.alpha = 1;       				
+				selObj.graphics.beginFill(imeLineColor);
+				
+				selObj.graphics.lineStyle(imeLineThickness, imeLineColor, selObj.alpha);
+				selObj.graphics.moveTo(imeLineStartX, imeLineStartY);
+				selObj.graphics.lineTo(imeLineEndX, imeLineEndY);
+				
+				selObj.graphics.endFill();
+				tLine.addChild(selObj);
+			}
+		}
+		
+		
+		/** @private return number of shapes added */
+		tlf_internal function updateAdornments(line:TextFlowLine, blockProgression:String):int
+		{
+			CONFIG::debug { assert(_computedFormat != null,"invalid call to updateAdornments"); }
+
+			// Only work on lines with strikethrough or underline
+			if (_computedFormat.textDecoration == TextDecoration.UNDERLINE || _computedFormat.lineThrough || _computedFormat.backgroundAlpha > 0 && _computedFormat.backgroundColor != BackgroundColor.TRANSPARENT)
+			{
+				var tLine:TextLine = line.getTextLine(true);
+				var spanBoundsArray:Array = getSpanBoundsOnLine(tLine, blockProgression);
+				for (var i:int = 0; i < spanBoundsArray.length; i++)
+					updateAdornmentsOnBounds(line, tLine, blockProgression, spanBoundsArray[i]);
+				return spanBoundsArray.length ;
+			}
+			return 0;
+		}
+		 
+		private function updateAdornmentsOnBounds(line:TextFlowLine, tLine:TextLine, blockProgression:String, spanBounds:Rectangle):void
+		{
+			CONFIG::debug { assert(_computedFormat != null,"invalid call to updateAdornmentsOnBounds"); }
+
+   			var selObj:Shape = new Shape();
+			var metrics:FontMetrics = getComputedFontMetrics();
+		
+			selObj.alpha = Number(_computedFormat.textAlpha);       				
+						
+			selObj.graphics.beginFill(uint(_computedFormat.color));
+			var stOffset:Number = calculateStrikeThrough(tLine, blockProgression, metrics);
+			var ulOffset:Number = calculateUnderlineOffset(stOffset, blockProgression, metrics, tLine);
+						
+			if (blockProgression != BlockProgression.RL)
+			{
+				if (_computedFormat.textDecoration == TextDecoration.UNDERLINE)
+				{
+					selObj.graphics.lineStyle(metrics.underlineThickness, _computedFormat.color as uint, selObj.alpha);
+					selObj.graphics.moveTo(spanBounds.topLeft.x, ulOffset);
+					selObj.graphics.lineTo(spanBounds.topLeft.x + spanBounds.width, ulOffset);
+				}
+				
+				if((_computedFormat.lineThrough))
+				{
+					selObj.graphics.lineStyle(metrics.strikethroughThickness, _computedFormat.color as uint, selObj.alpha);
+					selObj.graphics.moveTo(spanBounds.topLeft.x, stOffset);
+					selObj.graphics.lineTo(spanBounds.topLeft.x + spanBounds.width, stOffset);
+				}
+				
+				addBackgroundRect (line, tLine, metrics, spanBounds, true); 
+			}
+			else
+			{
+				//is this TCY?
+				var elemIdx:int = this.getAbsoluteStart() - line.absoluteStart;
+				
+				//elemIdx can sometimes be negative if the text is being wrapped due to a
+				//resize gesture - in which case the tLine has not necessarily been updated.
+				//If the elemIdx is invalid, just treat it like it's normal ttb text - gak 07.08.08
+				if(elemIdx < 0 || tLine.atomCount <= elemIdx || tLine.getAtomTextRotation(elemIdx) != TextRotation.ROTATE_0)
+				{
+					if (_computedFormat.textDecoration == TextDecoration.UNDERLINE)
+					{
+						selObj.graphics.lineStyle(metrics.underlineThickness, _computedFormat.color as uint, selObj.alpha);
+						selObj.graphics.moveTo(ulOffset, spanBounds.topLeft.y);
+						selObj.graphics.lineTo(ulOffset, spanBounds.topLeft.y + spanBounds.height);
+					}
+					
+					if (_computedFormat.lineThrough == true)
+					{
+						selObj.graphics.lineStyle(metrics.strikethroughThickness, _computedFormat.color as uint, selObj.alpha);
+						selObj.graphics.moveTo(-stOffset, spanBounds.topLeft.y);
+						selObj.graphics.lineTo(-stOffset, spanBounds.topLeft.y + spanBounds.height);															
+					}
+					
+					addBackgroundRect (line, tLine, metrics, spanBounds, false);
+				}
+				else
+				{
+					//it is TCY!
+					var tcyParent:TCYElement =  this.getParentByType(TCYElement) as TCYElement;
+					CONFIG::debug{ assert(tcyParent != null, "What kind of object is this that is ROTATE_0, but not TCY?");}
+					
+					//if the locale of the paragraph is Chinese, we need to adorn along the left and not right side.
+					var tcyPara:ParagraphElement = this.getParentByType(ParagraphElement) as ParagraphElement;
+					var lowerLocale:String = tcyPara.computedFormat.locale.toLowerCase();
+					var adornRight:Boolean = (lowerLocale.indexOf("zh") != 0);
+					
+					addBackgroundRect (line, tLine, metrics, spanBounds, true, true); 
+					
+					//only perform calculations for TCY adornments when we are on the last leaf.  ONLY the last leaf matters
+					if((this.getAbsoluteStart() + this.textLength) == (tcyParent.getAbsoluteStart() + tcyParent.textLength))
+					{
+						var tcyAdornBounds:Rectangle = new Rectangle();
+						tcyParent.calculateAdornmentBounds(tcyParent, tLine, blockProgression, tcyAdornBounds);
+						
+						if (_computedFormat.textDecoration == TextDecoration.UNDERLINE)
+						{
+							selObj.graphics.lineStyle(metrics.underlineThickness, _computedFormat.color as uint, selObj.alpha);
+							var baseULAdjustment:Number = metrics.underlineOffset + (metrics.underlineThickness/2);
+							var xCoor:Number = adornRight ? spanBounds.right : spanBounds.left;
+							if(!adornRight)
+								baseULAdjustment = -baseULAdjustment;
+							
+							selObj.graphics.moveTo(xCoor + baseULAdjustment, tcyAdornBounds.top);
+							selObj.graphics.lineTo(xCoor + baseULAdjustment, tcyAdornBounds.bottom);
+						}
+
+						if (_computedFormat.lineThrough == true)
+						{
+							var tcyMid:Number = spanBounds.bottomRight.x - tcyAdornBounds.x;
+							tcyMid /= 2;
+							tcyMid += tcyAdornBounds.x;
+							
+							selObj.graphics.lineStyle(metrics.strikethroughThickness, _computedFormat.color as uint, selObj.alpha);
+							selObj.graphics.moveTo(tcyMid, tcyAdornBounds.top);
+							selObj.graphics.lineTo(tcyMid, tcyAdornBounds.bottom);
+						}
+						
+					}
+				}
+			}
+			
+			selObj.graphics.endFill();
+			tLine.addChild(selObj);
+		}
+		
+		/** @private
+		 * Adds the background rectangle (if needed), making adjustments for glyph shifting as appropriate
+		 */
+		 private function addBackgroundRect(line:TextFlowLine, tLine:TextLine, metrics:FontMetrics, spanBounds:Rectangle, horizontalText:Boolean, isTCY:Boolean=false):void
+		 {
+			if(_computedFormat.backgroundAlpha == 0 || _computedFormat.backgroundColor == BackgroundColor.TRANSPARENT)
+				return;
+				
+			var tf:TextFlow = this.getTextFlow();
+			// ensure the TextFlow has a background manager - but its only supported with the StandardFlowComposer at this time
+			if(!tf.backgroundManager && (tf.flowComposer is StandardFlowComposer))
+				tf.backgroundManager = StandardFlowComposer(tf.flowComposer).createBackgroundManager();
+			
+			if (!tf.backgroundManager)
+				return;
+					
+			// The background rectangle usually needs to coincide with the passsed-in span bounds.
+			var r:Rectangle = spanBounds.clone();
+			
+			// With constrained glyph shifting (such as when superscript/subscript are in use), we'd like the
+			// background rectangle to follow the glyphs. Not so for arbitrary glyph shifting (such as when 
+			// baseline shift or baseline alignment are in use)	 	
+			// TODO-06/12/2009: Need to figure out adjustment for TCY background rect. No adjustment for now.
+			if (!isTCY && (_computedFormat.baselineShift == BaselineShift.SUPERSCRIPT || _computedFormat.baselineShift == BaselineShift.SUBSCRIPT))
+			{	
+				// The atom bounds returned by FTE do not reflect the effect of glyph shifting.
+				// We approximate this effect by making the following assumptions (strikethrough/underline code does the same)
+				// - The strike-through adornment runs through the center of the glyph
+				// - The Roman baseline is halfway between the center and bottom (descent)
+				// Effectively, the glyph's descent equals the strike-through offset, and its ascent is three times that
+				
+				var desiredExtent:Number; // The desired extent of the rectangle in the block progression direction
+				var baselineShift:Number; 
+				var fontSize:Number = getEffectiveFontSize();
+				var baseStrikethroughOffset:Number = metrics.strikethroughOffset + metrics.strikethroughThickness/2;
+				
+				if (_computedFormat.baselineShift == BaselineShift.SUPERSCRIPT)
+				{
+					// The rectangle needs to sit on the line's descent and must extend far enough to accommodate the
+					// ascender of the glyph (that has moved up because of superscript)
+					
+					var glyphAscent:Number = -3 * baseStrikethroughOffset; // see assumptions above
+					baselineShift = -metrics.superscriptOffset * fontSize;
+					var lineDescent:Number = tLine.getBaselinePosition(TextBaseline.DESCENT) - tLine.getBaselinePosition(TextBaseline.ROMAN);
+					
+					desiredExtent = glyphAscent  + baselineShift + lineDescent;
+					if (horizontalText)
+					{
+						if (desiredExtent > r.height)
+						{
+							r.y -= desiredExtent - r.height;
+							r.height = desiredExtent;
+						}
+					}
+					else
+					{
+						if (desiredExtent > r.width)
+							r.width = desiredExtent;
+					}
+				}
+				else
+				{
+					// The rectangle needs to hang from the line's ascent and must extend far enough to accommodate the
+					// descender of the glyph (that has moved down because of superscript)
+					
+					var glyphDescent:Number = -baseStrikethroughOffset; // see assumptions above
+					baselineShift = metrics.subscriptOffset * fontSize; 
+					var lineAscent:Number = tLine.getBaselinePosition(TextBaseline.ROMAN) - tLine.getBaselinePosition(TextBaseline.ASCENT);
+					
+					desiredExtent = lineAscent + baselineShift + glyphDescent;
+					if (horizontalText)
+					{
+						if (desiredExtent > r.height)
+							r.height = desiredExtent;
+					}
+					else
+					{
+						if (desiredExtent > r.width)
+						{
+							r.x -= desiredExtent - r.width
+							r.width = desiredExtent;
+						}
+					}
+				}
+			}
+			
+			tf.backgroundManager.addRect(line, this, r, _computedFormat.backgroundColor, _computedFormat.backgroundAlpha);	 
+		 }
+		 
+		
+		/** @private
+		 * Gets the EventDispatcher associated with this FlowLeafElement.  Use the functions
+		 * of EventDispatcher such as <code>setEventHandler()</code> and <code>removeEventHandler()</code> 
+		 * to capture events that happen over this FlowLeafElement object.  The
+		 * event handler that you specify will be called after this FlowLeafElement object does
+		 * the processing it needs to do.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+		 * @see flash.events.EventDispatcher
+		 */
+		tlf_internal function getEventMirror():EventDispatcher
+		{
+			if (!_blockElement)
+			{
+				var para:ParagraphElement = getParagraph();
+				if (para)
+					para.getTextBlock();
+				else
+					createContentElement();
+			}
+			if (_blockElement.eventMirror == null)
+			{				
+				_blockElement.eventMirror = new EventDispatcher();
+			}
+			_hasAttachedListeners = true;
+			return (_blockElement.eventMirror);
+		}
+		
+		
+		/** @private */
+		tlf_internal function calculateStrikeThrough(textLine:TextLine, blockProgression:String, metrics:FontMetrics):Number
+		{
+			var underlineAndStrikeThroughShift:int = 0;	
+			var effectiveFontSize:Number = this.getEffectiveFontSize()
+			if (_computedFormat.baselineShift == BaselineShift.SUPERSCRIPT)
+			{
+				underlineAndStrikeThroughShift = -(metrics.superscriptOffset * effectiveFontSize);
+			} else if (_computedFormat.baselineShift == BaselineShift.SUBSCRIPT)
+			{
+				underlineAndStrikeThroughShift = -(metrics.subscriptOffset * (effectiveFontSize / metrics.subscriptScale));
+			} else {
+				underlineAndStrikeThroughShift = TextLayoutFormat.baselineShiftProperty.computeActualPropertyValue(_computedFormat.baselineShift, effectiveFontSize);
+			}
+			
+			//grab the dominantBaseline and alignmentBaseline strings
+			var domBaselineString:String = resolveDomBaseline();
+			var alignmentBaselineString:String = this.computedFormat.alignmentBaseline;
+			
+			//this value represents the position of the baseline used to align this text
+			var alignDomBaselineAdjustment:Number = textLine.getBaselinePosition(domBaselineString);
+			
+			//if the alignment baseline differs from the dominant, then we need to apply the delta between the
+			//dominant and the alignment to determine the line along which the glyphs are lining up...
+			if(alignmentBaselineString != flash.text.engine.TextBaseline.USE_DOMINANT_BASELINE && 
+				alignmentBaselineString != domBaselineString)
+			{
+				alignDomBaselineAdjustment = textLine.getBaselinePosition(alignmentBaselineString);
+				//take the alignmentBaseline offset and make it relative to the dominantBaseline
+			}
+			
+			
+			//first, establish the offset relative to the glyph based in fontMetrics data
+			var stOffset:Number = metrics.strikethroughOffset;
+			
+			
+			//why are we using the stOffset?  Well, the stOffset effectively tells us where the mid-point
+			//of the glyph is.  By using this value, we can determine how we need to offset the underline.
+			//now adjust the value.  If it is center, then the glyphs are aligned along the ST position already
+			if(domBaselineString == flash.text.engine.TextBaseline.IDEOGRAPHIC_CENTER)
+			{
+				stOffset = 0;
+			}
+			else if(domBaselineString == flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP || 
+				domBaselineString == flash.text.engine.TextBaseline.ASCENT)
+			{
+				stOffset *= -2;  //if the glyphs are top or ascent, then we need to invert and double the offset
+				stOffset -= (2 * metrics.strikethroughThickness);
+			}
+			else if(domBaselineString == flash.text.engine.TextBaseline.IDEOGRAPHIC_BOTTOM || 
+				domBaselineString == flash.text.engine.TextBaseline.DESCENT)
+			{
+				stOffset *= 2; //if they're bottom, then we need to simply double it
+				stOffset += (2 * metrics.strikethroughThickness);
+			}
+			else //Roman
+			{
+				stOffset -= metrics.strikethroughThickness;
+			}
+			
+			
+			//Now apply the actual dominant baseline position to the offset
+			stOffset += (alignDomBaselineAdjustment - underlineAndStrikeThroughShift);
+			return stOffset;
+		}
+		
+		/** @private */
+		tlf_internal function calculateUnderlineOffset(stOffset:Number, blockProgression:String, metrics:FontMetrics, textLine:TextLine):Number
+		{
+			var ulOffset:Number = metrics.underlineOffset + metrics.underlineThickness;
+			var baseSTAdjustment:Number = metrics.strikethroughOffset;
+			
+			//based on the stOffset - which really represents the middle of the glyph, set the ulOffset
+			//which will always be relative.  Note that simply using the alignDomBaselineAdjustment is not enough
+			if(blockProgression != BlockProgression.RL)
+				ulOffset += (stOffset - baseSTAdjustment) + metrics.underlineThickness/2;
+			else
+			{	
+				var para:FlowElement = this.parent;
+				while(!(para is ParagraphElement))
+				{
+					para = para.parent;
+				}
+				var lowerLocale:String = para.computedFormat.locale.toLowerCase();
+				if(lowerLocale.indexOf("zh") == 0)
+				{
+					ulOffset = -ulOffset;
+					ulOffset -= (stOffset - baseSTAdjustment + (metrics.underlineThickness*2));
+				}
+				else
+					ulOffset -= (-ulOffset + stOffset + baseSTAdjustment + (metrics.underlineThickness/2));
+			}
+			
+			return ulOffset;
+		}
+		
+		/** @private */
+		CONFIG::debug public override function debugCheckFlowElement(depth:int = 0, extraData:String = ""):int
+		{
+			// debugging function that asserts if the flow element tree is in an invalid state
+			
+			var rslt:int = super.debugCheckFlowElement(depth," fte:"+getDebugIdentity(_blockElement)+" "+extraData);
+			
+			// TODO: eventually these tests will be valid for InlineGraphicElement elements as well
+			if (!(this is InlineGraphicElement))
+			{
+				rslt += assert(textLength != 0 || bindableElement || (parent is SubParagraphGroupElement && parent.numChildren == 1), "FlowLeafElement with zero textLength must be deleted"); 
+				rslt += assert(parent is ParagraphElement || parent is SubParagraphGroupElement, "FlowLeafElement must have a ParagraphElement or SubParagraphGroupElement parent");
+			}
+			return rslt;
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/FlowValueHolder.as b/textLayout_core/src/flashx/textLayout/elements/FlowValueHolder.as
new file mode 100755
index 0000000..b215383
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/FlowValueHolder.as
@@ -0,0 +1,104 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormatValueHolder;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+
+	[ExcludeClass]
+	/** This class extends TextLayoutFormatValueHolder and add capabilities to hold privateData and userStyles.  @private */
+	public class FlowValueHolder extends TextLayoutFormatValueHolder
+	{
+		private var _userStyles:Object;
+		private var _privateData:Object;
+		
+		public function FlowValueHolder(initialValues:FlowValueHolder = null)
+		{
+			super(initialValues);
+			initialize(initialValues);
+		}
+		
+		private function initialize(initialValues:FlowValueHolder):void
+		{
+			if (initialValues)
+			{
+				for (var s:String in initialValues.userStyles)
+					writableUserStyles()[s] = initialValues.userStyles[s];
+				for (s in initialValues.privateData)
+					writablePrivateData()[s] = initialValues.privateData[s];
+			}
+		}
+
+		private function writableUserStyles():Object
+		{ 
+			if (_userStyles == null)
+				_userStyles = new Object();
+			return _userStyles;
+		}
+			
+		public function get userStyles():Object
+		{ return _userStyles; }
+		public function set userStyles(val:Object):void
+		{ _userStyles = val; }
+
+		public function getUserStyle(styleProp:String):*
+		{ return _userStyles ? _userStyles[styleProp] : undefined; }
+		public function setUserStyle(styleProp:String,newValue:*):void
+		{
+			CONFIG::debug { assert(TextLayoutFormat.description[styleProp] === undefined,"bad call to setUserStyle"); }
+			if (newValue === undefined)
+			{
+				if (_userStyles)
+					delete _userStyles[styleProp];
+			}
+			else
+				writableUserStyles()[styleProp] = newValue;
+		}
+
+		private function writablePrivateData():Object
+		{
+			if (_privateData == null)
+				_privateData = new Object();
+			return _privateData;
+		}
+
+		public function get privateData():Object
+		{ return _privateData; }
+		public function set privateData(val:Object):void
+		{ _privateData = val; }
+
+		public function getPrivateData(styleProp:String):*
+		{ return _privateData ? _privateData[styleProp] : undefined; }
+
+		public function setPrivateData(styleProp:String,newValue:*):void
+		{
+			if (newValue === undefined)
+			{
+				if (_privateData)
+					delete _privateData[styleProp];
+			}
+			else
+				writablePrivateData()[styleProp] = newValue;
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/GlobalSettings.as b/textLayout_core/src/flashx/textLayout/elements/GlobalSettings.as
new file mode 100755
index 0000000..93e4575
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/GlobalSettings.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 flashx.textLayout.elements
+{
+	import flashx.textLayout.tlf_internal;
+	use namespace tlf_internal;
+	
+	/** Configuration that applies to all TextFlow objects.
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 */
+	public class GlobalSettings 
+	{
+		/** 
+		* Specifies the callback used for font mapping.
+		* The callback takes a <code>flash.text.engine.FontDescription</code> object and updates it as needed.
+		* 
+		* After setting a new font mapping callback, or changing the behavior of the exisiting font mapping callback, 
+		* the client must explicitly call <code>flashx.textLayout.elements.TextFlow.invalidateAllFormats</code> for each impacted text flow.
+		* This ensures that whenever a leaf element in the text flow is next recomposed, the FontDescription applied to it is recalculated, and the the callback is invoked. 
+		* 
+		* @see flash.text.engine.FontDescription FontDescription
+		* @see TextFlow.invalidateAllFormats invalidateAllFormats
+		* 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*/
+		public static function get fontMapperFunction():Function
+		{ 
+			return _fontMapperFunction; 
+		}
+		public static function set fontMapperFunction(val:Function):void
+		{
+			_fontMapperFunction = val;
+			FlowLeafElement.clearElementFormatsCache(); // clear out possibly stale mappings between computed TextLayoutFormats and ElementFormats
+		}
+		
+		private static var _fontMapperFunction:Function
+		
+		/** Controls whether the text will be visible to a search engine indexer. Defaults to <code>true</code>.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public static function get enableSearch():Boolean
+		{
+			return _enableSearch;
+		}
+		public static function set enableSearch(value:Boolean):void
+		{
+			_enableSearch = value;
+		}
+		
+		private static var _enableSearch:Boolean = true;
+	
+		/** 
+		 * Specifies the callback used for changing the FontLookup based on swfcontext.  The function will be called each time an ElementFormat is computed.
+		 * It gives the client the opportunity to modify the FontLookup setting.  The function is called with two parameters an ISWFContext and an ITextLayoutFormat.
+		 * It must return a valid FontLookup.
+		 * 
+		 * @see flashx.textLayout.compose.ISWFContext
+		 * @see flashx.textLayout.formats.ITextLayoutFormat
+		 * @see flash.text.engine.ElementFormat
+		 * @see flash.text.engine.FontLookup
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public static function get resolveFontLookupFunction():Function
+		{ 
+			return _resolveFontLookupFunction; 
+		}
+		public static function set resolveFontLookupFunction(val:Function):void
+		{
+			_resolveFontLookupFunction = val;
+		}
+		private static var _resolveFontLookupFunction:Function
+		
+		/** Function that takes two parameters, a resource id and an optional array of parameters to substitute into the string.
+		 * The string is of form "Content {0} more content {1}".  The parameters are read from the optional array and substituted for the bracketed substrings
+		 * TLF provides a default implementation with
+		 * default strings.  Clients may replace this function with their own implementation for localization.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public static function get resourceStringFunction():Function
+		{ 
+			return _resourceStringFunction; 
+		}
+		public static function set resourceStringFunction(val:Function):void
+		{
+			_resourceStringFunction = val;
+		}
+		
+		private static var _resourceStringFunction:Function = defaultResourceStringFunction;
+		
+		/** @private */
+		
+		private static const resourceDict:Object = 
+		{
+			missingStringResource:			"No string for resource {0}",
+			// core errors
+			invalidFlowElementConstruct:	"Attempted construct of invalid FlowElement subclass",
+			invalidSplitAtPosition:			"Invalid parameter to splitAtPosition",
+			badMXMLChildrenArgument: 		"Bad element of type {0} passed to mxmlChildren",
+			badReplaceChildrenIndex: 		"Out of range index to FlowGroupElement.replaceChildren",
+			invalidChildType: 				"NewElement not of a type that this can be parent of",
+			badRemoveChild: 				"Child to remove not found",
+			invalidSplitAtIndex:			"Invalid parameter to splitAtIndex",
+			badShallowCopyRange: 			"Bad range in shallowCopy",
+			badSurrogatePairCopy: 			"Copying only half of a surrogate pair in SpanElement.shallowCopy",
+			invalidReplaceTextPositions:	"Invalid positions passed to SpanElement.replaceText",
+			invalidSurrogatePairSplit: 		"Invalid splitting of a surrogate pair",
+			badPropertyValue:				"Property {0} value {1} is out of range",
+			// selection/editing
+			illegalOperation:				"Illegal attempt to execute {0} operation",
+			// shared import errors
+			unexpectedXMLElementInSpan:		"Unexpected element {0} within a span",
+			unexpectedNamespace:			"Unexpected namespace {0}",
+			unknownElement: 				"Unknown element {0}",
+			unknownAttribute: 				"Attribute {0} not permitted in element {1}",
+			// html format import errors
+			malformedTag:					"Malformed tag {0}",
+			malformedMarkup: 				"Malformed markup {0}",
+			// textlayoutformat import errors
+			missingTextFlow: 				"No TextFlow to parse",
+			expectedExactlyOneTextLayoutFormat: "Expected one and only one TextLayoutFormat in {0}" 	
+		};
+		
+		/** @private */
+		tlf_internal static function defaultResourceStringFunction(resourceName:String, parameters:Array = null):String
+		{
+			var value:String = String(resourceDict[resourceName]);
+			
+			if (value == null)
+			{
+				value = String(resourceDict["missingStringResource"]);
+				parameters = [ resourceName ];
+			}
+			
+			if (parameters)
+				value = substitute(value, parameters);
+			
+			return value;
+		}
+		
+		/** @private */
+		tlf_internal static function substitute(str:String, ... rest):String
+		{
+			if (str == null) 
+				return '';
+			
+			// Replace all of the parameters in the msg string.
+			var len:uint = rest.length;
+			var args:Array;
+			if (len == 1 && rest[0] is Array)
+			{
+				args = rest[0] as Array;
+				len = args.length;
+			}
+			else
+			{
+				args = rest;
+			}
+			
+			for (var i:int = 0; i < len; i++)
+			{
+				str = str.replace(new RegExp("\\{"+i+"\\}", "g"), args[i]);
+			}
+			
+			return str;
+		}
+		
+
+		private static var _enableDefaultTabStops:Boolean = false;
+		/** 
+		 * @private Player versions prior to 10.1 do not set up any default tabStops. As a workaround, if enableDefaultTabs
+		 * is true, TLF will set up default tabStops in the case where there are no tabs defined.
+		 * 
+		 */		
+		tlf_internal static function get enableDefaultTabStops():Boolean
+		{
+			return _enableDefaultTabStops;
+		}
+		/** 
+		 * @private 
+		 */			
+		tlf_internal static function set enableDefaultTabStops(val:Boolean):void
+		{
+			_enableDefaultTabStops = val;
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/IConfiguration.as b/textLayout_core/src/flashx/textLayout/elements/IConfiguration.as
new file mode 100755
index 0000000..d95a538
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/IConfiguration.as
@@ -0,0 +1,306 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements
+{
+	import flashx.textLayout.edit.SelectionFormat;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	/** Read-only interface to a configuration object.  Used by TextFlow to guarantee it has an unchangeable 
+	 * configuration once its constructed.
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public interface IConfiguration 
+	{
+		/** 
+		* Specifies whether the TAB key is entered as text by Text Layout Framework, or Flash Player or AIR handles it and 
+		* turns it into a tabbed panel event. 
+		*
+		* <p>Default value is <code>false</code>.</p>
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*/
+		
+		function get manageTabKey():Boolean
+
+		/** 
+		* Specifies whether the Enter / Return key is entered as text by Text Layout Framework, to split a paragraph for example,
+		* or the client code handles it. The client code might handle it by committing a form that has a default button 
+		* for that purpose, for example. 
+		*
+		* <p>Default value is <code>true</code>.</p>
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*/
+		
+		function get manageEnterKey():Boolean
+		
+		/** 
+		* Policy used for deciding whether the last line of a container fits in the container, or whether it overflows.
+		* Use the constants of the OverflowPolicy class to set this property.
+		*
+		* <p>Default value is OverflowPolicy.FIT_DESCENDERS, which fits the line in the composition area if the area
+		* from the top to the baseline fits.</p>
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*
+		* @see OverflowPolicy
+		*/
+		
+		function get overflowPolicy():String;
+		
+		/** 
+		* Specifies whether accessibility support is turned on or not.  If <code>true</code>, screen readers can read the TextFlow contents.
+		*
+		* <p>Default value is <code>false</code>.</p>
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*
+		* @see TextFlow
+		*/
+		
+		function get enableAccessibility():Boolean;
+		
+		/** 
+		* Specifies the initial link attributes for all LinkElement objects in the text flow. These are default
+		* values for new LinkElement objects that don't specify values for these attributes.
+		*
+		* The default normal format displays the link in blue with underlining.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+		* @see FlowElement#linkNormalFormat
+		* @see flashx.textLayout.formats.ITextLayoutFormat ITextLayoutFormat
+		* @see LinkElement
+		*/
+		
+		function get defaultLinkNormalFormat():ITextLayoutFormat
+		
+		/** 
+		* Specifies the initial character format attributes that apply to a link (LinkElement) in the text flow when
+		* the cursor hovers over it. These are defaults for new LinkElement objects that don't specify values
+		* for these attributes.
+		*
+		* <p>Default is <code>null</code>.</p>
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*
+		* @see  FlowElement#linkHoverFormat
+		* @see flashx.textLayout.formats.ITextLayoutFormat ITextLayoutFormat
+		* @see LinkElement
+		*/
+		
+		function get defaultLinkHoverFormat():ITextLayoutFormat
+		
+		/** 
+		* Specifies the active character format attributes that initially apply for all links (LinkElement objects) in the text 
+		* flow. These are defaults for new LinkElement objects that don't specify values for these attributes. 
+		*
+		* <p>Default is <code>null</code>.</p>
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*
+		* @see FlowElement#linkActiveFormat 
+		* @see flashx.textLayout.formats.ITextLayoutFormat ITextLayoutFormat
+		* @see LinkElement
+		*/
+		
+		function get defaultLinkActiveFormat():ITextLayoutFormat
+		
+		/** 
+		* Specifies the initial format TextLayoutFormat configuration for a text flow (TextFlow object).
+		*
+		* <p>Default is <code>null</code>.</p>
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*
+		* @see TextFlow
+		* @see flashx.textLayout.formats.ITextLayoutFormat ITextLayoutFormat
+		*/
+		
+		function get textFlowInitialFormat():ITextLayoutFormat
+		
+		/** 
+		* The initial selection format (SelectionFormat) for a text flow (TextFlow) when its window has focus. 
+		* Text Layout Framework uses <code>focusedSelectionFormat</code> to draw the selection when the window is active and one of 
+		* the containers in the TextFlow has focus. You can override this format using 
+		* <code>SelectionManager.focusedSelectionFormat</code>, if desired.
+		*
+		* <p>The SelectionFormat class specifies the default values, which invert the color of the text and its background.</p>
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*
+		* @see flashx.textLayout.edit.SelectionFormat SelectionFormat
+		* @see flashx.textLayout.edit.SelectionManager#focusedSelectionFormat SelectionManager.focusedSelectionFormat
+		* @see TextFlow
+		*/
+		
+		function get focusedSelectionFormat():SelectionFormat
+		
+		/** 
+		* The initial selection format that Text Layout Framework uses to draw the selection when the window is active but none of the containers
+		* in the TextFlow have focus. You can override this format using <code>SelectionManager.unfocusedSelectionFormat</code>, if desired.
+		*
+		* <p>If you do not override <code>unfocusedSelectionFormat</code> the SelectionFormat values used are:</p>
+		*
+		* <ul>
+		*   <li><code>color = 0xffffff</code> (white)</li>
+		*   <li><code>alpha = 0</code></li>
+		*   <li><code>blendMode = flash.display.BlendMode.DIFFERENCE</code></li>
+		* </ul>
+		* <p>The result is no selection is displayed.</p>
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*
+		* @see flashx.textLayout.edit.SelectionFormat SelectionFormat
+		* @see flashx.textLayout.edit.SelectionManager#unfocusedSelectionFormat SelectionManager.unfocusedSelectionFormat
+		* @see TextFlow
+		*/
+		
+		function get unfocusedSelectionFormat():SelectionFormat		
+		
+		/** 
+		* The initial selection format (SelectionFormat) for a text flow (TextFlow) when its window is inactive. Text Layout Framework uses 
+		* <code>inactiveSelectionFormat</code> for drawing the selection when the window is inactive. You can override 
+		* this format using <code>SelectionManager.inactiveSelectionFormat</code>, if desired.
+		*
+		* <p>If you do not override <code>unfocusedSelectionFormat</code> the SelectionFormat values used are:</p> 
+		* <ul>
+		*   <li><code>color = 0xffffff</code> (white)</li>
+		*   <li><code>alpha = 0</code></li>
+		*   <li><code>blendMode = flash.display.BlendMode.DIFFERENCE</code></li>
+		* </ul>
+		* <p>The result is no selection is displayed.</p>
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*
+		* @see flashx.textLayout.edit.SelectionFormat SelectionFormat
+		* @see flashx.textLayout.edit.SelectionManager#inactiveSelectionFormat SelectionManager.inactiveSelectionFormat
+		* @see TextFlow
+		*/
+		
+		function get inactiveSelectionFormat():SelectionFormat		
+		
+		/** 
+		* Specifies a timed delay between one scroll and the next to prevent scrolling from going 
+		* too fast. This value specifies what the delay is in milliseconds. The default value is 35.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*/
+		
+		function get scrollDragDelay():Number
+		
+		/** Specifies the default number of pixels to scroll when the user initiates auto scrolling by dragging 
+		* the selection. Default value is 20.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*/
+		
+		function get scrollDragPixels():Number
+		
+		/**
+		* Specifies the default percentage of the text flow to scroll for page scrolls. Default value is
+		* 7.0 / 8.0, or .875.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*/
+		
+		function get scrollPagePercentage(): Number
+		
+		/** Specifies the default number of pixels to scroll for Mouse wheel events. Default value is 20.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*/
+		
+		function get scrollMouseWheelMultiplier(): Number
+		
+		/** Specifies the type of flow composer to attach to a new TextFlow object by default. Default value is StandardFlowComposer.
+		*
+		* @see flashx.textLayout.compose.StandardFlowComposer StandardFlowComposer
+		* @see flashx.textLayout.elements.TextFlow TextFlow
+		* 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*/
+		
+		function get flowComposerClass():Class
+		
+		/** Requests that the process of composing text release line creation data after composing each paragraph.  
+		* This request saves memory but slows down the composing process.
+		*
+		* <p>Default value is <code>false</code>.</p>
+		*
+		* @see flashx.textLayout.compose.StandardFlowComposer StandardFlowComposer
+		* @see flash.text.engine.TextBlock#releaseLineCreationData() TextBlock.releaseLineCreationData()
+		* 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*/
+		function get releaseLineCreationData():Boolean;
+		
+		/** Specifies the callback used for resolving an inline graphic element.
+		* The callback takes a <code>flashx.textLayout.elements.InlineGraphicElement</code> object and returns
+		* the value to be used as the element's <code>flashx.textLayout.elements.InlineGraphicElement#source</code>.
+		* 
+		* This callback provides the mechanism to delay providing an inline graphic element's source until just before it is composed.
+		* <p><strong>Note:</strong> this callback will be invoked only if a 
+		* placeholder source of String type is already set. Moreover, it may be invoked
+		* multiple times. </p>
+		* 
+		* @see flashx.textLayout.elements.InlineGraphicElement InlineGraphicElement
+		* 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*/
+		function get inlineGraphicResolverFunction():Function;
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/IFormatResolver.as b/textLayout_core/src/flashx/textLayout/elements/IFormatResolver.as
new file mode 100755
index 0000000..f1780c8
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/IFormatResolver.as
@@ -0,0 +1,86 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements
+{
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	/** Interface to a format resolver. An implementation allows you to attach a styling mechanism of your choosing, such as
+	 *  Flex CSS styling and named styles, to a TextFlow.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 * 
+	 * @see flashx.textLayout.elements.TextFlow#formatResolver TextFlow.formatResolver
+	 */
+	 
+	public interface IFormatResolver 
+	{
+		/** Invalidates any cached formatting information for a TextFlow so that formatting must be recomputed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		function invalidateAll(textFlow:TextFlow):void;
+		
+		/** Invalidates cached formatting information on this element because, for example, the <code>parent</code> changed, 
+		 *  or the <code>id</code> or the <code>styleName</code> changed. 
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	  	 * @langversion 3.0*/
+	  	 
+		function invalidate(target:Object):void;
+		
+		/** Given a FlowElement or ContainerController object, return any format settings for it.
+		 *
+		 * @return format settings for the specified object.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+	 	 */
+	 	 
+		function resolveFormat(target:Object):ITextLayoutFormat;
+		
+		/** Given a FlowElement or ContainerController object and the name of a format property, return the format value
+		 * or <code>undefined</code> if the value is not found.
+		 *
+		 * @return the value of the specified format for the specified object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		 
+		function resolveUserFormat(target:Object,userFormat:String):*;
+		
+		/** Returns the format resolver when a TextFlow is copied.
+		 *
+		 * @return the format resolver for the copy of the TextFlow.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		 
+		function getResolverForNewFlow(oldFlow:TextFlow,newFlow:TextFlow):IFormatResolver;
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/InlineGraphicElement.as b/textLayout_core/src/flashx/textLayout/elements/InlineGraphicElement.as
new file mode 100755
index 0000000..5d25adc
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/InlineGraphicElement.as
@@ -0,0 +1,1081 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements 
+{
+	import flash.display.DisplayObject;
+	import flash.display.DisplayObjectContainer;
+	import flash.display.Loader;
+	import flash.display.LoaderInfo;
+	import flash.display.MovieClip;
+	import flash.display.Shape;
+	import flash.display.Sprite;
+	import flash.events.ErrorEvent;
+	import flash.events.Event;
+	import flash.events.IOErrorEvent;
+	import flash.geom.Rectangle;
+	import flash.net.URLRequest;
+	import flash.system.Capabilities;
+	import flash.text.engine.FontMetrics;
+	import flash.text.engine.GraphicElement;
+	import flash.text.engine.TextBaseline;
+	import flash.text.engine.TextLine;
+	import flash.text.engine.TextRotation;
+	
+	import flashx.textLayout.compose.TextFlowLine;
+	import flashx.textLayout.debug.Debugging;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.events.ModelChange;
+	import flashx.textLayout.events.StatusChangeEvent;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.formats.Float;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.formats.JustificationRule;
+	import flashx.textLayout.property.EnumStringProperty;
+	import flashx.textLayout.property.NumberOrPercentOrEnumProperty;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+
+	/** The InlineGraphicElement class handles graphic objects that display inline in the text. 
+	 * 
+	 * <p>You can embed a graphic or any DisplayObject or specify a URl for the location of the graphic. 
+	 * The <code>height</code> and <code>width</code> properties of InlineGraphicElement control the actual size 
+	 * of the graphic to display.  These values also control how much space to allocate
+	 * for the graphic in the TextLine object that contains the graphic.
+	 * The <code>height</code> and <code>width</code> properties each can be one of:</p>
+	 * <ol>
+	 * <li>A number of pixels</li>
+	 * <li>A percent of the measured size of the image</li>
+	 * <li>The constant, "auto", which computes the size (Default value)</li>
+	 * </ol>
+	 * There are three properties, or accessors, pertaining to the width and height of a graphic:
+	 * <ul>
+	 * <li>The <code>width</code> and <code>height</code> properties</li>
+	 * <li>The <code>measuredWidth</code> and <code>measuredHeight</code> properties, which are the width or height of the graphic at load time</li>
+	 * <li>The <code>actualWidth</code> and <code>actualHeight</code> properties, which are the actual display and compose width and height of the graphic as computed from <code>width</code> or <code>height</code> and <code>measuredWidth</code> or <code>measuredHeight</code></li>
+	 * </ul>
+	 * <p>The values of the <code>actualWidth</code> and <code>actualHeight</code> properties are always zero until the graphic 
+	 * is loaded.</p>
+	 *
+	 * <p>If <code>source</code> is specified as a URI, the graphic is loaded asynchronously. If it's a DisplayObject, TextLayout uses the <code>width</code> and 
+	 * <code>height</code> at the time the graphic is set into the InlineGraphicElement object as <code>measuredHeight</code> and <code>measuredWidth</code>; 
+	 * its width and height are read immediately.</p>
+	 * <p><strong>Notes</strong>: For graphics that are loaded asynchronously the user must listen for a 
+	 * StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE event on the TextFlow and call <code>IFlowComposer.updateAllControllers()</code> to have the 
+	 * graphic appear. The value of <code>measuredWidth</code> and <code>measuredHeight</code> for graphics that are in the 
+	 * process of loading is zero.</p>
+	 *
+	 * <p>Some inline graphics are animations or videos that possibly have audio. They begin to run the first time they are composed after they finish loading.  
+	 * They don't stop running until the flowComposer on the TextFlow is set to null.  At that time they are stopped and unloaded.</p>
+	 * 
+	 * The following restrictions apply to InLineGraphicElement objects:
+	 * <ol>
+	 * 	<li>On export of TLFMarkup, source is converted to a string. If the graphic element is 
+	 *		a class, the Text Layout Framework can't export it properly</li>.
+	 *	<li>When doing a copy/paste operation of an InlineGraphicElement, if source can't be 
+	 * 		used to create a new InLineGraphicElement, it won't be pasted.  For example if 
+	 *		source is a DisplayObject, or if the graphic is set directly, it can't be 
+	 *		duplicated.  Best results are obtained if the source is the class of an embedded graphic 
+	 * 		though that doesn't export/import.</li>
+	 * 	<li>InLineGraphicElement objects work in the factory (TextFlowTextLineFactory) only if 
+	 * 		the source is a class or if you explicitly set the graphic to a loaded graphic. 
+	 * 		InlineGraphic objects that require delayed loads generally do not show up.</li>
+	 * </ol>
+	 * @includeExample examples\InlineGraphicElementExample.as -noswf
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 *
+	 * @see #actualHeight
+	 * @see #actualWidth
+	 * @see flash.display.DisplayObject DisplayObject
+	 * @see flashx.textLayout.compose.IFlowComposer#updateAllControllers()
+	 * @see flashx.textLayout.events.StatusChangeEvent StatusChangeEvent
+	 * @see TextFlow
+	 */
+	public final class InlineGraphicElement extends FlowLeafElement
+	{	
+		private var _source:Object;
+		
+		private var _graphic:DisplayObject;
+		
+		private var _elementWidth:Number;
+		private var _elementHeight:Number;
+
+		// internal status of the graphic.  there are more status here than publicly shown
+		private var _graphicStatus:Object;
+		
+		// set when its ok - must delay until on the stage for dynamically loaded images
+		private var okToUpdateHeightAndWidth:Boolean;
+		
+		private var _width:*;
+		private var _height:*;
+		
+		// stash away the actual width and height of the graphic
+		private var _measuredWidth:Number;
+		private var _measuredHeight:Number;
+		
+		private var _float:*;
+
+		/** Constructor - create new InlineGraphicElement object
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function InlineGraphicElement():void
+		{
+			super();
+			// The width/height on the FE.fe don't actually take until the InlineGraphicElement is loaded.
+			okToUpdateHeightAndWidth = false;
+			_measuredWidth = 0;
+			_measuredHeight = 0;
+			internalSetWidth(undefined);
+			internalSetHeight(undefined);
+			_float = floatPropertyDefinition.defaultValue;
+			_graphicStatus = InlineGraphicElementStatus.LOAD_PENDING;
+			setTextLength(1);
+			_text = String.fromCharCode(0xFDEF);
+		}
+		
+		/** @private */
+		override tlf_internal function createContentElement():void
+		{
+			if (_blockElement)
+				return;
+				
+			var graphicElement:GraphicElement = new GraphicElement();			
+			_blockElement = graphicElement;
+			CONFIG::debug { Debugging.traceFTECall(_blockElement,null,"new GraphicElement()"); }
+			_blockElement.textRotation = String(rotationPropertyDefinition.defaultValue)
+			CONFIG::debug { Debugging.traceFTEAssign(_blockElement,"textRotation",String(rotationPropertyDefinition.defaultValue)); }
+			graphicElement.elementHeight = (_float != Float.NONE) ? 0 : elementHeight;
+			CONFIG::debug { Debugging.traceFTEAssign(_blockElement,"elementHeight",graphicElement.elementHeight); }
+			graphicElement.elementWidth = (_float != Float.NONE) ? 0 : elementWidth;
+			CONFIG::debug { Debugging.traceFTEAssign(_blockElement,"elementWidth",graphicElement.elementWidth); }
+			graphicElement.graphic = (_float != Float.NONE) ? new Sprite() : graphic;
+			CONFIG::debug { Debugging.traceFTEAssign(graphicElement,"graphic",graphic); }	// needs float fix
+			super.createContentElement();
+	//		trace("text is ", _blockElement.rawText.charCodeAt(0), "length", _blockElement.rawText.length);
+			_text = null;
+		}
+		
+		/** @private */
+		override tlf_internal function canReleaseContentElement():Boolean
+		{
+			return false;
+		}
+		
+		/** @private */
+		override tlf_internal function releaseContentElement():void
+		{
+			if (_blockElement == null || !canReleaseContentElement())
+				return;
+			_text = String.fromCharCode(0xFDEF);		// echo text property we get from FTE
+			super.releaseContentElement();
+		}
+		
+		// internal values for _graphicStatus.  It can also be an error code.
+		/** load initiated */
+		static private const LOAD_INITIATED:String = "loadInitiated";
+		/** public status string for open event received status.  @see flash.display.LoaderInfo.Events.open */
+		static private const OPEN_RECEIVED:String = "openReceived";
+		/** load complete received status.  @see flash.display.LoaderInfo.Events.open */
+		static private const LOAD_COMPLETE:String = "loadComplete";
+		/** loaded from embed */
+		static private const EMBED_LOADED:String = "embedLoaded";
+		/** specified as a DisplayObject */
+		static private const DISPLAY_OBJECT:String = "displayObject";
+		/** null graphic */
+		static private const NULL_GRAPHIC:String = "nullGraphic";
+		
+		
+		private function getGraphicElement():GraphicElement
+		{ 
+			if (!_blockElement)
+				createContentElement();
+			return GraphicElement(_blockElement); 
+		}
+		
+		private static var isMac:Boolean = (Capabilities.os.search("Mac OS") > -1);				
+		
+		/** The embedded graphic. 
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*/
+	 	
+		public function get graphic():DisplayObject
+		{
+			return _graphic;
+		}
+		private function setGraphic(value:DisplayObject):void
+		{
+			if (_blockElement)
+			{
+				// Update the graphicElement to match the new graphic value. If it's a float,
+				// we set it to a placeholder in the ge.graphic in order to be able to navigate
+				// to the element.  Without it, the FTE model will remove the atom and selection will not be
+				// possible. - gak 12.12.08
+				GraphicElement(_blockElement).graphic = (_float != Float.NONE) ? new Sprite() : value;
+				CONFIG::debug { Debugging.traceFTEAssign(_blockElement,"graphic",GraphicElement(_blockElement).graphic); }
+			}
+
+			_graphic = value;
+		// I think this should do a model change. But it will break paste because when we paste we do a reimport,
+		// which will cause a delayed update, which will bump the generation number *after* the command. Which 
+		// will cause undo of the command not to work.
+		//	modelChanged(ModelChange.ELEMENT_MODIFIED,0,textLength);
+		}
+		
+		/** Width used by composition for laying out text around the graphic. @private */
+		tlf_internal function get elementWidth():Number
+		{
+			return _elementWidth;			
+		}
+		/** Width used by composition for laying out text around the graphic. @private */
+		tlf_internal function set elementWidth(value:Number):void
+		{
+			if (_blockElement)
+			{
+				GraphicElement(_blockElement).elementWidth = (_float != Float.NONE) ? 0 : value;
+				CONFIG::debug { Debugging.traceFTEAssign(GraphicElement(_blockElement),"elementWidth",GraphicElement(_blockElement).elementWidth); }
+				
+			}
+
+			 _elementWidth = value;
+			modelChanged(ModelChange.ELEMENT_MODIFIED,0,textLength,true,false);
+		}
+		
+		/** Height used by composition for laying out text around the graphic. @private */
+		tlf_internal function get elementHeight():Number
+		{
+			return _elementHeight;			
+		}
+		/** Height used by composition for laying out text around the graphic. @private */
+		tlf_internal function set elementHeight(value:Number):void
+		{
+			if (_blockElement)
+			{
+				GraphicElement(_blockElement).elementHeight = (_float != Float.NONE) ? 0 : value;	
+				CONFIG::debug { Debugging.traceFTEAssign(GraphicElement(_blockElement),"elementHeight",GraphicElement(_blockElement).elementHeight); }
+			}
+			_elementHeight = value;
+			modelChanged(ModelChange.ELEMENT_MODIFIED,0,textLength,true,false);
+		}
+		
+		/** Definition of the height property @private */
+		static tlf_internal const heightPropertyDefinition:NumberOrPercentOrEnumProperty = new NumberOrPercentOrEnumProperty("height", FormatValue.AUTO, false, null, 0, 32000, "0%", "1000000%", FormatValue.AUTO );
+		
+		/** Definition of the width property @private */
+		static tlf_internal const widthPropertyDefinition:NumberOrPercentOrEnumProperty = new NumberOrPercentOrEnumProperty("width", FormatValue.AUTO, false, null, 0, 32000, "0%", "1000000%", FormatValue.AUTO );
+		
+		/** Disabled due to player bug.  @private */
+		static tlf_internal const rotationPropertyDefinition:EnumStringProperty = new EnumStringProperty("rotation", TextRotation.ROTATE_0, false, null, 
+			TextRotation.ROTATE_0, TextRotation.ROTATE_90, TextRotation.ROTATE_180, TextRotation.ROTATE_270);		
+		
+		/** Definition of the float property @private */
+		static tlf_internal const floatPropertyDefinition:EnumStringProperty = new EnumStringProperty("float", Float.NONE, false, null, 
+			 Float.NONE, Float.LEFT, Float.RIGHT);
+			
+		/** The current status of the image. On each status change the owning TextFlow sends a StatusChangeEvent.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+		 * @return one of LOAD_PENDING, LOADING, SIZE_PENDING, READY, ERROR
+		 * @see flashx.textLayout.elements.InlineGraphicElementStatus
+		 * @see flashx.textLayout.events.StatusChangeEvent
+		 */
+		 
+		public function get status():String
+		{
+			switch(_graphicStatus)
+			{
+				case LOAD_INITIATED:
+				case OPEN_RECEIVED:
+					return InlineGraphicElementStatus.LOADING;
+				case LOAD_COMPLETE:
+				case EMBED_LOADED:
+				case DISPLAY_OBJECT:
+				case NULL_GRAPHIC:
+					return InlineGraphicElementStatus.READY;
+				case InlineGraphicElementStatus.LOAD_PENDING:
+				case InlineGraphicElementStatus.SIZE_PENDING:
+					return String(_graphicStatus);
+			}
+			CONFIG::debug { assert(_graphicStatus is ErrorEvent,"unexpected _graphicStatus"); }
+			return InlineGraphicElementStatus.ERROR; 
+		}
+		
+		private function changeGraphicStatus(stat:Object):void
+		{
+			var oldStatus:String = status;
+			_graphicStatus = stat;
+			var newStatus:String = status;
+			if (oldStatus != newStatus || stat is ErrorEvent)
+			{
+				var tf:TextFlow = getTextFlow();
+				if (tf)
+				{
+					if (newStatus == InlineGraphicElementStatus.SIZE_PENDING)
+						tf.processAutoSizeImageLoaded(this);
+					tf.dispatchEvent(new StatusChangeEvent(StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE, false, false, this, newStatus, stat as ErrorEvent));
+				}
+			}
+		}
+				
+		/** The width of the graphic. The value can be 'auto', a number of pixels or a percent of the measured width of the image.
+		 * 
+		 * <p>Legal values are flashx.textLayout.formats.FormatValue.AUTO and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Legal values as a number are from 0 to 32000.</p>
+		 * <p>Legal values as a percent are numbers from 0 to 1000000.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined or "inherit" the InlineGraphicElement will use the default value of "auto".</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see #actualWidth
+	 	 * @see #measuredWidth
+	 	 */
+		public function get width():*
+		{ return _width; }
+		public function set width(w:*):void
+		{ 
+			internalSetWidth(w);
+			modelChanged(ModelChange.ELEMENT_MODIFIED,0,textLength);
+		}
+		
+		/** The natural width of the graphic. This is the width of the graphic at load time.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+	 	* @see #actualWidth
+	 	* @see #width
+	 	*/
+	 	
+		public function get measuredWidth():Number
+		{ return _measuredWidth; }
+		
+		/** The actual width in effect. This is the display and compose width that's computed from the
+		* <code>width</code> and <code>measuredWidth</code> properties.
+		*
+		* <p>The values of the <code>actualWidth</code>property are computed according to the 
+		* following table:</p>
+		* <table class="innertable" width="100%">
+		* <tr>
+		*   <th>width property</th> 
+		*   <th>actualWidth</th>
+		* </tr>
+		* <tr>
+		*   <td>auto</td>
+		*   <td>measuredWidth</td>
+		* </tr>
+		* <tr>
+		*   <td>w a Percent</td>
+		*   <td>w percent of measuredWidth</td>
+		* </tr>
+		* <tr>
+		*   <td>w a Number</td>
+		*   <td>w</td>
+		* </tr>
+		* </table>
+		*
+		* <p><strong>Notes</strong>: If the inline graphic is a DisplayObject, its width and height are read immediately.
+		* If <code>measuredWidth</code> or <code>measuredHeight</code> are zero, then any auto calculations that would cause a divide by zero sets the result to zero.</p>
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+	 	* @see #measuredWidth
+	 	* @see #width
+	 	*
+	 	*/
+	 	
+		public function get actualWidth():Number
+		{ return elementWidth; }
+		
+		private function widthIsComputed():Boolean
+		{ return internalWidth is String; }
+		
+		private function get internalWidth():Object
+		{ return _width === undefined ? widthPropertyDefinition.defaultValue : _width; }		
+
+		private function computeWidth():Number
+		{
+			CONFIG::debug { assert(widthIsComputed(),"bad call to InlineGraphicElement.computeWidth"); }
+			if (internalWidth == FormatValue.AUTO)
+			{
+				if (internalHeight == FormatValue.AUTO)
+					return _measuredWidth;
+				if (_measuredHeight == 0 || _measuredWidth == 0)
+					return 0;
+				// can't rely on height being calculated yet
+				var effHeight:Number = heightIsComputed() ? computeHeight(): Number(internalHeight);
+				return effHeight/_measuredHeight * _measuredWidth;
+			}
+			return widthPropertyDefinition.computeActualPropertyValue(internalWidth,_measuredWidth); 
+		}
+		
+		private function internalSetWidth(w:*):void
+		{
+			_width = widthPropertyDefinition.setHelper(width,w);
+			elementWidth = widthIsComputed() ? 0 : Number(internalWidth);
+			if (okToUpdateHeightAndWidth && graphic)
+			{
+				if (widthIsComputed())
+					elementWidth =  computeWidth();
+				graphic.width = elementWidth;
+				CONFIG::debug { Debugging.traceFTEAssign(graphic,"width",elementWidth); }
+				if (internalHeight == FormatValue.AUTO)
+				{
+					elementHeight =  computeHeight();
+					graphic.height = elementHeight;
+					CONFIG::debug { Debugging.traceFTEAssign(graphic,"height",elementHeight); }
+				}
+			}
+		}
+
+		/** The height of the image. May be 'auto', a number of pixels or a percent of the measured height. 
+		 *
+		 * <p>Legal values are flashx.textLayout.formats.FormatValue.AUTO and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Legal values as a number are from 0 to 32000.</p>
+		 * <p>Legal values as a percent are numbers from 0 to 1000000.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined or "inherit" the InlineGraphicElement will use the default value of "auto".</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		  * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see #actualHeight
+	 	 * @see #measuredHeight
+	 	 */
+		public function get height():*
+		{ return _height; }
+		public function set height(h:*):void
+		{
+			internalSetHeight(h);
+			modelChanged(ModelChange.ELEMENT_MODIFIED,0,textLength);
+		}
+		
+		private function get internalHeight():Object
+		{ return _height === undefined ? heightPropertyDefinition.defaultValue : _height; }
+		
+		/** @private - prototype phase only */
+		tlf_internal function get float():*
+		{
+			return _float;
+		}
+		/** @private - prototype phase only */
+		tlf_internal function set float(value:*):*
+		{
+			if (value === undefined)
+				value = floatPropertyDefinition.defaultValue;
+			value = floatPropertyDefinition.setHelper(float, value) as String;
+			if (_float != value)
+			{
+				var origWasInline:Boolean = _float == Float.NONE;
+				_float = value;
+				
+				if (_float != Float.NONE)		// it's float; move variables from fte back to floating so fte won't see them
+				{
+					//only apply the graphicElement width and height if the original graphicElement was not a placeHolder
+					//failure to do so will result in a 0 width/height element.
+					if(origWasInline && _blockElement)
+					{
+						var graphicElement:GraphicElement = GraphicElement(_blockElement);
+						setGraphic(graphicElement.graphic);
+						elementWidth = graphicElement.elementWidth;
+						elementHeight = graphicElement.elementHeight;
+					}
+				}
+				else 	// it's inline: move varibles back from floating to where fte will see them
+				{
+					_graphic.x = 0;		// clear out whatever repositioning was done by floats code
+					_graphic.y = 0;
+					setGraphic (_graphic);
+					elementWidth = _elementWidth;
+					elementHeight = _elementHeight;					
+				}
+				modelChanged(ModelChange.ELEMENT_MODIFIED,0,textLength);
+			}					
+		}
+		
+		/** The natural height of the graphic. This is the height of the graphic at load time.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	* 
+	 	* @see #actualHeight
+	 	* @see #height
+	 	*/
+	 	
+		public function get measuredHeight():Number
+		{ return _measuredHeight; }
+			
+		/** The actual height in effect. This is the display and compose height that's computed from the
+		* <code>height</code> and <code>measuredHeight</code> properties.
+		*
+		* <p>The values of the <code>actualHeight</code> property are computed according to the following table:</p>
+		* <table class="innertable" width="100%">
+		* <tr>
+		*   <th>height property</th>
+		*   <th>actualHeight</th>
+		* </tr>
+		* <tr>
+		*   <td>auto</td>
+		*   <td>measuredheight</td>
+		* </tr>
+		* <tr>
+		*   <td>h a Percent</td>
+		*   <td>h percent of measuredheight</td>
+		* </tr>
+		* <tr>
+		*   <td>h a Number</td>
+		*   <td>h</td>
+		* </tr>
+		* </table>
+		* <p><strong>Notes</strong>: If the inline graphic is a DisplayObject, its width and height are read immmediately.
+		* If <code>measuredWidth</code> or <code>measuredHeight</code> are zero, then any auto calculations that would cause a divide by zero sets the result to zero.</p>
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+	 	* @see #height
+	 	* @see #measuredHeight
+	 	*/
+	 	
+		public function get actualHeight():Number
+		{ return elementHeight; }
+		
+		private function heightIsComputed():Boolean
+		{ return internalHeight is String; }
+		
+		private function computeHeight():Number
+		{
+			CONFIG::debug { assert(heightIsComputed(),"bad call to InlineGraphicElement.computeWidth"); }
+			if (internalHeight == FormatValue.AUTO)
+			{
+				if (internalWidth == FormatValue.AUTO)
+					return _measuredHeight;
+				if (_measuredHeight == 0 || _measuredWidth == 0)
+					return 0;
+				// can't rely on width being calculated yet
+				var effWidth:Number = widthIsComputed() ? computeWidth(): Number(internalWidth);
+				return effWidth/_measuredWidth * _measuredHeight;
+			}
+			return heightPropertyDefinition.computeActualPropertyValue(internalHeight,_measuredHeight); 
+		}
+		
+		private function internalSetHeight(h:*):void
+		{
+			_height = heightPropertyDefinition.setHelper(height,h);
+			elementHeight = heightIsComputed() ? 0 : Number(internalHeight);
+			if (okToUpdateHeightAndWidth && graphic != null)
+			{
+				if (heightIsComputed())
+					elementHeight =  computeHeight();
+				graphic.height = elementHeight;
+				CONFIG::debug { Debugging.traceFTEAssign(graphic,"height",elementHeight); }
+
+				if (internalWidth == FormatValue.AUTO)
+				{
+					elementWidth =  computeWidth();
+					graphic.width = elementWidth;
+					CONFIG::debug { Debugging.traceFTEAssign(graphic,"width",elementWidth); }
+				}
+			}
+		}
+		
+		private function loadCompleteHandler(e:Event):void
+		{			
+			CONFIG::debug { Debugging.traceFTECall(null,null,"loadCompleteHandler",this); }
+			removeDefaultLoadHandlers();
+			CONFIG::debug { assert(okToUpdateHeightAndWidth == false,"invalid call to loadCompleteHandler"); }
+			okToUpdateHeightAndWidth = true;
+			
+			var g:DisplayObject = graphic;
+			_measuredWidth = g.width;
+			_measuredHeight = g.height;
+			
+			if (!widthIsComputed())
+				g.width  = elementWidth;
+			if (!heightIsComputed())
+				g.height = elementHeight;
+				
+			if (e is IOErrorEvent)
+				changeGraphicStatus(e);
+			else if (widthIsComputed() || heightIsComputed())
+			{
+				g.visible = false;
+				// triggers a delayedElementUpdate
+				changeGraphicStatus(InlineGraphicElementStatus.SIZE_PENDING);
+			}
+			else
+				changeGraphicStatus(LOAD_COMPLETE);
+		}
+				
+		private function openHandler(e:Event):void
+		{
+			changeGraphicStatus(OPEN_RECEIVED);
+		}
+		
+		private function addDefaultLoadHandlers(loader:Loader):void
+		{
+			var loaderInfo:LoaderInfo = loader.contentLoaderInfo;
+			CONFIG::debug { Debugging.traceFTECall(loaderInfo,loader,"contentLoaderInfo"); }
+			
+			loaderInfo.addEventListener(Event.OPEN, openHandler, false, 0, true);
+			CONFIG::debug { Debugging.traceFTECall(null,loaderInfo,"addEventListener",Event.OPEN, "openHandler", false, 0, true); }
+			loaderInfo.addEventListener(Event.COMPLETE,loadCompleteHandler,false,0,true);	
+			CONFIG::debug { Debugging.traceFTECall(null,loaderInfo,"addEventListener",Event.COMPLETE, "loadCompleteHandler", false, 0, true); }
+			loaderInfo.addEventListener(IOErrorEvent.IO_ERROR,loadCompleteHandler,false,0,true);	
+			CONFIG::debug { Debugging.traceFTECall(null,loaderInfo,"addEventListener",IOErrorEvent.IO_ERROR, "loadCompleteHandler", false, 0, true); }
+		}
+		
+		private function removeDefaultLoadHandlers():void
+		{
+			var loader:Loader = Loader(graphic);
+			CONFIG::debug{ assert(loader != null,"bad call to removeDefaultLoadHandlers"); }
+			loader.contentLoaderInfo.removeEventListener(Event.OPEN, openHandler);
+			loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loadCompleteHandler);
+			loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, loadCompleteHandler);
+		}
+		
+		/** Sets the source for the graphic. 
+		 * 
+		 * The value can be either a String that is interpreted as a URI, a Class that's interpreted as the class of an 
+		 * embeddded DisplayObject, a DisplayObject instance, or a URLRequest. Creates a DisplayObject and,
+		 * if the InlineGraphicElement object is added into a ParagraphElement in a TextFlow object, causes it to appear
+		 * inline in the text.
+		 *
+		 * @includeExample examples\InlineGraphicElement_sourceExample.as -noswf
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function get source():Object
+		{
+			return _source;
+		}
+		public function set source(value:Object):void
+		{
+			stop(true);
+			_source = value;
+			modelChanged(ModelChange.ELEMENT_MODIFIED,0,textLength);
+			changeGraphicStatus(InlineGraphicElementStatus.LOAD_PENDING);
+		}
+	
+		/** @private */
+		tlf_internal override function applyDelayedElementUpdate(textFlow:TextFlow,okToUnloadGraphics:Boolean,hasController:Boolean):void
+		{
+			CONFIG::debug { assert(textFlow != null,"ILG:applyDelayedElementUpdate: null textFlow"); }		
+			if (_graphicStatus == InlineGraphicElementStatus.LOAD_PENDING)
+			{
+				// trace("FEX LOADING", this.toString());
+				if (hasController)
+				{
+					var source:Object = _source;
+					if (source is String)
+					{
+						var inlineGraphicResolver:Function = textFlow.configuration.inlineGraphicResolverFunction;
+						if (inlineGraphicResolver != null)
+							source = inlineGraphicResolver(this);
+					}
+					
+					var elem:DisplayObject;
+					if (source is String || source is URLRequest)
+					{
+						okToUpdateHeightAndWidth = false;
+						var loader:Loader = new Loader();
+						CONFIG::debug { Debugging.traceFTECall(loader,null,"new Loader()"); }
+
+						// set the width/height on COMPLETE or IOError
+						addDefaultLoadHandlers(loader);
+						if (source is String)
+						{
+ 							var myPattern:RegExp = /\\/g;  							
+							var src:String = source as String;
+							src = src.replace(myPattern, "/");
+							//workaround for Watson bug 1896186.  FlashPlayer requres that file
+							//names be encoded on Macintosh, but not on Windows.  Grouped this
+							//bug with FlashPlayer Watson bug 1899687
+							var pictURLReq:URLRequest;
+							if (isMac)
+							{
+								pictURLReq = new URLRequest(encodeURI(src));
+								CONFIG::debug { Debugging.traceFTECall(pictURLReq,null,"new URLRequest",encodeURI(src)); }
+							}
+							else
+							{
+								pictURLReq = new URLRequest(src);	
+								CONFIG::debug { Debugging.traceFTECall(pictURLReq,null,"new URLRequest",src); }									
+							}					
+							loader.load(pictURLReq);
+							CONFIG::debug { Debugging.traceFTECall(null,loader,"load",pictURLReq); }									
+						}
+						else
+							loader.load(URLRequest(source));
+								
+						setGraphic(loader);		
+						changeGraphicStatus(LOAD_INITIATED);
+					}
+					else if (source is Class)	// value is class --> it is an Embed
+					{
+						var cls:Class = source as Class;
+						elem = DisplayObject(new cls());
+						changeGraphicStatus(EMBED_LOADED);
+					}
+					else if (source is DisplayObject)
+					{
+						elem = DisplayObject(source);
+						changeGraphicStatus(DISPLAY_OBJECT);
+					}
+					else
+					{
+						elem = new Shape();
+						changeGraphicStatus(NULL_GRAPHIC);
+					}
+					
+					// complete setup of width and height
+					if (_graphicStatus != LOAD_INITIATED)
+					{
+						okToUpdateHeightAndWidth = true;
+						_measuredWidth = elem ? elem.width : 0;
+						_measuredHeight = elem ? elem.height : 0;
+
+						if (widthIsComputed())
+						{
+							if (elem)
+							{
+								elem.width = elementWidth = computeWidth();
+								CONFIG::debug { Debugging.traceFTEAssign(elem,"width",elem.width); }
+							}
+							else
+								elementWidth = 0;
+						}
+						else
+						{
+							elem.width = Number(width);
+							CONFIG::debug { Debugging.traceFTEAssign(elem,"width",elem.width); }
+						}
+							
+						if (heightIsComputed())
+						{
+							if (elem)
+							{
+								elem.height = elementHeight = computeHeight();
+								CONFIG::debug { Debugging.traceFTEAssign(elem,"height",elem.height); }
+							}
+							else
+								elementHeight = 0;
+						}
+						else
+						{
+							elem.height = Number(height);
+							CONFIG::debug { Debugging.traceFTEAssign(elem,"height",elem.height); }
+						}
+							
+						setGraphic(elem);
+					}
+				}
+			}
+			else
+			{
+				if (_graphicStatus == InlineGraphicElementStatus.SIZE_PENDING)
+				{
+					// this is width/height auto case hasn't been set yet - the graphic is hidden!
+					updateAutoSizes();
+					graphic.visible = true;
+					changeGraphicStatus(LOAD_COMPLETE);
+				}
+				if (!hasController)
+				{
+					// shutdown the audio on any movie clips
+					stop(okToUnloadGraphics);
+				}
+			}
+		}
+		
+		/** @private This API supports the inputmanager */
+		tlf_internal override function updateForMustUseComposer(textFlow:TextFlow):Boolean
+		{ 
+			applyDelayedElementUpdate(textFlow,false,true);
+			return status != InlineGraphicElementStatus.READY;
+		}
+		
+		/** This function updates the size of the graphic element when the size is expressed as a percentage of the graphic's actual size. */
+		private function updateAutoSizes():void
+		{
+			// some discussion about making this function public.  the idea is that if the graphic
+			// changes size the client can force it to recompute.  however the measuredWidth and measuredHeight
+			// of the graphic doesn't really exist anywhere.
+			
+			// when public can only call ths for certain values of _graphicStatus
+			// if (_graphicStatus == NULL_GRAPHIC || _graphicStatus == LOAD_INITIATED || _graphicStatus == OPEN_RECEIVED)
+			//	return;
+				
+			// if (widthIsComputed() || heightIsComputed())	
+			{
+				if (widthIsComputed())
+				{
+					elementWidth = computeWidth();
+					graphic.width = elementWidth;
+				}
+				if (heightIsComputed())
+				{
+					elementHeight = computeHeight();
+					graphic.height = elementHeight;
+				}
+			}
+		}
+		
+		
+		/** stop if its a movieclip */
+		private function stop(okToUnloadGraphics:Boolean):Boolean
+		{
+			
+			// watch for changing the source while we've got an event listener on the current graphic
+			// if so cancel the load and remove the listeners
+			if (_graphicStatus == OPEN_RECEIVED || _graphicStatus == LOAD_INITIATED)
+			{
+				try
+				{
+					Loader(graphic).close();	// cancels in process load
+				}
+				catch (e:Error)
+				{ /* ignore */ }
+				removeDefaultLoadHandlers();
+			}
+
+			// shutdown any running movieclips - this graphic will no longer be referenced
+			// for graphics that the client has passed us - just ignore they own the responsibliity
+			if (_graphicStatus != DISPLAY_OBJECT)
+			{
+				if (okToUnloadGraphics)
+				{
+					recursiveShutDownGraphic(graphic);
+					setGraphic(null);
+				}
+				if (widthIsComputed())
+					elementWidth = 0;
+				if (heightIsComputed())
+					elementHeight = 0;
+				changeGraphicStatus(InlineGraphicElementStatus.LOAD_PENDING);
+			}
+			return true;
+		}
+		
+		// searches through the graphic and stops any playing grpahics
+		private static function recursiveShutDownGraphic(graphic:DisplayObject):void
+		{
+			if (graphic is Loader)
+				Loader(graphic).unloadAndStop();
+			else if (graphic)
+			{
+				var container:DisplayObjectContainer = graphic as DisplayObjectContainer;
+				if (container)
+				{
+					for (var idx:int = 0; idx < container.numChildren; idx++)
+					{
+						recursiveShutDownGraphic(container.getChildAt(idx));
+					}
+				}
+
+				if (graphic is MovieClip)
+					MovieClip(graphic).stop();
+			}
+		}
+		
+		/** @private */
+		tlf_internal override function getEffectiveFontSize():Number
+		{
+			if (float != Float.NONE)
+				return 0;
+			var defaultLeading:Number = super.getEffectiveFontSize();
+			return Math.max(defaultLeading, elementHeight);
+		}
+		
+		/** Returns the actual ascent of the image. Used for computing baselines when they are ascent.  @private */
+		tlf_internal function getEffectiveAscent():Number
+		{
+			if (float != Float.NONE)
+				return 0;
+				
+			return elementHeight + GraphicElement(_blockElement).elementFormat.baselineShift;
+		}
+		
+		/** Returns the typographic ascent of the image (i.e. relative to the line's Roman baseline). @private */
+		tlf_internal function getTypographicAscent(textLine:TextLine):Number
+		{
+			if (float != Float.NONE)
+				return 0;
+				
+			var effectiveHeight:Number = elementHeight;
+			
+			var dominantBaselineString:String;
+			if(this._computedFormat.dominantBaseline != FormatValue.AUTO)
+			{
+				dominantBaselineString = this._computedFormat.dominantBaseline;
+			}
+			else
+			{
+				dominantBaselineString = this.getParagraph().getEffectiveDominantBaseline();
+			}
+			
+			var graphicElement:GraphicElement = GraphicElement(_blockElement);
+			var alignmentBaseline:String = (graphicElement.elementFormat.alignmentBaseline == flash.text.engine.TextBaseline.USE_DOMINANT_BASELINE ? dominantBaselineString : graphicElement.elementFormat.alignmentBaseline);
+				
+			var top:Number=0;
+
+			// Calcluate relative to dominant baseline; remains 0 for ASCENT and IDEOGRAPHIC_TOP
+			if (dominantBaselineString == flash.text.engine.TextBaseline.IDEOGRAPHIC_CENTER)
+				top += effectiveHeight/2;
+			else if (dominantBaselineString == flash.text.engine.TextBaseline.IDEOGRAPHIC_BOTTOM || dominantBaselineString == flash.text.engine.TextBaseline.DESCENT || dominantBaselineString == flash.text.engine.TextBaseline.ROMAN)
+				top += effectiveHeight;
+				
+			// re-jig to be relative to the ROMAN baseline rather than whatever baseline is used for alignment
+			top += textLine.getBaselinePosition(flash.text.engine.TextBaseline.ROMAN) - textLine.getBaselinePosition(alignmentBaseline);
+			
+			// finally, account for baseline shift
+			top += graphicElement.elementFormat.baselineShift; 
+			
+			return top;
+		}
+		
+		/** @private */
+		 public override function shallowCopy(startPos:int = 0, endPos:int = -1):FlowElement
+		{
+			if (endPos == -1)
+				endPos = textLength;
+				
+			var retFlow:InlineGraphicElement = super.shallowCopy(startPos, endPos) as InlineGraphicElement;
+			retFlow.source = source;
+			retFlow.width = width;
+			retFlow.height = height;
+			retFlow.float = float;
+			
+			return retFlow;
+		}
+
+		/** @private */
+		override protected function get abstract():Boolean
+		{
+			return false;
+		}		
+		
+		/** @private */
+		tlf_internal override function appendElementsForDelayedUpdate(tf:TextFlow):void
+		{ 
+			if (_graphicStatus == InlineGraphicElementStatus.LOAD_PENDING || _graphicStatus == InlineGraphicElementStatus.SIZE_PENDING || !tf.flowComposer || tf.flowComposer.numControllers == 0)
+				tf.appendOneElementForUpdate(this);
+		}
+		
+		/** @private */
+		tlf_internal override function calculateStrikeThrough(tLine:TextLine, blockProgression:String, metrics:FontMetrics):Number
+		{
+			if (!this.graphic || status != InlineGraphicElementStatus.READY)
+				return super.calculateStrikeThrough(tLine,blockProgression,metrics);
+				
+			var stOffset:Number = 0;
+		//	trace(spanBounds.y);
+		//	trace(this.graphic.getBounds(tLine));
+			var myBounds:Rectangle = this.graphic.getBounds(tLine);
+			
+			if(blockProgression != BlockProgression.RL)
+			{
+				stOffset = myBounds.y + this.elementHeight/2;
+			}
+			else
+			{
+				var line:TextFlowLine = tLine.userData as TextFlowLine;
+				var elemIdx:int = this.getAbsoluteStart() - line.absoluteStart;
+				if(tLine.getAtomTextRotation(elemIdx) != TextRotation.ROTATE_0)
+					stOffset = myBounds.x + this.elementHeight/2;
+				else
+					stOffset = myBounds.x + this.elementWidth/2;
+			}
+			
+			return blockProgression == BlockProgression.TB ? stOffset : -stOffset;
+		}
+		
+		/** @private */
+		tlf_internal override function calculateUnderlineOffset(stOffset:Number, blockProgression:String, metrics:FontMetrics, tLine:TextLine):Number
+		{
+			if (!this.graphic || status != InlineGraphicElementStatus.READY)
+				return super.calculateUnderlineOffset(stOffset,blockProgression,metrics,tLine);
+				
+			var ulOffset:Number = 0;
+			if(blockProgression == BlockProgression.TB)
+				ulOffset = this.graphic.getBounds(tLine).bottom;
+			else
+				ulOffset = this.graphic.getBounds(tLine).right;
+				
+			ulOffset += metrics.underlineOffset + (metrics.underlineThickness/2);
+			
+			var para:ParagraphElement = this.getParagraph();
+			var justRule:String = para.getEffectiveJustificationRule();
+			if(justRule == JustificationRule.EAST_ASIAN)
+				ulOffset += 1;
+		
+			return ulOffset;
+		}
+		// **************************************** 
+		// Begin debug support code
+		// ****************************************	
+		
+		/** @private */
+		CONFIG::debug public override function toString():String
+		{
+			return super.toString() + " " + source;
+		}
+		
+		/** @private */
+		CONFIG::debug public override function debugCheckFlowElement(depth:int = 0, extraData:String = ""):int
+		{
+			// debugging function that asserts if the flow element tree is in an invalid state
+			
+			var rslt:int = super.debugCheckFlowElement(depth,extraData+" url:"+source);
+
+			if (_blockElement)
+				rslt += assert(textLength == GraphicElement(_blockElement).rawText.length,"image is different than its textElement");
+			rslt += assert(this != getParagraph().getLastLeaf(),"last Leaf in paragraph cannot be image");
+
+			return rslt;
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/InlineGraphicElementStatus.as b/textLayout_core/src/flashx/textLayout/elements/InlineGraphicElementStatus.as
new file mode 100755
index 0000000..f8b7a3e
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/InlineGraphicElementStatus.as
@@ -0,0 +1,78 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements
+{
+    /** The InlineGraphicElementStatus class defines a set of constants for checking the value of
+     * <code>InlineGraphicElement.status</code>.
+     *
+     * @playerversion Flash 10
+     * @playerversion AIR 1.5
+     * @langversion 3.0
+     *
+     * @see InlineGraphicElement#status
+     */
+    public final class InlineGraphicElementStatus
+    {
+    	/** Graphic element is an URL that has not been loaded.  
+    	 *
+    	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+        public static const LOAD_PENDING:String = "loadPending";
+        
+        /** Load has been initiated (but not completed) on a graphic element that is a URL.  
+         *
+         * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	 
+        public static const LOADING:String  	= "loading";
+        
+        /** 
+         * Graphic element with auto or percentage width/height has completed loading but has not been recomposed.  At the next 
+         * recompose the actual size of the graphic element is calculated. 
+         *
+         * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	 
+        public static const SIZE_PENDING:String = "sizePending";
+        
+	/** Graphic is completely loaded and properly sized. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	 
+        public static const READY:String = "ready";
+        
+        /** An error occurred during loading of a referenced graphic. 
+         *
+         * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	 
+        public static const ERROR:String = "error";
+    }
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/LinkElement.as b/textLayout_core/src/flashx/textLayout/elements/LinkElement.as
new file mode 100755
index 0000000..c7e32b7
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/LinkElement.as
@@ -0,0 +1,885 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements
+{
+	import flash.display.DisplayObject;
+	import flash.display.Sprite;
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+	import flash.events.IEventDispatcher;
+	import flash.events.MouseEvent;
+	import flash.net.*;
+	import flash.text.engine.GroupElement;
+	import flash.text.engine.TextLine;
+	import flash.text.engine.TextLineMirrorRegion;
+	import flash.text.engine.TextLineValidity;
+	import flash.ui.Mouse;
+	import flash.ui.MouseCursor;
+	
+	import flashx.textLayout.compose.IFlowComposer;
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.edit.EditingMode;
+	import flashx.textLayout.events.FlowElementMouseEvent;
+	import flashx.textLayout.events.ModelChange;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormatValueHolder;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+			
+	/** 
+	 * Dispatched when the mouse is pressed down over a link.
+	 * @eventType flashx.textLayout.events.FlowElementMouseEvent.MOUSE_DOWN
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	[Event(name="mouseDown", type="flashx.textLayout.events.FlowElementMouseEvent")]
+	
+	/** 
+	 * Dispatched when the mouse is released over a link. 
+	 * @eventType flashx.textLayout.events.FlowElementMouseEvent.MOUSE_UP
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+ 	 */
+	[Event(name="mouseUp", type="flashx.textLayout.events.FlowElementMouseEvent")]	
+	/** 
+	 * Dispatched when the mouse passes over the link. 
+	 * @eventType flashx.textLayout.events.FlowElementMouseEvent.MOUSE_MOVE
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	[Event(name="mouseMove", type="flashx.textLayout.events.FlowElementMouseEvent")]	
+	/**
+	 * Dispatched when the mouse first enters the link. 
+	 * @eventType flashx.textLayout.events.FlowElementMouseEvent.ROLL_OVER
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */			
+	[Event(name="rollOver", type="flashx.textLayout.events.FlowElementMouseEvent")]
+	/** 
+	 * Dispatched when the mouse goes out of the link. 
+	 * @eventType flashx.textLayout.events.FlowElementMouseEvent.ROLL_OUT
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	[Event(name="rollOut", type="flashx.textLayout.events.FlowElementMouseEvent")]	
+	/** 
+	 * Dispatched when the link is clicked. 
+	 * Clients may override how the link handles the event by handling it themselves, and calling preventDefault().
+	 * @eventType flashx.textLayout.events.FlowElementMouseEvent.CLICK
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */	
+	[Event(name="click", type="flashx.textLayout.events.FlowElementMouseEvent")]
+
+	/** The LinkElement class defines a link to a URI (Universal Resource Identifier), which is executed when the user clicks it.
+	 * The LinkElement class is a subclass of the SubParagraphGroupElement class and it can contain
+	 * one or more FlowElement objects, such as a SpanElement object that stores the link text. An empty
+	 * LinkElement, which does not contain a FlowElement object, is ignored.
+	 * <p>If you specify a target, it must be one of the following values:
+	 * <table class="innertable" width="100%">
+	 * <tr>
+	 *   <th>Target value</th> 
+	 *   <th>description</th>
+	 * </tr>
+	 * <tr>
+	 *   <td>_self</td>
+	 *   <td>Replaces the current HTML page. If it is in a frame or frameset, it will load within that frame. If it is
+	 *       the full browser, it opens to replace the page from which it came.</td>
+	 * </tr>
+	 * <tr>
+	 *   <td>_blank</td>
+	 *   <td>Opens a new browser name with no name.</td>
+	 * </tr>
+	 * <tr>
+	 *   <td>_parent</td>
+	 *   <td>Replaces the HTML page from which it came.</td>
+	 * </tr>
+	 * <tr>
+	 *   <td>_top</td>
+	 *   <td>Loads in the current browser, replacing anything within it, such as a frameset.</td>
+	 * </tr>
+	 * </table>
+	 * </p>
+	 *
+	 * @includeExample examples\LinkElementExample.as -noswf
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 *
+	 * @see LinkState
+	 * @see FlowElement#linkActiveFormat FlowElement.linkActiveFormat
+	 * @see FlowElement#linkHoverFormat FlowElement.linkHoverFormat
+	 * @see FlowElement#linkNormalFormat FlowElement.linkNormalFormat
+	 * @see TextFlow
+	 *
+	 */ 
+	 
+	public final class LinkElement extends SubParagraphGroupElement implements IEventDispatcher
+	{
+		private var _uriString:String;
+		private var _targetString:String;
+		private var _linkState:String;
+		private var _ignoreNextMouseOut:Boolean = false;
+		private var _mouseInLink:Boolean = false;
+		private var _isSelecting:Boolean = false;
+		private var _keyEventsAdded:Boolean = false;
+		private var eventDispatcher:EventDispatcher;
+		private var _mouseDownInLink:Boolean = false;
+
+		private static var _mouseInLinkElement:LinkElement;
+		
+		/** Constructor - creates a new LinkElement instance.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		public function LinkElement()
+		{
+			super();
+			
+           eventDispatcher = new EventDispatcher();
+            _linkState = LinkState.LINK;
+            _mouseDownInLink = false;
+            _isSelecting = false;
+        }
+        
+		/** @private */
+		override tlf_internal function createContentElement():void
+		{
+			super.createContentElement();
+			
+			var eventMirror:EventDispatcher = getEventMirror(SubParagraphGroupElement.INTERNAL_ATTACHED_LISTENERS);
+ 			eventMirror.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler, false, 0, true);
+			eventMirror.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, false, 0, true);
+			eventMirror.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler, false, 0, true);
+			eventMirror.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler, false, 0, true);
+			eventMirror.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, false, 0, true);
+		}
+		
+		/** @private */
+        tlf_internal override function get precedence():uint { return 800; }
+        
+		/**
+		* @param type The type of event.
+		* @param listener The listener function that processes the event. This function must accept an event object 
+		* as its only parameter and must return nothing, as this example shows:
+		* <p><code>function(evt:Event):void</code></p>
+		* The function can have any name.
+		* @param useCapture Determines whether the listener works in the capture phase or the target 
+		* and bubbling phases. If <code>useCapture</code> is set to <code>true</code>, the  
+		* listener processes the event only during the capture phase and not in the target or 
+		* bubbling phase. If <code>useCapture</code> is <code>false</code>, the listener processes the event only
+		* during the target or bubbling phase. To listen for the event in all three phases, call 
+		* <code>addEventListener()</code> twice, once with <code>useCapture</code> set to <code>true</code>, 
+		* then again with <code>useCapture</code> set to <code>false</code>.
+		* @param priority The priority level of the event listener. Priorities are designated by a 32-bit integer. The higher the number, the higher the priority. All listeners with priority <em>n</em> are processed before listeners of priority <em>n-1</em>. If two or more listeners share the same priority, they are processed in the order in which they were added. The default priority is 0. 
+		* @param useWeakReference Determines whether the reference to the listener is strong or weak. A strong 
+		* reference (the default) prevents your listener from being garbage-collected. A weak 
+		* reference does not. <p>Class-level member functions are not subject to garbage 
+		* collection, so you can set <code>useWeakReference</code> to <code>true</code> for 
+		* class-level member functions without subjecting them to garbage collection. If you set
+		* <code>useWeakReference</code> to <code>true</code> for a listener that is a nested inner 
+		* function, the function will be garbge-collected and no longer persistent. If you create 
+		* references to the inner function (save it in another variable) then it is not 
+		* garbage-collected and stays persistent.</p>
+		*
+		* @copy flash.events.IEventDispatcher#addEventListener()
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*/
+ 		 
+		public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false): void
+		{
+			eventDispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
+		}
+
+		/**
+		 * @copy flash.events.IEventDispatcher#dispatchEvent()
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+ 		 */
+ 		 
+		public function dispatchEvent(evt:Event):Boolean
+		{
+			return eventDispatcher.dispatchEvent(evt);
+		}
+		
+		/**
+		 * @copy flash.events.IEventDispatcher#hasEventListener()
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+ 		 */
+ 		 
+		public function hasEventListener(type:String):Boolean
+		{
+			return eventDispatcher.hasEventListener(type);
+		}
+		
+		/**
+		 *
+		 * @param type The type of event.
+		 * @param listener The listener object to remove.
+		 * @param useCapture Specifies whether the listener was registered for the capture phase or the target and bubbling phases. If the listener was registered for both the capture phase and the target and bubbling phases, two calls to <code>removeEventListener()</code> are required to remove both: one call with <code>useCapture</code> set to <code>true</code>, and another call with <code>useCapture</code> set to <code>false</code>. 
+		 *
+		 * @copy flash.events.IEventDispatcher#removeEventListener().
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+ 		 */
+ 		 
+		public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false): void
+		{
+			eventDispatcher.removeEventListener(type, listener, useCapture);
+		}
+
+		/**
+		 * @copy flash.events.IEventDispatcher#willTrigger()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+ 		 */
+ 		 
+		public function willTrigger(type:String):Boolean
+		{
+			return eventDispatcher.willTrigger(type);
+		}
+		// end of IEventDispatcher functions
+		
+		/** @private */
+		override protected function get abstract():Boolean
+		{
+			return false;
+		}		
+		
+		
+		/**
+		 * The Uniform Resource Identifier (URI) associated with the LinkElement object.  The URI can be any URI 
+		 * supported by the <code>flash.net.navigateToURL()</code> method. This property maps
+		 * to the <code>request</code> parameter for that method.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see ../../../flash/net/package.html#navigateToURL() flash.net.navigateToURL()
+		 */
+		 
+		public function get href():String
+		{
+			return _uriString;
+		}
+		 
+		public function set href(newUriString:String):void
+		{
+			_uriString = newUriString;
+			modelChanged(ModelChange.ELEMENT_MODIFIED,0,textLength);
+		}
+
+		/**
+		 * The Target value associated with the LinkElement. Possible values are "_self", "_blank",
+		 * "_parent", and "_top". This value maps to the <code>window</code> parameter of the
+		 * <code>flash.net.navigateToURL()</code> method.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see ../../../flash/net/package.html#navigateToURL() flash.net.navigateToURL()
+		 */
+		 
+		public function get target():String
+		{
+			return _targetString;
+		}
+		public function set target(newTargetString:String):void
+		{
+			_targetString = newTargetString;
+			modelChanged(ModelChange.ELEMENT_MODIFIED,0,textLength);
+		}
+
+		/**
+		 * The current state of the link.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see LinkState
+		 */
+		 
+		public function get linkState():String
+		{ return _linkState; }
+		
+		/** @private */
+		 public override function shallowCopy(startPos:int = 0, endPos:int = -1):FlowElement
+		{
+			if (endPos == -1)
+				endPos = textLength;
+				
+			var retFlow:LinkElement = super.shallowCopy(startPos, endPos) as LinkElement;
+			retFlow.href = href;
+			retFlow.target = target;
+			return retFlow;
+		}
+		
+		/** @private */
+		tlf_internal override function mergeToPreviousIfPossible():Boolean
+		{		
+			// in links the eventMirror exists.  TLF ignores that when merging.  The risk is that everything matches but the user has added a custom listener to the eventMirror.
+			var theParent:FlowGroupElement = parent;
+			if (theParent && !bindableElement)
+			{
+				var myidx:int = theParent.getChildIndex(this);
+				if (textLength == 0)
+				{
+					theParent.replaceChildren(myidx, myidx + 1, null);
+					return true;
+				}
+				
+				if (myidx != 0 && (attachedListenerStatus & SubParagraphGroupElement.CLIENT_ATTACHED_LISTENERS) == 0)
+				{
+					var sib:LinkElement = theParent.getChildAt(myidx-1) as LinkElement;
+					if (sib != null && (sib.attachedListenerStatus & SubParagraphGroupElement.CLIENT_ATTACHED_LISTENERS) == 0)
+					{
+						if ((this.href == sib.href) && (this.target == sib.target) && equalStylesForMerge(sib))
+						{
+							var curFlowElement:FlowElement = null;
+				   
+							if (numChildren > 0)
+							{
+								while (numChildren > 0)
+								{
+									curFlowElement = getChildAt(0);
+									replaceChildren(0, 1);
+									sib.replaceChildren(sib.numChildren, sib.numChildren, curFlowElement);
+								}
+							}
+							theParent.replaceChildren(myidx, myidx + 1, null);											
+							return true;
+						}
+					}
+				}
+			} 
+			return false;
+		}
+		
+		/** 
+		 * Specifies the name of the text format element of a LinkElement when the link is in the normal state.
+		 * @private
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		static tlf_internal const LINK_NORMAL_FORMAT_NAME:String = "linkNormalFormat";
+		
+		/** 
+		 * Specifies the name of the text format element of a LinkElement when the link is in the active state. 
+		 * @private
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+	 	 */
+		static tlf_internal const LINK_ACTIVE_FORMAT_NAME:String = "linkActiveFormat";
+		
+		/** Specifies the name of the text format element of a LinkElement when the cursor is hovering over the link. 
+		 * @private
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+	 	 */
+		static tlf_internal const LINK_HOVER_FORMAT_NAME:String  = "linkHoverFormat";
+		
+		private function computeLinkFormat(formatName:String):ITextLayoutFormat
+		{
+			var linkStyle:Object = getStyle(formatName);
+			if (linkStyle == null)
+			{
+				var tf:TextFlow = getTextFlow();
+				var formatStr:String = formatName.substr(1);
+				return tf == null ? null : tf.configuration["defaultL" + formatStr];
+			}
+			else if (linkStyle is ITextLayoutFormat)
+				return ITextLayoutFormat(linkStyle);
+		
+			// We need to convert the linkStyle object into a ITextLayoutFormat object		
+			var ca:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder;
+			var desc:Object = TextLayoutFormat.description;
+			for (var prop:String in desc)
+			{
+				if (linkStyle[prop] != undefined)
+					ca[prop] = linkStyle[prop];
+			}
+			return ca;
+		}
+		/** 
+		 * The state-dependent character attributes for the link.
+		 * @private
+		 */
+		
+		tlf_internal function get effectiveLinkElementTextLayoutFormat():ITextLayoutFormat
+		{	
+			var cf:ITextLayoutFormat;
+			if (_linkState == LinkState.ACTIVE)
+			{
+				cf = computeLinkFormat(LINK_ACTIVE_FORMAT_NAME);
+				if (cf)
+					return cf;
+			}
+			if (_linkState == LinkState.HOVER)
+			{
+				cf = computeLinkFormat(LINK_HOVER_FORMAT_NAME);
+				if (cf)
+					return cf;
+			}
+
+			return computeLinkFormat(LINK_NORMAL_FORMAT_NAME);
+		}
+		
+		/** @private */
+		tlf_internal override function get formatForCascade():ITextLayoutFormat
+		{
+			var superFormat:ITextLayoutFormat = format;
+			var effectiveFormat:ITextLayoutFormat = effectiveLinkElementTextLayoutFormat;
+			if (effectiveFormat || superFormat)
+			{
+				if (effectiveFormat && superFormat)
+				{
+					var resultingTextLayoutFormat:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder(effectiveFormat);
+					if (superFormat)
+						resultingTextLayoutFormat.concatInheritOnly(superFormat);
+					return resultingTextLayoutFormat;
+				}
+				return superFormat ? superFormat : effectiveFormat;
+			}
+			return null;
+		}
+		
+		/** @private */
+		CONFIG::debug tlf_internal override function setParentAndRelativeStart(newParent:FlowGroupElement,newStart:int):void
+		{
+			
+			if (groupElement)
+			{
+				var groupTextLength:int = groupElement.rawText ? groupElement.rawText.length : null;
+				assert(groupTextLength == this.textLength, "LinkElement - gc = " + this.groupElement.rawText + " this.textLength = " + this.textLength);
+			}
+			
+			super.setParentAndRelativeStart(newParent,newStart);
+				
+		}
+		
+		private function redrawLink(ignoreNextMouseOut:Boolean=true):void
+		{
+			parent.formatChanged(true);
+			var tf:TextFlow = getTextFlow();
+			if (tf && tf.flowComposer)
+			{
+				tf.flowComposer.updateAllControllers();
+				if (_linkState != LinkState.HOVER) 
+					_ignoreNextMouseOut = ignoreNextMouseOut;
+			}
+		}
+		
+		private function setToState(linkState:String, ignoreNextMouseOut:Boolean=true):void
+		{
+			if (_linkState != linkState)
+			{
+				var oldCharAttrs:ITextLayoutFormat = effectiveLinkElementTextLayoutFormat;
+				_linkState = linkState;
+				var newCharAttrs:ITextLayoutFormat = effectiveLinkElementTextLayoutFormat;
+				if (!(TextLayoutFormat.isEqual(oldCharAttrs, newCharAttrs)))
+				{
+					redrawLink(ignoreNextMouseOut);
+				}		
+			}
+		}				
+		
+		private function setHandCursor(state:Boolean=true):void
+		{
+			var tf:TextFlow = getTextFlow();
+			if (tf != null && tf.flowComposer && tf.flowComposer.numControllers)
+			{
+				doToAllControllers(setContainerHandCursor);
+				if (state)
+					Mouse.cursor = MouseCursor.AUTO;
+				else
+				{
+					var wmode:String = tf.computedFormat.blockProgression;									
+					if (tf.interactionManager && (wmode != BlockProgression.RL))
+						Mouse.cursor = MouseCursor.IBEAM;
+					else
+						Mouse.cursor = MouseCursor.AUTO;
+				}
+			}
+			function setContainerHandCursor(controller:ContainerController):void
+			{
+				var container:Sprite = controller.container as Sprite;
+				if (container)
+				{
+					container.buttonMode = state;
+					container.useHandCursor = state;
+				}
+			}
+		
+		}
+		
+		private function handleEvent(event:FlowElementMouseEvent):Boolean
+		{
+			eventDispatcher.dispatchEvent(event);
+			if (event.isDefaultPrevented())
+				return true;
+			var textFlow:TextFlow = getTextFlow();
+			if (textFlow)
+			{
+				textFlow.dispatchEvent(event);
+				if (event.isDefaultPrevented())
+					return true;
+			}
+			return false;
+		}
+		
+		private function mouseDownHandler(evt:MouseEvent):void
+		{
+			CONFIG::debug { assert(getTextFlow() != null,"Invalid TextFlow"); }
+
+			if ((evt.ctrlKey) || (getTextFlow().interactionManager == null) || (getTextFlow().interactionManager.editingMode == EditingMode.READ_SELECT))
+			{									
+				if (_mouseInLink)
+				{
+					_mouseDownInLink = true;					
+					var event:FlowElementMouseEvent = new FlowElementMouseEvent("mouseDown", false, true, this, evt);
+					if (handleEvent(event)) return;
+					setHandCursor(true);
+					setToState(LinkState.ACTIVE, false);
+				}
+				evt.stopImmediatePropagation();								
+			}
+			else
+			{
+				setHandCursor(false);
+				setToState(LinkState.LINK);
+			}
+		}
+
+		private function mouseMoveHandler(evt:MouseEvent):void
+		{
+			CONFIG::debug { assert(getTextFlow() != null,"Invalid TextFlow"); }
+			if (_isSelecting) return;
+			if ((evt.ctrlKey) || (getTextFlow().interactionManager == null) || (getTextFlow().interactionManager.editingMode == EditingMode.READ_SELECT))
+			{
+				if (_mouseInLink)
+				{
+					var event:FlowElementMouseEvent = new FlowElementMouseEvent("mouseMove", false, true, this, evt);
+					if (handleEvent(event)) return;				
+					setHandCursor(true);
+					if (evt.buttonDown)
+					{
+						setToState(LinkState.ACTIVE, false);
+					}
+					else
+					{
+						setToState(LinkState.HOVER);
+					}
+				}
+			}
+			else
+			{
+				_mouseInLink = true;
+				setHandCursor(false);
+				setToState(LinkState.LINK);
+			}
+		}
+				
+		private function mouseOutHandler(evt:MouseEvent):void
+		{
+			if (!_ignoreNextMouseOut)
+			{
+				_mouseInLink = false;
+				LinkElement.removeLinkFromMouseInArray(this);							
+				_isSelecting = false;
+				_mouseDownInLink = false;
+				var event:FlowElementMouseEvent = new FlowElementMouseEvent(MouseEvent.ROLL_OUT, false, true, this, evt);
+				if (handleEvent(event)) return;				
+				setHandCursor(false);
+				setToState(LinkState.LINK);
+			}
+			_ignoreNextMouseOut = false;		
+		}
+		
+		private static function addLinkToMouseInArray(linkEl:LinkElement):void
+		{
+			CONFIG::debug { assert(_mouseInLinkElement == null, "Multiple links active"); }
+			_mouseInLinkElement = linkEl;
+			attachContainerEventHandlers(linkEl);
+		}
+		
+		private static function removeLinkFromMouseInArray(linkEl:LinkElement):void
+		{
+			_mouseInLinkElement = null;
+			detachContainerEventHandlers(linkEl);
+		}
+		
+		/** @private */
+		// This function is a workaround for Flash Player bug in Astro where mouseOut event is not sent from eventMirror if mouse
+		// has left the TextLine at the next sample point (i.e., mouse leaves TextLine rapidly).
+		private static function stageMouseMoveHandler(evt:MouseEvent):void
+		{
+			CONFIG::debug { assert(_mouseInLinkElement != null, "containerMouseMoveHandler shouldn't be active listener now"); }
+
+			 // Check to see if we are still in the link. We could be over an InlineGraphicElement, which could be part of the link.
+			 // In that case, we don't want to turn off the link.
+			var target:DisplayObject = evt.target as DisplayObject;
+			while (target && !(target is TextLine))
+				target = target.parent;
+			 
+			if (target)
+			{
+				var textLine:TextLine = target as TextLine;
+				if (textLine.validity != TextLineValidity.INVALID)
+				{
+					var mirrorRegions:Vector.<TextLineMirrorRegion> = textLine.mirrorRegions;
+					var found:Boolean = false;
+					if (mirrorRegions)
+					{
+						for (var i:int = 0; i < mirrorRegions.length; i++)
+						{
+							if (_mouseInLinkElement.groupElement == (mirrorRegions[i].element as GroupElement))
+								found = true;
+						}
+					}
+					if (!found)
+						target = null;
+				}
+			}
+			if (!target)		
+			{
+				LinkElement.setLinksToDefaultState(evt);
+				Mouse.cursor = MouseCursor.AUTO;
+			}
+		}
+		
+		/** @private */
+		private static function setLinksToDefaultState(evt:MouseEvent, linkEl:LinkElement = null):void
+		{
+			//FIXME - HBS.  Workaround for bug 1918187.  The problem is that the mouseOut event isn't
+			//always sent to the link when the mouse rolls over the link very quickly. So, we simulate
+			//the mouseOut when the next mouseMove over something other than a link is sent.  The problem
+			//is probably that the mouseOut is being sent before the LinkElement is fully constructed.
+			if (_mouseInLinkElement && (linkEl != _mouseInLinkElement))
+			{
+				var linkElement:LinkElement = _mouseInLinkElement;
+				removeLinkFromMouseInArray(linkElement);
+				linkElement._mouseInLink = false;
+				linkElement._isSelecting = false;
+				linkElement._mouseDownInLink = false;
+				var mouseMoveEvt:MouseEvent = new MouseEvent(MouseEvent.MOUSE_OUT, evt.bubbles, evt.cancelable, evt.localX, evt.localY, evt.relatedObject, evt.ctrlKey, evt.altKey, evt.shiftKey, evt.buttonDown, evt.delta); 
+				var event:FlowElementMouseEvent = new FlowElementMouseEvent(MouseEvent.ROLL_OUT, false, true, linkElement, mouseMoveEvt);
+				if (linkElement.handleEvent(event)) return;				
+				linkElement.setHandCursor(false);
+				linkElement.setToState(LinkState.LINK);
+				linkElement._ignoreNextMouseOut = false;
+			}
+		}
+		
+		private function doToAllControllers(functionToCall:Function):void
+		{
+			var textFlow:TextFlow = getTextFlow();
+			var flowComposer:IFlowComposer = textFlow.flowComposer;
+			var start:int = getAbsoluteStart();
+			var controllerIndex:int = flowComposer.findControllerIndexAtPosition(start);
+			var lastController:int = flowComposer.findControllerIndexAtPosition(start + textLength - 1);
+			while (controllerIndex <= lastController)
+			{
+				functionToCall(flowComposer.getControllerAt(controllerIndex));
+				controllerIndex++;
+			}
+		}
+		
+		private static function findRootForEventHandlers(linkElement:LinkElement):DisplayObject
+		{
+			var textFlow:TextFlow = linkElement.getTextFlow();
+			if (textFlow)
+			{
+				var flowComposer:IFlowComposer = textFlow.flowComposer;
+				if (flowComposer && flowComposer.numControllers != 0)
+					return flowComposer.getControllerAt(0).getContainerRoot();
+			}
+			return null;
+		}
+				
+		private static function attachContainerEventHandlers(linkElement:LinkElement):void
+		{
+			var root:DisplayObject = findRootForEventHandlers(linkElement);
+			if (root)
+				root.addEventListener(MouseEvent.MOUSE_MOVE, stageMouseMoveHandler, false, 0, true);
+		}
+
+		private static function detachContainerEventHandlers(linkElement:LinkElement):void
+		{
+			var root:DisplayObject = findRootForEventHandlers(linkElement);
+			if (root)
+				root.removeEventListener(MouseEvent.MOUSE_MOVE, stageMouseMoveHandler);
+		}
+		
+		private function mouseOverHandler(evt:MouseEvent):void
+		{
+			if (_mouseInLink) return;
+			CONFIG::debug { assert(getTextFlow() != null,"Invalid TextFlow"); }									
+			if (evt.buttonDown) _isSelecting = true;
+			if (_isSelecting) return;
+			_mouseInLink = true;
+			LinkElement.setLinksToDefaultState(evt, this);			
+			LinkElement.addLinkToMouseInArray(this);
+			
+			if ((evt.ctrlKey) || (getTextFlow().interactionManager == null) || (getTextFlow().interactionManager.editingMode == EditingMode.READ_SELECT))
+			{
+				var event:FlowElementMouseEvent = new FlowElementMouseEvent(MouseEvent.ROLL_OVER, false, true, this, evt);
+				if (handleEvent(event)) return;				
+				setHandCursor(true);
+				if (evt.buttonDown)
+				{
+					setToState(LinkState.ACTIVE, false);
+				}
+				else
+				{
+					setToState(LinkState.HOVER, false);
+				}
+			}
+			else
+			{
+				setHandCursor(false);
+				setToState(LinkState.LINK);
+			}
+		}
+		
+		private function mouseUpHandler(evt:MouseEvent):void
+		{
+			CONFIG::debug { assert(getTextFlow() != null,"Invalid TextFlow"); }
+			if (_isSelecting) {_isSelecting = false; return; }												
+			if (_mouseInLink && ((evt.ctrlKey) || (getTextFlow().interactionManager == null) || (getTextFlow().interactionManager.editingMode == EditingMode.READ_SELECT)))
+			{
+				var event:FlowElementMouseEvent = new FlowElementMouseEvent("mouseUp", false, true, this, evt);
+				if (!handleEvent(event))				
+				{
+					setHandCursor(true);				
+					setToState(LinkState.HOVER);
+					evt.stopImmediatePropagation();
+				}
+				if (_mouseDownInLink) mouseClickHandler(evt);
+			} else {
+				setHandCursor(false);
+				setToState(LinkState.LINK);
+			}
+			_mouseDownInLink = false;
+		}
+		
+		private function mouseClickHandler(evt:MouseEvent):void
+		{
+			CONFIG::debug { assert(getTextFlow() != null,"Invalid TextFlow"); }
+			if (_isSelecting) return;
+			
+			if (((evt.ctrlKey) || (getTextFlow().interactionManager == null) || (getTextFlow().interactionManager.editingMode == EditingMode.READ_SELECT)))
+			{															
+				if (_mouseInLink)
+				{
+					var event:FlowElementMouseEvent = new FlowElementMouseEvent("click", false, true, this, evt);
+					if (handleEvent(event)) return;
+				
+					if (_uriString != null)
+					{
+						if ((_uriString.length > 6) && (_uriString.substr(0, 6) == "event:"))
+						{
+							event = new FlowElementMouseEvent(_uriString.substring(6, _uriString.length), false, true, this, evt);
+							handleEvent(event);
+						} else 
+						{
+		        			var u:URLRequest = new URLRequest(encodeURI(_uriString));
+		        			flash.net.navigateToURL(u, target);
+		   				}
+					}
+				}
+				evt.stopImmediatePropagation();		
+			}			
+		}
+		
+		/** @private */
+		tlf_internal override function acceptTextBefore():Boolean 
+		{ 
+			return false; 
+		}
+		
+		/** @private */
+		tlf_internal override function acceptTextAfter():Boolean
+		{
+			return false;
+		}
+		
+		/** @private */
+		/*public override function replaceChildren(beginChildIndex:int,endChildIndex:int,...rest):void
+		{
+			var applyParams:Array = [beginChildIndex, endChildIndex];
+			super.replaceChildren.apply(this, applyParams.concat(rest));
+			
+			//make sure that all elements of Link recalculate their attributes when
+			//something is added to the link.
+			
+			var len:int = numChildren;
+			var i:int = 0;
+			var fl:FlowElement;
+			while (i < len)
+			{
+				fl = getChildAtIndex(i);
+				fl.formatChanged(true);
+				i++;
+			}
+		}*/
+					
+		/** @private This is done so that the TextContainerManager can discover LinkElements in a TextFlow. */
+		tlf_internal override function appendElementsForDelayedUpdate(tf:TextFlow):void
+		{ 
+			tf.appendOneElementForUpdate(this);
+			super.appendElementsForDelayedUpdate(tf);
+		}
+		
+		/** @private This API supports the inputmanager */
+		tlf_internal override function updateForMustUseComposer(textFlow:TextFlow):Boolean
+		{ return true; }
+
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/LinkState.as b/textLayout_core/src/flashx/textLayout/elements/LinkState.as
new file mode 100755
index 0000000..ee2c80d
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/LinkState.as
@@ -0,0 +1,66 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements
+{
+	/**
+	 *  The LinkState class defines a set of constants for the <code>linkState</code> property
+	 *  of the LinkElement class. 
+	 *
+	 * @includeExample examples\LinkStateExample.as -noswf
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 *
+	 *  @see LinkElement#linkState
+	 */
+	 
+ 	public final class LinkState {
+ 	
+	/** 
+	 * Value for the normal, default link state. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	 
+    	public static const LINK:String = "link";
+    
+	/** 
+	 * Value for the hover state, which occurs when you drag the mouse over a link. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */ 
+	 
+    	public static const HOVER:String = "hover";
+    
+	/** 
+	 * Value for the active state, which occurs when you hold the mouse down over a link. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	 
+    	public static const ACTIVE:String = "active";
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/OverflowPolicy.as b/textLayout_core/src/flashx/textLayout/elements/OverflowPolicy.as
new file mode 100755
index 0000000..e082185
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/OverflowPolicy.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 flashx.textLayout.elements
+{
+	/**
+	 *  The OverflowPolicy class defines a set of constants for the <code>overflowPolicy</code> property
+	 *  of the IConfiguration class. This defines how the composer will treat lines at the end of the composition area.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	 
+ 	public final class OverflowPolicy {
+ 	
+	/** 
+	 * Fit the line in the composition area if any part of the line fits.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	 
+     public static const FIT_ANY:String = "fitAny";
+    
+	/*
+	 * Fit the line in the composition area if the area from the top to the baseline fits.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	 
+ //    public static const FIT_BASELINE:String = "fitAny";
+    
+	/** 
+	 * Fit the line in the composition area if the area from the top to the baseline fits.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	 
+     public static const FIT_DESCENDERS:String = "fitDescenders";
+    
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/ParagraphElement.as b/textLayout_core/src/flashx/textLayout/elements/ParagraphElement.as
new file mode 100755
index 0000000..661f583
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/ParagraphElement.as
@@ -0,0 +1,837 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements 
+{
+	import flash.display.Shape;
+	import flash.text.engine.ContentElement;
+	import flash.text.engine.EastAsianJustifier;
+	import flash.text.engine.GroupElement;
+	import flash.text.engine.LineJustification;
+	import flash.text.engine.SpaceJustifier;
+	import flash.text.engine.TabStop;
+	import flash.text.engine.TextBaseline;
+	import flash.text.engine.TextBlock;
+	import flash.text.engine.TextLine;
+	import flash.text.engine.TextLineValidity;
+	import flash.text.engine.TextRotation;
+	import flash.utils.getQualifiedClassName;
+	
+	import flashx.textLayout.compose.TextFlowLine;
+	import flashx.textLayout.debug.Debugging;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.formats.Direction;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.JustificationRule;
+	import flashx.textLayout.formats.LeadingModel;
+	import flashx.textLayout.formats.LineBreak;
+	import flashx.textLayout.formats.TabStopFormat;
+	import flashx.textLayout.formats.TextAlign;
+	import flashx.textLayout.formats.TextJustify;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.tlf_internal;
+	import flashx.textLayout.utils.CharacterUtil;
+	import flashx.textLayout.utils.LocaleUtil;
+	
+	use namespace tlf_internal;
+
+	/** 
+	 * The ParagraphElement class represents a paragraph in the text flow hierarchy. Its parent
+	 * is a ParagraphFormattedElement, and its children can include spans (SpanElement), images 
+	 * (inLineGraphicElement), links (LinkElement) and TCY (Tatechuuyoko - ta-tae-chu-yo-ko) elements (TCYElement). The 
+	 * paragraph text is stored in one or more SpanElement objects, which define ranges of text that share the same attributes. 
+	 * A TCYElement object defines a small run of Japanese text that runs perpendicular to the line, as in a horizontal run of text in a 
+	 * vertical line. A TCYElement can also contain multiple spans.
+	 *
+	 * @includeExample examples\ParagraphElementExample.as -noswf
+	 * @includeExample examples\ParagraphElementExample2.as -noswf
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 * 
+	 * @see InlineGraphicElement
+	 * @see LinkElement
+	 * @see SpanElement
+	 * @see TCYElement
+	 * @see TextFlow
+	 */
+	 
+	public final class ParagraphElement extends ParagraphFormattedElement
+	{
+		private var _textBlock:TextBlock;
+		
+		/** Constructor - represents a paragraph in a text flow. 
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*/
+	 	
+		public function ParagraphElement()
+		{
+			super();
+		}
+		
+		/** @private */
+		public override function shallowCopy(startPos:int = 0, endPos:int = -1):FlowElement
+		{
+			var retFlow:ParagraphElement = super.shallowCopy(startPos, endPos) as ParagraphElement;
+			if (_textBlock)
+				retFlow.createTextBlock();
+			return retFlow;
+		}
+		/** @private */
+		tlf_internal function createTextBlock():void
+		{
+			CONFIG::debug { assert(_textBlock == null,"createTextBlock called when there is already a textblock"); }
+			_textBlock = new TextBlock();
+			CONFIG::debug { Debugging.traceFTECall(_textBlock,null,"new TextBlock()"); }
+			for (var i:int = 0; i < numChildren; i++)
+			{
+				var child:FlowElement = getChildAt(i);
+				child.createContentElement();
+			}
+			updateTextBlock();
+		}
+		
+		/** @private */
+		
+		tlf_internal function releaseTextBlock():void
+		{
+			if (!_textBlock)
+				return;
+				
+			// Preflight children to see if any are in use
+			for (var i:int = 0; i < numChildren; i++)
+			{
+				var child:FlowElement = getChildAt(i);
+				if (!child.canReleaseContentElement())
+					return;
+			}
+
+			if (_textBlock.firstLine)	// A TextBlock may have no firstLine if it has previously been released.
+			{
+				for (var textLineTest:TextLine = _textBlock.firstLine; textLineTest != null; textLineTest = textLineTest.nextLine)
+				{	
+					if(textLineTest.numChildren != 0)
+					{	
+						//if the number of adornments added does not match the number of children on the textLine
+						//then a third party has added adornments.  Don't recycle the line or the adornment will be
+						//lost.
+						var tfl:TextFlowLine = textLineTest.userData as TextFlowLine;
+						if(tfl.adornCount != textLineTest.numChildren)
+							return;
+					}
+				}
+				
+				for (var textLine:TextLine = _textBlock.firstLine; textLine != null; textLine = textLine.nextLine)
+					TextFlowLine(textLine.userData).markReleased();
+				CONFIG::debug { Debugging.traceFTECall(null,_textBlock,"releaseLines",_textBlock.firstLine, _textBlock.lastLine); }				
+				_textBlock.releaseLines(_textBlock.firstLine, _textBlock.lastLine);	
+			}	
+
+			_textBlock.content = null;
+			for (i = 0; i < numChildren; i++)
+			{
+				child = getChildAt(i);
+				child.releaseContentElement();
+			}
+			_textBlock = null;
+			
+		}
+		
+		/** TextBlock where the text of the paragraph is kept. @private */
+		tlf_internal function getTextBlock():TextBlock
+		{ 
+			if (!_textBlock)
+				createTextBlock();
+			return _textBlock; 
+		}
+		
+		/** @private */
+		tlf_internal function releaseLineCreationData():void
+		{
+			CONFIG::debug { assert(Configuration.playerEnablesArgoFeatures,"bad call to releaseLineCreationData"); }
+			if (_textBlock)
+				_textBlock["releaseLineCreationData"]();
+		}
+		
+		/** @private */
+		tlf_internal override function createContentAsGroup():GroupElement
+		{ 			
+			var group:GroupElement = _textBlock.content as GroupElement;
+			if (!group)
+			{
+				var originalContent:ContentElement = _textBlock.content;
+				
+				group = new GroupElement();
+				CONFIG::debug { Debugging.traceFTECall(group,null,"new GroupElement()"); }
+				_textBlock.content = group;
+				CONFIG::debug { Debugging.traceFTEAssign(_textBlock,"content",group); }
+
+				if (originalContent)
+				{
+					var gc:Vector.<ContentElement> = new Vector.<ContentElement>();
+					CONFIG::debug { Debugging.traceFTECall(gc,null,"new Vector.<ContentElement>()") }
+					gc.push(originalContent);
+					CONFIG::debug { Debugging.traceFTECall(null,gc,"push",originalContent); }
+					group.replaceElements(0,0,gc);
+					CONFIG::debug { Debugging.traceFTECall(null,group,"replaceElements",0,0,gc); }
+				}
+				
+				// Now we've got to force damage the entire paragraph, because we restructured it in FTE.
+				if (_textBlock.firstLine && textLength)
+				{
+					var textFlow:TextFlow = getTextFlow();
+					if (textFlow)
+						textFlow.damage(getAbsoluteStart(), textLength, TextLineValidity.INVALID, false);
+				}
+			}
+			return group;
+ 		}
+ 		
+ 		/** @private */
+		tlf_internal override function removeBlockElement(child:FlowElement, block:ContentElement):void
+		{
+			if (numChildren == 1)
+			{
+				if (block is GroupElement)
+				{
+					// see insertBlockElement
+					CONFIG::debug { assert(_textBlock.content != block,"removeBlockElement: bad call to removeBlockElement"); }
+					CONFIG::debug { assert(_textBlock.content is GroupElement,"removeBlockElement: bad content"); }
+					CONFIG::debug { assert(GroupElement(_textBlock.content).elementCount == 1,"removeBlockElement: bad element count"); }
+					CONFIG::debug { assert(GroupElement(_textBlock.content).getElementAt(0) == block,"removeBlockElement: bad group content"); }
+					GroupElement(_textBlock.content).replaceElements(0,1,null);
+					CONFIG::debug { Debugging.traceFTECall(null,_textBlock.content,"replaceElements",0,1,null); }
+				}
+				_textBlock.content = null;
+				CONFIG::debug { Debugging.traceFTEAssign(_textBlock,"content",null); }
+			}
+			else
+			{
+				var idx:int = this.getChildIndex(child);
+				var group:GroupElement = GroupElement(_textBlock.content);
+				CONFIG::debug { assert(group.elementCount == numChildren,"Mismatched group and elementCount"); }
+				group.replaceElements(idx,idx+1,null);
+				CONFIG::debug { Debugging.traceFTECall(null,group,"replaceElements",idx,idx+1,null); }
+				if (numChildren == 2)	// its going to be one so ungroup
+				{
+					// ungroup - need to take it out first as inlinelements can only have one parent
+					var elem:ContentElement = group.getElementAt(0);
+					CONFIG::debug { Debugging.traceFTECall(elem,group,"getElementAt",0); }
+					if (!(elem is GroupElement))
+					{
+						group.replaceElements(0,1,null);
+						CONFIG::debug { Debugging.traceFTECall(null,group,"replaceElements",0,1,null); }
+						_textBlock.content = elem;
+						CONFIG::debug { Debugging.traceFTEAssign(_textBlock,"content",elem); }
+					}
+				}
+			}
+		}
+		
+		
+		/** @private */
+		tlf_internal override function hasBlockElement():Boolean
+		{
+			return _textBlock != null;
+		}
+		
+		/** @private */
+		override tlf_internal function createContentElement():void
+		{
+			createTextBlock();
+		}
+		
+		/** @private */
+		tlf_internal override function insertBlockElement(child:FlowElement, block:ContentElement):void
+		{
+			if (_textBlock == null)
+			{
+				child.releaseContentElement();
+				createTextBlock();	// does the whole tree
+				return;
+			}
+			var gc:Vector.<ContentElement>;	// scratch var
+			var group:GroupElement;			// scratch
+			if (numChildren == 1)
+			{
+				if (block is GroupElement)
+				{
+					// this case forces the Group to be in a Group so that following FlowLeafElements aren't in a SubParagraphGroupElement's group
+					gc = new Vector.<ContentElement>();
+					CONFIG::debug { Debugging.traceFTECall(gc,null,"new Vector.<ContentElement>()") }
+					gc.push(block);
+					CONFIG::debug { Debugging.traceFTECall(null,gc,"push",block); }
+					group = new GroupElement(gc);
+					CONFIG::debug { Debugging.traceFTECall(group,null,"new GroupElement",gc); }
+					_textBlock.content = group;
+					CONFIG::debug { Debugging.traceFTEAssign(_textBlock,"content",group); }
+				}
+				else
+				{
+					_textBlock.content = block;
+					CONFIG::debug { Debugging.traceFTEAssign(_textBlock,"content",block);  }
+				}
+			}
+			else
+			{
+				group = createContentAsGroup();
+				var idx:int = this.getChildIndex(child);
+				gc = new Vector.<ContentElement>();
+				CONFIG::debug { Debugging.traceFTECall(gc,null,"new Vector.<ContentElement>") }
+				gc.push(block);
+				CONFIG::debug { Debugging.traceFTECall(null,gc,"push",block); }
+				group.replaceElements(idx,idx,gc);
+				CONFIG::debug { Debugging.traceFTECall(null,group,"replaceElements",idx,idx,gc); }
+			}
+		}
+		
+		/** @private */
+		override protected function get abstract():Boolean
+		{
+			return false;
+		}		
+
+		/** @private */
+		public override function replaceChildren(beginChildIndex:int,endChildIndex:int,...rest):void
+		{
+			// are we replacing the last element?
+			var oldLastLeaf:FlowLeafElement = getLastLeaf();
+			
+			CONFIG::debug 
+			{ 
+				if (oldLastLeaf && (oldLastLeaf is SpanElement))
+					SpanElement(oldLastLeaf).verifyParagraphTerminator();
+
+			}
+			var applyParams:Array;
+			
+			// makes a measurable difference - rest.length zero and one are the common cases
+			if (rest.length == 1)
+				applyParams = [beginChildIndex, endChildIndex, rest[0]];
+			else
+			{
+				applyParams = [beginChildIndex, endChildIndex];
+				if (rest.length != 0)
+					applyParams = applyParams.concat.apply(applyParams, rest);
+			}
+			super.replaceChildren.apply(this, applyParams);
+			
+			ensureTerminatorAfterReplace(oldLastLeaf);
+		}
+		/** @private */
+		tlf_internal function ensureTerminatorAfterReplace(oldLastLeaf:FlowLeafElement):void
+		{
+			var newLastLeaf:FlowLeafElement = getLastLeaf();
+			if (oldLastLeaf != newLastLeaf)
+			{
+				if (oldLastLeaf && oldLastLeaf is SpanElement)
+					oldLastLeaf.removeParaTerminator();
+				if (newLastLeaf)
+				{
+					if (newLastLeaf is SpanElement)
+						newLastLeaf.addParaTerminator();
+					else
+					{
+						var s:SpanElement = new SpanElement();
+						super.replaceChildren(numChildren,numChildren,s);
+						s.format = newLastLeaf.format;
+						s.addParaTerminator();
+					}
+				}
+			}
+		}
+
+		[RichTextContent]
+		/** @private NOTE: all FlowElement implementers and overrides of mxmlChildren must specify [RichTextContent] metadata */
+		public override function set mxmlChildren(array:Array):void
+		{
+			// remove all existing children
+			replaceChildren(0,numChildren);
+			
+			for each (var child:Object in array)
+			{
+				if (child is FlowElement)
+				{
+					if ((child is SpanElement) || (child is SubParagraphGroupElement))
+						child.bindableElement = true;
+					
+					// Note: calling super.replaceChildren because we don't want to transfer para terminator each time
+					super.replaceChildren(numChildren, numChildren, child as FlowElement); 
+				}
+				else if (child is String)
+				{
+					var s:SpanElement = new SpanElement();
+					s.text = String(child);
+					s.bindableElement = true;
+					
+					// Note: calling super.replaceChildren because we don't want to transfer para terminator each time
+					super.replaceChildren(numChildren, numChildren, s);
+				}
+				else if (child != null)
+					throw new TypeError(GlobalSettings.resourceStringFunction("badMXMLChildrenArgument",[ getQualifiedClassName(child) ]));
+			}
+			
+			// Now ensure para terminator
+			ensureTerminatorAfterReplace(null);
+		}
+		
+		/** @private
+ 		 */
+		public override function getText(relativeStart:int=0, relativeEnd:int=-1, paragraphSeparator:String="\n"):String
+		{
+			// Optimization for getting text of the entire paragraph
+			if (relativeStart == 0 && (relativeEnd == -1 || relativeEnd >= textLength-1) && _textBlock)
+			{
+				if (_textBlock.content)
+				{
+					var text:String = _textBlock.content.rawText;
+					return text.substring(0, text.length - 1);
+				}
+				return "";		// content is null
+			}
+			return super.getText(relativeStart, relativeEnd, paragraphSeparator);
+		}
+		
+		/** Returns the paragraph that follows this one, or null if there are no more paragraphs. 
+		 *
+		 * @return the next paragraph or null if there are no more paragraphs.
+		 *
+		 * @includeExample examples\ParagraphElement_getNextParagraph.as -noswf
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 * 
+	 	 * @see #getPreviousParagraph()
+	 	 */
+		public function getNextParagraph():ParagraphElement
+		{
+			var nextLeaf:FlowLeafElement = getLastLeaf().getNextLeaf();
+			return nextLeaf ? nextLeaf.getParagraph() : null;
+		}
+	
+		/** Returns the paragraph that precedes this one, or null, if this paragraph is the first one 
+		 * in the TextFlow. 
+		 *
+		 * @includeExample examples\ParagraphElement_getPreviousParagraph.as -noswf
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see #getNextParagraph()
+	 	 */
+		public function getPreviousParagraph():ParagraphElement
+		{
+			var previousLeaf:FlowLeafElement = getFirstLeaf().getPreviousLeaf();
+			return previousLeaf ? previousLeaf.getParagraph() : null;
+		}
+	
+		/** 
+		 * Scans backward from the supplied position to find the location
+		 * in the text of the previous atom and returns the index. The term atom refers to 
+		 * both graphic elements and characters (including groups of combining characters), the 
+		 * indivisible entities that make up a text line.
+		 * 
+		 * @param relativePosition  position in the text to start from, counting from 0
+		 * @return index in the text of the previous cluster
+		 *
+		 * @includeExample examples\ParagraphElement_findPreviousAtomBoundary.as -noswf
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see flash.text.engine.TextLine
+		 */
+		 
+		public function findPreviousAtomBoundary(relativePosition:int):int
+		{
+			return getTextBlock().findPreviousAtomBoundary(relativePosition);
+		}
+
+		/** 
+		 * Scans ahead from the supplied position to find the location
+		 * in the text of the next atom and returns the index. The term atom refers to 
+		 * both graphic elements and characters (including groups of combining characters), the 
+		 * indivisible entities that make up a text line.
+		 * 
+		 * @param relativePosition  position in the text to start from, counting from 0
+		 * @return index in the text of the following atom
+		 *
+		 * @includeExample examples\ParagraphElement_findNextAtomBoundary.as -noswf
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see flash.text.engine.TextLine
+		 */
+		 
+		public function findNextAtomBoundary(relativePosition:int):int
+		{
+			return getTextBlock().findNextAtomBoundary(relativePosition);
+		}
+		
+		/** @private */
+		public override function getCharAtPosition(relativePosition:int):String
+		{
+			return getTextBlock().content.rawText.charAt(relativePosition);
+		} 
+
+		/** 
+		 * Returns the index of the previous word boundary in the text.
+		 * 
+		 * <p>Scans backward from the supplied position to find the previous position
+		 * in the text that starts or ends a word. </p>
+		 * 
+		 * @param relativePosition  position in the text to start from, counting from 0
+		 * @return index in the text of the previous word boundary
+		 *
+		 * @includeExample examples\ParagraphElement_findPreviousWordBoundary.as -noswf
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function findPreviousWordBoundary(relativePosition:int):int
+		{	
+			if (relativePosition == 0)
+				return 0;
+			var prevCharCode:int = getCharCodeAtPosition(relativePosition - 1);
+			if (CharacterUtil.isWhitespace(prevCharCode))
+			{				
+				while (CharacterUtil.isWhitespace(prevCharCode) && ((relativePosition - 1) > 0))
+				{
+					relativePosition--;
+					prevCharCode = getCharCodeAtPosition(relativePosition - 1);
+				}
+				return relativePosition;
+			}
+			return getTextBlock().findPreviousWordBoundary(relativePosition);
+		}
+
+		/** 
+		 * Returns the index of the next word boundary in the text.
+		 * 
+		 * <p>Scans ahead from the supplied position to find the next position
+		 * in the text that starts or ends a word. </p>
+		 * 
+		 * @param relativePosition  position in the text to start from, counting from 0
+		 * @return  index in the text of the next word boundary
+		 * 
+		 * @includeExample examples\ParagraphElement_findNextWordBoundary.as -noswf
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		 
+		public function findNextWordBoundary(relativePosition:int):int
+		{	
+			if (relativePosition == textLength) 
+				return textLength;
+			var curCharCode:int = getCharCodeAtPosition(relativePosition);
+			if (CharacterUtil.isWhitespace(curCharCode))
+			{
+				while (CharacterUtil.isWhitespace(curCharCode) && relativePosition < (textLength - 1))
+				{
+					relativePosition++;
+					curCharCode = getCharCodeAtPosition(relativePosition);
+				}
+				return relativePosition;
+			}
+			return getTextBlock().findNextWordBoundary(relativePosition);
+		}
+		
+		private static var _defaultTabStops:Vector.<TabStop>;
+		private const defaultTabWidth:int = 48;		// matches default tabs setting in Argo
+		private const defaultTabCount:int = 20;
+		
+		private function initializeDefaultTabStops():void
+		{
+			var lastTabPos:int = defaultTabWidth * defaultTabCount;
+			_defaultTabStops = new Vector.<TabStop>(defaultTabCount, true);
+			for (var i:int = 0; i < defaultTabCount; ++i)
+				_defaultTabStops[i] = new TabStop(TextAlign.START, defaultTabWidth * i);
+		}
+		
+		private function updateTextBlock():void
+		{
+			// find the ancestor with a container and use its format for various settings
+			var containerElement:ContainerFormattedElement = getAncestorWithContainer();
+			if (!containerElement)
+				return;
+				
+			var containerElementFormat:ITextLayoutFormat = containerElement ? containerElement.computedFormat : TextLayoutFormat.defaultFormat;
+			
+			var lineJust:String;
+			if (computedFormat.textAlign == TextAlign.JUSTIFY)
+			{
+				lineJust = (_computedFormat.textAlignLast == TextAlign.JUSTIFY) ?
+					LineJustification.ALL_INCLUDING_LAST :
+					LineJustification.ALL_BUT_LAST;
+					
+				// We don't allow explicit line breaks and justification together because it results in very strange (invisible) lines
+				if (containerElementFormat.lineBreak == LineBreak.EXPLICIT)
+					lineJust = LineJustification.UNJUSTIFIED;
+			}
+			else
+				lineJust = LineJustification.UNJUSTIFIED;
+		
+			
+			var makeJustRuleStyle:String = this.getEffectiveJustificationStyle();
+			
+			var justRule:String = this.getEffectiveJustificationRule();
+				
+			// set the justifier in the TextBlock
+			if (justRule == JustificationRule.SPACE)
+			{
+				var spaceJustifier:SpaceJustifier = new SpaceJustifier(_computedFormat.locale,lineJust,false);
+				spaceJustifier.letterSpacing = _computedFormat.textJustify == TextJustify.DISTRIBUTE ? true : false;
+				CONFIG::debug { Debugging.traceFTECall(spaceJustifier,null,"new SpaceJustifier",_computedFormat.locale,lineJust,false); }
+				_textBlock.textJustifier = spaceJustifier;
+				CONFIG::debug { Debugging.traceFTEAssign(_textBlock,"textJustifier",spaceJustifier); }
+				_textBlock.baselineZero = getLeadingBasis(this.getEffectiveLeadingModel());
+				CONFIG::debug { Debugging.traceFTEAssign(_textBlock,"baselineZero",_textBlock.baselineZero);  }
+			}
+			else
+			{
+				var eastAsianJustifier:EastAsianJustifier = new EastAsianJustifier(_computedFormat.locale,lineJust, makeJustRuleStyle);
+				CONFIG::debug { Debugging.traceFTECall(eastAsianJustifier,null,"new EastAsianJustifier",_computedFormat.locale,lineJust,makeJustRuleStyle); }
+				_textBlock.textJustifier = eastAsianJustifier;
+				CONFIG::debug { Debugging.traceFTEAssign(_textBlock,"textJustifier",eastAsianJustifier);  }
+				_textBlock.baselineZero = getLeadingBasis(this.getEffectiveLeadingModel());
+				CONFIG::debug { Debugging.traceFTEAssign(_textBlock,"baselineZero",_textBlock.baselineZero);  }
+			}
+			
+			_textBlock.bidiLevel = _computedFormat.direction == Direction.LTR ? 0 : 1;
+			CONFIG::debug { Debugging.traceFTEAssign(_textBlock,"bidiLevel",_textBlock.bidiLevel);  }
+
+			_textBlock.lineRotation = containerElementFormat.blockProgression == BlockProgression.RL ? TextRotation.ROTATE_90 : TextRotation.ROTATE_0;
+			CONFIG::debug { Debugging.traceFTEAssign(_textBlock,"lineRotation",_textBlock.lineRotation);  }
+			
+			if (_computedFormat.tabStops && _computedFormat.tabStops.length != 0)
+			{
+				//create a vector of TabStops and assign it to tabStops in _textBlock
+				var tabStops:Vector.<TabStop> = new Vector.<TabStop>();
+				CONFIG::debug { Debugging.traceFTECall(tabStops,null,"new Vector.<TabStop>()"); }
+				for each(var tsa:TabStopFormat in _computedFormat.tabStops)
+				{
+					var token:String = tsa.decimalAlignmentToken==null ? "" : tsa.decimalAlignmentToken;
+					var tabStop:TabStop = new TabStop(tsa.alignment,Number(tsa.position),token);
+					// this next line when uncommented works around bug 1912782
+					if (tsa.decimalAlignmentToken != null) var garbage:String = "x" + tabStop.decimalAlignmentToken;
+					CONFIG::debug { Debugging.traceFTECall(tabStop,null,"new TabStop",tabStop.alignment,tabStop.position,tabStop.decimalAlignmentToken); }
+					tabStops.push(tabStop);
+					CONFIG::debug { Debugging.traceFTECall(null,tabStops,"push",tabStop); }
+				}
+				_textBlock.tabStops = tabStops;
+				CONFIG::debug { Debugging.traceFTEAssign(_textBlock,"tabStops",tabStops);  }
+			} 
+			else if (GlobalSettings.enableDefaultTabStops && !Configuration.playerEnablesArgoFeatures)
+			{
+				// 	Player versions prior to 10.1 do not set up any default tabStops. As a workaround, if enableDefaultTabs
+				//	is true, TLF will set up default tabStops in the case where there are no tabs defined. 
+				if (_defaultTabStops == null)
+					initializeDefaultTabStops();
+				_textBlock.tabStops = _defaultTabStops;
+				CONFIG::debug { Debugging.traceFTEAssign(_textBlock,"tabStops",_defaultTabStops);  }
+			}
+			else
+			{
+				_textBlock.tabStops = null;
+				CONFIG::debug { Debugging.traceFTEAssign(_textBlock,"tabStops",null);  }
+			}		 
+		}
+		
+		/** @private */
+		public override function get computedFormat():ITextLayoutFormat
+		{
+			if (!_computedFormat)
+			{
+				super.computedFormat;
+				if (_textBlock)
+					updateTextBlock();
+			}
+			return _computedFormat;
+		}
+
+		/** @private */
+		tlf_internal override function canOwnFlowElement(elem:FlowElement):Boolean
+		{
+			return elem is FlowLeafElement || elem is SubParagraphGroupElement;
+		}
+		
+		/** @private */
+		tlf_internal override function normalizeRange(normalizeStart:uint,normalizeEnd:uint):void
+		{
+			var idx:int = findChildIndexAtPosition(normalizeStart);
+			if (idx != -1 && idx < numChildren)
+			{
+				var child:FlowElement = getChildAt(idx);
+				normalizeStart = normalizeStart-child.parentRelativeStart;
+				
+				CONFIG::debug { assert(normalizeStart >= 0, "bad normalizeStart in normalizeRange"); }
+				for (;;)
+				{
+					// watch out for changes in the length of the child
+					var origChildEnd:int = child.parentRelativeStart+child.textLength;
+					child.normalizeRange(normalizeStart,normalizeEnd-child.parentRelativeStart);
+					var newChildEnd:int = child.parentRelativeStart+child.textLength;
+					normalizeEnd += newChildEnd-origChildEnd;	// adjust
+					
+					// no zero length children
+					if (child.textLength == 0 && !child.bindableElement)
+						replaceChildren(idx,idx+1);
+					else if (child.mergeToPreviousIfPossible())
+					{
+						var prevElement:FlowElement = this.getChildAt(idx-1);
+						// possibly optimize the start to the length of prevelement before the merge
+						prevElement.normalizeRange(0,prevElement.textLength);
+					}
+					else
+						idx++;
+
+					if (idx == numChildren)
+					{
+						// check if last child is an empty SubPargraphBlock and remove it
+						if (idx != 0)
+						{
+							var lastChild:FlowElement = this.getChildAt(idx-1);
+							if (lastChild is SubParagraphGroupElement && lastChild.textLength == 1 && !lastChild.bindableElement)
+								replaceChildren(idx-1,idx);
+						}
+						break;
+					}
+					
+					// next child
+					child = getChildAt(idx);
+					
+					if (child.parentRelativeStart > normalizeEnd)
+						break;
+						
+					normalizeStart = 0;		// for the next child	
+				}
+			}
+			
+			// empty paragraphs not allowed after normalize
+			if (numChildren == 0 || textLength == 0)
+			{
+				var s:SpanElement = new SpanElement();
+				replaceChildren(0,0,s);
+				s.normalizeRange(0,s.textLength);
+			}
+		}
+		
+		/** @private */
+		tlf_internal function getEffectiveLeadingModel():String
+		{
+			return computedFormat.leadingModel == LeadingModel.AUTO ? LocaleUtil.leadingModel(computedFormat.locale) : computedFormat.leadingModel;
+		}
+		
+		/** @private */
+		tlf_internal function getEffectiveDominantBaseline():String
+		{
+			return computedFormat.dominantBaseline == FormatValue.AUTO ? LocaleUtil.dominantBaseline(computedFormat.locale) : computedFormat.dominantBaseline;
+		}
+		
+		/** @private */
+		tlf_internal function getEffectiveJustificationRule():String
+		{
+			return computedFormat.justificationRule == FormatValue.AUTO ? LocaleUtil.justificationRule(computedFormat.locale) : computedFormat.justificationRule;
+		}
+		
+		/** @private */
+		tlf_internal function getEffectiveJustificationStyle():String
+		{
+			return computedFormat.justificationStyle == FormatValue.AUTO ? LocaleUtil.justificationStyle(computedFormat.locale) : computedFormat.justificationStyle;
+		}
+		
+		
+		/** @private */
+		CONFIG::debug public override function debugCheckFlowElement(depth:int = 0, extraData:String = ""):int
+		{
+			var rslt:int = super.debugCheckFlowElement(depth," fte:"+getDebugIdentity(_textBlock)+" "+extraData);
+			
+			// now check the character count and then the last character 
+			
+			if (_textBlock)
+			{
+				var contentLength:int = _textBlock.content && _textBlock.content.rawText ? _textBlock.content.rawText.length : 0;
+				rslt += assert(contentLength == textLength,"Bad paragraph length mode:"+textLength.toString()+" _textBlock:" + contentLength.toString());
+
+				var groupElement:GroupElement = _textBlock.content as GroupElement;
+				if (groupElement)
+					assert(groupElement.elementCount == numChildren,"Mismatched group and elementCount"); 
+				else if (_textBlock.content)
+					assert(1 == numChildren,"Mismatched group and elementCount"); 
+				else 
+					assert(0 == numChildren,"Mismatched group and elementCount"); 
+			}
+			rslt += assert(numChildren == 0 || textLength > 0,"Para must have at least one text char");
+			return rslt;
+		}
+		
+		/** @private */
+		tlf_internal static function getLeadingBasis (leadingModel:String):String
+		{
+			switch (leadingModel)
+			{
+				default:
+					CONFIG::debug { assert(false,"Unsupported parameter to ParagraphElement.getLeadingBasis"); } // In particular, AUTO is not supported by this method. Must be mapped to one of the above 
+				case LeadingModel.ASCENT_DESCENT_UP:
+				case LeadingModel.APPROXIMATE_TEXT_FIELD:
+				case LeadingModel.ROMAN_UP:
+					return flash.text.engine.TextBaseline.ROMAN;
+				case LeadingModel.IDEOGRAPHIC_TOP_UP:
+				case LeadingModel.IDEOGRAPHIC_TOP_DOWN:
+					return flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP;
+				case LeadingModel.IDEOGRAPHIC_CENTER_UP:
+				case LeadingModel.IDEOGRAPHIC_CENTER_DOWN:
+					return flash.text.engine.TextBaseline.IDEOGRAPHIC_CENTER;
+			}
+		}
+		
+		/** @private */
+		tlf_internal static function useUpLeadingDirection (leadingModel:String):Boolean
+		{
+			switch (leadingModel)
+			{
+				default:
+					CONFIG::debug { assert(false,"Unsupported parameter to ParagraphElement.useUpLeadingDirection"); } // In particular, AUTO is not supported by this method. Must be mapped to one of the above 
+				case LeadingModel.ASCENT_DESCENT_UP:
+				case LeadingModel.APPROXIMATE_TEXT_FIELD:
+				case LeadingModel.ROMAN_UP:
+				case LeadingModel.IDEOGRAPHIC_TOP_UP:
+				case LeadingModel.IDEOGRAPHIC_CENTER_UP:
+					return true;
+				case LeadingModel.IDEOGRAPHIC_TOP_DOWN:
+				case LeadingModel.IDEOGRAPHIC_CENTER_DOWN:
+					return false;
+			}
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/ParagraphFormattedElement.as b/textLayout_core/src/flashx/textLayout/elements/ParagraphFormattedElement.as
new file mode 100755
index 0000000..0c1b3e5
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/ParagraphFormattedElement.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 flashx.textLayout.elements
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.property.Property;	
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+	
+	/** The ParagraphFormattedElement class is an abstract base class for FlowElement classes that have paragraph properties.
+	*
+	* <p>You cannot create a ParagraphFormattedElement object directly. Invoking <code>new ParagraphFormattedElement()</code> 
+	* throws an error exception.</p> 
+	*
+	* @playerversion Flash 10
+	* @playerversion AIR 1.5
+	* @langversion 3.0
+	*
+	* @see ContainerFormattedElement
+	* @see ParagraphElement
+	* 
+	*/
+	public class ParagraphFormattedElement extends FlowGroupElement
+	{
+		/** @private TODO: DELETE THIS CLASS */
+		public override function shallowCopy(startPos:int = 0, endPos:int = -1):FlowElement
+		{
+			return super.shallowCopy(startPos, endPos) as ParagraphFormattedElement;
+		}
+
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/elements/SpanElement.as b/textLayout_core/src/flashx/textLayout/elements/SpanElement.as
new file mode 100755
index 0000000..ebff88a
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/SpanElement.as
@@ -0,0 +1,596 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements
+{
+	import flash.text.engine.GroupElement;
+	import flash.text.engine.TextElement;
+	import flash.utils.getQualifiedClassName;
+	
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.debug.Debugging;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.events.ModelChange;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.WhiteSpaceCollapse;
+	import flashx.textLayout.property.Property;
+	import flashx.textLayout.tlf_internal;
+	import flashx.textLayout.utils.CharacterUtil;
+	
+	use namespace tlf_internal;
+			
+	[DefaultProperty("mxmlChildren")]
+	
+	/** 
+	* The SpanElement class represents a run of text that has a single set of formatting attributes applied. SpanElement 
+	* objects contain the text in a paragraph. A simple paragraph (ParagraphElement) includes one or more SpanElement objects. 
+	*
+	* <p>A ParagraphElement will have a single SpanElement object if all the text in the paragraph shares the same set of 
+	* attributes. It has multiple SpanElement objects if the text in the paragraph has multiple formats.</p>
+	*
+	* @playerversion Flash 10
+	* @playerversion AIR 1.5
+	* @langversion 3.0
+	*
+	* @includeExample examples/SpanElementExample.as -noswf
+	*
+	* @see FlowElement
+	* @see ParagraphElement
+	* @see TextFlow
+     	*/
+     	
+	public class SpanElement extends FlowLeafElement
+	{	
+		/** @private */
+		tlf_internal static const kParagraphTerminator:String = '\u2029';
+		
+		/** Constructor - creates a SpanElement object to hold a run of text in a paragraph.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*/
+	 	
+		public function SpanElement():void
+		{
+			super();
+		}
+		
+		/** @private */
+		override tlf_internal function createContentElement():void
+		{
+			if (_blockElement)
+				return;
+				
+			_blockElement = new TextElement(null,null);			
+			CONFIG::debug { Debugging.traceFTECall(_blockElement,null,"new TextElement",null,null); }
+			TextElement(_blockElement).replaceText(0, 0, _text);
+			CONFIG::debug { Debugging.traceFTECall(null,_blockElement,"replaceText",0,0,_text); }
+			_text = null;
+			super.createContentElement();
+		}
+		/** @private */
+		override tlf_internal function releaseContentElement():void
+		{
+			if (_blockElement == null || !canReleaseContentElement())
+				return;
+			
+			CONFIG::debug { assert(_text == null, "_text already has content -- out of date?");	}
+			_text = _blockElement.rawText;
+			super.releaseContentElement();
+		}
+		
+		/** @private */
+		private function getTextElement():TextElement
+		{ return TextElement(_blockElement); }
+		
+		/** @private */
+		public override function shallowCopy(startPos:int = 0, endPos:int = -1):FlowElement
+		{
+			if (endPos == -1)
+				endPos = textLength;
+				
+			// Note to callers: If you are calling this function outside a try/catch, do ensure that the 
+			// state of the model is coherent before the call.
+			var retFlow:SpanElement = super.shallowCopy(startPos, endPos) as SpanElement;
+						
+			var startSpan:int = 0;
+			var endSpan:int = startSpan + textLength;
+			
+			var leafElStartPos:int = startSpan >= startPos ? startSpan : startPos;
+			var leafElEndPos:int =  endSpan < endPos ? endSpan : endPos;
+			if (leafElEndPos == textLength && hasParagraphTerminator)
+				--leafElEndPos;
+				
+			if (leafElStartPos > leafElEndPos)
+				throw RangeError(GlobalSettings.resourceStringFunction("badShallowCopyRange"));
+			
+			var spanText:String = _blockElement ? _blockElement.rawText : _text;
+			if (((leafElStartPos != endSpan) && CharacterUtil.isLowSurrogate(spanText.charCodeAt(leafElStartPos))) ||
+				((leafElEndPos != 0) && CharacterUtil.isHighSurrogate(spanText.charCodeAt(leafElEndPos-1))))
+					throw RangeError(GlobalSettings.resourceStringFunction("badSurrogatePairCopy"));
+			
+			retFlow.replaceText(0, retFlow.textLength,  String(spanText).substring(leafElStartPos, leafElEndPos));
+			
+			return retFlow;
+		}	
+	
+		/** @private */
+		override protected function get abstract():Boolean
+		{
+			return false;
+		}		
+
+		/** @private */
+		public override function get text():String
+		{
+			// Get the text from the blockElement is there is one, otherwise grab it from the text property
+			var textValue:String = _blockElement ? _blockElement.rawText : _text;
+			
+			// test textLength cause this is a property and the debugger may run this calculation in intermediate states
+			if (textLength && hasParagraphTerminator)
+				return textValue.substr(0,textLength-1);
+				
+			return textValue != null ? textValue : "";
+		}
+		/** 
+		 * Receives the String of text that this SpanElement object holds.
+		 *
+		 * <p>The text of a span does not include the carriage return (CR) at the end of the paragraph
+		 * but it is included in the value of <code>textLength</code>.</p>
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	
+	 	public function set text(textValue:String):void
+		{
+			//original code stripped breaking and tab characters.  new code moved to collapseWhitevar newLineTabPattern:RegExp = /[\n\r\t]/g;
+			replaceText(0,textLength, textValue); 
+		} 
+		
+		/** @private */
+		public override function getText(relativeStart:int=0, relativeEnd:int=-1, paragraphSeparator:String="\n"):String
+		{
+			// Get the text from the blockElement is there is one, otherwise grab it from the text property
+			var textValue:String = _blockElement ? _blockElement.rawText : _text;
+
+			if (textLength && relativeEnd == textLength && hasParagraphTerminator)
+				--relativeEnd;		// don't include terminator
+			return textValue ? textValue.substring(relativeStart, relativeEnd) : "";
+		}
+
+		[RichTextContent]
+		/** 
+		 * Sets text based on content within span tags; always deletes existing children.
+		 * This property is intended for use during mxml compiled import. When TLF markup elements have other
+		 * TLF markup elements as children, the children are assigned to this property.
+		 *
+		 * @throws TypeError if array element is not a SpecialCharacterElement or a String
+		 * @param array - an array of elements within span tags. Each element of array must be a SpecialCharacterElement or a String.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		public function get mxmlChildren():Array
+		{
+			return [ text ];
+		}
+		public function set mxmlChildren(array:Array):void
+		{
+			/* NOTE: all FlowElement implementers and overrides of mxmlChildren must specify [RichTextContent] metadata */
+
+			var str:String = new String();
+			for each (var elem:Object in array)
+			{
+				if (elem is String)
+					str += elem as String;
+				else if (elem is Number)	// TODO: remove the Number else if when we can test with the most recent compilers.  The [RichTextContent] metadata fixes the issue
+					str += elem.toString();
+				else if (elem is BreakElement)
+					str += String.fromCharCode(0x2028);
+				else if (elem is TabElement)
+				{
+					// Add a placeholder (from Unicode private use area) instead of '\t' because the latter is 
+					// stripped during white space collapse. After white space collapse, we will change the placeholder
+					// to '\t' 
+					str += String.fromCharCode(0xE000); 
+				}	
+				else if (elem != null)
+					throw new TypeError(GlobalSettings.resourceStringFunction("badMXMLChildrenArgument",[ getQualifiedClassName(elem) ]));
+					
+			}
+			replaceText(0,textLength, str); 
+		}
+		
+		
+		/** 
+		 * Specifies whether this SpanElement object terminates the paragraph. The SpanElement object that terminates a 
+		 * paragraph has an extra, hidden character at the end. This character is added automatically by the component and is
+		 * included in the value of the <code>textLength</code> property.
+		 * 
+		 * @private */
+		 
+		tlf_internal function get hasParagraphTerminator():Boolean
+		{
+			var p:ParagraphElement = getParagraph();
+			return (p && p.getLastLeaf() == this); 
+		}
+		
+		/** @private */
+		CONFIG::debug tlf_internal function verifyParagraphTerminator():void
+		{
+			var str:String = _blockElement ? _blockElement.rawText : _text;
+			assert(str && str.length && str.charAt(str.length-1) == SpanElement.kParagraphTerminator,
+				"attempting to remove para terminator when it doesn't exist");
+		}
+		
+		
+		/**
+		 * Makes a shallow copy of this SpanElement between 2 character positions
+		 * and returns it as a FlowElement.  Unlike deepCopy, shallowCopy does
+		 * not copy any of the children of this SpanElement.
+		 * 
+		 */
+		 
+		 // If I have a sequence of different sorts of spaces (e.g., en quad, hair space), would I want them converted down to one space? Probably not.
+		 // For now, u0020 is the only space character we consider for eliminating duplicates, though u00A0 (non-breaking space) is potentially eligible. 
+		 private static const _dblSpacePattern:RegExp = /[\u0020]{2,}/g;
+		 // Tab, line feed, and carriage return
+		 private static const _newLineTabPattern:RegExp = /[\u0009\u000a\u000d]/g;
+		 private static const _tabPlaceholderPattern:RegExp = /\uE000/g;
+		 
+		 // static private const anyPrintChar:RegExp = /[^\s]/g;
+		 // Consider only tab, line feed, carriage return, and space as characters used for pretty-printing. 
+		 // While debatable, this is consistent with what CSS does. 
+		 static private const anyPrintChar:RegExp = /[^\u0009\u000a\u000d\u0020]/g; 
+
+		 /** @private */
+		tlf_internal override function applyWhiteSpaceCollapse():void
+		{
+			var stripValue:String = computedFormat.whiteSpaceCollapse;
+				
+			var tempTxt:String = text;
+				
+			if (!stripValue /* null == default value == COLLAPSE */ || stripValue == WhiteSpaceCollapse.COLLAPSE)
+			{
+				// The span was added automatically when a String was passed to replaceChildren.
+				// If it contains only whitespace, we remove the text.
+				if (impliedElement && parent != null)
+				{
+					// var matchArray:Array = tempTxt.search(anyPrintChar);
+					if (tempTxt.search(anyPrintChar) == -1)
+					{
+						parent.removeChild(this);
+						return;
+					}
+				}
+				
+				// For now, replace the newlines and tabs inside the element with a space.
+				// This is necessary for support of compiled mxml files that have newlines and tabs, because
+				// these are most likely not intended to be part of the text content, but only there so the
+				// text can be conveniently edited in the mxml file. Later on we need to add standalone elements
+				// for <br/> and <tab/>. Note that tab character is not supported in HTML.	
+				tempTxt = tempTxt.replace(_newLineTabPattern, " ");
+
+				// Replace sequences of 2 or more whitespace characters with single space
+				tempTxt = tempTxt.replace(_dblSpacePattern, " ");
+				}
+			
+			// Replace tab placeholders (used for tabs that are expected to survive whitespace collapse) with '\t'
+			replaceText(0, textLength, tempTxt.replace(_tabPlaceholderPattern, '\t'));
+
+			super.applyWhiteSpaceCollapse();
+		}
+		
+		/** 
+		 * Updates the text in text span based on the specified start and end positions. To insert text, set the end position
+		 * equal to the start position. To append text to the existing text in the span, set the start position and the
+		 * end position equal to the length of the existing text.
+		 *
+		 * <p>The replaced text includes the start character and up to but not including the end character.</p>
+		 * 
+		 *  @param relativeStartPosition The index position of the beginning of the text to be replaced, 
+		 *   relative to the start of the span. The first character in the span is at position 0.
+		 *  @param relativeEndPosition The index one position after the last character of the text to be replaced, 
+		 *   relative to the start of the span. Set this value equal to <code>relativeStartPos</code>
+		 *   for an insert. 
+		 *  @param textValue The replacement text or the text to add, as the case may be.
+		 * 
+		 *  @throws RangeError The <code>relativeStartPosition</code> or <code>relativeEndPosition</code> specified is out of 
+		 * range or a surrogate pair is being split as a result of the replace.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @includeExample examples/SpanElement_replaceTextExample.as -noswf
+		 */
+		 
+		public function replaceText(relativeStartPosition:int, relativeEndPosition:int, textValue:String):void
+		{
+			// Note to callers: If you are calling this function outside a try/catch, do ensure that the 
+			// state of the model is coherent before the call.
+			if (relativeStartPosition < 0 || relativeEndPosition > textLength || relativeEndPosition < relativeStartPosition)
+				throw RangeError(GlobalSettings.resourceStringFunction("invalidReplaceTextPositions"));	
+
+
+			var spanText:String = _blockElement ? _blockElement.rawText : _text;
+			if ((relativeStartPosition != 0 && relativeStartPosition != textLength && CharacterUtil.isLowSurrogate(spanText.charCodeAt(relativeStartPosition))) ||
+				(relativeEndPosition != 0 && relativeEndPosition != textLength && CharacterUtil.isHighSurrogate(spanText.charCodeAt(relativeEndPosition-1))))
+					throw RangeError (GlobalSettings.resourceStringFunction("invalidSurrogatePairSplit"));
+				
+			if (hasParagraphTerminator)
+			{
+				CONFIG::debug { assert(textLength > 0,"invalid span"); }
+				if (relativeStartPosition == textLength)
+					relativeStartPosition--;
+				if (relativeEndPosition == textLength)
+					relativeEndPosition--;
+			}
+			
+			if (relativeEndPosition != relativeStartPosition)
+				modelChanged(ModelChange.TEXT_DELETED,relativeStartPosition,relativeEndPosition-relativeStartPosition);
+			
+			replaceTextInternal(relativeStartPosition,relativeEndPosition,textValue);
+			
+			if (textValue && textValue.length)
+				modelChanged(ModelChange.TEXT_INSERTED,relativeStartPosition,textValue.length);
+		}
+		private function replaceTextInternal(startPos:int, endPos:int, textValue:String):void
+		{			
+			var textValueLength:int = textValue == null ? 0 : textValue.length;
+			var deleteTotal:int = endPos-startPos;
+			var deltaChars:int =  textValueLength - deleteTotal;
+			if (_blockElement)
+			{
+				TextElement(_blockElement).replaceText(startPos,endPos,textValue);
+				CONFIG::debug { Debugging.traceFTECall(null,TextElement(_blockElement),"replaceText",startPos,endPos,textValue); }
+			}
+			else if (_text)
+			{
+				if (textValue)
+					_text = _text.slice(0, startPos) + textValue + _text.slice(endPos, _text.length);
+				else
+					_text = _text.slice(0, startPos) + _text.slice(endPos, _text.length);
+			}
+			else
+				_text = textValue;
+			
+			if (deltaChars != 0)
+			{
+				updateLengths(getAbsoluteStart() + startPos, deltaChars, true);
+				deleteContainerText(endPos,deleteTotal);
+				
+				if (textValueLength != 0)
+				{
+					var enclosingContainer:ContainerController = getEnclosingController(startPos);
+					if (enclosingContainer)
+						ContainerController(enclosingContainer).setTextLength(enclosingContainer.textLength + textValueLength);
+				}
+			}
+
+			CONFIG::debug { 
+				var debugText:String = _blockElement == null ? _text : _blockElement.rawText;
+				assert(textLength == (debugText ? debugText.length : 0),"span textLength doesn't match the length of the text property, text property length is " + debugText.length.toString() + " textLength property is " + textLength.toString());
+			}
+		}
+	
+		/** @private */
+		tlf_internal override function addParaTerminator():void
+		{
+			CONFIG::debug 
+			{ 
+				// TODO: Is this assert valid? Do we prevent users from adding para terminators themselves? 
+				if (_blockElement && _blockElement.rawText && _blockElement.rawText.length)
+					assert(_blockElement.rawText.charAt(_blockElement.rawText.length-1) != SpanElement.kParagraphTerminator,"adding para terminator twice");
+			}
+
+			replaceTextInternal(textLength,textLength,SpanElement.kParagraphTerminator);
+			
+			CONFIG::debug 
+			{ 
+				// TODO: Is this assert valid? Do we prevent users from adding para terminators themselves? 
+				if (_blockElement)
+					assert(_blockElement.rawText.charAt(_blockElement.rawText.length-1) == SpanElement.kParagraphTerminator,"adding para terminator failed");
+			}			
+			
+			modelChanged(ModelChange.TEXT_INSERTED,textLength-1,1);
+		}
+		/** @private */
+		tlf_internal override function removeParaTerminator():void
+		{
+			CONFIG::debug 
+			{ 
+				var str:String = _blockElement ? _blockElement.rawText : _text;
+				assert(str && str.length && str.charAt(str.length-1) == SpanElement.kParagraphTerminator,
+					"attempting to remove para terminator when it doesn't exist");
+			}
+			replaceTextInternal(textLength-1,textLength,"");
+			modelChanged(ModelChange.TEXT_DELETED,textLength > 0 ? textLength-1 : 0,1);
+		}
+		// **************************************** 
+		// Begin tree modification support code
+		// ****************************************
+
+		/** 
+		 * Splits this SpanElement object at the specified position and returns a new SpanElement object for the content
+		 * that follows the specified position. 
+		 *
+		 * <p>This method throws an error if you attempt to split a surrogate pair. In Unicode UTF-16, a surrogate pair is a pair of 
+		 * 16-bit code units (a high code unit and a low code unit) that represent one of the abstract Unicode characters 
+		 * that cannot be represented in a single 16-bit word. The 16-bit high code unit is in the range of D800 to DBFF. The
+		 * 16-bit low code unit is in the range of DC00 to DFFF.</p>
+		 * 
+		 * @param relativePosition - relative position in the span to create the split
+		 * @return - the newly created span. 
+		 * @throws RangeError <code>relativePosition</code> is less than 0 or greater than textLength or a surrogate pair is being split.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 * 
+	 	 * @private
+	 	 */
+	 	 
+		public override function splitAtPosition(relativePosition:int):FlowElement
+		{
+			// Note to callers: If you are calling this function outside a try/catch, do ensure that the 
+			// state of the model is coherent before the call.
+			if (relativePosition < 0 || relativePosition > textLength)
+				throw RangeError(GlobalSettings.resourceStringFunction("invalidSplitAtPosition"));
+			
+			if ((relativePosition < textLength) && CharacterUtil.isLowSurrogate(String(text).charCodeAt(relativePosition)))
+				throw RangeError (GlobalSettings.resourceStringFunction("invalidSurrogatePairSplit"));
+			
+			var newSpan:SpanElement = new SpanElement();
+			// clone styling information
+			newSpan.id = this.id;
+			newSpan.styleName = this.styleName;			
+			
+			if (parent)
+			{
+				var newBlockElement:TextElement;
+				var newSpanLength:int = textLength - relativePosition;
+				if (_blockElement)
+				{
+				// optimized version leverages player APIs
+					// TODO: Jeff to add split on TextElement so we don't have to go find a group every time
+					var group:GroupElement = parent.createContentAsGroup();
+					
+					var elementIndex:int = group.getElementIndex(_blockElement);
+					
+					CONFIG::debug { assert(elementIndex == parent.getChildIndex(this),"bad group index"); }
+					CONFIG::debug { assert(elementIndex != -1 && elementIndex < group.elementCount,"bad span split"); }
+					//trace("GROUP BEFORE: " + group.rawText);
+					//trace("BLOCK BEFORE: " + group.block.content.rawText);
+					//trace("calling group.splitTextElement("+elementIndex.toString()+","+relativePosition.toString()+")");
+					group.splitTextElement(elementIndex, relativePosition);
+					CONFIG::debug { Debugging.traceFTECall(null,group,"splitTextElement",elementIndex,relativePosition); }
+
+					//trace("GROUP AFTER: " + group.rawText);
+					//trace("BLOCK AFTER: " + group.block.content.rawText);
+					
+					// no guarantee on how the split works
+					_blockElement = group.getElementAt(elementIndex);
+					CONFIG::debug { Debugging.traceFTECall(_blockElement,group,"getElementAt",elementIndex); }
+					newBlockElement = group.getElementAt(elementIndex+1) as TextElement;
+					CONFIG::debug { Debugging.traceFTECall(newBlockElement,group,"getElementAt",elementIndex+1); }
+				}
+				else if (relativePosition < textLength)
+				{
+					newSpan.text = _text.substr(relativePosition);
+					_text = _text.substring(0, relativePosition);
+				}
+
+				// Split this span at the offset, into two equivalent spans
+				modelChanged(ModelChange.TEXT_DELETED,relativePosition,newSpanLength);
+				newSpan.quickInitializeForSplit(this, newSpanLength,newBlockElement);
+
+				setTextLength(relativePosition);
+			
+				// slices it in, sets the parent and the start
+				parent.addChildAfterInternal(this,newSpan);	
+				newSpan.modelChanged(ModelChange.ELEMENT_ADDED,0,newSpan.textLength);
+			}
+			else
+			{
+				// this version also works if para is non-null but may not be as efficient.
+				newSpan.format = format;
+
+				// could be we are splitting 
+				if (relativePosition < textLength)
+				{
+					newSpan.text = String(this.text).substr(relativePosition);
+					replaceText(relativePosition,textLength,null);
+				}
+			}
+			
+			return newSpan;
+		}
+		
+		/** @private */
+		tlf_internal override function normalizeRange(normalizeStart:uint,normalizeEnd:uint):void
+		{
+			if (this.textLength == 1)
+			{
+				var p:ParagraphElement = getParagraph();
+				if (p && p.getLastLeaf() == this)
+				{
+					var prevLeaf:FlowLeafElement = getPreviousLeaf(p);
+					if (prevLeaf)
+					{
+						this.format = prevLeaf.format;
+						this.userStyles = prevLeaf.userStyles ? Property.shallowCopy(prevLeaf.userStyles) : null;
+					}
+				}
+			}
+			super.normalizeRange(normalizeStart,normalizeEnd);
+		}
+
+		/** @private */
+		tlf_internal override function mergeToPreviousIfPossible():Boolean
+		{
+			// if canReleaseContentElement is false than the contentElement has something special (like an eventMirror) and the span can't be merged
+			if (parent && !bindableElement && canReleaseContentElement())
+			{
+				var myidx:int = parent.getChildIndex(this);
+				if (myidx != 0)
+				{
+					var sib:SpanElement = parent.getChildAt(myidx-1) as SpanElement;
+					if (sib != null && sib.canReleaseContentElement() && 
+						(equalStylesForMerge(sib) || (this.textLength == 1 && this.hasParagraphTerminator)))
+					{
+						CONFIG::debug { assert(this.parent == sib.parent, "Should never merge two spans with different parents!"); }
+						CONFIG::debug { assert(TextLayoutFormat.isEqual(this.formatForCascade,sib.formatForCascade) || (this.textLength == 1 && this.hasParagraphTerminator), "Bad merge!"); }
+						
+						// Merge them in the Player's TextBlock structure
+						var siblingInsertPosition:int = sib.textLength;
+						sib.replaceText(siblingInsertPosition, siblingInsertPosition, this.text);
+						parent.replaceChildren(myidx,myidx+1,null);
+						return true;
+					}
+				}
+			} 
+			return false;
+		}
+		
+		// **************************************** 
+		// Begin debug support code
+		// ****************************************	
+		
+		/** @private */
+		CONFIG::debug public override function debugCheckFlowElement(depth:int = 0, extraData:String = ""):int
+		{
+			// debugging function that asserts if the flow element tree is in an invalid state
+			
+			var rslt:int = super.debugCheckFlowElement(depth,"text:"+String(text).substr(0,32)+" "+extraData);
+
+			var textValue:String = _blockElement ? _blockElement.rawText : _text;
+			var textLen:int = textLength;
+			if (textValue)
+				rslt += assert(textLen == textValue.length,"span is different than its textElement, span text length is " + textValue.length.toString() + " expecting " + textLen.toString());
+			else	
+				rslt += assert(textLen == 0,"span is different than its textElement, span text length is null expecting " + textLen.toString());
+			rslt += assert(this != getParagraph().getLastLeaf() || (textValue.length >= 1 && textValue.substr(textValue.length-1,1) == SpanElement.kParagraphTerminator),"last span in paragraph must end with terminator");
+			return rslt;
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/SpecialCharacterElement.as b/textLayout_core/src/flashx/textLayout/elements/SpecialCharacterElement.as
new file mode 100755
index 0000000..709b36d
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/SpecialCharacterElement.as
@@ -0,0 +1,92 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements
+{
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.WhiteSpaceCollapse;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+	
+	/** The SpecialCharacterElement class is an abstract base class for elements that represent special characters.
+	 *
+	 * <p>You cannot create a SpecialCharacterElement object directly. Invoking <code>new SpecialCharacterElement()</code>
+	 * throws an error exception.</p>
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 *
+	 * @see BreakElement
+	 * @see TabElement
+	 */
+	public class SpecialCharacterElement extends SpanElement
+	{
+		/**  
+		 * Base class - invoking <code>new SpecialCharacterElement()</code> throws an error exception.
+		 * 
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		 
+		public function SpecialCharacterElement()
+		{
+			super();
+		//	blockElement = new TextElement(null, null);
+						
+			// Set WhiteSpaceCollapse.PRESERVE to prevent merging with a sibling span with WhiteSpaceCollapse.COLLAPSE setting
+			// (during normalization). Otherwise the '\t' will be removed during the call to applyWhiteSpaceCollapse (following normalization).
+			// Once applyWhiteSpaceCollapse has been called, we can allow merging.
+			whiteSpaceCollapse = WhiteSpaceCollapse.PRESERVE; 
+		}
+		
+		/** @private */
+		tlf_internal override function mergeToPreviousIfPossible():Boolean
+		{
+			if (parent)
+			{
+				var myidx:int = parent.getChildIndex(this);
+				if (myidx != 0)
+				{
+					var sib:SpanElement = parent.getChildAt(myidx-1) as SpanElement;
+					if (sib != null && (sib is SpanElement) && TextLayoutFormat.isEqual(sib.format,format))
+					{
+						CONFIG::debug { assert(this.parent == sib.parent, "Should never merge two spans with different parents!"); }
+						
+						// Merge them in the Player's TextBlock structure
+						var siblingInsertPosition:int = sib.textLength;
+						sib.replaceText(siblingInsertPosition, siblingInsertPosition, this.text);
+						parent.replaceChildren(myidx,myidx+1);
+						return true;
+					}
+				}
+				// make a span and replace ourself
+				var newSib:SpanElement = new SpanElement();
+				newSib.text = this.text;
+				newSib.format = format;
+				parent.replaceChildren(myidx,myidx+1,newSib);
+				newSib.normalizeRange(0,newSib.textLength);
+				return false;
+			} 
+			return false;
+		}
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/elements/SubParagraphGroupElement.as b/textLayout_core/src/flashx/textLayout/elements/SubParagraphGroupElement.as
new file mode 100755
index 0000000..cb9bc20
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/SubParagraphGroupElement.as
@@ -0,0 +1,405 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements
+{
+	import __AS3__.vec.Vector;
+	
+	import flash.events.EventDispatcher;
+	import flash.text.engine.ContentElement;
+	import flash.text.engine.GroupElement;
+	import flash.utils.getQualifiedClassName;
+	
+	import flashx.textLayout.debug.Debugging;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+	
+	/** 
+	 * The SubParagraphGroupElement class groups FlowLeafElements together. A SubParagraphGroupElement is a child of a 
+	 * ParagraphElement object and it can contain one or more FlowLeafElement objects as children.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 * 
+	 * @see FlowLeafElement
+	 * @see LinkElement
+	 * @see ParagraphElement
+	 * @see TCYElement
+	 */
+	 
+	public class SubParagraphGroupElement extends FlowGroupElement
+	{
+		private var _groupElement:GroupElement;
+		
+		/** @private - no listeners attached */
+		tlf_internal static const NO_ATTACHED_LISTENERS:uint       	= 0;
+		/** @private - only internal listeners attached */
+		tlf_internal static const INTERNAL_ATTACHED_LISTENERS:uint = 1;
+		/** @private - *may* be client attached listeners. */
+		tlf_internal static const CLIENT_ATTACHED_LISTENERS:uint   = 2;
+		
+		/** bit field describing attached listeners */
+		private var _attachedListenerStatus:uint;
+		
+		/** Maximum precedence value @private */
+		tlf_internal static const kMaxSPGEPrecedence:uint = 1000;
+		/** Minimum precedence value @private */
+		tlf_internal static const kMinSPGEPrecedence:uint = 0;
+		
+		private var _canMerge:Boolean; 	// true if element is bound to an external data source - generated text
+
+		/** Constructor - creates a new SubParagraphGroupElement instance.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		 
+		public function SubParagraphGroupElement()
+		{
+			_canMerge = true;
+			_attachedListenerStatus = NO_ATTACHED_LISTENERS;
+			super();
+		}
+		
+		/** @private */
+		public override function shallowCopy(startPos:int = 0, endPos:int = -1):FlowElement
+		{
+			var retFlow:SubParagraphGroupElement = super.shallowCopy(startPos, endPos) as SubParagraphGroupElement;
+			if (_groupElement)
+				retFlow.createContentElement();
+			return retFlow;
+		}
+
+		/** @private */
+		override tlf_internal function createContentElement():void
+		{
+			if (_groupElement)
+				return;
+				
+			_groupElement = new GroupElement(null);
+			CONFIG::debug { Debugging.traceFTECall(_groupElement,null,"new GroupElement",null); }  
+			for (var i:int = 0; i < numChildren; i++)
+			{
+				var child:FlowElement = getChildAt(i);
+				child.createContentElement();
+			}			
+			if (parent)
+				parent.insertBlockElement(this, _groupElement);
+		}
+		
+		/** @private */
+		override tlf_internal function releaseContentElement():void
+		{
+			if (!canReleaseContentElement() || groupElement == null)
+				return;
+			for (var i:int = 0; i < numChildren; i++)
+			{
+				var child:FlowElement = getChildAt(i);
+				child.releaseContentElement();
+			}			
+			_groupElement = null;
+		}
+		
+		/** @private */
+		override tlf_internal function canReleaseContentElement():Boolean
+		{
+			return _attachedListenerStatus == NO_ATTACHED_LISTENERS;
+		}
+		
+		/**
+		 * @public getter to return the precedence value of this SubParagraphGroupElement
+		 * Precedence is used to determine which SPGE element will be the container element
+		 * when two or more SPGEs of the same textLength are inside one another.
+		 * 
+		 * Precedence is used to determine which SubParagraphGroupElement is the owner when two or 
+		 * more elements have the same text and are embedded within each other.
+		 * 
+		 * Example: SPGEs A(precedence 900), B(precedence 400), C(precedence 600)
+		 * Model Result when all wrap SpanElement "123"
+		 * 
+		 * <A><C><B>123</B></C></A>
+		 * 
+		 * If two or more SPGE's have the same precedence value, then the alphabetic order is used:
+		 * Example: SPGE A(precedence 400), B(precedence 400), C(precedence 600)
+		 * 
+		 * <C><A><B>123</B></A></C>
+		 * 
+		 * Current values for SubParagraphGroupElements are:
+		 * 	LinkElement - 800
+		 * 	TCYElement - 100
+		 * 
+		 * If the value is not overriden by descendents of SPGE, then value is kMaxSPGEPrecedence;
+		 * @private
+		 */
+		tlf_internal function get precedence():uint { return kMaxSPGEPrecedence; }
+		
+		 
+		/** @private */
+		tlf_internal function get groupElement():GroupElement
+		{ return _groupElement; }
+		
+		/** @private */
+		tlf_internal function get attachedListenerStatus():int
+		{ return _attachedListenerStatus; }
+		
+		/** @private */
+		tlf_internal override function createContentAsGroup():GroupElement
+		{
+			return groupElement;
+		}
+		/** @private */
+		tlf_internal override function removeBlockElement(child:FlowElement, block:ContentElement):void
+		{
+			var idx:int = this.getChildIndex(child);
+			groupElement.replaceElements(idx,idx+1,null);
+
+		}
+		
+		/** @private */
+		tlf_internal override function insertBlockElement(child:FlowElement, block:ContentElement):void
+		{
+			if (groupElement)
+			{
+				var idx:int = this.getChildIndex(child);
+				var gc:Vector.<ContentElement> = new Vector.<ContentElement>();
+				gc.push(block);
+				groupElement.replaceElements(idx,idx,gc);
+			}
+			else
+			{
+				child.releaseContentElement();
+				
+				var para:ParagraphElement = getParagraph();
+				if (para)
+					para.createTextBlock();
+			}
+		}
+		
+
+		/** @private */
+		tlf_internal override function hasBlockElement():Boolean
+		{
+			return groupElement != null;
+		}
+		
+		/** @private */
+		override tlf_internal function setParentAndRelativeStart(newParent:FlowGroupElement,newStart:int):void
+		{
+			if (newParent == parent)
+				return;
+		
+			// remove textElement from the parent content
+			if (parent && parent.hasBlockElement() && groupElement)
+				parent.removeBlockElement(this,groupElement);
+			if (newParent && !newParent.hasBlockElement() && groupElement)
+				newParent.createContentElement();
+					
+			super.setParentAndRelativeStart(newParent,newStart);
+			
+			// Update the FTE ContentElement structure. If the parent has FTE elements, then create FTE elements for the leaf node 
+			// if it doesn't already have them, and add them in. If the parent does not have FTE elements, release the leaf's FTE
+			// elements also so they match.
+			if (parent && parent.hasBlockElement())
+			{
+				if (!groupElement)
+					createContentElement();
+				else
+					parent.insertBlockElement(this,groupElement);
+			}
+		}
+		
+		/** @private */
+		public override function replaceChildren(beginChildIndex:int,endChildIndex:int,...rest):void
+		{
+			var p:ParagraphElement = this.getParagraph();
+			
+			// are we replacing the last element?
+			var oldLastLeaf:FlowLeafElement = p ? p.getLastLeaf() : null;
+				
+			var applyParams:Array = [beginChildIndex, endChildIndex];
+			super.replaceChildren.apply(this, applyParams.concat(rest));
+			
+			if (p)
+				p.ensureTerminatorAfterReplace(oldLastLeaf);
+		}
+		
+		 /** @private
+		  * Returns the EventDispatcher associated with this SubParagraphGroupElement instance.  Use the functions
+		  * of EventDispatcher such as <code>addEventHandler()</code> and <code>removeEventHandler()</code> to 
+		  * capture events that happen over this SubParagraphGroupElement instance.  
+		  *
+		  * The event handling that you specify is called after this element does its processing.
+		  *
+		  * @playerversion Flash 10
+		  * @playerversion AIR 1.5
+		  * @langversion 3.0
+		  *
+		  * @see flash.events.EventDispatcher
+		  * @see flash.text.engine.TextLineMirrorRegion
+		  */
+		  
+		tlf_internal function getEventMirror(statusMask:uint = CLIENT_ATTACHED_LISTENERS):EventDispatcher
+		{
+			if (!_groupElement)
+			{
+				var para:ParagraphElement = getParagraph();
+				if (para)
+					para.getTextBlock();
+				else
+					createContentElement();
+			}
+			if (_groupElement.eventMirror == null)
+			{				
+				_groupElement.eventMirror = new EventDispatcher();
+			}
+			_attachedListenerStatus |= statusMask;
+			return (_groupElement.eventMirror);
+		}
+
+		/** @private */
+		tlf_internal override function normalizeRange(normalizeStart:uint,normalizeEnd:uint):void
+		{
+			var idx:int = findChildIndexAtPosition(normalizeStart);
+			if (idx != -1 && idx < numChildren)
+			{
+				var child:FlowElement = getChildAt(idx);
+				normalizeStart = normalizeStart-child.parentRelativeStart;
+				
+				CONFIG::debug { assert(normalizeStart >= 0, "bad normalizeStart in normalizeRange"); }
+				for (;;)
+				{
+					// watch out for changes in the length of the child
+					var origChildEnd:int = child.parentRelativeStart+child.textLength;
+					child.normalizeRange(normalizeStart,normalizeEnd-child.parentRelativeStart);
+					var newChildEnd:int = child.parentRelativeStart+child.textLength;
+					normalizeEnd += newChildEnd-origChildEnd;	// adjust
+					
+					// no zero length children
+					if (child.textLength == 0 && !child.bindableElement)
+						replaceChildren(idx,idx+1);
+					else if (child.mergeToPreviousIfPossible())
+					{
+						var prevElement:FlowElement = this.getChildAt(idx-1);
+						// possibly optimize the start to the length of prevelement before the merge
+						prevElement.normalizeRange(0,prevElement.textLength);
+					}
+					else
+						idx++;
+
+					if (idx == numChildren)
+						break;
+					
+					// next child
+					child = getChildAt(idx);
+					
+					if (child.parentRelativeStart > normalizeEnd)
+						break;
+						
+					normalizeStart = 0;		// for the next child	
+				}
+			}
+			// empty subparagraphgroups not allowed after normalize
+			if (numChildren == 0 && parent != null)
+			{
+				var s:SpanElement = new SpanElement();
+				replaceChildren(0,0,s);
+				s.normalizeRange(0,s.textLength);
+			}
+		}
+
+		/** @private */
+		tlf_internal override function canOwnFlowElement(elem:FlowElement):Boolean
+		{
+			// Only allow sub-paragraph group elements (with restrictions) and leaf elements 
+			if (elem is FlowLeafElement)
+				return true;
+			
+			var subParagraphGroupElem:SubParagraphGroupElement = elem as SubParagraphGroupElement;
+			if (subParagraphGroupElem)
+			{ 
+				// Sub-paragraph group elements of the same kind cannot nest, even indirectly.
+				// For example, a link cannot contain a link, nor can it contain a TCY whose child is a link and so on.				
+				// We assume that the two trees being joined are themselves valid, so the above rule can only be violated if
+				// a) elem's type is same as my type
+				// b) elem's type is same as my parent's type
+				// c) an elem's child's type is same as my type
+				// [Note: this is valid only because we have just two kinds of sub-paragraph groups. Any more, and we'll need more
+				// complex rules]  
+
+				var myClass:String = getQualifiedClassName(this);
+				var elemClass:String = getQualifiedClassName(elem);
+				var parentClass:String = parent ? getQualifiedClassName(parent) : null;
+				
+				if (elemClass == myClass || elemClass == parentClass)
+					return false;
+					
+				for (var i:int=0; i<subParagraphGroupElem.numChildren; i++)
+				{
+					if (getQualifiedClassName(subParagraphGroupElem.getChildAt(i)) == myClass)
+						return false;
+				}
+				
+				return true;
+			}
+			
+			return false;
+		}
+		
+		/** Helper function for determination of where text should be inserted.  In the case of LinkElements,
+		 * text inserted before the LinkElement and text inserted after the LinkElement should not become
+		 * par of the link.  However, for most other SubParagraphGroupElements, inserted text should become
+		 * part of the SubParagraphGroupElement.
+		 * @private
+		 * */
+		tlf_internal function acceptTextBefore():Boolean 
+		{ 
+			return true; 
+		}
+		
+		/** Helper function for determination of where text should be inserted.  In the case of LinkElements,
+		 * text inserted before the LinkElement and text inserted after the LinkElement should not become
+		 * par of the link.  However, for most other SubParagraphGroupElements, inserted text should become
+		 * part of the SubParagraphGroupElement.
+		 * @private
+		 * */
+		tlf_internal function acceptTextAfter():Boolean
+		{
+			return true;
+		}
+		
+		/** @private */
+		CONFIG::debug public override function debugCheckFlowElement(depth:int = 0, extraData:String = ""):int
+		{
+			// debugging function that asserts if the flow element tree is in an invalid state
+			var rslt:int = super.debugCheckFlowElement(depth," fte:"+getDebugIdentity(groupElement)+" "+extraData);
+			rslt += assert(getParagraph() != null && (parent is ParagraphElement || parent is SubParagraphGroupElement), "SubParagraphGroupElement must be nested in a pargraph");
+			
+			//groupElement can be null if the Paragraph is overset or not yet composed.  Don't check elementCount - Watson 2283828
+			if(this.groupElement)
+				rslt += assert(this.groupElement.elementCount == this.numChildren,"Bad element count in SubParagraphGroupElement");
+				
+			if (parent is ParagraphElement)
+				rslt += assert(this.groupElement != ParagraphElement(parent).getTextBlock().content,"Bad group");
+			return rslt; 
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/TCYElement.as b/textLayout_core/src/flashx/textLayout/elements/TCYElement.as
new file mode 100755
index 0000000..f0086e1
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/TCYElement.as
@@ -0,0 +1,182 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements
+{
+	import flash.geom.Rectangle;
+	import flash.text.engine.TextLine;
+	import flash.text.engine.TextRotation;
+	
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+	
+	/** 
+	 * The TCYElement (Tatechuuyoko - ta-tae-chu-yo-ko) class is a subclass of SubParagraphGroupElement that causes
+	 * text to draw horizontally within a vertical line.  Traditionally, it is used to make small
+	 * blocks of non-Japanese text or numbers, such as dates, more readable.  TCY can be applied to 
+	 * horizontal text, but has no effect on drawing style unless and until it is turned vertically.
+	 * 
+	 * TCY blocks which contain no text will be removed from the text flow during the normalization process.
+	 * <p>
+	 * In the example below, the image on the right shows TCY applied to the number 57, while the
+	 * image on the left has no TCY formatting.</p>
+	 * <p><img src="../../../images/textLayout_TCYElement.png" alt="TCYElement" border="0"/>
+	 * </p>
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 *
+	 * @see TextFlow
+	 * @see ParagraphElement
+	 * @see SpanElement
+	 */
+	public final class TCYElement extends SubParagraphGroupElement
+	{
+		/** Constructor - creates a new TCYElement instance.
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 */
+		public function TCYElement()
+		{
+			super();
+		}
+		
+		/** @private */
+		override tlf_internal function createContentElement():void
+		{
+			super.createContentElement();
+			updateTCYRotation();
+		}
+		
+		/** @private */
+		override protected function get abstract():Boolean
+		{
+			return false;
+		}		
+		/** @private */
+        tlf_internal override function get precedence():uint { return 100; }
+		
+		/** @private */
+		tlf_internal override function mergeToPreviousIfPossible():Boolean
+		{	
+			if (parent && !bindableElement)
+			{
+				var myidx:int = parent.getChildIndex(this);
+				if (myidx != 0)
+				{
+					var prevEl:TCYElement = parent.getChildAt(myidx - 1) as TCYElement;
+					if(prevEl)
+					{
+						while(this.numChildren > 0)
+						{
+							var xferEl:FlowElement = this.getChildAt(0);
+							replaceChildren(0, 1);
+							prevEl.replaceChildren(prevEl.numChildren, prevEl.numChildren, xferEl);
+						}
+						parent.replaceChildren(myidx, myidx + 1);								
+						return true;
+					}		
+				}
+			}
+			
+			return false;
+		}
+		
+		/** @private */
+		tlf_internal override function acceptTextBefore():Boolean 
+		{ 
+			return false; 
+		}
+		
+		/** @private */
+		tlf_internal override function setParentAndRelativeStart(newParent:FlowGroupElement,newStart:int):void
+		{
+			super.setParentAndRelativeStart(newParent,newStart);
+			updateTCYRotation();
+		}
+		
+		/** @private */
+		tlf_internal override function formatChanged(notifyModelChanged:Boolean = true):void
+		{
+			super.formatChanged(notifyModelChanged);
+			updateTCYRotation();
+		}
+		
+		/** @private */
+		tlf_internal function calculateAdornmentBounds(spg:SubParagraphGroupElement, tLine:TextLine, blockProgression:String, spgRect:Rectangle):void
+		{
+			var childCount:int = 0;
+			while(childCount < spg.numChildren)
+			{
+				var curChild:FlowElement = spg.getChildAt(childCount) as FlowElement;
+				var curFlowLeaf:FlowLeafElement = curChild as FlowLeafElement;
+				if(!curFlowLeaf && curChild is SubParagraphGroupElement)
+				{
+					calculateAdornmentBounds(curChild as SubParagraphGroupElement, tLine, blockProgression, spgRect);
+					++childCount;
+					continue;
+				}
+				
+				CONFIG::debug{ assert(curFlowLeaf != null, "The TCY contains a non-FlowLeafElement!  Cannot calculate mirror!")};
+				var curBounds:Rectangle = null;
+				if(!(curFlowLeaf is InlineGraphicElement))
+					curBounds = curFlowLeaf.getSpanBoundsOnLine(tLine, blockProgression)[0];
+				else
+				{
+					curBounds = (curFlowLeaf as InlineGraphicElement).graphic.getBounds(tLine);
+				}
+				
+				if(childCount != 0)
+				{
+					if(curBounds.top < spgRect.top)
+						spgRect.top = curBounds.top;
+						
+					if(curBounds.bottom > spgRect.bottom)
+						spgRect.bottom = curBounds.bottom;
+					
+					if(spgRect.x > curBounds.x)
+						spgRect.x = curBounds.x;
+				}
+				else
+				{
+					spgRect.top = curBounds.top;
+					spgRect.bottom = curBounds.bottom;
+					spgRect.x = curBounds.x;
+				}
+				++childCount;
+			}
+		}
+		
+		/** @private */
+		private function updateTCYRotation():void
+		{
+			var contElement:ContainerFormattedElement = getAncestorWithContainer();
+			if (groupElement)
+				groupElement.textRotation = (contElement && contElement.computedFormat.blockProgression == BlockProgression.RL) ? TextRotation.ROTATE_270 : TextRotation.ROTATE_0;	
+		}
+	}
+	
+	
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/elements/TabElement.as b/textLayout_core/src/flashx/textLayout/elements/TabElement.as
new file mode 100755
index 0000000..30596a5
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/TabElement.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 flashx.textLayout.elements
+{
+	import flash.text.engine.TextElement;
+	
+	/** 
+	 * The TabElement class represents a &lt;tab/&gt; in the text flow. You assign tab stops as an array of TabStopFormat objects to the 
+	 * <code>ParagraphElement.tabStops</code> property.
+	 * 
+	 * <p><strong>Note</strong>:This class exists primarily to support &lt;tab/&gt; in MXML markup. You can add tab characters (\t) directly 
+	 * into the text like this:</p>
+	 *
+	 * <listing version="3.0" >
+	 * spanElement1.text += '\t';
+	 * </listing>
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 *
+	 * @see flashx.textLayout.formats.TabStopFormat
+	 * @see FlowElement#tabStops
+	 * @see SpanElement
+	 */
+	 
+	public final class TabElement extends SpecialCharacterElement
+	{
+		/** Constructor - creates a new TabElement instance. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function TabElement()
+		{
+			super();
+			this.text = '\t';
+		}			
+		
+		/** @private */
+		override protected function get abstract():Boolean
+		{
+			return false;
+		}		
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/elements/TextFlow.as b/textLayout_core/src/flashx/textLayout/elements/TextFlow.as
new file mode 100755
index 0000000..0f86825
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/TextFlow.as
@@ -0,0 +1,1232 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements
+{
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+	import flash.events.IEventDispatcher;
+	import flash.text.engine.TextLineValidity;
+	import flash.utils.Dictionary;
+	
+	import flashx.textLayout.compose.FlowComposerBase;
+	import flashx.textLayout.compose.IFlowComposer;
+	import flashx.textLayout.compose.ISWFContext;
+	import flashx.textLayout.compose.StandardFlowComposer;
+	import flashx.textLayout.compose.TextFlowLine;
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.debug.Debugging;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.edit.ISelectionManager;
+	import flashx.textLayout.events.CompositionCompleteEvent;
+	import flashx.textLayout.events.DamageEvent;
+	import flashx.textLayout.events.ModelChange;
+	import flashx.textLayout.events.StatusChangeEvent;
+	import flashx.textLayout.external.WeakRef;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormatValueHolder;
+	import flashx.textLayout.property.Property;
+	import flashx.textLayout.tlf_internal;
+		
+	use namespace tlf_internal;
+	
+	/**
+	 *
+	 *  @eventType flashx.textLayout.events.FlowOperationEvent.FLOW_OPERATION_BEGIN
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	 
+	[Event(name="flowOperationBegin", type="flashx.textLayout.events.FlowOperationEvent")]
+	
+	/**
+	 * 
+	 * @eventType flashx.textLayout.events.FlowOperationEvent.FLOW_OPERATION_END
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	 
+	[Event(name="flowOperationEnd", type="flashx.textLayout.events.FlowOperationEvent")]
+	
+	/**
+	 * 
+	 * @eventType flashx.textLayout.events.FlowOperationEvent.FLOW_OPERATION_COMPLETE
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="flowOperationComplete", type="flashx.textLayout.events.FlowOperationEvent")]
+	
+	/** Dispatched whenever the selection is changed.  Primarily used to update selection-dependent user interface. 
+	 * It can also be used to alter the selection, but cannot be used to alter the TextFlow itself.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="selectionChange", type="flashx.textLayout.events.SelectionEvent")]
+	
+	/** Dispatched after every recompose. 
+	*
+	* @playerversion Flash 10
+	* @playerversion AIR 1.5
+	* @langversion 3.0
+	*/
+	
+	[Event(name="compositionComplete", type="flashx.textLayout.events.CompositionCompleteEvent")]
+	
+	/** Dispatched when the mouse is pressed down over any link. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="mouseDown", type="flashx.textLayout.events.FlowElementMouseEvent")]
+	
+	/** Dispatched when the mouse is released over any link. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="mouseUp", type="flashx.textLayout.events.FlowElementMouseEvent")]
+	
+	/** Dispatched when the mouse passes over any link. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="mouseMove", type="flashx.textLayout.events.FlowElementMouseEvent")]	
+	
+	/** Dispatched when the mouse first enters any link. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="rollOver", type="flashx.textLayout.events.FlowElementMouseEvent")]
+	
+	/** Dispatched when the mouse goes out of any link. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="rollOut", type="flashx.textLayout.events.FlowElementMouseEvent")]	
+	
+	/** Dispatched when any link is clicked. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="click", type="flashx.textLayout.events.FlowElementMouseEvent")]
+	
+	/** Dispatched when a InlineGraphicElement is resized due to having width or height as auto or percent 
+	 * and the graphic has finished loading. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="inlineGraphicStatusChanged", type="flashx.textLayout.events.StatusChangeEvent")]
+	
+	/** Dispatched by a TextFlow object after text is scrolled within a controller container.  
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="scroll", type="flashx.textLayout.events.TextLayoutEvent")]
+	
+	/** Dispatched by a TextFlow object each time it is damaged 
+	 * 
+	 * You can use this event to find out that the TextFlow has changed, but do not access the TextFlow itself when this event 
+	 * is sent out. This event is sent when TextFlow changes are partially complete, so it can be in an inconsistent state: 
+	 * some changes have been mad already, and other changes are still pending. Get the information you need from the event, and make 
+	 * required changes after control returns to your application.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="damage", type="flashx.textLayout.events.DamageEvent")]
+
+	/** Dispatched by a TextFlow object each time a container has had new DisplayObjects added or updated as a result of composition.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="updateComplete", type="flashx.textLayout.events.UpdateCompleteEvent")]
+
+
+	/**
+	 * The TextFlow class is responsible for managing all the text content of a story. In TextLayout, text is stored in a 
+	 * hierarchical tree of elements. TextFlow is the root object of the element tree. All elements on the tree
+	 * derive from the base class, FlowElement. 
+	 *
+	 * <p>A TextFlow object can have ParagraphElement and DivElement objects as children. A div (DivElement object)
+	 * represents a group of paragraphs (ParagraphElement objects). A paragraph can have SpanElement, InlineGraphicElement, 
+	 * LinkElement, and TCYElement objects as children.</p>
+	 * 
+	 * <p>A span (SpanElement) is a range of text in a paragraph that has the same attributes. An image 
+	 * (InlineGraphicElement) represents an arbitrary graphic that appears as a single character in a line of text. A 
+	 * LinkElement represents a hyperlink, or HTML <code>a</code> tag, and it can contain multiple spans. A TCYElement object
+	 * is used in Japanese text when there is a small run of text that appears perpendicular to the line, as in a horizontal
+	 * run within a vertical line. A TCYElement also can contain multiple spans.</p>
+	 
+	 * <p>TextFlow also derives from the ContainerFormattedElement class, which is the root class for all container-level block 
+	 * elements.</p>
+ 	 * <p>The following illustration shows the relationship of other elements, such as spans and paragraphs, to the TextFlow 
+ 	 * object.</p>
+ 	 * <p><img src="../../../images/textLayout_textFlowHierarchy.gif" alt="example TextFlow hierarchy"></img></p>
+ 	 *
+ 	 * <p>Each TextFlow object has a corresponding Configuration object that allows you to specify initial character and 
+ 	 * paragraph formats and the initial container format. It also allows you to specify attributes for selection, links, 
+ 	 * focus, and scrolling. When you supply a Configuration object as parameter to the <code>TextFlow()</code>
+ 	 * constructor, it creates a read-only snapshot that you can access through the <code>TextFlow.configuration</code>
+ 	 * property. After creation, you can't change the TextFlow's configuration. If you do not specify a Configuration, you 
+ 	 * can access the default configuration through the <code>TextFlow.defaultConfiguration</code> property.</p>
+	 *
+	 * @includeExample examples\TextFlowExample.as -noswf
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 *
+	 * @see #configuration
+	 * @see IConfiguration
+	 * @see DivElement
+	 * @see FlowElement
+	 * @see FlowGroupElement
+	 * @see FlowLeafElement
+	 * @see flashx.textLayout.compose.IFlowComposer IFlowComposer
+	 * @see ParagraphElement
+	 * @see SpanElement
+	 */
+	 
+	public class TextFlow extends ContainerFormattedElement implements IEventDispatcher
+	{		
+		private var _flowComposer:IFlowComposer;
+		
+		/** References the Selection manager attached to this TextFlow object. */
+		private var _interactionManager:ISelectionManager;
+		
+		/** References the Configuration object for this TextFlow object. */
+		
+		private var _configuration:IConfiguration;
+		
+		/** Manages computing and drawing backgroundColor attribute */
+		private var _backgroundManager:BackgroundManager;
+		
+		/** Default configuration for all new TextFlow objects if the configuration is not specified. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see Configuration
+		 */
+		
+		public static var defaultConfiguration:Configuration = new Configuration();
+				
+		// normalize support
+		private var normalizeStart:int = 0;
+		private var normalizeLen:int = 0;
+		
+		// event dispatch support
+		private var _eventDispatcher:EventDispatcher;
+		
+		// textflow specific generation support - used to validate undo
+		private var _generation:uint;
+		// next generation number to hand out - these just have to be unique so share one.
+		// 0 is reserved to mean "not set"
+		static private var _nextGeneration:uint = 1;
+		
+		// styling support
+		private var _formatResolver:IFormatResolver;
+				
+		/** 
+		 * Constructor - creates a new TextFlow instance.
+		 *
+		 * <p>If you provide a <code>config</code> parameter, the contents of the Configuration object are copied and
+		 * you cannot make changes. You can access configuration settings, however, through the 
+		 * <code>configuration</code> property. If the <code>config</code> parameter is null, you can access the default
+		 * configuration settings through the <code>defaultConfiguration</code> property.</p> 
+		 *
+		 * <p>The Configuration object provides a mechanism for setting configurable default attributes on a TextFlow.  
+		 * While you can't make changes to the Configuration object, you can override default attributes, if necessary, 
+		 * by setting the attributes of TextFlow and its children.</p>
+		 * 
+		 * @param config Specifies the configuration to use for this TextFlow object. If it's null, use 
+		 * <code>TextFlow.defaultConfiguration</code> to access configuration values. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 * 
+	 	 * @see Configuration
+	 	 * @see #configuration
+	 	 * @see #defaultConfiguration
+		 * 
+		 */
+		 
+		public function TextFlow(config:IConfiguration = null)
+		{
+			super();
+			initializeForConstructor(config);
+		}
+		
+		private function initializeForConstructor(config:IConfiguration):void
+		{
+			if (config == null)
+				config = defaultConfiguration;
+			// read only non changing copy of current state
+			_configuration = Configuration(config).getImmutableClone();
+			_eventDispatcher = new EventDispatcher(this);
+	
+			format = _configuration.textFlowInitialFormat;
+			
+			// initialize the flowComposer
+			if (_configuration.flowComposerClass)
+				flowComposer = new _configuration.flowComposerClass();
+			
+			_generation = _nextGeneration++;
+		}
+		
+		/** @private */
+		public override function shallowCopy(startPos:int = 0, endPos:int = -1):FlowElement
+		{		
+			var retFlow:TextFlow = super.shallowCopy(startPos, endPos) as TextFlow;
+			retFlow._configuration = _configuration;
+			retFlow._generation = _nextGeneration++;
+			if (formatResolver)
+				retFlow.formatResolver = formatResolver.getResolverForNewFlow(this,retFlow);
+			// TODO: preserve the hostFormat??
+			// preserve the swfContext
+			if (retFlow.flowComposer && flowComposer)
+				retFlow.flowComposer.swfContext = flowComposer.swfContext;
+			return retFlow;						
+		}
+		
+		/** 
+		* The Configuration object for this TextFlow object. The Configuration object specifies the initial character 
+		* and paragraph formats, the initial container format, and attributes for selection highlighting, 
+		* links, focus, and scrolling.
+		*
+		* <p>If you do not specify a Configuration object, Text Layout Framework uses a default Configuration object, which
+		* is referenced by the <code>defaultConfiguration</code> property.</p>
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+	 	* @see Configuration
+	 	* @see #defaultConfiguration
+	 	*/
+		public function get configuration():IConfiguration
+		{ return _configuration; }
+
+		/**
+		 * The InteractionManager associated with this TextFlow object.
+		 * <p>Controls all selection and editing on the text. If the TextFlow is not selectable, 
+		 * the interactionManager is null. To make the TextFlow editable, assign a interactionManager
+		 * that is both an ISelectionManager and an IEditManager. To make a TextFlow that is read-only
+		 * and allows selection, assign a interactionManager that is an ISelectionManager only. </p>
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+		 * @see flashx.textLayout.edit.ISelectionManager ISelectionManager
+		 * @see flashx.textLayout.edit.IEditManager IEditManager
+		 */
+		public function get interactionManager():ISelectionManager
+		{
+			return _interactionManager;
+		}
+		public function set interactionManager(newInteractionManager:ISelectionManager):void
+		{
+			// detatch old interactionManager
+			if (_interactionManager != newInteractionManager)
+			{
+				if (_interactionManager)
+					_interactionManager.textFlow = null;
+				_interactionManager = newInteractionManager;
+				if (_interactionManager)
+					_interactionManager.textFlow = this;
+				if (flowComposer)
+					flowComposer.interactionManagerChanged(newInteractionManager);
+			}
+		}
+		
+		/** Manages the containers for this element.
+		 * 
+		 * <p>The TextLines that are created from the element appear as children of the container.
+		 * The flowComposer manages the containers, and as the text is edited it adds lines to and removes lines
+		 * from the containers. The flowComposer also keeps track of some critical attributes, such as the
+		 * width and height to compose to, whether scrolling is on, and so on.</p>
+		 * 
+		 * <p>The container and <code>flowComposer</code> are closely related. If you reset <code>flowComposer</code>, 
+		 * the container is reset to the new flowComposer's container. Likewise if the container is reset, 
+		 * <code>flowComposer</code> is reset to the container's new flowComposer.</p>
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see flashx.textLayout.compose.IFlowComposer FlowComposer
+		 */
+		public override function get flowComposer():IFlowComposer
+		{ 
+			return _flowComposer; 
+		}
+		
+		public function set flowComposer(composer:IFlowComposer):void
+		{
+			changeFlowComposer(composer,true);
+		}
+		
+		/** @private */
+		tlf_internal function changeFlowComposer(newComposer:IFlowComposer,okToUnloadGraphics:Boolean):void
+		{
+			if (_flowComposer != newComposer)
+			{
+				var oldSWFContext:ISWFContext = FlowComposerBase.computeBaseSWFContext(_flowComposer ? _flowComposer.swfContext : null);
+				var newSWFContext:ISWFContext = FlowComposerBase.computeBaseSWFContext(newComposer ? newComposer.swfContext : null);					
+				
+				// no flowComposer on the clipboard - we should really delay this until the flowComposer gets its first container and 
+				if (!flowComposer && newComposer || flowComposer && !newComposer)
+					appendElementsForDelayedUpdate(this);
+				
+				// Clear out old settings
+				if (_flowComposer)
+				{
+					//hideSelection is no longer on IFlowComposer, so do it manually
+					var containerIter:int = 0;
+					while(containerIter < _flowComposer.numControllers)
+					{
+						_flowComposer.getControllerAt(containerIter++).clearSelectionShapes();
+					}
+					
+					_flowComposer.setRootElement(null); 	// clear event listeners
+				}
+
+				_flowComposer = newComposer;
+	
+				if (_flowComposer)
+					_flowComposer.setRootElement(this);
+					
+				// Mark flow as damaged
+				if (textLength)
+					damage(getAbsoluteStart(), textLength, TextLineValidity.INVALID, false);
+				
+				if (oldSWFContext != newSWFContext)
+					invalidateAllFormats();
+	
+				// containers *may* have changed requiring reinherit of columnDirection/blockProgression
+				// but that's only in the case when we have ContainerFormattedElements that can have containers -- if then
+				// this call is really expensive for long flows and needs to be optimized for cases when nothing changes
+				// containerFormatChanged(false);
+
+				// no longer visible shut down all the FEs
+				if (flowComposer == null)
+					applyUpdateElements(okToUnloadGraphics);
+			}
+		}
+		
+		/** Returns an element whose <code>id</code> property matches the <code>idName</code> parameter. Provides
+		 * the ability to apply a style based on the <code>id</code>. 
+		 *
+		 * <p>For example, the following line sets the style "color" to 0xFF0000 (red), for the
+		 * element having the <code>id</code> span1.</p>
+		 *
+		 * <listing version="3.0" >
+		 * textFlow.getElementByID("span1").setStyle("color", 0xFF0000);
+		 * </listing>
+		 *
+		 * <p><strong>Note:</strong> In the following code, <code>p.addChild(s)</code> <em>removes</em> <code>s</code> 
+		 * from its original parent and adds it to <code>p</code>, the new parent.</p>
+		 *
+		 * <listing version="3.0" >
+		 * var s:SpanElement = new SpanElement();
+		 * var p:ParagraphElement = new ParagraphElement();
+		 * ...
+		 * s = textFlow.getElementByID("span3") as SpanElement;
+		 * p.addChild(s);
+		 * textFlow.addChild(p);
+		 * </listing>
+		 *
+		 * @param idName The <code>id</code> value of the element to find.
+		 *
+		 * @return The element whose id matches <code>idName</code>.
+		 *
+		 * @includeExample examples\TextFlow_getElementByIDExample.as -noswf
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 *
+		 * @see FlowElement#id 
+		 */
+		
+		public function getElementByID(idName:String):FlowElement
+		{
+			return getElementByIDHelper(idName);
+		}
+		
+		/** Returns all elements that have <code>styleName</code> set to <code>styleNameValue</code>.
+		 *
+		 * @param styleNameValue The name of the style for which to find elements that have it set.
+		 *
+		 * @return An array of the elements whose <code>styleName</code> value matches <code>styleNameValue</code>. For example,
+		 * all elements that have the style name "color".
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 *
+		 * @see FlowElement#styleName 
+		 */
+		public function getElementsByStyleName(styleNameValue:String):Array
+		{
+			var a:Array = new Array;
+			getElementsByStyleNameHelper(a,styleNameValue);
+			return a;
+		}
+
+		/** @private */
+		override protected function get abstract():Boolean
+		{
+			return false;
+		}		
+		
+		/** @private */
+		tlf_internal override function updateLengths(startIdx:int,len:int,updateLines:Boolean):void
+		{
+			if (normalizeStart != -1)
+			{
+				var newNormalizeStart:int = startIdx < normalizeStart ? startIdx : normalizeStart;
+
+				if (newNormalizeStart < normalizeStart)
+					normalizeLen += (normalizeStart-newNormalizeStart);
+				normalizeLen += len;
+				normalizeStart = newNormalizeStart;
+			}
+			else
+			{
+				normalizeStart = startIdx;
+				normalizeLen   = len;
+			}
+			// never go below zero
+			if (normalizeLen < 0)
+				normalizeLen = 0;
+			
+			// fix the lines
+			if (updateLines && _flowComposer)
+			{
+				_flowComposer.updateLengths(startIdx,len);
+				super.updateLengths(startIdx,len, false);
+			}
+			else
+				super.updateLengths(startIdx,len,updateLines);
+		}
+		
+		[RichTextContent]
+		/** @private NOTE: all FlowElement implementers and overrides of mxmlChildren must specify [RichTextContent] metadata */
+		public override function set mxmlChildren(array:Array):void
+		{
+			super.mxmlChildren = array; 
+			normalize();
+			applyWhiteSpaceCollapse();
+		} 
+		
+		/** @private Update any elements that have a delayed updated.  Normally used to stop and stop foreignelements when they 
+		 * are either displayed the first time or removed from the stage
+		 */
+		tlf_internal function applyUpdateElements(okToUnloadGraphics:Boolean):Boolean
+		{
+			if (_elemsToUpdate)
+			{
+				var hasController:Boolean = flowComposer && flowComposer.numControllers != 0;
+				for each (var child:FlowElement in _elemsToUpdate)
+					child.applyDelayedElementUpdate(this,okToUnloadGraphics,hasController);
+				_elemsToUpdate = null;	// expect this array is transient
+				return true;
+			}
+			return false;
+		}
+		
+		/** @private */
+		tlf_internal override function preCompose():void
+		{
+			// normalizes the flow
+			do 
+			{
+				normalize();
+			}	
+				// starts or stops any FEs that have been modified, removed or deleted
+			while (applyUpdateElements(true));
+			
+			// need to call normalize again in case any of the element updates have modified the hierarchy
+			// normalize();
+		}
+	
+		/**
+		 * Mark the a range of text as invalid - needs to be recomposed.
+		 * <p>The text classes are self damaging.  This is only used when modifying the container chain.</p>
+		 * <p>Warning: Plan to evaulate a way to hide this method totally.</p>
+		 * @param start		text index of first character to marked invalid
+		 * @param damageLen	number of characters to mark invalid
+		 * @param needNormalize optional parameter (true is default) - normalize should include this range.
+		 * @private
+		 */
+		tlf_internal function damage(damageStart:int, damageLen:int, damageType:String, needNormalize:Boolean = true):void
+		{
+			CONFIG::debug { assert(damageLen > 0,"must have at least 1 char in damageLen"); }
+				
+			if (needNormalize)
+			{
+				if (normalizeStart == -1)
+				{
+					normalizeStart = damageStart;
+					normalizeLen   = damageLen;
+				}
+				else
+				{
+					if (damageStart < normalizeStart)
+					{
+						var newNormalizeLen:uint = normalizeLen;
+						newNormalizeLen = normalizeStart+normalizeLen - damageStart;
+						if (damageLen > newNormalizeLen)
+							newNormalizeLen = damageLen;
+						normalizeStart = damageStart;
+						normalizeLen = newNormalizeLen;
+					}
+					else if ((normalizeStart+normalizeLen) > damageStart)
+					{
+						if (damageStart+damageLen > normalizeStart+normalizeLen)
+							normalizeLen = damageStart+damageLen-normalizeStart;
+					}
+					else
+						normalizeLen = damageStart+damageLen-normalizeStart;
+				}
+				
+				// clamp to textLength
+				CONFIG::debug { assert(normalizeStart <= textLength,"damage bad length"); }
+				if (normalizeStart+normalizeLen > textLength)
+					normalizeLen = textLength-normalizeStart;
+				// trace("damage damageStart:" + damageStart.toString() + " damageLen:" + damageLen.toString() + " textLength:" + this.textLength + " normalizeStart:" + normalizeStart.toString() + " normalizeLen:"  + normalizeLen.toString() );
+			}
+			
+			if (_flowComposer)
+				_flowComposer.damage(damageStart, damageLen, damageType);
+				
+			if (hasEventListener(DamageEvent.DAMAGE))
+				dispatchEvent(new DamageEvent(DamageEvent.DAMAGE,false,false,this,damageStart,damageLen));
+		}
+			
+		/**
+		 * Find the paragraph at the specified absolute position
+		 * @private
+		 */
+		tlf_internal function findAbsoluteParagraph(pos:int):ParagraphElement
+		{
+			var elem:FlowElement = findLeaf(pos);
+			return elem ? elem.getParagraph() : null;
+		}
+
+		/**
+		 * Find the FlowGroupElement at the absolute position,
+		 * could be synonymous with the paragraph OR a subBlockElement
+		 * @private
+		 */
+		 tlf_internal function findAbsoluteFlowGroupElement(pos:int):FlowGroupElement
+		 {
+		 	var elem:FlowElement = findLeaf(pos);
+		 	return elem.parent;
+		 }
+		
+		/** @private */
+		CONFIG::debug public override function debugCheckFlowElement(depth:int = 0, extraData:String = ""):int
+		{
+			// debugging function that asserts if the flow element tree is in an invalid state
+			
+			var rslt:int = super.debugCheckFlowElement(depth,extraData);
+			
+			// describe the lines
+			if (Debugging.verbose && flowComposer)
+			{
+				for ( var lineIdx:int = 0; lineIdx < flowComposer.numLines; lineIdx++)
+				{
+					var workLine:TextFlowLine = flowComposer.getLineAt(lineIdx);
+					var containerIdx:int = flowComposer.getControllerIndex(workLine.controller);
+					trace("line:",lineIdx,"controller:",containerIdx,workLine.toString());
+				}
+				
+				for (var idx:int = 0; idx < flowComposer.numControllers; idx++)
+				{
+					var controller:ContainerController = flowComposer.getControllerAt(idx);
+					trace("controller:",idx,Debugging.getIdentity(controller),controller.absoluteStart,controller.textLength,controller.compositionWidth,controller.compositionHeight,controller.getContentBounds());
+				}
+			}
+			
+			rslt += assert(parent == null, "TextFlow should not have a parent");
+			rslt += assert(parentRelativeStart == 0, "TextFlow start not zero");
+
+			return rslt;		
+		}
+		
+		/**
+		 * Check the internal consistency of the flow's FlowElement tree.
+		 * @private
+		 * Asserts if the data structures in the flow are invalid.
+		 */
+		CONFIG::debug public function debugCheckTextFlow(validateControllers:Boolean=true):int
+		{
+			var rslt:int = debugCheckFlowElement();
+			
+			if (_flowComposer && validateControllers)
+			{
+				var idx:int;
+				var endPrevController:int = 0;
+				for (idx = 0; idx < flowComposer.numControllers; idx++)
+				{
+					var controller:ContainerController = flowComposer.getControllerAt(idx);
+					if (Debugging.verbose)
+					{
+						trace("controller:",idx,"absoluteStart:",controller.absoluteStart,"textLength:",controller.textLength);
+					}
+					
+					rslt += assert(controller.absoluteStart == endPrevController, "controller has bad start");
+					rslt += assert(controller.textLength >= 0, "controller has bad textLength");
+					endPrevController = controller.absoluteStart+controller.textLength;
+					rslt += assert(endPrevController <= textLength, "textLength may not extend past end of root element!");
+				}
+			}
+			
+			if (_flowComposer is StandardFlowComposer)
+				rslt += StandardFlowComposer(_flowComposer).debugCheckTextFlowLines(validateControllers);
+			return rslt;
+		}
+		
+		/**
+		 * Called after an import to validate that the entire flow textLength needs normalize.
+		 * @private
+		 */
+		 CONFIG::debug public function debugCheckNormalizeAll():void
+		{
+			assert(normalizeStart == 0,"normalizeStart: bad normailzeStart");
+			assert(normalizeLen == textLength,"debugCheckNormalizeAll: bad normalizeLen");
+		}
+		
+		/**
+		 * @copy flash.events.IEventDispatcher#addEventListener()
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+ 		 */
+ 		 
+		public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false): void
+		{
+			_eventDispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
+		}
+
+		/**
+		 * @copy flash.events.IEventDispatcher#dispatchEvent()
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+ 		 */
+ 		 
+		public function dispatchEvent(event:Event):Boolean
+		{
+			return _eventDispatcher.dispatchEvent(event);
+		}
+		
+		/**
+		 * @copy flash.events.IEventDispatcher#hasEventListener()
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+ 		 */
+ 		 
+		public function hasEventListener(type:String):Boolean
+		{
+			return _eventDispatcher.hasEventListener(type);
+		}
+		
+		/**
+		 * @copy flash.events.IEventDispatcher#removeEventListener().
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+ 		 */						
+		public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false): void
+		{
+			_eventDispatcher.removeEventListener(type, listener, useCapture);
+		}
+
+		/**
+		 * @copy flash.events.IEventDispatcher#willTrigger()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+ 		 */								
+		public function willTrigger(type:String):Boolean
+		{
+			return _eventDispatcher.willTrigger(type);
+		}
+		
+		// elements which are images or blocks that *may* have children requiring activation or deactivation
+		private var _elemsToUpdate:Array;
+		
+		/** @private */
+		tlf_internal function appendOneElementForUpdate(elem:FlowElement):void
+		{
+			if (_elemsToUpdate == null)
+				_elemsToUpdate = [ elem ];
+			else
+				_elemsToUpdate.push(elem);
+		}
+		
+		/** @private */
+		tlf_internal function mustUseComposer():Boolean
+		{ 
+			if (_elemsToUpdate == null || _elemsToUpdate.length == 0)
+				return false; 
+				
+			normalize();
+			
+			// anything that doesn't normalize completely forces use of the compser
+			var rslt:Boolean = false;
+			for each (var elem:FlowElement in _elemsToUpdate)
+			{
+				if (elem.updateForMustUseComposer(this))
+					rslt = true;
+			}
+			
+			return rslt;
+		}
+		
+		/** @private */
+		tlf_internal function processModelChanged(changeType:String, elem:FlowElement, changeStart:int, changeLen:int, needNormalize:Boolean, bumpGeneration:Boolean):void
+		{
+			// track added and removed elements while the flow is visible
+			if (flowComposer)
+				elem.appendElementsForDelayedUpdate(this);
+			
+			if (bumpGeneration)
+				_generation = _nextGeneration++;
+			
+			if (changeLen > 0)
+				damage(changeStart+elem.getAbsoluteStart(), changeLen, TextLineValidity.INVALID, needNormalize);
+			
+			if (formatResolver)
+			{
+				switch(changeType)
+				{
+					case ModelChange.ELEMENT_REMOVAL:
+					case ModelChange.ELEMENT_ADDED:
+					case ModelChange.STYLE_SELECTOR_CHANGED:
+						formatResolver.invalidate(elem);
+						elem.formatChanged(false);
+						break;
+				}
+			}
+		}
+		
+		/** 
+		* The generation number for this TextFlow object. The undo and redo operations use the generation number to validate that 
+		* it's legal to undo or redo an operation. The generation numbers must match. 
+		* 
+		* <p>Each model change increments <code>generation</code> so if the generation number changes, you know the 
+		* TextFlow model has changed.</p>
+		* 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*/
+	 	
+		public function get generation():uint
+		{
+			return _generation;
+		}
+		
+		/** used to reset the number backwards after an undo or redo. @private */
+		tlf_internal function setGeneration(num:uint):void
+		{
+			_generation = num;
+		}
+		
+		/** @private */
+		tlf_internal function processAutoSizeImageLoaded(elem:InlineGraphicElement):void
+		{
+			if (flowComposer)
+				elem.appendElementsForDelayedUpdate(this);
+		}
+		
+		/**
+		 * Examine the damaged textLength of the TextFlow and put it in a normal form.  This includes adding spans to empty paragraph and
+		 * merging sibling spans that have the same attributes.
+		 * @private 
+		 */
+		tlf_internal function normalize():void
+		{
+			//trace("NORMALIZE");
+			
+			if (normalizeStart != -1)
+			{
+				var normalizeEnd:int = normalizeStart + (normalizeLen==0?1:normalizeLen);
+				normalizeRange(normalizeStart,normalizeEnd);
+
+				normalizeStart = -1;
+				normalizeLen = 0;				
+			}
+			CONFIG::debug { debugCheckTextFlow(false); }
+		}
+		
+		private var _hostFormatHelper:HostFormatHelper;
+		
+		/** The TextLayoutFormat object for this TextFlow object. This enables several optimizations for reusing 
+		* host formats. For example;
+		*
+		* <listing>
+		* textFlowA.hostFormat = textFlowB.hostFormat
+		* </listing>
+		* 
+		* You must set format values before assigning the TextLayoutFormat object to <code>hostFormat</code>.
+		* For example, the following lines do <em>not</em> set the font size to 24 because
+		* the font size is set <em>after</em> the TextLayoutFormat object has been assigned to <code>hostFormat</code>.
+		*
+		* <listing>
+		* format = new TextLayoutFormat()
+		* textFlow.hostFormat = format
+		* format.fontSize = 24;
+		* </listing>
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*
+	 	* @see flashx.textLayout.formats.ITextLayoutFormat ITextLayoutFormat
+	 	*/
+	 	
+		public function get hostFormat():ITextLayoutFormat
+		{ return _hostFormatHelper ? _hostFormatHelper.format : null; }
+		public function set hostFormat(value:ITextLayoutFormat):void
+		{
+			if (value == null)
+				_hostFormatHelper = null;
+			else
+			{
+				if (_hostFormatHelper == null)
+					_hostFormatHelper = new HostFormatHelper();
+				_hostFormatHelper.format = value;
+			}
+			formatChanged();
+		}
+		/** @private */
+		tlf_internal function getDefaultFormat():ITextLayoutFormat
+		{
+			if (_hostFormatHelper == null)
+				return TextLayoutFormat.defaultFormat;
+
+			return _hostFormatHelper.computedFormat;
+		}
+		/** @private */
+		tlf_internal function getDefaultFormatHash():uint
+		{
+			// note it calls getDefaultFormat which will force computedFormat to be called and getComputedTextLayoutFormatHash will be valid
+			return getDefaultFormat() == TextLayoutFormat.defaultFormat ? TextLayoutFormat.getDefaultFormatHash() : _hostFormatHelper.getComputedTextLayoutFormatHash();
+		}
+		
+		
+		/** Use the formatResolver to get the character style of an Object.
+		 * @param elem is either a FlowElement or a ContainerController(doesn't happen for characterformat)
+		 * @return any styled CharacterFormat for that element
+		 * @private
+		 */
+		tlf_internal function getTextLayoutFormatStyle(elem:Object):ITextLayoutFormat
+		{
+			return _formatResolver != null ? (_formatResolver.resolveFormat(elem) as ITextLayoutFormat) : null;
+		}
+		
+		/** @private */
+		tlf_internal function set backgroundManager(bgm:BackgroundManager):void
+		{
+			if(_backgroundManager)
+				_backgroundManager.textFlow = null;
+			_backgroundManager = bgm;
+			if(_backgroundManager)
+				_backgroundManager.textFlow = this;
+		}
+		
+		/** @private */
+		tlf_internal function get backgroundManager():BackgroundManager
+		{
+			return _backgroundManager;
+		}
+		
+		/** A callback function for resolving element styles. You can use this to provide styling using CSS or 
+		 * named styles, for example. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see IFormatResolver
+		 */
+		 
+		public function get formatResolver(): IFormatResolver
+		{ 
+			return _formatResolver; 
+		}
+		public function set formatResolver(val:IFormatResolver):void
+		{
+			if (_formatResolver != val)
+			{
+				if (_formatResolver)
+					_formatResolver.invalidateAll(this);
+				_formatResolver = val;
+				if (_formatResolver)
+					_formatResolver.invalidateAll(this);
+					
+				formatChanged(true);
+			}
+		}
+		
+		/** Invalidates all formatting information for the TextFlow, forcing it to be recomputed.
+		 * Call this method when styles have changed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+	 	 * @see IFormatResolver#invalidateAll()
+		 */
+		 
+		public function invalidateAllFormats():void
+		{
+			if (_formatResolver)
+				_formatResolver.invalidateAll(this);
+			if (GlobalSettings.fontMapperFunction != null)
+				FlowLeafElement.clearElementFormatsCache(); // clear out possibly stale mappings between computed TextLayoutFormats and ElementFormats
+			formatChanged(true);
+		}
+		
+		/** @private */
+		static private var _dictionary:Dictionary = new Dictionary();
+		 
+		static private var _seeksSinceLastPurge:int = 0;
+
+		/** @private */
+		CONFIG::debug static tlf_internal var _dictionarySeeks:Number = 0;
+
+		/** @private */
+		CONFIG::debug static tlf_internal var _dictionaryHits:Number = 0;
+
+		/** @private */
+		CONFIG::debug static tlf_internal var _dictionaryCollisions:Number = 0;
+
+		/** @private */		
+		CONFIG::debug static tlf_internal var _emptyRef:int = 0;
+		
+		/** Gets the canonical TextLayoutFormat object that is equal to incoming.
+		 * This class maintains a collection of TextLayoutFormat objects no two of which are functionally equivalent.
+		 * To reduce memory consumption, code elsewhere that intends to hold references to TextLayoutFormat objects
+		 * should refer to these 'canonical' objects -- obtained by calling this method.
+		 * Note: If no TextLayoutFormat object equal to incoming already exists in the collection, a new one is created and added.
+		 * This function never returns null unless incoming is null.
+		 * @param incoming the object whose canonical equivalent is requested
+		 * @param addDefaults whether incoming already includes defaults. If not, defaults will be concatenated before lookup.
+		 * @return the canonical object equal to incoming
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @private
+		 */
+		static tlf_internal function getCanonical(incoming:TextLayoutFormatValueHolder,defaultFormat:ITextLayoutFormat,defaultFormatHash:uint):ITextLayoutFormat
+		{
+			if (defaultFormat == null)
+			{
+				defaultFormat = TextLayoutFormat.defaultFormat;
+				defaultFormatHash = TextLayoutFormat.getDefaultFormatHash();
+			}
+			
+			if (incoming == null)
+				return defaultFormat;
+				
+			CONFIG::debug { _dictionarySeeks++; }
+			
+			_seeksSinceLastPurge++;
+			
+			// The cache dictionary never garbage collects any entries - even though it constructed with weakKeys the keys are uints and so don't get gc'ed
+			// Every 1000 seeks iterate over the values in the dicitionary and delete dictionary entries with garbage collected values
+			// note iteratiing over the keys returns strings which require a string to uint conversion and another lookup.  Storing the keys in the values saves this work.
+			if (_seeksSinceLastPurge == 1000)
+			{
+				for each ( var item:Object in _dictionary )
+				{
+					if (item.format.get() == null)
+						delete _dictionary[item.hash];
+				}
+				_seeksSinceLastPurge = 0;
+			}
+					
+			/*CONFIG::debug
+			{
+				if((_dictionarySeeks % 100) == 0)
+				{
+					var dictLen:int = 0;
+					var emptySlot:int = 0;
+					for each ( item in _dictionary )
+					{
+						if (item.format.get() == null)
+							emptySlot++;
+						dictLen++;
+					}
+
+					trace("TextLayoutFormat.getCanonical Seeks:" + _dictionarySeeks + " Hits:" + _dictionaryHits + " Collisions:" + _dictionaryCollisions + " EmptyRefs:" + _emptyRef + " DictLength:" + dictLen + " EmptySlots:" + emptySlot);
+				}
+			}*/
+			var hash:uint = incoming.hash(defaultFormatHash);
+
+			var cacheObject:Object = _dictionary[hash];
+			if (cacheObject)
+			{
+				var format:TextLayoutFormat = cacheObject.format.get();
+				if (format)
+				{
+					if (defaultFormat == cacheObject.defaultFormat && Property.equalCoreStyles(incoming.coreStyles,cacheObject.coreStyles,TextLayoutFormat.description))
+					{
+						CONFIG::debug {_dictionaryHits++;}				
+						return format;
+					}
+					
+					CONFIG::debug {_dictionaryCollisions++;}	
+				}
+				else
+				{
+					CONFIG::debug { _emptyRef++; }
+				}
+				// Handled below; previous object bumped out
+			}
+			
+			var newFormat:TextLayoutFormat = new TextLayoutFormat(incoming);
+			newFormat.concat(defaultFormat);
+			
+			cacheObject = new Object();
+			cacheObject.coreStyles = Property.shallowCopy(incoming.coreStyles);
+			cacheObject.format = new WeakRef(newFormat);
+			cacheObject.defaultFormat = defaultFormat;
+			cacheObject.hash = hash
+			_dictionary[hash] = cacheObject;
+			
+			/* CONFIG::debug 
+			{
+				for each (var prop:Property in TextLayoutFormat.description)
+				{
+					assert(newFormat[prop.name] !== undefined,"BAD CASCADE");
+				}
+			} */
+
+			return newFormat;
+		}
+	} // end TextFlow class
+}
+import flash.utils.Dictionary;
+
+import flashx.textLayout.debug.assert;
+import flashx.textLayout.formats.TextLayoutFormat;
+import flashx.textLayout.formats.ITextLayoutFormat;
+import flashx.textLayout.tlf_internal;
+
+use namespace tlf_internal;
+
+/** @private.  Expected usage is that all values are set. */
+class HostFormatHelper
+{
+	static private const computedFormatCache:Dictionary = new Dictionary(true);
+
+	private var _format:ITextLayoutFormat;
+	
+	public function get format():ITextLayoutFormat
+	{ return _format; }
+	public function set format(value:ITextLayoutFormat):void
+	{ _format = value; _computedFormat = null; }
+	
+	private var _computedFormat:ITextLayoutFormat;
+	private var _computedFormatHash:uint;
+	
+	public function get computedFormat():ITextLayoutFormat
+	{ 
+		if (_computedFormat)
+			return  _computedFormat;
+				
+		var cacheObject:Object = computedFormatCache[_format];
+
+		if (cacheObject == null)
+		{
+			var format:TextLayoutFormat = new TextLayoutFormat(format);
+			format.concat(TextLayoutFormat.defaultFormat);
+				
+			cacheObject = new Object();
+			cacheObject.format = format;
+			cacheObject.hash = format.hash(0);
+			computedFormatCache[_format] = cacheObject;
+			//trace("Miss");
+		}
+		// else trace("Hit");
+
+		_computedFormat = cacheObject.format;
+		_computedFormatHash = cacheObject.hash;		
+		return _computedFormat;
+	}
+	
+	public function getComputedTextLayoutFormatHash():uint
+	{
+		CONFIG::debug { assert( _computedFormat != null, " bad call to getComputedTextLayoutFormatHash"); }
+		return _computedFormatHash; 
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/elements/TextRange.as b/textLayout_core/src/flashx/textLayout/elements/TextRange.as
new file mode 100755
index 0000000..15eb91b
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/elements/TextRange.as
@@ -0,0 +1,169 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.elements
+{
+	import flashx.textLayout.elements.TextFlow;
+	
+	/**
+	 * A read only class that describes a range of contiguous text. Such a range occurs when you select a
+	 * section of text. The range consists of the anchor point of the selection, <code>anchorPosition</code>,
+	 * and the point that is to be modified by actions, <code>activePosition</code>.  As block selections are 
+	 * modified and extended <code>anchorPosition</code> remains fixed and <code>activePosition</code> is modified.  
+	 * The anchor position may be placed in the text before or after the active position.
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 *
+	 * @see flashx.textLayout.elements.TextFlow TextFlow
+	 * @see flashx.textLayout.edit.SelectionState SelectionState
+	 */
+	public class TextRange
+	{
+		/** The TextFlow of the selection.
+ 	 	 */
+		private var _textFlow:TextFlow;
+		
+		// current range of selection
+		/** Anchor point of the current selection, as an absolute position in the TextFlow. */
+		private var _anchorPosition:int;
+		/** Active end of the current selection, as an absolute position in the TextFlow. */
+		private var _activePosition:int;
+		
+		private function clampToRange(index:int):int
+		{
+			if (index < 0)
+				return 0;
+			if (index > _textFlow.textLength)
+				return _textFlow.textLength;
+			return index;
+		}
+		
+		/** Constructor - creates a new TextRange instance.  A TextRange can be (-1,-1), indicating no range, or a pair of 
+		* values from 0 to <code>TextFlow.textLength</code>.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 * @param	root	the TextFlow associated with the selection.
+		 * @param anchorIndex	the index position of the anchor in the selection. The first position in the text is position 0.
+		 * @param activeIndex	the index position of the active location in the selection. The first position in the text is position 0. 
+		 *
+		 * @see FlowElement#textLength
+		 */		
+		public function TextRange(root:TextFlow,anchorIndex:int,activeIndex:int)
+		{
+			_textFlow = root;
+			
+			if (anchorIndex != -1 || activeIndex != -1)
+			{
+				anchorIndex = clampToRange(anchorIndex);
+				activeIndex = clampToRange(activeIndex);
+			}
+			
+			_anchorPosition = anchorIndex;
+			_activePosition = activeIndex;
+		}
+		
+		/** Update the range with new anchor or active position values.
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 *  @param newAnchorPosition	the anchor index of the selection.
+		 *  @param newActivePosition	the active index of the selection.
+		 *  @return true if selection is changed.
+		 */
+		public function updateRange(newAnchorPosition:int,newActivePosition:int):Boolean
+		{
+			if (newAnchorPosition != -1 || newActivePosition != -1)
+			{
+				newAnchorPosition = clampToRange(newAnchorPosition);
+				newActivePosition = clampToRange(newActivePosition);
+			}
+			
+			if (_anchorPosition != newAnchorPosition || _activePosition != newActivePosition)
+			{
+				_anchorPosition = newAnchorPosition;
+				_activePosition = newActivePosition;
+				return true;
+			}
+			return false;
+		}
+		
+		/** Returns the TextFlow associated with the selection.
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */						
+		public function get textFlow():TextFlow
+		{ return _textFlow; }
+		public function set textFlow(value:TextFlow):void
+		{ _textFlow = value; }
+		
+		/** Anchor position of the selection, as an absolute position in the TextFlow.
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */								
+		public function get anchorPosition():int
+		{ return _anchorPosition; }
+		public function set anchorPosition(value:int):void
+		{ _anchorPosition = value; }
+		
+		/** Active position of the selection, as an absolute position in the TextFlow.
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */										
+		public function get activePosition():int
+		{ return _activePosition; }
+		public function set activePosition(value:int):void
+		{ _activePosition = value; }
+		
+		/** Start of the selection, as an absolute position in the TextFlow.
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */										
+		public function get absoluteStart():int
+		{ return _activePosition < _anchorPosition ? _activePosition : _anchorPosition; }
+		public function set absoluteStart(value:int):void
+		{
+			if (_activePosition < _anchorPosition)
+				_activePosition = value;
+			else
+				_anchorPosition = value;
+		}
+		
+		/** End of the selection, as an absolute position in the TextFlow.
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */								
+		public function get absoluteEnd():int
+		{ return _activePosition > _anchorPosition ? _activePosition : _anchorPosition; }
+		public function set absoluteEnd(value:int):void
+		{
+			if (_activePosition > _anchorPosition)
+				_activePosition = value;
+			else
+				_anchorPosition = value;
+		}		
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/events/CompositionCompleteEvent.as b/textLayout_core/src/flashx/textLayout/events/CompositionCompleteEvent.as
new file mode 100755
index 0000000..e4332a5
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/events/CompositionCompleteEvent.as
@@ -0,0 +1,127 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.events
+{
+	import flash.events.Event;
+	import flashx.textLayout.elements.TextFlow;
+	
+	/** 
+	 * A TextFlow instance dispatches this event after a compose operation completes. 
+	 * Each text container has two states: composition and display. This event notifies
+	 * you when the composition phase has ended. This provides an opportunity to make any
+	 * necessary and appropriate changes to the container before you display the text. 
+	 * For example, you can use this event to add highlighting of certain words or
+	 * characters in the text flow before the text is displayed.
+	 * 
+	 * <p>The three main methods that dispatch this event are <code>compose()</code>, 
+	 * <code>updateToController()</code>, and <code>updateAllControllers()</code>.
+	 * All three of these methods are in the StandardFlowComposer class.</p>
+	 *
+	 * <p><strong>Note: </strong>If the event is dispatched by the
+	 * <code>updateAllControllers()</code> method, do not call 
+	 * <code>updateAllControllers()</code> again in your event handler function.
+	 * Such a call would be a recursive call because the <code>updateAllControllers()</code> 
+	 * method executes both the composition and display steps. The <code>updateAllControllers()</code>
+	 * dispatches this event after composition completes, but before the display step executes.
+	 * The same reasoning applies to the <code>updateToController()</code> method.
+	 * </p>
+	 *
+	 * @includeExample examples\CompositionCompleteEvent_example.as -noswf
+	 *
+	 * @see flashx.textLayout.elements.TextFlow 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class CompositionCompleteEvent extends Event
+	{
+	    /** 
+	     * Defines the value of the <code>type</code> property of a <code>compositionComplete</code> event object 
+	     * @playerversion Flash 10
+	     * @playerversion AIR 1.5
+	     * @langversion 3.0 
+	     */
+	    public static const COMPOSITION_COMPLETE:String = "compositionComplete";
+		
+		
+		//temporary removal of params until Flex removes references to old CompositionCompletionEvent
+		private var _compositionStart:int;
+		private var _compositionLength:int;
+		private var _textFlow:TextFlow;	
+		
+		/** Constructor
+		 * @param type event type - use the static property COMPOSITION_COMPLETE.
+		 * @param bubbles Indicates whether an event is a bubbling event. This event does not bubble.
+		 * @param cancelable Indicates whether the behavior associated with the event can be prevented.
+		 * This event cannot be cancelled.
+		 * @param textFlow The TextFlow which was composed
+		 * @param compositionStart start of composition, in terms of an index into the text flow.
+		 * @param compositionLength length number of characters composed
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 **/
+		public function CompositionCompleteEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false, textFlow:TextFlow =  null, compositionStart:int=0, compositionLength:int=0)
+		{
+			_compositionStart = compositionStart;
+			_compositionLength = compositionLength;
+			_textFlow = textFlow
+			super(type, bubbles, cancelable);
+		}
+		
+      	/** @private */
+		override public function clone():Event
+		{
+			return new CompositionCompleteEvent(type, bubbles, cancelable, textFlow, compositionStart, compositionLength);
+		}
+		
+		/** 
+		 * The start location of the text range affected by the composition, expressed as an index into the text flow.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 		 
+		 */
+		public function get compositionStart():int
+		{ return _compositionStart; }		
+		public function set compositionStart(value:int):void
+		{ _compositionStart = value; }		
+		
+		/** 
+		 * The number of characters composed.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function get compositionLength():int
+		{ return _compositionLength; }
+		public function set compositionLength(value:int):void
+		{ _compositionLength = value; }
+		
+		/**
+		 * TextFlow on which composition has been completed. 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get textFlow():TextFlow
+		{ return _textFlow; }
+		public function set textFlow(value:TextFlow):void
+		{ _textFlow = value; }
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/events/DamageEvent.as b/textLayout_core/src/flashx/textLayout/events/DamageEvent.as
new file mode 100755
index 0000000..d371fa5
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/events/DamageEvent.as
@@ -0,0 +1,97 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.events
+{
+	import flash.events.Event;
+	
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.TextFlow;
+	
+	/** 
+	 * A TextFlow instance dispatches this each time it is marked as damaged.  Damage can be caused by changes to the model or changes to the layout.
+	 * 
+	 * @includeExample examples\DamageEvent_example.as -noswf
+	 * 
+	 * @see flashx.textLayout.elements.TextFlow 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class DamageEvent extends Event
+	{
+		/** Event type for DamageEvent */
+	    public static const DAMAGE:String = "damage";
+
+		private var _textFlow:TextFlow;
+		private var _damageAbsoluteStart:int;
+		private var _damageLength:int;	
+		
+		/** Constructor
+		 * @param damageAbsoluteStart text index of the start of the damage
+		 * @param damageLength length of text that was damaged
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function DamageEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false, textFlow:TextFlow =  null, damageAbsoluteStart:int = 0, damageLength:int = 0)
+		{
+			_textFlow = textFlow;
+			_damageAbsoluteStart = damageAbsoluteStart;
+			_damageLength = damageLength;
+			super(type, bubbles, cancelable);
+		}
+		
+      	/** @private */
+		override public function clone():Event
+		{
+			return new DamageEvent(type, bubbles, cancelable, _textFlow, _damageAbsoluteStart, _damageLength);
+		}
+		
+		/**
+		 * TextFlow owning the damage 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+
+		public function get textFlow():TextFlow
+		{ return _textFlow; }
+		
+		/**
+		 * Absolute start of the damage 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+
+		public function get damageAbsoluteStart():int
+		{ return _damageAbsoluteStart; }
+		
+		/**
+		 * Length of the damage 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+
+		public function get damageLength():int
+		{ return _damageLength; }
+	}
+}
+
diff --git a/textLayout_core/src/flashx/textLayout/events/FlowElementMouseEvent.as b/textLayout_core/src/flashx/textLayout/events/FlowElementMouseEvent.as
new file mode 100755
index 0000000..abc53f3
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/events/FlowElementMouseEvent.as
@@ -0,0 +1,160 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.events
+{
+	import flash.events.Event;
+	import flash.events.MouseEvent;
+	import flashx.textLayout.elements.FlowElement;
+			
+	/** A LinkElement dispatches this event when it detects mouse activity.
+	 * The Text Layout Framework includes this special version of mouse events
+	 * because mouse events are generally unwanted when a link element is
+	 * embedded in an editable text flow. 
+	 * <p>You can add an event listener to a LinkElement to listen for this
+	 * type of event. If you choose to cancel the event by calling
+	 * <code>Event.preventDefault()</code>, the default behavior associated
+	 * with the event will not occur.
+	 * </p>
+	 * <p>If you choose not to add an event listener to the LinkElement, or
+	 * your event listener function does not cancel the behavior, the 
+	 * event is again dispatched, but this time by the LinkElement's
+	 * associated TextFlow instance rather than by the LinkElement itself. 
+	 * This provides a second opportunity to listen for this event with
+	 * an event listener attached to the TextFlow. 
+	 * </p>
+	 * <p>FlowElementMouseEvents are
+	 * dispatched only when the text cannot be edited or when the control key 
+	 * is pressed concurrently with the mouse activity.</p>
+	 * <p>
+	 * The following six event types are dispatched only when the text
+	 * cannot be edited or when the control key is pressed:
+	 * <ul>
+	 *   <li><code>MouseEvent.CLICK</code></li>
+	 *   <li><code>MouseEvent.MOUSE_DOWN</code></li>
+	 *   <li><code>MouseEvent.MOUSE_OUT</code></li>
+	 *   <li><code>MouseEvent.MOUSE_UP</code></li>
+	 *   <li><code>MouseEvent.ROLL_OVER</code></li>
+	 *   <li><code>MouseEvent.ROLL_OUT</code></li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @includeExample examples\FlowElementMouseEvent_example.as -noswf
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 * @see flashx.textLayout.elements.LinkElement
+	 */
+	public class FlowElementMouseEvent extends Event
+	{
+		
+		public static const MOUSE_DOWN:String = "mouseDown";
+		public static const MOUSE_UP:String = "mouseUp";	
+		public static const MOUSE_MOVE:String = "mouseMove";			
+		public static const ROLL_OVER:String = "rollOver";
+		public static const ROLL_OUT:String = "rollOut";	
+		public static const CLICK:String = "click";
+
+		private var _flowElement:FlowElement;
+		private var _originalEvent:MouseEvent;
+		
+		/** 
+		 * The LinkElement that dispatched the event.
+		 *
+		 * @see flashx.textLayout.elements.LinkElement
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function get flowElement():FlowElement
+		{ return _flowElement; }		
+		public function set flowElement(value:FlowElement):void
+		{ _flowElement = value; }
+		
+		/** 
+		 * The original mouse event generated by the mouse activity. 
+		 * This property can contain any of the following values:
+		 * <ul>
+		 *   <li><code>MouseEvent.CLICK</code></li>
+		 *   <li><code>MouseEvent.MOUSE_DOWN</code></li>
+		 *   <li><code>MouseEvent.MOUSE_OUT</code></li>
+		 *   <li><code>MouseEvent.MOUSE_UP</code></li>
+		 *   <li><code>MouseEvent.MOUSE_OVER</code></li>
+		 *   <li><code>MouseEvent.MOUSE_OUT</code></li>
+		 * </ul>
+		 * <p>
+		 * In most cases the original event matches the event that the
+		 * LinkElement dispatches. The events match for the <code>click</code>,
+		 * <code>mouseDown</code>, <code>mouseOut</code>, and <code>mouseOver</code>
+		 * events. There are two cases, however, in which the original event
+		 * is converted by the LinkElement to a related event. 
+		 * If a LinkElement detects a <code>mouseOver</code> event, it dispatches
+		 * a <code>rollOver</code> event. Likewise, if a LinkElement detects
+		 * a <code>mouseOut</code> event, it dispatches a <code>rollOut</code> event.
+		 * </p>
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 * @see flash.events.MouseEvent
+		 */
+		public function get originalEvent():MouseEvent
+		{ return _originalEvent; }		
+		public function set originalEvent(value:MouseEvent):void
+		{ _originalEvent = value; }
+				
+		/** 
+		 * Creates an event object that contains information about mouse activity.
+		 * Event objects are passed as parameters to event listeners. Use the
+		 * constructor if you plan to manually dispatch an event. You do not need
+		 * to use the constructor to listen for FlowElementMouseEvent objects
+		 * generated by a LinkElement.
+		 * @param type  The type of the event. Event listeners can access this information through the
+		 * inherited <code>type</code> property. There are six types:
+		 * <code>MouseEvent.CLICK</code>; <code>MouseEvent.MOUSE_DOWN</code>; <code>MouseEvent.MOUSE_OUT</code>;
+		 * <code>MouseEvent.MOUSE_UP</code>; <code>MouseEvent.ROLL_OVER</code>; and <code>MouseEvent.ROLL_OUT</code>.
+		 * @param bubbles Determines whether the Event object participates in the bubbling phase of the
+		 * event flow. FlowElementMouseEvent objects do not bubble.
+		 * @param cancelable Determines whether the Event object can be canceled. Event listeners can
+		 * access this information through the inherited <code>cancelable</code> property. FlowElementMouseEvent
+		 * objects can be cancelled. You can cancel the default behavior associated with this event
+		 * by calling the <code>preventDefault()</code> method in your event listener.
+		 * @param flowElement The instance of FlowElement, usually a LinkElement, associated with this
+		 * event. Event listeners can access this information through the <code>flowElement</code> property.
+		 * @param originalEvent The original mouse event that occurred on the flowElement. Event listeners can 
+		 * access this information through the <code>originalEvent</code> property.
+
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function FlowElementMouseEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = true, flowElement:FlowElement = null, originalEvent:MouseEvent = null)
+		{
+			super(type, bubbles, cancelable);
+			_flowElement = flowElement;
+			_originalEvent = originalEvent;
+        }
+        
+        /** @private */
+        override public function clone():Event
+        {
+        	return new FlowElementMouseEvent(type, bubbles, cancelable, flowElement, originalEvent);
+        }
+        
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/events/ModelChange.as b/textLayout_core/src/flashx/textLayout/events/ModelChange.as
new file mode 100755
index 0000000..cc23230
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/events/ModelChange.as
@@ -0,0 +1,38 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.events
+{
+	
+	/** ModelChange values.  These are various types of model change. @private */
+	public final class ModelChange
+	{
+		public static const ELEMENT_ADDED:String    = "elementAdded";
+		public static const ELEMENT_REMOVAL:String  = "elementRemoval";
+		public static const ELEMENT_MODIFIED:String = "elementModified";		
+		
+		public static const TEXTLAYOUT_FORMAT_CHANGED:String = "formatChanged";
+		
+		public static const TEXT_INSERTED:String = "textInserted";
+		public static const TEXT_DELETED:String  = "textDeleted";
+		
+		public static const STYLE_SELECTOR_CHANGED:String = "styleSelectorChanged";
+		
+		public static const USER_STYLE_CHANGED:String = "userStyleChanged";
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/events/StatusChangeEvent.as b/textLayout_core/src/flashx/textLayout/events/StatusChangeEvent.as
new file mode 100755
index 0000000..4b1153a
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/events/StatusChangeEvent.as
@@ -0,0 +1,125 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.events
+{
+	import flash.events.ErrorEvent;
+	import flash.events.Event;
+	
+	import flashx.textLayout.elements.FlowElement;
+	
+	/** 
+	 * A TextFlow instance dispatches this event when the status of a FlowElement changes. 
+	 * This event can be used to detect when an inline graphic element has
+	 * completed loading. You can use your event handler to recompose the text flow
+	 * based on the presence of the newly loaded inline graphic element.
+	 *
+	 * @includeExample examples\StatusChangeEvent_example.as -noswf
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class StatusChangeEvent extends Event
+	{
+	    /** 
+	     * Defines the value of the <code>type</code> property of a <code>inlineGraphicStatusChanged</code> event object.
+	     * @playerversion Flash 10
+	     * @playerversion AIR 1.5
+	     * @langversion 3.0 
+	     */
+	    public static const INLINE_GRAPHIC_STATUS_CHANGE:String = "inlineGraphicStatusChange";
+	    
+	    private var _element:FlowElement;
+	    private var _status:String;
+	    private var _errorEvent:ErrorEvent;
+
+		/** Creates an event object that contains information about a status change.
+		 * @param type		The type of the event. Event listeners can access this information through the
+		 * inherited <code>type</code> property. There is only one type of StatusChangeEvent: 
+		 * <code>StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE</code>; 
+		 * @param bubbles 	Indicates whether an event is a bubbling event.This event does not bubble.
+		 * @param cancelable 	Indicates whether the behavior associated with the event can be prevented.
+		 * This event cannot be cancelled.
+		 * @param element The FlowElement instance that has experienced a change in status.
+		 * @param newStatus The FlowElement instance's new status.
+		 * @param e The ErrorEvent object, if any, associated with the status.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 **/
+		public function StatusChangeEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false, element:FlowElement = null,status:String = null,errorEvent:ErrorEvent = null)
+		{
+			_element = element;
+			_status = status;
+			_errorEvent = errorEvent;
+			super(type, false, false);
+		}
+		
+      	/** @private */
+		override public function clone():Event
+		{
+			return new StatusChangeEvent(type,bubbles,cancelable,_element,_status,_errorEvent);
+		}
+		
+		/** 
+		 * The FlowElement instance that has experienced a change in status. 
+		 * @see flashx.textLayout.elements.FlowElement
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function get element():FlowElement
+		{ return _element; }		
+		public function set element(value:FlowElement):void
+		{ _element = value; }		
+		
+		/**
+		 * The FlowElement's new status. The possible values of this property are
+		 * defined by the InlineGraphicElementStatus class. There are five static constants
+		 * available in the InlineGraphicElementStatus class:
+		 * <ul>
+		 *   <li>ERROR : String = "error". An error occurred during loading of a referenced graphic.</li>
+		 *   <li>LOADING : String = "loading". Load has been initiated (but not completed) on a graphic element that is a URL.</li>
+		 *   <li>LOAD_PENDING : String = "loadPending". Graphic element is an URL that has not been loaded.</li>
+		 *   <li>READY : String = "ready". Graphic is completely loaded and properly sized.</li>
+		 *   <li>SIZE_PENDING : String = "sizePending". Graphic element with auto or percentage width/height has completed loading but has not been recomposed.</li>
+		 * </ul>
+		 *
+		 * @see flashx.textLayout.elements.InlineGraphicElementStatus
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function get status():String
+		{ return _status; }
+		public function set status(value:String):void
+		{ _status = value; }
+		
+		/** 
+		 * The ErrorEvent object that was dispatched as a result of the status change. 
+		 * @see flash.events.ErrorEvent
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function get errorEvent():ErrorEvent
+		{ return _errorEvent; }
+		public function set errorEvent(value:ErrorEvent):void
+		{ _errorEvent = value; }
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/events/TextLayoutEvent.as b/textLayout_core/src/flashx/textLayout/events/TextLayoutEvent.as
new file mode 100755
index 0000000..56f751c
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/events/TextLayoutEvent.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 flashx.textLayout.events
+{
+	import flash.events.Event;
+	
+	/**
+	 * A TextLayoutEvent instance represents an event, such as the 
+	 * <code>TextLayoutEvent.SCROLL</code> event, that does not require
+	 * custom properties. 
+	 * <p>A scroll event is represented by a TextLayoutEvent instance with its 
+	 * <code>type</code> property set to <code>TextLayoutEvent.SCROLL</code>.
+	 * A class specifically for scroll events is not necessary because there are
+	 * no custom properties for a scroll event, as there are for the other
+	 * events that have specific event classes.
+	 * If a new text layout event is needed, and the event does not require
+	 * custom properties, the new event will also be represented by a
+	 * TextLayoutEvent object, but with its <code>type</code> property
+	 * set to a new static constant.
+	 * </p>
+	 *
+	 * @includeExample examples\TextLayoutEvent_example.as -noswf
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public class TextLayoutEvent extends Event
+	{
+	    /**
+	     *  The <code>TextLayoutEvent.SCROLL</code> constant defines the value of the
+	     *  <code>type</code> property of the event object for a <code>scroll</code> event.
+	     * @playerversion Flash 10
+	     * @playerversion AIR 1.5
+	     * @langversion 3.0
+	     */
+	    public static const SCROLL:String = "scroll";
+	    
+		/**
+		 *  The TextLayoutEvent class represents the event object passed to
+		 *  the event listener for many Text Layout events.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function TextLayoutEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
+		{
+			super(type, bubbles, cancelable);
+		}
+		
+        /** @private */
+        override public function clone():Event
+        {
+        	return new TextLayoutEvent(type, bubbles, cancelable);
+        }		
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/events/UpdateCompleteEvent.as b/textLayout_core/src/flashx/textLayout/events/UpdateCompleteEvent.as
new file mode 100755
index 0000000..f3f082c
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/events/UpdateCompleteEvent.as
@@ -0,0 +1,106 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.events
+{
+	import flash.events.Event;
+	
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.elements.TextFlow;
+
+	/** 
+	 * A TextFlow instance dispatches this event after any of its containers completes 
+	 * an update. Each text container has two states: composition and display. This 
+	 * event notifies you when the display phase has ended. This provides an 
+	 * opportunity to make any necessary changes to the container when it is ready to
+	 * be displayed, but hasn't yet been painted to the screen.
+	 * 
+	 * @internal Note: the DamageEvent_example class contains a good example of 
+	 * using the UpdateCompleteEvent, so I have included it as the class example
+	 * instead of creating a new example. I've updated the description of the
+	 * DamageEvent_example file to include prominent mention of the UpdateCompleteEvent.
+	 *
+	 * @includeExample examples\DamageEvent_example.as -noswf
+	 * @see flashx.textLayout.elements.TextFlow 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class UpdateCompleteEvent extends Event
+	{
+	    /** 
+	     * Defines the value of the <code>type</code> property of an <code>UpdateCompleteEvent</code> object 
+	     * @playerversion Flash 10
+	     * @playerversion AIR 1.5
+	     * @langversion 3.0 
+	     */
+	    public static const UPDATE_COMPLETE:String = "updateComplete";
+	    
+	    /** @private */
+	    private var _controller:ContainerController;
+	    /** @private */
+		private var _textFlow:TextFlow;
+		
+		/** Constructor
+		 * @param type event type - use the static property UPDATE_COMPLETE.
+		 * @param bubbles Indicates whether an event is a bubbling event. This event does not bubble.
+		 * @param cancelable Indicates whether the behavior associated with the event can be prevented.
+		 * This event cannot be cancelled.
+		 * @param controller The ContainerController whose container was updated
+		 * @param textFlow The TextFlow which was updated
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 **/
+		public function UpdateCompleteEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false, textFlow:TextFlow =  null, controller:ContainerController=null)
+		{
+			super(type, bubbles, cancelable);
+			this.controller = controller;
+			_textFlow = textFlow;
+		}
+
+      	/** @private */
+		override public function clone():Event
+		{
+			return new UpdateCompleteEvent(type, bubbles, cancelable, _textFlow, _controller);
+		}
+
+		/** 
+		 * The controller of the container being updated
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 		 
+		 */
+		public function get controller():ContainerController
+		{ return _controller; }
+		public function set controller(c:ContainerController):void
+		{ _controller = c; }
+		
+		
+		/**
+		 * TextFlow which has been updated. 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public  function get textFlow():TextFlow
+		{ return _textFlow; }
+		public  function set textFlow(value:TextFlow):void
+		{ _textFlow = value; }
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/external/WeakRef.as b/textLayout_core/src/flashx/textLayout/external/WeakRef.as
new file mode 100755
index 0000000..ee292f7
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/external/WeakRef.as
@@ -0,0 +1,66 @@
+﻿/**
+ * Weak reference to an object
+ * 
+ * To create:
+ * var weak:Weakref = new WeakRef( obj );
+ *
+ * To use:
+ * var strong = weak.get();
+ * if( strong != null )
+ * {
+ *     // use strong here
+ * }
+ * else
+ * {
+ *     // garbage collector has disposed of the object
+ * }
+ * 
+ * Author: Richard Lord
+ * Copyright (c) Big Room Ventures Ltd. 2007
+ *
+ * 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 flashx.textLayout.external
+{
+	import flash.utils.Dictionary;
+	
+[ExcludeClass]
+	/** @private */
+	public class WeakRef
+	{
+		private var dic:Dictionary;
+		
+		public function WeakRef( obj:* )
+		{
+			dic = new Dictionary( true );
+			if (obj != null)
+				dic[obj] = 1;
+		}
+		
+		public function get():*
+		{
+			for( var item:* in dic )
+			{
+				return item;
+			}
+			return null;
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/factory/StringTextLineFactory.as b/textLayout_core/src/flashx/textLayout/factory/StringTextLineFactory.as
new file mode 100755
index 0000000..c5c765f
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/factory/StringTextLineFactory.as
@@ -0,0 +1,449 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.factory
+{
+	import flash.geom.Rectangle;
+	import flash.text.engine.TextLine;
+	
+	import flashx.textLayout.compose.FlowComposerBase;
+	import flashx.textLayout.container.ScrollPolicy;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.Configuration;
+	import flashx.textLayout.elements.IConfiguration;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.SpanElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.LineBreak;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+
+/**
+ * The StringTextLineFactory class provides a simple way to create TextLines from a string. 
+ * 
+ * <p>The text lines are static and are created using a single format and a single paragraph. 
+ * The lines are created to fit in the specified bounding rectangle.</p>
+ * 
+ * <p>The StringTextLineFactory provides an efficient way to create TextLines, since it reuses single TextFlow,
+ * ParagraphElement, SpanElement, and ContainerController objects across many repeated invocations. You can create a
+ * single factory, and use it again and again. You can also reuse all the parts that are the same each time
+ * you call it; for instance, you can reuse the various formats and the bounds.</p> 
+ *
+ * <p><b>Note:</b> To create static lines that use multiple formats or paragraphs, or that include
+ * inline graphics, use a TextFlowTextLineFactory and a TextFlow object. </p>
+ * 
+ * @includeExample examples\StringTextLineFactory_example.as -noswf
+ * 
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ *
+ * @see flashx.textLayout.factory.TextFlowTextLineFactory TextFlowTextLineFactory
+*/
+	public final class StringTextLineFactory extends TextLineFactoryBase
+	{
+		private var _tf:TextFlow;
+		private var _para:ParagraphElement;
+		private var _span:SpanElement;
+		private var _formatsChanged:Boolean;
+
+		static private var _defaultConfiguration:Configuration = null;
+		
+		private var _configuration:IConfiguration;
+		
+		/** 
+		 * The configuration used by the internal TextFlow object.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get configuration():IConfiguration
+		{
+			return _configuration; 
+		}
+		
+		/** 
+		 * The default configuration used by this factory if none is specified. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		static public function get defaultConfiguration():IConfiguration
+		{
+			if (!_defaultConfiguration)
+			{
+				_defaultConfiguration = TextFlow.defaultConfiguration.clone();
+				_defaultConfiguration.flowComposerClass = getDefaultFlowComposerClass();
+				_defaultConfiguration.textFlowInitialFormat = null;
+			}
+			return _defaultConfiguration;
+		}
+		
+		/** 
+		 * Creates a StringTextLineFactory object.  
+		 * 
+		 * @param configuration The configuration object used to set the properties of the 
+		 * internal TextFlow object used to compose lines produced by this factory. 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function StringTextLineFactory(configuration:IConfiguration = null):void
+		{
+			super();
+			initialize(configuration);
+		}
+		
+		private function initialize(config:IConfiguration):void
+		{	
+			_configuration = Configuration(config ? config : defaultConfiguration).getImmutableClone();
+			_tf = new TextFlow(_configuration);
+			_para = new ParagraphElement();
+			_span = new SpanElement();
+			_para.replaceChildren(0, 0, _span);
+			_tf.replaceChildren(0, 0, _para);
+			
+			_tf.flowComposer.addController(containerController);
+			_formatsChanged = true;
+		}
+		
+		/** 
+		 * The character format. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get spanFormat():ITextLayoutFormat
+		{
+			return _span.format;
+		}
+		public function set spanFormat(format:ITextLayoutFormat):void
+		{
+			_span.format = format;
+			_formatsChanged = true;
+		}
+		/** 
+		 * The paragraph format. 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paragraphFormat():ITextLayoutFormat
+		{
+			return _para.format;
+		}
+		public function set paragraphFormat(format:ITextLayoutFormat):void
+		{
+			_para.format = format;
+			_formatsChanged = true;
+		}
+		
+		/** 
+		 * The text flow format.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get textFlowFormat():ITextLayoutFormat
+		{
+			return _tf.format;
+		}
+		public function set textFlowFormat(format:ITextLayoutFormat):void
+		{
+			_tf.format = format;
+			_formatsChanged = true;
+		}
+		
+		/** 
+		 * The text to convert into TextLine objects.
+		 * 
+		 * <p>To produce TextLines, call <code>createTextLines()</code> after setting this
+		 * <code>text</code> property and the desired formats.</p> 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get text():String
+		{ return _span.text; }
+		public function set text(string:String):void
+		{
+			_span.text = string;
+		}
+		
+		/** @private  Used for measuring the truncation indicator */
+		static private var _measurementFactory:StringTextLineFactory = null;
+		static private function measurementFactory():StringTextLineFactory
+		{
+			if (_measurementFactory == null)
+				_measurementFactory = new StringTextLineFactory();
+			return _measurementFactory;
+		}
+		static private var _measurementLines:Array = null;
+		static private function measurementLines():Array
+		{
+			if (_measurementLines == null)
+				_measurementLines = new Array();
+			return _measurementLines;
+		}
+		
+		/** 
+		 * Creates TextLine objects using the text currently assigned to this factory object.
+		 * 
+		 * <p>The text lines are created using the currently assigned text and formats and
+		 * are composed to fit the bounds assigned to the <code>compositionBounds</code> property.
+		 * As each line is created, the factory calls the function specified in the 
+		 * <code>callback</code> parameter. This function is passed the TextLine object and
+		 * is responsible for displaying the line.</p>
+		 * 
+		 * <p>To create a different set of lines, change any properties desired and call
+		 * <code>createTextLines()</code> again.</p>
+		 *  
+		 * @param callback	The callback function called for each TextLine object created.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function createTextLines(callback:Function):void
+		{
+			createTextLinesInternal(callback);
+			_factoryComposer._lines.splice(0);
+			if (_pass0Lines)
+				_pass0Lines.splice(0);
+		}
+		
+		/** Internal version preserves generated lines
+		 */
+		private function createTextLinesInternal(callback:Function):void
+		{
+			var measureWidth:Boolean  = !compositionBounds || isNaN(compositionBounds.width);
+			var measureHeight:Boolean = !compositionBounds || isNaN(compositionBounds.height);
+
+			CONFIG::debug { assert(_tf.flowComposer.numControllers == 1,"DisplayController bad number containers"); }
+			CONFIG::debug { assert(containerController == _tf.flowComposer.getControllerAt(0),"ContainerController mixup"); }
+			var bp:String = _tf.computedFormat.blockProgression;
+
+			containerController.setCompositionSize(compositionBounds.width, compositionBounds.height);
+			// override scroll policy if truncation options are set
+			containerController.verticalScrollPolicy = truncationOptions ? ScrollPolicy.OFF : verticalScrollPolicy;
+			containerController.horizontalScrollPolicy = truncationOptions ? ScrollPolicy.OFF : horizontalScrollPolicy;
+
+			_isTruncated = false;
+			_truncatedText = text;
+			
+			if (!_formatsChanged && FlowComposerBase.computeBaseSWFContext(_tf.flowComposer.swfContext) != FlowComposerBase.computeBaseSWFContext(swfContext))
+				_formatsChanged = true;
+
+			_tf.flowComposer.swfContext = swfContext;
+			
+			if (_formatsChanged)
+			{
+				_tf.normalize();
+				_formatsChanged = false;
+			}
+
+			_tf.flowComposer.compose();
+			
+			// Need truncation if all the following are true
+			// - truncation options exist
+			// - content doesn't fit		
+			if (truncationOptions && !doesComposedTextFit(truncationOptions.lineCountLimit, _tf.textLength, bp))
+			{
+				_isTruncated = true;
+				var somethingFit:Boolean = false; // were we able to fit something?
+				var originalText:String = _span.text;
+				
+				computeLastAllowedLineIndex (truncationOptions.lineCountLimit);	
+				if (_truncationLineIndex >= 0)
+				{
+					// Estimate the initial truncation position using the following steps 
+					
+					// 1. Measure the space that the truncation indicator will take
+					measureTruncationIndicator (compositionBounds, truncationOptions.truncationIndicator);
+					
+					// 2. Move target line for truncation higher by as many lines as the number of full lines taken by the truncation indicator
+					_truncationLineIndex -= (_measurementLines.length -1);
+					if (_truncationLineIndex >= 0)
+					{
+						var truncateAtCharPosition:int;
+						
+						if (_tf.computedFormat.lineBreak == LineBreak.EXPLICIT || (bp == BlockProgression.TB ? measureWidth : measureHeight))
+						{
+							// 3., 4. Initial truncation position: end of the last allowed line 
+							var line:TextLine = _factoryComposer._lines[_truncationLineIndex] as TextLine; 
+							truncateAtCharPosition =  line.userData + line.rawTextLength;
+						}
+						else
+						{
+							// 3. Calculate allowed width (width left over from the last line of the truncation indicator)
+							var targetWidth:Number = (bp == BlockProgression.TB ? compositionBounds.width : compositionBounds.height); 
+							if (paragraphFormat)
+							{
+								targetWidth -= (Number(paragraphFormat.paragraphSpaceAfter) + Number(paragraphFormat.paragraphSpaceBefore));
+								if (_truncationLineIndex == 0)
+									targetWidth -= paragraphFormat.textIndent;
+							}
+							
+							var allowedWidth:Number = targetWidth - (_measurementLines[_measurementLines.length-1] as TextLine).unjustifiedTextWidth;
+													
+							// 4. Get the initial truncation position on the target line given this allowed width 
+							truncateAtCharPosition = getTruncationPosition(_factoryComposer._lines[_truncationLineIndex], allowedWidth);
+						}
+						
+						// Save off the original lines: used in getNextTruncationPosition
+						if (!_pass0Lines)
+							_pass0Lines = new Array();
+						_pass0Lines = _factoryComposer.swapLines(_pass0Lines);
+						
+						// Note that for the original lines to be valid when used, the containing text block should not be modified
+						// Cloning the paragraph ensures this 
+						_para = _para.deepCopy() as ParagraphElement; 
+						_span = _para.getChildAt(0) as SpanElement;
+						_tf.replaceChildren(0, 1, _para);
+						_tf.normalize();
+						
+						// Replace all content starting at the inital truncation position with the truncation indicator
+						_span.replaceText(truncateAtCharPosition, _span.textLength, truncationOptions.truncationIndicator);
+						
+						// The following loop executes repeatedly composing text until it fits
+						// In each iteration, an atoms's worth of characters of original content is dropped
+						do
+						{
+							_tf.flowComposer.compose();
+							
+							if (doesComposedTextFit(truncationOptions.lineCountLimit, _tf.textLength, bp))
+							{
+								somethingFit = true;
+								break; 
+							}		
+							
+							if (truncateAtCharPosition == 0)
+								break; // no original content left to make room for truncation indicator
+							
+							// Try again by truncating at the beginning of the preceding atom
+							var newTruncateAtCharPosition:int = getNextTruncationPosition(truncateAtCharPosition);
+							_span.replaceText(newTruncateAtCharPosition, truncateAtCharPosition, null);
+							truncateAtCharPosition = newTruncateAtCharPosition;
+							
+						} while (true);
+					}
+					_measurementLines.splice(0);	// cleanup
+				}
+				
+				if (somethingFit)
+					_truncatedText = _span.text;
+				else
+				{
+					_truncatedText = "";
+					_factoryComposer._lines.splice(0); // return no lines
+				}
+				
+				 _span.text = originalText;
+			}
+			
+			var xadjust:Number = compositionBounds.x;
+			// toptobottom sets zero to the right edge - adjust the locations
+			var controllerBounds:Rectangle = containerController.getContentBounds();
+			if (bp == BlockProgression.RL)
+				xadjust += (measureWidth ? controllerBounds.width : compositionBounds.width);
+				
+			// apply x and y adjustment to the bounds
+			controllerBounds.left += xadjust;
+			controllerBounds.right += xadjust;
+			controllerBounds.top += compositionBounds.y;
+			controllerBounds.bottom += compositionBounds.y;			
+
+			callbackWithTextLines(callback,xadjust,compositionBounds.y);
+
+			setContentBounds(controllerBounds);
+		}
+		
+		
+		/** @private 
+		 * Gets the text that is composed in the preceding call to <code>createTextLines</code>
+		 * If no truncation is performed, a string equal to <code>text</code> is returned. 
+		 * If truncation is performed, but nothing fits, an empty string is returned.
+		 * Otherwise, a substring of <code>text</code> followed by the truncation indicator is returned. 
+		 */
+		tlf_internal function get truncatedText():String
+		{ return _truncatedText; }
+		private var _truncatedText:String;
+		
+		/** 
+		 * Measures the truncation indicator using the same bounds and formats, but without truncation options
+		 * Resultant lines are added to _measurementLines
+		 */
+		private function measureTruncationIndicator (compositionBounds:Rectangle, truncationIndicator:String):void
+		{
+			var originalLines:Array = _factoryComposer.swapLines(measurementLines()); // ensure we don't overwrite original lines
+			var measureFactory:StringTextLineFactory = measurementFactory();
+			measureFactory.compositionBounds = compositionBounds;
+			measureFactory.text = truncationIndicator;
+			measureFactory.spanFormat = spanFormat;
+			measureFactory.paragraphFormat = paragraphFormat;
+			measureFactory.textFlowFormat = textFlowFormat;
+			measureFactory.truncationOptions = null;
+			measureFactory.createTextLinesInternal(noOpCallback);
+			_factoryComposer.swapLines(originalLines); // restore
+		}
+		
+
+		/** 
+		 * Gets the truncation position on a line given the allowed width 
+		 * - Must be at an atom boundary
+		 * - Must scan the line for atoms in logical order, not physical position order
+		 * For example, given bi-di text ABאבCD
+		 * atoms must be scanned in this order 
+		 * A, B, א
+         * ג, C, D  
+		 */
+		private function getTruncationPosition (line:TextLine, allowedWidth:Number):uint
+		{			
+			var consumedWidth:Number = 0;
+			var charPosition:int = line.userData; 						// start of line
+			
+			while (charPosition < line.userData + line.rawTextLength)	// end of line
+			{
+				var atomIndex:int = line.getAtomIndexAtCharIndex(charPosition);
+				var atomBounds:Rectangle = line.getAtomBounds(atomIndex); 
+				consumedWidth += atomBounds.width;
+				if (consumedWidth > allowedWidth)
+					break;
+					
+				charPosition = line.getAtomTextBlockEndIndex(atomIndex);
+			}
+			
+			line.flushAtomData();
+			return charPosition;
+		}
+		
+		
+		private function noOpCallback(line:TextLine):void
+		{	
+		}
+		
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/factory/TextFlowTextLineFactory.as b/textLayout_core/src/flashx/textLayout/factory/TextFlowTextLineFactory.as
new file mode 100755
index 0000000..42359d1
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/factory/TextFlowTextLineFactory.as
@@ -0,0 +1,261 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.factory
+{
+	import flash.display.Shape;
+	import flash.display.Sprite;
+	import flash.geom.Rectangle;
+	import flash.text.engine.TextBlock;
+	import flash.text.engine.TextLine;
+	import flash.text.engine.TextLineValidity;
+	
+	import flashx.textLayout.compose.IFlowComposer;
+	import flashx.textLayout.compose.SimpleCompose;
+	import flashx.textLayout.compose.StandardFlowComposer;
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.container.ScrollPolicy;
+	import flashx.textLayout.debug.Debugging;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.OverflowPolicy;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.SpanElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.compose.TextFlowLine;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.LineBreak;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+
+/**
+ * The TextFlowTextLineFactory class provides a simple way to create TextLines for displaying text from a text flow.
+ * 
+ * <p>The text lines are static and created fit in a single bounding rectangle, but can have multiple paragraphs and formats as well as
+ * inline graphics. To create TextLine objects directly from a string, use StringTextLineFactory.</p> 
+ *
+ * <p><b>Note:</b> When using inline graphics, the <code>source</code> property of the InlineGraphicElement object 
+ * must either be an instance of a DisplayObject or a Class object representing an embedded asset. 
+ * URLRequest objects cannot be used. The width and height of the inline graphic at the time the line 
+ * is created is used to compose the flow. </p>
+ * 
+ * @includeExample examples\TextFlowTextLineFactory_example.as 
+ * 
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ *
+ * @see flashx.textLayout.elements.TextFlow TextFlow
+ * @see flashx.textLayout.factory.StringTextLineFactory StringTextLineFactory
+*/
+	public final class TextFlowTextLineFactory extends TextLineFactoryBase
+	{
+		/** 
+		 * Creates a TextFlowTextLineFactory object. 
+		 * 
+ 		 * @playerversion Flash 10
+ 		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+ 		 */
+		public function TextFlowTextLineFactory():void
+		{
+			super();
+		}
+
+		/**
+		 * Creates TextLine objects from the specified text flow.
+		 * 
+		 * <p>The text lines are composed to fit the bounds assigned to the <code>compositionBounds</code> property.
+		 * As each line is created, the factory calls the function specified in the 
+		 * <code>callback</code> parameter. This function is passed the TextLine object and
+		 * is responsible for displaying the line. If a line has a background color, the factory also calls the
+		 * callback function with a Shape object containing a rectangle of the background color.</p>
+		 * 
+		 * @param callback function to call with each generated TextLine object.  
+		 * The callback will be called with a Shape object representing any background color (if present), 
+		 * and with TextLine objects for the text.
+		 * @param textFlow The TextFlow from which the lines are created.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 */	
+		public function createTextLines(callback:Function,textFlow:TextFlow):void
+		{
+			var measureWidth:Boolean  = isNaN(compositionBounds.width);
+			
+			var bp:String = textFlow.computedFormat.blockProgression;
+						
+			var helper:IFlowComposer = createFlowComposer();
+			helper.swfContext = swfContext;
+
+			helper.addController(containerController);
+			textFlow.flowComposer = helper; 
+			textFlow.backgroundManager = null;
+			
+			_isTruncated = false;
+			
+			// compose
+			containerController.setCompositionSize(compositionBounds.width, compositionBounds.height);
+			containerController.verticalScrollPolicy = truncationOptions ? ScrollPolicy.OFF : verticalScrollPolicy;
+			containerController.horizontalScrollPolicy = truncationOptions ? ScrollPolicy.OFF : horizontalScrollPolicy;
+			textFlow.normalize();
+			textFlow.applyUpdateElements(true);
+
+			helper.compose();
+		
+			// Need truncation if all the following are true
+			// - truncation options exist
+			// - content doesn't fit		
+			if (truncationOptions && !doesComposedTextFit(truncationOptions.lineCountLimit, textFlow.textLength, bp))
+			{
+				_isTruncated = true;
+				var somethingFit:Boolean = false; // were we able to fit something?
+
+				computeLastAllowedLineIndex (truncationOptions.lineCountLimit);	
+				if (_truncationLineIndex >= 0)
+				{					
+					// Create a span for the truncation indicator
+					var truncationIndicatorSpan:SpanElement = new SpanElement();
+					truncationIndicatorSpan.text = truncationOptions.truncationIndicator; 
+					truncationIndicatorSpan.id = "truncationIndicator"; // prevents merging with other spans 
+					if (truncationOptions.truncationIndicatorFormat)
+						truncationIndicatorSpan.format = truncationOptions.truncationIndicatorFormat;
+					
+					var hostFormat:ITextLayoutFormat = textFlow.hostFormat;
+					
+					// Initial truncation position: end of the last allowed line
+					var line:TextLine = _factoryComposer._lines[_truncationLineIndex] as TextLine; 
+					var truncateAtCharPosition:int =  line.userData + line.rawTextLength;
+					
+					// Save off the original lines: used in getNextTruncationPosition
+					// Note that for the original lines to be valid when used, the containing text block should not be modified
+					// Cloning the text flow before modifying it ensures that
+					if (!_pass0Lines)
+						_pass0Lines = new Array();
+					_pass0Lines = _factoryComposer.swapLines(_pass0Lines); 
+
+					// The following loop executes repeatedly composing text until it fits
+					// In each iteration, an atoms's worth of characters of original content is dropped 
+					do
+					{
+						// Clone the part of the flow before the truncation position  
+						textFlow = textFlow.deepCopy(0, truncateAtCharPosition) as TextFlow;
+						// TODO-2/18/2009-deepCopy does not copy hostTextLayoutFormat
+						if (hostFormat)
+							textFlow.hostFormat = hostFormat;
+						
+						// Find a parent for the truncation span
+						var parent:FlowGroupElement;
+						var lastLeaf:FlowLeafElement = textFlow.getLastLeaf();
+						if (lastLeaf)
+						{
+							parent = lastLeaf.parent;
+							// Set format to match the leaf if none specified 
+							if (!truncationOptions.truncationIndicatorFormat)
+								truncationIndicatorSpan.format = lastLeaf.format;
+						}
+						else
+						{
+							parent = new ParagraphElement();
+							textFlow.addChild(parent);
+						}
+					
+						// Append the truncation span (after severing it from the previous flow)
+						if (truncationIndicatorSpan.parent)
+							truncationIndicatorSpan.parent.removeChild(truncationIndicatorSpan);
+						parent.addChild(truncationIndicatorSpan);
+						
+						textFlow.flowComposer = helper;
+						textFlow.normalize();
+						
+						helper.compose();
+			
+						if (doesComposedTextFit(truncationOptions.lineCountLimit, textFlow.textLength, bp))
+						{
+							somethingFit = true;
+							break; 
+						}		
+						
+						if (truncateAtCharPosition == 0)
+							break; // no original content left to make room for truncation indicator
+						
+						// Try again by truncating at the beginning of the preceding atom
+						truncateAtCharPosition = getNextTruncationPosition(truncateAtCharPosition, true);
+
+					} while (true);
+				}
+				
+				if (_truncatedTextFlowCallback != null)
+					_truncatedTextFlowCallback (somethingFit ? textFlow : null);
+					
+				if (!somethingFit)
+					_factoryComposer._lines.splice(0); // return no lines
+			}
+			
+			var xadjust:Number = compositionBounds.x;
+			// toptobottom sets zero to the right edge - adjust the locations
+			var controllerBounds:Rectangle = containerController.getContentBounds();
+			if (bp == BlockProgression.RL)
+				xadjust += (measureWidth ? controllerBounds.width : compositionBounds.width);	
+			
+			// apply x and y adjustment to the bounds
+			controllerBounds.left += xadjust;
+			controllerBounds.right += xadjust;
+			controllerBounds.top += compositionBounds.y;
+			controllerBounds.bottom += compositionBounds.y;
+				
+			if (textFlow.backgroundManager)
+			{
+				var bgShape:Shape = new Shape();
+				textFlow.backgroundManager.drawAllRects(bgShape,containerController);
+				bgShape.x = xadjust;
+				bgShape.y = compositionBounds.y;
+				callback(bgShape);
+				textFlow.backgroundManager = null;
+			}	
+
+			callbackWithTextLines(callback,xadjust,compositionBounds.y);
+
+			setContentBounds(controllerBounds);
+
+			textFlow.changeFlowComposer(null,false);
+			
+			// clear out lines in the FactoryComposer
+			_factoryComposer._lines.splice(0);
+			if (_pass0Lines)
+				_pass0Lines.splice(0);
+		}
+		
+		/** @private 
+		 * Test hook: Sets a callback function for getting the truncated text flow.
+		 * This function is only called if truncation is performed. It takes a single parameter which will have the following value:
+		 * null, if nothing fits
+		 * A text flow representing the truncated text (containing inital text from the original text flow followed by the truncation indicator), otherwise 
+		 */
+		tlf_internal function set truncatedTextFlowCallback(val:Function):void
+		{ _truncatedTextFlowCallback = val; }
+		
+		private var _truncatedTextFlowCallback:Function;
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/factory/TextLineFactoryBase.as b/textLayout_core/src/flashx/textLayout/factory/TextLineFactoryBase.as
new file mode 100755
index 0000000..8ae1bbe
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/factory/TextLineFactoryBase.as
@@ -0,0 +1,454 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.factory
+{
+	import flash.display.Sprite;
+	import flash.geom.Rectangle;
+	import flash.text.engine.TextBlock;
+	import flash.text.engine.TextLine;
+	import flash.text.engine.TextLineValidity;
+	
+	import flashx.textLayout.compose.IFlowComposer;
+	import flashx.textLayout.compose.ISWFContext;
+	import flashx.textLayout.compose.SimpleCompose;
+	import flashx.textLayout.compose.StandardFlowComposer;
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.container.ScrollPolicy;
+	import flashx.textLayout.debug.Debugging;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.OverflowPolicy;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+
+	[Exclude(name="containerController",kind="property")]	
+	[Exclude(name="setContentBounds",kind="method")]
+	[Exclude(name="callbackWithTextLines",kind="method")]
+	[Exclude(name="doesComposedTextFit",kind="method")]
+	[Exclude(name="getNextTruncationPosition",kind="method")]
+
+
+/**
+ * The TextLineFactoryBase class serves as the base class for the Text Layout Framework text line factories.
+ * 
+ * <p><b>Note:</b> Application code does not typically need to create or use a TextLineFactoryBase object directly.
+ * Use one of the derived text factory classes instead.</p>
+ *  
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ *
+ * @see flashx.textLayout.elements.TextFlow
+*/
+	public class TextLineFactoryBase
+	{
+		/** Requested logical bounds to wrap to */
+		private var _compositionBounds:Rectangle;
+
+		/** Bounds of composition results - where the text landed */
+		private var _contentBounds:Rectangle;
+		
+		/** @private */
+		protected var _isTruncated:Boolean = false;
+		
+		private var _horizontalScrollPolicy:String;
+		private var _verticalScrollPolicy:String;
+		private var _truncationOptions:TruncationOptions;
+		private var _containerController:ContainerController;
+		static private var _tc:Sprite = new Sprite();
+		
+		private var _swfContext:ISWFContext;
+		
+		/** @private */
+		static tlf_internal var _factoryComposer:SimpleCompose= new SimpleCompose();
+
+		/** @private */		
+		static protected var _truncationLineIndex:int; 	// used during truncation
+		/** @private */		
+		static protected var _pass0Lines:Array; 		// used during truncation
+		
+		/** 
+		 * Base-class constructor for text line factories.
+		 *  
+ 		 * <p><b>Note:</b> Application code does not typically need to create or use a TextLineFactoryBase object directly.
+		 * Use one of the derived text factory classes instead.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function TextLineFactoryBase():void
+		{
+			_containerController = new ContainerController(_tc);
+			_horizontalScrollPolicy = _verticalScrollPolicy = String(ScrollPolicy.scrollPolicyPropertyDefinition.defaultValue);
+		}
+		
+		/**
+		 * The rectangle within which text lines are created.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get compositionBounds():Rectangle
+		{
+			return _compositionBounds;
+		}
+		
+		public function set compositionBounds(value:Rectangle):void
+		{
+			_compositionBounds = value;
+		}
+		
+		/**
+		 * The smallest rectangle in which the layed-out content fits.
+		 * 
+		 * <p><b>Note:</b> Truncated lines are not included in the size calculation.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function getContentBounds():Rectangle
+		{
+			return _contentBounds;
+		}
+		
+		/** @private */
+		protected function setContentBounds(controllerBounds:Rectangle):void
+		{
+			_contentBounds = controllerBounds;
+			_contentBounds.offset(compositionBounds.left, compositionBounds.top);
+		}
+		
+		/** 
+		* The ISWFContext instance used to make FTE calls as needed. 
+		*
+		* <p>By default, the ISWFContext implementation is this FlowComposerBase object.
+		* Applications can provide a custom implementation to use fonts
+		* embedded in a different SWF file or to cache and reuse text lines.</p>
+		* 
+		* @see flashx.textLayout.compose.ISWFContext
+		* 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*/
+ 	
+		public function get swfContext():ISWFContext
+		{
+			return _swfContext;
+		}
+		public function set swfContext(value:ISWFContext):void
+		{
+			_swfContext = value;
+		}
+		
+		/** 
+		 * Specifies the options for truncating the text if it doesn't fit in the composition bounds.
+		 *  
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get truncationOptions():TruncationOptions
+		{
+			return _truncationOptions;
+		}
+		public function set truncationOptions(value:TruncationOptions):void
+		{
+			_truncationOptions = value;
+		}
+		
+		/** 
+		 * Indicates whether text was truncated when lines were last created.
+		 *  
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get isTruncated():Boolean
+		{
+			return _isTruncated;
+		}
+
+		/** 
+		 * Specifies how lines are created when the composition bounds are not large enough.
+		 *  
+		 * <p>If set to <code>ScrollPolicy.ON</code> or <code>ScrollPolicy.AUTO</code>, all lines
+		 * are created. It is the your responsibility to scroll lines in the viewable area (and to
+		 * mask lines outside this area, if necessary). If set to <code>ScrollPolicy.OFF</code>, then 
+		 * only lines that fit within the composition bounds are created.</p>
+		 * 
+		 * <p>If the <code>truncationOptions</code> property is set, the scroll policy is ignored 
+		 * (and treated as <code>ScrollPolicy.OFF</code>).</p> 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * 
+		 * @see flashx.textLayout.compose.StandardFlowComposer
+		 * @see flashx.textLayout.container.ScrollPolicy
+		 * @see #truncationOptions
+	 	 */
+	 	 
+	 	public function get horizontalScrollPolicy():String
+		{
+			return _horizontalScrollPolicy;
+		}
+		public function set horizontalScrollPolicy(scrollPolicy:String):void
+		{
+			_horizontalScrollPolicy =  scrollPolicy;
+		}
+		
+		/** 
+		 * Specifies how lines are created when the composition bounds are not large enough.
+		 *  
+		 * <p>If set to <code>ScrollPolicy.ON</code> or <code>ScrollPolicy.AUTO</code>, all lines
+		 * are created. It is the your responsibility to scroll lines in the viewable area (and to
+		 * mask lines outside this area, if necessary). If set to <code>ScrollPolicy.OFF</code>, then 
+		 * only lines that fit within the composition bounds are created.</p>
+		 * 
+		 * <p>If the <code>truncationOptions</code> property is set, the scroll policy is ignored 
+		 * (and treated as <code>ScrollPolicy.OFF</code>).</p> 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * 
+		 * @see flashx.textLayout.compose.StandardFlowComposer
+		 * @see flashx.textLayout.container.ScrollPolicy
+		 * @see #truncationOptions
+	 	 */
+	 	 
+		public function get verticalScrollPolicy():String
+		{
+			return _verticalScrollPolicy;
+		}
+		public function set verticalScrollPolicy(scrollPolicy:String):void
+		{
+			_verticalScrollPolicy =  scrollPolicy;
+		}		
+		
+		/** @private */
+		tlf_internal static function getDefaultFlowComposerClass():Class
+		{
+			return FactoryDisplayComposer;
+		}
+		
+		/** @private */
+		protected function get containerController():ContainerController
+		{
+			return _containerController;
+		}
+		
+		/** 
+		 * Sends the created TextLine objects to the client using the supplied callback function.
+		 * 
+		 * <p>This method sets the <code>x</code> and <code>y</code> properties of the line.</p>
+		 * 
+		 * @param callback the callback function supplied by the factory user
+		 * @param delx the horizontal offset
+		 * @param dely the vertical offset
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		protected function callbackWithTextLines(callback:Function,delx:Number,dely:Number):void
+		{
+			for each (var textLine:TextLine in _factoryComposer._lines)
+			{
+				var textBlock:TextBlock = textLine.textBlock;
+				if (textBlock)
+				{
+					CONFIG::debug { Debugging.traceFTECall(null,textBlock,"releaseLines",textBlock.firstLine, textBlock.lastLine); }	
+					textBlock.releaseLines(textBlock.firstLine,textBlock.lastLine);
+				}
+				textLine.userData = null;
+				textLine.x += delx;
+				textLine.y += dely;
+				textLine.validity = TextLineValidity.STATIC;
+				CONFIG::debug { Debugging.traceFTEAssign(textLine,"validity",TextLineValidity.STATIC); }
+				callback(textLine);
+			}
+		}
+		
+		/**
+		 * Indicates whether the composed text fits in the line count limit and includes all text
+		 *  
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */	
+		protected function doesComposedTextFit (lineCountLimit:int, textLength:uint, blockProgression:String):Boolean
+		{
+			if (lineCountLimit != TruncationOptions.NO_LINE_COUNT_LIMIT && _factoryComposer._lines.length > lineCountLimit)
+				return false; // Line count limit exceded
+			
+			var lines:Array = _factoryComposer._lines;
+		
+			if (!lines.length)
+				return textLength ? false /* something to compose, but no line could fit */ : true /* nothing to compose */; 
+				
+			// This code is only called when scrolling if OFF, so only lines that fit in bounds are generated
+			// Just check if the last line reaches the end of flow
+			var lastLine:TextLine = lines[lines.length - 1] as TextLine;
+			return lastLine.userData + lastLine.rawTextLength == textLength;
+		}
+		
+		/** 
+		 * Gets the next truncation position by shedding an atom's worth of characters.
+		 * 
+		 * @param truncateAtCharPosition the current truncation candidate position.
+		 * @param multiPara <code>true</code> if text has more than one paragraph.
+		 * 
+		 * @returns the next candidate truncation position.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		protected function getNextTruncationPosition(truncateAtCharPosition:int, multiPara:Boolean=false):int
+		{
+			// 1. Get the position of the last character of the preceding atom
+			truncateAtCharPosition--; // truncateAtCharPosition-1, because truncateAtCharPosition is an atom boundary
+			
+			// Note: The current set of lines may not contain the next truncation position because the truncation indicator
+			// could combine with original content to form a word that does not afford a suitable break opportunity. 
+			// The combined word would then move to the next line, which may not have been composed if the bounds were exceeded.
+			// Therefore, this function needs to use the original lines (from before truncation is attempted). 
+			CONFIG::debug 
+			{ 
+				assert(_pass0Lines != null, "getNextTruncationPosition called before saving off lines from the first pass at composition"); 
+				assert(_truncationLineIndex < _pass0Lines.length, "index out of range in getNextTruncationPosition");
+			}
+			
+			// 2. Find the new target line (i.e., the line that has the new truncation position) 
+			// If the last truncation position was at the beginning of the target line, the new position may have moved to a previous line
+			// In any case, the new truncation position lies in the vicinity of the previous target line, so a linear search suffices
+			var line:TextLine = _pass0Lines[_truncationLineIndex] as TextLine;
+			do
+			{
+				if (truncateAtCharPosition >= line.userData && truncateAtCharPosition < line.userData + line.rawTextLength)
+					break;
+				if (truncateAtCharPosition < line.userData)
+					line = _pass0Lines[--_truncationLineIndex] as TextLine;
+				else
+				{
+					CONFIG::debug {	assert(false, "truncation position should decrease monotonically");	}
+				}	
+			}
+			while (true);
+
+			var paraStart:int = multiPara ?  line.userData - line.textBlockBeginIndex : 0;
+			
+			// 3. Get the line atom index at this position			
+			var atomIndex:int = line.getAtomIndexAtCharIndex(truncateAtCharPosition - paraStart);
+			
+			// 4. Get the char index for this atom index
+			var nextTruncationPosition:int = line.getAtomTextBlockBeginIndex(atomIndex) + paraStart;
+			
+			line.flushAtomData();
+			
+			return nextTruncationPosition;
+		} 
+		/** @private */
+		tlf_internal function createFlowComposer():IFlowComposer
+		{
+			return new FactoryDisplayComposer();
+		}			
+		
+		/** @private
+		 * Calculates the last line that fits in the line count limit
+		 * The result is stored in  _truncationLineIndex
+		 * 
+		 * Note: This code is only called when scrolling is OFF, so only lines that fit in bounds are generated
+		 */
+		tlf_internal function computeLastAllowedLineIndex (lineCountLimit:int):void
+		{			
+			_truncationLineIndex = _factoryComposer._lines.length - 1;
+
+			// if line count limit is smaller, use that
+			if (lineCountLimit != TruncationOptions.NO_LINE_COUNT_LIMIT && lineCountLimit <= _truncationLineIndex)
+				_truncationLineIndex = lineCountLimit - 1;
+		}
+	}
+
+} // end package
+
+import flash.geom.Rectangle;
+
+import flashx.textLayout.compose.StandardFlowComposer;
+import flashx.textLayout.compose.SimpleCompose;
+import flashx.textLayout.debug.assert;
+import flashx.textLayout.elements.BackgroundManager;
+import flashx.textLayout.elements.FlowLeafElement;
+import flashx.textLayout.compose.TextFlowLine;
+import flashx.textLayout.factory.TextLineFactoryBase;
+import flashx.textLayout.tlf_internal;
+import flash.text.engine.TextLine;
+import flashx.textLayout.container.ContainerController;
+import flashx.textLayout.compose.TextFlowLine;
+use namespace tlf_internal;
+
+class FactoryDisplayComposer extends StandardFlowComposer
+{
+	tlf_internal override function callTheComposer(absoluteEndPosition:int, controllerEndIndex:int):ContainerController
+	{
+		// always do a full compose
+		clearCompositionResults();
+		
+		var state:SimpleCompose = TextLineFactoryBase._factoryComposer;
+		state.composeTextFlow(textFlow, -1, -1);
+		state.releaseAnyReferences()
+		return getControllerAt(0);
+	}
+		
+	/** Returns true if composition is necessary, false otherwise */
+	protected override function preCompose():Boolean
+	{
+		return true;
+	}
+	
+	/** @private */
+	public override function createBackgroundManager():BackgroundManager
+	{ return new FactoryBackgroundManager(); }
+}
+
+class FactoryBackgroundManager extends BackgroundManager
+{
+
+	public override function finalizeLine(line:TextFlowLine):void
+	{
+		var textLine:TextLine = line.getTextLine();
+		
+		var array:Array = lineDict[textLine];
+		if (array)
+		{
+			// attach the columnRect and the TextLine to the first object in the Array
+			var obj:Object = array[0];
+			
+			if (obj)	// check not needed?
+				obj.columnRect = line.controller.columnState.getColumnAt(line.columnIndex);
+		}
+	}
+}
+
diff --git a/textLayout_core/src/flashx/textLayout/factory/TruncationOptions.as b/textLayout_core/src/flashx/textLayout/factory/TruncationOptions.as
new file mode 100755
index 0000000..aa333f4
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/factory/TruncationOptions.as
@@ -0,0 +1,154 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.factory
+{
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	
+	/** 
+	 * The TruncationOptions class specifies options for limiting the number of lines of text 
+	 * created by a text line factory and for indicating when lines have been left out.
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public final class TruncationOptions
+	{
+		/** 
+		 * Creates a TruncationOptions object.
+		 * 
+		 * @param truncationIndicator the string used to indicate that text has been truncated. 
+		 * It appears at the end of the composed text. The default value is the horizontal ellipsis (U+2026).
+		 * @param lineCountLimit specifies a truncation criterion in the form of the maximum 
+		 * number of lines allowed. The default value of <code>NO_LINE_COUNT_LIMIT</code> 
+		 * indicates that there is no line count limit.
+		 * @param truncationIndicatorFormat specifies the format for the truncation indicator. 
+		 * A null format (the default value) specifies that the truncation indicator assume 
+		 * the format of content just before the truncation point. The <code>TextLineFactory</code> 
+		 * methods that take a simple string as input also ignore this parameter and implement 
+		 * the default behavior.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function TruncationOptions (truncationIndicator:String=HORIZONTAL_ELLIPSIS, lineCountLimit:int=NO_LINE_COUNT_LIMIT, truncationIndicatorFormat:ITextLayoutFormat=null)
+		{
+			this.truncationIndicator =  truncationIndicator;
+			this.truncationIndicatorFormat = truncationIndicatorFormat;
+			this.lineCountLimit = lineCountLimit;
+		}
+		
+		/** 
+		 * A string used to indicate that content could not be fully displayed
+		 * because of limits on the number of lines.
+		 * 
+		 * @return the truncation indicator
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get truncationIndicator():String
+		{
+			return _truncationIndicator ? _truncationIndicator : HORIZONTAL_ELLIPSIS;
+		}
+		/** 
+		 * Sets the truncation indicator
+		 * @param val the string used to indicate that text has been truncated
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function set truncationIndicator(val:String):void
+		{
+			_truncationIndicator = val;
+		}
+		
+		/** 
+		 * The style applied to the truncation indicator string.
+		 * @return the format truncation indicator
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get truncationIndicatorFormat():ITextLayoutFormat
+		{
+			return _truncationIndicatorFormat;
+		}
+		/** 
+		 * Sets the styles applied to the truncation indicator character
+		 * 
+		 * @param val specifies the format for the truncation indicator. A null format specifies that the truncation indicator assume the format of content
+		 * just before the truncation point. The <code>TextLineFactory</code> methods that take a simple string as input also ignore this parameter and implement the default behavior
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function set truncationIndicatorFormat(val:ITextLayoutFormat):void
+		{
+			_truncationIndicatorFormat = val;
+		}
+		
+		/** 
+		 * The maximum number of lines to create.
+		 * @return the line count limit
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get lineCountLimit():int
+		{
+			return _lineCountLimit < NO_LINE_COUNT_LIMIT ? 0 : _lineCountLimit;
+		}
+		/** 
+		 * Sets the maximum number of lines to create
+		 * @param val specifies the maximum number of lines allowed. 
+		 * A value of <code>NO_LINE_COUNT_LIMIT</code> indicates that there is no line count limit.
+		 */
+		public function set lineCountLimit(val:int):void
+		{
+			_lineCountLimit = val;
+		} 
+		
+		private var _truncationIndicator:String;
+		private var _truncationIndicatorFormat:ITextLayoutFormat;
+		private var _lineCountLimit:int;
+		
+		/**
+		 * Defines the <code>lineCountLimit</code> property value, <code>-1</code>, that represents no limit.
+		 *
+		 * @see #lineCountLimit
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public static const NO_LINE_COUNT_LIMIT:int = -1;
+
+		/**
+		 * Defines the <code>truncationIndicator</code> property value, <code>\u2026</code>, that represents a horizontal ellipsis.
+		 *
+		 * @see #truncationIndicator
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public static const HORIZONTAL_ELLIPSIS:String = "\u2026";
+	}	
+}
+
+
diff --git a/textLayout_core/src/flashx/textLayout/formats/BackgroundColor.as b/textLayout_core/src/flashx/textLayout/formats/BackgroundColor.as
new file mode 100755
index 0000000..ca48aa2
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/BackgroundColor.as
@@ -0,0 +1,41 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	/**
+	 *  Defines a constant for specifying that the value of the <code>backgroundColor</code> property
+	 *  of the <code>TextLayoutFormat</code> class is "transparent".
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 * @see flashx.textLayout.formats.TextLayoutFormat#backgroundColor TextLayoutFormat.backgroundColor
+	 */
+	public final class BackgroundColor
+	{
+		/** Transparent - no background color is applied.
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public static const TRANSPARENT:String = "transparent";
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/formats/BaselineOffset.as b/textLayout_core/src/flashx/textLayout/formats/BaselineOffset.as
new file mode 100755
index 0000000..1a02b65
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/BaselineOffset.as
@@ -0,0 +1,68 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	/**
+	 *  Defines values for the <code>firstBaselineOffset</code> property
+	 *  of the <code>TextLayoutFormat</code> and <code>ContainerFormattedElement</code> classes. 
+	 *  Determines the offset from the top inset of the container
+	 *  to the baseline of the first line. Baseline offset may be specified as 
+	 *  the ascent of the line, the height of the line, or an auto generated amount.
+	 *  <p>
+	 *  <img src="../../../images/textLayout_FBO1.jpg" alt="firstBaselineOffset_1" border="0"/>
+	 *  <img src="../../../images/textLayout_FBO2.jpg" alt="firstBaselineOffset_2" border="0"/>
+	 *  <img src="../../../images/textLayout_FBO3.jpg" alt="firstBaselineOffset_3" border="0"/>
+	 *  <img src="../../../images/textLayout_FBO4.jpg" alt="firstBaselineOffset_4" border="0"/>
+	 *  </p>
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 *  @see TextLayoutFormat#firstBaselineOffset
+	 */
+	public final class BaselineOffset
+	{
+		/** Aligns the ascent of the line with the container top inset.
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public static const AUTO:String = "auto";
+		
+		/** Specifies an offset equal to the ascent of the line, that is, the ascent of the tallest font in the line, accounting for inline graphics as having the bottom of the graphic on the baseline.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		 
+		public static const ASCENT:String = "ascent";
+		
+		/** Specifies an offset equal to the height of the line.
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public static const LINE_HEIGHT:String = "lineHeight";		
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/formats/BaselineShift.as b/textLayout_core/src/flashx/textLayout/formats/BaselineShift.as
new file mode 100755
index 0000000..e446416
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/BaselineShift.as
@@ -0,0 +1,53 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	/**
+	 *  Defines constants for specifying subscript or superscript in the <code>baselineShift</code> property
+	 *  of the <code>TextLayoutFormat</code> class. You can specify baseline shift as an absolute pixel offset, 
+	 *  a percentage of the current point size, or the constants SUPERSCRIPT or 
+	 *  SUBSCRIPT. Positive values shift the line up for horizontal text (right for vertical) and negative values 
+	 *  shift it down for horizontal (left for vertical). 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 *
+	 *  @see flashx.textLayout.formats.TextLayoutFormat#baselineShift TextLayoutFormat.baselineShift
+	 */
+	public final class BaselineShift
+	{
+		/** Shifts baseline to the current superscript position.
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public static const SUPERSCRIPT:String = "superscript";
+		
+		/** Shifts baseline to the current subscript position.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		 
+		public static const SUBSCRIPT:String = "subscript";		
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/formats/BlockProgression.as b/textLayout_core/src/flashx/textLayout/formats/BlockProgression.as
new file mode 100755
index 0000000..23aa355
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/BlockProgression.as
@@ -0,0 +1,58 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	/**
+	 *  Defines values for the <code>blockProgression</code> property
+	 *  of the <code>TextLayouFormat</code> class. BlockProgression specifies the direction in 
+	 *  which lines are placed in the container.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 * 
+	 *  @see flashx.textLayout.formats.TextLayoutFormat#blockProgression TextLayoutFormat.blockProgression
+	 */
+	 
+	public final class BlockProgression
+	{
+		/** 
+		 *  Specifies right to left block progression. Lines are laid out vertically starting at the right 
+		 *  edge of the container and progressing leftward. Used for vertical text, for example, vertical 
+		 *  Chinese or Japanese text. 
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	  	 * @langversion 3.0 
+	 	 */
+	 	 
+		public static const RL:String = "rl";
+		
+		/** 
+		 *  Specifies top to bottom block progression. Lines are laid out horizontally starting at the top of 
+		 *  the container and progressing down to the bottom. Used for horizontal text. 
+		 * 
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	  	 * @langversion 3.0 
+	  	 */
+	  	 
+		public static const TB:String = "tb";				
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/formats/Category.as b/textLayout_core/src/flashx/textLayout/formats/Category.as
new file mode 100755
index 0000000..f31efad
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/Category.as
@@ -0,0 +1,36 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	/**
+	 *  Property categories
+	 * @private
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 *  @see flashx.textLayout.elements.ParagraphFormattedElement
+	 */
+	public final class Category
+	{
+		public static const PARAGRAPH:String = "Paragraph";
+		public static const CONTAINER:String = "Container";
+		public static const CHARACTER:String = "Character";
+		public static const TABSTOP:String = "TabStop";
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/formats/Direction.as b/textLayout_core/src/flashx/textLayout/formats/Direction.as
new file mode 100755
index 0000000..fc1469b
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/Direction.as
@@ -0,0 +1,51 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	/**
+	 *  Defines values for setting the <code>direction</code> property
+	 *  of the <code>TextLayoutFormat</code> class. Left-to-right reading order 
+	 *  is used in Latin-style scripts. Right-to-left reading order is used with scripts such as Arabic or Hebrew. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 * @see TextLayoutFormat#direction 
+	 */
+	public final class Direction
+	{
+		/** Specifies left-to-right direction for text. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const LTR:String = "ltr";
+		
+		/** Specifies right-to-left direction for text. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const RTL:String = "rtl";
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/formats/Float.as b/textLayout_core/src/flashx/textLayout/formats/Float.as
new file mode 100755
index 0000000..dd0eea8
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/Float.as
@@ -0,0 +1,40 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	/**
+	 *  Some of the values for the <code>float</code> property
+	 *  of the InlineGraphicElement class. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 *  @see text.InlineGrapic
+	 * @private - still in prototype phase
+	 */
+	public final class Float
+	{
+		/** None - graphic will appear inline in the text (doesn't float) */
+		public static const NONE:String = "none";		
+		/** Left - graphic will float on the left side of the text */
+		public static const LEFT:String = "left";
+		/** Right - graphic will float on the right side of the text */
+		public static const RIGHT:String = "right";
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/formats/FlowElementDisplayType.as b/textLayout_core/src/flashx/textLayout/formats/FlowElementDisplayType.as
new file mode 100755
index 0000000..16ceded
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/FlowElementDisplayType.as
@@ -0,0 +1,39 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+[ExcludeClass]
+	/**
+	 * An enumeration to describe how a FlowElement should be treated when composed. 
+	 * @see text.elements.FlowElement#display
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 * These APIs are still in prototype phase
+	 * @private
+	 */
+	public final class FlowElementDisplayType 
+	{
+			/** Element appears inline in the text; it is placed in its parent's geometry context */
+		public static const INLINE:String = "inline";
+			/** Element floats with the text, but supplies its own geometry context (e.g., a sidebar or table) */
+		public static const FLOAT:String = "float";	
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/formats/FormatValue.as b/textLayout_core/src/flashx/textLayout/formats/FormatValue.as
new file mode 100755
index 0000000..d544a75
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/FormatValue.as
@@ -0,0 +1,55 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	/**
+	 *  Defines values for specifying that a formatting property is to inherit its parent's value or have it's value
+	 *  generated automatically. The <code>INHERIT</code> constant specifies that a property inherits its parent's value 
+	 *  while the <code>AUTO</code> constant specifies that an internal algorithm automatically determine the property's 
+	 *  value. As one example, you can set <code>TextLayoutFormat.columnWidth</code> using these values. Typically, a 
+	 *  property's description indicates whether it accepts these constants.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 *
+	 * @see flashx.textLayout.formats.TextLayoutFormat TextLayoutFormat
+	 */
+	 
+	public final class FormatValue
+	{
+		/** Specifies that a property's value is automatically generated. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const AUTO:String = "auto";
+		
+		/** Specifies that a property is to inherit its parent's value.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const INHERIT:String = "inherit";
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/formats/IMEStatus.as b/textLayout_core/src/flashx/textLayout/formats/IMEStatus.as
new file mode 100755
index 0000000..a0b0e45
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/IMEStatus.as
@@ -0,0 +1,103 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	[ExcludeClass]
+	/**
+	 *  Used internally for specifying the status of clauses in IME text during an IME text entry session.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public final class IMEStatus
+	{
+		public function IMEStatus()
+		{
+		}
+		
+		/** The name of the IMEClause property. Value is an integer.
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public static const IME_CLAUSE:String = "imeClause";
+		
+		/** The name of the IMEStatus property
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public static const IME_STATUS:String = "imeStatus";
+		
+		// Following are all the possible values of imeStatus property:
+		
+		/** Selected raw - text has not been converted and is the current clause in the IME session
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public static const SELECTED_RAW:String = "selectedRaw";
+
+		/** Selected coverted - text has been converted and is the current clause in the IME session
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public static const SELECTED_CONVERTED:String = "selectedConverted";
+
+		/** Not selected raw - text has not been converted and is not part of the current clause 
+		 *  in the IME session
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public static const NOT_SELECTED_RAW:String = "notSelectedRaw";
+		
+		/** Not selected converted - text has been converted and is not part of the current clause 
+		 * 	in the IME session
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public static const NOT_SELECTED_CONVERTED:String = "notSelectedConverted";
+
+		/** Dead key input state - in the process of entering a multi-key character, such as an accented char
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public static const DEAD_KEY_INPUT_STATE:String = "deadKeyInputState";
+
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/formats/ITabStopFormat.as b/textLayout_core/src/flashx/textLayout/formats/ITabStopFormat.as
new file mode 100755
index 0000000..d51b50b
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/ITabStopFormat.as
@@ -0,0 +1,74 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	/**
+	 * This interface provides read access to tab stop-related properties.
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public interface ITabStopFormat
+	{
+		/**
+		 * The position of the tab stop, in pixels, relative to the start of the line.
+		 * <p>Legal values are numbers from 0 to 10000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 0.</p>
+		 * @see FormatValue#INHERIT
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get position():*;
+
+		/**
+		 * The tab alignment for this tab stop. 
+		 * <p>Legal values are flash.text.engine.TabAlignment.START, flash.text.engine.TabAlignment.CENTER, flash.text.engine.TabAlignment.END, flash.text.engine.TabAlignment.DECIMAL, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of START.</p>
+		 * @see FormatValue#INHERIT
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.TabAlignment
+		 */
+		function get alignment():*;
+
+		/**
+		 * The alignment token to be used if the alignment is DECIMAL.
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of null.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get decimalAlignmentToken():*;
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/formats/ITextLayoutFormat.as b/textLayout_core/src/flashx/textLayout/formats/ITextLayoutFormat.as
new file mode 100755
index 0000000..5acb152
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/ITextLayoutFormat.as
@@ -0,0 +1,816 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	/**
+	 * This interface provides read access to FlowElements-related properties.
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public interface ITextLayoutFormat
+	{
+		/**
+		 * Color of the text. A hexadecimal number that specifies three 8-bit RGB (red, green, blue) values; for example, 0xFF0000 is red and 0x00FF00 is green. 
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get color():*;
+
+		/**
+		 * Background color of the text (adopts default value if undefined during cascade). Can be either the constant value  <code>BackgroundColor.TRANSPARENT</code>, or a hexadecimal value that specifies the three 8-bit RGB (red, green, blue) values; for example, 0xFF0000 is red and 0x00FF00 is green.
+		 * <p>Legal values as a string are flashx.textLayout.formats.BackgroundColor.TRANSPARENT, flashx.textLayout.formats.FormatValue.INHERIT and uints from 0x0 to 0xffffffff.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of TRANSPARENT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.BackgroundColor
+		 */
+		function get backgroundColor():*;
+
+		/**
+		 * If <code>true</code>, applies strikethrough, a line drawn through the middle of the text.
+		 * <p>Legal values are true, false and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of false.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get lineThrough():*;
+
+		/**
+		 * Alpha (transparency) value for the text. A value of 0 is fully transparent, and a value of 1 is fully opaque. Display objects with <code>textAlpha</code> set to 0 are active, even though they are invisible.
+		 * <p>Legal values are numbers from 0 to 1 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 1.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get textAlpha():*;
+
+		/**
+		 * Alpha (transparency) value for the background (adopts default value if undefined during cascade). A value of 0 is fully transparent, and a value of 1 is fully opaque. Display objects with alpha set to 0 are active, even though they are invisible.
+		 * <p>Legal values are numbers from 0 to 1 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 1.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get backgroundAlpha():*;
+
+		/**
+		 * The size of the text in pixels.
+		 * <p>Legal values are numbers from 1 to 720 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 12.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get fontSize():*;
+
+		/**
+		 * Amount to shift the baseline from the <code>dominantBaseline</code> value. Units are in pixels, or a percentage of <code>fontSize</code> (in which case, enter a string value, like 140%).  Positive values shift the line up for horizontal text (right for vertical) and negative values shift it down for horizontal (left for vertical). 
+		 * <p>Legal values are flashx.textLayout.formats.BaselineShift.SUPERSCRIPT, flashx.textLayout.formats.BaselineShift.SUBSCRIPT, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Legal values as a number are from -1000 to 1000.</p>
+		 * <p>Legal values as a percent are numbers from -1000 to 1000.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.BaselineShift
+		 */
+		function get baselineShift():*;
+
+		/**
+		 * Number in pixels (or percent of <code>fontSize</code>, like 120%) indicating the amount of tracking (manual kerning) to be applied to the left of each character. If kerning is enabled, the <code>trackingLeft</code> value is added to the values in the kerning table for the font. If kerning is disabled, the <code>trackingLeft</code> value is used as a manual kerning value. Supports both positive and negative values. 
+		 * <p>Legal values as a number are from -1000 to 1000.</p>
+		 * <p>Legal values as a percent are numbers from -1000% to 1000%.</p>
+		 * <p>Legal values include flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get trackingLeft():*;
+
+		/**
+		 * Number in pixels (or percent of <code>fontSize</code>, like 120%) indicating the amount of tracking (manual kerning) to be applied to the right of each character.  If kerning is enabled, the <code>trackingRight</code> value is added to the values in the kerning table for the font. If kerning is disabled, the <code>trackingRight</code> value is used as a manual kerning value. Supports both positive and negative values. 
+		 * <p>Legal values as a number are from -1000 to 1000.</p>
+		 * <p>Legal values as a percent are numbers from -1000% to 1000%.</p>
+		 * <p>Legal values include flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get trackingRight():*;
+
+		/**
+		 * Leading controls for the text. The distance from the baseline of the previous or the next line (based on <code>LeadingModel</code>) to the baseline of the current line is equal to the maximum amount of the leading applied to any character in the line. This is either a number or a percent.  If specifying a percent, enter a string value, like 140%.<p><img src='../../../images/textLayout_lineHeight1.jpg' alt='lineHeight1' /><img src='../../../images/textLayout_lineHeight2.jpg' alt='lineHeight2' /></p>
+		 * <p>Legal values as a number are from -720 to 720.</p>
+		 * <p>Legal values as a percent are numbers from -1000% to 1000%.</p>
+		 * <p>Legal values include flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 120%.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get lineHeight():*;
+
+		/**
+		 * Controls where lines are allowed to break when breaking wrapping text into multiple lines. Set to <code>BreakOpportunity.AUTO</code> to break text normally. Set to <code>BreakOpportunity.NONE</code> to <em>not</em> break the text unless the text would overrun the measure and there are no other places to break the line. Set to <code>BreakOpportunity.ANY</code> to allow the line to break anywhere, rather than just between words. Set to <code>BreakOpportunity.ALL</code> to have each typographic cluster put on a separate line (useful for text on a path).
+		 * <p>Legal values are flash.text.engine.BreakOpportunity.ALL, flash.text.engine.BreakOpportunity.ANY, flash.text.engine.BreakOpportunity.AUTO, flash.text.engine.BreakOpportunity.NONE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.BreakOpportunity
+		 */
+		function get breakOpportunity():*;
+
+		/**
+		 * The type of digit case used for this text. Setting the value to <code>DigitCase.OLD_STYLE</code> approximates lowercase letterforms with varying ascenders and descenders. The figures are proportionally spaced. This style is only available in selected typefaces, most commonly in a supplemental or expert font. The <code>DigitCase.LINING</code> setting has all-cap height and is typically monospaced to line up in charts.<p><img src='../../../images/textLayout_digitcase.gif' alt='digitCase' /></p>
+		 * <p>Legal values are flash.text.engine.DigitCase.DEFAULT, flash.text.engine.DigitCase.LINING, flash.text.engine.DigitCase.OLD_STYLE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of DEFAULT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.DigitCase
+		 */
+		function get digitCase():*;
+
+		/**
+		 * Type of digit width used for this text. This can be <code>DigitWidth.PROPORTIONAL</code>, which looks best for individual numbers, or <code>DigitWidth.TABULAR</code>, which works best for numbers in tables, charts, and vertical rows.<p><img src='../../../images/textLayout_digitwidth.gif' alt='digitWidth' /></p>
+		 * <p>Legal values are flash.text.engine.DigitWidth.DEFAULT, flash.text.engine.DigitWidth.PROPORTIONAL, flash.text.engine.DigitWidth.TABULAR, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of DEFAULT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.DigitWidth
+		 */
+		function get digitWidth():*;
+
+		/**
+		 * Specifies which element baseline snaps to the <code>alignmentBaseline</code> to determine the vertical position of the element on the line. A value of <code>TextBaseline.AUTO</code> selects the dominant baseline based on the <code>locale</code> property of the parent paragraph.  For Japanese and Chinese, the selected baseline value is <code>TextBaseline.IDEOGRAPHIC_CENTER</code>; for all others it is <code>TextBaseline.ROMAN</code>. These baseline choices are determined by the choice of font and the font size.<p><img src='../../../images/textLayout_baselines.jpg' alt='baselines' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.FormatValue.AUTO, flash.text.engine.TextBaseline.ROMAN, flash.text.engine.TextBaseline.ASCENT, flash.text.engine.TextBaseline.DESCENT, flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP, flash.text.engine.TextBaseline.IDEOGRAPHIC_CENTER, flash.text.engine.TextBaseline.IDEOGRAPHIC_BOTTOM, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of flashx.textLayout.formats.FormatValue.AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.TextBaseline
+		 */
+		function get dominantBaseline():*;
+
+		/**
+		 * Kerning adjusts the pixels between certain character pairs to improve readability. Kerning is supported for all fonts with kerning tables.
+		 * <p>Legal values are flash.text.engine.Kerning.ON, flash.text.engine.Kerning.OFF, flash.text.engine.Kerning.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.Kerning
+		 */
+		function get kerning():*;
+
+		/**
+		 * Controls which of the ligatures that are defined in the font may be used in the text. The ligatures that appear for each of these settings is dependent on the font. A ligature occurs where two or more letter-forms are joined as a single glyph. Ligatures usually replace consecutive characters sharing common components, such as the letter pairs 'fi', 'fl', or 'ae'. They are used with both Latin and Non-Latin character sets. The ligatures enabled by the values of the LigatureLevel class - <code>MINIMUM</code>, <code>COMMON</code>, <code>UNCOMMON</code>, and <code>EXOTIC</code> - are additive. Each value enables a new set of ligatures, but also includes those of the previous types.<p><b>Note: </b>When working with Arabic or Syriac fonts, <code>ligatureLevel</code> must be set to MINIMUM or above.</p><p><img src='../../../images/textLayout_ligatures.png' alt='ligatureLevel' /></p>
+		 * <p>Legal values are flash.text.engine.LigatureLevel.MINIMUM, flash.text.engine.LigatureLevel.COMMON, flash.text.engine.LigatureLevel.UNCOMMON, flash.text.engine.LigatureLevel.EXOTIC, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of COMMON.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.LigatureLevel
+		 */
+		function get ligatureLevel():*;
+
+		/**
+		 * Specifies the baseline to which the dominant baseline aligns. For example, if you set <code>dominantBaseline</code> to ASCENT, setting <code>alignmentBaseline</code> to DESCENT aligns the top of the text with the DESCENT baseline, or below the line.  The largest element in the line generally determines the baselines.<p><img src='../../../images/textLayout_baselines.jpg' alt='baselines' /></p>
+		 * <p>Legal values are flash.text.engine.TextBaseline.ROMAN, flash.text.engine.TextBaseline.ASCENT, flash.text.engine.TextBaseline.DESCENT, flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP, flash.text.engine.TextBaseline.IDEOGRAPHIC_CENTER, flash.text.engine.TextBaseline.IDEOGRAPHIC_BOTTOM, flash.text.engine.TextBaseline.USE_DOMINANT_BASELINE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of USE_DOMINANT_BASELINE.</p>
+		 * @includeExample examples\TextLayoutFormat_alignmentBaselineExample.as -noswf
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.TextBaseline
+		 */
+		function get alignmentBaseline():*;
+
+		/**
+		 * The locale of the text. Controls case transformations and shaping. Standard locale identifiers as described in Unicode Technical Standard #35 are used. For example en, en_US and en-US are all English, ja is Japanese. 
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of en.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get locale():*;
+
+		/**
+		 * The type of typographic case used for this text. Here are some examples:<p><img src='../../../images/textLayout_typographiccase.png' alt='typographicCase' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.TLFTypographicCase.DEFAULT, flashx.textLayout.formats.TLFTypographicCase.CAPS_TO_SMALL_CAPS, flashx.textLayout.formats.TLFTypographicCase.UPPERCASE, flashx.textLayout.formats.TLFTypographicCase.LOWERCASE, flashx.textLayout.formats.TLFTypographicCase.LOWERCASE_TO_SMALL_CAPS, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of DEFAULT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TLFTypographicCase
+		 */
+		function get typographicCase():*;
+
+		/**
+		 *  The name of the font to use, or a comma-separated list of font names. The Flash runtime renders the element with the first available font in the list. For example Arial, Helvetica, _sans causes the player to search for Arial, then Helvetica if Arial is not found, then _sans if neither is found.
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of Arial.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get fontFamily():*;
+
+		/**
+		 * Decoration on text. Use to apply underlining; default is none.
+		 * <p>Legal values are flashx.textLayout.formats.TextDecoration.NONE, flashx.textLayout.formats.TextDecoration.UNDERLINE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of NONE.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TextDecoration
+		 */
+		function get textDecoration():*;
+
+		/**
+		 * Weight of text. May be <code>FontWeight.NORMAL</code> for use in plain text, or <code>FontWeight.BOLD</code>. Applies only to device fonts (<code>fontLookup</code> property is set to flash.text.engine.FontLookup.DEVICE).
+		 * <p>Legal values are flash.text.engine.FontWeight.NORMAL, flash.text.engine.FontWeight.BOLD, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of NORMAL.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.FontWeight
+		 */
+		function get fontWeight():*;
+
+		/**
+		 * Style of text. May be <code>FontPosture.NORMAL</code>, for use in plain text, or <code>FontPosture.ITALIC</code> for italic. This property applies only to device fonts (<code>fontLookup</code> property is set to flash.text.engine.FontLookup.DEVICE).
+		 * <p>Legal values are flash.text.engine.FontPosture.NORMAL, flash.text.engine.FontPosture.ITALIC, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of NORMAL.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.FontPosture
+		 */
+		function get fontStyle():*;
+
+		/**
+		 * Collapses or preserves whitespace when importing text into a TextFlow. <code>WhiteSpaceCollapse.PRESERVE</code> retains all whitespace characters. <code>WhiteSpaceCollapse.COLLAPSE</code> removes newlines, tabs, and leading or trailing spaces within a block of imported text. Line break tags (<br/>) and Unicode line separator characters are retained.
+		 * <p>Legal values are flashx.textLayout.formats.WhiteSpaceCollapse.PRESERVE, flashx.textLayout.formats.WhiteSpaceCollapse.COLLAPSE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of COLLAPSE.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.WhiteSpaceCollapse
+		 */
+		function get whiteSpaceCollapse():*;
+
+		/**
+		 * The rendering mode used for this text.  Applies only to embedded fonts (<code>fontLookup</code> property is set to <code>FontLookup.EMBEDDED_CFF</code>).
+		 * <p>Legal values are flash.text.engine.RenderingMode.NORMAL, flash.text.engine.RenderingMode.CFF, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of CFF.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.RenderingMode
+		 */
+		function get renderingMode():*;
+
+		/**
+		 * The type of CFF hinting used for this text. CFF hinting determines whether the Flash runtime forces strong horizontal stems to fit to a sub pixel grid or not. This property applies only if the <code>renderingMode</code> property is set to <code>RenderingMode.CFF</code>, and the font is embedded (<code>fontLookup</code> property is set to <code>FontLookup.EMBEDDED_CFF</code>). At small screen sizes, hinting produces a clear, legible text for human readers.
+		 * <p>Legal values are flash.text.engine.CFFHinting.NONE, flash.text.engine.CFFHinting.HORIZONTAL_STEM, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of HORIZONTAL_STEM.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.CFFHinting
+		 */
+		function get cffHinting():*;
+
+		/**
+		 * Font lookup to use. Specifying <code>FontLookup.DEVICE</code> uses the fonts installed on the system that is running the SWF file. Device fonts result in a smaller movie size, but text is not always rendered the same across different systems and platforms. Specifying <code>FontLookup.EMBEDDED_CFF</code> uses font outlines embedded in the published SWF file. Embedded fonts increase the size of the SWF file (sometimes dramatically), but text is consistently displayed in the chosen font.
+		 * <p>Legal values are flash.text.engine.FontLookup.DEVICE, flash.text.engine.FontLookup.EMBEDDED_CFF, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of DEVICE.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.FontLookup
+		 */
+		function get fontLookup():*;
+
+		/**
+		 * Determines the number of degrees to rotate this text.
+		 * <p>Legal values are flash.text.engine.TextRotation.ROTATE_0, flash.text.engine.TextRotation.ROTATE_180, flash.text.engine.TextRotation.ROTATE_270, flash.text.engine.TextRotation.ROTATE_90, flash.text.engine.TextRotation.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.TextRotation
+		 */
+		function get textRotation():*;
+
+		/**
+		 * A Number that specifies, in pixels, the amount to indent the first line of the paragraph.
+		 * A negative indent will push the line into the margin, and possibly out of the container.
+		 * <p>Legal values are numbers from -1000 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get textIndent():*;
+
+		/**
+		 * A Number that specifies, in pixels, the amount to indent the paragraph's start edge. Refers to the left edge in left-to-right text and the right edge in right-to-left text. 
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get paragraphStartIndent():*;
+
+		/**
+		 * A Number that specifies, in pixels, the amount to indent the paragraph's end edge. Refers to the right edge in left-to-right text and the left edge in right-to-left text. 
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get paragraphEndIndent():*;
+
+		/**
+		 * A Number that specifies the amount of space, in pixels, to leave before the paragraph. 
+		 * Collapses in tandem with <code>paragraphSpaceAfter</code>.
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get paragraphSpaceBefore():*;
+
+		/**
+		 * A Number that specifies the amount of space, in pixels, to leave after the paragraph.
+		 * Collapses in tandem with  <code>paragraphSpaceBefore</code>.
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get paragraphSpaceAfter():*;
+
+		/**
+		 * Alignment of lines in the paragraph relative to the container.
+		 * <code>TextAlign.LEFT</code> aligns lines along the left edge of the container. <code>TextAlign.RIGHT</code> aligns on the right edge. <code>TextAlign.CENTER</code> positions the line equidistant from the left and right edges. <code>TextAlign.JUSTIFY</code> spreads the lines out so they fill the space. <code>TextAlign.START</code> is equivalent to setting left in left-to-right text, or right in right-to-left text. <code>TextAlign.END</code> is equivalent to setting right in left-to-right text, or left in right-to-left text.
+		 * <p>Legal values are flashx.textLayout.formats.TextAlign.LEFT, flashx.textLayout.formats.TextAlign.RIGHT, flashx.textLayout.formats.TextAlign.CENTER, flashx.textLayout.formats.TextAlign.JUSTIFY, flashx.textLayout.formats.TextAlign.START, flashx.textLayout.formats.TextAlign.END, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of START.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TextAlign
+		 */
+		function get textAlign():*;
+
+		/**
+		 * Alignment of the last (or only) line in the paragraph relative to the container in justified text.
+		 * If <code>textAlign</code> is set to <code>TextAlign.JUSTIFY</code>, <code>textAlignLast</code> specifies how the last line (or only line, if this is a one line block) is aligned. Values are similar to <code>textAlign</code>.
+		 * <p>Legal values are flashx.textLayout.formats.TextAlign.LEFT, flashx.textLayout.formats.TextAlign.RIGHT, flashx.textLayout.formats.TextAlign.CENTER, flashx.textLayout.formats.TextAlign.JUSTIFY, flashx.textLayout.formats.TextAlign.START, flashx.textLayout.formats.TextAlign.END, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of START.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TextAlign
+		 */
+		function get textAlignLast():*;
+
+		/**
+		 * Specifies options for justifying text.
+		 * Default value is <code>TextJustify.INTER_WORD</code>, meaning that extra space is added to the space characters. <code>TextJustify.DISTRIBUTE</code> adds extra space to space characters and between individual letters. Used only in conjunction with a <code>justificationRule</code> value of <code>JustificationRule.SPACE</code>.
+		 * <p>Legal values are flashx.textLayout.formats.TextJustify.INTER_WORD, flashx.textLayout.formats.TextJustify.DISTRIBUTE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of INTER_WORD.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TextJustify
+		 */
+		function get textJustify():*;
+
+		/**
+		 * Rule used to justify text in a paragraph.
+		 * Default value is <code>FormatValue.AUTO</code>, which justifies text based on the paragraph's <code>locale</code> property. For all languages except Japanese and Chinese, <code>FormatValue.AUTO</code> becomes <code>JustificationRule.SPACE</code>, which adds extra space to the space characters.  For Japanese and Chinese, <code>FormatValue.AUTO</code> becomes <code>JustficationRule.EAST_ASIAN</code>. In part, justification changes the spacing of punctuation. In Roman text the comma and Japanese periods take a full character's width but in East Asian text only half of a character's width. Also, in the East Asian text the spacing between sequential punctuation marks becomes tighter, obeying traditional East Asian typographic conventions. Note, too, in the example below the leading that is applied to the second line of the paragraphs. In the East Asian version, the last two lines push left. In the Roman version, the second and following lines push left.<p><img src='../../../images/textLayout_justificationrule.png' alt='justificationRule' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.JustificationRule.EAST_ASIAN, flashx.textLayout.formats.JustificationRule.SPACE, flashx.textLayout.formats.FormatValue.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of flashx.textLayout.formats.FormatValue.AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.JustificationRule
+		 */
+		function get justificationRule():*;
+
+		/**
+		 * The style used for justification of the paragraph. Used only in conjunction with a <code>justificationRule</code> setting of <code>JustificationRule.EAST_ASIAN</code>.
+		 * Default value of <code>FormatValue.AUTO</code> is resolved to <code>JustificationStyle.PUSH_IN_KINSOKU</code> for all locales.  The constants defined by the JustificationStyle class specify options for handling kinsoku characters, which are Japanese characters that cannot appear at either the beginning or end of a line. If you want looser text, specify <code>JustificationStyle.PUSH-OUT-ONLY</code>. If you want behavior that is like what you get with the  <code>justificationRule</code> of <code>JustificationRule.SPACE</code>, use <code>JustificationStyle.PRIORITIZE-LEAST-ADJUSTMENT</code>.
+		 * <p>Legal values are flash.text.engine.JustificationStyle.PRIORITIZE_LEAST_ADJUSTMENT, flash.text.engine.JustificationStyle.PUSH_IN_KINSOKU, flash.text.engine.JustificationStyle.PUSH_OUT_ONLY, flashx.textLayout.formats.FormatValue.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of flashx.textLayout.formats.FormatValue.AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.JustificationStyle
+		 */
+		function get justificationStyle():*;
+
+		/**
+		 * Specifies the default bidirectional embedding level of the text in the text block. 
+		 * Left-to-right reading order, as in Latin-style scripts, or right-to-left reading order, as in Arabic or Hebrew. This property also affects column direction when it is applied at the container level. Columns can be either left-to-right or right-to-left, just like text. Below are some examples:<p><img src='../../../images/textLayout_direction.gif' alt='direction' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.Direction.LTR, flashx.textLayout.formats.Direction.RTL, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of LTR.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.Direction
+		 */
+		function get direction():*;
+
+		/**
+		 * Specifies the tab stops associated with the paragraph.
+		 * Setters can take an array of flashx.textLayout.formats.TabStopFormat, a condensed string representation, undefined, or <code>FormatValue.INHERIT</code>. The condensed string representation is always converted into an array of flashx.textLayout.formats.TabStopFormat. <p>The string-based format is a list of tab stops, where each tab stop is delimited by one or more spaces.</p><p>A tab stop takes the following form: &lt;alignment type&gt;&lt;alignment position&gt;|&lt;alignment token&gt;.</p><p>The alignment type is a single character, and can be S, E, C, or D (or lower-case equivalents). S or s for start, E or e for end, C or c for center, D or d for decimal. The alignment type is optional, and if its not specified will default to S.</p><p>The alignment position is a Number, and is specified according to FXG spec for Numbers (decimal or scientific notation). The alignment position is required.</p><p>The vertical bar is used to separate the alignment position from the alignment token, and should only be present if the alignment token is present.</p><p> The alignment token is optional if the alignment type is D, and should not be present if the alignment type is anything other than D. The alignment token may be any sequence of characters terminated by the space that ends the tab stop (for the last tab stop, the terminating space is optional; end of alignment token is implied). A space may be part of the alignment token if it is escaped with a backslash (\ ). A backslash may be part of the alignment token if it is escaped with another backslash (\\). If the alignment type is D, and the alignment token is not specified, it will take on the default value of null.</p><p>If no tab stops are specified, a tab action defaults to the end of the line.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of null.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get tabStops():*;
+
+		/**
+		 * Specifies the leading model, which is a combination of leading basis and leading direction.
+		 * Leading basis is the baseline to which the <code>lineHeight</code> property refers. Leading direction determines whether the <code>lineHeight</code> property refers to the distance of a line's baseline from that of the line before it or the line after it. The default value of <code>FormatValue.AUTO</code> is resolved based on the paragraph's <code>locale</code> property.  For Japanese and Chinese, it is <code>LeadingModel.IDEOGRAPHIC_TOP_DOWN</code> and for all others it is <code>LeadingModel.ROMAN_UP</code>.<p><strong>Leading Basis:</strong></p><p><img src='../../../images/textLayout_LB1.png' alt='leadingBasis1' />    <img src='../../../images/textLayout_LB2.png' alt='leadingBasis2' />    <img src='../../../images/textLayout_LB3.png' alt='leadingBasis3' /></p><p><strong>Leading Direction:</strong></p><p><img src='../../../images/textLayout_LD1.png' alt='leadingDirection1' />    <img src='../../../images/textLayout_LD2.png' alt='leadingDirection2' />    <img src='../../../images/textLayout_LD3.png' alt='leadingDirection3' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.LeadingModel.ROMAN_UP, flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_TOP_UP, flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_CENTER_UP, flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_TOP_DOWN, flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_CENTER_DOWN, flashx.textLayout.formats.LeadingModel.APPROXIMATE_TEXT_FIELD, flashx.textLayout.formats.LeadingModel.ASCENT_DESCENT_UP, flashx.textLayout.formats.LeadingModel.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.LeadingModel
+		 */
+		function get leadingModel():*;
+
+		/**
+		 * Specifies the amount of gutter space, in pixels, to leave between the columns (adopts default value if undefined during cascade).
+		 * Value is a Number
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 20.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get columnGap():*;
+
+		/**
+		 * Left inset in pixels (adopts default value if undefined during cascade).
+		 * Space between the left edge of the container and the text.  Value is a Number.<p> With vertical text, in scrollable containers with multiple columns, the first and following columns will show the padding as blank space at the end of the container, but for the last column, if the text doesn't all fit, you may have to scroll in order to see the padding.</p>
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get paddingLeft():*;
+
+		/**
+		 * Top inset in pixels (adopts default value if undefined during cascade).
+		 * Space between the top edge of the container and the text.  Value is a Number.
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get paddingTop():*;
+
+		/**
+		 * Right inset in pixels (adopts default value if undefined during cascade).
+		 * Space between the right edge of the container and the text.  Value is a Number.
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get paddingRight():*;
+
+		/**
+		 * Botttom inset in pixels (adopts default value if undefined during cascade).
+		 * Space between the bottom edge of the container and the text.  Value is a Number. <p> With horizontal text, in scrollable containers with multiple columns, the first and following columns will show the padding as blank space at the bottom of the container, but for the last column, if the text doesn't all fit, you may have to scroll in order to see the padding.</p>
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		function get paddingBottom():*;
+
+		/**
+		 * Number of text columns (adopts default value if undefined during cascade).
+		 * The column number overrides the  other column settings. Value is an integer, or <code>FormatValue.AUTO</code> if unspecified. If <code>columnCount</code> is not specified,<code>columnWidth</code> is used to create as many columns as can fit in the container.
+		 * <p>Legal values as a string are flashx.textLayout.formats.FormatValue.AUTO, flashx.textLayout.formats.FormatValue.INHERIT and from ints from 1 to 50.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.FormatValue
+		 */
+		function get columnCount():*;
+
+		/**
+		 * Column width in pixels (adopts default value if undefined during cascade).
+		 * If you specify the width of the columns, but not the count, TextLayout will create as many columns of that width as possible, given the  container width and <code>columnGap</code> settings. Any remainder space is left after the last column. Value is a Number.
+		 * <p>Legal values as a string are flashx.textLayout.formats.FormatValue.AUTO, flashx.textLayout.formats.FormatValue.INHERIT and numbers from 0 to 8000.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.FormatValue
+		 */
+		function get columnWidth():*;
+
+		/**
+		 * Specifies the baseline position of the first line in the container. Which baseline this property refers to depends on the container-level locale.  For Japanese and Chinese, it is <code>TextBaseline.IDEOGRAPHIC_BOTTOM</code>; for all others it is <code>TextBaseline.ROMAN</code>.
+		 * The offset from the top inset (or right inset if <code>blockProgression</code> is RL) of the container to the baseline of the first line can be either <code>BaselineOffset.ASCENT</code>, meaning equal to the ascent of the line, <code>BaselineOffset.LINE_HEIGHT</code>, meaning equal to the height of that first line, or any fixed-value number to specify an absolute distance. <code>BaselineOffset.AUTO</code> aligns the ascent of the line with the container top inset.<p><img src='../../../images/textLayout_FBO1.png' alt='firstBaselineOffset1' /><img src='../../../images/textLayout_FBO2.png' alt='firstBaselineOffset2' /><img src='../../../images/textLayout_FBO3.png' alt='firstBaselineOffset3' /><img src='../../../images/textLayout_FBO4.png' alt='firstBaselineOffset4' /></p>
+		 * <p>Legal values as a string are flashx.textLayout.formats.BaselineOffset.AUTO, flashx.textLayout.formats.BaselineOffset.ASCENT, flashx.textLayout.formats.BaselineOffset.LINE_HEIGHT, flashx.textLayout.formats.FormatValue.INHERIT and numbers from 0 to 1000.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.BaselineOffset
+		 */
+		function get firstBaselineOffset():*;
+
+		/**
+		 * Vertical alignment or justification (adopts default value if undefined during cascade).
+		 * Determines how TextFlow elements align within the container.
+		 * <p>Legal values are flashx.textLayout.formats.VerticalAlign.TOP, flashx.textLayout.formats.VerticalAlign.MIDDLE, flashx.textLayout.formats.VerticalAlign.BOTTOM, flashx.textLayout.formats.VerticalAlign.JUSTIFY, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of TOP.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.VerticalAlign
+		 */
+		function get verticalAlign():*;
+
+		/**
+		 * Specifies a vertical or horizontal progression of line placement.
+		 * Lines are either placed top-to-bottom (<code>BlockProgression.TB</code>, used for horizontal text) or right-to-left (<code>BlockProgression.RL</code>, used for vertical text).
+		 * <p>Legal values are flashx.textLayout.formats.BlockProgression.RL, flashx.textLayout.formats.BlockProgression.TB, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of TB.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.BlockProgression
+		 */
+		function get blockProgression():*;
+
+		/**
+		 * Controls word wrapping within the container (adopts default value if undefined during cascade).
+		 * Text in the container may be set to fit the width of the container (<code>LineBreak.TO_FIT</code>), or can be set to break only at explicit return or line feed characters (<code>LineBreak.EXPLICIT</code>).
+		 * <p>Legal values are flashx.textLayout.formats.LineBreak.EXPLICIT, flashx.textLayout.formats.LineBreak.TO_FIT, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of TO_FIT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.LineBreak
+		 */
+		function get lineBreak():*;
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/formats/JustificationRule.as b/textLayout_core/src/flashx/textLayout/formats/JustificationRule.as
new file mode 100755
index 0000000..00b7769
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/JustificationRule.as
@@ -0,0 +1,60 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	/**
+	 *  Defines values for setting the <code>justificationRule</code> property
+	 *  of the TextLayoutFormat class. Default value is SPACE, which accomplishes justification by adding 
+	 *  extra space to the space characters. When you use EAST_ASIAN, Japanese style leading is employed, which 
+	 *  applies bottom-down as opposed to top-up, which is used in Roman text. The spacing of punctuation is also 
+	 *  different. In the Roman version, the comma and Japanese periods take a full character's width but only half 
+	 *  in East Asian. Additionally, the spacing between sequential punctuation marks becomes tighter, obeying traditional 
+	 *  East Asian typographic conventions. Also note the leading, applied to the second line of the paragraphs in the 
+	 *  example below. In the East Asian version, the last two lines push left. In the Roman version, the second and 
+	 *  following lines push left.
+	 *  <p><img src="../../../images/textLayout_justificationrule.png" alt="justificationRule" /></p>
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 *
+	 * @see TextLayoutFormat#justificationRule
+	 */
+	public final class JustificationRule
+	{
+		/** Specifies East Asian justification rules. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const EAST_ASIAN:String = "eastAsian";
+		
+		/** Specifies justification for Latin and other horizontal scripts that divide words using spaces. 
+		 *  Use this value for everything except East Asian text.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const SPACE:String = "space";
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/formats/LeadingModel.as b/textLayout_core/src/flashx/textLayout/formats/LeadingModel.as
new file mode 100755
index 0000000..d26c362
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/LeadingModel.as
@@ -0,0 +1,137 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	/**
+	 *  Defines values for setting the <code>leadingModel</code> property
+	 *  of the <code>TextLayoutFormat</code> class, composed of valid combinations of leading basis and leading direction.
+	 *  Leading basis describes which baselines determine the leading (or <code>lineHeight</code>) of lines in a paragraph.
+	 *  Leading direction specifies whether the <code>lineHeight</code> property refers to the distance of a line's 
+	 *  baseline from that of the line before it or the line after it. 
+	 *  <p>
+	 *  <img src="../../../images/textLayout_baselines.jpg" alt="baselines" border="0"/>
+	 *  <img src="../../../images/textLayout_LD1.jpg" alt="leadingDirection_1" border="0"/>
+	 *  <img src="../../../images/textLayout_LD2.jpg" alt="leadingDirection_2" border="0"/>
+	 *  <img src="../../../images/textLayout_LD3.jpg" alt="leadingDirection_3" border="0"/>
+	 *  </p>
+	 *  @playerversion Flash 10
+	 *  @playerversion AIR 1.5
+	 *  @langversion 3.0 
+	 * 
+	 *  @see TextLayoutFormat#leadingModel
+	 *  @see TextLayoutFormat#lineHeight
+	 *  @see flash.text.TextField
+	 *  @see flash.text.engine.TextLine 
+	 */
+	 
+	public final class LeadingModel
+	{
+		/** Specifies that leading basis is ROMAN and leading direction is UP. 
+		 * In other words, <code>lineHeight</code> refers to the distance of a line's Roman baseline from the 
+		 * previous line's Roman baseline.
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	  	 * @langversion 3.0 
+	 	 */
+	 	 
+		public static const ROMAN_UP:String = "romanUp";
+		
+		/** Specifies that leading basis is IDEOGRAPHIC_TOP and leading direction is UP. 
+		 *  In other words, <code>lineHeight</code> refers to the distance of a line's ideographic top 
+		 *  baseline from the previous line's ideographic top baseline.
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+	 	 */
+	 	 
+		public static const IDEOGRAPHIC_TOP_UP:String = "ideographicTopUp";
+		
+		/** Specifies that leading basis is IDEOGRAPHIC_CENTER and leading direction is UP. 
+		 * In other words, <code>lineHeight</code> refers to the distance of a line's ideographic center 
+		 * baseline from the previous line's ideographic center baseline.
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const IDEOGRAPHIC_CENTER_UP:String = "ideographicCenterUp";
+		
+		/** Specifies that leading basis is IDEOGRAPHIC_TOP and leading direction is DOWN.
+		 * In other words, <code>lineHeight</code> refers to the distance of a line's ideographic top baseline 
+		 * from the next line's ideographic top baseline.
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+	 	 */
+	 	 
+		public static const IDEOGRAPHIC_TOP_DOWN:String = "ideographicTopDown";
+		
+		/** Specifies that leading basis is IDEOGRAPHIC_CENTER and leading direction is down.
+		 *  In other words, <code>lineHeight</code> refers to the distance of a line's ideographic center 
+		 *  baseline from the next line's ideographic center baseline.
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+	 	 */
+	 	 
+		public static const IDEOGRAPHIC_CENTER_DOWN:String = "ideographicCenterDown";
+		
+		/** Specifies that leading basis is ASCENT/DESCENT and leading direction is UP. 
+		 *  In other words, <code>lineHeight</code> refers to the distance of a line's ascent baseline from the 
+		 *  previous line's descent baseline.
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	  	 * @langversion 3.0 
+	 	 */
+	 	 
+		public static const ASCENT_DESCENT_UP:String = "ascentDescentUp";
+		
+		/** Specifies that leading model is chosen automatically based on the paragraph's <code>locale</code> property.  
+		 * For Japanese and Chinese, it is IDEOGRAPHIC_TOP_DOWN and for all others it is ROMAN_UP.
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+	 	 * 
+	 	 * #IDEOGRAPHIC_TOP_DOWN
+	 	 * #ROMAN_UP
+	 	 */
+	 	 
+		public static const AUTO:String = "auto";
+		
+		/** Specifies a leading model that approximates the line spacing behavior of <code>TextField</code>.
+		 * It is similar to <code>ASCENT_DESCENT_UP</code> in that <code>lineHeight</code> refers to the 
+		 * distance of a line's ascent baseline from the previous line's descent baseline. However, baseline 
+		 * positions approximate those determined by <code>TextField</code>, rather than using metrics 
+		 * offered by <code>TextLine</code>.  
+		 *
+		 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public static const APPROXIMATE_TEXT_FIELD:String = "approximateTextField";
+		
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/formats/LineBreak.as b/textLayout_core/src/flashx/textLayout/formats/LineBreak.as
new file mode 100755
index 0000000..9708916
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/LineBreak.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 flashx.textLayout.formats
+{
+	/** Defines values for setting the <code>lineBreak</code> property of <code>TextLayoutFormat</code> to
+	 *  specify how lines are broken within wrapping text.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 * @see TextLayoutFormat#linebreak
+	 */
+	public final class LineBreak
+	{
+		/** Specifies that lines wrap to fit the container width. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	  	 * @langversion 3.0 
+		 */
+		 
+		public static const TO_FIT:String = "toFit";
+		
+		/** Specifies that lines break only at explicit return or line feed characters. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const EXPLICIT:String = "explicit";
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/formats/TLFTypographicCase.as b/textLayout_core/src/flashx/textLayout/formats/TLFTypographicCase.as
new file mode 100755
index 0000000..3adbdc6
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/TLFTypographicCase.as
@@ -0,0 +1,79 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	/**
+	 *  Defines values for the <code>typographicCase</code> property of the TextLayoutFormat
+	 *  class. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 * 
+	 * @see TextLayoutFormat#typographicCase
+	 */
+	public final class TLFTypographicCase
+	{
+		/** Specifies default typographic case -- no special features applied. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+ 		public static const DEFAULT:String = "default";
+ 		
+		/** Converts all lowercase characters to uppercase, then applies small caps to only the 
+		 * characters that the conversion changed. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+  	 	public static const LOWERCASE_TO_SMALL_CAPS:String = "lowercaseToSmallCaps";
+  	 	
+  	 	/** Specifies that all characters use lowercase glyphs on output. 
+  	 	 *
+  	 	 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+ 	 	public static const LOWERCASE:String = "lowercase";
+
+		/** Specifies that uppercase characters use small-caps glyphs on output. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+ 	 	public static const CAPS_TO_SMALL_CAPS:String = "capsToSmallCaps";
+
+		/** Specifies that all characters use uppercase glyphs on output.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+ 	 	public static const UPPERCASE:String = "uppercase";
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/formats/TabStopFormat.as b/textLayout_core/src/flashx/textLayout/formats/TabStopFormat.as
new file mode 100755
index 0000000..2cc59aa
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/TabStopFormat.as
@@ -0,0 +1,374 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	import flashx.textLayout.debug.Debugging
+	import flashx.textLayout.debug.assert
+	import flashx.textLayout.property.*
+	import flashx.textLayout.tlf_internal
+	use namespace tlf_internal
+	import flash.text.engine.TabAlignment
+	/**
+	 * The TabStopFormat class represents the properties of a tab stop in a paragraph. You can set the <code>TextLayoutFormat.tabstops</code> property to an array of TabStopFormat objects.
+	 * @includeExample examples\TabStopFormat_example.as -noswf
+	 * @see flashx.textLayout.elements.TabElement 
+	 * @see flashx.textLayout.formats.TextLayoutFormat#tabStops
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public class TabStopFormat implements ITabStopFormat
+	{
+		/** @private */
+		static private var _positionProperty:NumberProperty = new NumberProperty("position",0,false,Category.TABSTOP,0,10000); 		/** @private */
+		static private var _alignmentProperty:EnumStringProperty = new EnumStringProperty(
+			"alignment",flash.text.engine.TabAlignment.START,false,Category.TABSTOP
+			,flash.text.engine.TabAlignment.START
+			,flash.text.engine.TabAlignment.CENTER
+			,flash.text.engine.TabAlignment.END
+			,flash.text.engine.TabAlignment.DECIMAL
+		);
+		/** @private */
+		static private var _decimalAlignmentTokenProperty:StringProperty = new StringProperty("decimalAlignmentToken",null,false,Category.TABSTOP);
+
+		/** @private */
+		static tlf_internal function get positionProperty():NumberProperty
+		{ return _positionProperty; }
+		/** @private */
+		static tlf_internal function get alignmentProperty():EnumStringProperty
+		{ return _alignmentProperty; }
+		/** @private */
+		static tlf_internal function get decimalAlignmentTokenProperty():StringProperty
+		{ return _decimalAlignmentTokenProperty; }
+
+		static private var _description:Object = {
+			  position:_positionProperty
+			, alignment:_alignmentProperty
+			, decimalAlignmentToken:_decimalAlignmentTokenProperty
+		}
+
+		/** Property descriptions accessible by name. @private */
+		static tlf_internal function get description():Object
+		{ return _description; }
+
+		/** @private */
+		static private var _emptyTabStopFormat:ITabStopFormat;
+		/**
+		 * Returns an ITabStopFormat instance with all properties set to <code>undefined</code>.
+		 * @private
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		static tlf_internal function get emptyTabStopFormat():ITabStopFormat
+		{
+			if (_emptyTabStopFormat == null)
+				_emptyTabStopFormat = new TabStopFormat();
+			return _emptyTabStopFormat;
+		}
+
+
+		private var _position:*;
+		private var _alignment:*;
+		private var _decimalAlignmentToken:*;
+
+		/**
+		 * The position of the tab stop, in pixels, relative to the start of the line.
+		 * <p>Legal values are numbers from 0 to 10000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 0.</p>
+		 * @see FormatValue#INHERIT
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get position():*
+		{ return _position; }
+		public function set position(newValue:*):void
+		{ _position = _positionProperty.setHelper(_position,newValue); }
+
+		/**
+		 * The tab alignment for this tab stop. 
+		 * <p>Legal values are flash.text.engine.TabAlignment.START, flash.text.engine.TabAlignment.CENTER, flash.text.engine.TabAlignment.END, flash.text.engine.TabAlignment.DECIMAL, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of START.</p>
+		 * @see FormatValue#INHERIT
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.TabAlignment
+		 */
+		public function get alignment():*
+		{ return _alignment; }
+		public function set alignment(newValue:*):void
+		{ _alignment = _alignmentProperty.setHelper(_alignment,newValue); }
+
+		/**
+		 * The alignment token to be used if the alignment is DECIMAL.
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of null.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get decimalAlignmentToken():*
+		{ return _decimalAlignmentToken; }
+		public function set decimalAlignmentToken(newValue:*):void
+		{ _decimalAlignmentToken = _decimalAlignmentTokenProperty.setHelper(_decimalAlignmentToken,newValue); }
+
+		/**
+		 * Creates a new TabStopFormat object. All settings are empty or, optionally, are initialized from the
+		 * supplied <code>initialValues</code> object.
+		 * 
+		 * @param initialValues optional instance from which to copy initial values.
+		 * 
+		 * @see #defaultFormat
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function TabStopFormat(initialValues:ITabStopFormat = null)
+		{
+			if (initialValues)
+				apply(initialValues)
+		}
+
+		/**
+		 * Copies TabStopFormat settings from the <code>values</code> ITabStopFormat instance into this TabStopFormat object.
+		 * If <code>values</code> is <code>null</code>, this TabStopFormat object is initialized with undefined values for all properties.
+		 * @param values optional instance from which to copy values.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function copy(values:ITabStopFormat):void
+		{
+			 if (values == null)
+				values = emptyTabStopFormat;
+			this.position = values.position;
+			this.alignment = values.alignment;
+			this.decimalAlignmentToken = values.decimalAlignmentToken;
+		}
+
+		/**
+		 * Concatenates the values of properties in the <code>incoming</code> ITabStopFormat instance
+		 * with the values of this TabStopFormat object. In this (the receiving) TabStopFormat object, properties whose values are <code>FormatValue.INHERIT</code>,
+		 * and inheriting properties whose values are <code>undefined</code> will get new values from the <code>incoming</code> object.
+		 * Non-inheriting properties whose values are <code>undefined</code> will get their default values.
+		 * All other property values will remain unmodified.
+		 * 
+		 * @param incoming instance from which values are concatenated.
+		 * @see flashx.textLayout.formats.FormatValue#INHERIT
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function concat(incoming:ITabStopFormat):void
+		{
+			this.position = _positionProperty.concatHelper(this.position, incoming.position);
+			this.alignment = _alignmentProperty.concatHelper(this.alignment, incoming.alignment);
+			this.decimalAlignmentToken = _decimalAlignmentTokenProperty.concatHelper(this.decimalAlignmentToken, incoming.decimalAlignmentToken);
+		}
+
+		/**
+		 * Concatenates the values of properties in the <code>incoming</code> ITabStopFormat instance
+		 * with the values of this TabStopFormat object. In this (the receiving) TabStopFormat object, properties whose values are <code>FormatValue.INHERIT</code>,
+		 * and inheriting properties whose values are <code>undefined</code> will get new values from the <code>incoming</code> object.
+		 * All other property values will remain unmodified.
+		 * 
+		 * @param incoming instance from which values are concatenated.
+		 * @see flashx.textLayout.formats.FormatValue#INHERIT
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function concatInheritOnly(incoming:ITabStopFormat):void
+		{
+			this.position = _positionProperty.concatInheritOnlyHelper(this.position, incoming.position);
+			this.alignment = _alignmentProperty.concatInheritOnlyHelper(this.alignment, incoming.alignment);
+			this.decimalAlignmentToken = _decimalAlignmentTokenProperty.concatInheritOnlyHelper(this.decimalAlignmentToken, incoming.decimalAlignmentToken);
+		}
+
+		/**
+		 * Replaces property values in this TabStopFormat object with the values of properties that are set in
+		 * the <code>incoming</code> ITabStopFormat instance. Properties that are <code>undefined</code> in the <code>incoming</code>
+		 * ITabStopFormat instance are not changed in this object.
+		 * 
+		 * @param incoming instance whose property values are applied to this TabStopFormat object.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function apply(incoming:ITabStopFormat):void
+		{
+			var val:*;
+
+			if ((val = incoming.position) !== undefined)
+				this.position = val;
+			if ((val = incoming.alignment) !== undefined)
+				this.alignment = val;
+			if ((val = incoming.decimalAlignmentToken) !== undefined)
+				this.decimalAlignmentToken = val;
+		}
+
+		/**
+		 * Compares properties in ITabStopFormat instance <code>p1</code> with properties in ITabStopFormat instance <code>p2</code>
+		 * and returns <code>true</code> if all properties match.
+		 * 
+		 * @param p1 instance to compare to <code>p2</code>.
+		 * @param p2 instance to compare to <code>p1</code>.
+		 * 
+		 * @return true if all properties match, false otherwise.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		static public function isEqual(p1:ITabStopFormat,p2:ITabStopFormat):Boolean
+		{
+			if (p1 == null)
+				p1 = emptyTabStopFormat;
+			if (p2 == null)
+				p2 = emptyTabStopFormat;
+			if (p1 == p2)
+				return true;
+
+			if (!_positionProperty.equalHelper(p1.position, p2.position))
+				return false;
+			if (!_alignmentProperty.equalHelper(p1.alignment, p2.alignment))
+				return false;
+			if (!_decimalAlignmentTokenProperty.equalHelper(p1.decimalAlignmentToken, p2.decimalAlignmentToken))
+				return false;
+
+			return true;
+		}
+
+		/**
+		 * Sets properties in this TabStopFormat object to <code>undefined</code> if they match those in the <code>incoming</code>
+		 * ITabStopFormat instance.
+		 * 
+		 * @param incoming instance against which to compare this TabStopFormat object's property values.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function removeMatching(incoming:ITabStopFormat):void
+		{
+			if (incoming == null)
+				return;
+
+			if (_positionProperty.equalHelper(this.position, incoming.position))
+				this.position = undefined;
+			if (_alignmentProperty.equalHelper(this.alignment, incoming.alignment))
+				this.alignment = undefined;
+			if (_decimalAlignmentTokenProperty.equalHelper(this.decimalAlignmentToken, incoming.decimalAlignmentToken))
+				this.decimalAlignmentToken = undefined;
+		}
+
+		/**
+		 * Sets properties in this TabStopFormat object to <code>undefined</code> if they do not match those in the
+		 * <code>incoming</code> ITabStopFormat instance.
+		 * 
+		 * @param incoming instance against which to compare this TabStopFormat object's property values.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function removeClashing(incoming:ITabStopFormat):void
+		{
+			if (incoming == null)
+				return;
+
+			if (!_positionProperty.equalHelper(this.position, incoming.position))
+				this.position = undefined;
+			if (!_alignmentProperty.equalHelper(this.alignment, incoming.alignment))
+				this.alignment = undefined;
+			if (!_decimalAlignmentTokenProperty.equalHelper(this.decimalAlignmentToken, incoming.decimalAlignmentToken))
+				this.decimalAlignmentToken = undefined;
+		}
+
+		/**
+		 * Gets the TabStopFormat hash
+		 * @param seed seed value for the hash algorithm
+		 * @return the TabStopFormat hash
+		 * @private
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		tlf_internal function hash(seed:uint):uint
+		{
+			var hash:uint = seed;
+
+			if (_position)
+				hash = _positionProperty.hash(_position, hash);
+			if (_alignment)
+				hash = _alignmentProperty.hash(_alignment, hash);
+			if (_decimalAlignmentToken)
+				hash = _decimalAlignmentTokenProperty.hash(_decimalAlignmentToken, hash);
+
+			return hash;
+		}
+
+		static private var _defaults:TabStopFormat;
+		/**
+		 * Returns a TabStopFormat object with default settings.
+		 * This function always returns the same object.
+		 * 
+		 * @return a singleton instance of ITabStopFormat that is populated with default values.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		static public function get defaultFormat():ITabStopFormat
+		{
+			if (_defaults == null)
+			{
+				_defaults = new TabStopFormat();
+				Property.defaultsAllHelper(_description,_defaults);
+				_defaultFormatHash = _defaults.hash(0);
+			}
+			return _defaults;
+		}
+		static private var _defaultFormatHash:uint;
+		/** @private */
+		static tlf_internal function getDefaultFormatHash():uint
+		{
+			defaultFormat;
+			return _defaultFormatHash;
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/formats/TabStopFormatInc.as b/textLayout_core/src/flashx/textLayout/formats/TabStopFormatInc.as
new file mode 100755
index 0000000..4a19f2f
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/TabStopFormatInc.as
@@ -0,0 +1,74 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+		public function get position():*
+		{
+			return _tabStopFormatValueHolder ? _tabStopFormatValueHolder.position : undefined;
+		}
+		public function set position(positionValue:*):void
+		{
+			writableTabStopFormatValueHolder().position = positionValue;
+			tabStopFormatChanged();
+		}
+
+		/**
+		 * TabStopFormat:
+		 * The tab alignment for this tab stop. 
+		 * <p>Legal values are flash.text.engine.TabAlignment.START, flash.text.engine.TabAlignment.CENTER, flash.text.engine.TabAlignment.END, flash.text.engine.TabAlignment.DECIMAL, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of START.</p>
+		 * @see FormatValue#INHERIT
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.TabAlignment
+		 */
+		public function get alignment():*
+		{
+			return _tabStopFormatValueHolder ? _tabStopFormatValueHolder.alignment : undefined;
+		}
+		public function set alignment(alignmentValue:*):void
+		{
+			writableTabStopFormatValueHolder().alignment = alignmentValue;
+			tabStopFormatChanged();
+		}
+
+		/**
+		 * TabStopFormat:
+		 * The alignment token to be used if the alignment is DECIMAL.
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of null.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get decimalAlignmentToken():*
+		{
+			return _tabStopFormatValueHolder ? _tabStopFormatValueHolder.decimalAlignmentToken : undefined;
+		}
+		public function set decimalAlignmentToken(decimalAlignmentTokenValue:*):void
+		{
+			writableTabStopFormatValueHolder().decimalAlignmentToken = decimalAlignmentTokenValue;
+			tabStopFormatChanged();
+		}
diff --git a/textLayout_core/src/flashx/textLayout/formats/TextAlign.as b/textLayout_core/src/flashx/textLayout/formats/TextAlign.as
new file mode 100755
index 0000000..b53a0dc
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/TextAlign.as
@@ -0,0 +1,93 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	/**
+	 *  Defines values for setting the <code>textAlign</code> and <code>textAlignLast</code> properties
+	 *  of the TextLayoutFormat class. The values describe the alignment of lines in the paragraph relative to the 
+	 *  container.
+	 *
+	 * @includeExample examples\TextAlignExample.as -noswf
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 * @see TextLayoutFormat#textAlign 
+	 * @see TextLayoutFormat#textAlignLast 
+	 */
+	public final class TextAlign
+	{
+		/** Specifies start edge alignment - text is aligned to match the writing order. Equivalent to setting 
+		 * left in left-to-right text, or right in right-to-left text.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const START:String = "start";
+		
+		/** Specifies end edge alignment - text is aligned opposite from the writing order. Equivalent to 
+		 *  specifying right in left-to-right text, or left in right-to-left text. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const END:String = "end";
+		
+		/** Specifies left edge alignment. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const LEFT:String = "left";
+		
+		/** Specifies right edge alignment. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const RIGHT:String = "right";
+		
+		/** Specifies center alignment within the container.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const CENTER:String = "center";
+		
+		/** Specifies that text is justified within the lines so they fill the container space.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const JUSTIFY:String = "justify";
+		
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/formats/TextDecoration.as b/textLayout_core/src/flashx/textLayout/formats/TextDecoration.as
new file mode 100755
index 0000000..260b0c8
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/TextDecoration.as
@@ -0,0 +1,53 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	/**
+	 *  Defines values for the <code>textDecoration</code> property
+	 *  of the TextLayoutFormat class. The values specify either normal text, with no decoration,
+	 *  or underline.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 *  
+	 * @see TextLayoutFormat#textDecoration
+	 */
+	 
+	public final class TextDecoration
+	{
+		/** Specifies normal text - no decoration applied 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const NONE:String = "none";
+		
+		/** Specifies that text is underlined. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const UNDERLINE:String = "underline";
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/formats/TextJustify.as b/textLayout_core/src/flashx/textLayout/formats/TextJustify.as
new file mode 100755
index 0000000..6e58e31
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/TextJustify.as
@@ -0,0 +1,55 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	/**
+	 *  Defines values for setting the <code>textJustify</code> property of the TextLayoutFormat class. 
+	 *  Default value is INTER_WORD, meaning that extra space in justification is added to the space characters.
+	 *  DISTRIBUTE specifies that extra space is added both to space characters and between individual
+	 *  letters. Use these values only when setting <code>justificationRule</code> to SPACE.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 *
+	 * @see TextLayoutFormat#textJustify
+	 * @see TextLayoutFormat#justificationRule
+	 */
+	public final class TextJustify
+	{
+		/** Specifies that justification is to add space both to space characters and 
+		 * between individual letters.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const DISTRIBUTE:String = "distribute";
+		
+		/** Specifies that justification is to add space to space characters. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const INTER_WORD:String = "interWord";
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/formats/TextLayoutFormat.as b/textLayout_core/src/flashx/textLayout/formats/TextLayoutFormat.as
new file mode 100755
index 0000000..f5499a3
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/TextLayoutFormat.as
@@ -0,0 +1,2482 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	import flashx.textLayout.debug.Debugging
+	import flashx.textLayout.debug.assert
+	import flashx.textLayout.property.*
+	import flashx.textLayout.tlf_internal
+	use namespace tlf_internal
+	import flashx.textLayout.formats.BackgroundColor
+	import flash.text.engine.BreakOpportunity
+	import flash.text.engine.DigitCase
+	import flash.text.engine.DigitWidth
+	import flash.text.engine.TextBaseline
+	import flash.text.engine.Kerning
+	import flash.text.engine.LigatureLevel
+	import flash.text.engine.TextBaseline
+	import flashx.textLayout.formats.TLFTypographicCase
+	import flashx.textLayout.formats.TextDecoration
+	import flash.text.engine.FontWeight
+	import flash.text.engine.FontPosture
+	import flashx.textLayout.formats.WhiteSpaceCollapse
+	import flash.text.engine.RenderingMode
+	import flash.text.engine.CFFHinting
+	import flash.text.engine.FontLookup
+	import flash.text.engine.TextRotation
+	import flashx.textLayout.formats.TextAlign
+	import flashx.textLayout.formats.TextAlign
+	import flashx.textLayout.formats.TextJustify
+	import flashx.textLayout.formats.JustificationRule
+	import flash.text.engine.JustificationStyle
+	import flashx.textLayout.formats.Direction
+	import flashx.textLayout.formats.LeadingModel
+	import flashx.textLayout.formats.FormatValue
+	import flashx.textLayout.formats.FormatValue
+	import flashx.textLayout.formats.BaselineOffset
+	import flashx.textLayout.formats.VerticalAlign
+	import flashx.textLayout.formats.BlockProgression
+	import flashx.textLayout.formats.LineBreak
+	/**
+	 * The TextLayoutFormat class holds all of the text layout properties. These properties affect the format and style of a text flow at the container level, paragraph level, and text level.  Both the ContainerController class and the FlowElement base class have <code>format</code> properties that enable you to assign a TextLayoutFormat instance to them. Assign a TextLayoutFormat object to a container to affect the format of all of the container's content. Assign a TextLayoutFormat object to a FlowElement descendant to specify formatting for that particular element: TextFlow, ParagraphElement, DivElement, SpanElement, InlineGraphicElement, LinkElement, and TCYElement.
+	 * In addition to the <code>format</code> property, these classes also define each of the individual TextLayoutFormat properties so that you can override the setting of a particular style property for that element, if you wish. <p>Because you can set a given style at multiple levels, it is possible to have conflicts. For example, the color of the text at the TextFlow level could be set to black while a SpanElement object sets it to blue. The general rule is that the setting at the lowest level on the text flow tree takes precedence. So if the ligature level is set for a TextFlow instance and also set for a DivElement, the DivElement setting takes precedence. </p><p>Cascading styles refers to the process of adopting styles from a higher level in the text flow if a style value is undefined at a lower level. When a style is undefined on an element at the point it is about to be rendered, it either takes its default value or the value cascades or descends from the value on a parent element. For example, if the transparency (<code>textAlpha</code> property) of the text is undefined on a SpanElement object, but is set on the TextFlow, the value of the <code>TextFlow.textAlpha</code> property cascades to the SpanElement object and is applied to the text for that span. The result of the cascade, or the sum of the styles that is applied to the element, is stored in the element's <code>computedFormat</code> property.</p><p>In the same way, you can apply user styles using the <code>userStyles</code> property of the ContainerController and FlowElement classes. This  property allows you to read or write a dictionary of user styles and apply its settings to a container or a text flow element. The user styles dictionary is an object that consists of <em>stylename-value</em> pairs. Styles specified by the <code>userStyles</code> property take precedence over all others.</p><p>Most styles that are undefined inherit the value of their immediate parent during a cascade. A small number of styles, however, do not inherit their parent's value and take on their default values instead.</p><p><strong>Style properties that adopt their default values, if undefined, include:</strong> <code>backgroundAlpha</code>, <code>backgroundColor</code>, <code>columnCount</code>, <code>columnGap</code>, <code>columnWidth</code>, <code>lineBreak</code>, <code>paddingBottom</code>, <code>paddingLeft</code>, <code>paddingRight</code>, <code>paddingTop</code>, <code>verticalAlign</code>.</p>
+	 * @includeExample examples\TextLayoutFormatExample.as -noswf
+	 * @includeExample examples\TextLayoutFormatExample2.as -noswf
+	 * @see flashx.textLayout.elements.FlowElement#format
+	 * @see flashx.textLayout.factory.TextFlowTextLineFactory
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5 
+	 * @langversion 3.0 
+	 */
+	public class TextLayoutFormat implements ITextLayoutFormat
+	{
+		/** @private */
+		static private var _colorProperty:UintProperty = new UintProperty("color",0,true,Category.CHARACTER);
+		/** @private */
+		static private var _backgroundColorProperty:UintWithEnumProperty = new UintWithEnumProperty(
+			"backgroundColor",flashx.textLayout.formats.BackgroundColor.TRANSPARENT,false,Category.CHARACTER
+			,flashx.textLayout.formats.BackgroundColor.TRANSPARENT
+		);
+		/** @private */
+		static private var _lineThroughProperty:BooleanProperty = new BooleanProperty("lineThrough",false,true,Category.CHARACTER);
+		/** @private */
+		static private var _textAlphaProperty:NumberProperty = new NumberProperty("textAlpha",1,true,Category.CHARACTER,0,1); 		/** @private */
+		static private var _backgroundAlphaProperty:NumberProperty = new NumberProperty("backgroundAlpha",1,false,Category.CHARACTER,0,1); 		/** @private */
+		static private var _fontSizeProperty:NumberProperty = new NumberProperty("fontSize",12,true,Category.CHARACTER,1,720); 		/** @private */
+		static private var _baselineShiftProperty:NumberOrPercentOrEnumProperty = new NumberOrPercentOrEnumProperty("baselineShift",0.0,true,Category.CHARACTER,-1000,1000,"-1000%","1000%"
+			,flashx.textLayout.formats.BaselineShift.SUPERSCRIPT
+			,flashx.textLayout.formats.BaselineShift.SUBSCRIPT
+		);
+		/** @private */
+		static private var _trackingLeftProperty:NumberOrPercentProperty = new NumberOrPercentProperty("trackingLeft",0,true,Category.CHARACTER,-1000,1000,"-1000%","1000%")
+		/** @private */
+		static private var _trackingRightProperty:NumberOrPercentProperty = new NumberOrPercentProperty("trackingRight",0,true,Category.CHARACTER,-1000,1000,"-1000%","1000%")
+		/** @private */
+		static private var _lineHeightProperty:NumberOrPercentProperty = new NumberOrPercentProperty("lineHeight","120%",true,Category.CHARACTER,-720,720,"-1000%","1000%")
+		/** @private */
+		static private var _breakOpportunityProperty:EnumStringProperty = new EnumStringProperty(
+			"breakOpportunity",flash.text.engine.BreakOpportunity.AUTO,true,Category.CHARACTER
+			,flash.text.engine.BreakOpportunity.ALL
+			,flash.text.engine.BreakOpportunity.ANY
+			,flash.text.engine.BreakOpportunity.AUTO
+			,flash.text.engine.BreakOpportunity.NONE
+		);
+		/** @private */
+		static private var _digitCaseProperty:EnumStringProperty = new EnumStringProperty(
+			"digitCase",flash.text.engine.DigitCase.DEFAULT,true,Category.CHARACTER
+			,flash.text.engine.DigitCase.DEFAULT
+			,flash.text.engine.DigitCase.LINING
+			,flash.text.engine.DigitCase.OLD_STYLE
+		);
+		/** @private */
+		static private var _digitWidthProperty:EnumStringProperty = new EnumStringProperty(
+			"digitWidth",flash.text.engine.DigitWidth.DEFAULT,true,Category.CHARACTER
+			,flash.text.engine.DigitWidth.DEFAULT
+			,flash.text.engine.DigitWidth.PROPORTIONAL
+			,flash.text.engine.DigitWidth.TABULAR
+		);
+		/** @private */
+		static private var _dominantBaselineProperty:EnumStringProperty = new EnumStringProperty(
+			"dominantBaseline",flashx.textLayout.formats.FormatValue.AUTO,true,Category.CHARACTER
+			,flashx.textLayout.formats.FormatValue.AUTO
+			,flash.text.engine.TextBaseline.ROMAN
+			,flash.text.engine.TextBaseline.ASCENT
+			,flash.text.engine.TextBaseline.DESCENT
+			,flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP
+			,flash.text.engine.TextBaseline.IDEOGRAPHIC_CENTER
+			,flash.text.engine.TextBaseline.IDEOGRAPHIC_BOTTOM
+		);
+		/** @private */
+		static private var _kerningProperty:EnumStringProperty = new EnumStringProperty(
+			"kerning",flash.text.engine.Kerning.AUTO,true,Category.CHARACTER
+			,flash.text.engine.Kerning.ON
+			,flash.text.engine.Kerning.OFF
+			,flash.text.engine.Kerning.AUTO
+		);
+		/** @private */
+		static private var _ligatureLevelProperty:EnumStringProperty = new EnumStringProperty(
+			"ligatureLevel",flash.text.engine.LigatureLevel.COMMON,true,Category.CHARACTER
+			,flash.text.engine.LigatureLevel.MINIMUM
+			,flash.text.engine.LigatureLevel.COMMON
+			,flash.text.engine.LigatureLevel.UNCOMMON
+			,flash.text.engine.LigatureLevel.EXOTIC
+		);
+		/** @private */
+		static private var _alignmentBaselineProperty:EnumStringProperty = new EnumStringProperty(
+			"alignmentBaseline",flash.text.engine.TextBaseline.USE_DOMINANT_BASELINE,true,Category.CHARACTER
+			,flash.text.engine.TextBaseline.ROMAN
+			,flash.text.engine.TextBaseline.ASCENT
+			,flash.text.engine.TextBaseline.DESCENT
+			,flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP
+			,flash.text.engine.TextBaseline.IDEOGRAPHIC_CENTER
+			,flash.text.engine.TextBaseline.IDEOGRAPHIC_BOTTOM
+			,flash.text.engine.TextBaseline.USE_DOMINANT_BASELINE
+		);
+		/** @private */
+		static private var _localeProperty:StringProperty = new StringProperty("locale","en",true,Category.CHARACTER);
+		/** @private */
+		static private var _typographicCaseProperty:EnumStringProperty = new EnumStringProperty(
+			"typographicCase",flashx.textLayout.formats.TLFTypographicCase.DEFAULT,true,Category.CHARACTER
+			,flashx.textLayout.formats.TLFTypographicCase.DEFAULT
+			,flashx.textLayout.formats.TLFTypographicCase.CAPS_TO_SMALL_CAPS
+			,flashx.textLayout.formats.TLFTypographicCase.UPPERCASE
+			,flashx.textLayout.formats.TLFTypographicCase.LOWERCASE
+			,flashx.textLayout.formats.TLFTypographicCase.LOWERCASE_TO_SMALL_CAPS
+		);
+		/** @private */
+		static private var _fontFamilyProperty:StringProperty = new StringProperty("fontFamily","Arial",true,Category.CHARACTER);
+		/** @private */
+		static private var _textDecorationProperty:EnumStringProperty = new EnumStringProperty(
+			"textDecoration",flashx.textLayout.formats.TextDecoration.NONE,true,Category.CHARACTER
+			,flashx.textLayout.formats.TextDecoration.NONE
+			,flashx.textLayout.formats.TextDecoration.UNDERLINE
+		);
+		/** @private */
+		static private var _fontWeightProperty:EnumStringProperty = new EnumStringProperty(
+			"fontWeight",flash.text.engine.FontWeight.NORMAL,true,Category.CHARACTER
+			,flash.text.engine.FontWeight.NORMAL
+			,flash.text.engine.FontWeight.BOLD
+		);
+		/** @private */
+		static private var _fontStyleProperty:EnumStringProperty = new EnumStringProperty(
+			"fontStyle",flash.text.engine.FontPosture.NORMAL,true,Category.CHARACTER
+			,flash.text.engine.FontPosture.NORMAL
+			,flash.text.engine.FontPosture.ITALIC
+		);
+		/** @private */
+		static private var _whiteSpaceCollapseProperty:EnumStringProperty = new EnumStringProperty(
+			"whiteSpaceCollapse",flashx.textLayout.formats.WhiteSpaceCollapse.COLLAPSE,true,Category.CHARACTER
+			,flashx.textLayout.formats.WhiteSpaceCollapse.PRESERVE
+			,flashx.textLayout.formats.WhiteSpaceCollapse.COLLAPSE
+		);
+		/** @private */
+		static private var _renderingModeProperty:EnumStringProperty = new EnumStringProperty(
+			"renderingMode",flash.text.engine.RenderingMode.CFF,true,Category.CHARACTER
+			,flash.text.engine.RenderingMode.NORMAL
+			,flash.text.engine.RenderingMode.CFF
+		);
+		/** @private */
+		static private var _cffHintingProperty:EnumStringProperty = new EnumStringProperty(
+			"cffHinting",flash.text.engine.CFFHinting.HORIZONTAL_STEM,true,Category.CHARACTER
+			,flash.text.engine.CFFHinting.NONE
+			,flash.text.engine.CFFHinting.HORIZONTAL_STEM
+		);
+		/** @private */
+		static private var _fontLookupProperty:EnumStringProperty = new EnumStringProperty(
+			"fontLookup",flash.text.engine.FontLookup.DEVICE,true,Category.CHARACTER
+			,flash.text.engine.FontLookup.DEVICE
+			,flash.text.engine.FontLookup.EMBEDDED_CFF
+		);
+		/** @private */
+		static private var _textRotationProperty:EnumStringProperty = new EnumStringProperty(
+			"textRotation",flash.text.engine.TextRotation.AUTO,true,Category.CHARACTER
+			,flash.text.engine.TextRotation.ROTATE_0
+			,flash.text.engine.TextRotation.ROTATE_180
+			,flash.text.engine.TextRotation.ROTATE_270
+			,flash.text.engine.TextRotation.ROTATE_90
+			,flash.text.engine.TextRotation.AUTO
+		);
+		/** @private */
+		static private var _textIndentProperty:NumberProperty = new NumberProperty("textIndent",0,true,Category.PARAGRAPH,-1000,1000); 		/** @private */
+		static private var _paragraphStartIndentProperty:NumberProperty = new NumberProperty("paragraphStartIndent",0,true,Category.PARAGRAPH,0,1000); 		/** @private */
+		static private var _paragraphEndIndentProperty:NumberProperty = new NumberProperty("paragraphEndIndent",0,true,Category.PARAGRAPH,0,1000); 		/** @private */
+		static private var _paragraphSpaceBeforeProperty:NumberProperty = new NumberProperty("paragraphSpaceBefore",0,true,Category.PARAGRAPH,0,1000); 		/** @private */
+		static private var _paragraphSpaceAfterProperty:NumberProperty = new NumberProperty("paragraphSpaceAfter",0,true,Category.PARAGRAPH,0,1000); 		/** @private */
+		static private var _textAlignProperty:EnumStringProperty = new EnumStringProperty(
+			"textAlign",flashx.textLayout.formats.TextAlign.START,true,Category.PARAGRAPH
+			,flashx.textLayout.formats.TextAlign.LEFT
+			,flashx.textLayout.formats.TextAlign.RIGHT
+			,flashx.textLayout.formats.TextAlign.CENTER
+			,flashx.textLayout.formats.TextAlign.JUSTIFY
+			,flashx.textLayout.formats.TextAlign.START
+			,flashx.textLayout.formats.TextAlign.END
+		);
+		/** @private */
+		static private var _textAlignLastProperty:EnumStringProperty = new EnumStringProperty(
+			"textAlignLast",flashx.textLayout.formats.TextAlign.START,true,Category.PARAGRAPH
+			,flashx.textLayout.formats.TextAlign.LEFT
+			,flashx.textLayout.formats.TextAlign.RIGHT
+			,flashx.textLayout.formats.TextAlign.CENTER
+			,flashx.textLayout.formats.TextAlign.JUSTIFY
+			,flashx.textLayout.formats.TextAlign.START
+			,flashx.textLayout.formats.TextAlign.END
+		);
+		/** @private */
+		static private var _textJustifyProperty:EnumStringProperty = new EnumStringProperty(
+			"textJustify",flashx.textLayout.formats.TextJustify.INTER_WORD,true,Category.PARAGRAPH
+			,flashx.textLayout.formats.TextJustify.INTER_WORD
+			,flashx.textLayout.formats.TextJustify.DISTRIBUTE
+		);
+		/** @private */
+		static private var _justificationRuleProperty:EnumStringProperty = new EnumStringProperty(
+			"justificationRule",flashx.textLayout.formats.FormatValue.AUTO,true,Category.PARAGRAPH
+			,flashx.textLayout.formats.JustificationRule.EAST_ASIAN
+			,flashx.textLayout.formats.JustificationRule.SPACE
+			,flashx.textLayout.formats.FormatValue.AUTO
+		);
+		/** @private */
+		static private var _justificationStyleProperty:EnumStringProperty = new EnumStringProperty(
+			"justificationStyle",flashx.textLayout.formats.FormatValue.AUTO,true,Category.PARAGRAPH
+			,flash.text.engine.JustificationStyle.PRIORITIZE_LEAST_ADJUSTMENT
+			,flash.text.engine.JustificationStyle.PUSH_IN_KINSOKU
+			,flash.text.engine.JustificationStyle.PUSH_OUT_ONLY
+			,flashx.textLayout.formats.FormatValue.AUTO
+		);
+		/** @private */
+		static private var _directionProperty:EnumStringProperty = new EnumStringProperty(
+			"direction",flashx.textLayout.formats.Direction.LTR,true,Category.PARAGRAPH
+			,flashx.textLayout.formats.Direction.LTR
+			,flashx.textLayout.formats.Direction.RTL
+		);
+		/** @private */
+		static private var _tabStopsProperty:TabStopsProperty = new TabStopsProperty("tabStops",null,true,Category.PARAGRAPH);
+		/** @private */
+		static private var _leadingModelProperty:EnumStringProperty = new EnumStringProperty(
+			"leadingModel",flashx.textLayout.formats.LeadingModel.AUTO,true,Category.PARAGRAPH
+			,flashx.textLayout.formats.LeadingModel.ROMAN_UP
+			,flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_TOP_UP
+			,flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_CENTER_UP
+			,flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_TOP_DOWN
+			,flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_CENTER_DOWN
+			,flashx.textLayout.formats.LeadingModel.APPROXIMATE_TEXT_FIELD
+			,flashx.textLayout.formats.LeadingModel.ASCENT_DESCENT_UP
+			,flashx.textLayout.formats.LeadingModel.AUTO
+		);
+		/** @private */
+		static private var _columnGapProperty:NumberProperty = new NumberProperty("columnGap",20,false,Category.CONTAINER,0,1000); 		/** @private */
+		static private var _paddingLeftProperty:NumberProperty = new NumberProperty("paddingLeft",0,false,Category.CONTAINER,0,1000); 		/** @private */
+		static private var _paddingTopProperty:NumberProperty = new NumberProperty("paddingTop",0,false,Category.CONTAINER,0,1000); 		/** @private */
+		static private var _paddingRightProperty:NumberProperty = new NumberProperty("paddingRight",0,false,Category.CONTAINER,0,1000); 		/** @private */
+		static private var _paddingBottomProperty:NumberProperty = new NumberProperty("paddingBottom",0,false,Category.CONTAINER,0,1000); 		/** @private */
+		static private var _columnCountProperty:IntWithEnumProperty = new IntWithEnumProperty(
+			"columnCount",flashx.textLayout.formats.FormatValue.AUTO,false,Category.CONTAINER,1,50
+			,flashx.textLayout.formats.FormatValue.AUTO
+		);
+		/** @private */
+		static private var _columnWidthProperty:NumberWithEnumProperty = new NumberWithEnumProperty(
+			"columnWidth",flashx.textLayout.formats.FormatValue.AUTO,false,Category.CONTAINER,0,8000
+			,flashx.textLayout.formats.FormatValue.AUTO
+		);
+		/** @private */
+		static private var _firstBaselineOffsetProperty:NumberWithEnumProperty = new NumberWithEnumProperty(
+			"firstBaselineOffset",flashx.textLayout.formats.BaselineOffset.AUTO,true,Category.CONTAINER,0,1000
+			,flashx.textLayout.formats.BaselineOffset.AUTO
+			,flashx.textLayout.formats.BaselineOffset.ASCENT
+			,flashx.textLayout.formats.BaselineOffset.LINE_HEIGHT
+		);
+		/** @private */
+		static private var _verticalAlignProperty:EnumStringProperty = new EnumStringProperty(
+			"verticalAlign",flashx.textLayout.formats.VerticalAlign.TOP,false,Category.CONTAINER
+			,flashx.textLayout.formats.VerticalAlign.TOP
+			,flashx.textLayout.formats.VerticalAlign.MIDDLE
+			,flashx.textLayout.formats.VerticalAlign.BOTTOM
+			,flashx.textLayout.formats.VerticalAlign.JUSTIFY
+		);
+		/** @private */
+		static private var _blockProgressionProperty:EnumStringProperty = new EnumStringProperty(
+			"blockProgression",flashx.textLayout.formats.BlockProgression.TB,true,Category.CONTAINER
+			,flashx.textLayout.formats.BlockProgression.RL
+			,flashx.textLayout.formats.BlockProgression.TB
+		);
+		/** @private */
+		static private var _lineBreakProperty:EnumStringProperty = new EnumStringProperty(
+			"lineBreak",flashx.textLayout.formats.LineBreak.TO_FIT,false,Category.CONTAINER
+			,flashx.textLayout.formats.LineBreak.EXPLICIT
+			,flashx.textLayout.formats.LineBreak.TO_FIT
+		);
+
+		/** @private */
+		static tlf_internal function get colorProperty():UintProperty
+		{ return _colorProperty; }
+		/** @private */
+		static tlf_internal function get backgroundColorProperty():UintWithEnumProperty
+		{ return _backgroundColorProperty; }
+		/** @private */
+		static tlf_internal function get lineThroughProperty():BooleanProperty
+		{ return _lineThroughProperty; }
+		/** @private */
+		static tlf_internal function get textAlphaProperty():NumberProperty
+		{ return _textAlphaProperty; }
+		/** @private */
+		static tlf_internal function get backgroundAlphaProperty():NumberProperty
+		{ return _backgroundAlphaProperty; }
+		/** @private */
+		static tlf_internal function get fontSizeProperty():NumberProperty
+		{ return _fontSizeProperty; }
+		/** @private */
+		static tlf_internal function get baselineShiftProperty():NumberOrPercentOrEnumProperty
+		{ return _baselineShiftProperty; }
+		/** @private */
+		static tlf_internal function get trackingLeftProperty():NumberOrPercentProperty
+		{ return _trackingLeftProperty; }
+		/** @private */
+		static tlf_internal function get trackingRightProperty():NumberOrPercentProperty
+		{ return _trackingRightProperty; }
+		/** @private */
+		static tlf_internal function get lineHeightProperty():NumberOrPercentProperty
+		{ return _lineHeightProperty; }
+		/** @private */
+		static tlf_internal function get breakOpportunityProperty():EnumStringProperty
+		{ return _breakOpportunityProperty; }
+		/** @private */
+		static tlf_internal function get digitCaseProperty():EnumStringProperty
+		{ return _digitCaseProperty; }
+		/** @private */
+		static tlf_internal function get digitWidthProperty():EnumStringProperty
+		{ return _digitWidthProperty; }
+		/** @private */
+		static tlf_internal function get dominantBaselineProperty():EnumStringProperty
+		{ return _dominantBaselineProperty; }
+		/** @private */
+		static tlf_internal function get kerningProperty():EnumStringProperty
+		{ return _kerningProperty; }
+		/** @private */
+		static tlf_internal function get ligatureLevelProperty():EnumStringProperty
+		{ return _ligatureLevelProperty; }
+		/** @private */
+		static tlf_internal function get alignmentBaselineProperty():EnumStringProperty
+		{ return _alignmentBaselineProperty; }
+		/** @private */
+		static tlf_internal function get localeProperty():StringProperty
+		{ return _localeProperty; }
+		/** @private */
+		static tlf_internal function get typographicCaseProperty():EnumStringProperty
+		{ return _typographicCaseProperty; }
+		/** @private */
+		static tlf_internal function get fontFamilyProperty():StringProperty
+		{ return _fontFamilyProperty; }
+		/** @private */
+		static tlf_internal function get textDecorationProperty():EnumStringProperty
+		{ return _textDecorationProperty; }
+		/** @private */
+		static tlf_internal function get fontWeightProperty():EnumStringProperty
+		{ return _fontWeightProperty; }
+		/** @private */
+		static tlf_internal function get fontStyleProperty():EnumStringProperty
+		{ return _fontStyleProperty; }
+		/** @private */
+		static tlf_internal function get whiteSpaceCollapseProperty():EnumStringProperty
+		{ return _whiteSpaceCollapseProperty; }
+		/** @private */
+		static tlf_internal function get renderingModeProperty():EnumStringProperty
+		{ return _renderingModeProperty; }
+		/** @private */
+		static tlf_internal function get cffHintingProperty():EnumStringProperty
+		{ return _cffHintingProperty; }
+		/** @private */
+		static tlf_internal function get fontLookupProperty():EnumStringProperty
+		{ return _fontLookupProperty; }
+		/** @private */
+		static tlf_internal function get textRotationProperty():EnumStringProperty
+		{ return _textRotationProperty; }
+		/** @private */
+		static tlf_internal function get textIndentProperty():NumberProperty
+		{ return _textIndentProperty; }
+		/** @private */
+		static tlf_internal function get paragraphStartIndentProperty():NumberProperty
+		{ return _paragraphStartIndentProperty; }
+		/** @private */
+		static tlf_internal function get paragraphEndIndentProperty():NumberProperty
+		{ return _paragraphEndIndentProperty; }
+		/** @private */
+		static tlf_internal function get paragraphSpaceBeforeProperty():NumberProperty
+		{ return _paragraphSpaceBeforeProperty; }
+		/** @private */
+		static tlf_internal function get paragraphSpaceAfterProperty():NumberProperty
+		{ return _paragraphSpaceAfterProperty; }
+		/** @private */
+		static tlf_internal function get textAlignProperty():EnumStringProperty
+		{ return _textAlignProperty; }
+		/** @private */
+		static tlf_internal function get textAlignLastProperty():EnumStringProperty
+		{ return _textAlignLastProperty; }
+		/** @private */
+		static tlf_internal function get textJustifyProperty():EnumStringProperty
+		{ return _textJustifyProperty; }
+		/** @private */
+		static tlf_internal function get justificationRuleProperty():EnumStringProperty
+		{ return _justificationRuleProperty; }
+		/** @private */
+		static tlf_internal function get justificationStyleProperty():EnumStringProperty
+		{ return _justificationStyleProperty; }
+		/** @private */
+		static tlf_internal function get directionProperty():EnumStringProperty
+		{ return _directionProperty; }
+		/** @private */
+		static tlf_internal function get tabStopsProperty():TabStopsProperty
+		{ return _tabStopsProperty; }
+		/** @private */
+		static tlf_internal function get leadingModelProperty():EnumStringProperty
+		{ return _leadingModelProperty; }
+		/** @private */
+		static tlf_internal function get columnGapProperty():NumberProperty
+		{ return _columnGapProperty; }
+		/** @private */
+		static tlf_internal function get paddingLeftProperty():NumberProperty
+		{ return _paddingLeftProperty; }
+		/** @private */
+		static tlf_internal function get paddingTopProperty():NumberProperty
+		{ return _paddingTopProperty; }
+		/** @private */
+		static tlf_internal function get paddingRightProperty():NumberProperty
+		{ return _paddingRightProperty; }
+		/** @private */
+		static tlf_internal function get paddingBottomProperty():NumberProperty
+		{ return _paddingBottomProperty; }
+		/** @private */
+		static tlf_internal function get columnCountProperty():IntWithEnumProperty
+		{ return _columnCountProperty; }
+		/** @private */
+		static tlf_internal function get columnWidthProperty():NumberWithEnumProperty
+		{ return _columnWidthProperty; }
+		/** @private */
+		static tlf_internal function get firstBaselineOffsetProperty():NumberWithEnumProperty
+		{ return _firstBaselineOffsetProperty; }
+		/** @private */
+		static tlf_internal function get verticalAlignProperty():EnumStringProperty
+		{ return _verticalAlignProperty; }
+		/** @private */
+		static tlf_internal function get blockProgressionProperty():EnumStringProperty
+		{ return _blockProgressionProperty; }
+		/** @private */
+		static tlf_internal function get lineBreakProperty():EnumStringProperty
+		{ return _lineBreakProperty; }
+
+		static private var _description:Object = {
+			  color:_colorProperty
+			, backgroundColor:_backgroundColorProperty
+			, lineThrough:_lineThroughProperty
+			, textAlpha:_textAlphaProperty
+			, backgroundAlpha:_backgroundAlphaProperty
+			, fontSize:_fontSizeProperty
+			, baselineShift:_baselineShiftProperty
+			, trackingLeft:_trackingLeftProperty
+			, trackingRight:_trackingRightProperty
+			, lineHeight:_lineHeightProperty
+			, breakOpportunity:_breakOpportunityProperty
+			, digitCase:_digitCaseProperty
+			, digitWidth:_digitWidthProperty
+			, dominantBaseline:_dominantBaselineProperty
+			, kerning:_kerningProperty
+			, ligatureLevel:_ligatureLevelProperty
+			, alignmentBaseline:_alignmentBaselineProperty
+			, locale:_localeProperty
+			, typographicCase:_typographicCaseProperty
+			, fontFamily:_fontFamilyProperty
+			, textDecoration:_textDecorationProperty
+			, fontWeight:_fontWeightProperty
+			, fontStyle:_fontStyleProperty
+			, whiteSpaceCollapse:_whiteSpaceCollapseProperty
+			, renderingMode:_renderingModeProperty
+			, cffHinting:_cffHintingProperty
+			, fontLookup:_fontLookupProperty
+			, textRotation:_textRotationProperty
+			, textIndent:_textIndentProperty
+			, paragraphStartIndent:_paragraphStartIndentProperty
+			, paragraphEndIndent:_paragraphEndIndentProperty
+			, paragraphSpaceBefore:_paragraphSpaceBeforeProperty
+			, paragraphSpaceAfter:_paragraphSpaceAfterProperty
+			, textAlign:_textAlignProperty
+			, textAlignLast:_textAlignLastProperty
+			, textJustify:_textJustifyProperty
+			, justificationRule:_justificationRuleProperty
+			, justificationStyle:_justificationStyleProperty
+			, direction:_directionProperty
+			, tabStops:_tabStopsProperty
+			, leadingModel:_leadingModelProperty
+			, columnGap:_columnGapProperty
+			, paddingLeft:_paddingLeftProperty
+			, paddingTop:_paddingTopProperty
+			, paddingRight:_paddingRightProperty
+			, paddingBottom:_paddingBottomProperty
+			, columnCount:_columnCountProperty
+			, columnWidth:_columnWidthProperty
+			, firstBaselineOffset:_firstBaselineOffsetProperty
+			, verticalAlign:_verticalAlignProperty
+			, blockProgression:_blockProgressionProperty
+			, lineBreak:_lineBreakProperty
+		}
+
+		/** Property descriptions accessible by name. @private */
+		static tlf_internal function get description():Object
+		{ return _description; }
+
+		/** @private */
+		static private var _emptyTextLayoutFormat:ITextLayoutFormat;
+		/**
+		 * Returns an ITextLayoutFormat instance with all properties set to <code>undefined</code>.
+		 * @private
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		static tlf_internal function get emptyTextLayoutFormat():ITextLayoutFormat
+		{
+			if (_emptyTextLayoutFormat == null)
+				_emptyTextLayoutFormat = new TextLayoutFormatValueHolder();
+			return _emptyTextLayoutFormat;
+		}
+
+
+		private var _color:*;
+		private var _backgroundColor:*;
+		private var _lineThrough:*;
+		private var _textAlpha:*;
+		private var _backgroundAlpha:*;
+		private var _fontSize:*;
+		private var _baselineShift:*;
+		private var _trackingLeft:*;
+		private var _trackingRight:*;
+		private var _lineHeight:*;
+		private var _breakOpportunity:*;
+		private var _digitCase:*;
+		private var _digitWidth:*;
+		private var _dominantBaseline:*;
+		private var _kerning:*;
+		private var _ligatureLevel:*;
+		private var _alignmentBaseline:*;
+		private var _locale:*;
+		private var _typographicCase:*;
+		private var _fontFamily:*;
+		private var _textDecoration:*;
+		private var _fontWeight:*;
+		private var _fontStyle:*;
+		private var _whiteSpaceCollapse:*;
+		private var _renderingMode:*;
+		private var _cffHinting:*;
+		private var _fontLookup:*;
+		private var _textRotation:*;
+		private var _textIndent:*;
+		private var _paragraphStartIndent:*;
+		private var _paragraphEndIndent:*;
+		private var _paragraphSpaceBefore:*;
+		private var _paragraphSpaceAfter:*;
+		private var _textAlign:*;
+		private var _textAlignLast:*;
+		private var _textJustify:*;
+		private var _justificationRule:*;
+		private var _justificationStyle:*;
+		private var _direction:*;
+		private var _tabStops:*;
+		private var _leadingModel:*;
+		private var _columnGap:*;
+		private var _paddingLeft:*;
+		private var _paddingTop:*;
+		private var _paddingRight:*;
+		private var _paddingBottom:*;
+		private var _columnCount:*;
+		private var _columnWidth:*;
+		private var _firstBaselineOffset:*;
+		private var _verticalAlign:*;
+		private var _blockProgression:*;
+		private var _lineBreak:*;
+
+		/**
+		 * Color of the text. A hexadecimal number that specifies three 8-bit RGB (red, green, blue) values; for example, 0xFF0000 is red and 0x00FF00 is green. 
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get color():*
+		{ return _color; }
+		public function set color(newValue:*):void
+		{ _color = _colorProperty.setHelper(_color,newValue); }
+
+		/**
+		 * Background color of the text (adopts default value if undefined during cascade). Can be either the constant value  <code>BackgroundColor.TRANSPARENT</code>, or a hexadecimal value that specifies the three 8-bit RGB (red, green, blue) values; for example, 0xFF0000 is red and 0x00FF00 is green.
+		 * <p>Legal values as a string are flashx.textLayout.formats.BackgroundColor.TRANSPARENT, flashx.textLayout.formats.FormatValue.INHERIT and uints from 0x0 to 0xffffffff.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of TRANSPARENT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.BackgroundColor
+		 */
+		public function get backgroundColor():*
+		{ return _backgroundColor; }
+		public function set backgroundColor(newValue:*):void
+		{ _backgroundColor = _backgroundColorProperty.setHelper(_backgroundColor,newValue); }
+
+		/**
+		 * If <code>true</code>, applies strikethrough, a line drawn through the middle of the text.
+		 * <p>Legal values are true, false and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of false.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get lineThrough():*
+		{ return _lineThrough; }
+		public function set lineThrough(newValue:*):void
+		{ _lineThrough = _lineThroughProperty.setHelper(_lineThrough,newValue); }
+
+		/**
+		 * Alpha (transparency) value for the text. A value of 0 is fully transparent, and a value of 1 is fully opaque. Display objects with <code>textAlpha</code> set to 0 are active, even though they are invisible.
+		 * <p>Legal values are numbers from 0 to 1 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 1.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get textAlpha():*
+		{ return _textAlpha; }
+		public function set textAlpha(newValue:*):void
+		{ _textAlpha = _textAlphaProperty.setHelper(_textAlpha,newValue); }
+
+		/**
+		 * Alpha (transparency) value for the background (adopts default value if undefined during cascade). A value of 0 is fully transparent, and a value of 1 is fully opaque. Display objects with alpha set to 0 are active, even though they are invisible.
+		 * <p>Legal values are numbers from 0 to 1 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 1.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get backgroundAlpha():*
+		{ return _backgroundAlpha; }
+		public function set backgroundAlpha(newValue:*):void
+		{ _backgroundAlpha = _backgroundAlphaProperty.setHelper(_backgroundAlpha,newValue); }
+
+		/**
+		 * The size of the text in pixels.
+		 * <p>Legal values are numbers from 1 to 720 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 12.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get fontSize():*
+		{ return _fontSize; }
+		public function set fontSize(newValue:*):void
+		{ _fontSize = _fontSizeProperty.setHelper(_fontSize,newValue); }
+
+		/**
+		 * Amount to shift the baseline from the <code>dominantBaseline</code> value. Units are in pixels, or a percentage of <code>fontSize</code> (in which case, enter a string value, like 140%).  Positive values shift the line up for horizontal text (right for vertical) and negative values shift it down for horizontal (left for vertical). 
+		 * <p>Legal values are flashx.textLayout.formats.BaselineShift.SUPERSCRIPT, flashx.textLayout.formats.BaselineShift.SUBSCRIPT, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Legal values as a number are from -1000 to 1000.</p>
+		 * <p>Legal values as a percent are numbers from -1000 to 1000.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.BaselineShift
+		 */
+		public function get baselineShift():*
+		{ return _baselineShift; }
+		public function set baselineShift(newValue:*):void
+		{ _baselineShift = _baselineShiftProperty.setHelper(_baselineShift,newValue); }
+
+		/**
+		 * Number in pixels (or percent of <code>fontSize</code>, like 120%) indicating the amount of tracking (manual kerning) to be applied to the left of each character. If kerning is enabled, the <code>trackingLeft</code> value is added to the values in the kerning table for the font. If kerning is disabled, the <code>trackingLeft</code> value is used as a manual kerning value. Supports both positive and negative values. 
+		 * <p>Legal values as a number are from -1000 to 1000.</p>
+		 * <p>Legal values as a percent are numbers from -1000% to 1000%.</p>
+		 * <p>Legal values include flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get trackingLeft():*
+		{ return _trackingLeft; }
+		public function set trackingLeft(newValue:*):void
+		{ _trackingLeft = _trackingLeftProperty.setHelper(_trackingLeft,newValue); }
+
+		/**
+		 * Number in pixels (or percent of <code>fontSize</code>, like 120%) indicating the amount of tracking (manual kerning) to be applied to the right of each character.  If kerning is enabled, the <code>trackingRight</code> value is added to the values in the kerning table for the font. If kerning is disabled, the <code>trackingRight</code> value is used as a manual kerning value. Supports both positive and negative values. 
+		 * <p>Legal values as a number are from -1000 to 1000.</p>
+		 * <p>Legal values as a percent are numbers from -1000% to 1000%.</p>
+		 * <p>Legal values include flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get trackingRight():*
+		{ return _trackingRight; }
+		public function set trackingRight(newValue:*):void
+		{ _trackingRight = _trackingRightProperty.setHelper(_trackingRight,newValue); }
+
+		/**
+		 * Leading controls for the text. The distance from the baseline of the previous or the next line (based on <code>LeadingModel</code>) to the baseline of the current line is equal to the maximum amount of the leading applied to any character in the line. This is either a number or a percent.  If specifying a percent, enter a string value, like 140%.<p><img src='../../../images/textLayout_lineHeight1.jpg' alt='lineHeight1' /><img src='../../../images/textLayout_lineHeight2.jpg' alt='lineHeight2' /></p>
+		 * <p>Legal values as a number are from -720 to 720.</p>
+		 * <p>Legal values as a percent are numbers from -1000% to 1000%.</p>
+		 * <p>Legal values include flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 120%.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get lineHeight():*
+		{ return _lineHeight; }
+		public function set lineHeight(newValue:*):void
+		{ _lineHeight = _lineHeightProperty.setHelper(_lineHeight,newValue); }
+
+		/**
+		 * Controls where lines are allowed to break when breaking wrapping text into multiple lines. Set to <code>BreakOpportunity.AUTO</code> to break text normally. Set to <code>BreakOpportunity.NONE</code> to <em>not</em> break the text unless the text would overrun the measure and there are no other places to break the line. Set to <code>BreakOpportunity.ANY</code> to allow the line to break anywhere, rather than just between words. Set to <code>BreakOpportunity.ALL</code> to have each typographic cluster put on a separate line (useful for text on a path).
+		 * <p>Legal values are flash.text.engine.BreakOpportunity.ALL, flash.text.engine.BreakOpportunity.ANY, flash.text.engine.BreakOpportunity.AUTO, flash.text.engine.BreakOpportunity.NONE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.BreakOpportunity
+		 */
+		public function get breakOpportunity():*
+		{ return _breakOpportunity; }
+		public function set breakOpportunity(newValue:*):void
+		{ _breakOpportunity = _breakOpportunityProperty.setHelper(_breakOpportunity,newValue); }
+
+		/**
+		 * The type of digit case used for this text. Setting the value to <code>DigitCase.OLD_STYLE</code> approximates lowercase letterforms with varying ascenders and descenders. The figures are proportionally spaced. This style is only available in selected typefaces, most commonly in a supplemental or expert font. The <code>DigitCase.LINING</code> setting has all-cap height and is typically monospaced to line up in charts.<p><img src='../../../images/textLayout_digitcase.gif' alt='digitCase' /></p>
+		 * <p>Legal values are flash.text.engine.DigitCase.DEFAULT, flash.text.engine.DigitCase.LINING, flash.text.engine.DigitCase.OLD_STYLE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of DEFAULT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.DigitCase
+		 */
+		public function get digitCase():*
+		{ return _digitCase; }
+		public function set digitCase(newValue:*):void
+		{ _digitCase = _digitCaseProperty.setHelper(_digitCase,newValue); }
+
+		/**
+		 * Type of digit width used for this text. This can be <code>DigitWidth.PROPORTIONAL</code>, which looks best for individual numbers, or <code>DigitWidth.TABULAR</code>, which works best for numbers in tables, charts, and vertical rows.<p><img src='../../../images/textLayout_digitwidth.gif' alt='digitWidth' /></p>
+		 * <p>Legal values are flash.text.engine.DigitWidth.DEFAULT, flash.text.engine.DigitWidth.PROPORTIONAL, flash.text.engine.DigitWidth.TABULAR, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of DEFAULT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.DigitWidth
+		 */
+		public function get digitWidth():*
+		{ return _digitWidth; }
+		public function set digitWidth(newValue:*):void
+		{ _digitWidth = _digitWidthProperty.setHelper(_digitWidth,newValue); }
+
+		/**
+		 * Specifies which element baseline snaps to the <code>alignmentBaseline</code> to determine the vertical position of the element on the line. A value of <code>TextBaseline.AUTO</code> selects the dominant baseline based on the <code>locale</code> property of the parent paragraph.  For Japanese and Chinese, the selected baseline value is <code>TextBaseline.IDEOGRAPHIC_CENTER</code>; for all others it is <code>TextBaseline.ROMAN</code>. These baseline choices are determined by the choice of font and the font size.<p><img src='../../../images/textLayout_baselines.jpg' alt='baselines' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.FormatValue.AUTO, flash.text.engine.TextBaseline.ROMAN, flash.text.engine.TextBaseline.ASCENT, flash.text.engine.TextBaseline.DESCENT, flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP, flash.text.engine.TextBaseline.IDEOGRAPHIC_CENTER, flash.text.engine.TextBaseline.IDEOGRAPHIC_BOTTOM, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of flashx.textLayout.formats.FormatValue.AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.TextBaseline
+		 */
+		public function get dominantBaseline():*
+		{ return _dominantBaseline; }
+		public function set dominantBaseline(newValue:*):void
+		{ _dominantBaseline = _dominantBaselineProperty.setHelper(_dominantBaseline,newValue); }
+
+		/**
+		 * Kerning adjusts the pixels between certain character pairs to improve readability. Kerning is supported for all fonts with kerning tables.
+		 * <p>Legal values are flash.text.engine.Kerning.ON, flash.text.engine.Kerning.OFF, flash.text.engine.Kerning.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.Kerning
+		 */
+		public function get kerning():*
+		{ return _kerning; }
+		public function set kerning(newValue:*):void
+		{ _kerning = _kerningProperty.setHelper(_kerning,newValue); }
+
+		/**
+		 * Controls which of the ligatures that are defined in the font may be used in the text. The ligatures that appear for each of these settings is dependent on the font. A ligature occurs where two or more letter-forms are joined as a single glyph. Ligatures usually replace consecutive characters sharing common components, such as the letter pairs 'fi', 'fl', or 'ae'. They are used with both Latin and Non-Latin character sets. The ligatures enabled by the values of the LigatureLevel class - <code>MINIMUM</code>, <code>COMMON</code>, <code>UNCOMMON</code>, and <code>EXOTIC</code> - are additive. Each value enables a new set of ligatures, but also includes those of the previous types.<p><b>Note: </b>When working with Arabic or Syriac fonts, <code>ligatureLevel</code> must be set to MINIMUM or above.</p><p><img src='../../../images/textLayout_ligatures.png' alt='ligatureLevel' /></p>
+		 * <p>Legal values are flash.text.engine.LigatureLevel.MINIMUM, flash.text.engine.LigatureLevel.COMMON, flash.text.engine.LigatureLevel.UNCOMMON, flash.text.engine.LigatureLevel.EXOTIC, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of COMMON.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.LigatureLevel
+		 */
+		public function get ligatureLevel():*
+		{ return _ligatureLevel; }
+		public function set ligatureLevel(newValue:*):void
+		{ _ligatureLevel = _ligatureLevelProperty.setHelper(_ligatureLevel,newValue); }
+
+		/**
+		 * Specifies the baseline to which the dominant baseline aligns. For example, if you set <code>dominantBaseline</code> to ASCENT, setting <code>alignmentBaseline</code> to DESCENT aligns the top of the text with the DESCENT baseline, or below the line.  The largest element in the line generally determines the baselines.<p><img src='../../../images/textLayout_baselines.jpg' alt='baselines' /></p>
+		 * <p>Legal values are flash.text.engine.TextBaseline.ROMAN, flash.text.engine.TextBaseline.ASCENT, flash.text.engine.TextBaseline.DESCENT, flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP, flash.text.engine.TextBaseline.IDEOGRAPHIC_CENTER, flash.text.engine.TextBaseline.IDEOGRAPHIC_BOTTOM, flash.text.engine.TextBaseline.USE_DOMINANT_BASELINE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of USE_DOMINANT_BASELINE.</p>
+		 * @includeExample examples\TextLayoutFormat_alignmentBaselineExample.as -noswf
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.TextBaseline
+		 */
+		public function get alignmentBaseline():*
+		{ return _alignmentBaseline; }
+		public function set alignmentBaseline(newValue:*):void
+		{ _alignmentBaseline = _alignmentBaselineProperty.setHelper(_alignmentBaseline,newValue); }
+
+		/**
+		 * The locale of the text. Controls case transformations and shaping. Standard locale identifiers as described in Unicode Technical Standard #35 are used. For example en, en_US and en-US are all English, ja is Japanese. 
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of en.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get locale():*
+		{ return _locale; }
+		public function set locale(newValue:*):void
+		{ _locale = _localeProperty.setHelper(_locale,newValue); }
+
+		/**
+		 * The type of typographic case used for this text. Here are some examples:<p><img src='../../../images/textLayout_typographiccase.png' alt='typographicCase' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.TLFTypographicCase.DEFAULT, flashx.textLayout.formats.TLFTypographicCase.CAPS_TO_SMALL_CAPS, flashx.textLayout.formats.TLFTypographicCase.UPPERCASE, flashx.textLayout.formats.TLFTypographicCase.LOWERCASE, flashx.textLayout.formats.TLFTypographicCase.LOWERCASE_TO_SMALL_CAPS, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of DEFAULT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TLFTypographicCase
+		 */
+		public function get typographicCase():*
+		{ return _typographicCase; }
+		public function set typographicCase(newValue:*):void
+		{ _typographicCase = _typographicCaseProperty.setHelper(_typographicCase,newValue); }
+
+		/**
+		 *  The name of the font to use, or a comma-separated list of font names. The Flash runtime renders the element with the first available font in the list. For example Arial, Helvetica, _sans causes the player to search for Arial, then Helvetica if Arial is not found, then _sans if neither is found.
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of Arial.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get fontFamily():*
+		{ return _fontFamily; }
+		public function set fontFamily(newValue:*):void
+		{ _fontFamily = _fontFamilyProperty.setHelper(_fontFamily,newValue); }
+
+		/**
+		 * Decoration on text. Use to apply underlining; default is none.
+		 * <p>Legal values are flashx.textLayout.formats.TextDecoration.NONE, flashx.textLayout.formats.TextDecoration.UNDERLINE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of NONE.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TextDecoration
+		 */
+		public function get textDecoration():*
+		{ return _textDecoration; }
+		public function set textDecoration(newValue:*):void
+		{ _textDecoration = _textDecorationProperty.setHelper(_textDecoration,newValue); }
+
+		/**
+		 * Weight of text. May be <code>FontWeight.NORMAL</code> for use in plain text, or <code>FontWeight.BOLD</code>. Applies only to device fonts (<code>fontLookup</code> property is set to flash.text.engine.FontLookup.DEVICE).
+		 * <p>Legal values are flash.text.engine.FontWeight.NORMAL, flash.text.engine.FontWeight.BOLD, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of NORMAL.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.FontWeight
+		 */
+		public function get fontWeight():*
+		{ return _fontWeight; }
+		public function set fontWeight(newValue:*):void
+		{ _fontWeight = _fontWeightProperty.setHelper(_fontWeight,newValue); }
+
+		/**
+		 * Style of text. May be <code>FontPosture.NORMAL</code>, for use in plain text, or <code>FontPosture.ITALIC</code> for italic. This property applies only to device fonts (<code>fontLookup</code> property is set to flash.text.engine.FontLookup.DEVICE).
+		 * <p>Legal values are flash.text.engine.FontPosture.NORMAL, flash.text.engine.FontPosture.ITALIC, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of NORMAL.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.FontPosture
+		 */
+		public function get fontStyle():*
+		{ return _fontStyle; }
+		public function set fontStyle(newValue:*):void
+		{ _fontStyle = _fontStyleProperty.setHelper(_fontStyle,newValue); }
+
+		/**
+		 * Collapses or preserves whitespace when importing text into a TextFlow. <code>WhiteSpaceCollapse.PRESERVE</code> retains all whitespace characters. <code>WhiteSpaceCollapse.COLLAPSE</code> removes newlines, tabs, and leading or trailing spaces within a block of imported text. Line break tags (&lt;br/&gt;) and Unicode line separator characters are retained.
+		 * <p>Legal values are flashx.textLayout.formats.WhiteSpaceCollapse.PRESERVE, flashx.textLayout.formats.WhiteSpaceCollapse.COLLAPSE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of COLLAPSE.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.WhiteSpaceCollapse
+		 */
+		public function get whiteSpaceCollapse():*
+		{ return _whiteSpaceCollapse; }
+		public function set whiteSpaceCollapse(newValue:*):void
+		{ _whiteSpaceCollapse = _whiteSpaceCollapseProperty.setHelper(_whiteSpaceCollapse,newValue); }
+
+		/**
+		 * The rendering mode used for this text.  Applies only to embedded fonts (<code>fontLookup</code> property is set to <code>FontLookup.EMBEDDED_CFF</code>).
+		 * <p>Legal values are flash.text.engine.RenderingMode.NORMAL, flash.text.engine.RenderingMode.CFF, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of CFF.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.RenderingMode
+		 */
+		public function get renderingMode():*
+		{ return _renderingMode; }
+		public function set renderingMode(newValue:*):void
+		{ _renderingMode = _renderingModeProperty.setHelper(_renderingMode,newValue); }
+
+		/**
+		 * The type of CFF hinting used for this text. CFF hinting determines whether the Flash runtime forces strong horizontal stems to fit to a sub pixel grid or not. This property applies only if the <code>renderingMode</code> property is set to <code>RenderingMode.CFF</code>, and the font is embedded (<code>fontLookup</code> property is set to <code>FontLookup.EMBEDDED_CFF</code>). At small screen sizes, hinting produces a clear, legible text for human readers.
+		 * <p>Legal values are flash.text.engine.CFFHinting.NONE, flash.text.engine.CFFHinting.HORIZONTAL_STEM, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of HORIZONTAL_STEM.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.CFFHinting
+		 */
+		public function get cffHinting():*
+		{ return _cffHinting; }
+		public function set cffHinting(newValue:*):void
+		{ _cffHinting = _cffHintingProperty.setHelper(_cffHinting,newValue); }
+
+		/**
+		 * Font lookup to use. Specifying <code>FontLookup.DEVICE</code> uses the fonts installed on the system that is running the SWF file. Device fonts result in a smaller movie size, but text is not always rendered the same across different systems and platforms. Specifying <code>FontLookup.EMBEDDED_CFF</code> uses font outlines embedded in the published SWF file. Embedded fonts increase the size of the SWF file (sometimes dramatically), but text is consistently displayed in the chosen font.
+		 * <p>Legal values are flash.text.engine.FontLookup.DEVICE, flash.text.engine.FontLookup.EMBEDDED_CFF, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of DEVICE.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.FontLookup
+		 */
+		public function get fontLookup():*
+		{ return _fontLookup; }
+		public function set fontLookup(newValue:*):void
+		{ _fontLookup = _fontLookupProperty.setHelper(_fontLookup,newValue); }
+
+		/**
+		 * Determines the number of degrees to rotate this text.
+		 * <p>Legal values are flash.text.engine.TextRotation.ROTATE_0, flash.text.engine.TextRotation.ROTATE_180, flash.text.engine.TextRotation.ROTATE_270, flash.text.engine.TextRotation.ROTATE_90, flash.text.engine.TextRotation.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.TextRotation
+		 */
+		public function get textRotation():*
+		{ return _textRotation; }
+		public function set textRotation(newValue:*):void
+		{ _textRotation = _textRotationProperty.setHelper(_textRotation,newValue); }
+
+		/**
+		 * A Number that specifies, in pixels, the amount to indent the first line of the paragraph.
+		 * A negative indent will push the line into the margin, and possibly out of the container.
+		 * <p>Legal values are numbers from -1000 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get textIndent():*
+		{ return _textIndent; }
+		public function set textIndent(newValue:*):void
+		{ _textIndent = _textIndentProperty.setHelper(_textIndent,newValue); }
+
+		/**
+		 * A Number that specifies, in pixels, the amount to indent the paragraph's start edge. Refers to the left edge in left-to-right text and the right edge in right-to-left text. 
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paragraphStartIndent():*
+		{ return _paragraphStartIndent; }
+		public function set paragraphStartIndent(newValue:*):void
+		{ _paragraphStartIndent = _paragraphStartIndentProperty.setHelper(_paragraphStartIndent,newValue); }
+
+		/**
+		 * A Number that specifies, in pixels, the amount to indent the paragraph's end edge. Refers to the right edge in left-to-right text and the left edge in right-to-left text. 
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paragraphEndIndent():*
+		{ return _paragraphEndIndent; }
+		public function set paragraphEndIndent(newValue:*):void
+		{ _paragraphEndIndent = _paragraphEndIndentProperty.setHelper(_paragraphEndIndent,newValue); }
+
+		/**
+		 * A Number that specifies the amount of space, in pixels, to leave before the paragraph. 
+		 * Collapses in tandem with <code>paragraphSpaceAfter</code>.
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paragraphSpaceBefore():*
+		{ return _paragraphSpaceBefore; }
+		public function set paragraphSpaceBefore(newValue:*):void
+		{ _paragraphSpaceBefore = _paragraphSpaceBeforeProperty.setHelper(_paragraphSpaceBefore,newValue); }
+
+		/**
+		 * A Number that specifies the amount of space, in pixels, to leave after the paragraph.
+		 * Collapses in tandem with  <code>paragraphSpaceBefore</code>.
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paragraphSpaceAfter():*
+		{ return _paragraphSpaceAfter; }
+		public function set paragraphSpaceAfter(newValue:*):void
+		{ _paragraphSpaceAfter = _paragraphSpaceAfterProperty.setHelper(_paragraphSpaceAfter,newValue); }
+
+		/**
+		 * Alignment of lines in the paragraph relative to the container.
+		 * <code>TextAlign.LEFT</code> aligns lines along the left edge of the container. <code>TextAlign.RIGHT</code> aligns on the right edge. <code>TextAlign.CENTER</code> positions the line equidistant from the left and right edges. <code>TextAlign.JUSTIFY</code> spreads the lines out so they fill the space. <code>TextAlign.START</code> is equivalent to setting left in left-to-right text, or right in right-to-left text. <code>TextAlign.END</code> is equivalent to setting right in left-to-right text, or left in right-to-left text.
+		 * <p>Legal values are flashx.textLayout.formats.TextAlign.LEFT, flashx.textLayout.formats.TextAlign.RIGHT, flashx.textLayout.formats.TextAlign.CENTER, flashx.textLayout.formats.TextAlign.JUSTIFY, flashx.textLayout.formats.TextAlign.START, flashx.textLayout.formats.TextAlign.END, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of START.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TextAlign
+		 */
+		public function get textAlign():*
+		{ return _textAlign; }
+		public function set textAlign(newValue:*):void
+		{ _textAlign = _textAlignProperty.setHelper(_textAlign,newValue); }
+
+		/**
+		 * Alignment of the last (or only) line in the paragraph relative to the container in justified text.
+		 * If <code>textAlign</code> is set to <code>TextAlign.JUSTIFY</code>, <code>textAlignLast</code> specifies how the last line (or only line, if this is a one line block) is aligned. Values are similar to <code>textAlign</code>.
+		 * <p>Legal values are flashx.textLayout.formats.TextAlign.LEFT, flashx.textLayout.formats.TextAlign.RIGHT, flashx.textLayout.formats.TextAlign.CENTER, flashx.textLayout.formats.TextAlign.JUSTIFY, flashx.textLayout.formats.TextAlign.START, flashx.textLayout.formats.TextAlign.END, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of START.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TextAlign
+		 */
+		public function get textAlignLast():*
+		{ return _textAlignLast; }
+		public function set textAlignLast(newValue:*):void
+		{ _textAlignLast = _textAlignLastProperty.setHelper(_textAlignLast,newValue); }
+
+		/**
+		 * Specifies options for justifying text.
+		 * Default value is <code>TextJustify.INTER_WORD</code>, meaning that extra space is added to the space characters. <code>TextJustify.DISTRIBUTE</code> adds extra space to space characters and between individual letters. Used only in conjunction with a <code>justificationRule</code> value of <code>JustificationRule.SPACE</code>.
+		 * <p>Legal values are flashx.textLayout.formats.TextJustify.INTER_WORD, flashx.textLayout.formats.TextJustify.DISTRIBUTE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of INTER_WORD.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TextJustify
+		 */
+		public function get textJustify():*
+		{ return _textJustify; }
+		public function set textJustify(newValue:*):void
+		{ _textJustify = _textJustifyProperty.setHelper(_textJustify,newValue); }
+
+		/**
+		 * Rule used to justify text in a paragraph.
+		 * Default value is <code>FormatValue.AUTO</code>, which justifies text based on the paragraph's <code>locale</code> property. For all languages except Japanese and Chinese, <code>FormatValue.AUTO</code> becomes <code>JustificationRule.SPACE</code>, which adds extra space to the space characters.  For Japanese and Chinese, <code>FormatValue.AUTO</code> becomes <code>JustficationRule.EAST_ASIAN</code>. In part, justification changes the spacing of punctuation. In Roman text the comma and Japanese periods take a full character's width but in East Asian text only half of a character's width. Also, in the East Asian text the spacing between sequential punctuation marks becomes tighter, obeying traditional East Asian typographic conventions. Note, too, in the example below the leading that is applied to the second line of the paragraphs. In the East Asian version, the last two lines push left. In the Roman version, the second and following lines push left.<p><img src='../../../images/textLayout_justificationrule.png' alt='justificationRule' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.JustificationRule.EAST_ASIAN, flashx.textLayout.formats.JustificationRule.SPACE, flashx.textLayout.formats.FormatValue.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of flashx.textLayout.formats.FormatValue.AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.JustificationRule
+		 */
+		public function get justificationRule():*
+		{ return _justificationRule; }
+		public function set justificationRule(newValue:*):void
+		{ _justificationRule = _justificationRuleProperty.setHelper(_justificationRule,newValue); }
+
+		/**
+		 * The style used for justification of the paragraph. Used only in conjunction with a <code>justificationRule</code> setting of <code>JustificationRule.EAST_ASIAN</code>.
+		 * Default value of <code>FormatValue.AUTO</code> is resolved to <code>JustificationStyle.PUSH_IN_KINSOKU</code> for all locales.  The constants defined by the JustificationStyle class specify options for handling kinsoku characters, which are Japanese characters that cannot appear at either the beginning or end of a line. If you want looser text, specify <code>JustificationStyle.PUSH-OUT-ONLY</code>. If you want behavior that is like what you get with the  <code>justificationRule</code> of <code>JustificationRule.SPACE</code>, use <code>JustificationStyle.PRIORITIZE-LEAST-ADJUSTMENT</code>.
+		 * <p>Legal values are flash.text.engine.JustificationStyle.PRIORITIZE_LEAST_ADJUSTMENT, flash.text.engine.JustificationStyle.PUSH_IN_KINSOKU, flash.text.engine.JustificationStyle.PUSH_OUT_ONLY, flashx.textLayout.formats.FormatValue.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of flashx.textLayout.formats.FormatValue.AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.JustificationStyle
+		 */
+		public function get justificationStyle():*
+		{ return _justificationStyle; }
+		public function set justificationStyle(newValue:*):void
+		{ _justificationStyle = _justificationStyleProperty.setHelper(_justificationStyle,newValue); }
+
+		/**
+		 * Specifies the default bidirectional embedding level of the text in the text block. 
+		 * Left-to-right reading order, as in Latin-style scripts, or right-to-left reading order, as in Arabic or Hebrew. This property also affects column direction when it is applied at the container level. Columns can be either left-to-right or right-to-left, just like text. Below are some examples:<p><img src='../../../images/textLayout_direction.gif' alt='direction' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.Direction.LTR, flashx.textLayout.formats.Direction.RTL, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of LTR.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.Direction
+		 */
+		public function get direction():*
+		{ return _direction; }
+		public function set direction(newValue:*):void
+		{ _direction = _directionProperty.setHelper(_direction,newValue); }
+
+		/**
+		 * Specifies the tab stops associated with the paragraph.
+		 * Setters can take an array of flashx.textLayout.formats.TabStopFormat, a condensed string representation, undefined, or <code>FormatValue.INHERIT</code>. The condensed string representation is always converted into an array of flashx.textLayout.formats.TabStopFormat. <p>The string-based format is a list of tab stops, where each tab stop is delimited by one or more spaces.</p><p>A tab stop takes the following form: &lt;alignment type&gt;&lt;alignment position&gt;|&lt;alignment token&gt;.</p><p>The alignment type is a single character, and can be S, E, C, or D (or lower-case equivalents). S or s for start, E or e for end, C or c for center, D or d for decimal. The alignment type is optional, and if its not specified will default to S.</p><p>The alignment position is a Number, and is specified according to FXG spec for Numbers (decimal or scientific notation). The alignment position is required.</p><p>The vertical bar is used to separate the alignment position from the alignment token, and should only be present if the alignment token is present.</p><p> The alignment token is optional if the alignment type is D, and should not be present if the alignment type is anything other than D. The alignment token may be any sequence of characters terminated by the space that ends the tab stop (for the last tab stop, the terminating space is optional; end of alignment token is implied). A space may be part of the alignment token if it is escaped with a backslash (\ ). A backslash may be part of the alignment token if it is escaped with another backslash (\\). If the alignment type is D, and the alignment token is not specified, it will take on the default value of null.</p><p>If no tab stops are specified, a tab action defaults to the end of the line.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of null.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get tabStops():*
+		{ return _tabStops; }
+		public function set tabStops(newValue:*):void
+		{ _tabStops = _tabStopsProperty.setHelper(_tabStops,newValue); }
+
+		/**
+		 * Specifies the leading model, which is a combination of leading basis and leading direction.
+		 * Leading basis is the baseline to which the <code>lineHeight</code> property refers. Leading direction determines whether the <code>lineHeight</code> property refers to the distance of a line's baseline from that of the line before it or the line after it. The default value of <code>FormatValue.AUTO</code> is resolved based on the paragraph's <code>locale</code> property.  For Japanese and Chinese, it is <code>LeadingModel.IDEOGRAPHIC_TOP_DOWN</code> and for all others it is <code>LeadingModel.ROMAN_UP</code>.<p><strong>Leading Basis:</strong></p><p><img src='../../../images/textLayout_LB1.png' alt='leadingBasis1' />    <img src='../../../images/textLayout_LB2.png' alt='leadingBasis2' />    <img src='../../../images/textLayout_LB3.png' alt='leadingBasis3' /></p><p><strong>Leading Direction:</strong></p><p><img src='../../../images/textLayout_LD1.png' alt='leadingDirection1' />    <img src='../../../images/textLayout_LD2.png' alt='leadingDirection2' />    <img src='../../../images/textLayout_LD3.png' alt='leadingDirection3' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.LeadingModel.ROMAN_UP, flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_TOP_UP, flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_CENTER_UP, flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_TOP_DOWN, flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_CENTER_DOWN, flashx.textLayout.formats.LeadingModel.APPROXIMATE_TEXT_FIELD, flashx.textLayout.formats.LeadingModel.ASCENT_DESCENT_UP, flashx.textLayout.formats.LeadingModel.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.LeadingModel
+		 */
+		public function get leadingModel():*
+		{ return _leadingModel; }
+		public function set leadingModel(newValue:*):void
+		{ _leadingModel = _leadingModelProperty.setHelper(_leadingModel,newValue); }
+
+		/**
+		 * Specifies the amount of gutter space, in pixels, to leave between the columns (adopts default value if undefined during cascade).
+		 * Value is a Number
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 20.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get columnGap():*
+		{ return _columnGap; }
+		public function set columnGap(newValue:*):void
+		{ _columnGap = _columnGapProperty.setHelper(_columnGap,newValue); }
+
+		/**
+		 * Left inset in pixels (adopts default value if undefined during cascade).
+		 * Space between the left edge of the container and the text.  Value is a Number.<p> With vertical text, in scrollable containers with multiple columns, the first and following columns will show the padding as blank space at the end of the container, but for the last column, if the text doesn't all fit, you may have to scroll in order to see the padding.</p>
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paddingLeft():*
+		{ return _paddingLeft; }
+		public function set paddingLeft(newValue:*):void
+		{ _paddingLeft = _paddingLeftProperty.setHelper(_paddingLeft,newValue); }
+
+		/**
+		 * Top inset in pixels (adopts default value if undefined during cascade).
+		 * Space between the top edge of the container and the text.  Value is a Number.
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paddingTop():*
+		{ return _paddingTop; }
+		public function set paddingTop(newValue:*):void
+		{ _paddingTop = _paddingTopProperty.setHelper(_paddingTop,newValue); }
+
+		/**
+		 * Right inset in pixels (adopts default value if undefined during cascade).
+		 * Space between the right edge of the container and the text.  Value is a Number.
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paddingRight():*
+		{ return _paddingRight; }
+		public function set paddingRight(newValue:*):void
+		{ _paddingRight = _paddingRightProperty.setHelper(_paddingRight,newValue); }
+
+		/**
+		 * Botttom inset in pixels (adopts default value if undefined during cascade).
+		 * Space between the bottom edge of the container and the text.  Value is a Number. <p> With horizontal text, in scrollable containers with multiple columns, the first and following columns will show the padding as blank space at the bottom of the container, but for the last column, if the text doesn't all fit, you may have to scroll in order to see the padding.</p>
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paddingBottom():*
+		{ return _paddingBottom; }
+		public function set paddingBottom(newValue:*):void
+		{ _paddingBottom = _paddingBottomProperty.setHelper(_paddingBottom,newValue); }
+
+		/**
+		 * Number of text columns (adopts default value if undefined during cascade).
+		 * The column number overrides the  other column settings. Value is an integer, or <code>FormatValue.AUTO</code> if unspecified. If <code>columnCount</code> is not specified,<code>columnWidth</code> is used to create as many columns as can fit in the container.
+		 * <p>Legal values as a string are flashx.textLayout.formats.FormatValue.AUTO, flashx.textLayout.formats.FormatValue.INHERIT and from ints from 1 to 50.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.FormatValue
+		 */
+		public function get columnCount():*
+		{ return _columnCount; }
+		public function set columnCount(newValue:*):void
+		{ _columnCount = _columnCountProperty.setHelper(_columnCount,newValue); }
+
+		/**
+		 * Column width in pixels (adopts default value if undefined during cascade).
+		 * If you specify the width of the columns, but not the count, TextLayout will create as many columns of that width as possible, given the  container width and <code>columnGap</code> settings. Any remainder space is left after the last column. Value is a Number.
+		 * <p>Legal values as a string are flashx.textLayout.formats.FormatValue.AUTO, flashx.textLayout.formats.FormatValue.INHERIT and numbers from 0 to 8000.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.FormatValue
+		 */
+		public function get columnWidth():*
+		{ return _columnWidth; }
+		public function set columnWidth(newValue:*):void
+		{ _columnWidth = _columnWidthProperty.setHelper(_columnWidth,newValue); }
+
+		/**
+		 * Specifies the baseline position of the first line in the container. Which baseline this property refers to depends on the container-level locale.  For Japanese and Chinese, it is <code>TextBaseline.IDEOGRAPHIC_BOTTOM</code>; for all others it is <code>TextBaseline.ROMAN</code>.
+		 * The offset from the top inset (or right inset if <code>blockProgression</code> is RL) of the container to the baseline of the first line can be either <code>BaselineOffset.ASCENT</code>, meaning equal to the ascent of the line, <code>BaselineOffset.LINE_HEIGHT</code>, meaning equal to the height of that first line, or any fixed-value number to specify an absolute distance. <code>BaselineOffset.AUTO</code> aligns the ascent of the line with the container top inset.<p><img src='../../../images/textLayout_FBO1.png' alt='firstBaselineOffset1' /><img src='../../../images/textLayout_FBO2.png' alt='firstBaselineOffset2' /><img src='../../../images/textLayout_FBO3.png' alt='firstBaselineOffset3' /><img src='../../../images/textLayout_FBO4.png' alt='firstBaselineOffset4' /></p>
+		 * <p>Legal values as a string are flashx.textLayout.formats.BaselineOffset.AUTO, flashx.textLayout.formats.BaselineOffset.ASCENT, flashx.textLayout.formats.BaselineOffset.LINE_HEIGHT, flashx.textLayout.formats.FormatValue.INHERIT and numbers from 0 to 1000.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.BaselineOffset
+		 */
+		public function get firstBaselineOffset():*
+		{ return _firstBaselineOffset; }
+		public function set firstBaselineOffset(newValue:*):void
+		{ _firstBaselineOffset = _firstBaselineOffsetProperty.setHelper(_firstBaselineOffset,newValue); }
+
+		/**
+		 * Vertical alignment or justification (adopts default value if undefined during cascade).
+		 * Determines how TextFlow elements align within the container.
+		 * <p>Legal values are flashx.textLayout.formats.VerticalAlign.TOP, flashx.textLayout.formats.VerticalAlign.MIDDLE, flashx.textLayout.formats.VerticalAlign.BOTTOM, flashx.textLayout.formats.VerticalAlign.JUSTIFY, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of TOP.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.VerticalAlign
+		 */
+		public function get verticalAlign():*
+		{ return _verticalAlign; }
+		public function set verticalAlign(newValue:*):void
+		{ _verticalAlign = _verticalAlignProperty.setHelper(_verticalAlign,newValue); }
+
+		/**
+		 * Specifies a vertical or horizontal progression of line placement.
+		 * Lines are either placed top-to-bottom (<code>BlockProgression.TB</code>, used for horizontal text) or right-to-left (<code>BlockProgression.RL</code>, used for vertical text).
+		 * <p>Legal values are flashx.textLayout.formats.BlockProgression.RL, flashx.textLayout.formats.BlockProgression.TB, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of TB.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.BlockProgression
+		 */
+		public function get blockProgression():*
+		{ return _blockProgression; }
+		public function set blockProgression(newValue:*):void
+		{ _blockProgression = _blockProgressionProperty.setHelper(_blockProgression,newValue); }
+
+		/**
+		 * Controls word wrapping within the container (adopts default value if undefined during cascade).
+		 * Text in the container may be set to fit the width of the container (<code>LineBreak.TO_FIT</code>), or can be set to break only at explicit return or line feed characters (<code>LineBreak.EXPLICIT</code>).
+		 * <p>Legal values are flashx.textLayout.formats.LineBreak.EXPLICIT, flashx.textLayout.formats.LineBreak.TO_FIT, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of TO_FIT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.LineBreak
+		 */
+		public function get lineBreak():*
+		{ return _lineBreak; }
+		public function set lineBreak(newValue:*):void
+		{ _lineBreak = _lineBreakProperty.setHelper(_lineBreak,newValue); }
+
+		/**
+		 * Creates a new TextLayoutFormat object. All settings are empty or, optionally, are initialized from the
+		 * supplied <code>initialValues</code> object.
+		 * 
+		 * @param initialValues optional instance from which to copy initial values.
+		 * 
+		 * @see #defaultFormat
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function TextLayoutFormat(initialValues:ITextLayoutFormat = null)
+		{
+			if (initialValues)
+				apply(initialValues)
+		}
+
+		/**
+		 * Copies TextLayoutFormat settings from the <code>values</code> ITextLayoutFormat instance into this TextLayoutFormat object.
+		 * If <code>values</code> is <code>null</code>, this TextLayoutFormat object is initialized with undefined values for all properties.
+		 * @param values optional instance from which to copy values.
+		 * 
+		 * @includeExample examples\TextLayoutFormat_copyExample.as -noswf
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function copy(values:ITextLayoutFormat):void
+		{
+			 if (values == null)
+				values = emptyTextLayoutFormat;
+			this.color = values.color;
+			this.backgroundColor = values.backgroundColor;
+			this.lineThrough = values.lineThrough;
+			this.textAlpha = values.textAlpha;
+			this.backgroundAlpha = values.backgroundAlpha;
+			this.fontSize = values.fontSize;
+			this.baselineShift = values.baselineShift;
+			this.trackingLeft = values.trackingLeft;
+			this.trackingRight = values.trackingRight;
+			this.lineHeight = values.lineHeight;
+			this.breakOpportunity = values.breakOpportunity;
+			this.digitCase = values.digitCase;
+			this.digitWidth = values.digitWidth;
+			this.dominantBaseline = values.dominantBaseline;
+			this.kerning = values.kerning;
+			this.ligatureLevel = values.ligatureLevel;
+			this.alignmentBaseline = values.alignmentBaseline;
+			this.locale = values.locale;
+			this.typographicCase = values.typographicCase;
+			this.fontFamily = values.fontFamily;
+			this.textDecoration = values.textDecoration;
+			this.fontWeight = values.fontWeight;
+			this.fontStyle = values.fontStyle;
+			this.whiteSpaceCollapse = values.whiteSpaceCollapse;
+			this.renderingMode = values.renderingMode;
+			this.cffHinting = values.cffHinting;
+			this.fontLookup = values.fontLookup;
+			this.textRotation = values.textRotation;
+			this.textIndent = values.textIndent;
+			this.paragraphStartIndent = values.paragraphStartIndent;
+			this.paragraphEndIndent = values.paragraphEndIndent;
+			this.paragraphSpaceBefore = values.paragraphSpaceBefore;
+			this.paragraphSpaceAfter = values.paragraphSpaceAfter;
+			this.textAlign = values.textAlign;
+			this.textAlignLast = values.textAlignLast;
+			this.textJustify = values.textJustify;
+			this.justificationRule = values.justificationRule;
+			this.justificationStyle = values.justificationStyle;
+			this.direction = values.direction;
+			this.tabStops = values.tabStops;
+			this.leadingModel = values.leadingModel;
+			this.columnGap = values.columnGap;
+			this.paddingLeft = values.paddingLeft;
+			this.paddingTop = values.paddingTop;
+			this.paddingRight = values.paddingRight;
+			this.paddingBottom = values.paddingBottom;
+			this.columnCount = values.columnCount;
+			this.columnWidth = values.columnWidth;
+			this.firstBaselineOffset = values.firstBaselineOffset;
+			this.verticalAlign = values.verticalAlign;
+			this.blockProgression = values.blockProgression;
+			this.lineBreak = values.lineBreak;
+		}
+
+		/**
+		 * Concatenates the values of properties in the <code>incoming</code> ITextLayoutFormat instance
+		 * with the values of this TextLayoutFormat object. In this (the receiving) TextLayoutFormat object, properties whose values are <code>FormatValue.INHERIT</code>,
+		 * and inheriting properties whose values are <code>undefined</code> will get new values from the <code>incoming</code> object.
+		 * Non-inheriting properties whose values are <code>undefined</code> will get their default values.
+		 * All other property values will remain unmodified.
+		 * 
+		 * @param incoming instance from which values are concatenated.
+		 * @see flashx.textLayout.formats.FormatValue#INHERIT
+		 * 
+		 * @includeExample examples\TextLayoutFormat_concatExample.as -noswf
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function concat(incoming:ITextLayoutFormat):void
+		{
+			var holder:TextLayoutFormatValueHolder = incoming as TextLayoutFormatValueHolder;
+			if (holder)
+			{
+					for (var key:String in holder.coreStyles)
+					{
+						this[key] = description[key].concatHelper(this[key],holder.coreStyles[key]);
+				}
+				return;
+			}
+			this.color = _colorProperty.concatHelper(this.color, incoming.color);
+			this.backgroundColor = _backgroundColorProperty.concatHelper(this.backgroundColor, incoming.backgroundColor);
+			this.lineThrough = _lineThroughProperty.concatHelper(this.lineThrough, incoming.lineThrough);
+			this.textAlpha = _textAlphaProperty.concatHelper(this.textAlpha, incoming.textAlpha);
+			this.backgroundAlpha = _backgroundAlphaProperty.concatHelper(this.backgroundAlpha, incoming.backgroundAlpha);
+			this.fontSize = _fontSizeProperty.concatHelper(this.fontSize, incoming.fontSize);
+			this.baselineShift = _baselineShiftProperty.concatHelper(this.baselineShift, incoming.baselineShift);
+			this.trackingLeft = _trackingLeftProperty.concatHelper(this.trackingLeft, incoming.trackingLeft);
+			this.trackingRight = _trackingRightProperty.concatHelper(this.trackingRight, incoming.trackingRight);
+			this.lineHeight = _lineHeightProperty.concatHelper(this.lineHeight, incoming.lineHeight);
+			this.breakOpportunity = _breakOpportunityProperty.concatHelper(this.breakOpportunity, incoming.breakOpportunity);
+			this.digitCase = _digitCaseProperty.concatHelper(this.digitCase, incoming.digitCase);
+			this.digitWidth = _digitWidthProperty.concatHelper(this.digitWidth, incoming.digitWidth);
+			this.dominantBaseline = _dominantBaselineProperty.concatHelper(this.dominantBaseline, incoming.dominantBaseline);
+			this.kerning = _kerningProperty.concatHelper(this.kerning, incoming.kerning);
+			this.ligatureLevel = _ligatureLevelProperty.concatHelper(this.ligatureLevel, incoming.ligatureLevel);
+			this.alignmentBaseline = _alignmentBaselineProperty.concatHelper(this.alignmentBaseline, incoming.alignmentBaseline);
+			this.locale = _localeProperty.concatHelper(this.locale, incoming.locale);
+			this.typographicCase = _typographicCaseProperty.concatHelper(this.typographicCase, incoming.typographicCase);
+			this.fontFamily = _fontFamilyProperty.concatHelper(this.fontFamily, incoming.fontFamily);
+			this.textDecoration = _textDecorationProperty.concatHelper(this.textDecoration, incoming.textDecoration);
+			this.fontWeight = _fontWeightProperty.concatHelper(this.fontWeight, incoming.fontWeight);
+			this.fontStyle = _fontStyleProperty.concatHelper(this.fontStyle, incoming.fontStyle);
+			this.whiteSpaceCollapse = _whiteSpaceCollapseProperty.concatHelper(this.whiteSpaceCollapse, incoming.whiteSpaceCollapse);
+			this.renderingMode = _renderingModeProperty.concatHelper(this.renderingMode, incoming.renderingMode);
+			this.cffHinting = _cffHintingProperty.concatHelper(this.cffHinting, incoming.cffHinting);
+			this.fontLookup = _fontLookupProperty.concatHelper(this.fontLookup, incoming.fontLookup);
+			this.textRotation = _textRotationProperty.concatHelper(this.textRotation, incoming.textRotation);
+			this.textIndent = _textIndentProperty.concatHelper(this.textIndent, incoming.textIndent);
+			this.paragraphStartIndent = _paragraphStartIndentProperty.concatHelper(this.paragraphStartIndent, incoming.paragraphStartIndent);
+			this.paragraphEndIndent = _paragraphEndIndentProperty.concatHelper(this.paragraphEndIndent, incoming.paragraphEndIndent);
+			this.paragraphSpaceBefore = _paragraphSpaceBeforeProperty.concatHelper(this.paragraphSpaceBefore, incoming.paragraphSpaceBefore);
+			this.paragraphSpaceAfter = _paragraphSpaceAfterProperty.concatHelper(this.paragraphSpaceAfter, incoming.paragraphSpaceAfter);
+			this.textAlign = _textAlignProperty.concatHelper(this.textAlign, incoming.textAlign);
+			this.textAlignLast = _textAlignLastProperty.concatHelper(this.textAlignLast, incoming.textAlignLast);
+			this.textJustify = _textJustifyProperty.concatHelper(this.textJustify, incoming.textJustify);
+			this.justificationRule = _justificationRuleProperty.concatHelper(this.justificationRule, incoming.justificationRule);
+			this.justificationStyle = _justificationStyleProperty.concatHelper(this.justificationStyle, incoming.justificationStyle);
+			this.direction = _directionProperty.concatHelper(this.direction, incoming.direction);
+			this.tabStops = _tabStopsProperty.concatHelper(this.tabStops, incoming.tabStops);
+			this.leadingModel = _leadingModelProperty.concatHelper(this.leadingModel, incoming.leadingModel);
+			this.columnGap = _columnGapProperty.concatHelper(this.columnGap, incoming.columnGap);
+			this.paddingLeft = _paddingLeftProperty.concatHelper(this.paddingLeft, incoming.paddingLeft);
+			this.paddingTop = _paddingTopProperty.concatHelper(this.paddingTop, incoming.paddingTop);
+			this.paddingRight = _paddingRightProperty.concatHelper(this.paddingRight, incoming.paddingRight);
+			this.paddingBottom = _paddingBottomProperty.concatHelper(this.paddingBottom, incoming.paddingBottom);
+			this.columnCount = _columnCountProperty.concatHelper(this.columnCount, incoming.columnCount);
+			this.columnWidth = _columnWidthProperty.concatHelper(this.columnWidth, incoming.columnWidth);
+			this.firstBaselineOffset = _firstBaselineOffsetProperty.concatHelper(this.firstBaselineOffset, incoming.firstBaselineOffset);
+			this.verticalAlign = _verticalAlignProperty.concatHelper(this.verticalAlign, incoming.verticalAlign);
+			this.blockProgression = _blockProgressionProperty.concatHelper(this.blockProgression, incoming.blockProgression);
+			this.lineBreak = _lineBreakProperty.concatHelper(this.lineBreak, incoming.lineBreak);
+		}
+
+		/**
+		 * Concatenates the values of properties in the <code>incoming</code> ITextLayoutFormat instance
+		 * with the values of this TextLayoutFormat object. In this (the receiving) TextLayoutFormat object, properties whose values are <code>FormatValue.INHERIT</code>,
+		 * and inheriting properties whose values are <code>undefined</code> will get new values from the <code>incoming</code> object.
+		 * All other property values will remain unmodified.
+		 * 
+		 * @param incoming instance from which values are concatenated.
+		 * @see flashx.textLayout.formats.FormatValue#INHERIT
+		 * 
+		 * @includeExample examples\TextLayoutFormat_concatInheritOnlyExample.as -noswf
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function concatInheritOnly(incoming:ITextLayoutFormat):void
+		{
+			var holder:TextLayoutFormatValueHolder = incoming as TextLayoutFormatValueHolder;
+			if (holder)
+			{
+					for (var key:String in holder.coreStyles)
+					{
+						this[key] = description[key].concatInheritOnlyHelper(this[key],holder.coreStyles[key]);
+				}
+				return;
+			}
+			this.color = _colorProperty.concatInheritOnlyHelper(this.color, incoming.color);
+			this.backgroundColor = _backgroundColorProperty.concatInheritOnlyHelper(this.backgroundColor, incoming.backgroundColor);
+			this.lineThrough = _lineThroughProperty.concatInheritOnlyHelper(this.lineThrough, incoming.lineThrough);
+			this.textAlpha = _textAlphaProperty.concatInheritOnlyHelper(this.textAlpha, incoming.textAlpha);
+			this.backgroundAlpha = _backgroundAlphaProperty.concatInheritOnlyHelper(this.backgroundAlpha, incoming.backgroundAlpha);
+			this.fontSize = _fontSizeProperty.concatInheritOnlyHelper(this.fontSize, incoming.fontSize);
+			this.baselineShift = _baselineShiftProperty.concatInheritOnlyHelper(this.baselineShift, incoming.baselineShift);
+			this.trackingLeft = _trackingLeftProperty.concatInheritOnlyHelper(this.trackingLeft, incoming.trackingLeft);
+			this.trackingRight = _trackingRightProperty.concatInheritOnlyHelper(this.trackingRight, incoming.trackingRight);
+			this.lineHeight = _lineHeightProperty.concatInheritOnlyHelper(this.lineHeight, incoming.lineHeight);
+			this.breakOpportunity = _breakOpportunityProperty.concatInheritOnlyHelper(this.breakOpportunity, incoming.breakOpportunity);
+			this.digitCase = _digitCaseProperty.concatInheritOnlyHelper(this.digitCase, incoming.digitCase);
+			this.digitWidth = _digitWidthProperty.concatInheritOnlyHelper(this.digitWidth, incoming.digitWidth);
+			this.dominantBaseline = _dominantBaselineProperty.concatInheritOnlyHelper(this.dominantBaseline, incoming.dominantBaseline);
+			this.kerning = _kerningProperty.concatInheritOnlyHelper(this.kerning, incoming.kerning);
+			this.ligatureLevel = _ligatureLevelProperty.concatInheritOnlyHelper(this.ligatureLevel, incoming.ligatureLevel);
+			this.alignmentBaseline = _alignmentBaselineProperty.concatInheritOnlyHelper(this.alignmentBaseline, incoming.alignmentBaseline);
+			this.locale = _localeProperty.concatInheritOnlyHelper(this.locale, incoming.locale);
+			this.typographicCase = _typographicCaseProperty.concatInheritOnlyHelper(this.typographicCase, incoming.typographicCase);
+			this.fontFamily = _fontFamilyProperty.concatInheritOnlyHelper(this.fontFamily, incoming.fontFamily);
+			this.textDecoration = _textDecorationProperty.concatInheritOnlyHelper(this.textDecoration, incoming.textDecoration);
+			this.fontWeight = _fontWeightProperty.concatInheritOnlyHelper(this.fontWeight, incoming.fontWeight);
+			this.fontStyle = _fontStyleProperty.concatInheritOnlyHelper(this.fontStyle, incoming.fontStyle);
+			this.whiteSpaceCollapse = _whiteSpaceCollapseProperty.concatInheritOnlyHelper(this.whiteSpaceCollapse, incoming.whiteSpaceCollapse);
+			this.renderingMode = _renderingModeProperty.concatInheritOnlyHelper(this.renderingMode, incoming.renderingMode);
+			this.cffHinting = _cffHintingProperty.concatInheritOnlyHelper(this.cffHinting, incoming.cffHinting);
+			this.fontLookup = _fontLookupProperty.concatInheritOnlyHelper(this.fontLookup, incoming.fontLookup);
+			this.textRotation = _textRotationProperty.concatInheritOnlyHelper(this.textRotation, incoming.textRotation);
+			this.textIndent = _textIndentProperty.concatInheritOnlyHelper(this.textIndent, incoming.textIndent);
+			this.paragraphStartIndent = _paragraphStartIndentProperty.concatInheritOnlyHelper(this.paragraphStartIndent, incoming.paragraphStartIndent);
+			this.paragraphEndIndent = _paragraphEndIndentProperty.concatInheritOnlyHelper(this.paragraphEndIndent, incoming.paragraphEndIndent);
+			this.paragraphSpaceBefore = _paragraphSpaceBeforeProperty.concatInheritOnlyHelper(this.paragraphSpaceBefore, incoming.paragraphSpaceBefore);
+			this.paragraphSpaceAfter = _paragraphSpaceAfterProperty.concatInheritOnlyHelper(this.paragraphSpaceAfter, incoming.paragraphSpaceAfter);
+			this.textAlign = _textAlignProperty.concatInheritOnlyHelper(this.textAlign, incoming.textAlign);
+			this.textAlignLast = _textAlignLastProperty.concatInheritOnlyHelper(this.textAlignLast, incoming.textAlignLast);
+			this.textJustify = _textJustifyProperty.concatInheritOnlyHelper(this.textJustify, incoming.textJustify);
+			this.justificationRule = _justificationRuleProperty.concatInheritOnlyHelper(this.justificationRule, incoming.justificationRule);
+			this.justificationStyle = _justificationStyleProperty.concatInheritOnlyHelper(this.justificationStyle, incoming.justificationStyle);
+			this.direction = _directionProperty.concatInheritOnlyHelper(this.direction, incoming.direction);
+			this.tabStops = _tabStopsProperty.concatInheritOnlyHelper(this.tabStops, incoming.tabStops);
+			this.leadingModel = _leadingModelProperty.concatInheritOnlyHelper(this.leadingModel, incoming.leadingModel);
+			this.columnGap = _columnGapProperty.concatInheritOnlyHelper(this.columnGap, incoming.columnGap);
+			this.paddingLeft = _paddingLeftProperty.concatInheritOnlyHelper(this.paddingLeft, incoming.paddingLeft);
+			this.paddingTop = _paddingTopProperty.concatInheritOnlyHelper(this.paddingTop, incoming.paddingTop);
+			this.paddingRight = _paddingRightProperty.concatInheritOnlyHelper(this.paddingRight, incoming.paddingRight);
+			this.paddingBottom = _paddingBottomProperty.concatInheritOnlyHelper(this.paddingBottom, incoming.paddingBottom);
+			this.columnCount = _columnCountProperty.concatInheritOnlyHelper(this.columnCount, incoming.columnCount);
+			this.columnWidth = _columnWidthProperty.concatInheritOnlyHelper(this.columnWidth, incoming.columnWidth);
+			this.firstBaselineOffset = _firstBaselineOffsetProperty.concatInheritOnlyHelper(this.firstBaselineOffset, incoming.firstBaselineOffset);
+			this.verticalAlign = _verticalAlignProperty.concatInheritOnlyHelper(this.verticalAlign, incoming.verticalAlign);
+			this.blockProgression = _blockProgressionProperty.concatInheritOnlyHelper(this.blockProgression, incoming.blockProgression);
+			this.lineBreak = _lineBreakProperty.concatInheritOnlyHelper(this.lineBreak, incoming.lineBreak);
+		}
+
+		/**
+		 * Replaces property values in this TextLayoutFormat object with the values of properties that are set in
+		 * the <code>incoming</code> ITextLayoutFormat instance. Properties that are <code>undefined</code> in the <code>incoming</code>
+		 * ITextLayoutFormat instance are not changed in this object.
+		 * 
+		 * @param incoming instance whose property values are applied to this TextLayoutFormat object.
+		 * 
+		 * @includeExample examples\TextLayoutFormat_applyExample.as -noswf
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function apply(incoming:ITextLayoutFormat):void
+		{
+			var val:*;
+
+			var holder:TextLayoutFormatValueHolder = incoming as TextLayoutFormatValueHolder;
+			if (holder)
+			{
+					for (var key:String in holder.coreStyles)
+					{
+						CONFIG::debug { assert(holder.coreStyles[key] !== undefined,"bad value in apply"); }
+						this[key] = holder.coreStyles[key];
+				}
+				return;
+			}
+
+			if ((val = incoming.color) !== undefined)
+				this.color = val;
+			if ((val = incoming.backgroundColor) !== undefined)
+				this.backgroundColor = val;
+			if ((val = incoming.lineThrough) !== undefined)
+				this.lineThrough = val;
+			if ((val = incoming.textAlpha) !== undefined)
+				this.textAlpha = val;
+			if ((val = incoming.backgroundAlpha) !== undefined)
+				this.backgroundAlpha = val;
+			if ((val = incoming.fontSize) !== undefined)
+				this.fontSize = val;
+			if ((val = incoming.baselineShift) !== undefined)
+				this.baselineShift = val;
+			if ((val = incoming.trackingLeft) !== undefined)
+				this.trackingLeft = val;
+			if ((val = incoming.trackingRight) !== undefined)
+				this.trackingRight = val;
+			if ((val = incoming.lineHeight) !== undefined)
+				this.lineHeight = val;
+			if ((val = incoming.breakOpportunity) !== undefined)
+				this.breakOpportunity = val;
+			if ((val = incoming.digitCase) !== undefined)
+				this.digitCase = val;
+			if ((val = incoming.digitWidth) !== undefined)
+				this.digitWidth = val;
+			if ((val = incoming.dominantBaseline) !== undefined)
+				this.dominantBaseline = val;
+			if ((val = incoming.kerning) !== undefined)
+				this.kerning = val;
+			if ((val = incoming.ligatureLevel) !== undefined)
+				this.ligatureLevel = val;
+			if ((val = incoming.alignmentBaseline) !== undefined)
+				this.alignmentBaseline = val;
+			if ((val = incoming.locale) !== undefined)
+				this.locale = val;
+			if ((val = incoming.typographicCase) !== undefined)
+				this.typographicCase = val;
+			if ((val = incoming.fontFamily) !== undefined)
+				this.fontFamily = val;
+			if ((val = incoming.textDecoration) !== undefined)
+				this.textDecoration = val;
+			if ((val = incoming.fontWeight) !== undefined)
+				this.fontWeight = val;
+			if ((val = incoming.fontStyle) !== undefined)
+				this.fontStyle = val;
+			if ((val = incoming.whiteSpaceCollapse) !== undefined)
+				this.whiteSpaceCollapse = val;
+			if ((val = incoming.renderingMode) !== undefined)
+				this.renderingMode = val;
+			if ((val = incoming.cffHinting) !== undefined)
+				this.cffHinting = val;
+			if ((val = incoming.fontLookup) !== undefined)
+				this.fontLookup = val;
+			if ((val = incoming.textRotation) !== undefined)
+				this.textRotation = val;
+			if ((val = incoming.textIndent) !== undefined)
+				this.textIndent = val;
+			if ((val = incoming.paragraphStartIndent) !== undefined)
+				this.paragraphStartIndent = val;
+			if ((val = incoming.paragraphEndIndent) !== undefined)
+				this.paragraphEndIndent = val;
+			if ((val = incoming.paragraphSpaceBefore) !== undefined)
+				this.paragraphSpaceBefore = val;
+			if ((val = incoming.paragraphSpaceAfter) !== undefined)
+				this.paragraphSpaceAfter = val;
+			if ((val = incoming.textAlign) !== undefined)
+				this.textAlign = val;
+			if ((val = incoming.textAlignLast) !== undefined)
+				this.textAlignLast = val;
+			if ((val = incoming.textJustify) !== undefined)
+				this.textJustify = val;
+			if ((val = incoming.justificationRule) !== undefined)
+				this.justificationRule = val;
+			if ((val = incoming.justificationStyle) !== undefined)
+				this.justificationStyle = val;
+			if ((val = incoming.direction) !== undefined)
+				this.direction = val;
+			if ((val = incoming.tabStops) !== undefined)
+				this.tabStops = val;
+			if ((val = incoming.leadingModel) !== undefined)
+				this.leadingModel = val;
+			if ((val = incoming.columnGap) !== undefined)
+				this.columnGap = val;
+			if ((val = incoming.paddingLeft) !== undefined)
+				this.paddingLeft = val;
+			if ((val = incoming.paddingTop) !== undefined)
+				this.paddingTop = val;
+			if ((val = incoming.paddingRight) !== undefined)
+				this.paddingRight = val;
+			if ((val = incoming.paddingBottom) !== undefined)
+				this.paddingBottom = val;
+			if ((val = incoming.columnCount) !== undefined)
+				this.columnCount = val;
+			if ((val = incoming.columnWidth) !== undefined)
+				this.columnWidth = val;
+			if ((val = incoming.firstBaselineOffset) !== undefined)
+				this.firstBaselineOffset = val;
+			if ((val = incoming.verticalAlign) !== undefined)
+				this.verticalAlign = val;
+			if ((val = incoming.blockProgression) !== undefined)
+				this.blockProgression = val;
+			if ((val = incoming.lineBreak) !== undefined)
+				this.lineBreak = val;
+		}
+
+		/**
+		 * Compares properties in ITextLayoutFormat instance <code>p1</code> with properties in ITextLayoutFormat instance <code>p2</code>
+		 * and returns <code>true</code> if all properties match.
+		 * 
+		 * @param p1 instance to compare to <code>p2</code>.
+		 * @param p2 instance to compare to <code>p1</code>.
+		 * 
+		 * @return true if all properties match, false otherwise.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		static public function isEqual(p1:ITextLayoutFormat,p2:ITextLayoutFormat):Boolean
+		{
+			if (p1 == null)
+				p1 = emptyTextLayoutFormat;
+			if (p2 == null)
+				p2 = emptyTextLayoutFormat;
+			if (p1 == p2)
+				return true;
+			var p1Holder:TextLayoutFormatValueHolder = p1 as TextLayoutFormatValueHolder;
+			var p2Holder:TextLayoutFormatValueHolder = p2 as TextLayoutFormatValueHolder;
+			if (p1Holder && p2Holder)
+				return Property.equalCoreStyles(p1Holder.coreStyles,p2Holder.coreStyles,TextLayoutFormat.description);
+
+			if (!_colorProperty.equalHelper(p1.color, p2.color))
+				return false;
+			if (!_backgroundColorProperty.equalHelper(p1.backgroundColor, p2.backgroundColor))
+				return false;
+			if (!_lineThroughProperty.equalHelper(p1.lineThrough, p2.lineThrough))
+				return false;
+			if (!_textAlphaProperty.equalHelper(p1.textAlpha, p2.textAlpha))
+				return false;
+			if (!_backgroundAlphaProperty.equalHelper(p1.backgroundAlpha, p2.backgroundAlpha))
+				return false;
+			if (!_fontSizeProperty.equalHelper(p1.fontSize, p2.fontSize))
+				return false;
+			if (!_baselineShiftProperty.equalHelper(p1.baselineShift, p2.baselineShift))
+				return false;
+			if (!_trackingLeftProperty.equalHelper(p1.trackingLeft, p2.trackingLeft))
+				return false;
+			if (!_trackingRightProperty.equalHelper(p1.trackingRight, p2.trackingRight))
+				return false;
+			if (!_lineHeightProperty.equalHelper(p1.lineHeight, p2.lineHeight))
+				return false;
+			if (!_breakOpportunityProperty.equalHelper(p1.breakOpportunity, p2.breakOpportunity))
+				return false;
+			if (!_digitCaseProperty.equalHelper(p1.digitCase, p2.digitCase))
+				return false;
+			if (!_digitWidthProperty.equalHelper(p1.digitWidth, p2.digitWidth))
+				return false;
+			if (!_dominantBaselineProperty.equalHelper(p1.dominantBaseline, p2.dominantBaseline))
+				return false;
+			if (!_kerningProperty.equalHelper(p1.kerning, p2.kerning))
+				return false;
+			if (!_ligatureLevelProperty.equalHelper(p1.ligatureLevel, p2.ligatureLevel))
+				return false;
+			if (!_alignmentBaselineProperty.equalHelper(p1.alignmentBaseline, p2.alignmentBaseline))
+				return false;
+			if (!_localeProperty.equalHelper(p1.locale, p2.locale))
+				return false;
+			if (!_typographicCaseProperty.equalHelper(p1.typographicCase, p2.typographicCase))
+				return false;
+			if (!_fontFamilyProperty.equalHelper(p1.fontFamily, p2.fontFamily))
+				return false;
+			if (!_textDecorationProperty.equalHelper(p1.textDecoration, p2.textDecoration))
+				return false;
+			if (!_fontWeightProperty.equalHelper(p1.fontWeight, p2.fontWeight))
+				return false;
+			if (!_fontStyleProperty.equalHelper(p1.fontStyle, p2.fontStyle))
+				return false;
+			if (!_whiteSpaceCollapseProperty.equalHelper(p1.whiteSpaceCollapse, p2.whiteSpaceCollapse))
+				return false;
+			if (!_renderingModeProperty.equalHelper(p1.renderingMode, p2.renderingMode))
+				return false;
+			if (!_cffHintingProperty.equalHelper(p1.cffHinting, p2.cffHinting))
+				return false;
+			if (!_fontLookupProperty.equalHelper(p1.fontLookup, p2.fontLookup))
+				return false;
+			if (!_textRotationProperty.equalHelper(p1.textRotation, p2.textRotation))
+				return false;
+			if (!_textIndentProperty.equalHelper(p1.textIndent, p2.textIndent))
+				return false;
+			if (!_paragraphStartIndentProperty.equalHelper(p1.paragraphStartIndent, p2.paragraphStartIndent))
+				return false;
+			if (!_paragraphEndIndentProperty.equalHelper(p1.paragraphEndIndent, p2.paragraphEndIndent))
+				return false;
+			if (!_paragraphSpaceBeforeProperty.equalHelper(p1.paragraphSpaceBefore, p2.paragraphSpaceBefore))
+				return false;
+			if (!_paragraphSpaceAfterProperty.equalHelper(p1.paragraphSpaceAfter, p2.paragraphSpaceAfter))
+				return false;
+			if (!_textAlignProperty.equalHelper(p1.textAlign, p2.textAlign))
+				return false;
+			if (!_textAlignLastProperty.equalHelper(p1.textAlignLast, p2.textAlignLast))
+				return false;
+			if (!_textJustifyProperty.equalHelper(p1.textJustify, p2.textJustify))
+				return false;
+			if (!_justificationRuleProperty.equalHelper(p1.justificationRule, p2.justificationRule))
+				return false;
+			if (!_justificationStyleProperty.equalHelper(p1.justificationStyle, p2.justificationStyle))
+				return false;
+			if (!_directionProperty.equalHelper(p1.direction, p2.direction))
+				return false;
+			if (!_tabStopsProperty.equalHelper(p1.tabStops, p2.tabStops))
+				return false;
+			if (!_leadingModelProperty.equalHelper(p1.leadingModel, p2.leadingModel))
+				return false;
+			if (!_columnGapProperty.equalHelper(p1.columnGap, p2.columnGap))
+				return false;
+			if (!_paddingLeftProperty.equalHelper(p1.paddingLeft, p2.paddingLeft))
+				return false;
+			if (!_paddingTopProperty.equalHelper(p1.paddingTop, p2.paddingTop))
+				return false;
+			if (!_paddingRightProperty.equalHelper(p1.paddingRight, p2.paddingRight))
+				return false;
+			if (!_paddingBottomProperty.equalHelper(p1.paddingBottom, p2.paddingBottom))
+				return false;
+			if (!_columnCountProperty.equalHelper(p1.columnCount, p2.columnCount))
+				return false;
+			if (!_columnWidthProperty.equalHelper(p1.columnWidth, p2.columnWidth))
+				return false;
+			if (!_firstBaselineOffsetProperty.equalHelper(p1.firstBaselineOffset, p2.firstBaselineOffset))
+				return false;
+			if (!_verticalAlignProperty.equalHelper(p1.verticalAlign, p2.verticalAlign))
+				return false;
+			if (!_blockProgressionProperty.equalHelper(p1.blockProgression, p2.blockProgression))
+				return false;
+			if (!_lineBreakProperty.equalHelper(p1.lineBreak, p2.lineBreak))
+				return false;
+
+			return true;
+		}
+
+		/**
+		 * Sets properties in this TextLayoutFormat object to <code>undefined</code> if they match those in the <code>incoming</code>
+		 * ITextLayoutFormat instance.
+		 * 
+		 * @param incoming instance against which to compare this TextLayoutFormat object's property values.
+		 * 
+		 * @includeExample examples\TextLayoutFormat_removeMatchingExample.as -noswf
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function removeMatching(incoming:ITextLayoutFormat):void
+		{
+			if (incoming == null)
+				return;
+
+			var holder:TextLayoutFormatValueHolder = incoming as TextLayoutFormatValueHolder;
+			if (holder)
+			{
+					for (var key:String in holder.coreStyles)
+					{
+						CONFIG::debug { assert(holder.coreStyles[key] !== undefined,"bad value in removeMatching"); }
+						if (description[key].equalHelper(this[key],holder.coreStyles[key]))
+							this[key] = undefined;
+				}
+				return;
+			}
+
+			if (_colorProperty.equalHelper(this.color, incoming.color))
+				this.color = undefined;
+			if (_backgroundColorProperty.equalHelper(this.backgroundColor, incoming.backgroundColor))
+				this.backgroundColor = undefined;
+			if (_lineThroughProperty.equalHelper(this.lineThrough, incoming.lineThrough))
+				this.lineThrough = undefined;
+			if (_textAlphaProperty.equalHelper(this.textAlpha, incoming.textAlpha))
+				this.textAlpha = undefined;
+			if (_backgroundAlphaProperty.equalHelper(this.backgroundAlpha, incoming.backgroundAlpha))
+				this.backgroundAlpha = undefined;
+			if (_fontSizeProperty.equalHelper(this.fontSize, incoming.fontSize))
+				this.fontSize = undefined;
+			if (_baselineShiftProperty.equalHelper(this.baselineShift, incoming.baselineShift))
+				this.baselineShift = undefined;
+			if (_trackingLeftProperty.equalHelper(this.trackingLeft, incoming.trackingLeft))
+				this.trackingLeft = undefined;
+			if (_trackingRightProperty.equalHelper(this.trackingRight, incoming.trackingRight))
+				this.trackingRight = undefined;
+			if (_lineHeightProperty.equalHelper(this.lineHeight, incoming.lineHeight))
+				this.lineHeight = undefined;
+			if (_breakOpportunityProperty.equalHelper(this.breakOpportunity, incoming.breakOpportunity))
+				this.breakOpportunity = undefined;
+			if (_digitCaseProperty.equalHelper(this.digitCase, incoming.digitCase))
+				this.digitCase = undefined;
+			if (_digitWidthProperty.equalHelper(this.digitWidth, incoming.digitWidth))
+				this.digitWidth = undefined;
+			if (_dominantBaselineProperty.equalHelper(this.dominantBaseline, incoming.dominantBaseline))
+				this.dominantBaseline = undefined;
+			if (_kerningProperty.equalHelper(this.kerning, incoming.kerning))
+				this.kerning = undefined;
+			if (_ligatureLevelProperty.equalHelper(this.ligatureLevel, incoming.ligatureLevel))
+				this.ligatureLevel = undefined;
+			if (_alignmentBaselineProperty.equalHelper(this.alignmentBaseline, incoming.alignmentBaseline))
+				this.alignmentBaseline = undefined;
+			if (_localeProperty.equalHelper(this.locale, incoming.locale))
+				this.locale = undefined;
+			if (_typographicCaseProperty.equalHelper(this.typographicCase, incoming.typographicCase))
+				this.typographicCase = undefined;
+			if (_fontFamilyProperty.equalHelper(this.fontFamily, incoming.fontFamily))
+				this.fontFamily = undefined;
+			if (_textDecorationProperty.equalHelper(this.textDecoration, incoming.textDecoration))
+				this.textDecoration = undefined;
+			if (_fontWeightProperty.equalHelper(this.fontWeight, incoming.fontWeight))
+				this.fontWeight = undefined;
+			if (_fontStyleProperty.equalHelper(this.fontStyle, incoming.fontStyle))
+				this.fontStyle = undefined;
+			if (_whiteSpaceCollapseProperty.equalHelper(this.whiteSpaceCollapse, incoming.whiteSpaceCollapse))
+				this.whiteSpaceCollapse = undefined;
+			if (_renderingModeProperty.equalHelper(this.renderingMode, incoming.renderingMode))
+				this.renderingMode = undefined;
+			if (_cffHintingProperty.equalHelper(this.cffHinting, incoming.cffHinting))
+				this.cffHinting = undefined;
+			if (_fontLookupProperty.equalHelper(this.fontLookup, incoming.fontLookup))
+				this.fontLookup = undefined;
+			if (_textRotationProperty.equalHelper(this.textRotation, incoming.textRotation))
+				this.textRotation = undefined;
+			if (_textIndentProperty.equalHelper(this.textIndent, incoming.textIndent))
+				this.textIndent = undefined;
+			if (_paragraphStartIndentProperty.equalHelper(this.paragraphStartIndent, incoming.paragraphStartIndent))
+				this.paragraphStartIndent = undefined;
+			if (_paragraphEndIndentProperty.equalHelper(this.paragraphEndIndent, incoming.paragraphEndIndent))
+				this.paragraphEndIndent = undefined;
+			if (_paragraphSpaceBeforeProperty.equalHelper(this.paragraphSpaceBefore, incoming.paragraphSpaceBefore))
+				this.paragraphSpaceBefore = undefined;
+			if (_paragraphSpaceAfterProperty.equalHelper(this.paragraphSpaceAfter, incoming.paragraphSpaceAfter))
+				this.paragraphSpaceAfter = undefined;
+			if (_textAlignProperty.equalHelper(this.textAlign, incoming.textAlign))
+				this.textAlign = undefined;
+			if (_textAlignLastProperty.equalHelper(this.textAlignLast, incoming.textAlignLast))
+				this.textAlignLast = undefined;
+			if (_textJustifyProperty.equalHelper(this.textJustify, incoming.textJustify))
+				this.textJustify = undefined;
+			if (_justificationRuleProperty.equalHelper(this.justificationRule, incoming.justificationRule))
+				this.justificationRule = undefined;
+			if (_justificationStyleProperty.equalHelper(this.justificationStyle, incoming.justificationStyle))
+				this.justificationStyle = undefined;
+			if (_directionProperty.equalHelper(this.direction, incoming.direction))
+				this.direction = undefined;
+			if (_tabStopsProperty.equalHelper(this.tabStops, incoming.tabStops))
+				this.tabStops = undefined;
+			if (_leadingModelProperty.equalHelper(this.leadingModel, incoming.leadingModel))
+				this.leadingModel = undefined;
+			if (_columnGapProperty.equalHelper(this.columnGap, incoming.columnGap))
+				this.columnGap = undefined;
+			if (_paddingLeftProperty.equalHelper(this.paddingLeft, incoming.paddingLeft))
+				this.paddingLeft = undefined;
+			if (_paddingTopProperty.equalHelper(this.paddingTop, incoming.paddingTop))
+				this.paddingTop = undefined;
+			if (_paddingRightProperty.equalHelper(this.paddingRight, incoming.paddingRight))
+				this.paddingRight = undefined;
+			if (_paddingBottomProperty.equalHelper(this.paddingBottom, incoming.paddingBottom))
+				this.paddingBottom = undefined;
+			if (_columnCountProperty.equalHelper(this.columnCount, incoming.columnCount))
+				this.columnCount = undefined;
+			if (_columnWidthProperty.equalHelper(this.columnWidth, incoming.columnWidth))
+				this.columnWidth = undefined;
+			if (_firstBaselineOffsetProperty.equalHelper(this.firstBaselineOffset, incoming.firstBaselineOffset))
+				this.firstBaselineOffset = undefined;
+			if (_verticalAlignProperty.equalHelper(this.verticalAlign, incoming.verticalAlign))
+				this.verticalAlign = undefined;
+			if (_blockProgressionProperty.equalHelper(this.blockProgression, incoming.blockProgression))
+				this.blockProgression = undefined;
+			if (_lineBreakProperty.equalHelper(this.lineBreak, incoming.lineBreak))
+				this.lineBreak = undefined;
+		}
+
+		/**
+		 * Sets properties in this TextLayoutFormat object to <code>undefined</code> if they do not match those in the
+		 * <code>incoming</code> ITextLayoutFormat instance.
+		 * 
+		 * @param incoming instance against which to compare this TextLayoutFormat object's property values.
+		 * 
+		 * @includeExample examples\TextLayoutFormat_removeClashingExample.as -noswf
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function removeClashing(incoming:ITextLayoutFormat):void
+		{
+			if (incoming == null)
+				return;
+
+			var holder:TextLayoutFormatValueHolder = incoming as TextLayoutFormatValueHolder;
+			if (holder)
+			{
+					for (var key:String in holder.coreStyles)
+					{
+						CONFIG::debug { assert(holder.coreStyles[key] !== undefined,"bad value in removeClashing"); }
+						if (!description[key].equalHelper(this[key],holder.coreStyles[key]))
+							this[key] = undefined;
+				}
+				return;
+			}
+
+			if (!_colorProperty.equalHelper(this.color, incoming.color))
+				this.color = undefined;
+			if (!_backgroundColorProperty.equalHelper(this.backgroundColor, incoming.backgroundColor))
+				this.backgroundColor = undefined;
+			if (!_lineThroughProperty.equalHelper(this.lineThrough, incoming.lineThrough))
+				this.lineThrough = undefined;
+			if (!_textAlphaProperty.equalHelper(this.textAlpha, incoming.textAlpha))
+				this.textAlpha = undefined;
+			if (!_backgroundAlphaProperty.equalHelper(this.backgroundAlpha, incoming.backgroundAlpha))
+				this.backgroundAlpha = undefined;
+			if (!_fontSizeProperty.equalHelper(this.fontSize, incoming.fontSize))
+				this.fontSize = undefined;
+			if (!_baselineShiftProperty.equalHelper(this.baselineShift, incoming.baselineShift))
+				this.baselineShift = undefined;
+			if (!_trackingLeftProperty.equalHelper(this.trackingLeft, incoming.trackingLeft))
+				this.trackingLeft = undefined;
+			if (!_trackingRightProperty.equalHelper(this.trackingRight, incoming.trackingRight))
+				this.trackingRight = undefined;
+			if (!_lineHeightProperty.equalHelper(this.lineHeight, incoming.lineHeight))
+				this.lineHeight = undefined;
+			if (!_breakOpportunityProperty.equalHelper(this.breakOpportunity, incoming.breakOpportunity))
+				this.breakOpportunity = undefined;
+			if (!_digitCaseProperty.equalHelper(this.digitCase, incoming.digitCase))
+				this.digitCase = undefined;
+			if (!_digitWidthProperty.equalHelper(this.digitWidth, incoming.digitWidth))
+				this.digitWidth = undefined;
+			if (!_dominantBaselineProperty.equalHelper(this.dominantBaseline, incoming.dominantBaseline))
+				this.dominantBaseline = undefined;
+			if (!_kerningProperty.equalHelper(this.kerning, incoming.kerning))
+				this.kerning = undefined;
+			if (!_ligatureLevelProperty.equalHelper(this.ligatureLevel, incoming.ligatureLevel))
+				this.ligatureLevel = undefined;
+			if (!_alignmentBaselineProperty.equalHelper(this.alignmentBaseline, incoming.alignmentBaseline))
+				this.alignmentBaseline = undefined;
+			if (!_localeProperty.equalHelper(this.locale, incoming.locale))
+				this.locale = undefined;
+			if (!_typographicCaseProperty.equalHelper(this.typographicCase, incoming.typographicCase))
+				this.typographicCase = undefined;
+			if (!_fontFamilyProperty.equalHelper(this.fontFamily, incoming.fontFamily))
+				this.fontFamily = undefined;
+			if (!_textDecorationProperty.equalHelper(this.textDecoration, incoming.textDecoration))
+				this.textDecoration = undefined;
+			if (!_fontWeightProperty.equalHelper(this.fontWeight, incoming.fontWeight))
+				this.fontWeight = undefined;
+			if (!_fontStyleProperty.equalHelper(this.fontStyle, incoming.fontStyle))
+				this.fontStyle = undefined;
+			if (!_whiteSpaceCollapseProperty.equalHelper(this.whiteSpaceCollapse, incoming.whiteSpaceCollapse))
+				this.whiteSpaceCollapse = undefined;
+			if (!_renderingModeProperty.equalHelper(this.renderingMode, incoming.renderingMode))
+				this.renderingMode = undefined;
+			if (!_cffHintingProperty.equalHelper(this.cffHinting, incoming.cffHinting))
+				this.cffHinting = undefined;
+			if (!_fontLookupProperty.equalHelper(this.fontLookup, incoming.fontLookup))
+				this.fontLookup = undefined;
+			if (!_textRotationProperty.equalHelper(this.textRotation, incoming.textRotation))
+				this.textRotation = undefined;
+			if (!_textIndentProperty.equalHelper(this.textIndent, incoming.textIndent))
+				this.textIndent = undefined;
+			if (!_paragraphStartIndentProperty.equalHelper(this.paragraphStartIndent, incoming.paragraphStartIndent))
+				this.paragraphStartIndent = undefined;
+			if (!_paragraphEndIndentProperty.equalHelper(this.paragraphEndIndent, incoming.paragraphEndIndent))
+				this.paragraphEndIndent = undefined;
+			if (!_paragraphSpaceBeforeProperty.equalHelper(this.paragraphSpaceBefore, incoming.paragraphSpaceBefore))
+				this.paragraphSpaceBefore = undefined;
+			if (!_paragraphSpaceAfterProperty.equalHelper(this.paragraphSpaceAfter, incoming.paragraphSpaceAfter))
+				this.paragraphSpaceAfter = undefined;
+			if (!_textAlignProperty.equalHelper(this.textAlign, incoming.textAlign))
+				this.textAlign = undefined;
+			if (!_textAlignLastProperty.equalHelper(this.textAlignLast, incoming.textAlignLast))
+				this.textAlignLast = undefined;
+			if (!_textJustifyProperty.equalHelper(this.textJustify, incoming.textJustify))
+				this.textJustify = undefined;
+			if (!_justificationRuleProperty.equalHelper(this.justificationRule, incoming.justificationRule))
+				this.justificationRule = undefined;
+			if (!_justificationStyleProperty.equalHelper(this.justificationStyle, incoming.justificationStyle))
+				this.justificationStyle = undefined;
+			if (!_directionProperty.equalHelper(this.direction, incoming.direction))
+				this.direction = undefined;
+			if (!_tabStopsProperty.equalHelper(this.tabStops, incoming.tabStops))
+				this.tabStops = undefined;
+			if (!_leadingModelProperty.equalHelper(this.leadingModel, incoming.leadingModel))
+				this.leadingModel = undefined;
+			if (!_columnGapProperty.equalHelper(this.columnGap, incoming.columnGap))
+				this.columnGap = undefined;
+			if (!_paddingLeftProperty.equalHelper(this.paddingLeft, incoming.paddingLeft))
+				this.paddingLeft = undefined;
+			if (!_paddingTopProperty.equalHelper(this.paddingTop, incoming.paddingTop))
+				this.paddingTop = undefined;
+			if (!_paddingRightProperty.equalHelper(this.paddingRight, incoming.paddingRight))
+				this.paddingRight = undefined;
+			if (!_paddingBottomProperty.equalHelper(this.paddingBottom, incoming.paddingBottom))
+				this.paddingBottom = undefined;
+			if (!_columnCountProperty.equalHelper(this.columnCount, incoming.columnCount))
+				this.columnCount = undefined;
+			if (!_columnWidthProperty.equalHelper(this.columnWidth, incoming.columnWidth))
+				this.columnWidth = undefined;
+			if (!_firstBaselineOffsetProperty.equalHelper(this.firstBaselineOffset, incoming.firstBaselineOffset))
+				this.firstBaselineOffset = undefined;
+			if (!_verticalAlignProperty.equalHelper(this.verticalAlign, incoming.verticalAlign))
+				this.verticalAlign = undefined;
+			if (!_blockProgressionProperty.equalHelper(this.blockProgression, incoming.blockProgression))
+				this.blockProgression = undefined;
+			if (!_lineBreakProperty.equalHelper(this.lineBreak, incoming.lineBreak))
+				this.lineBreak = undefined;
+		}
+
+		/**
+		 * Gets the TextLayoutFormat hash
+		 * @param seed seed value for the hash algorithm
+		 * @return the TextLayoutFormat hash
+		 * @private
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		tlf_internal function hash(seed:uint):uint
+		{
+			var hash:uint = seed;
+
+			if (_color)
+				hash = _colorProperty.hash(_color, hash);
+			if (_backgroundColor)
+				hash = _backgroundColorProperty.hash(_backgroundColor, hash);
+			if (_lineThrough)
+				hash = _lineThroughProperty.hash(_lineThrough, hash);
+			if (_textAlpha)
+				hash = _textAlphaProperty.hash(_textAlpha, hash);
+			if (_backgroundAlpha)
+				hash = _backgroundAlphaProperty.hash(_backgroundAlpha, hash);
+			if (_fontSize)
+				hash = _fontSizeProperty.hash(_fontSize, hash);
+			if (_baselineShift)
+				hash = _baselineShiftProperty.hash(_baselineShift, hash);
+			if (_trackingLeft)
+				hash = _trackingLeftProperty.hash(_trackingLeft, hash);
+			if (_trackingRight)
+				hash = _trackingRightProperty.hash(_trackingRight, hash);
+			if (_lineHeight)
+				hash = _lineHeightProperty.hash(_lineHeight, hash);
+			if (_breakOpportunity)
+				hash = _breakOpportunityProperty.hash(_breakOpportunity, hash);
+			if (_digitCase)
+				hash = _digitCaseProperty.hash(_digitCase, hash);
+			if (_digitWidth)
+				hash = _digitWidthProperty.hash(_digitWidth, hash);
+			if (_dominantBaseline)
+				hash = _dominantBaselineProperty.hash(_dominantBaseline, hash);
+			if (_kerning)
+				hash = _kerningProperty.hash(_kerning, hash);
+			if (_ligatureLevel)
+				hash = _ligatureLevelProperty.hash(_ligatureLevel, hash);
+			if (_alignmentBaseline)
+				hash = _alignmentBaselineProperty.hash(_alignmentBaseline, hash);
+			if (_locale)
+				hash = _localeProperty.hash(_locale, hash);
+			if (_typographicCase)
+				hash = _typographicCaseProperty.hash(_typographicCase, hash);
+			if (_fontFamily)
+				hash = _fontFamilyProperty.hash(_fontFamily, hash);
+			if (_textDecoration)
+				hash = _textDecorationProperty.hash(_textDecoration, hash);
+			if (_fontWeight)
+				hash = _fontWeightProperty.hash(_fontWeight, hash);
+			if (_fontStyle)
+				hash = _fontStyleProperty.hash(_fontStyle, hash);
+			if (_whiteSpaceCollapse)
+				hash = _whiteSpaceCollapseProperty.hash(_whiteSpaceCollapse, hash);
+			if (_renderingMode)
+				hash = _renderingModeProperty.hash(_renderingMode, hash);
+			if (_cffHinting)
+				hash = _cffHintingProperty.hash(_cffHinting, hash);
+			if (_fontLookup)
+				hash = _fontLookupProperty.hash(_fontLookup, hash);
+			if (_textRotation)
+				hash = _textRotationProperty.hash(_textRotation, hash);
+			if (_textIndent)
+				hash = _textIndentProperty.hash(_textIndent, hash);
+			if (_paragraphStartIndent)
+				hash = _paragraphStartIndentProperty.hash(_paragraphStartIndent, hash);
+			if (_paragraphEndIndent)
+				hash = _paragraphEndIndentProperty.hash(_paragraphEndIndent, hash);
+			if (_paragraphSpaceBefore)
+				hash = _paragraphSpaceBeforeProperty.hash(_paragraphSpaceBefore, hash);
+			if (_paragraphSpaceAfter)
+				hash = _paragraphSpaceAfterProperty.hash(_paragraphSpaceAfter, hash);
+			if (_textAlign)
+				hash = _textAlignProperty.hash(_textAlign, hash);
+			if (_textAlignLast)
+				hash = _textAlignLastProperty.hash(_textAlignLast, hash);
+			if (_textJustify)
+				hash = _textJustifyProperty.hash(_textJustify, hash);
+			if (_justificationRule)
+				hash = _justificationRuleProperty.hash(_justificationRule, hash);
+			if (_justificationStyle)
+				hash = _justificationStyleProperty.hash(_justificationStyle, hash);
+			if (_direction)
+				hash = _directionProperty.hash(_direction, hash);
+			if (_tabStops)
+				hash = _tabStopsProperty.hash(_tabStops, hash);
+			if (_leadingModel)
+				hash = _leadingModelProperty.hash(_leadingModel, hash);
+			if (_columnGap)
+				hash = _columnGapProperty.hash(_columnGap, hash);
+			if (_paddingLeft)
+				hash = _paddingLeftProperty.hash(_paddingLeft, hash);
+			if (_paddingTop)
+				hash = _paddingTopProperty.hash(_paddingTop, hash);
+			if (_paddingRight)
+				hash = _paddingRightProperty.hash(_paddingRight, hash);
+			if (_paddingBottom)
+				hash = _paddingBottomProperty.hash(_paddingBottom, hash);
+			if (_columnCount)
+				hash = _columnCountProperty.hash(_columnCount, hash);
+			if (_columnWidth)
+				hash = _columnWidthProperty.hash(_columnWidth, hash);
+			if (_firstBaselineOffset)
+				hash = _firstBaselineOffsetProperty.hash(_firstBaselineOffset, hash);
+			if (_verticalAlign)
+				hash = _verticalAlignProperty.hash(_verticalAlign, hash);
+			if (_blockProgression)
+				hash = _blockProgressionProperty.hash(_blockProgression, hash);
+			if (_lineBreak)
+				hash = _lineBreakProperty.hash(_lineBreak, hash);
+
+			return hash;
+		}
+
+		static private var _defaults:TextLayoutFormat;
+		/**
+		 * Returns a TextLayoutFormat object with default settings.
+		 * This function always returns the same object.
+		 * 
+		 * @return a singleton instance of ITextLayoutFormat that is populated with default values.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		static public function get defaultFormat():ITextLayoutFormat
+		{
+			if (_defaults == null)
+			{
+				_defaults = new TextLayoutFormat();
+				Property.defaultsAllHelper(_description,_defaults);
+				_defaultFormatHash = _defaults.hash(0);
+			}
+			return _defaults;
+		}
+		static private var _defaultFormatHash:uint;
+		/** @private */
+		static tlf_internal function getDefaultFormatHash():uint
+		{
+			defaultFormat;
+			return _defaultFormatHash;
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/formats/TextLayoutFormatInc.as b/textLayout_core/src/flashx/textLayout/formats/TextLayoutFormatInc.as
new file mode 100755
index 0000000..5356d98
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/TextLayoutFormatInc.as
@@ -0,0 +1,1259 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+		public function get color():*
+		{
+			return _formatValueHolder ? _formatValueHolder.color : undefined;
+		}
+		public function set color(colorValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().color = colorValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Background color of the text (adopts default value if undefined during cascade). Can be either the constant value  <code>BackgroundColor.TRANSPARENT</code>, or a hexadecimal value that specifies the three 8-bit RGB (red, green, blue) values; for example, 0xFF0000 is red and 0x00FF00 is green.
+		 * <p>Legal values as a string are flashx.textLayout.formats.BackgroundColor.TRANSPARENT, flashx.textLayout.formats.FormatValue.INHERIT and uints from 0x0 to 0xffffffff.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of TRANSPARENT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.BackgroundColor
+		 */
+		public function get backgroundColor():*
+		{
+			return _formatValueHolder ? _formatValueHolder.backgroundColor : undefined;
+		}
+		public function set backgroundColor(backgroundColorValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().backgroundColor = backgroundColorValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * If <code>true</code>, applies strikethrough, a line drawn through the middle of the text.
+		 * <p>Legal values are true, false and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of false.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get lineThrough():*
+		{
+			return _formatValueHolder ? _formatValueHolder.lineThrough : undefined;
+		}
+		public function set lineThrough(lineThroughValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().lineThrough = lineThroughValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Alpha (transparency) value for the text. A value of 0 is fully transparent, and a value of 1 is fully opaque. Display objects with <code>textAlpha</code> set to 0 are active, even though they are invisible.
+		 * <p>Legal values are numbers from 0 to 1 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 1.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get textAlpha():*
+		{
+			return _formatValueHolder ? _formatValueHolder.textAlpha : undefined;
+		}
+		public function set textAlpha(textAlphaValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().textAlpha = textAlphaValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Alpha (transparency) value for the background (adopts default value if undefined during cascade). A value of 0 is fully transparent, and a value of 1 is fully opaque. Display objects with alpha set to 0 are active, even though they are invisible.
+		 * <p>Legal values are numbers from 0 to 1 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 1.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get backgroundAlpha():*
+		{
+			return _formatValueHolder ? _formatValueHolder.backgroundAlpha : undefined;
+		}
+		public function set backgroundAlpha(backgroundAlphaValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().backgroundAlpha = backgroundAlphaValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * The size of the text in pixels.
+		 * <p>Legal values are numbers from 1 to 720 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 12.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get fontSize():*
+		{
+			return _formatValueHolder ? _formatValueHolder.fontSize : undefined;
+		}
+		public function set fontSize(fontSizeValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().fontSize = fontSizeValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Amount to shift the baseline from the <code>dominantBaseline</code> value. Units are in pixels, or a percentage of <code>fontSize</code> (in which case, enter a string value, like 140%).  Positive values shift the line up for horizontal text (right for vertical) and negative values shift it down for horizontal (left for vertical). 
+		 * <p>Legal values are flashx.textLayout.formats.BaselineShift.SUPERSCRIPT, flashx.textLayout.formats.BaselineShift.SUBSCRIPT, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Legal values as a number are from -1000 to 1000.</p>
+		 * <p>Legal values as a percent are numbers from -1000 to 1000.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.BaselineShift
+		 */
+		public function get baselineShift():*
+		{
+			return _formatValueHolder ? _formatValueHolder.baselineShift : undefined;
+		}
+		public function set baselineShift(baselineShiftValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().baselineShift = baselineShiftValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Number in pixels (or percent of <code>fontSize</code>, like 120%) indicating the amount of tracking (manual kerning) to be applied to the left of each character. If kerning is enabled, the <code>trackingLeft</code> value is added to the values in the kerning table for the font. If kerning is disabled, the <code>trackingLeft</code> value is used as a manual kerning value. Supports both positive and negative values. 
+		 * <p>Legal values as a number are from -1000 to 1000.</p>
+		 * <p>Legal values as a percent are numbers from -1000% to 1000%.</p>
+		 * <p>Legal values include flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get trackingLeft():*
+		{
+			return _formatValueHolder ? _formatValueHolder.trackingLeft : undefined;
+		}
+		public function set trackingLeft(trackingLeftValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().trackingLeft = trackingLeftValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Number in pixels (or percent of <code>fontSize</code>, like 120%) indicating the amount of tracking (manual kerning) to be applied to the right of each character.  If kerning is enabled, the <code>trackingRight</code> value is added to the values in the kerning table for the font. If kerning is disabled, the <code>trackingRight</code> value is used as a manual kerning value. Supports both positive and negative values. 
+		 * <p>Legal values as a number are from -1000 to 1000.</p>
+		 * <p>Legal values as a percent are numbers from -1000% to 1000%.</p>
+		 * <p>Legal values include flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get trackingRight():*
+		{
+			return _formatValueHolder ? _formatValueHolder.trackingRight : undefined;
+		}
+		public function set trackingRight(trackingRightValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().trackingRight = trackingRightValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Leading controls for the text. The distance from the baseline of the previous or the next line (based on <code>LeadingModel</code>) to the baseline of the current line is equal to the maximum amount of the leading applied to any character in the line. This is either a number or a percent.  If specifying a percent, enter a string value, like 140%.<p><img src='../../../images/textLayout_lineHeight1.jpg' alt='lineHeight1' /><img src='../../../images/textLayout_lineHeight2.jpg' alt='lineHeight2' /></p>
+		 * <p>Legal values as a number are from -720 to 720.</p>
+		 * <p>Legal values as a percent are numbers from -1000% to 1000%.</p>
+		 * <p>Legal values include flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 120%.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get lineHeight():*
+		{
+			return _formatValueHolder ? _formatValueHolder.lineHeight : undefined;
+		}
+		public function set lineHeight(lineHeightValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().lineHeight = lineHeightValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Controls where lines are allowed to break when breaking wrapping text into multiple lines. Set to <code>BreakOpportunity.AUTO</code> to break text normally. Set to <code>BreakOpportunity.NONE</code> to <em>not</em> break the text unless the text would overrun the measure and there are no other places to break the line. Set to <code>BreakOpportunity.ANY</code> to allow the line to break anywhere, rather than just between words. Set to <code>BreakOpportunity.ALL</code> to have each typographic cluster put on a separate line (useful for text on a path).
+		 * <p>Legal values are flash.text.engine.BreakOpportunity.ALL, flash.text.engine.BreakOpportunity.ANY, flash.text.engine.BreakOpportunity.AUTO, flash.text.engine.BreakOpportunity.NONE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.BreakOpportunity
+		 */
+		public function get breakOpportunity():*
+		{
+			return _formatValueHolder ? _formatValueHolder.breakOpportunity : undefined;
+		}
+		public function set breakOpportunity(breakOpportunityValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().breakOpportunity = breakOpportunityValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * The type of digit case used for this text. Setting the value to <code>DigitCase.OLD_STYLE</code> approximates lowercase letterforms with varying ascenders and descenders. The figures are proportionally spaced. This style is only available in selected typefaces, most commonly in a supplemental or expert font. The <code>DigitCase.LINING</code> setting has all-cap height and is typically monospaced to line up in charts.<p><img src='../../../images/textLayout_digitcase.gif' alt='digitCase' /></p>
+		 * <p>Legal values are flash.text.engine.DigitCase.DEFAULT, flash.text.engine.DigitCase.LINING, flash.text.engine.DigitCase.OLD_STYLE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of DEFAULT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.DigitCase
+		 */
+		public function get digitCase():*
+		{
+			return _formatValueHolder ? _formatValueHolder.digitCase : undefined;
+		}
+		public function set digitCase(digitCaseValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().digitCase = digitCaseValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Type of digit width used for this text. This can be <code>DigitWidth.PROPORTIONAL</code>, which looks best for individual numbers, or <code>DigitWidth.TABULAR</code>, which works best for numbers in tables, charts, and vertical rows.<p><img src='../../../images/textLayout_digitwidth.gif' alt='digitWidth' /></p>
+		 * <p>Legal values are flash.text.engine.DigitWidth.DEFAULT, flash.text.engine.DigitWidth.PROPORTIONAL, flash.text.engine.DigitWidth.TABULAR, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of DEFAULT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.DigitWidth
+		 */
+		public function get digitWidth():*
+		{
+			return _formatValueHolder ? _formatValueHolder.digitWidth : undefined;
+		}
+		public function set digitWidth(digitWidthValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().digitWidth = digitWidthValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Specifies which element baseline snaps to the <code>alignmentBaseline</code> to determine the vertical position of the element on the line. A value of <code>TextBaseline.AUTO</code> selects the dominant baseline based on the <code>locale</code> property of the parent paragraph.  For Japanese and Chinese, the selected baseline value is <code>TextBaseline.IDEOGRAPHIC_CENTER</code>; for all others it is <code>TextBaseline.ROMAN</code>. These baseline choices are determined by the choice of font and the font size.<p><img src='../../../images/textLayout_baselines.jpg' alt='baselines' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.FormatValue.AUTO, flash.text.engine.TextBaseline.ROMAN, flash.text.engine.TextBaseline.ASCENT, flash.text.engine.TextBaseline.DESCENT, flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP, flash.text.engine.TextBaseline.IDEOGRAPHIC_CENTER, flash.text.engine.TextBaseline.IDEOGRAPHIC_BOTTOM, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of flashx.textLayout.formats.FormatValue.AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.TextBaseline
+		 */
+		public function get dominantBaseline():*
+		{
+			return _formatValueHolder ? _formatValueHolder.dominantBaseline : undefined;
+		}
+		public function set dominantBaseline(dominantBaselineValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().dominantBaseline = dominantBaselineValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Kerning adjusts the pixels between certain character pairs to improve readability. Kerning is supported for all fonts with kerning tables.
+		 * <p>Legal values are flash.text.engine.Kerning.ON, flash.text.engine.Kerning.OFF, flash.text.engine.Kerning.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.Kerning
+		 */
+		public function get kerning():*
+		{
+			return _formatValueHolder ? _formatValueHolder.kerning : undefined;
+		}
+		public function set kerning(kerningValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().kerning = kerningValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Controls which of the ligatures that are defined in the font may be used in the text. The ligatures that appear for each of these settings is dependent on the font. A ligature occurs where two or more letter-forms are joined as a single glyph. Ligatures usually replace consecutive characters sharing common components, such as the letter pairs 'fi', 'fl', or 'ae'. They are used with both Latin and Non-Latin character sets. The ligatures enabled by the values of the LigatureLevel class - <code>MINIMUM</code>, <code>COMMON</code>, <code>UNCOMMON</code>, and <code>EXOTIC</code> - are additive. Each value enables a new set of ligatures, but also includes those of the previous types.<p><b>Note: </b>When working with Arabic or Syriac fonts, <code>ligatureLevel</code> must be set to MINIMUM or above.</p><p><img src='../../../images/textLayout_ligatures.png' alt='ligatureLevel' /></p>
+		 * <p>Legal values are flash.text.engine.LigatureLevel.MINIMUM, flash.text.engine.LigatureLevel.COMMON, flash.text.engine.LigatureLevel.UNCOMMON, flash.text.engine.LigatureLevel.EXOTIC, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of COMMON.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.LigatureLevel
+		 */
+		public function get ligatureLevel():*
+		{
+			return _formatValueHolder ? _formatValueHolder.ligatureLevel : undefined;
+		}
+		public function set ligatureLevel(ligatureLevelValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().ligatureLevel = ligatureLevelValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Specifies the baseline to which the dominant baseline aligns. For example, if you set <code>dominantBaseline</code> to ASCENT, setting <code>alignmentBaseline</code> to DESCENT aligns the top of the text with the DESCENT baseline, or below the line.  The largest element in the line generally determines the baselines.<p><img src='../../../images/textLayout_baselines.jpg' alt='baselines' /></p>
+		 * <p>Legal values are flash.text.engine.TextBaseline.ROMAN, flash.text.engine.TextBaseline.ASCENT, flash.text.engine.TextBaseline.DESCENT, flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP, flash.text.engine.TextBaseline.IDEOGRAPHIC_CENTER, flash.text.engine.TextBaseline.IDEOGRAPHIC_BOTTOM, flash.text.engine.TextBaseline.USE_DOMINANT_BASELINE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of USE_DOMINANT_BASELINE.</p>
+		 * @includeExample examples\TextLayoutFormat_alignmentBaselineExample.as -noswf
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.TextBaseline
+		 */
+		public function get alignmentBaseline():*
+		{
+			return _formatValueHolder ? _formatValueHolder.alignmentBaseline : undefined;
+		}
+		public function set alignmentBaseline(alignmentBaselineValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().alignmentBaseline = alignmentBaselineValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * The locale of the text. Controls case transformations and shaping. Standard locale identifiers as described in Unicode Technical Standard #35 are used. For example en, en_US and en-US are all English, ja is Japanese. 
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of en.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get locale():*
+		{
+			return _formatValueHolder ? _formatValueHolder.locale : undefined;
+		}
+		public function set locale(localeValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().locale = localeValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * The type of typographic case used for this text. Here are some examples:<p><img src='../../../images/textLayout_typographiccase.png' alt='typographicCase' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.TLFTypographicCase.DEFAULT, flashx.textLayout.formats.TLFTypographicCase.CAPS_TO_SMALL_CAPS, flashx.textLayout.formats.TLFTypographicCase.UPPERCASE, flashx.textLayout.formats.TLFTypographicCase.LOWERCASE, flashx.textLayout.formats.TLFTypographicCase.LOWERCASE_TO_SMALL_CAPS, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of DEFAULT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TLFTypographicCase
+		 */
+		public function get typographicCase():*
+		{
+			return _formatValueHolder ? _formatValueHolder.typographicCase : undefined;
+		}
+		public function set typographicCase(typographicCaseValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().typographicCase = typographicCaseValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 *  The name of the font to use, or a comma-separated list of font names. The Flash runtime renders the element with the first available font in the list. For example Arial, Helvetica, _sans causes the player to search for Arial, then Helvetica if Arial is not found, then _sans if neither is found.
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of Arial.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get fontFamily():*
+		{
+			return _formatValueHolder ? _formatValueHolder.fontFamily : undefined;
+		}
+		public function set fontFamily(fontFamilyValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().fontFamily = fontFamilyValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Decoration on text. Use to apply underlining; default is none.
+		 * <p>Legal values are flashx.textLayout.formats.TextDecoration.NONE, flashx.textLayout.formats.TextDecoration.UNDERLINE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of NONE.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TextDecoration
+		 */
+		public function get textDecoration():*
+		{
+			return _formatValueHolder ? _formatValueHolder.textDecoration : undefined;
+		}
+		public function set textDecoration(textDecorationValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().textDecoration = textDecorationValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Weight of text. May be <code>FontWeight.NORMAL</code> for use in plain text, or <code>FontWeight.BOLD</code>. Applies only to device fonts (<code>fontLookup</code> property is set to flash.text.engine.FontLookup.DEVICE).
+		 * <p>Legal values are flash.text.engine.FontWeight.NORMAL, flash.text.engine.FontWeight.BOLD, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of NORMAL.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.FontWeight
+		 */
+		public function get fontWeight():*
+		{
+			return _formatValueHolder ? _formatValueHolder.fontWeight : undefined;
+		}
+		public function set fontWeight(fontWeightValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().fontWeight = fontWeightValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Style of text. May be <code>FontPosture.NORMAL</code>, for use in plain text, or <code>FontPosture.ITALIC</code> for italic. This property applies only to device fonts (<code>fontLookup</code> property is set to flash.text.engine.FontLookup.DEVICE).
+		 * <p>Legal values are flash.text.engine.FontPosture.NORMAL, flash.text.engine.FontPosture.ITALIC, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of NORMAL.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.FontPosture
+		 */
+		public function get fontStyle():*
+		{
+			return _formatValueHolder ? _formatValueHolder.fontStyle : undefined;
+		}
+		public function set fontStyle(fontStyleValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().fontStyle = fontStyleValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Collapses or preserves whitespace when importing text into a TextFlow. <code>WhiteSpaceCollapse.PRESERVE</code> retains all whitespace characters. <code>WhiteSpaceCollapse.COLLAPSE</code> removes newlines, tabs, and leading or trailing spaces within a block of imported text. Line break tags (<br/>) and Unicode line separator characters are retained.
+		 * <p>Legal values are flashx.textLayout.formats.WhiteSpaceCollapse.PRESERVE, flashx.textLayout.formats.WhiteSpaceCollapse.COLLAPSE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of COLLAPSE.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.WhiteSpaceCollapse
+		 */
+		public function get whiteSpaceCollapse():*
+		{
+			return _formatValueHolder ? _formatValueHolder.whiteSpaceCollapse : undefined;
+		}
+		public function set whiteSpaceCollapse(whiteSpaceCollapseValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().whiteSpaceCollapse = whiteSpaceCollapseValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * The rendering mode used for this text.  Applies only to embedded fonts (<code>fontLookup</code> property is set to <code>FontLookup.EMBEDDED_CFF</code>).
+		 * <p>Legal values are flash.text.engine.RenderingMode.NORMAL, flash.text.engine.RenderingMode.CFF, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of CFF.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.RenderingMode
+		 */
+		public function get renderingMode():*
+		{
+			return _formatValueHolder ? _formatValueHolder.renderingMode : undefined;
+		}
+		public function set renderingMode(renderingModeValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().renderingMode = renderingModeValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * The type of CFF hinting used for this text. CFF hinting determines whether the Flash runtime forces strong horizontal stems to fit to a sub pixel grid or not. This property applies only if the <code>renderingMode</code> property is set to <code>RenderingMode.CFF</code>, and the font is embedded (<code>fontLookup</code> property is set to <code>FontLookup.EMBEDDED_CFF</code>). At small screen sizes, hinting produces a clear, legible text for human readers.
+		 * <p>Legal values are flash.text.engine.CFFHinting.NONE, flash.text.engine.CFFHinting.HORIZONTAL_STEM, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of HORIZONTAL_STEM.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.CFFHinting
+		 */
+		public function get cffHinting():*
+		{
+			return _formatValueHolder ? _formatValueHolder.cffHinting : undefined;
+		}
+		public function set cffHinting(cffHintingValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().cffHinting = cffHintingValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Font lookup to use. Specifying <code>FontLookup.DEVICE</code> uses the fonts installed on the system that is running the SWF file. Device fonts result in a smaller movie size, but text is not always rendered the same across different systems and platforms. Specifying <code>FontLookup.EMBEDDED_CFF</code> uses font outlines embedded in the published SWF file. Embedded fonts increase the size of the SWF file (sometimes dramatically), but text is consistently displayed in the chosen font.
+		 * <p>Legal values are flash.text.engine.FontLookup.DEVICE, flash.text.engine.FontLookup.EMBEDDED_CFF, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of DEVICE.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.FontLookup
+		 */
+		public function get fontLookup():*
+		{
+			return _formatValueHolder ? _formatValueHolder.fontLookup : undefined;
+		}
+		public function set fontLookup(fontLookupValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().fontLookup = fontLookupValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Determines the number of degrees to rotate this text.
+		 * <p>Legal values are flash.text.engine.TextRotation.ROTATE_0, flash.text.engine.TextRotation.ROTATE_180, flash.text.engine.TextRotation.ROTATE_270, flash.text.engine.TextRotation.ROTATE_90, flash.text.engine.TextRotation.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.TextRotation
+		 */
+		public function get textRotation():*
+		{
+			return _formatValueHolder ? _formatValueHolder.textRotation : undefined;
+		}
+		public function set textRotation(textRotationValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().textRotation = textRotationValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * A Number that specifies, in pixels, the amount to indent the first line of the paragraph.
+		 * A negative indent will push the line into the margin, and possibly out of the container.
+		 * <p>Legal values are numbers from -1000 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get textIndent():*
+		{
+			return _formatValueHolder ? _formatValueHolder.textIndent : undefined;
+		}
+		public function set textIndent(textIndentValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().textIndent = textIndentValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * A Number that specifies, in pixels, the amount to indent the paragraph's start edge. Refers to the left edge in left-to-right text and the right edge in right-to-left text. 
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paragraphStartIndent():*
+		{
+			return _formatValueHolder ? _formatValueHolder.paragraphStartIndent : undefined;
+		}
+		public function set paragraphStartIndent(paragraphStartIndentValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().paragraphStartIndent = paragraphStartIndentValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * A Number that specifies, in pixels, the amount to indent the paragraph's end edge. Refers to the right edge in left-to-right text and the left edge in right-to-left text. 
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paragraphEndIndent():*
+		{
+			return _formatValueHolder ? _formatValueHolder.paragraphEndIndent : undefined;
+		}
+		public function set paragraphEndIndent(paragraphEndIndentValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().paragraphEndIndent = paragraphEndIndentValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * A Number that specifies the amount of space, in pixels, to leave before the paragraph. 
+		 * Collapses in tandem with <code>paragraphSpaceAfter</code>.
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paragraphSpaceBefore():*
+		{
+			return _formatValueHolder ? _formatValueHolder.paragraphSpaceBefore : undefined;
+		}
+		public function set paragraphSpaceBefore(paragraphSpaceBeforeValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().paragraphSpaceBefore = paragraphSpaceBeforeValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * A Number that specifies the amount of space, in pixels, to leave after the paragraph.
+		 * Collapses in tandem with  <code>paragraphSpaceBefore</code>.
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paragraphSpaceAfter():*
+		{
+			return _formatValueHolder ? _formatValueHolder.paragraphSpaceAfter : undefined;
+		}
+		public function set paragraphSpaceAfter(paragraphSpaceAfterValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().paragraphSpaceAfter = paragraphSpaceAfterValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Alignment of lines in the paragraph relative to the container.
+		 * <code>TextAlign.LEFT</code> aligns lines along the left edge of the container. <code>TextAlign.RIGHT</code> aligns on the right edge. <code>TextAlign.CENTER</code> positions the line equidistant from the left and right edges. <code>TextAlign.JUSTIFY</code> spreads the lines out so they fill the space. <code>TextAlign.START</code> is equivalent to setting left in left-to-right text, or right in right-to-left text. <code>TextAlign.END</code> is equivalent to setting right in left-to-right text, or left in right-to-left text.
+		 * <p>Legal values are flashx.textLayout.formats.TextAlign.LEFT, flashx.textLayout.formats.TextAlign.RIGHT, flashx.textLayout.formats.TextAlign.CENTER, flashx.textLayout.formats.TextAlign.JUSTIFY, flashx.textLayout.formats.TextAlign.START, flashx.textLayout.formats.TextAlign.END, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of START.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TextAlign
+		 */
+		public function get textAlign():*
+		{
+			return _formatValueHolder ? _formatValueHolder.textAlign : undefined;
+		}
+		public function set textAlign(textAlignValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().textAlign = textAlignValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Alignment of the last (or only) line in the paragraph relative to the container in justified text.
+		 * If <code>textAlign</code> is set to <code>TextAlign.JUSTIFY</code>, <code>textAlignLast</code> specifies how the last line (or only line, if this is a one line block) is aligned. Values are similar to <code>textAlign</code>.
+		 * <p>Legal values are flashx.textLayout.formats.TextAlign.LEFT, flashx.textLayout.formats.TextAlign.RIGHT, flashx.textLayout.formats.TextAlign.CENTER, flashx.textLayout.formats.TextAlign.JUSTIFY, flashx.textLayout.formats.TextAlign.START, flashx.textLayout.formats.TextAlign.END, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of START.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TextAlign
+		 */
+		public function get textAlignLast():*
+		{
+			return _formatValueHolder ? _formatValueHolder.textAlignLast : undefined;
+		}
+		public function set textAlignLast(textAlignLastValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().textAlignLast = textAlignLastValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Specifies options for justifying text.
+		 * Default value is <code>TextJustify.INTER_WORD</code>, meaning that extra space is added to the space characters. <code>TextJustify.DISTRIBUTE</code> adds extra space to space characters and between individual letters. Used only in conjunction with a <code>justificationRule</code> value of <code>JustificationRule.SPACE</code>.
+		 * <p>Legal values are flashx.textLayout.formats.TextJustify.INTER_WORD, flashx.textLayout.formats.TextJustify.DISTRIBUTE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of INTER_WORD.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TextJustify
+		 */
+		public function get textJustify():*
+		{
+			return _formatValueHolder ? _formatValueHolder.textJustify : undefined;
+		}
+		public function set textJustify(textJustifyValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().textJustify = textJustifyValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Rule used to justify text in a paragraph.
+		 * Default value is <code>FormatValue.AUTO</code>, which justifies text based on the paragraph's <code>locale</code> property. For all languages except Japanese and Chinese, <code>FormatValue.AUTO</code> becomes <code>JustificationRule.SPACE</code>, which adds extra space to the space characters.  For Japanese and Chinese, <code>FormatValue.AUTO</code> becomes <code>JustficationRule.EAST_ASIAN</code>. In part, justification changes the spacing of punctuation. In Roman text the comma and Japanese periods take a full character's width but in East Asian text only half of a character's width. Also, in the East Asian text the spacing between sequential punctuation marks becomes tighter, obeying traditional East Asian typographic conventions. Note, too, in the example below the leading that is applied to the second line of the paragraphs. In the East Asian version, the last two lines push left. In the Roman version, the second and following lines push left.<p><img src='../../../images/textLayout_justificationrule.png' alt='justificationRule' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.JustificationRule.EAST_ASIAN, flashx.textLayout.formats.JustificationRule.SPACE, flashx.textLayout.formats.FormatValue.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of flashx.textLayout.formats.FormatValue.AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.JustificationRule
+		 */
+		public function get justificationRule():*
+		{
+			return _formatValueHolder ? _formatValueHolder.justificationRule : undefined;
+		}
+		public function set justificationRule(justificationRuleValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().justificationRule = justificationRuleValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * The style used for justification of the paragraph. Used only in conjunction with a <code>justificationRule</code> setting of <code>JustificationRule.EAST_ASIAN</code>.
+		 * Default value of <code>FormatValue.AUTO</code> is resolved to <code>JustificationStyle.PUSH_IN_KINSOKU</code> for all locales.  The constants defined by the JustificationStyle class specify options for handling kinsoku characters, which are Japanese characters that cannot appear at either the beginning or end of a line. If you want looser text, specify <code>JustificationStyle.PUSH-OUT-ONLY</code>. If you want behavior that is like what you get with the  <code>justificationRule</code> of <code>JustificationRule.SPACE</code>, use <code>JustificationStyle.PRIORITIZE-LEAST-ADJUSTMENT</code>.
+		 * <p>Legal values are flash.text.engine.JustificationStyle.PRIORITIZE_LEAST_ADJUSTMENT, flash.text.engine.JustificationStyle.PUSH_IN_KINSOKU, flash.text.engine.JustificationStyle.PUSH_OUT_ONLY, flashx.textLayout.formats.FormatValue.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of flashx.textLayout.formats.FormatValue.AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.JustificationStyle
+		 */
+		public function get justificationStyle():*
+		{
+			return _formatValueHolder ? _formatValueHolder.justificationStyle : undefined;
+		}
+		public function set justificationStyle(justificationStyleValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().justificationStyle = justificationStyleValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Specifies the default bidirectional embedding level of the text in the text block. 
+		 * Left-to-right reading order, as in Latin-style scripts, or right-to-left reading order, as in Arabic or Hebrew. This property also affects column direction when it is applied at the container level. Columns can be either left-to-right or right-to-left, just like text. Below are some examples:<p><img src='../../../images/textLayout_direction.gif' alt='direction' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.Direction.LTR, flashx.textLayout.formats.Direction.RTL, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of LTR.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.Direction
+		 */
+		public function get direction():*
+		{
+			return _formatValueHolder ? _formatValueHolder.direction : undefined;
+		}
+		public function set direction(directionValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().direction = directionValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Specifies the tab stops associated with the paragraph.
+		 * Setters can take an array of flashx.textLayout.formats.TabStopFormat, a condensed string representation, undefined, or <code>FormatValue.INHERIT</code>. The condensed string representation is always converted into an array of flashx.textLayout.formats.TabStopFormat. <p>The string-based format is a list of tab stops, where each tab stop is delimited by one or more spaces.</p><p>A tab stop takes the following form: &lt;alignment type&gt;&lt;alignment position&gt;|&lt;alignment token&gt;.</p><p>The alignment type is a single character, and can be S, E, C, or D (or lower-case equivalents). S or s for start, E or e for end, C or c for center, D or d for decimal. The alignment type is optional, and if its not specified will default to S.</p><p>The alignment position is a Number, and is specified according to FXG spec for Numbers (decimal or scientific notation). The alignment position is required.</p><p>The vertical bar is used to separate the alignment position from the alignment token, and should only be present if the alignment token is present.</p><p> The alignment token is optional if the alignment type is D, and should not be present if the alignment type is anything other than D. The alignment token may be any sequence of characters terminated by the space that ends the tab stop (for the last tab stop, the terminating space is optional; end of alignment token is implied). A space may be part of the alignment token if it is escaped with a backslash (\ ). A backslash may be part of the alignment token if it is escaped with another backslash (\\). If the alignment type is D, and the alignment token is not specified, it will take on the default value of null.</p><p>If no tab stops are specified, a tab action defaults to the end of the line.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of null.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get tabStops():*
+		{
+			return _formatValueHolder ? _formatValueHolder.tabStops : undefined;
+		}
+		public function set tabStops(tabStopsValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().tabStops = tabStopsValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Specifies the leading model, which is a combination of leading basis and leading direction.
+		 * Leading basis is the baseline to which the <code>lineHeight</code> property refers. Leading direction determines whether the <code>lineHeight</code> property refers to the distance of a line's baseline from that of the line before it or the line after it. The default value of <code>FormatValue.AUTO</code> is resolved based on the paragraph's <code>locale</code> property.  For Japanese and Chinese, it is <code>LeadingModel.IDEOGRAPHIC_TOP_DOWN</code> and for all others it is <code>LeadingModel.ROMAN_UP</code>.<p><strong>Leading Basis:</strong></p><p><img src='../../../images/textLayout_LB1.png' alt='leadingBasis1' />    <img src='../../../images/textLayout_LB2.png' alt='leadingBasis2' />    <img src='../../../images/textLayout_LB3.png' alt='leadingBasis3' /></p><p><strong>Leading Direction:</strong></p><p><img src='../../../images/textLayout_LD1.png' alt='leadingDirection1' />    <img src='../../../images/textLayout_LD2.png' alt='leadingDirection2' />    <img src='../../../images/textLayout_LD3.png' alt='leadingDirection3' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.LeadingModel.ROMAN_UP, flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_TOP_UP, flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_CENTER_UP, flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_TOP_DOWN, flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_CENTER_DOWN, flashx.textLayout.formats.LeadingModel.APPROXIMATE_TEXT_FIELD, flashx.textLayout.formats.LeadingModel.ASCENT_DESCENT_UP, flashx.textLayout.formats.LeadingModel.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.LeadingModel
+		 */
+		public function get leadingModel():*
+		{
+			return _formatValueHolder ? _formatValueHolder.leadingModel : undefined;
+		}
+		public function set leadingModel(leadingModelValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().leadingModel = leadingModelValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Specifies the amount of gutter space, in pixels, to leave between the columns (adopts default value if undefined during cascade).
+		 * Value is a Number
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 20.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get columnGap():*
+		{
+			return _formatValueHolder ? _formatValueHolder.columnGap : undefined;
+		}
+		public function set columnGap(columnGapValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().columnGap = columnGapValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Left inset in pixels (adopts default value if undefined during cascade).
+		 * Space between the left edge of the container and the text.  Value is a Number.<p> With vertical text, in scrollable containers with multiple columns, the first and following columns will show the padding as blank space at the end of the container, but for the last column, if the text doesn't all fit, you may have to scroll in order to see the padding.</p>
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paddingLeft():*
+		{
+			return _formatValueHolder ? _formatValueHolder.paddingLeft : undefined;
+		}
+		public function set paddingLeft(paddingLeftValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().paddingLeft = paddingLeftValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Top inset in pixels (adopts default value if undefined during cascade).
+		 * Space between the top edge of the container and the text.  Value is a Number.
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paddingTop():*
+		{
+			return _formatValueHolder ? _formatValueHolder.paddingTop : undefined;
+		}
+		public function set paddingTop(paddingTopValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().paddingTop = paddingTopValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Right inset in pixels (adopts default value if undefined during cascade).
+		 * Space between the right edge of the container and the text.  Value is a Number.
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paddingRight():*
+		{
+			return _formatValueHolder ? _formatValueHolder.paddingRight : undefined;
+		}
+		public function set paddingRight(paddingRightValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().paddingRight = paddingRightValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Botttom inset in pixels (adopts default value if undefined during cascade).
+		 * Space between the bottom edge of the container and the text.  Value is a Number. <p> With horizontal text, in scrollable containers with multiple columns, the first and following columns will show the padding as blank space at the bottom of the container, but for the last column, if the text doesn't all fit, you may have to scroll in order to see the padding.</p>
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paddingBottom():*
+		{
+			return _formatValueHolder ? _formatValueHolder.paddingBottom : undefined;
+		}
+		public function set paddingBottom(paddingBottomValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().paddingBottom = paddingBottomValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Number of text columns (adopts default value if undefined during cascade).
+		 * The column number overrides the  other column settings. Value is an integer, or <code>FormatValue.AUTO</code> if unspecified. If <code>columnCount</code> is not specified,<code>columnWidth</code> is used to create as many columns as can fit in the container.
+		 * <p>Legal values as a string are flashx.textLayout.formats.FormatValue.AUTO, flashx.textLayout.formats.FormatValue.INHERIT and from ints from 1 to 50.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.FormatValue
+		 */
+		public function get columnCount():*
+		{
+			return _formatValueHolder ? _formatValueHolder.columnCount : undefined;
+		}
+		public function set columnCount(columnCountValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().columnCount = columnCountValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Column width in pixels (adopts default value if undefined during cascade).
+		 * If you specify the width of the columns, but not the count, TextLayout will create as many columns of that width as possible, given the  container width and <code>columnGap</code> settings. Any remainder space is left after the last column. Value is a Number.
+		 * <p>Legal values as a string are flashx.textLayout.formats.FormatValue.AUTO, flashx.textLayout.formats.FormatValue.INHERIT and numbers from 0 to 8000.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.FormatValue
+		 */
+		public function get columnWidth():*
+		{
+			return _formatValueHolder ? _formatValueHolder.columnWidth : undefined;
+		}
+		public function set columnWidth(columnWidthValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().columnWidth = columnWidthValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Specifies the baseline position of the first line in the container. Which baseline this property refers to depends on the container-level locale.  For Japanese and Chinese, it is <code>TextBaseline.IDEOGRAPHIC_BOTTOM</code>; for all others it is <code>TextBaseline.ROMAN</code>.
+		 * The offset from the top inset (or right inset if <code>blockProgression</code> is RL) of the container to the baseline of the first line can be either <code>BaselineOffset.ASCENT</code>, meaning equal to the ascent of the line, <code>BaselineOffset.LINE_HEIGHT</code>, meaning equal to the height of that first line, or any fixed-value number to specify an absolute distance. <code>BaselineOffset.AUTO</code> aligns the ascent of the line with the container top inset.<p><img src='../../../images/textLayout_FBO1.png' alt='firstBaselineOffset1' /><img src='../../../images/textLayout_FBO2.png' alt='firstBaselineOffset2' /><img src='../../../images/textLayout_FBO3.png' alt='firstBaselineOffset3' /><img src='../../../images/textLayout_FBO4.png' alt='firstBaselineOffset4' /></p>
+		 * <p>Legal values as a string are flashx.textLayout.formats.BaselineOffset.AUTO, flashx.textLayout.formats.BaselineOffset.ASCENT, flashx.textLayout.formats.BaselineOffset.LINE_HEIGHT, flashx.textLayout.formats.FormatValue.INHERIT and numbers from 0 to 1000.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.BaselineOffset
+		 */
+		public function get firstBaselineOffset():*
+		{
+			return _formatValueHolder ? _formatValueHolder.firstBaselineOffset : undefined;
+		}
+		public function set firstBaselineOffset(firstBaselineOffsetValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().firstBaselineOffset = firstBaselineOffsetValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Vertical alignment or justification (adopts default value if undefined during cascade).
+		 * Determines how TextFlow elements align within the container.
+		 * <p>Legal values are flashx.textLayout.formats.VerticalAlign.TOP, flashx.textLayout.formats.VerticalAlign.MIDDLE, flashx.textLayout.formats.VerticalAlign.BOTTOM, flashx.textLayout.formats.VerticalAlign.JUSTIFY, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of TOP.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.VerticalAlign
+		 */
+		public function get verticalAlign():*
+		{
+			return _formatValueHolder ? _formatValueHolder.verticalAlign : undefined;
+		}
+		public function set verticalAlign(verticalAlignValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().verticalAlign = verticalAlignValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Specifies a vertical or horizontal progression of line placement.
+		 * Lines are either placed top-to-bottom (<code>BlockProgression.TB</code>, used for horizontal text) or right-to-left (<code>BlockProgression.RL</code>, used for vertical text).
+		 * <p>Legal values are flashx.textLayout.formats.BlockProgression.RL, flashx.textLayout.formats.BlockProgression.TB, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of TB.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.BlockProgression
+		 */
+		public function get blockProgression():*
+		{
+			return _formatValueHolder ? _formatValueHolder.blockProgression : undefined;
+		}
+		public function set blockProgression(blockProgressionValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().blockProgression = blockProgressionValue;
+			formatChanged();
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Controls word wrapping within the container (adopts default value if undefined during cascade).
+		 * Text in the container may be set to fit the width of the container (<code>LineBreak.TO_FIT</code>), or can be set to break only at explicit return or line feed characters (<code>LineBreak.EXPLICIT</code>).
+		 * <p>Legal values are flashx.textLayout.formats.LineBreak.EXPLICIT, flashx.textLayout.formats.LineBreak.TO_FIT, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of TO_FIT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.LineBreak
+		 */
+		public function get lineBreak():*
+		{
+			return _formatValueHolder ? _formatValueHolder.lineBreak : undefined;
+		}
+		public function set lineBreak(lineBreakValue:*):void
+		{
+			writableTextLayoutFormatValueHolder().lineBreak = lineBreakValue;
+			formatChanged();
+		}
diff --git a/textLayout_core/src/flashx/textLayout/formats/TextLayoutFormatValueHolder.as b/textLayout_core/src/flashx/textLayout/formats/TextLayoutFormatValueHolder.as
new file mode 100755
index 0000000..5c336ac
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/TextLayoutFormatValueHolder.as
@@ -0,0 +1,1457 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.property.Property;
+	import flashx.textLayout.tlf_internal;
+	use namespace tlf_internal;
+
+	[ExcludeClass]
+	/** @private */
+	public class TextLayoutFormatValueHolder implements ITextLayoutFormat
+	{
+		private var _coreStyles:Object;
+
+		public function TextLayoutFormatValueHolder(initialValues:ITextLayoutFormat = null)
+		{
+			initialize(initialValues);
+		}
+
+		private function initialize(initialValues:ITextLayoutFormat):void
+		{
+			if (initialValues)
+			{
+				var holder:TextLayoutFormatValueHolder = initialValues as TextLayoutFormatValueHolder;
+				if (holder)
+				{
+					for (var s:String in holder.coreStyles)
+						writableCoreStyles()[s] = holder.coreStyles[s];
+				}
+				else
+				{
+					for each (var prop:Property in TextLayoutFormat.description)
+					{
+						var val:* = initialValues[prop.name];
+						if (val !== undefined)
+							writableCoreStyles()[prop.name] = val;
+					}
+				}
+			}
+		}
+
+		private function writableCoreStyles():Object
+		{
+			if (_coreStyles == null)
+				_coreStyles = new Object();
+			return _coreStyles;
+		}
+
+		public function get coreStyles():Object
+		{ return _coreStyles; }
+		public function set coreStyles(val:Object):void
+		{ _coreStyles = val; }
+
+		private function getCoreStyle(styleProp:String):*
+		{ return _coreStyles ? _coreStyles[styleProp] : undefined; }
+		private function setCoreStyle(styleProp:Property,currValue:*,newValue:*):void
+		{
+			newValue = styleProp.setHelper(currValue,newValue);
+			if (newValue !== undefined)
+				writableCoreStyles()[styleProp.name] = newValue;
+			else if (_coreStyles)
+				delete _coreStyles[styleProp.name];
+		}
+
+		public function hash(hash:uint):uint
+		{
+			for (var s:String in coreStyles)
+				hash = TextLayoutFormat.description[s].hash(coreStyles[s],hash);
+			return hash;
+		}
+
+		public function set format(incoming:ITextLayoutFormat):void
+		{
+			if (incoming == null)
+			{
+				coreStyles = null;
+				return;
+			}
+			var holder:TextLayoutFormatValueHolder = incoming as TextLayoutFormatValueHolder;
+			if (holder)
+			{
+				coreStyles = holder.coreStyles ? Property.shallowCopy(holder.coreStyles) : null;
+				return;
+			}
+
+			coreStyles = null;
+			var val:*;
+			if ((val = incoming.color) !== undefined)
+				this.color = val;
+			if ((val = incoming.backgroundColor) !== undefined)
+				this.backgroundColor = val;
+			if ((val = incoming.lineThrough) !== undefined)
+				this.lineThrough = val;
+			if ((val = incoming.textAlpha) !== undefined)
+				this.textAlpha = val;
+			if ((val = incoming.backgroundAlpha) !== undefined)
+				this.backgroundAlpha = val;
+			if ((val = incoming.fontSize) !== undefined)
+				this.fontSize = val;
+			if ((val = incoming.baselineShift) !== undefined)
+				this.baselineShift = val;
+			if ((val = incoming.trackingLeft) !== undefined)
+				this.trackingLeft = val;
+			if ((val = incoming.trackingRight) !== undefined)
+				this.trackingRight = val;
+			if ((val = incoming.lineHeight) !== undefined)
+				this.lineHeight = val;
+			if ((val = incoming.breakOpportunity) !== undefined)
+				this.breakOpportunity = val;
+			if ((val = incoming.digitCase) !== undefined)
+				this.digitCase = val;
+			if ((val = incoming.digitWidth) !== undefined)
+				this.digitWidth = val;
+			if ((val = incoming.dominantBaseline) !== undefined)
+				this.dominantBaseline = val;
+			if ((val = incoming.kerning) !== undefined)
+				this.kerning = val;
+			if ((val = incoming.ligatureLevel) !== undefined)
+				this.ligatureLevel = val;
+			if ((val = incoming.alignmentBaseline) !== undefined)
+				this.alignmentBaseline = val;
+			if ((val = incoming.locale) !== undefined)
+				this.locale = val;
+			if ((val = incoming.typographicCase) !== undefined)
+				this.typographicCase = val;
+			if ((val = incoming.fontFamily) !== undefined)
+				this.fontFamily = val;
+			if ((val = incoming.textDecoration) !== undefined)
+				this.textDecoration = val;
+			if ((val = incoming.fontWeight) !== undefined)
+				this.fontWeight = val;
+			if ((val = incoming.fontStyle) !== undefined)
+				this.fontStyle = val;
+			if ((val = incoming.whiteSpaceCollapse) !== undefined)
+				this.whiteSpaceCollapse = val;
+			if ((val = incoming.renderingMode) !== undefined)
+				this.renderingMode = val;
+			if ((val = incoming.cffHinting) !== undefined)
+				this.cffHinting = val;
+			if ((val = incoming.fontLookup) !== undefined)
+				this.fontLookup = val;
+			if ((val = incoming.textRotation) !== undefined)
+				this.textRotation = val;
+			if ((val = incoming.textIndent) !== undefined)
+				this.textIndent = val;
+			if ((val = incoming.paragraphStartIndent) !== undefined)
+				this.paragraphStartIndent = val;
+			if ((val = incoming.paragraphEndIndent) !== undefined)
+				this.paragraphEndIndent = val;
+			if ((val = incoming.paragraphSpaceBefore) !== undefined)
+				this.paragraphSpaceBefore = val;
+			if ((val = incoming.paragraphSpaceAfter) !== undefined)
+				this.paragraphSpaceAfter = val;
+			if ((val = incoming.textAlign) !== undefined)
+				this.textAlign = val;
+			if ((val = incoming.textAlignLast) !== undefined)
+				this.textAlignLast = val;
+			if ((val = incoming.textJustify) !== undefined)
+				this.textJustify = val;
+			if ((val = incoming.justificationRule) !== undefined)
+				this.justificationRule = val;
+			if ((val = incoming.justificationStyle) !== undefined)
+				this.justificationStyle = val;
+			if ((val = incoming.direction) !== undefined)
+				this.direction = val;
+			if ((val = incoming.tabStops) !== undefined)
+				this.tabStops = val;
+			if ((val = incoming.leadingModel) !== undefined)
+				this.leadingModel = val;
+			if ((val = incoming.columnGap) !== undefined)
+				this.columnGap = val;
+			if ((val = incoming.paddingLeft) !== undefined)
+				this.paddingLeft = val;
+			if ((val = incoming.paddingTop) !== undefined)
+				this.paddingTop = val;
+			if ((val = incoming.paddingRight) !== undefined)
+				this.paddingRight = val;
+			if ((val = incoming.paddingBottom) !== undefined)
+				this.paddingBottom = val;
+			if ((val = incoming.columnCount) !== undefined)
+				this.columnCount = val;
+			if ((val = incoming.columnWidth) !== undefined)
+				this.columnWidth = val;
+			if ((val = incoming.firstBaselineOffset) !== undefined)
+				this.firstBaselineOffset = val;
+			if ((val = incoming.verticalAlign) !== undefined)
+				this.verticalAlign = val;
+			if ((val = incoming.blockProgression) !== undefined)
+				this.blockProgression = val;
+			if ((val = incoming.lineBreak) !== undefined)
+				this.lineBreak = val;
+		}
+
+		public function concat(incoming:ITextLayoutFormat):void
+		{
+			var holder:TextLayoutFormatValueHolder = incoming as TextLayoutFormatValueHolder;
+			if (holder)
+			{
+				for (var key:String in holder.coreStyles)
+				{
+					this[key] = TextLayoutFormat.description[key].concatHelper(this[key],holder.coreStyles[key]);
+				}
+				return;
+			}
+
+			this.color = TextLayoutFormat.colorProperty.concatHelper(this.color, incoming.color);
+			this.backgroundColor = TextLayoutFormat.backgroundColorProperty.concatHelper(this.backgroundColor, incoming.backgroundColor);
+			this.lineThrough = TextLayoutFormat.lineThroughProperty.concatHelper(this.lineThrough, incoming.lineThrough);
+			this.textAlpha = TextLayoutFormat.textAlphaProperty.concatHelper(this.textAlpha, incoming.textAlpha);
+			this.backgroundAlpha = TextLayoutFormat.backgroundAlphaProperty.concatHelper(this.backgroundAlpha, incoming.backgroundAlpha);
+			this.fontSize = TextLayoutFormat.fontSizeProperty.concatHelper(this.fontSize, incoming.fontSize);
+			this.baselineShift = TextLayoutFormat.baselineShiftProperty.concatHelper(this.baselineShift, incoming.baselineShift);
+			this.trackingLeft = TextLayoutFormat.trackingLeftProperty.concatHelper(this.trackingLeft, incoming.trackingLeft);
+			this.trackingRight = TextLayoutFormat.trackingRightProperty.concatHelper(this.trackingRight, incoming.trackingRight);
+			this.lineHeight = TextLayoutFormat.lineHeightProperty.concatHelper(this.lineHeight, incoming.lineHeight);
+			this.breakOpportunity = TextLayoutFormat.breakOpportunityProperty.concatHelper(this.breakOpportunity, incoming.breakOpportunity);
+			this.digitCase = TextLayoutFormat.digitCaseProperty.concatHelper(this.digitCase, incoming.digitCase);
+			this.digitWidth = TextLayoutFormat.digitWidthProperty.concatHelper(this.digitWidth, incoming.digitWidth);
+			this.dominantBaseline = TextLayoutFormat.dominantBaselineProperty.concatHelper(this.dominantBaseline, incoming.dominantBaseline);
+			this.kerning = TextLayoutFormat.kerningProperty.concatHelper(this.kerning, incoming.kerning);
+			this.ligatureLevel = TextLayoutFormat.ligatureLevelProperty.concatHelper(this.ligatureLevel, incoming.ligatureLevel);
+			this.alignmentBaseline = TextLayoutFormat.alignmentBaselineProperty.concatHelper(this.alignmentBaseline, incoming.alignmentBaseline);
+			this.locale = TextLayoutFormat.localeProperty.concatHelper(this.locale, incoming.locale);
+			this.typographicCase = TextLayoutFormat.typographicCaseProperty.concatHelper(this.typographicCase, incoming.typographicCase);
+			this.fontFamily = TextLayoutFormat.fontFamilyProperty.concatHelper(this.fontFamily, incoming.fontFamily);
+			this.textDecoration = TextLayoutFormat.textDecorationProperty.concatHelper(this.textDecoration, incoming.textDecoration);
+			this.fontWeight = TextLayoutFormat.fontWeightProperty.concatHelper(this.fontWeight, incoming.fontWeight);
+			this.fontStyle = TextLayoutFormat.fontStyleProperty.concatHelper(this.fontStyle, incoming.fontStyle);
+			this.whiteSpaceCollapse = TextLayoutFormat.whiteSpaceCollapseProperty.concatHelper(this.whiteSpaceCollapse, incoming.whiteSpaceCollapse);
+			this.renderingMode = TextLayoutFormat.renderingModeProperty.concatHelper(this.renderingMode, incoming.renderingMode);
+			this.cffHinting = TextLayoutFormat.cffHintingProperty.concatHelper(this.cffHinting, incoming.cffHinting);
+			this.fontLookup = TextLayoutFormat.fontLookupProperty.concatHelper(this.fontLookup, incoming.fontLookup);
+			this.textRotation = TextLayoutFormat.textRotationProperty.concatHelper(this.textRotation, incoming.textRotation);
+			this.textIndent = TextLayoutFormat.textIndentProperty.concatHelper(this.textIndent, incoming.textIndent);
+			this.paragraphStartIndent = TextLayoutFormat.paragraphStartIndentProperty.concatHelper(this.paragraphStartIndent, incoming.paragraphStartIndent);
+			this.paragraphEndIndent = TextLayoutFormat.paragraphEndIndentProperty.concatHelper(this.paragraphEndIndent, incoming.paragraphEndIndent);
+			this.paragraphSpaceBefore = TextLayoutFormat.paragraphSpaceBeforeProperty.concatHelper(this.paragraphSpaceBefore, incoming.paragraphSpaceBefore);
+			this.paragraphSpaceAfter = TextLayoutFormat.paragraphSpaceAfterProperty.concatHelper(this.paragraphSpaceAfter, incoming.paragraphSpaceAfter);
+			this.textAlign = TextLayoutFormat.textAlignProperty.concatHelper(this.textAlign, incoming.textAlign);
+			this.textAlignLast = TextLayoutFormat.textAlignLastProperty.concatHelper(this.textAlignLast, incoming.textAlignLast);
+			this.textJustify = TextLayoutFormat.textJustifyProperty.concatHelper(this.textJustify, incoming.textJustify);
+			this.justificationRule = TextLayoutFormat.justificationRuleProperty.concatHelper(this.justificationRule, incoming.justificationRule);
+			this.justificationStyle = TextLayoutFormat.justificationStyleProperty.concatHelper(this.justificationStyle, incoming.justificationStyle);
+			this.direction = TextLayoutFormat.directionProperty.concatHelper(this.direction, incoming.direction);
+			this.tabStops = TextLayoutFormat.tabStopsProperty.concatHelper(this.tabStops, incoming.tabStops);
+			this.leadingModel = TextLayoutFormat.leadingModelProperty.concatHelper(this.leadingModel, incoming.leadingModel);
+			this.columnGap = TextLayoutFormat.columnGapProperty.concatHelper(this.columnGap, incoming.columnGap);
+			this.paddingLeft = TextLayoutFormat.paddingLeftProperty.concatHelper(this.paddingLeft, incoming.paddingLeft);
+			this.paddingTop = TextLayoutFormat.paddingTopProperty.concatHelper(this.paddingTop, incoming.paddingTop);
+			this.paddingRight = TextLayoutFormat.paddingRightProperty.concatHelper(this.paddingRight, incoming.paddingRight);
+			this.paddingBottom = TextLayoutFormat.paddingBottomProperty.concatHelper(this.paddingBottom, incoming.paddingBottom);
+			this.columnCount = TextLayoutFormat.columnCountProperty.concatHelper(this.columnCount, incoming.columnCount);
+			this.columnWidth = TextLayoutFormat.columnWidthProperty.concatHelper(this.columnWidth, incoming.columnWidth);
+			this.firstBaselineOffset = TextLayoutFormat.firstBaselineOffsetProperty.concatHelper(this.firstBaselineOffset, incoming.firstBaselineOffset);
+			this.verticalAlign = TextLayoutFormat.verticalAlignProperty.concatHelper(this.verticalAlign, incoming.verticalAlign);
+			this.blockProgression = TextLayoutFormat.blockProgressionProperty.concatHelper(this.blockProgression, incoming.blockProgression);
+			this.lineBreak = TextLayoutFormat.lineBreakProperty.concatHelper(this.lineBreak, incoming.lineBreak);
+		}
+
+		public function concatInheritOnly(incoming:ITextLayoutFormat):void
+		{
+			var holder:TextLayoutFormatValueHolder = incoming as TextLayoutFormatValueHolder;
+			if (holder)
+			{
+				for (var key:String in holder.coreStyles)
+				{
+					this[key] = TextLayoutFormat.description[key].concatInheritOnlyHelper(this[key],holder.coreStyles[key]);
+				}
+				return;
+			}
+
+			this.color = TextLayoutFormat.colorProperty.concatInheritOnlyHelper(this.color, incoming.color);
+			this.backgroundColor = TextLayoutFormat.backgroundColorProperty.concatInheritOnlyHelper(this.backgroundColor, incoming.backgroundColor);
+			this.lineThrough = TextLayoutFormat.lineThroughProperty.concatInheritOnlyHelper(this.lineThrough, incoming.lineThrough);
+			this.textAlpha = TextLayoutFormat.textAlphaProperty.concatInheritOnlyHelper(this.textAlpha, incoming.textAlpha);
+			this.backgroundAlpha = TextLayoutFormat.backgroundAlphaProperty.concatInheritOnlyHelper(this.backgroundAlpha, incoming.backgroundAlpha);
+			this.fontSize = TextLayoutFormat.fontSizeProperty.concatInheritOnlyHelper(this.fontSize, incoming.fontSize);
+			this.baselineShift = TextLayoutFormat.baselineShiftProperty.concatInheritOnlyHelper(this.baselineShift, incoming.baselineShift);
+			this.trackingLeft = TextLayoutFormat.trackingLeftProperty.concatInheritOnlyHelper(this.trackingLeft, incoming.trackingLeft);
+			this.trackingRight = TextLayoutFormat.trackingRightProperty.concatInheritOnlyHelper(this.trackingRight, incoming.trackingRight);
+			this.lineHeight = TextLayoutFormat.lineHeightProperty.concatInheritOnlyHelper(this.lineHeight, incoming.lineHeight);
+			this.breakOpportunity = TextLayoutFormat.breakOpportunityProperty.concatInheritOnlyHelper(this.breakOpportunity, incoming.breakOpportunity);
+			this.digitCase = TextLayoutFormat.digitCaseProperty.concatInheritOnlyHelper(this.digitCase, incoming.digitCase);
+			this.digitWidth = TextLayoutFormat.digitWidthProperty.concatInheritOnlyHelper(this.digitWidth, incoming.digitWidth);
+			this.dominantBaseline = TextLayoutFormat.dominantBaselineProperty.concatInheritOnlyHelper(this.dominantBaseline, incoming.dominantBaseline);
+			this.kerning = TextLayoutFormat.kerningProperty.concatInheritOnlyHelper(this.kerning, incoming.kerning);
+			this.ligatureLevel = TextLayoutFormat.ligatureLevelProperty.concatInheritOnlyHelper(this.ligatureLevel, incoming.ligatureLevel);
+			this.alignmentBaseline = TextLayoutFormat.alignmentBaselineProperty.concatInheritOnlyHelper(this.alignmentBaseline, incoming.alignmentBaseline);
+			this.locale = TextLayoutFormat.localeProperty.concatInheritOnlyHelper(this.locale, incoming.locale);
+			this.typographicCase = TextLayoutFormat.typographicCaseProperty.concatInheritOnlyHelper(this.typographicCase, incoming.typographicCase);
+			this.fontFamily = TextLayoutFormat.fontFamilyProperty.concatInheritOnlyHelper(this.fontFamily, incoming.fontFamily);
+			this.textDecoration = TextLayoutFormat.textDecorationProperty.concatInheritOnlyHelper(this.textDecoration, incoming.textDecoration);
+			this.fontWeight = TextLayoutFormat.fontWeightProperty.concatInheritOnlyHelper(this.fontWeight, incoming.fontWeight);
+			this.fontStyle = TextLayoutFormat.fontStyleProperty.concatInheritOnlyHelper(this.fontStyle, incoming.fontStyle);
+			this.whiteSpaceCollapse = TextLayoutFormat.whiteSpaceCollapseProperty.concatInheritOnlyHelper(this.whiteSpaceCollapse, incoming.whiteSpaceCollapse);
+			this.renderingMode = TextLayoutFormat.renderingModeProperty.concatInheritOnlyHelper(this.renderingMode, incoming.renderingMode);
+			this.cffHinting = TextLayoutFormat.cffHintingProperty.concatInheritOnlyHelper(this.cffHinting, incoming.cffHinting);
+			this.fontLookup = TextLayoutFormat.fontLookupProperty.concatInheritOnlyHelper(this.fontLookup, incoming.fontLookup);
+			this.textRotation = TextLayoutFormat.textRotationProperty.concatInheritOnlyHelper(this.textRotation, incoming.textRotation);
+			this.textIndent = TextLayoutFormat.textIndentProperty.concatInheritOnlyHelper(this.textIndent, incoming.textIndent);
+			this.paragraphStartIndent = TextLayoutFormat.paragraphStartIndentProperty.concatInheritOnlyHelper(this.paragraphStartIndent, incoming.paragraphStartIndent);
+			this.paragraphEndIndent = TextLayoutFormat.paragraphEndIndentProperty.concatInheritOnlyHelper(this.paragraphEndIndent, incoming.paragraphEndIndent);
+			this.paragraphSpaceBefore = TextLayoutFormat.paragraphSpaceBeforeProperty.concatInheritOnlyHelper(this.paragraphSpaceBefore, incoming.paragraphSpaceBefore);
+			this.paragraphSpaceAfter = TextLayoutFormat.paragraphSpaceAfterProperty.concatInheritOnlyHelper(this.paragraphSpaceAfter, incoming.paragraphSpaceAfter);
+			this.textAlign = TextLayoutFormat.textAlignProperty.concatInheritOnlyHelper(this.textAlign, incoming.textAlign);
+			this.textAlignLast = TextLayoutFormat.textAlignLastProperty.concatInheritOnlyHelper(this.textAlignLast, incoming.textAlignLast);
+			this.textJustify = TextLayoutFormat.textJustifyProperty.concatInheritOnlyHelper(this.textJustify, incoming.textJustify);
+			this.justificationRule = TextLayoutFormat.justificationRuleProperty.concatInheritOnlyHelper(this.justificationRule, incoming.justificationRule);
+			this.justificationStyle = TextLayoutFormat.justificationStyleProperty.concatInheritOnlyHelper(this.justificationStyle, incoming.justificationStyle);
+			this.direction = TextLayoutFormat.directionProperty.concatInheritOnlyHelper(this.direction, incoming.direction);
+			this.tabStops = TextLayoutFormat.tabStopsProperty.concatInheritOnlyHelper(this.tabStops, incoming.tabStops);
+			this.leadingModel = TextLayoutFormat.leadingModelProperty.concatInheritOnlyHelper(this.leadingModel, incoming.leadingModel);
+			this.columnGap = TextLayoutFormat.columnGapProperty.concatInheritOnlyHelper(this.columnGap, incoming.columnGap);
+			this.paddingLeft = TextLayoutFormat.paddingLeftProperty.concatInheritOnlyHelper(this.paddingLeft, incoming.paddingLeft);
+			this.paddingTop = TextLayoutFormat.paddingTopProperty.concatInheritOnlyHelper(this.paddingTop, incoming.paddingTop);
+			this.paddingRight = TextLayoutFormat.paddingRightProperty.concatInheritOnlyHelper(this.paddingRight, incoming.paddingRight);
+			this.paddingBottom = TextLayoutFormat.paddingBottomProperty.concatInheritOnlyHelper(this.paddingBottom, incoming.paddingBottom);
+			this.columnCount = TextLayoutFormat.columnCountProperty.concatInheritOnlyHelper(this.columnCount, incoming.columnCount);
+			this.columnWidth = TextLayoutFormat.columnWidthProperty.concatInheritOnlyHelper(this.columnWidth, incoming.columnWidth);
+			this.firstBaselineOffset = TextLayoutFormat.firstBaselineOffsetProperty.concatInheritOnlyHelper(this.firstBaselineOffset, incoming.firstBaselineOffset);
+			this.verticalAlign = TextLayoutFormat.verticalAlignProperty.concatInheritOnlyHelper(this.verticalAlign, incoming.verticalAlign);
+			this.blockProgression = TextLayoutFormat.blockProgressionProperty.concatInheritOnlyHelper(this.blockProgression, incoming.blockProgression);
+			this.lineBreak = TextLayoutFormat.lineBreakProperty.concatInheritOnlyHelper(this.lineBreak, incoming.lineBreak);
+		}
+
+		public function apply(incoming:ITextLayoutFormat):void
+		{
+			var holder:TextLayoutFormatValueHolder = incoming as TextLayoutFormatValueHolder;
+			if (holder)
+			{
+				for (var key:String in holder.coreStyles)
+				{
+					CONFIG::debug { assert(holder.coreStyles[key] !== undefined,"bad value in apply"); }
+					this[key] = holder.coreStyles[key];
+				}
+				return;
+			}
+
+			var val:*;
+			if ((val = incoming.color) !== undefined)
+				this.color = val;
+			if ((val = incoming.backgroundColor) !== undefined)
+				this.backgroundColor = val;
+			if ((val = incoming.lineThrough) !== undefined)
+				this.lineThrough = val;
+			if ((val = incoming.textAlpha) !== undefined)
+				this.textAlpha = val;
+			if ((val = incoming.backgroundAlpha) !== undefined)
+				this.backgroundAlpha = val;
+			if ((val = incoming.fontSize) !== undefined)
+				this.fontSize = val;
+			if ((val = incoming.baselineShift) !== undefined)
+				this.baselineShift = val;
+			if ((val = incoming.trackingLeft) !== undefined)
+				this.trackingLeft = val;
+			if ((val = incoming.trackingRight) !== undefined)
+				this.trackingRight = val;
+			if ((val = incoming.lineHeight) !== undefined)
+				this.lineHeight = val;
+			if ((val = incoming.breakOpportunity) !== undefined)
+				this.breakOpportunity = val;
+			if ((val = incoming.digitCase) !== undefined)
+				this.digitCase = val;
+			if ((val = incoming.digitWidth) !== undefined)
+				this.digitWidth = val;
+			if ((val = incoming.dominantBaseline) !== undefined)
+				this.dominantBaseline = val;
+			if ((val = incoming.kerning) !== undefined)
+				this.kerning = val;
+			if ((val = incoming.ligatureLevel) !== undefined)
+				this.ligatureLevel = val;
+			if ((val = incoming.alignmentBaseline) !== undefined)
+				this.alignmentBaseline = val;
+			if ((val = incoming.locale) !== undefined)
+				this.locale = val;
+			if ((val = incoming.typographicCase) !== undefined)
+				this.typographicCase = val;
+			if ((val = incoming.fontFamily) !== undefined)
+				this.fontFamily = val;
+			if ((val = incoming.textDecoration) !== undefined)
+				this.textDecoration = val;
+			if ((val = incoming.fontWeight) !== undefined)
+				this.fontWeight = val;
+			if ((val = incoming.fontStyle) !== undefined)
+				this.fontStyle = val;
+			if ((val = incoming.whiteSpaceCollapse) !== undefined)
+				this.whiteSpaceCollapse = val;
+			if ((val = incoming.renderingMode) !== undefined)
+				this.renderingMode = val;
+			if ((val = incoming.cffHinting) !== undefined)
+				this.cffHinting = val;
+			if ((val = incoming.fontLookup) !== undefined)
+				this.fontLookup = val;
+			if ((val = incoming.textRotation) !== undefined)
+				this.textRotation = val;
+			if ((val = incoming.textIndent) !== undefined)
+				this.textIndent = val;
+			if ((val = incoming.paragraphStartIndent) !== undefined)
+				this.paragraphStartIndent = val;
+			if ((val = incoming.paragraphEndIndent) !== undefined)
+				this.paragraphEndIndent = val;
+			if ((val = incoming.paragraphSpaceBefore) !== undefined)
+				this.paragraphSpaceBefore = val;
+			if ((val = incoming.paragraphSpaceAfter) !== undefined)
+				this.paragraphSpaceAfter = val;
+			if ((val = incoming.textAlign) !== undefined)
+				this.textAlign = val;
+			if ((val = incoming.textAlignLast) !== undefined)
+				this.textAlignLast = val;
+			if ((val = incoming.textJustify) !== undefined)
+				this.textJustify = val;
+			if ((val = incoming.justificationRule) !== undefined)
+				this.justificationRule = val;
+			if ((val = incoming.justificationStyle) !== undefined)
+				this.justificationStyle = val;
+			if ((val = incoming.direction) !== undefined)
+				this.direction = val;
+			if ((val = incoming.tabStops) !== undefined)
+				this.tabStops = val;
+			if ((val = incoming.leadingModel) !== undefined)
+				this.leadingModel = val;
+			if ((val = incoming.columnGap) !== undefined)
+				this.columnGap = val;
+			if ((val = incoming.paddingLeft) !== undefined)
+				this.paddingLeft = val;
+			if ((val = incoming.paddingTop) !== undefined)
+				this.paddingTop = val;
+			if ((val = incoming.paddingRight) !== undefined)
+				this.paddingRight = val;
+			if ((val = incoming.paddingBottom) !== undefined)
+				this.paddingBottom = val;
+			if ((val = incoming.columnCount) !== undefined)
+				this.columnCount = val;
+			if ((val = incoming.columnWidth) !== undefined)
+				this.columnWidth = val;
+			if ((val = incoming.firstBaselineOffset) !== undefined)
+				this.firstBaselineOffset = val;
+			if ((val = incoming.verticalAlign) !== undefined)
+				this.verticalAlign = val;
+			if ((val = incoming.blockProgression) !== undefined)
+				this.blockProgression = val;
+			if ((val = incoming.lineBreak) !== undefined)
+				this.lineBreak = val;
+		}
+
+		/**
+		 * TextLayoutFormat:
+		 * Color of the text. A hexadecimal number that specifies three 8-bit RGB (red, green, blue) values; for example, 0xFF0000 is red and 0x00FF00 is green. 
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get color():*
+		{ return getCoreStyle("color"); }
+		public function set color(value:*):void
+		{ setCoreStyle(TextLayoutFormat.colorProperty,color,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Background color of the text (adopts default value if undefined during cascade). Can be either the constant value  <code>BackgroundColor.TRANSPARENT</code>, or a hexadecimal value that specifies the three 8-bit RGB (red, green, blue) values; for example, 0xFF0000 is red and 0x00FF00 is green.
+		 * <p>Legal values as a string are flashx.textLayout.formats.BackgroundColor.TRANSPARENT, flashx.textLayout.formats.FormatValue.INHERIT and uints from 0x0 to 0xffffffff.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of TRANSPARENT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.BackgroundColor
+		 */
+		public function get backgroundColor():*
+		{ return getCoreStyle("backgroundColor"); }
+		public function set backgroundColor(value:*):void
+		{ setCoreStyle(TextLayoutFormat.backgroundColorProperty,backgroundColor,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * If <code>true</code>, applies strikethrough, a line drawn through the middle of the text.
+		 * <p>Legal values are true, false and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of false.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get lineThrough():*
+		{ return getCoreStyle("lineThrough"); }
+		public function set lineThrough(value:*):void
+		{ setCoreStyle(TextLayoutFormat.lineThroughProperty,lineThrough,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Alpha (transparency) value for the text. A value of 0 is fully transparent, and a value of 1 is fully opaque. Display objects with <code>textAlpha</code> set to 0 are active, even though they are invisible.
+		 * <p>Legal values are numbers from 0 to 1 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 1.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get textAlpha():*
+		{ return getCoreStyle("textAlpha"); }
+		public function set textAlpha(value:*):void
+		{ setCoreStyle(TextLayoutFormat.textAlphaProperty,textAlpha,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Alpha (transparency) value for the background (adopts default value if undefined during cascade). A value of 0 is fully transparent, and a value of 1 is fully opaque. Display objects with alpha set to 0 are active, even though they are invisible.
+		 * <p>Legal values are numbers from 0 to 1 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 1.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get backgroundAlpha():*
+		{ return getCoreStyle("backgroundAlpha"); }
+		public function set backgroundAlpha(value:*):void
+		{ setCoreStyle(TextLayoutFormat.backgroundAlphaProperty,backgroundAlpha,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * The size of the text in pixels.
+		 * <p>Legal values are numbers from 1 to 720 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 12.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get fontSize():*
+		{ return getCoreStyle("fontSize"); }
+		public function set fontSize(value:*):void
+		{ setCoreStyle(TextLayoutFormat.fontSizeProperty,fontSize,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Amount to shift the baseline from the <code>dominantBaseline</code> value. Units are in pixels, or a percentage of <code>fontSize</code> (in which case, enter a string value, like 140%).  Positive values shift the line up for horizontal text (right for vertical) and negative values shift it down for horizontal (left for vertical). 
+		 * <p>Legal values are flashx.textLayout.formats.BaselineShift.SUPERSCRIPT, flashx.textLayout.formats.BaselineShift.SUBSCRIPT, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Legal values as a number are from -1000 to 1000.</p>
+		 * <p>Legal values as a percent are numbers from -1000 to 1000.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.BaselineShift
+		 */
+		public function get baselineShift():*
+		{ return getCoreStyle("baselineShift"); }
+		public function set baselineShift(value:*):void
+		{ setCoreStyle(TextLayoutFormat.baselineShiftProperty,baselineShift,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Number in pixels (or percent of <code>fontSize</code>, like 120%) indicating the amount of tracking (manual kerning) to be applied to the left of each character. If kerning is enabled, the <code>trackingLeft</code> value is added to the values in the kerning table for the font. If kerning is disabled, the <code>trackingLeft</code> value is used as a manual kerning value. Supports both positive and negative values. 
+		 * <p>Legal values as a number are from -1000 to 1000.</p>
+		 * <p>Legal values as a percent are numbers from -1000% to 1000%.</p>
+		 * <p>Legal values include flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get trackingLeft():*
+		{ return getCoreStyle("trackingLeft"); }
+		public function set trackingLeft(value:*):void
+		{ setCoreStyle(TextLayoutFormat.trackingLeftProperty,trackingLeft,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Number in pixels (or percent of <code>fontSize</code>, like 120%) indicating the amount of tracking (manual kerning) to be applied to the right of each character.  If kerning is enabled, the <code>trackingRight</code> value is added to the values in the kerning table for the font. If kerning is disabled, the <code>trackingRight</code> value is used as a manual kerning value. Supports both positive and negative values. 
+		 * <p>Legal values as a number are from -1000 to 1000.</p>
+		 * <p>Legal values as a percent are numbers from -1000% to 1000%.</p>
+		 * <p>Legal values include flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get trackingRight():*
+		{ return getCoreStyle("trackingRight"); }
+		public function set trackingRight(value:*):void
+		{ setCoreStyle(TextLayoutFormat.trackingRightProperty,trackingRight,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Leading controls for the text. The distance from the baseline of the previous or the next line (based on <code>LeadingModel</code>) to the baseline of the current line is equal to the maximum amount of the leading applied to any character in the line. This is either a number or a percent.  If specifying a percent, enter a string value, like 140%.<p><img src='../../../images/textLayout_lineHeight1.jpg' alt='lineHeight1' /><img src='../../../images/textLayout_lineHeight2.jpg' alt='lineHeight2' /></p>
+		 * <p>Legal values as a number are from -720 to 720.</p>
+		 * <p>Legal values as a percent are numbers from -1000% to 1000%.</p>
+		 * <p>Legal values include flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 120%.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get lineHeight():*
+		{ return getCoreStyle("lineHeight"); }
+		public function set lineHeight(value:*):void
+		{ setCoreStyle(TextLayoutFormat.lineHeightProperty,lineHeight,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Controls where lines are allowed to break when breaking wrapping text into multiple lines. Set to <code>BreakOpportunity.AUTO</code> to break text normally. Set to <code>BreakOpportunity.NONE</code> to <em>not</em> break the text unless the text would overrun the measure and there are no other places to break the line. Set to <code>BreakOpportunity.ANY</code> to allow the line to break anywhere, rather than just between words. Set to <code>BreakOpportunity.ALL</code> to have each typographic cluster put on a separate line (useful for text on a path).
+		 * <p>Legal values are flash.text.engine.BreakOpportunity.ALL, flash.text.engine.BreakOpportunity.ANY, flash.text.engine.BreakOpportunity.AUTO, flash.text.engine.BreakOpportunity.NONE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.BreakOpportunity
+		 */
+		public function get breakOpportunity():*
+		{ return getCoreStyle("breakOpportunity"); }
+		public function set breakOpportunity(value:*):void
+		{ setCoreStyle(TextLayoutFormat.breakOpportunityProperty,breakOpportunity,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * The type of digit case used for this text. Setting the value to <code>DigitCase.OLD_STYLE</code> approximates lowercase letterforms with varying ascenders and descenders. The figures are proportionally spaced. This style is only available in selected typefaces, most commonly in a supplemental or expert font. The <code>DigitCase.LINING</code> setting has all-cap height and is typically monospaced to line up in charts.<p><img src='../../../images/textLayout_digitcase.gif' alt='digitCase' /></p>
+		 * <p>Legal values are flash.text.engine.DigitCase.DEFAULT, flash.text.engine.DigitCase.LINING, flash.text.engine.DigitCase.OLD_STYLE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of DEFAULT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.DigitCase
+		 */
+		public function get digitCase():*
+		{ return getCoreStyle("digitCase"); }
+		public function set digitCase(value:*):void
+		{ setCoreStyle(TextLayoutFormat.digitCaseProperty,digitCase,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Type of digit width used for this text. This can be <code>DigitWidth.PROPORTIONAL</code>, which looks best for individual numbers, or <code>DigitWidth.TABULAR</code>, which works best for numbers in tables, charts, and vertical rows.<p><img src='../../../images/textLayout_digitwidth.gif' alt='digitWidth' /></p>
+		 * <p>Legal values are flash.text.engine.DigitWidth.DEFAULT, flash.text.engine.DigitWidth.PROPORTIONAL, flash.text.engine.DigitWidth.TABULAR, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of DEFAULT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.DigitWidth
+		 */
+		public function get digitWidth():*
+		{ return getCoreStyle("digitWidth"); }
+		public function set digitWidth(value:*):void
+		{ setCoreStyle(TextLayoutFormat.digitWidthProperty,digitWidth,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Specifies which element baseline snaps to the <code>alignmentBaseline</code> to determine the vertical position of the element on the line. A value of <code>TextBaseline.AUTO</code> selects the dominant baseline based on the <code>locale</code> property of the parent paragraph.  For Japanese and Chinese, the selected baseline value is <code>TextBaseline.IDEOGRAPHIC_CENTER</code>; for all others it is <code>TextBaseline.ROMAN</code>. These baseline choices are determined by the choice of font and the font size.<p><img src='../../../images/textLayout_baselines.jpg' alt='baselines' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.FormatValue.AUTO, flash.text.engine.TextBaseline.ROMAN, flash.text.engine.TextBaseline.ASCENT, flash.text.engine.TextBaseline.DESCENT, flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP, flash.text.engine.TextBaseline.IDEOGRAPHIC_CENTER, flash.text.engine.TextBaseline.IDEOGRAPHIC_BOTTOM, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of flashx.textLayout.formats.FormatValue.AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.TextBaseline
+		 */
+		public function get dominantBaseline():*
+		{ return getCoreStyle("dominantBaseline"); }
+		public function set dominantBaseline(value:*):void
+		{ setCoreStyle(TextLayoutFormat.dominantBaselineProperty,dominantBaseline,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Kerning adjusts the pixels between certain character pairs to improve readability. Kerning is supported for all fonts with kerning tables.
+		 * <p>Legal values are flash.text.engine.Kerning.ON, flash.text.engine.Kerning.OFF, flash.text.engine.Kerning.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.Kerning
+		 */
+		public function get kerning():*
+		{ return getCoreStyle("kerning"); }
+		public function set kerning(value:*):void
+		{ setCoreStyle(TextLayoutFormat.kerningProperty,kerning,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Controls which of the ligatures that are defined in the font may be used in the text. The ligatures that appear for each of these settings is dependent on the font. A ligature occurs where two or more letter-forms are joined as a single glyph. Ligatures usually replace consecutive characters sharing common components, such as the letter pairs 'fi', 'fl', or 'ae'. They are used with both Latin and Non-Latin character sets. The ligatures enabled by the values of the LigatureLevel class - <code>MINIMUM</code>, <code>COMMON</code>, <code>UNCOMMON</code>, and <code>EXOTIC</code> - are additive. Each value enables a new set of ligatures, but also includes those of the previous types.<p><b>Note: </b>When working with Arabic or Syriac fonts, <code>ligatureLevel</code> must be set to MINIMUM or above.</p><p><img src='../../../images/textLayout_ligatures.png' alt='ligatureLevel' /></p>
+		 * <p>Legal values are flash.text.engine.LigatureLevel.MINIMUM, flash.text.engine.LigatureLevel.COMMON, flash.text.engine.LigatureLevel.UNCOMMON, flash.text.engine.LigatureLevel.EXOTIC, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of COMMON.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.LigatureLevel
+		 */
+		public function get ligatureLevel():*
+		{ return getCoreStyle("ligatureLevel"); }
+		public function set ligatureLevel(value:*):void
+		{ setCoreStyle(TextLayoutFormat.ligatureLevelProperty,ligatureLevel,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Specifies the baseline to which the dominant baseline aligns. For example, if you set <code>dominantBaseline</code> to ASCENT, setting <code>alignmentBaseline</code> to DESCENT aligns the top of the text with the DESCENT baseline, or below the line.  The largest element in the line generally determines the baselines.<p><img src='../../../images/textLayout_baselines.jpg' alt='baselines' /></p>
+		 * <p>Legal values are flash.text.engine.TextBaseline.ROMAN, flash.text.engine.TextBaseline.ASCENT, flash.text.engine.TextBaseline.DESCENT, flash.text.engine.TextBaseline.IDEOGRAPHIC_TOP, flash.text.engine.TextBaseline.IDEOGRAPHIC_CENTER, flash.text.engine.TextBaseline.IDEOGRAPHIC_BOTTOM, flash.text.engine.TextBaseline.USE_DOMINANT_BASELINE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of USE_DOMINANT_BASELINE.</p>
+		 * @includeExample examples\TextLayoutFormat_alignmentBaselineExample.as -noswf
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.TextBaseline
+		 */
+		public function get alignmentBaseline():*
+		{ return getCoreStyle("alignmentBaseline"); }
+		public function set alignmentBaseline(value:*):void
+		{ setCoreStyle(TextLayoutFormat.alignmentBaselineProperty,alignmentBaseline,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * The locale of the text. Controls case transformations and shaping. Standard locale identifiers as described in Unicode Technical Standard #35 are used. For example en, en_US and en-US are all English, ja is Japanese. 
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of en.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get locale():*
+		{ return getCoreStyle("locale"); }
+		public function set locale(value:*):void
+		{ setCoreStyle(TextLayoutFormat.localeProperty,locale,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * The type of typographic case used for this text. Here are some examples:<p><img src='../../../images/textLayout_typographiccase.png' alt='typographicCase' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.TLFTypographicCase.DEFAULT, flashx.textLayout.formats.TLFTypographicCase.CAPS_TO_SMALL_CAPS, flashx.textLayout.formats.TLFTypographicCase.UPPERCASE, flashx.textLayout.formats.TLFTypographicCase.LOWERCASE, flashx.textLayout.formats.TLFTypographicCase.LOWERCASE_TO_SMALL_CAPS, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of DEFAULT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TLFTypographicCase
+		 */
+		public function get typographicCase():*
+		{ return getCoreStyle("typographicCase"); }
+		public function set typographicCase(value:*):void
+		{ setCoreStyle(TextLayoutFormat.typographicCaseProperty,typographicCase,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 *  The name of the font to use, or a comma-separated list of font names. The Flash runtime renders the element with the first available font in the list. For example Arial, Helvetica, _sans causes the player to search for Arial, then Helvetica if Arial is not found, then _sans if neither is found.
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of Arial.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get fontFamily():*
+		{ return getCoreStyle("fontFamily"); }
+		public function set fontFamily(value:*):void
+		{ setCoreStyle(TextLayoutFormat.fontFamilyProperty,fontFamily,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Decoration on text. Use to apply underlining; default is none.
+		 * <p>Legal values are flashx.textLayout.formats.TextDecoration.NONE, flashx.textLayout.formats.TextDecoration.UNDERLINE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of NONE.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TextDecoration
+		 */
+		public function get textDecoration():*
+		{ return getCoreStyle("textDecoration"); }
+		public function set textDecoration(value:*):void
+		{ setCoreStyle(TextLayoutFormat.textDecorationProperty,textDecoration,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Weight of text. May be <code>FontWeight.NORMAL</code> for use in plain text, or <code>FontWeight.BOLD</code>. Applies only to device fonts (<code>fontLookup</code> property is set to flash.text.engine.FontLookup.DEVICE).
+		 * <p>Legal values are flash.text.engine.FontWeight.NORMAL, flash.text.engine.FontWeight.BOLD, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of NORMAL.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.FontWeight
+		 */
+		public function get fontWeight():*
+		{ return getCoreStyle("fontWeight"); }
+		public function set fontWeight(value:*):void
+		{ setCoreStyle(TextLayoutFormat.fontWeightProperty,fontWeight,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Style of text. May be <code>FontPosture.NORMAL</code>, for use in plain text, or <code>FontPosture.ITALIC</code> for italic. This property applies only to device fonts (<code>fontLookup</code> property is set to flash.text.engine.FontLookup.DEVICE).
+		 * <p>Legal values are flash.text.engine.FontPosture.NORMAL, flash.text.engine.FontPosture.ITALIC, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of NORMAL.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.FontPosture
+		 */
+		public function get fontStyle():*
+		{ return getCoreStyle("fontStyle"); }
+		public function set fontStyle(value:*):void
+		{ setCoreStyle(TextLayoutFormat.fontStyleProperty,fontStyle,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Collapses or preserves whitespace when importing text into a TextFlow. <code>WhiteSpaceCollapse.PRESERVE</code> retains all whitespace characters. <code>WhiteSpaceCollapse.COLLAPSE</code> removes newlines, tabs, and leading or trailing spaces within a block of imported text. Line break tags (<br/>) and Unicode line separator characters are retained.
+		 * <p>Legal values are flashx.textLayout.formats.WhiteSpaceCollapse.PRESERVE, flashx.textLayout.formats.WhiteSpaceCollapse.COLLAPSE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of COLLAPSE.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.WhiteSpaceCollapse
+		 */
+		public function get whiteSpaceCollapse():*
+		{ return getCoreStyle("whiteSpaceCollapse"); }
+		public function set whiteSpaceCollapse(value:*):void
+		{ setCoreStyle(TextLayoutFormat.whiteSpaceCollapseProperty,whiteSpaceCollapse,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * The rendering mode used for this text.  Applies only to embedded fonts (<code>fontLookup</code> property is set to <code>FontLookup.EMBEDDED_CFF</code>).
+		 * <p>Legal values are flash.text.engine.RenderingMode.NORMAL, flash.text.engine.RenderingMode.CFF, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of CFF.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.RenderingMode
+		 */
+		public function get renderingMode():*
+		{ return getCoreStyle("renderingMode"); }
+		public function set renderingMode(value:*):void
+		{ setCoreStyle(TextLayoutFormat.renderingModeProperty,renderingMode,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * The type of CFF hinting used for this text. CFF hinting determines whether the Flash runtime forces strong horizontal stems to fit to a sub pixel grid or not. This property applies only if the <code>renderingMode</code> property is set to <code>RenderingMode.CFF</code>, and the font is embedded (<code>fontLookup</code> property is set to <code>FontLookup.EMBEDDED_CFF</code>). At small screen sizes, hinting produces a clear, legible text for human readers.
+		 * <p>Legal values are flash.text.engine.CFFHinting.NONE, flash.text.engine.CFFHinting.HORIZONTAL_STEM, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of HORIZONTAL_STEM.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.CFFHinting
+		 */
+		public function get cffHinting():*
+		{ return getCoreStyle("cffHinting"); }
+		public function set cffHinting(value:*):void
+		{ setCoreStyle(TextLayoutFormat.cffHintingProperty,cffHinting,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Font lookup to use. Specifying <code>FontLookup.DEVICE</code> uses the fonts installed on the system that is running the SWF file. Device fonts result in a smaller movie size, but text is not always rendered the same across different systems and platforms. Specifying <code>FontLookup.EMBEDDED_CFF</code> uses font outlines embedded in the published SWF file. Embedded fonts increase the size of the SWF file (sometimes dramatically), but text is consistently displayed in the chosen font.
+		 * <p>Legal values are flash.text.engine.FontLookup.DEVICE, flash.text.engine.FontLookup.EMBEDDED_CFF, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of DEVICE.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.FontLookup
+		 */
+		public function get fontLookup():*
+		{ return getCoreStyle("fontLookup"); }
+		public function set fontLookup(value:*):void
+		{ setCoreStyle(TextLayoutFormat.fontLookupProperty,fontLookup,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Determines the number of degrees to rotate this text.
+		 * <p>Legal values are flash.text.engine.TextRotation.ROTATE_0, flash.text.engine.TextRotation.ROTATE_180, flash.text.engine.TextRotation.ROTATE_270, flash.text.engine.TextRotation.ROTATE_90, flash.text.engine.TextRotation.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.TextRotation
+		 */
+		public function get textRotation():*
+		{ return getCoreStyle("textRotation"); }
+		public function set textRotation(value:*):void
+		{ setCoreStyle(TextLayoutFormat.textRotationProperty,textRotation,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * A Number that specifies, in pixels, the amount to indent the first line of the paragraph.
+		 * A negative indent will push the line into the margin, and possibly out of the container.
+		 * <p>Legal values are numbers from -1000 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get textIndent():*
+		{ return getCoreStyle("textIndent"); }
+		public function set textIndent(value:*):void
+		{ setCoreStyle(TextLayoutFormat.textIndentProperty,textIndent,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * A Number that specifies, in pixels, the amount to indent the paragraph's start edge. Refers to the left edge in left-to-right text and the right edge in right-to-left text. 
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paragraphStartIndent():*
+		{ return getCoreStyle("paragraphStartIndent"); }
+		public function set paragraphStartIndent(value:*):void
+		{ setCoreStyle(TextLayoutFormat.paragraphStartIndentProperty,paragraphStartIndent,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * A Number that specifies, in pixels, the amount to indent the paragraph's end edge. Refers to the right edge in left-to-right text and the left edge in right-to-left text. 
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paragraphEndIndent():*
+		{ return getCoreStyle("paragraphEndIndent"); }
+		public function set paragraphEndIndent(value:*):void
+		{ setCoreStyle(TextLayoutFormat.paragraphEndIndentProperty,paragraphEndIndent,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * A Number that specifies the amount of space, in pixels, to leave before the paragraph. 
+		 * Collapses in tandem with <code>paragraphSpaceAfter</code>.
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paragraphSpaceBefore():*
+		{ return getCoreStyle("paragraphSpaceBefore"); }
+		public function set paragraphSpaceBefore(value:*):void
+		{ setCoreStyle(TextLayoutFormat.paragraphSpaceBeforeProperty,paragraphSpaceBefore,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * A Number that specifies the amount of space, in pixels, to leave after the paragraph.
+		 * Collapses in tandem with  <code>paragraphSpaceBefore</code>.
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paragraphSpaceAfter():*
+		{ return getCoreStyle("paragraphSpaceAfter"); }
+		public function set paragraphSpaceAfter(value:*):void
+		{ setCoreStyle(TextLayoutFormat.paragraphSpaceAfterProperty,paragraphSpaceAfter,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Alignment of lines in the paragraph relative to the container.
+		 * <code>TextAlign.LEFT</code> aligns lines along the left edge of the container. <code>TextAlign.RIGHT</code> aligns on the right edge. <code>TextAlign.CENTER</code> positions the line equidistant from the left and right edges. <code>TextAlign.JUSTIFY</code> spreads the lines out so they fill the space. <code>TextAlign.START</code> is equivalent to setting left in left-to-right text, or right in right-to-left text. <code>TextAlign.END</code> is equivalent to setting right in left-to-right text, or left in right-to-left text.
+		 * <p>Legal values are flashx.textLayout.formats.TextAlign.LEFT, flashx.textLayout.formats.TextAlign.RIGHT, flashx.textLayout.formats.TextAlign.CENTER, flashx.textLayout.formats.TextAlign.JUSTIFY, flashx.textLayout.formats.TextAlign.START, flashx.textLayout.formats.TextAlign.END, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of START.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TextAlign
+		 */
+		public function get textAlign():*
+		{ return getCoreStyle("textAlign"); }
+		public function set textAlign(value:*):void
+		{ setCoreStyle(TextLayoutFormat.textAlignProperty,textAlign,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Alignment of the last (or only) line in the paragraph relative to the container in justified text.
+		 * If <code>textAlign</code> is set to <code>TextAlign.JUSTIFY</code>, <code>textAlignLast</code> specifies how the last line (or only line, if this is a one line block) is aligned. Values are similar to <code>textAlign</code>.
+		 * <p>Legal values are flashx.textLayout.formats.TextAlign.LEFT, flashx.textLayout.formats.TextAlign.RIGHT, flashx.textLayout.formats.TextAlign.CENTER, flashx.textLayout.formats.TextAlign.JUSTIFY, flashx.textLayout.formats.TextAlign.START, flashx.textLayout.formats.TextAlign.END, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of START.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TextAlign
+		 */
+		public function get textAlignLast():*
+		{ return getCoreStyle("textAlignLast"); }
+		public function set textAlignLast(value:*):void
+		{ setCoreStyle(TextLayoutFormat.textAlignLastProperty,textAlignLast,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Specifies options for justifying text.
+		 * Default value is <code>TextJustify.INTER_WORD</code>, meaning that extra space is added to the space characters. <code>TextJustify.DISTRIBUTE</code> adds extra space to space characters and between individual letters. Used only in conjunction with a <code>justificationRule</code> value of <code>JustificationRule.SPACE</code>.
+		 * <p>Legal values are flashx.textLayout.formats.TextJustify.INTER_WORD, flashx.textLayout.formats.TextJustify.DISTRIBUTE, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of INTER_WORD.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.TextJustify
+		 */
+		public function get textJustify():*
+		{ return getCoreStyle("textJustify"); }
+		public function set textJustify(value:*):void
+		{ setCoreStyle(TextLayoutFormat.textJustifyProperty,textJustify,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Rule used to justify text in a paragraph.
+		 * Default value is <code>FormatValue.AUTO</code>, which justifies text based on the paragraph's <code>locale</code> property. For all languages except Japanese and Chinese, <code>FormatValue.AUTO</code> becomes <code>JustificationRule.SPACE</code>, which adds extra space to the space characters.  For Japanese and Chinese, <code>FormatValue.AUTO</code> becomes <code>JustficationRule.EAST_ASIAN</code>. In part, justification changes the spacing of punctuation. In Roman text the comma and Japanese periods take a full character's width but in East Asian text only half of a character's width. Also, in the East Asian text the spacing between sequential punctuation marks becomes tighter, obeying traditional East Asian typographic conventions. Note, too, in the example below the leading that is applied to the second line of the paragraphs. In the East Asian version, the last two lines push left. In the Roman version, the second and following lines push left.<p><img src='../../../images/textLayout_justificationrule.png' alt='justificationRule' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.JustificationRule.EAST_ASIAN, flashx.textLayout.formats.JustificationRule.SPACE, flashx.textLayout.formats.FormatValue.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of flashx.textLayout.formats.FormatValue.AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.JustificationRule
+		 */
+		public function get justificationRule():*
+		{ return getCoreStyle("justificationRule"); }
+		public function set justificationRule(value:*):void
+		{ setCoreStyle(TextLayoutFormat.justificationRuleProperty,justificationRule,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * The style used for justification of the paragraph. Used only in conjunction with a <code>justificationRule</code> setting of <code>JustificationRule.EAST_ASIAN</code>.
+		 * Default value of <code>FormatValue.AUTO</code> is resolved to <code>JustificationStyle.PUSH_IN_KINSOKU</code> for all locales.  The constants defined by the JustificationStyle class specify options for handling kinsoku characters, which are Japanese characters that cannot appear at either the beginning or end of a line. If you want looser text, specify <code>JustificationStyle.PUSH-OUT-ONLY</code>. If you want behavior that is like what you get with the  <code>justificationRule</code> of <code>JustificationRule.SPACE</code>, use <code>JustificationStyle.PRIORITIZE-LEAST-ADJUSTMENT</code>.
+		 * <p>Legal values are flash.text.engine.JustificationStyle.PRIORITIZE_LEAST_ADJUSTMENT, flash.text.engine.JustificationStyle.PUSH_IN_KINSOKU, flash.text.engine.JustificationStyle.PUSH_OUT_ONLY, flashx.textLayout.formats.FormatValue.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of flashx.textLayout.formats.FormatValue.AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flash.text.engine.JustificationStyle
+		 */
+		public function get justificationStyle():*
+		{ return getCoreStyle("justificationStyle"); }
+		public function set justificationStyle(value:*):void
+		{ setCoreStyle(TextLayoutFormat.justificationStyleProperty,justificationStyle,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Specifies the default bidirectional embedding level of the text in the text block. 
+		 * Left-to-right reading order, as in Latin-style scripts, or right-to-left reading order, as in Arabic or Hebrew. This property also affects column direction when it is applied at the container level. Columns can be either left-to-right or right-to-left, just like text. Below are some examples:<p><img src='../../../images/textLayout_direction.gif' alt='direction' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.Direction.LTR, flashx.textLayout.formats.Direction.RTL, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of LTR.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.Direction
+		 */
+		public function get direction():*
+		{ return getCoreStyle("direction"); }
+		public function set direction(value:*):void
+		{ setCoreStyle(TextLayoutFormat.directionProperty,direction,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Specifies the tab stops associated with the paragraph.
+		 * Setters can take an array of flashx.textLayout.formats.TabStopFormat, a condensed string representation, undefined, or <code>FormatValue.INHERIT</code>. The condensed string representation is always converted into an array of flashx.textLayout.formats.TabStopFormat. <p>The string-based format is a list of tab stops, where each tab stop is delimited by one or more spaces.</p><p>A tab stop takes the following form: &lt;alignment type&gt;&lt;alignment position&gt;|&lt;alignment token&gt;.</p><p>The alignment type is a single character, and can be S, E, C, or D (or lower-case equivalents). S or s for start, E or e for end, C or c for center, D or d for decimal. The alignment type is optional, and if its not specified will default to S.</p><p>The alignment position is a Number, and is specified according to FXG spec for Numbers (decimal or scientific notation). The alignment position is required.</p><p>The vertical bar is used to separate the alignment position from the alignment token, and should only be present if the alignment token is present.</p><p> The alignment token is optional if the alignment type is D, and should not be present if the alignment type is anything other than D. The alignment token may be any sequence of characters terminated by the space that ends the tab stop (for the last tab stop, the terminating space is optional; end of alignment token is implied). A space may be part of the alignment token if it is escaped with a backslash (\ ). A backslash may be part of the alignment token if it is escaped with another backslash (\\). If the alignment type is D, and the alignment token is not specified, it will take on the default value of null.</p><p>If no tab stops are specified, a tab action defaults to the end of the line.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of null.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get tabStops():*
+		{ return getCoreStyle("tabStops"); }
+		public function set tabStops(value:*):void
+		{ setCoreStyle(TextLayoutFormat.tabStopsProperty,tabStops,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Specifies the leading model, which is a combination of leading basis and leading direction.
+		 * Leading basis is the baseline to which the <code>lineHeight</code> property refers. Leading direction determines whether the <code>lineHeight</code> property refers to the distance of a line's baseline from that of the line before it or the line after it. The default value of <code>FormatValue.AUTO</code> is resolved based on the paragraph's <code>locale</code> property.  For Japanese and Chinese, it is <code>LeadingModel.IDEOGRAPHIC_TOP_DOWN</code> and for all others it is <code>LeadingModel.ROMAN_UP</code>.<p><strong>Leading Basis:</strong></p><p><img src='../../../images/textLayout_LB1.png' alt='leadingBasis1' />    <img src='../../../images/textLayout_LB2.png' alt='leadingBasis2' />    <img src='../../../images/textLayout_LB3.png' alt='leadingBasis3' /></p><p><strong>Leading Direction:</strong></p><p><img src='../../../images/textLayout_LD1.png' alt='leadingDirection1' />    <img src='../../../images/textLayout_LD2.png' alt='leadingDirection2' />    <img src='../../../images/textLayout_LD3.png' alt='leadingDirection3' /></p>
+		 * <p>Legal values are flashx.textLayout.formats.LeadingModel.ROMAN_UP, flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_TOP_UP, flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_CENTER_UP, flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_TOP_DOWN, flashx.textLayout.formats.LeadingModel.IDEOGRAPHIC_CENTER_DOWN, flashx.textLayout.formats.LeadingModel.APPROXIMATE_TEXT_FIELD, flashx.textLayout.formats.LeadingModel.ASCENT_DESCENT_UP, flashx.textLayout.formats.LeadingModel.AUTO, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.LeadingModel
+		 */
+		public function get leadingModel():*
+		{ return getCoreStyle("leadingModel"); }
+		public function set leadingModel(value:*):void
+		{ setCoreStyle(TextLayoutFormat.leadingModelProperty,leadingModel,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Specifies the amount of gutter space, in pixels, to leave between the columns (adopts default value if undefined during cascade).
+		 * Value is a Number
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 20.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get columnGap():*
+		{ return getCoreStyle("columnGap"); }
+		public function set columnGap(value:*):void
+		{ setCoreStyle(TextLayoutFormat.columnGapProperty,columnGap,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Left inset in pixels (adopts default value if undefined during cascade).
+		 * Space between the left edge of the container and the text.  Value is a Number.<p> With vertical text, in scrollable containers with multiple columns, the first and following columns will show the padding as blank space at the end of the container, but for the last column, if the text doesn't all fit, you may have to scroll in order to see the padding.</p>
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paddingLeft():*
+		{ return getCoreStyle("paddingLeft"); }
+		public function set paddingLeft(value:*):void
+		{ setCoreStyle(TextLayoutFormat.paddingLeftProperty,paddingLeft,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Top inset in pixels (adopts default value if undefined during cascade).
+		 * Space between the top edge of the container and the text.  Value is a Number.
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paddingTop():*
+		{ return getCoreStyle("paddingTop"); }
+		public function set paddingTop(value:*):void
+		{ setCoreStyle(TextLayoutFormat.paddingTopProperty,paddingTop,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Right inset in pixels (adopts default value if undefined during cascade).
+		 * Space between the right edge of the container and the text.  Value is a Number.
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paddingRight():*
+		{ return getCoreStyle("paddingRight"); }
+		public function set paddingRight(value:*):void
+		{ setCoreStyle(TextLayoutFormat.paddingRightProperty,paddingRight,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Botttom inset in pixels (adopts default value if undefined during cascade).
+		 * Space between the bottom edge of the container and the text.  Value is a Number. <p> With horizontal text, in scrollable containers with multiple columns, the first and following columns will show the padding as blank space at the bottom of the container, but for the last column, if the text doesn't all fit, you may have to scroll in order to see the padding.</p>
+		 * <p>Legal values are numbers from 0 to 1000 and flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of 0.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function get paddingBottom():*
+		{ return getCoreStyle("paddingBottom"); }
+		public function set paddingBottom(value:*):void
+		{ setCoreStyle(TextLayoutFormat.paddingBottomProperty,paddingBottom,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Number of text columns (adopts default value if undefined during cascade).
+		 * The column number overrides the  other column settings. Value is an integer, or <code>FormatValue.AUTO</code> if unspecified. If <code>columnCount</code> is not specified,<code>columnWidth</code> is used to create as many columns as can fit in the container.
+		 * <p>Legal values as a string are flashx.textLayout.formats.FormatValue.AUTO, flashx.textLayout.formats.FormatValue.INHERIT and from ints from 1 to 50.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.FormatValue
+		 */
+		public function get columnCount():*
+		{ return getCoreStyle("columnCount"); }
+		public function set columnCount(value:*):void
+		{ setCoreStyle(TextLayoutFormat.columnCountProperty,columnCount,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Column width in pixels (adopts default value if undefined during cascade).
+		 * If you specify the width of the columns, but not the count, TextLayout will create as many columns of that width as possible, given the  container width and <code>columnGap</code> settings. Any remainder space is left after the last column. Value is a Number.
+		 * <p>Legal values as a string are flashx.textLayout.formats.FormatValue.AUTO, flashx.textLayout.formats.FormatValue.INHERIT and numbers from 0 to 8000.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.FormatValue
+		 */
+		public function get columnWidth():*
+		{ return getCoreStyle("columnWidth"); }
+		public function set columnWidth(value:*):void
+		{ setCoreStyle(TextLayoutFormat.columnWidthProperty,columnWidth,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Specifies the baseline position of the first line in the container. Which baseline this property refers to depends on the container-level locale.  For Japanese and Chinese, it is <code>TextBaseline.IDEOGRAPHIC_BOTTOM</code>; for all others it is <code>TextBaseline.ROMAN</code>.
+		 * The offset from the top inset (or right inset if <code>blockProgression</code> is RL) of the container to the baseline of the first line can be either <code>BaselineOffset.ASCENT</code>, meaning equal to the ascent of the line, <code>BaselineOffset.LINE_HEIGHT</code>, meaning equal to the height of that first line, or any fixed-value number to specify an absolute distance. <code>BaselineOffset.AUTO</code> aligns the ascent of the line with the container top inset.<p><img src='../../../images/textLayout_FBO1.png' alt='firstBaselineOffset1' /><img src='../../../images/textLayout_FBO2.png' alt='firstBaselineOffset2' /><img src='../../../images/textLayout_FBO3.png' alt='firstBaselineOffset3' /><img src='../../../images/textLayout_FBO4.png' alt='firstBaselineOffset4' /></p>
+		 * <p>Legal values as a string are flashx.textLayout.formats.BaselineOffset.AUTO, flashx.textLayout.formats.BaselineOffset.ASCENT, flashx.textLayout.formats.BaselineOffset.LINE_HEIGHT, flashx.textLayout.formats.FormatValue.INHERIT and numbers from 0 to 1000.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of AUTO.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.BaselineOffset
+		 */
+		public function get firstBaselineOffset():*
+		{ return getCoreStyle("firstBaselineOffset"); }
+		public function set firstBaselineOffset(value:*):void
+		{ setCoreStyle(TextLayoutFormat.firstBaselineOffsetProperty,firstBaselineOffset,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Vertical alignment or justification (adopts default value if undefined during cascade).
+		 * Determines how TextFlow elements align within the container.
+		 * <p>Legal values are flashx.textLayout.formats.VerticalAlign.TOP, flashx.textLayout.formats.VerticalAlign.MIDDLE, flashx.textLayout.formats.VerticalAlign.BOTTOM, flashx.textLayout.formats.VerticalAlign.JUSTIFY, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of TOP.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.VerticalAlign
+		 */
+		public function get verticalAlign():*
+		{ return getCoreStyle("verticalAlign"); }
+		public function set verticalAlign(value:*):void
+		{ setCoreStyle(TextLayoutFormat.verticalAlignProperty,verticalAlign,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Specifies a vertical or horizontal progression of line placement.
+		 * Lines are either placed top-to-bottom (<code>BlockProgression.TB</code>, used for horizontal text) or right-to-left (<code>BlockProgression.RL</code>, used for vertical text).
+		 * <p>Legal values are flashx.textLayout.formats.BlockProgression.RL, flashx.textLayout.formats.BlockProgression.TB, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of TB.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.BlockProgression
+		 */
+		public function get blockProgression():*
+		{ return getCoreStyle("blockProgression"); }
+		public function set blockProgression(value:*):void
+		{ setCoreStyle(TextLayoutFormat.blockProgressionProperty,blockProgression,value); }
+
+		/**
+		 * TextLayoutFormat:
+		 * Controls word wrapping within the container (adopts default value if undefined during cascade).
+		 * Text in the container may be set to fit the width of the container (<code>LineBreak.TO_FIT</code>), or can be set to break only at explicit return or line feed characters (<code>LineBreak.EXPLICIT</code>).
+		 * <p>Legal values are flashx.textLayout.formats.LineBreak.EXPLICIT, flashx.textLayout.formats.LineBreak.TO_FIT, flashx.textLayout.formats.FormatValue.INHERIT.</p>
+		 * <p>Default value is undefined indicating not set.</p>
+		 * <p>If undefined during the cascade this property will have a value of TO_FIT.</p>
+		 * 
+		 * @throws RangeError when set value is not within range for this property
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * @see flashx.textLayout.formats.LineBreak
+		 */
+		public function get lineBreak():*
+		{ return getCoreStyle("lineBreak"); }
+		public function set lineBreak(value:*):void
+		{ setCoreStyle(TextLayoutFormat.lineBreakProperty,lineBreak,value); }
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/formats/VerticalAlign.as b/textLayout_core/src/flashx/textLayout/formats/VerticalAlign.as
new file mode 100755
index 0000000..3ae5db7
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/VerticalAlign.as
@@ -0,0 +1,68 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	/**
+	 *  Defines values for the <code>verticalAlign</code> property of the TextLayoutFormat class. Specifies how 
+	 *  TextFlow elements align with their containers.  
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 *  @see TextLayoutFormat#verticalAlign
+	 */
+	public final class VerticalAlign
+	{
+		/** Specifies alignment with the top edge of the frame. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const TOP:String = "top";
+		
+		/** Specifies alignment with the bottom edge of the frame. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const BOTTOM:String = "bottom";
+		
+		/** Specifies alignment with the middle of the frame. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		 
+		public static const MIDDLE:String = "middle";
+		
+		/** Specifies vertical line justification within the frame 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		
+		public static const JUSTIFY:String = "justify";		
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/formats/WhiteSpaceCollapse.as b/textLayout_core/src/flashx/textLayout/formats/WhiteSpaceCollapse.as
new file mode 100755
index 0000000..b8aa39a
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/formats/WhiteSpaceCollapse.as
@@ -0,0 +1,51 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.formats
+{
+	/**
+	 *  Defines values for setting the <code>whiteSpaceCollapse</code> property
+	 *  of the <code>TextLayoutFormat</code> class. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 *  
+	 *  @see TextLayoutFormat#whiteSpaceCollapse
+	 */
+	public final class WhiteSpaceCollapse
+	{
+		/** 
+		 * Collapse whitespace when importing text (default).
+		 * Within a block of imported text, removes newlines, tabs, and leading and trailing
+		 * spaces. Retains line break tags (br/) and Unicode line
+		 * separator characters.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public static const COLLAPSE:String = "collapse";
+		
+		/** Preserves whitespace when importing text. 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+		*/ 
+		public static const PRESERVE:String = "preserve";
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/property/ArrayProperty.as b/textLayout_core/src/flashx/textLayout/property/ArrayProperty.as
new file mode 100755
index 0000000..b409ed0
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/property/ArrayProperty.as
@@ -0,0 +1,224 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.property
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.tlf_internal;
+		
+	use namespace tlf_internal;
+		
+	[ExcludeClass]
+	/** A property description with an Array value.@private */
+	public class ArrayProperty extends Property
+	{
+		private var _memberType:Class;
+		
+		public function ArrayProperty(nameValue:String, defaultValue:Array, inherited:Boolean, category:String, mType:Class)
+		{ 
+			_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"); }
+			super(nameValue, defaultValue, inherited, category); 
+		}
+		
+		/** The type the members of the array are required to be. */
+		public function get memberType():Class
+		{ 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():Object
+		{ 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))
+			{
+				Property.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 (!Property.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 val:Object = member[prop.name];
+					if (val != null)
+					{
+						if (addComma)
+							rslt += ", ";
+						rslt += prop.name + ":" + prop.toXMLString(val);
+						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();
+			 	
+			 	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; 
+		}
+		
+		/** @private */
+		public override function hash(val:Object, seed:uint):uint
+		{
+			if (val == FormatValue.INHERIT)
+				return UintProperty.doHash(inheritHashValue, seed);
+			CONFIG::debug { assert(!(val is String),"ArrayProperty.has non inherit string"); }
+				
+			var hash:uint = seed;
+			
+			// TODO: Check for description?
+			var desc:Object = _memberType.description;
+			for each (var member:Object in val)
+			{
+				for each (var prop:Property in desc)
+				{
+					var val:Object = member[prop.name];
+					if (val != null)
+						hash = prop.hash(val, hash);
+				}
+			}
+			return hash;
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/property/BooleanProperty.as b/textLayout_core/src/flashx/textLayout/property/BooleanProperty.as
new file mode 100755
index 0000000..f72e8fe
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/property/BooleanProperty.as
@@ -0,0 +1,61 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.property
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.tlf_internal;
+		
+	use namespace tlf_internal;
+		
+	[ExcludeClass]
+	/** A property description with a Boolean value. @private */
+	public class BooleanProperty extends Property
+	{
+		public function BooleanProperty(nameValue:String, defaultValue:Boolean, inherited:Boolean, category:String)
+		{
+			super(nameValue, defaultValue, inherited, category);
+		}
+		
+		/** @private */
+		public override function setHelper(currVal:*,newObject:*):*
+		{ 
+			if (newObject === null)
+				newObject = undefined;
+
+			if (newObject === undefined || newObject is Boolean || newObject == FormatValue.INHERIT)
+				return newObject;
+			
+			if (newObject == "true" || newObject == "false")
+				return newObject == "true";
+			
+			Property.errorHandler(this,newObject);
+			return currVal;	
+		}
+		
+		/** @private */
+		public override function hash(val:Object, seed:uint):uint
+		{ 
+			if (val == FormatValue.INHERIT)
+				return UintProperty.doHash(inheritHashValue, seed);
+			CONFIG::debug { assert(!(val is String),"BooleanProperty.has non inherit string"); }
+			return UintProperty.doHash((val as Boolean) ? 1 : 0, seed);
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/property/EnumStringProperty.as b/textLayout_core/src/flashx/textLayout/property/EnumStringProperty.as
new file mode 100755
index 0000000..06474a1
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/property/EnumStringProperty.as
@@ -0,0 +1,82 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.property
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.tlf_internal;
+		
+	use namespace tlf_internal;
+		
+	[ExcludeClass]
+	/** An property description with an enumerated string as its value. @private */
+	public class EnumStringProperty extends Property
+	{
+		private var _range:Object;
+		
+		public function EnumStringProperty(nameValue:String, defaultValue:String, inherited:Boolean, category:String, ... rest)
+		{ 
+			super(nameValue, defaultValue, inherited, category);
+			_range = createRange(rest); 
+		}
+		
+		/** @private */
+		tlf_internal static var nextEnumHashValue:uint = 217287;
+		
+		/** @private */
+		tlf_internal static function createRange(rest:Array):Object
+		{
+			var range:Object = new Object();
+			// rest is the list of possible values
+			for (var i:int = 0; i < rest.length; i++)
+				range[rest[i]] = nextEnumHashValue++;
+			range[FormatValue.INHERIT] = nextEnumHashValue++;	
+			return range;
+		}
+		
+		/** Returns object whose properties are the legal enum values */
+		public function get range():Object
+		{
+			return Property.shallowCopy(_range); 
+		}
+		
+		/** @private */
+		public override function setHelper(currVal:*,newObject:*):*
+		{
+			if (newObject === null)
+				newObject = undefined;
+			
+			if (newObject === undefined)
+				return newObject;
+				
+			if (_range.hasOwnProperty(newObject))
+				return newObject;
+			Property.errorHandler(this,newObject);
+			return currVal;
+		}
+		
+		/** @private */
+		public override function hash(val:Object, seed:uint):uint
+		{ 
+			CONFIG::debug { assert(_range.hasOwnProperty(val), "String " + val + " not among possible values for this EnumStringProperty"); }
+			return UintProperty.doHash(_range[val], seed);
+		}
+		
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/property/IntProperty.as b/textLayout_core/src/flashx/textLayout/property/IntProperty.as
new file mode 100755
index 0000000..6a88a65
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/property/IntProperty.as
@@ -0,0 +1,84 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.property
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.tlf_internal;
+		
+	use namespace tlf_internal;
+	
+	[ExcludeClass]
+	/** A property description with an integer value. @private */
+	public class IntProperty extends Property
+	{
+		private var _minValue:int;
+		private var _maxValue:int;
+		
+		public function IntProperty(nameValue:String, defaultValue:int, inherited:Boolean, category:String, minValue:int, maxValue:int)
+		{
+			super(nameValue, defaultValue, inherited, category);
+			_minValue = minValue;
+			_maxValue = maxValue;
+		}
+		
+		public function get minValue():int
+		{ return _minValue; }
+		public function get maxValue():int
+		{ return _maxValue; } 
+
+		/** @private */
+		public override function setHelper(currVal:*,newObject:*):*
+		{ 
+			if (newObject === null)
+				newObject = undefined;
+			
+			if (newObject === undefined || newObject == FormatValue.INHERIT)
+				return newObject;
+
+			var newValNumber:Number = parseInt(newObject);
+			if (isNaN(newValNumber))
+			{
+				Property.errorHandler(this,newObject);
+				return currVal;
+			}
+			var newVal:int = int(newValNumber);
+			if (checkLowerLimit() && newVal < _minValue)
+			{
+				Property.errorHandler(this,newObject);
+				return currVal;
+			}
+			if (checkUpperLimit() && newVal > _maxValue)
+			{
+				Property.errorHandler(this,newObject);
+				return currVal;
+			}
+			return newVal;
+		}
+		
+		/** @private */
+		public override function hash(val:Object, seed:uint):uint
+		{ 
+			if (val == FormatValue.INHERIT)
+				return UintProperty.doHash(inheritHashValue, seed);
+			CONFIG::debug { assert(!(val is String),"IntProperty.has non inherit string"); }
+			return UintProperty.doHash(val as uint, seed);
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/property/IntWithEnumProperty.as b/textLayout_core/src/flashx/textLayout/property/IntWithEnumProperty.as
new file mode 100755
index 0000000..6204254
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/property/IntWithEnumProperty.as
@@ -0,0 +1,77 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.property
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.tlf_internal;
+		
+	use namespace tlf_internal;
+			
+	[ExcludeClass]
+	/** A property description with an integer or enumerated string as its value. @private */
+	public class IntWithEnumProperty extends IntProperty
+	{
+		private var _range:Object;
+		private var _defaultValue:Object;		// could be Int or EnumString value
+		
+		public function IntWithEnumProperty(nameValue:String, defaultValue:Object, inherited:Boolean, category:String, minValue:int, maxValue:int, ... rest)
+		{
+			// rest is the list of possible values
+			_range = EnumStringProperty.createRange(rest); 
+				
+			var defaultIsEnum:Boolean = defaultValue is String && _range.hasOwnProperty(defaultValue);
+			var numberDefault:int = defaultIsEnum ? 0 : int(defaultValue);
+			super(nameValue, numberDefault, inherited, category, minValue, maxValue);
+			_defaultValue = defaultValue;
+		}
+		
+		/** @private */
+		public override function get defaultValue():Object
+		{ return _defaultValue; }
+		
+		/** Returns object whose properties are the legal enum values */
+		public function get range():Object
+		{
+			return Property.shallowCopy(_range); 
+		}
+		
+		/** @private */
+		public override function setHelper(currVal:*,newObject:*):*
+		{ 
+			if (newObject === null)
+				newObject = undefined;
+			
+			if (newObject === undefined)	// range has INHERIT
+				return newObject;
+				
+			return _range.hasOwnProperty(newObject) ? newObject : super.setHelper(currVal,newObject);
+		}
+		
+		/** @private */
+		public override function hash(val:Object, seed:uint):uint
+		{ 
+			CONFIG::debug { assert(!(val is String) || _range.hasOwnProperty(val), "String " + val + " not among possible values for this IntWithEnumProperty"); }
+			var hash:uint = _range[val];
+			if (hash != 0)
+				return UintProperty.doHash(hash, seed);
+			return super.hash(val, seed);
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/property/NumberOrPercentOrEnumProperty.as b/textLayout_core/src/flashx/textLayout/property/NumberOrPercentOrEnumProperty.as
new file mode 100755
index 0000000..d35071a
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/property/NumberOrPercentOrEnumProperty.as
@@ -0,0 +1,78 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.property
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.tlf_internal;
+		
+	use namespace tlf_internal;
+	
+	[ExcludeClass]
+	/** A property description with a Number or a Percent or enumerated string as its value. @private */
+	public class NumberOrPercentOrEnumProperty extends NumberOrPercentProperty
+	{
+		private var _range:Object;
+		private var _defaultValue:Object;		// could be Number or Percent or EnumString value
+
+		/** Value will be a % terminated string or a number or an enumeration */
+		public function NumberOrPercentOrEnumProperty(nameValue:String, defaultValue:Object, inherited:Boolean, category:String, minValue:Number, maxValue:Number, minPercentValue:String, maxPercentValue:String, ... rest)
+		{
+			// rest is the list of possible values
+			_range = EnumStringProperty.createRange(rest); 
+
+			if (defaultValue is String && _range.hasOwnProperty(defaultValue))
+				_defaultValue = defaultValue;
+			// leave _defaultValue null if its not an enum
+
+			super(nameValue, defaultValue, inherited, category, minValue, maxValue, minPercentValue, maxPercentValue);
+		}
+		
+		/** @private */
+		public override function get defaultValue():Object
+		{ return (_defaultValue != null) ? _defaultValue : super.defaultValue; }
+		
+		/** Returns object whose properties are the legal enum values */
+		public function get range():Object
+		{
+			return Property.shallowCopy(_range); 
+		}
+		
+		/** @private */
+		public override function setHelper(currVal:*,newObject:*):*
+		{ 
+			if (newObject === null)
+				newObject = undefined;
+			
+			if (newObject === undefined)	// range has INHERIT
+				return newObject;
+				
+			return _range.hasOwnProperty(newObject) ? newObject : super.setHelper(currVal,newObject);
+		}
+		
+		/** @private */
+		public override function hash(val:Object, seed:uint):uint
+		{ 
+			var hash:uint = _range[val];
+			if (hash != 0)
+				return UintProperty.doHash(hash, seed);
+			return super.hash(val, seed);
+		}		
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/property/NumberOrPercentProperty.as b/textLayout_core/src/flashx/textLayout/property/NumberOrPercentProperty.as
new file mode 100755
index 0000000..8b0e237
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/property/NumberOrPercentProperty.as
@@ -0,0 +1,137 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.property
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.tlf_internal;
+		
+	use namespace tlf_internal;
+	
+	[ExcludeClass]
+	/** A property description with a Number or a Percent as its value. @private */
+	public class NumberOrPercentProperty extends Property
+	{
+		private var _minNumberValue:Number;
+		private var _maxNumberValue:Number;
+		private var _minPercentValue:Number;
+		private var _maxPercentValue:Number;
+		
+		/** Value will be a % terminated string or a number */
+		public function NumberOrPercentProperty(nameValue:String, defaultValue:Object, inherited:Boolean, category:String, minValue:Number, maxValue:Number, minPercentValue:String, maxPercentValue:String)
+		{
+			super(nameValue, defaultValue, inherited, category);
+			
+			// the nested properties don't need the true default
+			_minNumberValue = minValue;
+			_maxNumberValue = maxValue;
+			_minPercentValue = toNumberIfPercent(minPercentValue);
+			_maxPercentValue = toNumberIfPercent(maxPercentValue);
+		}
+		
+		public function get minNumberValue():Number
+		{ return _minNumberValue; }
+		public function get maxNumberValue():Number
+		{ return _maxNumberValue; } 
+		public function get minPercentValue():Number
+		{ return _minPercentValue; }
+		public function get maxPercentValue():Number
+		{ return _maxPercentValue; }
+		
+		static private function toNumberIfPercent(o:Object):Number
+		{
+			if (!(o is String))
+				return NaN;
+			var s:String = String(o);
+			var len:int = s.length;
+			
+			return len != 0 && s.charAt(len-1) == "%" ? parseFloat(s) : NaN;
+		}
+
+		/** @private */
+		public override function setHelper(currVal:*,newObject:*):*
+		{ 
+			if (newObject === null)
+				newObject = undefined;
+			
+			if (newObject === undefined || newObject == FormatValue.INHERIT)
+				return newObject;
+
+			var newVal:Number = toNumberIfPercent(newObject);
+			if (!isNaN(newVal))
+			{
+				if (checkLowerLimit() && newVal < _minPercentValue)
+				{
+					Property.errorHandler(this,newObject);
+					return currVal;
+				}
+				if (checkUpperLimit() && newVal > _maxPercentValue)
+				{
+					Property.errorHandler(this,newObject);
+					return currVal;
+				}
+				return newVal.toString()+"%";
+			}
+
+			newVal = parseFloat(newObject);
+			// Nan --> return the current value
+			if (isNaN(newVal))
+			{
+				Property.errorHandler(this,newObject);
+				return currVal;
+			}
+			if (checkLowerLimit() && newVal < _minNumberValue)
+			{
+				Property.errorHandler(this,newObject);
+				return currVal;
+			}
+			if (checkUpperLimit() && newVal > _maxNumberValue)
+			{
+				Property.errorHandler(this,newObject);
+				return currVal;
+			}
+			return newVal;
+		}
+		
+		/** @private */
+		public override function hash(val:Object, seed:uint):uint
+		{ 
+			if (val == FormatValue.INHERIT)
+				return UintProperty.doHash(inheritHashValue, seed);
+			if (val is String)
+				return StringProperty.doHash(String(val), seed);
+			return NumberProperty.doHash(val as Number, seed);
+		}
+		
+		public function computeActualPropertyValue(propertyValue:Object,percentInput:Number):Number
+		{
+			var percent:Number = toNumberIfPercent(propertyValue);
+			if (isNaN(percent))
+				return Number(propertyValue);
+				
+			// its a percent - calculate and clamp
+			var rslt:Number =  percentInput * (percent / 100);
+			if (rslt < _minNumberValue)
+				return _minNumberValue;
+			if (rslt > _maxNumberValue)
+				return _maxNumberValue;
+			return rslt;			
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/property/NumberProperty.as b/textLayout_core/src/flashx/textLayout/property/NumberProperty.as
new file mode 100755
index 0000000..f7ddd23
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/property/NumberProperty.as
@@ -0,0 +1,98 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.property
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.tlf_internal;
+		
+	use namespace tlf_internal;
+
+	[ExcludeClass]
+	/** A property description with a Number as its value. @private */
+	public class NumberProperty extends Property
+	{
+		private var _minValue:Number;
+		private var _maxValue:Number;
+		
+		public function NumberProperty(nameValue:String, defaultValue:Number, inherited:Boolean, category:String, minValue:Number, maxValue:Number)
+		{
+			super(nameValue, defaultValue, inherited, category);
+			_minValue = minValue;
+			_maxValue = maxValue;
+		}
+		
+		public function get minValue():Number
+		{ return _minValue; }
+		public function get maxValue():Number
+		{ return _maxValue; } 
+		
+		/** @private */
+		public override function setHelper(currVal:*,newObject:*):*
+		{ 
+			if (newObject === null)
+				newObject = undefined;
+			
+			if (newObject === undefined || newObject == FormatValue.INHERIT)
+				return newObject;
+
+			var newVal:Number = newObject is String ? parseFloat(newObject) : Number(newObject);
+			if (isNaN(newVal))
+			{
+				Property.errorHandler(this,newObject);
+				return currVal;
+			}
+			if (checkLowerLimit() && newVal < _minValue)
+			{
+				Property.errorHandler(this,newObject);
+				return currVal;
+			}
+			if (checkUpperLimit() && newVal > _maxValue)
+			{
+				Property.errorHandler(this,newObject);
+				return currVal;
+			}
+			return newVal;
+		}
+		
+		/** @private */
+		public override function hash(val:Object, seed:uint):uint
+		{ 
+			if (val == FormatValue.INHERIT)
+				return UintProperty.doHash(inheritHashValue, seed);
+			return NumberProperty.doHash(val as Number, seed);
+		}
+		
+		/** @private */
+		tlf_internal static function doHash(num:Number, seed:uint):uint
+		{ 
+			//return stringHash(num.toString(), seed);
+			
+			var trunc:uint = uint(num);
+			var hash:uint = UintProperty.doHash(trunc, seed);
+			if (trunc != num)
+			{
+				var fraction:uint = (uint)((num - trunc) * 10000000000);
+				hash =  UintProperty.doHash(fraction, hash);
+			}
+			
+			return hash; 
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/property/NumberWithEnumProperty.as b/textLayout_core/src/flashx/textLayout/property/NumberWithEnumProperty.as
new file mode 100755
index 0000000..420ce07
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/property/NumberWithEnumProperty.as
@@ -0,0 +1,77 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.property
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.tlf_internal;
+		
+	use namespace tlf_internal;
+			
+	[ExcludeClass]
+	/** A property description with a Number or enumerated string as its value. @private */
+	public class NumberWithEnumProperty extends NumberProperty
+	{
+		private var _range:Object;
+		private var _defaultValue:Object;		// could be Number or EnumString value
+		
+		public function NumberWithEnumProperty(nameValue:String, defaultValue:Object, inherited:Boolean, category:String, minValue:Number, maxValue:Number, ... rest)
+		{
+			// rest is the list of possible values
+			_range = EnumStringProperty.createRange(rest); 
+				
+			var defaultIsEnum:Boolean = defaultValue is String && _range.hasOwnProperty(defaultValue);
+			var numberDefault:Number = defaultIsEnum ? 0 : Number(defaultValue);
+			super(nameValue, numberDefault, inherited, category, minValue, maxValue);
+			_defaultValue = defaultValue;
+		}
+		
+		/** @private */
+		public override function get defaultValue():Object
+		{ return _defaultValue; }
+		
+		/** Returns object whose properties are the legal enum values */
+		public function get range():Object
+		{
+			return Property.shallowCopy(_range); 
+		}
+		
+		/** @private */
+		public override function setHelper(currVal:*,newObject:*):*
+		{ 
+			if (newObject === null)
+				newObject = undefined;
+			
+			if (newObject === undefined)	// range has INHERIT
+				return newObject;
+				
+			return _range.hasOwnProperty(newObject) ? newObject : super.setHelper(currVal,newObject);
+		}
+		
+		/** @private */
+		public override function hash(val:Object, seed:uint):uint
+		{ 
+			CONFIG::debug { assert(!(val is String) || _range.hasOwnProperty(val), "String " + val + " not among possible values for this NumberWithEnumProperty"); }
+			var hash:uint = _range[val];
+			if (hash != 0)
+				return UintProperty.doHash(hash, seed);
+			return super.hash(val, seed);
+		}
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/property/Property.as b/textLayout_core/src/flashx/textLayout/property/Property.as
new file mode 100755
index 0000000..4ea425e
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/property/Property.as
@@ -0,0 +1,248 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.property
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.GlobalSettings;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.tlf_internal;
+		
+	[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
+	{
+		public static var errorHandler:Function = defaultErrorHandler;
+		public static function defaultErrorHandler(p:Property,value:Object):void
+		{
+			throw(new RangeError(createErrorString(p,value)));
+		}
+		public static function createErrorString(p:Property,value:Object):String
+		{
+			return GlobalSettings.resourceStringFunction("badPropertyValue",[ p.name, value.toString() ])
+		}
+		
+		/** not yet enabled.  @private */
+		public const NO_LIMITS:String ="noLimits";
+		/** not yet enabled.  @private */
+		public const LOWER_LIMIT:String ="lowerLimit";
+		/** not yet enabled.  @private */
+		public const UPPER_LIMIT:String = "upperLimit";
+		/** not yet enabled.  @private */
+		public const ALL_LIMITS:String = "allLimits";
+		
+		// storing name here is redundant but is more efficient 
+		private var _name:String;
+		private var _default:Object;
+		private var _inherited:Boolean;
+		private var _limits:String;
+		private var _category:String;
+		
+		/** @private */
+		tlf_internal static const inheritHashValue:uint  = 314159;
+		
+		/** Initializer.  Each property has a name and a default. */
+		public function Property(nameValue:String,defaultValue:Object,inherited:Boolean,category:String)
+		{
+			_name = nameValue;
+			_default = defaultValue;
+			_limits = ALL_LIMITS;
+			_inherited = inherited;
+			_category = category;
+		}
+		
+		/** not yet enabled.  @private */
+		protected function checkLowerLimit():Boolean
+		{ return _limits == ALL_LIMITS || _limits == LOWER_LIMIT; }
+		
+		/** not yet enabled.  @private */
+		protected function checkUpperLimit():Boolean
+		{ return _limits == ALL_LIMITS || _limits == LOWER_LIMIT; }
+		
+		/** The name of the property */
+		public function get name():String
+		{ return _name; }
+		
+		/** The default value of this property */
+		public function get defaultValue():Object
+		{ return _default; }
+		
+		/** Is this property inherited */
+		public function get inherited():Object
+		{ return _inherited; }
+		
+		/** Category of this property. */
+		public function get category():String
+		{ return _category; }
+			
+		/** Helper function when setting the property */
+		public function setHelper(currVal:*,newVal:*):*
+		{
+			if (newVal === null)
+				newVal = undefined;
+
+			return newVal; 
+		}
+		
+		/** 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
+		{
+			return val.toString();
+		}
+		
+		/** Get the hash of the property value
+		 * @param val the property value
+		 * @param seed seed value for the hash algorithm 
+		 * @return the hash of the property value
+		 */
+		public function hash(val:Object, seed:uint):uint
+		{ 
+			return 0;
+		}
+		
+		// /////////////////////////////////////////////
+		// Following static functions are used by Format classes to 
+		// perform functions that iterate over all the attributes.
+		// They are driven by the attributes metadata object that contains
+		// definitions for all the properties.
+		// /////////////////////////////////////////////
+			
+		/** Helper function to initialize all property values from defaults. */
+		static public function defaultsAllHelper(description:Object,current:Object):void
+		{
+			for each (var prop:Property in description)
+				current[prop.name] = prop.defaultValue;
+		}
+		
+		/** Helper function to compare two sets of properties. */
+		static public function equalAllHelper(description:Object,p1:Object,p2:Object):Boolean
+		{
+			if (p1 == p2)
+				return true;
+			// these could be "equal" if all attributes of p1 or p2 are null
+			if (p1 == null || p2 == null)
+				return false;
+			for each (var prop:Property in description)
+			{
+				var name:String = prop.name;
+				if (!(prop.equalHelper(p1[name],p2[name])))
+					return false;
+			}
+			return true;
+		}
+
+		static public function extractInCategory(formatClass:Class,description:Object,props:Object,category:String):Object
+		{
+			var rslt:Object = null;
+			for each (var prop:Property in description)
+			{
+				if (prop.category == category && props[prop.name] != null)
+				{
+					if (rslt == null)
+						rslt = new formatClass();
+					rslt[prop.name] = props[prop.name];
+				}
+			}
+			return rslt;
+		}
+		/** @private */
+		static public function shallowCopy(src:Object):Object
+		{
+			// make a shallow copy
+			var rslt:Object = new Object()
+			for (var val:Object in src)
+				rslt[val] = src[val]; 
+			return rslt;
+		}
+		
+		static private const nullStyleObject:Object = new Object();
+		/** @private */
+		static public function equalStyleObjects(o1:Object,o2:Object):Boolean
+		{
+			if (o1 == null)
+				o1 = nullStyleObject;
+			if (o2 == null)
+				o2 = nullStyleObject;
+			var o1len:int = 0;
+			// compare property values and count o1len
+			for (var val:Object in o1)
+			{
+				CONFIG::debug { assert(!(o1[val] is Array) && !(o2[val] is Array),"Arrays as user styles not supported"); }
+				if (o1[val] != o2[val])
+					return false;	// different
+				o1len++;
+			}
+			var o2len:int = 0;
+			for (val in o2)
+				o2len++;
+			// matching keys from o1 to o2.  return equal if they both have the same length
+			return o1len == o2len;
+		}
+		
+		/** @private */
+		static public function equalCoreStyles(o1:Object,o2:Object,description:Object):Boolean
+		{
+			if (o1 == null)
+				o1 = nullStyleObject;
+			if (o2 == null)
+				o2 = nullStyleObject;
+			var o1len:int = 0;
+			// compare property values and count o1len
+			for (var val:String in o1)
+			{
+				var o1val:Object = o1[val];
+				var o2val:Object = o2[val];
+				if (o1val != o2val)
+				{
+					if (!(o1val is Array) || !(o2val is Array) || o1val.length != o2val.length)
+						return false;	// different
+					var valClass:Class = description[val].memberType;
+					if (!Property.equalAllHelper(valClass.tlf_internal::description,o1val,o2val))
+						return false;
+				}
+				o1len++;
+			}
+			var o2len:int = 0;
+			for (val in o2)
+				o2len++;
+			// matching keys from o1 to o2.  return equal if they both have the same length
+			return o1len == o2len;
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/property/StringProperty.as b/textLayout_core/src/flashx/textLayout/property/StringProperty.as
new file mode 100755
index 0000000..7972203
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/property/StringProperty.as
@@ -0,0 +1,75 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.property
+{
+	import flashx.textLayout.tlf_internal;
+		
+	use namespace tlf_internal;
+	
+	[ExcludeClass]
+	/** A property description with a String as its value @private */
+	public class StringProperty extends Property
+	{
+		public function StringProperty(nameValue:String, defaultValue:String, inherited:Boolean, category:String)
+		{
+			super(nameValue, defaultValue, inherited, category);
+		}
+		
+		/** @private */
+		public override function setHelper(currVal:*,newObject:*):*
+		{ 
+			if (newObject === null)
+				newObject = undefined;
+			
+			if (newObject === undefined || newObject is String)
+				return newObject;
+			
+			Property.errorHandler(this,newObject);
+			return currVal;	
+		}	
+		
+		/** @private */
+		public override function hash(val:Object, seed:uint):uint
+		{ 
+			return doHash(val as String, seed);
+		}
+		
+		/** @private */
+		tlf_internal static function doHash(val:String, seed:uint):uint
+		{
+			if (val == null)
+				return seed;
+				
+			var len:uint = val.length;
+			var hash:uint = seed;
+
+			// Incrementally hash integers composed of pairs of character codes in the string
+			for (var ix:uint=0; ix<len/2; ix++)
+			{
+				hash = UintProperty.doHash((val.charCodeAt(2*ix) << 16) | val.charCodeAt(2*ix+1), hash);
+			}
+			
+			// Handle last character code in an odd-length string
+			if (len % 2 != 0)
+				hash = UintProperty.doHash (val.charCodeAt(len-1), hash);
+			
+			return hash;
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/property/TabStopsProperty.as b/textLayout_core/src/flashx/textLayout/property/TabStopsProperty.as
new file mode 100755
index 0000000..9bacf2c
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/property/TabStopsProperty.as
@@ -0,0 +1,194 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.property
+{
+	import flash.text.engine.TabAlignment;
+	
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.formats.TabStopFormat;
+		
+	[ExcludeClass]
+	/** Property for tab stops. Extends ArrayProperty; setter takes a string representation of tab stops in addition to an array. @private */
+	public class TabStopsProperty extends ArrayProperty
+	{
+		public function TabStopsProperty(nameValue:String, defaultValue:Array, inherited:Boolean, category:String)
+		{ 
+			super (nameValue, defaultValue, inherited, category, TabStopFormat);
+		}
+			
+		
+		/** Helper function when setting the property */
+		public override function setHelper(currVal:*,newVal:*):*
+		{
+			// null is a real value - DO NOT map to undefined like the others
+			
+			// null, undefined and INHERIT are all valid for arrays
+			if (newVal == null || newVal == FormatValue.INHERIT)
+				return newVal;
+				
+			// Accepts either an array or a string representation
+			var tabStops:Array = newVal as Array;
+			if (tabStops)
+			{
+				if (!checkArrayTypes(tabStops))
+				{
+					Property.errorHandler(this,newVal);
+					return currVal;
+				}
+			}
+			else
+			{
+				var valString:String = newVal as String;
+				if (!valString)
+				{
+					Property.errorHandler(this,newVal);
+					return currVal;
+				}
+					
+				// Parse the string representation and create an equivalent array
+				tabStops = new Array();
+				
+				// Replace escape sequences (\ followed by a space or \) with placeholder strings
+				// that can't naturally occur in the passed-in string 
+				valString = valString.replace(_escapeBackslashRegex, _backslashPlaceHolder);
+				valString = valString.replace(_escapeSpaceRegex, _spacePlaceHolder);
+				
+				_tabStopRegex.lastIndex = 0;
+				do
+				{
+					var result:Object = _tabStopRegex.exec(valString);
+					if (!result)
+						break; // no more matches
+						
+					var tabStop:TabStopFormat = new TabStopFormat();
+					switch (result[1].toLowerCase())
+					{
+						case "s":
+						case "": // START is the default
+							tabStop.alignment = TabAlignment.START;
+							break;
+						case "c":
+							tabStop.alignment = TabAlignment.CENTER;
+							break;
+						case "e":
+							tabStop.alignment = TabAlignment.END;
+							break;
+						case "d":
+							tabStop.alignment = TabAlignment.DECIMAL;
+							break;
+					}
+					
+					var position:Number = Number(result[2]); 
+					if (isNaN(position))
+					{
+						Property.errorHandler(this,newVal);
+						return currVal;
+					}
+					tabStop.position = position;
+
+					if (tabStop.alignment == TabAlignment.DECIMAL)
+					{
+						if (result[3] == "")
+							tabStop.decimalAlignmentToken = "."; //default
+						else
+						{
+							// strip the leading vertical bar and restore \ and space characters where intended
+							tabStop.decimalAlignmentToken = result[3].slice(1).replace(_backslashPlaceholderRegex, "\\");
+							tabStop.decimalAlignmentToken = tabStop.decimalAlignmentToken.replace(_spacePlaceholderRegex, " ");
+						}
+					}
+					else if (result[3] != "")
+					{
+						Property.errorHandler(this,newVal);
+						return currVal; // if alignment is not decimal, the alignment token is not allowed
+					}
+						
+					tabStops.push(tabStop);
+				
+				} while (true);
+			
+			}
+
+			return tabStops.sort(compareTabStopFormats);
+		}
+		
+		/** @private */
+		public override function toXMLString(val:Object):String
+		{
+			var str:String = "";
+			var tabStops:Array = val as Array;
+			for each (var tabStop:TabStopFormat in tabStops)
+			{
+				if (str.length)
+					str += " ";
+				
+				switch (tabStop.alignment)
+				{
+					case TabAlignment.START:
+						str += "s";
+						break;
+					case TabAlignment.CENTER:
+						str += "c";
+						break;
+					case TabAlignment.END:
+						str += "e";
+						break;
+					case TabAlignment.DECIMAL:
+						str += "d";
+						break;
+				}
+				
+				str += tabStop.position.toString();
+				
+				if (tabStop.alignment == TabAlignment.DECIMAL)
+				{
+					var escapedAlignmentToken:String = tabStop.decimalAlignmentToken.replace(_backslashRegex, "\\\\");
+					escapedAlignmentToken = escapedAlignmentToken.replace(_spaceRegex, "\\ ");
+					str += "|" + escapedAlignmentToken;
+				}
+			}
+			
+			return str;
+		}
+		
+		private static function compareTabStopFormats(a:TabStopFormat, b:TabStopFormat):Number
+		{
+			return a.position == b.position ? 0 : a.position < b.position ? -1 : 1;
+		}
+		
+		// Alignment type: [sScCeEdD]?  - Atmost 1 occurance of one of s/c/e/d (or upper-case equivalents)
+		// Position: [^| ]+ - At least character which is not a space or | (further validation is done by the Number constructor)
+		// Alignment token and separator:(|[^ ]*)? - Atmost one occurance of a | followed by 0 or more non-space characters
+		// Delimiter: ( |$) - A space or end-of-string
+		private static const _tabStopRegex:RegExp = /([sScCeEdD]?)([^| ]+)(|[^ ]*)?( |$)/g;
+		private static const _escapeBackslashRegex:RegExp = /\\\\/g;
+		private static const _escapeSpaceRegex:RegExp = /\\ /g;
+		private static const _backslashRegex:RegExp = /\\/g;
+		private static const _spaceRegex:RegExp = / /g;
+		private static const _backslashPlaceholderRegex:RegExp = /\uE000/g;
+		private static const _spacePlaceholderRegex:RegExp = /\uE001/g;
+		
+		// Replace escape sequences (\ followed by a space or \) with placeholder strings
+		// containing characters from Unicode private use area (won't naturally occur in the passed-in string) 
+		private static const _backslashPlaceHolder:String = String.fromCharCode(0xE000);
+		private static const _spacePlaceHolder:String = String.fromCharCode(0xE001);
+				
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/property/UintProperty.as b/textLayout_core/src/flashx/textLayout/property/UintProperty.as
new file mode 100755
index 0000000..9111bc5
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/property/UintProperty.as
@@ -0,0 +1,106 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.property
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.tlf_internal;
+		
+	use namespace tlf_internal;
+
+	[ExcludeClass]
+	/** A property description with an unsigned integer as its value.  Typically used for color. @private */
+	public class UintProperty extends Property
+	{
+		public function UintProperty(nameValue:String, defaultValue:uint, inherited:Boolean, category:String)
+		{
+			super(nameValue, defaultValue, inherited, category);
+		}
+		
+		/** @private */
+		public override function setHelper(currVal:*,newObject:*):*
+		{ 
+			if (newObject === null)
+				newObject = undefined;
+			
+			if (newObject === undefined || newObject == FormatValue.INHERIT)
+				return newObject;
+			
+			var newVal:*;
+			if (newObject is String)
+			{
+				var str:String = String(newObject);
+				// Normally, we could just cast a string to a uint. However, the casting technique only works for
+				// normal numbers and numbers preceded by "0x". We can encounter numbers of the form "#ffffffff"					
+				if (str.substr(0, 1) == "#")
+					str = "0x" + str.substr(1, str.length-1);
+				newVal = (str.toLowerCase().substr(0, 2) == "0x") ? parseInt(str) : NaN;
+			}
+			else if (newObject is Number || newObject is int || newObject is uint)
+				newVal = Number(newObject);
+			else
+				newVal = NaN;
+			
+			if (isNaN(newVal))
+			{
+				Property.errorHandler(this,str);
+				return currVal;
+			}
+			
+			if (newVal is Number)
+			{
+				if (newVal < 0 || newVal > 0xffffffff)
+				{
+					Property.errorHandler(this,newObject);
+					return currVal;					
+				}
+			}
+			
+			return newVal;
+		}
+		
+		/** @private */
+		public override function toXMLString(val:Object):String
+		{
+			// Always export in # format, to be compatible with color spec.
+			if (val == FormatValue.INHERIT)
+				return String(val);
+				
+			var result:String = val.toString(16);
+			if (result.length < 6)
+				result = "000000".substr(0, 6 - result.length) + result;
+			result = "#" + result;
+			return result;
+		}
+		
+		/** @private */
+		public override function hash(val:Object, seed:uint):uint
+		{ 
+			if (val == FormatValue.INHERIT)
+				return UintProperty.doHash(inheritHashValue, seed);
+			return doHash(val as uint, seed);
+		}
+		
+		/** @private */
+		tlf_internal static function doHash(val:uint, seed:uint):uint
+		{ 
+			return ((seed << 5) ^ (seed >> 27)) ^ val;
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/property/UintWithEnumProperty.as b/textLayout_core/src/flashx/textLayout/property/UintWithEnumProperty.as
new file mode 100755
index 0000000..81d3bfd
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/property/UintWithEnumProperty.as
@@ -0,0 +1,83 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.property
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.tlf_internal;
+		
+	use namespace tlf_internal;
+			
+	[ExcludeClass]
+	/** A property description with a Uint or enumerated string as its value. @private */
+	public class UintWithEnumProperty extends UintProperty
+	{
+		private var _range:Object;
+		private var _defaultValue:Object;		// could be Uint or EnumString value
+		
+		public function UintWithEnumProperty(nameValue:String, defaultValue:Object, inherited:Boolean, category:String,  ... rest)
+		{
+			// rest is the list of possible values
+			_range = EnumStringProperty.createRange(rest); 
+				
+			var defaultIsEnum:Boolean = defaultValue is String && _range.hasOwnProperty(defaultValue);
+			var numberDefault:Number = defaultIsEnum ? 0 : Number(defaultValue);
+			super(nameValue, numberDefault, inherited, category);
+			_defaultValue = defaultValue;
+		}
+		
+		/** @private */
+		public override function get defaultValue():Object
+		{ return _defaultValue; }
+		
+		/** Returns object whose properties are the legal enum values */
+		public function get range():Object
+		{
+			return Property.shallowCopy(_range); 
+		}
+		
+		/** @private */
+		public override function setHelper(currVal:*,newObject:*):*
+		{ 
+			if (newObject === null)
+				newObject = undefined;
+			
+			if (newObject === undefined)	// range has INHERIT
+				return newObject;
+				
+			return _range.hasOwnProperty(newObject) ? newObject : super.setHelper(currVal,newObject);
+		}
+		
+		/** @private */
+		public override function hash(val:Object, seed:uint):uint
+		{ 
+			CONFIG::debug { assert(!(val is String) || _range.hasOwnProperty(val), "String " + val + " not among possible values for this NumberWithEnumProperty"); }
+			var hash:uint = _range[val];
+			if (hash != 0)
+				return UintProperty.doHash(hash, seed);
+			return super.hash(val, seed);
+		}
+		
+		/** @private */
+		public override function toXMLString(val:Object):String
+		{
+			return _range.hasOwnProperty(val) ? String(val) : super.toXMLString(val);
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/tlf_internal.as b/textLayout_core/src/flashx/textLayout/tlf_internal.as
new file mode 100755
index 0000000..358ca67
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/tlf_internal.as
@@ -0,0 +1,34 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout
+{
+
+	/**
+	 *  This namespace is used for undocumented APIs -- usually implementation
+	 *  details -- which can't be private because they need to visible
+	 *  to other classes.
+	 *  APIs in this namespace are completely unsupported and are likely to
+	 *  change in future versions of TextLayout.
+	 * 
+	 *  @private
+	 */
+	public namespace tlf_internal =
+		"http://ns.adobe.com/textLayout/internal/2008";
+}
+
diff --git a/textLayout_core/src/flashx/textLayout/utils/CharacterUtil.as b/textLayout_core/src/flashx/textLayout/utils/CharacterUtil.as
new file mode 100755
index 0000000..0f725d1
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/utils/CharacterUtil.as
@@ -0,0 +1,167 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.utils
+{
+	/** 
+	 * Utilities for managing and getting information about characters.
+	 * The methods of this class are static and must be called using
+	 * the syntax <code>CharacterUtil.method(<em>parameter</em>)</code>.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public final class CharacterUtil
+	{
+		/** 
+		 * Returns <code>true</code> if the <code>charCode</code> argument is a high word in a surrogate pair. 
+		 * A surrogate pair represents a character with a code point that requires more
+		 * than sixteen bits to express and thus requires a combination
+		 * of two 16-bit words, a high surrogate and a low surrogate, to embody its code point.
+		 * <p>This method can be used when processing a series of characters to
+		 * ensure that you do not inadvertently divide a surrogate pair
+		 * into incomplete halves.</p>
+		 * 
+		 *
+		 * @param charCode An integer that represents a character code.
+		 * Character codes are usually represented in hexadecimal format.
+		 * For example, the space character's character code can be
+		 * represented by the number <code>0x0020</code>.
+		 * @return <code>true</code> if <code>charCode</code> is the high surrogate in a surrogate pair.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		static public function isHighSurrogate(charCode:int):Boolean
+		{
+			return (charCode >= 0xD800 && charCode <= 0xDBFF);
+		}
+		
+		/** 
+		 * Returns <code>true</code> if the <code>charCode</code> argument is a low word in a surrogate pair. 
+		 * A surrogate pair represents a character with a code point that requires more
+		 * than sixteen bits to express and thus requires a combination
+		 * of two 16-bit words, a high surrogate and a low surrogate, to embody its code point.
+		 * <p>This method can be used when processing a series of characters to
+		 * ensure that you do not inadvertently divide a surrogate pair
+		 * into incomplete halves.</p>
+		 *
+		 * @param charCode An integer that represents a character code.
+		 * Character codes are usually represented in hexadecimal format.
+		 * For example, the space character's character code can be
+		 * represented by the number <code>0x0020</code>.
+		 * @return <code>true</code> if <code>charCode</code> is the low surrogate in a surrogate pair.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		static public function isLowSurrogate (charCode:int):Boolean
+		{
+			return (charCode >= 0xDC00 && charCode <= 0xDFFF);
+		}
+
+		static private var whiteSpaceObject:Object = createWhiteSpaceObject();
+		
+		static private function createWhiteSpaceObject():Object
+		{
+			var rslt:Object = new Object();
+			//members of SpaceSeparator category
+			rslt[0x0020] =  true;  //SPACE
+			rslt[0x1680] =  true;  //OGHAM SPACE MARK
+			rslt[0x180E] =  true;  //MONGOLIAN VOWEL SEPARATOR
+			rslt[0x2000] =  true;  //EN QUAD
+			rslt[0x2001] =  true;  //EM QUAD
+			rslt[0x2002] =  true;  //EN SPACE
+			rslt[0x2003] =  true;  //EM SPACE
+			rslt[0x2004] =  true;  //THREE-PER-EM SPACE
+			rslt[0x2005] =  true;  //FOUR-PER-EM SPACE
+			rslt[0x2006] =  true;  //SIZE-PER-EM SPACE
+			rslt[0x2007] =  true;  //FIGURE SPACE
+			rslt[0x2008] =  true;  //PUNCTUATION SPACE
+			rslt[0x2009] =  true;  //THIN SPACE
+			rslt[0x200A] =  true;  //HAIR SPACE
+			rslt[0x202F] =  true;  //NARROW NO-BREAK SPACE
+			rslt[0x205F] =  true;  //MEDIUM MATHEMATICAL SPACE
+			rslt[0x3000] =  true;  //IDEOGRAPHIC SPACE
+			//members of LineSeparator category
+			rslt[0x2028] =  true;  //LINE SEPARATOR
+			//members of ParagraphSeparator category
+			rslt[0x2029] =  true;
+			//Other characters considered to be a space
+			rslt[0x0009] =  true; //CHARACTER TABULATION
+			rslt[0x000A] =  true; //LINE FEED
+			rslt[0x000B] =  true; //LINE TABULATION
+			rslt[0x000C] =  true; //FORM FEED
+			rslt[0x000D] =  true; //CARRIAGE RETURN
+			rslt[0x0085] =  true; //NEXT LINE
+			rslt[0x00A0] =  true; //NO-BREAK SPACE	
+			return rslt;
+		}
+		/** 
+		 * Returns <code>true</code> if <code>charCode</code> is a whitespace character. 
+		 * <p>The following table describes all characters that this
+		 * method considers a whitespace character.
+		 * </p>
+		 * <table class="innertable">
+		 *     <tr><th>Character Code</th><th>Unicode Character Name</th><th>Category</th></tr>
+		 *     <tr><td><code>0x0020</code></td><td>SPACE</td><td>Space Separator</td></tr>
+		 *     <tr><td><code>0x1680</code></td><td>OGHAM SPACE MARK</td><td>Space Separator</td></tr>
+		 *     <tr><td><code>0x180E</code></td><td>MONGOLIAN VOWEL SEPARATOR</td><td>Space Separator</td></tr>
+		 *     <tr><td><code>0x2000</code></td><td>EN QUAD</td><td>Space Separator</td></tr>
+		 *     <tr><td><code>0x2001</code></td><td>EM QUAD</td><td>Space Separator</td></tr>
+		 *     <tr><td><code>0x2002</code></td><td>EN SPACE</td><td>Space Separator</td></tr>
+		 *     <tr><td><code>0x2003</code></td><td>EM SPACE</td><td>Space Separator</td></tr>
+		 *     <tr><td><code>0x2004</code></td><td>THREE-PER-EM SPACE</td><td>Space Separator</td></tr>
+		 *     <tr><td><code>0x2005</code></td><td>FOUR-PER-EM SPACE</td><td>Space Separator</td></tr>
+		 *     <tr><td><code>0x2006</code></td><td>SIX-PER-EM SPACE</td><td>Space Separator</td></tr>
+		 *     <tr><td><code>0x2007</code></td><td>FIGURE SPACE</td><td>Space Separator</td></tr>
+		 *     <tr><td><code>0x2008</code></td><td>PUNCTUATION SPACE</td><td>Space Separator</td></tr>
+		 *     <tr><td><code>0x2009</code></td><td>THIN SPACE</td><td>Space Separator</td></tr>
+		 *     <tr><td><code>0x200A</code></td><td>HAIR SPACE</td><td>Space Separator</td></tr>
+		 *     <tr><td><code>0x202F</code></td><td>NARROW NO-BREAK SPACE</td><td>Space Separator</td></tr>
+		 *     <tr><td><code>0x205F</code></td><td>MEDIUM MATHEMATICAL SPACE</td><td>Space Separator</td></tr>
+		 *     <tr><td><code>0x3000</code></td><td>IDEOGRAPHIC SPACE</td><td>Space Separator</td></tr>
+		 *     <tr><td><code>0x2028</code></td><td>LINE SEPARATOR</td><td>Line Separator</td></tr>
+		 *     <tr><td><code>0x2029</code></td><td>PARAGRAPH SEPARATOR</td><td>Paragraph Separator</td></tr>
+		 *     <tr><td><code>0x0009</code></td><td>CHARACTER TABULATION</td><td>Other</td></tr>
+		 *     <tr><td><code>0x000A</code></td><td>LINE FEED</td><td>Other</td></tr>
+		 *     <tr><td><code>0x000B</code></td><td>LINE TABULATION</td><td>Other</td></tr>
+		 *     <tr><td><code>0x000C</code></td><td>FORM FEED</td><td>Other</td></tr>
+		 *     <tr><td><code>0x000D</code></td><td>CARRIAGE RETURN</td><td>Other</td></tr>
+		 *     <tr><td><code>0x0085</code></td><td>NEXT LINE</td><td>Other</td></tr>
+		 *     <tr><td><code>0x00A0</code></td><td>NO-BREAK SPACE</td><td>Other</td></tr>
+		 *  </table>
+
+		 *
+		 * @param charCode An integer that represents a character code.
+		 * Character codes are usually represented in hexadecimal format.
+		 * For example, the space character's character code can be
+		 * represented by the number <code>0x0020</code>.
+		 *
+		 * @return <code>true</code> if <code>charCode</code> is a whitespace character. 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		static public function isWhitespace(charCode:int):Boolean
+		{			
+			return whiteSpaceObject[charCode];
+		}
+	}
+}
diff --git a/textLayout_core/src/flashx/textLayout/utils/GeometryUtil.as b/textLayout_core/src/flashx/textLayout/utils/GeometryUtil.as
new file mode 100755
index 0000000..b5e710f
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/utils/GeometryUtil.as
@@ -0,0 +1,128 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.utils
+{
+	import flash.geom.Rectangle;
+	import flash.text.engine.TextLine;
+	
+	import flashx.textLayout.compose.IFlowComposer;
+	import flashx.textLayout.compose.TextFlowLine;
+	import flashx.textLayout.elements.TextRange;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+	/** 
+	 * Utilities for getting information about text geometry and bounds.
+	 * The methods of this class are static and must be called using
+	 * the syntax <code>GeometryUtil.method(<em>parameter</em>)</code>.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	 [ExcludeClass]
+	public final class GeometryUtil
+	{
+		/**
+		 * Returns an array of line/rectangle object pairs describing the highlight area of the text 
+		 * based on the content bounded within the indicies. The rectangles are the same as those which would be 
+		 * created if the text were selected. May return one or more pair per line.
+		 * 
+		 * 
+		 * @param range	- a TextRange describing the TextFlow as well as the beginning and end indicies
+		 * @return Array - An array of TextLine and Rectangle pairs. The objects can be referenced as:
+		 * 		obj.textLine - to access the TextLine object
+		 *		obj.rect - to access the rectangle describing the selection in TextLine coordinates
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * 
+		 * Example Usage:
+		 *  var theRect:Rectangle = returnArray[0].rect.clone(); 
+		 *  var textLine:TextLine = returnArray[0].textLine; 
+		 * 	var globalStart:Point = new Point(theRect.x, theRect.y);
+		 *  globalStart = textLine.localToGlobal(globalStart);
+		 *  globalStart = textLine.parent.globalToLocal(globalStart);
+		 *  theRect.x = globalStart.x;
+		 *  theRect.y = globalStart.y;
+		 * 
+		 *  [Make a new shape and draw the path into it. See flash.display.graphics]
+		 *  textLine.parent.addChild(newShape);
+		 */
+		public static function getHighlightBounds(range:TextRange):Array
+		{
+			var flowComposer:IFlowComposer = range.textFlow.flowComposer;
+			if (!flowComposer)
+				return null;
+			
+			
+			var resultShapes:Array = new Array();
+			
+			var begLine:int = flowComposer.findLineIndexAtPosition(range.absoluteStart);
+			var endLine:int = range.absoluteStart == range.absoluteEnd ? begLine : flowComposer.findLineIndexAtPosition(range.absoluteEnd);
+			
+			// watch for going past the end
+			if (endLine >= flowComposer.numLines)
+				endLine = flowComposer.numLines-1;
+					
+			var prevLine:TextFlowLine = begLine > 0 ? flowComposer.getLineAt(begLine-1) : null;
+			var nextLine:TextFlowLine;
+
+			var line:TextFlowLine = flowComposer.getLineAt(begLine); 
+			
+			
+			for (var curLineIndex:int = begLine; curLineIndex <= endLine; curLineIndex++)
+			{
+				nextLine = curLineIndex != (flowComposer.numLines - 1) ? flowComposer.getLineAt(curLineIndex + 1) : null;
+				
+				var mainRects:Array = new Array();
+				var tcyRects:Array = new Array();
+				
+				var heightAndAdj:Array = line.getRomanSelectionHeightAndVerticalAdjustment(prevLine, nextLine);
+				
+				var textLine:TextLine = line.getTextLine();
+				line.calculateSelectionBounds(textLine, mainRects, 
+					range.absoluteStart < line.absoluteStart ? line.absoluteStart - line.paragraph.getAbsoluteStart()
+ 															 : range.absoluteStart - line.paragraph.getAbsoluteStart(), 
+					range.absoluteEnd > (line.absoluteStart + line.textLength) ? line.absoluteStart + line.textLength - line.paragraph.getAbsoluteStart()
+																			   : range.absoluteEnd - line.paragraph.getAbsoluteStart(), 
+					range.textFlow.computedFormat.blockProgression, heightAndAdj);
+				
+					
+				for each(var rect:Rectangle in mainRects)
+				{
+					var obj:Object = new Object();
+					obj.textLine = textLine;
+					obj.rect = rect.clone();
+					
+					resultShapes.push(obj);
+				}
+				
+				var temp:TextFlowLine = line;
+				line = nextLine;
+				prevLine = temp;
+				
+			}
+			
+			return resultShapes;
+		}
+	}
+	
+}
\ No newline at end of file
diff --git a/textLayout_core/src/flashx/textLayout/utils/LocaleUtil.as b/textLayout_core/src/flashx/textLayout/utils/LocaleUtil.as
new file mode 100755
index 0000000..0e46618
--- /dev/null
+++ b/textLayout_core/src/flashx/textLayout/utils/LocaleUtil.as
@@ -0,0 +1,237 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.utils
+{
+	import flash.text.engine.JustificationStyle;
+	import flash.text.engine.TextBaseline;
+	import flash.utils.Dictionary;
+	
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.JustificationRule;
+	import flashx.textLayout.formats.LeadingModel;
+	import flashx.textLayout.tlf_internal;
+	
+	
+	use namespace tlf_internal;
+	/** 
+	 * Utilities for managing and getting information about Locale based defaults.
+	 * The methods of this class are static and must be called using
+	 * the syntax <code>LocaleUtil.method(<em>parameter</em>)</code>.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	[ExcludeClass]
+	public final class LocaleUtil
+	{
+		public function LocaleUtil()
+		{
+		}
+		
+		
+		/** @private */
+		static private var _localeSettings:Dictionary = null;
+		static private var _lastLocaleKey:String = "";
+		static private var _lastLocale:LocaleSettings = null;
+		
+		static public function justificationRule(locale:String):String 
+		{
+			var localeSet:LocaleSettings = fetchLocaleSet(locale);
+			CONFIG::debug{ assert(localeSet != null, "Failed to get LocaleSettings from locale! locale = " + locale); }
+			
+			return localeSet.justificationRule;
+		}
+		
+		static public function justificationStyle(locale:String):String
+		{
+			var localeSet:LocaleSettings = fetchLocaleSet(locale);
+			CONFIG::debug{ assert(localeSet != null, "Failed to get LocaleSettings from locale! locale = " + locale); }
+			
+			return localeSet.justificationStyle;
+		}
+		
+		static public function leadingModel(locale:String):String
+		{
+			var localeSet:LocaleSettings = fetchLocaleSet(locale);
+			CONFIG::debug{ assert(localeSet != null, "Failed to get LocaleSettings from locale! locale = " + locale); }
+			
+			return localeSet.leadingModel;
+		}
+		
+		
+		static public function dominantBaseline(locale:String):String
+		{
+			var localeSet:LocaleSettings = fetchLocaleSet(locale);
+			CONFIG::debug{ assert(localeSet != null, "Failed to get LocaleSettings from locale! locale = " + locale); }
+			
+			return localeSet.dominantBaseline;
+		}
+		
+		/** @private */
+		static private function initializeDefaultLocales():void
+		{
+			CONFIG::debug{ assert(_localeSettings == null, "Should not call initializeDefaultLocales when dictionary exists!"); }
+			_localeSettings = new Dictionary();
+			
+			try
+			{
+				var locale:LocaleSettings = addLocale("en");
+				CONFIG::debug{ assert(locale != null, "Failed to create new locale for 'en'!"); }
+	
+				locale.justificationRule = JustificationRule.SPACE;
+				locale.justificationStyle = JustificationStyle.PUSH_IN_KINSOKU;
+				locale.leadingModel = LeadingModel.ROMAN_UP;
+				locale.dominantBaseline = TextBaseline.ROMAN;
+				
+				locale = addLocale("ja");
+				CONFIG::debug{ assert(locale != null, "Failed to create new locale for 'ja'!"); }
+	
+				locale.justificationRule = JustificationRule.EAST_ASIAN;
+				locale.justificationStyle = JustificationStyle.PUSH_IN_KINSOKU;
+				locale.leadingModel = LeadingModel.IDEOGRAPHIC_TOP_DOWN;
+				locale.dominantBaseline = TextBaseline.IDEOGRAPHIC_CENTER;
+				
+				locale = addLocale("zh");
+				CONFIG::debug{ assert(locale != null, "Failed to create new locale for 'zh'!"); }
+	
+				locale.justificationRule = JustificationRule.EAST_ASIAN;
+				locale.justificationStyle = JustificationStyle.PUSH_IN_KINSOKU;
+				locale.leadingModel = LeadingModel.IDEOGRAPHIC_TOP_DOWN;
+				locale.dominantBaseline = TextBaseline.IDEOGRAPHIC_CENTER;
+			}	
+			catch(e:ArgumentError)
+			{
+				trace(e);
+				return;
+			}		
+			finally
+			{
+				return;
+			}
+		}
+		
+		/** @private */
+		static private function addLocale(locale:String):LocaleSettings
+		{
+			CONFIG::debug{ assert(_localeSettings[locale] == null, "Cannot add a new locale property set when it already exists.  Locale == " + locale); }
+			_localeSettings[locale] = new LocaleSettings();
+			return _localeSettings[locale];
+		}
+		
+		/** @private */
+		static private function getLocale(locale:String):LocaleSettings
+		{
+			var lowerLocale:String = locale.toLowerCase();
+			if(lowerLocale.indexOf("en") == 0)
+				return _localeSettings["en"];
+			else if(lowerLocale.indexOf("ja") == 0)
+				return _localeSettings["ja"];
+			else if(lowerLocale.indexOf("zh") == 0)
+				return _localeSettings["zh"];
+			else //default
+				return _localeSettings["en"];
+		}
+		
+		/** @private */
+		static private function fetchLocaleSet(locale:String):LocaleSettings
+		{
+			if(_localeSettings == null)
+				initializeDefaultLocales();
+			
+			var localeSet:LocaleSettings = null;
+			if(locale == _lastLocaleKey)
+				localeSet = _lastLocale;
+			else
+			{
+				localeSet = getLocale(locale);
+				
+				//update the last locale data
+				_lastLocale = localeSet;
+				_lastLocaleKey = locale;
+			}
+			return localeSet;
+		}
+	}
+	
+	
+}
+
+import flashx.textLayout.formats.JustificationRule;
+import flash.text.engine.JustificationStyle;
+import flashx.textLayout.formats.LeadingModel;
+import flash.text.engine.TextBaseline;
+
+import flashx.textLayout.debug.assert;
+import flashx.textLayout.tlf_internal;
+import flashx.textLayout.formats.TextLayoutFormat;
+
+use namespace tlf_internal;
+
+internal class LocaleSettings
+{
+	public function LocaleSettings()
+	{}
+	
+	private var _justificationRule:String = null;
+	private var _justificationStyle:String = null;
+	private var _leadingModel:String = null;
+	private var _dominantBaseline:String = null;
+	
+	public function get justificationRule():String { return _justificationRule; }
+	public function set justificationRule(newValue:String):void 
+	{ 
+		var setValue:Object = TextLayoutFormat.justificationRuleProperty.setHelper(_justificationRule,newValue);
+		//don't assert if the newValue is null, only if it is invalid
+		CONFIG::debug{ assert(newValue == null || setValue != null, "LocaleUtil should never be providing an invalid JustificationRule!"); }
+		
+		_justificationRule = setValue == null ? null : (setValue as String);
+	}
+	
+	public function get justificationStyle():String { return _justificationStyle; }
+	public function set justificationStyle(newValue:String):void 
+	{ 
+		var setValue:Object = TextLayoutFormat.justificationStyleProperty.setHelper(_justificationStyle,newValue);
+		//don't assert if the newValue is null, only if it is invalid
+		CONFIG::debug{ assert(newValue == null || setValue != null, "LocaleUtil should never be providing an invalid LeadingDirection!"); }
+		
+		_justificationStyle = setValue == null ? null : (setValue as String);
+	}
+	
+	public function get leadingModel():String { return _leadingModel; }
+	public function set leadingModel(newValue:String):void 
+	{ 
+		var setValue:Object = TextLayoutFormat.leadingModelProperty.setHelper(_leadingModel,newValue);
+		//don't assert if the newValue is null, only if it is invalid
+		CONFIG::debug{ assert(newValue == null || setValue != null, "LocaleUtil should never be providing an invalid JustificationStyle!"); }
+		
+		_leadingModel = setValue == null ? null : (setValue as String);
+	}
+	
+	
+	public function get dominantBaseline():String { return _dominantBaseline; }
+	public function set dominantBaseline(newValue:String):void 
+	{ 
+		var setValue:Object = TextLayoutFormat.dominantBaselineProperty.setHelper(_dominantBaseline,newValue);
+		//don't assert if the newValue is null, only if it is invalid
+		CONFIG::debug{ assert(newValue == null || setValue != null, "LocaleUtil should never be providing an invalid TextBaseline!"); }
+		
+		_dominantBaseline = setValue == null ? null : (setValue as String);
+	}
+}
\ No newline at end of file
diff --git a/textLayout_core/version.txt b/textLayout_core/version.txt
new file mode 100755
index 0000000..8374538
--- /dev/null
+++ b/textLayout_core/version.txt
@@ -0,0 +1,8 @@
+#Fri Jan 29 11:40:38 PST 2010
+buildType=Published
+flashplayer.latest.good.win=309
+flashplayer.latest.good.lnx=584
+version=1.0
+flashplayer.latest.good.mac=307
+flashplayer.version=10.1.50.302
+build=595
diff --git a/textLayout_edit/.actionScriptProperties b/textLayout_edit/.actionScriptProperties
new file mode 100755
index 0000000..bee8a68
--- /dev/null
+++ b/textLayout_edit/.actionScriptProperties
@@ -0,0 +1,64 @@
+# 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.
+
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<actionScriptProperties mainApplicationPath="textLayout_edit.as" projectUUID="741cd106-3543-4625-982d-b703fe2bcdf5" version="6">
+  <compiler additionalCompilerArguments="-locale en_US -load-config+=../../config.xml" autoRSLOrdering="true" copyDependentFiles="false" generateAccessible="false" htmlExpressInstall="true" htmlGenerate="false" htmlHistoryManagement="false" htmlPlayerVersionCheck="true" includeNetmonSwc="false" outputFolderPath="bin" sourceFolderPath="src" strict="true" targetPlayerVersion="0.0.0" useApolloConfig="false" useDebugRSLSwfs="true" verifyDigests="true" warn="true">
+    <compilerSourcePath/>
+    <libraryPath defaultLinkType="0">
+      <libraryPathEntry kind="3" linkType="4" path="/textLayout_conversion/bin/textLayout_conversion.swc" useDefaultLinkType="true"/>
+      <libraryPathEntry kind="3" linkType="4" path="/textLayout_core/bin/textLayout_core.swc" useDefaultLinkType="true"/>
+      <libraryPathEntry kind="4" path="">
+        <excludedEntries>
+          <libraryPathEntry kind="1" linkType="1" path="${PROJECT_FRAMEWORKS}/locale/{locale}"/>
+          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/flex.swc" useDefaultLinkType="false"/>
+          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/sparkskins.swc" useDefaultLinkType="false"/>
+          <libraryPathEntry index="4" kind="3" linkType="4" path="${PROJECT_FRAMEWORKS}/libs/rpc.swc" useDefaultLinkType="true">
+            <crossDomainRsls>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="http://fpdownload.adobe.com/pub/swz/crossdomain.xml" rslUrl="http://fpdownload.adobe.com/pub/swz/flex/4.0.0.10485/rpc_4.0.0.10485.swz"/>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="" rslUrl="rpc_4.0.0.10485.swz"/>
+            </crossDomainRsls>
+          </libraryPathEntry>
+          <libraryPathEntry index="2" kind="3" linkType="4" path="${PROJECT_FRAMEWORKS}/libs/framework.swc" useDefaultLinkType="true">
+            <crossDomainRsls>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="http://fpdownload.adobe.com/pub/swz/crossdomain.xml" rslUrl="http://fpdownload.adobe.com/pub/swz/flex/4.0.0.10485/framework_4.0.0.10485.swz"/>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="" rslUrl="framework_4.0.0.10485.swz"/>
+            </crossDomainRsls>
+          </libraryPathEntry>
+          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/datavisualization.swc" useDefaultLinkType="false"/>
+          <libraryPathEntry index="1" kind="3" linkType="4" path="${PROJECT_FRAMEWORKS}/libs/textLayout.swc" useDefaultLinkType="true">
+            <crossDomainRsls>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="http://fpdownload.adobe.com/pub/swz/crossdomain.xml" rslUrl="http://fpdownload.adobe.com/pub/swz/flex/4.0.0.10485/textLayout_4.0.0.10485.swz"/>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="" rslUrl="textLayout_4.0.0.10485.swz"/>
+            </crossDomainRsls>
+          </libraryPathEntry>
+          <libraryPathEntry index="3" kind="3" linkType="4" path="${PROJECT_FRAMEWORKS}/libs/spark.swc" useDefaultLinkType="true">
+            <crossDomainRsls>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="http://fpdownload.adobe.com/pub/swz/crossdomain.xml" rslUrl="http://fpdownload.adobe.com/pub/swz/flex/4.0.0.10485/spark_4.0.0.10485.swz"/>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="" rslUrl="spark_4.0.0.10485.swz"/>
+            </crossDomainRsls>
+          </libraryPathEntry>
+          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/utilities.swc" useDefaultLinkType="false"/>
+        </excludedEntries>
+      </libraryPathEntry>
+    </libraryPath>
+    <sourceAttachmentPath/>
+  </compiler>
+  <applications>
+    <application path="textLayout_edit.as"/>
+  </applications>
+  <modules/>
+  <buildCSSFiles/>
+</actionScriptProperties>
diff --git a/textLayout_edit/.flexLibProperties b/textLayout_edit/.flexLibProperties
new file mode 100755
index 0000000..7bd5bd6
--- /dev/null
+++ b/textLayout_edit/.flexLibProperties
@@ -0,0 +1,23 @@
+# 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.
+
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<flexLibProperties includeAllClasses="false" version="3">
+  <includeClasses>
+    <classEntry path="flashx.textLayout.EditClasses"/>
+  </includeClasses>
+  <includeResources/>
+  <namespaceManifests/>
+</flexLibProperties>
diff --git a/textLayout_edit/.project b/textLayout_edit/.project
new file mode 100755
index 0000000..f357d31
--- /dev/null
+++ b/textLayout_edit/.project
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<projectDescription>
+	<name>textLayout_edit</name>
+	<comment></comment>
+	<projects>
+		<project>textLayout_conversion</project>
+		<project>textLayout_core</project>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.adobe.flexbuilder.project.flexbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.adobe.flexbuilder.project.flexlibnature</nature>
+		<nature>com.adobe.flexbuilder.project.actionscriptnature</nature>
+	</natures>
+</projectDescription>
diff --git a/textLayout_edit/src/flash/text/ime/CompositionAttributeRange.as b/textLayout_edit/src/flash/text/ime/CompositionAttributeRange.as
new file mode 100755
index 0000000..9473ae7
--- /dev/null
+++ b/textLayout_edit/src/flash/text/ime/CompositionAttributeRange.as
@@ -0,0 +1,121 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flash.text.ime
+{
+
+//
+// CompositionAttributeRange
+//
+
+/**
+* The CompositionAttributeRange class represents a range of composition attributes for use with IME events. 
+* For example, when editing text in the IME, the text is divided by the IME into composition ranges.
+* These composition ranges are flagged as selected (i.e. currently being lengthened, shortened, or edited),
+* and/or converted (i.e. they have made one pass through the IME dictionary lookup already).
+*
+* <p>By convention, the client should adorn these composition ranges with underlining or hiliting according to
+* the flags.</p>
+*
+* <p>For example:</p>
+* <listing>
+*      !converted              = thick gray underline (raw text)
+*      !selected &#38;&#38; converted  = thin black underline
+*       selected &#38;&#38; converted  = thick black underline
+* </listing>
+* @playerversion Flash 10.1
+ * @playerversion AIR 1.5
+* @langversion 3.0
+*/
+public final class CompositionAttributeRange
+{
+	/**
+	 * The relative start from the beginning of the inline edit session
+	 * i.e. 0 = the start of the text the IME can see (there may be text 
+	 * before that in the edit field)
+	 * 
+	 * @helpid 
+	 * 
+	 * @playerversion Flash 10.1
+	 * @langversion 3.0
+	 * 
+	*/
+	public var relativeStart:int;
+
+	/**
+	 * The relative end of the composition clause, relative to the beginning
+	 * of the inline edit session.
+	 * i.e. 0 = the start of the text the IME can see (there may be text 
+	 * before that in the edit field)
+	 * 
+	 * @helpid 
+	 * 
+	 * @playerversion Flash 10.1
+	 * @langversion 3.0
+	 * 
+	*/
+	public var relativeEnd:int;
+
+	/**
+	 * The selected flag, meaning this composition clause is active and 
+	 * being lengthened or shortened or edited with the IME, and the neighboring
+	 * clauses are not.
+	 * 
+	 * @helpid 
+	 * 
+	 * @playerversion Flash 10.1
+	 * @langversion 3.0
+	 * 
+	*/
+	public var selected:Boolean;
+
+	/**
+	 * The converted flag, meaning this clause has been processed by the IME
+	 * and is awaiting acceptance/confirmation by the user
+	 * 
+	 * @helpid 
+	 * 
+	 * @playerversion Flash 10.1
+	 * @langversion 3.0
+	 * 
+	*/
+	public var converted:Boolean;
+
+	// Constructor
+	/**
+	 * Creates a CompositionAttributeRange object.
+	 *
+	 * @playerversion Flash 10.1
+	 * @langversion 3.0
+	 * 
+	 * @param relativeStart  The zero based index of the first character included in the character range.
+	 * @param relativeEnd  The zero based index of the last character included in the character range.
+	 * @param selected  The selected flag
+	 * @param converted  The converted flag
+	 *
+	 * @tiptext Constructor for CompositionAttributeRange objects.
+	 */	
+	public function CompositionAttributeRange(relativeStart:int, relativeEnd:int, selected:Boolean, converted:Boolean):void
+	{
+		this.relativeStart = relativeStart;
+		this.relativeEnd = relativeEnd;
+		this.selected = selected;
+		this.converted = converted;
+	}
+} // end of class
+} // end of package
diff --git a/textLayout_edit/src/flash/text/ime/IIMEClient.as b/textLayout_edit/src/flash/text/ime/IIMEClient.as
new file mode 100755
index 0000000..ec7ea82
--- /dev/null
+++ b/textLayout_edit/src/flash/text/ime/IIMEClient.as
@@ -0,0 +1,186 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flash.text.ime
+{
+
+import flash.geom.Rectangle;
+
+//
+// IIMEClient
+//
+/**
+ * Dispatched when the user begins to use an IME (input method editor).
+ * @eventType flash.events.IMEEvent.IME_START_COMPOSITION
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+[Event(name="imeStartComposition", type="flash.IMEEvent.IME_START_COMPOSITION")]
+
+/**
+ * Dispatched when the user enters text. For IME (input method editor) clients, the receiver should 
+ * insert the string contained in the event object's <code>text</code> property at the current insertion point.
+ * @eventType flash.events.TextEvent.TEXT_INPUT
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */
+[Event(name="textInput", type="flash.TextEvent.TEXT_INPUT")]
+
+/**
+* Interface for IME (input method editor) clients.  Components based on the flash.text.engine package must implement 
+* this interface to support editing text inline using an IME. This interface is not used with TextField objects. 
+* TextLayoutFramework (TLF) uses this interface to support inline IME, so clients using TLF do not need to implement this 
+* interface. 
+* <p>To support inline IME, set the <code>imeClient</code> property of an <code>ImeEvent.IME_START_COMPOSITION</code> event to
+* an object which implements this interface.</p>
+*
+* @see flash.text.ime.CompositionAttributeRange
+* @see flash.events.ImeEvent:imeClient
+* 
+* @playerversion Flash 10.1
+* @playerversion AIR 1.5
+* @langversion 3.0
+*/
+public interface IIMEClient
+{
+	/**
+	* Callback for updating the contents of the inline editing session.
+	* This gets called whenever the text being edited with the IME has changed
+	* and its contents are used by the client to redraw the entire inline edit session.
+	* 
+	* @playerversion Flash 10.1
+	* @langversion 3.0
+	* 
+	* @param text  contains the text of the inline edit session from the IME
+	* @param attributes  contains an array of composition clauses with adornment info 
+	* @param relativeSelectionStart  start of the inline session relative to the start of the text object
+	* @param relativeSelectionEnd  end of the inline session relative to the start of the text object
+	*/
+	function updateComposition(text:String, attributes:Vector.<CompositionAttributeRange>,
+								compositionStartIndex:int, compositionEndIndex:int):void;
+								
+	/**
+	* Use this callback to end the inline editing session and confirm the text.
+	* 
+	* @playerversion Flash 10.1
+	* @langversion 3.0
+	* 
+	* @param text  the final state of the text in the inline session (the text that got confirmed).
+	* @param preserveSelection  when true, you should not reset the current selection to the end of the confirmed text.
+	*/
+	function confirmComposition(text:String = null, preserveSelection:Boolean = false):void;
+
+	/**
+	* This callback is used by the IME to query the bounding box of the text being edited with the IME client.
+	* Use this method to place the candidate window and set the mouse cursor in the IME client when the mouse is over the 
+	* text field or other component that supports IME.
+	* 
+	* @playerversion Flash 10.1
+	* @langversion 3.0
+	* 
+	* @param startIndex an integer that specifies the starting location of the range of text for which you need to measure the bounding box.
+	* @param endIndex Optional; an integer that specifies the ending location of the range of text for which you need to measure the bounding box.
+	*
+	* @return  the bounding box of the specified range of text, or <code>null</code> if either or both of the indexes are invalid.
+	* The same value should be returned independant of whether <code>startIndex</code> is greater or less than <code>endIndex</code>.
+	*/
+	function getTextBounds(startIndex:int, endIndex:int):Rectangle;
+
+	/** 
+	 * The zero-based character index value of the start of the current edit session text (i.e.
+	 * all text in the inline session that is still not yet confirmed to the document).
+	 *
+	 * @return the index of the first character of the composition, or <code>-1</code> if there is no active composition.
+	 * 
+	 * @playerversion Flash 10.1
+	 * @langversion 3.0
+	 */
+	function get compositionStartIndex():int;
+
+	/** 
+	 * The zero-based character index value of the end of the current edit session text (i.e.
+	 * all text in the inline session that is still not yet confirmed to the document).
+	 *
+	 * @return the index of the last character of the composition, or <code>-1</code> if there is no active composition.
+	 * 
+	 * @playerversion Flash 10.1
+	 * @langversion 3.0
+	 */
+	function get compositionEndIndex():int;
+
+	/** 
+	 * Indicates whether the text in the component is vertical or not.  This will affect the positioning
+	 * of the candidate window (beside vertical text, below horizontal text).
+	 *
+	 * @return <code>true</code> if the text is vertical, otherwise false.
+	 * 
+	 * @playerversion Flash 10.1
+	 * @langversion 3.0
+	 */
+    function get verticalTextLayout():Boolean;
+
+	/** 
+	 * The zero-based character index value of the first character in the current selection.
+	 *
+	 * @return the index of the character at the anchor end of the selection, or <code>-1</code> if no text is selected.
+	 * 
+	 * @playerversion Flash 10.1
+	 * @langversion 3.0
+	 */
+	function get selectionAnchorIndex():int;
+
+	/** 
+	 * The zero-based character index value of the last character in the current selection.
+	 *
+	 * @return the index of the character at the active end of the selection, or <code>-1</code> if no text is selected.
+	 * 
+	 * @playerversion Flash 10.1
+	 * @langversion 3.0
+	 */
+	function get selectionActiveIndex():int;
+    
+	/** 
+	 * Sets the range of selected text in the component.
+	 * If either of the arguments is out of bounds the selection should not be changed.
+	 * 
+	 * @param anchorIndex The zero-based index value of the character at the anchor end of the selection
+	 * @param activeIndex The zero-based index value of the character at the active end of the selection.
+	 * 
+	 * @playerversion Flash 10.1
+	 * @langversion 3.0
+	 */
+	function selectRange(anchorIndex:int, activeIndex:int):void;
+    
+	/** 
+	 * Gets the specified range of text from the component.  This method is called during IME reconversion.
+	 * 
+	 * @param startIndex an integer that specifies the starting location of the range of text to be retrieved.
+	 * @param endIndex an integer that specifies the ending location of the range of text to be retrieved.
+	 * 
+	 * @return The requested text, or <code>null</code> if no text is available in the requested range
+	 * or if either or both of the indexes are invalid.  The same value should be returned 
+	 * independant of whether <code>startIndex</code> is greater or less than <code>endIndex</code>.
+	 * 
+	 * @playerversion Flash 10.1
+	 * @langversion 3.0
+	 */
+	function getTextInRange(startIndex:int, endIndex:int):String;
+} // end of class
+} // end of package
diff --git a/textLayout_edit/src/flashx/textLayout/EditClasses.as b/textLayout_edit/src/flashx/textLayout/EditClasses.as
new file mode 100755
index 0000000..f6cce19
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/EditClasses.as
@@ -0,0 +1,66 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout
+{
+	internal class EditClasses
+	{
+		import flash.text.ime.CompositionAttributeRange; flash.text.ime.CompositionAttributeRange;
+		import flash.text.ime.IIMEClient; flash.text.ime.IIMEClient;
+		
+		import flashx.textLayout.container.TextContainerManager; TextContainerManager;
+		
+		import flashx.textLayout.events.FlowOperationEvent; FlowOperationEvent;
+		import flashx.textLayout.events.SelectionEvent; SelectionEvent;
+ 
+		import flashx.textLayout.edit.ElementRange; ElementRange;
+		import flashx.textLayout.edit.IEditManager; IEditManager;
+		import flashx.textLayout.edit.Mark; Mark;
+		import flashx.textLayout.edit.SelectionManager; SelectionManager;
+
+		import flashx.textLayout.edit.TextScrap; TextScrap;
+
+		import flashx.textLayout.operations.ApplyFormatOperation; ApplyFormatOperation;
+		import flashx.textLayout.operations.ApplyFormatToElementOperation; ApplyFormatToElementOperation;
+		import flashx.textLayout.operations.ApplyLinkOperation; ApplyLinkOperation;
+		import flashx.textLayout.operations.ApplyTCYOperation; ApplyTCYOperation;
+		import flashx.textLayout.operations.ApplyElementIDOperation; ApplyElementIDOperation;
+		import flashx.textLayout.operations.ApplyElementStyleNameOperation; ApplyElementStyleNameOperation;
+		import flashx.textLayout.operations.ClearFormatOperation; ClearFormatOperation;
+		import flashx.textLayout.operations.ClearFormatOnElementOperation; ClearFormatOnElementOperation;
+		import flashx.textLayout.operations.CompositeOperation; CompositeOperation;
+		import flashx.textLayout.operations.CopyOperation; CopyOperation;
+		import flashx.textLayout.operations.CutOperation; CutOperation;
+		import flashx.textLayout.operations.DeleteTextOperation; DeleteTextOperation;
+		import flashx.textLayout.operations.FlowOperation; FlowOperation;
+		import flashx.textLayout.operations.InsertInlineGraphicOperation; InsertInlineGraphicOperation;
+		import flashx.textLayout.operations.InsertTextOperation; InsertTextOperation;
+		import flashx.textLayout.operations.PasteOperation; PasteOperation;
+		import flashx.textLayout.operations.RedoOperation; RedoOperation;
+		import flashx.textLayout.operations.ApplyElementUserStyleOperation; ApplyElementUserStyleOperation;
+		import flashx.textLayout.operations.SplitParagraphOperation; SplitParagraphOperation;
+		import flashx.textLayout.operations.UndoOperation; UndoOperation;
+
+		import flashx.textLayout.utils.NavigationUtil; NavigationUtil;
+		
+		import flashx.undo.IOperation; flashx.undo.IOperation;
+		import flashx.undo.IUndoManager; flashx.undo.IUndoManager;
+		import flashx.undo.UndoManager; flashx.undo.UndoManager;
+
+	}
+}
diff --git a/textLayout_edit/src/flashx/textLayout/container/TextContainerManager.as b/textLayout_edit/src/flashx/textLayout/container/TextContainerManager.as
new file mode 100755
index 0000000..37126be
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/container/TextContainerManager.as
@@ -0,0 +1,2241 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.container
+{
+	import flash.display.DisplayObject;
+	import flash.display.InteractiveObject;
+	import flash.display.Sprite;
+	import flash.events.ContextMenuEvent;
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+	import flash.events.FocusEvent;
+	import flash.events.IMEEvent;
+	import flash.events.KeyboardEvent;
+	import flash.events.MouseEvent;
+	import flash.events.TextEvent;
+	import flash.geom.Rectangle;
+	import flash.text.engine.TextBlock;
+	import flash.text.engine.TextLine;
+	import flash.text.engine.TextLineValidity;
+	import flash.ui.ContextMenu;
+	import flash.ui.ContextMenuClipboardItems;
+	import flash.ui.Mouse;
+	import flash.ui.MouseCursor;
+	import flash.utils.Dictionary;
+	
+	import flashx.textLayout.compose.BaseCompose;
+	import flashx.textLayout.compose.ISWFContext;
+	import flashx.textLayout.compose.StandardFlowComposer;
+	import flashx.textLayout.compose.TextFlowLine;
+	import flashx.textLayout.compose.TextLineRecycler;
+	import flashx.textLayout.debug.Debugging;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.edit.EditManager;
+	import flashx.textLayout.edit.EditingMode;
+	import flashx.textLayout.edit.IEditManager;
+	import flashx.textLayout.edit.IInteractionEventHandler;
+	import flashx.textLayout.edit.ISelectionManager;
+	import flashx.textLayout.edit.SelectionFormat;
+	import flashx.textLayout.edit.SelectionManager;
+	import flashx.textLayout.elements.Configuration;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.IConfiguration;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.SpanElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.events.CompositionCompleteEvent;
+	import flashx.textLayout.events.DamageEvent;
+	import flashx.textLayout.events.FlowOperationEvent;
+	import flashx.textLayout.events.SelectionEvent;
+	import flashx.textLayout.events.StatusChangeEvent;
+	import flashx.textLayout.events.TextLayoutEvent;
+	import flashx.textLayout.events.UpdateCompleteEvent;
+	import flashx.textLayout.external.WeakRef;
+	import flashx.textLayout.factory.StringTextLineFactory;
+	import flashx.textLayout.factory.TextFlowTextLineFactory;
+	import flashx.textLayout.factory.TextLineFactoryBase;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.formats.FormatValue;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.property.EnumStringProperty;
+	import flashx.textLayout.property.Property;
+	import flashx.textLayout.tlf_internal;
+	import flashx.undo.IUndoManager;
+	import flashx.undo.UndoManager;
+
+	use namespace tlf_internal;
+	/**
+	 *
+	 *  @eventType flashx.textLayout.events.FlowOperationEvent.FLOW_OPERATION_BEGIN
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	 
+	[Event(name="flowOperationBegin", type="flashx.textLayout.events.FlowOperationEvent")]
+	
+	/**
+	 * 
+	 * @eventType flashx.textLayout.events.FlowOperationEvent.FLOW_OPERATION_END
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	 
+	[Event(name="flowOperationEnd", type="flashx.textLayout.events.FlowOperationEvent")]
+	
+	
+	/**
+	 * 
+	 * @eventType flashx.textLayout.events.FlowOperationEvent.FLOW_OPERATION_COMPLETE
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="flowOperationComplete", type="flashx.textLayout.events.FlowOperationEvent")]
+	
+	/** Dispatched whenever the selection is changed.  Primarily used to update selection-dependent user interface. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="selectionChange", type="flashx.textLayout.events.SelectionEvent")]
+	
+	/** Dispatched after every recompose. 
+	*
+	* @playerversion Flash 10
+	* @playerversion AIR 1.5
+	* @langversion 3.0
+	*/
+	
+	[Event(name="compositionComplete", type="flashx.textLayout.events.CompositionCompleteEvent")]
+	
+	/** Dispatched when the mouse is pressed down over any link. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="mouseDown", type="flashx.textLayout.events.FlowElementMouseEvent")]
+	
+	/** Dispatched when the mouse is released over any link. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="mouseUp", type="flashx.textLayout.events.FlowElementMouseEvent")]
+	
+	/** Dispatched when the mouse passes over any link. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="mouseMove", type="flashx.textLayout.events.FlowElementMouseEvent")]	
+	
+	/** Dispatched when the mouse first enters any link. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="rollOver", type="flashx.textLayout.events.FlowElementMouseEvent")]
+	
+	/** Dispatched when the mouse goes out of any link. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="rollOut", type="flashx.textLayout.events.FlowElementMouseEvent")]	
+	
+	/** Dispatched when any link is clicked. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="click", type="flashx.textLayout.events.FlowElementMouseEvent")]
+	
+	/** Dispatched when a InlineGraphicElement is resized due to having width or height as auto or percent 
+	 * and the graphic has finished loading. 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="inlineGraphicStatusChanged", type="flashx.textLayout.events.StatusChangeEvent")]
+	
+	/** Dispatched by a TextFlow object after text is scrolled within a controller container.  
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="scroll", type="flashx.textLayout.events.TextLayoutEvent")]
+	
+	/** Dispatched by a TextFlow object each time it is damaged 
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="damage", type="flashx.textLayout.events.DamageEvent")]
+
+	/** Dispatched by a TextFlow object each time a container has had new DisplayObjects added or updated as a result of composition.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	
+	[Event(name="updateComplete", type="flashx.textLayout.events.UpdateCompleteEvent")]
+		
+	[Exclude(name="getBaseSWFContext",kind="method")]
+	
+	[Exclude(name="callInContext",kind="method")]
+	/** Manages text in a container. Assumes that it manages all children of the container. 
+	 * Consider using TextContainerManager for better performance in cases where there is a 
+	 * one container per TextFlow, and the TextFlow is not the main focus, is static text, or
+	 * is infrequently selected. Good for text in form fields, for example.
+	 * 
+	 * @includeExample examples\TextContainerManager.as -noswf
+	 *
+ 	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 * 
+	 * @see ContainerController
+	 */			
+	public class TextContainerManager extends EventDispatcher implements ISWFContext, IInteractionEventHandler, ISandboxSupport
+	{
+		static private var _inputManagerTextFlowFactory:TextFlowTextLineFactory = new TextFlowTextLineFactory();
+		
+		// all events that are listened for need to be in this list.
+		static private const eventList:Array = [ 
+			FlowOperationEvent.FLOW_OPERATION_BEGIN,
+			FlowOperationEvent.FLOW_OPERATION_END,
+			FlowOperationEvent.FLOW_OPERATION_COMPLETE,
+			SelectionEvent.SELECTION_CHANGE,
+			CompositionCompleteEvent.COMPOSITION_COMPLETE,
+			MouseEvent.CLICK,		//from FlowElementMouseEvent
+			MouseEvent.MOUSE_DOWN,	//from FlowElementMouseEvent
+			MouseEvent.MOUSE_OUT,	//from FlowElementMouseEvent
+			MouseEvent.MOUSE_UP,	//from FlowElementMouseEvent
+			MouseEvent.MOUSE_OVER,	//from FlowElementMouseEvent
+			MouseEvent.MOUSE_OUT,	//from FlowElementMouseEvent
+			StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE,
+		 	TextLayoutEvent.SCROLL,
+			DamageEvent.DAMAGE,
+			UpdateCompleteEvent.UPDATE_COMPLETE
+		];
+		
+		/** Configuration to be used by the TextContainerManager.  This can only be set once and before the inputmanager is used.  */
+		static private var _inputManagerConfiguration:IConfiguration = null;
+		
+		/** The default configuration for this TextContainerManager. Column and padding attributes
+		 * are set to <code>FormatValue.INHERIT</code>.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 * 
+	 	 * @see flashx.textLayout.elements.IConfiguration IConfiguration
+	 	 * @see flashx.textLayout.formats.FormatValue#INHERIT FormatValue.INHERIT
+		 */
+		static public function get defaultConfiguration():IConfiguration
+		{
+			if (_inputManagerConfiguration == null)
+			{
+				var config:Configuration = new Configuration();
+				config.flowComposerClass = TextLineFactoryBase.getDefaultFlowComposerClass();
+				_inputManagerConfiguration = config;
+			}
+			return _inputManagerConfiguration; 
+		}
+		
+		static private var stringFactoryDictionary:Dictionary = new Dictionary(true);
+		static private function inputManagerStringFactory(config:IConfiguration):StringTextLineFactory
+		{
+			var factory:StringTextLineFactory = stringFactoryDictionary[config];
+			if (factory == null)
+			{
+				factory = new StringTextLineFactory(config);
+				stringFactoryDictionary[config] = factory;
+			}
+			return factory;
+		}
+		
+		/** Shared definition of the scrollPolicy property. @private */
+		static tlf_internal const editingModePropertyDefinition:EnumStringProperty = new EnumStringProperty("editingMode", EditingMode.READ_WRITE, false, null, 
+			EditingMode.READ_WRITE, EditingMode.READ_ONLY, EditingMode.READ_SELECT);	
+		
+		private var _container:Sprite;
+		private var _compositionWidth:Number;
+		private var _compositionHeight:Number;
+		
+		private var _text:String;
+		private var _textDamaged:Boolean;				// indicates the _text property needs updating when sourceState is SOURCE_TEXTFLOW
+		private var _lastSeparator:String;
+		
+		private var _hostFormat:ITextLayoutFormat;
+		private var _hostFormatHash:*;
+		
+		private var _contentTop:Number;
+		private var _contentLeft:Number;
+		private var _contentHeight:Number;
+		private var _contentWidth:Number;
+		
+		private var _horizontalScrollPolicy:String;
+		private var _verticalScrollPolicy:String;
+		
+		private var _swfContext:ISWFContext;
+		private var _config:IConfiguration;
+		
+		/** @private */
+		static tlf_internal const SOURCE_STRING:int = 0;
+		/** @private */
+		static tlf_internal const SOURCE_TEXTFLOW:int = 1;
+		
+		/** @private */
+		static tlf_internal const COMPOSE_FACTORY:int = 0;
+		/** @private */
+		static tlf_internal const COMPOSE_COMPOSER:int = 1;
+		
+		/** @private */
+		static tlf_internal const HANDLERS_NOTADDED:int  = 0;
+		/** @private */
+		static tlf_internal const HANDLERS_NONE:int      = 1;
+		/** @private */
+		static tlf_internal const HANDLERS_CREATION:int  = 2;
+		/** @private */
+		static tlf_internal const HANDLERS_ACTIVE:int    = 3;
+		
+		private var _sourceState:int;
+		private var _composeState:int;
+		private var _handlersState:int;
+		// track hasFocus.  Depending on various factors focus and mouseDown can occur in different order
+		private var _hasFocus:Boolean;
+		private var _editingMode:String;
+		private var _ibeamCursorSet:Boolean;
+		private var _interactionCount:int;
+		
+		/** @private */
+		tlf_internal function get sourceState():int
+		{ return _sourceState; }
+		/** @private */
+		tlf_internal function get composeState():int
+		{ return _composeState; }
+		/** @private */
+		tlf_internal function get handlersState():int
+		{ return _handlersState; }
+	
+		// Tracks damage when sourceState is SOURCE_STRING. TODO - Might be worthwhile to always set and clear this
+		private var _damaged:Boolean;			
+		private var _textFlow:TextFlow;
+		private var _needsRedraw:Boolean;
+		
+		/** Constructor function - creates a TextContainerManager instance.
+		 *
+		 * For best results:
+		 * <ol>
+		 *	<li>Start with TextContainerManager.defaultConfiguration and modify it</li>   
+		 *	<li>Share the same Configuration among many InputManagers</li>
+		 * </ol>
+		 *
+		 * @param container The DisplayObjectContainer in which to manage the text lines.
+		 * @param config - The IConfiguration instance to use with this TextContainerManager instance. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0	 	
+		 */
+		public function TextContainerManager(container:Sprite,configuration:IConfiguration =  null)
+		{
+			_container = container;
+			_compositionWidth = 100;
+			_compositionHeight = 100;
+			
+			_config = configuration ? configuration : defaultConfiguration;
+			_config = Configuration(_config).getImmutableClone();
+
+			_horizontalScrollPolicy = _verticalScrollPolicy = String(ScrollPolicy.scrollPolicyPropertyDefinition.defaultValue);
+
+			_damaged = true;
+			_needsRedraw = false;
+			_text = "";
+			_textDamaged = false;
+			
+			_sourceState = SOURCE_STRING;
+			_composeState = COMPOSE_FACTORY;
+			_handlersState = HANDLERS_NOTADDED;
+			_hasFocus = false;
+			
+			_editingMode = editingModePropertyDefinition.defaultValue as String;
+			_ibeamCursorSet = false;
+			_interactionCount = 0;
+			
+			if (_container is InteractiveObject)
+			{
+				_container.doubleClickEnabled = true;
+				// so the textlines can be swapped on the first click and a double click still works
+				_container.mouseChildren = false;
+				_container.focusRect = false;
+			}
+		}
+
+		/** Returns the container (DisplayObjectContainer) that holds the text that this TextContainerManager manages.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see ContainerController#container
+	 	 */
+	 	 
+		public function get container():Sprite
+		{ return _container; }
+		
+		/** Returns <code>true</code> if the content needs composing. 
+		 * 
+		 * @return	<code>true</code> if the content needs composing; <code>false</code> otherwise.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		public function isDamaged():Boolean
+		{ return _composeState == COMPOSE_FACTORY ? _damaged : _textFlow.flowComposer.isDamaged(_textFlow.textLength); }
+		
+		/** Editing mode of this TextContainerManager. Modes are reading only, reading and selection permitted, 
+		 * and editing (reading, selection, and writing)  permitted. Use the constant values of the EditingMode
+		 * class to set this property. 
+		 * <p>Default value is READ_WRITE.</p>
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+		 * @see flashx.textLayout.edit.EditingMode EditingMode
+		 */
+		public function get editingMode():String
+		{ return _editingMode; }
+		public function set editingMode(val:String):void
+		{
+			var newMode:String = editingModePropertyDefinition.setHelper(_editingMode, val) as String;
+			
+			if (newMode != _editingMode)
+			{
+				if (composeState == COMPOSE_COMPOSER)
+				{
+					_editingMode = newMode;
+					invalidateInteractionManager();
+				}
+				else
+				{
+					removeActivationEventListeners();
+					_editingMode = newMode;
+					// there is no way to turn it on here if going from READ_ONLY to editable and mouse is over the inputmanager field
+					if (_editingMode == EditingMode.READ_ONLY)
+						removeIBeamCursor();
+					addActivationEventListeners();
+				}
+			}
+		}
+		 		
+		/**
+		 * Returns the current text using a separator between paragraphs.
+		 * The separator can be specified with the <code>separator</code>
+		 * argument. The default value of the <code>separator</code> argument
+		 * is the Unicode character <code>'PARAGRAPH SEPARATOR' (U+2029)</code>.
+		 *
+		 * <p>Calling the setter discards any attached TextFlow. Any selection is lost.</p>
+		 * 
+		 * @param separator String to set between paragraphs.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+	 	 */
+		public function getText(separator:String = '\u2029'):String
+		{
+			if (_sourceState == SOURCE_STRING)
+				return _text;
+
+			if (_textDamaged || _lastSeparator != separator)
+			{
+				_text = "";
+				var firstLeaf:FlowLeafElement = _textFlow.getFirstLeaf();
+				if (firstLeaf != null)
+				{
+					var para:ParagraphElement = firstLeaf.getParagraph();
+					while (para)
+					{
+						var nextPara:ParagraphElement = para.getNextParagraph();
+						_text += para.getText();
+						_text += nextPara ? separator : "";
+						para = nextPara;
+					}
+				}
+				_textDamaged = false;
+				_lastSeparator = separator;
+			}
+			return _text;
+		}
+		/**
+		 * Sets the <code>text</code> property to the specified String.
+		 *
+		 * Discards any attached TextFlow. Any selection is lost.
+		 * 
+		 * @param str the String to set
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+	 	 */
+		public function setText(text:String):void
+		{
+			var hadPreviousSelection:Boolean = false;
+
+			if (_sourceState == SOURCE_TEXTFLOW)
+			{
+				if (_textFlow.interactionManager && _textFlow.interactionManager.hasSelection())
+					hadPreviousSelection = true;
+				removeTextFlowListeners();
+				if (_textFlow.flowComposer)
+					_textFlow.flowComposer.removeAllControllers();
+				_textFlow = null;
+				_sourceState = SOURCE_STRING;
+				_composeState = COMPOSE_FACTORY;
+				if (_container is InteractiveObject)
+					_container.mouseChildren = false;
+				addActivationEventListeners();
+			}
+			_text = text ? text : ""; 
+			_damaged = true;
+			_textDamaged = false;
+			
+			// Generate a damage event 
+			dispatchEvent(new DamageEvent(DamageEvent.DAMAGE, false, false, null, 0, _text.length));
+			
+			// generate a selection changed event
+			if (hadPreviousSelection)
+				dispatchEvent(new SelectionEvent(SelectionEvent.SELECTION_CHANGE, false, false, null));
+			
+			if (_hasFocus)
+				requiredFocusInHandler(null);
+		}
+				
+		/** Sets the format when display just a string.  If displaying a TextFlow this has no immediate effect.  The supplied ITextLayoutFormat is not copied.  Modifying it without calling this setter has indeterminate effects. */
+		public function get hostFormat():ITextLayoutFormat
+		{ return _hostFormat; }
+		public function set hostFormat(val:ITextLayoutFormat):void
+		{
+			_hostFormat = val;
+			_hostFormatHash = undefined;
+			
+			if (_sourceState == SOURCE_TEXTFLOW)
+				_textFlow.hostFormat = _hostFormat;
+			if (_composeState == COMPOSE_FACTORY)
+				_damaged = true;
+		}
+		
+		/** Returns the horizontal extent allowed for text inside the container. The value is specified in pixels.
+		 * 
+		 * <p>After setting this property, the text in the container is damaged and requires composing.</p>
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0  
+	 	 */
+		public function get compositionWidth():Number
+		{ return _compositionWidth; }
+		public function set compositionWidth(val:Number):void
+		{
+			if (_compositionWidth == val || (isNaN(_compositionWidth) && isNaN(val)))
+				return;
+			_compositionWidth = val; 
+			if (_composeState == COMPOSE_COMPOSER)
+			{
+				getController().setCompositionSize(_compositionWidth,_compositionHeight);
+			}
+			else
+			{
+				_damaged = true; 
+			}
+		}
+	
+		/** Returns the vertical extent allowed for text inside the container. The value is specified in pixels. 
+		 * <p>After setting this property, the text in the container is damaged and requires composing.</p>
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+	 	 
+		public function get compositionHeight():Number
+		{ return _compositionHeight; }
+		public function set compositionHeight(val:Number):void
+		{
+			if (_compositionHeight == val || (isNaN(_compositionHeight) && isNaN(val)))
+				return;
+			_compositionHeight = val; 
+			if (_composeState == COMPOSE_COMPOSER)
+			{
+				getController().setCompositionSize(_compositionWidth,_compositionHeight);
+			}
+			else
+			{
+				_damaged = true; 
+			}
+		}
+		
+		/** The Configuration object for this TextContainerManager. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see flashx.textLayout.IConfiguration IConfiguration
+	 	 */
+		public function get configuration():IConfiguration
+		{ return _config; }
+			
+		/** Creates a rectangle that shows where the last call to either the <code>compose()</code> 
+		 * method or the <code>updateContainer()</code> method placed the text.
+		 *
+		 * @return  the bounds of the content
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see #compose()
+	 	 * @see #updateContainer()
+		 */
+		public function getContentBounds():Rectangle
+		{
+			if (_composeState == COMPOSE_FACTORY)
+				return new Rectangle(_contentLeft, _contentTop, _contentWidth, _contentHeight);
+			var controller:ContainerController = getController();
+			return controller.getContentBounds();
+		}	
+		
+		/** The current TextFlow. Converts this to a full TextFlow representation if it 
+		 * isn't already one. 
+		 *
+		 * @return 	the current TextFlow object
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		public function getTextFlow():TextFlow
+		{
+			if (_sourceState != SOURCE_TEXTFLOW)
+			{
+				var wasDamaged:Boolean = isDamaged();
+				convertToTextFlow();
+				if (!wasDamaged)
+					updateContainer();
+			}
+			return _textFlow;
+		}
+
+		/** Sets a TextFlow into this TextContainerManager replacing any existing TextFlow and discarding the 
+		 * current text. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		public function setTextFlow(textFlow:TextFlow):void
+		{
+			if (textFlow == null)
+			{
+				setText(null);
+				return;
+			}
+			if (_sourceState == SOURCE_TEXTFLOW)
+			{
+				removeTextFlowListeners();
+				if (_textFlow.flowComposer)
+					_textFlow.flowComposer.removeAllControllers();
+			}
+				
+			_textFlow = textFlow;
+			_textFlow.hostFormat = hostFormat;
+			_sourceState = SOURCE_TEXTFLOW;
+			_composeState = textFlow.interactionManager || textFlow.mustUseComposer() ? COMPOSE_COMPOSER : COMPOSE_FACTORY;
+			_textDamaged = true;
+			addTextFlowListeners();
+			
+			if (_composeState == COMPOSE_COMPOSER)
+			{
+				// Possible issue - this clear call could be delayed until updateToController
+				_container.mouseChildren = true;
+				clearContainerChildren(true);
+				clearComposedLines();
+				_textFlow.flowComposer = new StandardFlowComposer();
+				_textFlow.flowComposer.swfContext = _swfContext;
+				var controller:TMContainerController = new TMContainerController(_container,_compositionWidth,_compositionHeight,this);
+				_textFlow.flowComposer.addController(controller);
+				
+				invalidateInteractionManager();
+				
+				// always start with an empty selection
+				if (_textFlow.interactionManager)
+					_textFlow.interactionManager.selectRange(-1,-1);
+			}
+			else
+				_damaged = true;
+			
+			if (_hasFocus)
+				requiredFocusInHandler(null);
+			
+			addActivationEventListeners();
+		}
+		
+		/** 
+		 * Controls whether the factory generates all text lines or stops when the container bounds are filled.
+		 * 
+		 * @copy flashx.textLayout.container.ContainerController#horizontalScrollPolicy 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+	 	 */
+	 	public function get horizontalScrollPolicy():String
+		{
+			return _horizontalScrollPolicy;
+		}
+		public function set horizontalScrollPolicy(scrollPolicy:String):void
+		{
+			_horizontalScrollPolicy = ScrollPolicy.scrollPolicyPropertyDefinition.setHelper(_horizontalScrollPolicy, scrollPolicy) as String;
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().horizontalScrollPolicy = _horizontalScrollPolicy;
+			else
+				_damaged = true;
+		}
+		
+		/** 
+		 * Controls whether the factory generates all text lines or stops when the container bounds are filled.
+		 * 
+		 * @copy flashx.textLayout.container.ContainerController#verticalScrollPolicy 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+	 	 */
+	 	 
+		public function get verticalScrollPolicy():String
+		{
+			return _verticalScrollPolicy;
+		}
+		public function set verticalScrollPolicy(scrollPolicy:String):void
+		{
+			_verticalScrollPolicy = ScrollPolicy.scrollPolicyPropertyDefinition.setHelper(_verticalScrollPolicy, scrollPolicy) as String;
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().verticalScrollPolicy = _verticalScrollPolicy;
+			else
+				_damaged = true;
+		}
+			
+		/** 
+		 * @copy flashx.textLayout.container.ContainerController#horizontalScrollPosition
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+	 	 */
+		public function get horizontalScrollPosition():Number
+		{ return _composeState == COMPOSE_COMPOSER ? getController().horizontalScrollPosition : 0; }
+		public function set horizontalScrollPosition(val:Number):void
+		{ 
+			if (val == 0 && _composeState == COMPOSE_FACTORY)
+				return;
+			if (_composeState != COMPOSE_COMPOSER)
+				convertToTextFlowWithComposer();
+			getController().horizontalScrollPosition = val;
+		}
+		
+		/** 
+		 * @copy flashx.textLayout.container.ContainerController#verticalScrollPosition 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+	 	 */
+		public function get verticalScrollPosition():Number
+		{ return _composeState == COMPOSE_COMPOSER ? getController().verticalScrollPosition : 0; }
+		public function set verticalScrollPosition(val:Number):void
+		{
+			if (val == 0 && _composeState == COMPOSE_FACTORY)
+				return;
+			if (_composeState != COMPOSE_COMPOSER)
+				convertToTextFlowWithComposer();
+			getController().verticalScrollPosition = val;
+		}
+
+		/** 
+		* @copy flashx.textLayout.container.ContainerController#getScrollDelta() 
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+	 	*/
+		public function getScrollDelta(numLines:int):Number
+		{
+			if (_composeState != COMPOSE_COMPOSER)
+				convertToTextFlowWithComposer();
+			return getController().getScrollDelta(numLines);
+		}
+		
+		/** 
+		* @copy flashx.textLayout.container.ContainerController#scrollToRange() 
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+		* @langversion 3.0
+	 	*/
+	 	public function scrollToRange(activePosition:int,anchorPosition:int):void
+	 	{
+			if (_composeState != COMPOSE_COMPOSER)
+				convertToTextFlowWithComposer();
+			getController().scrollToRange(activePosition,anchorPosition);	 		
+	 	}
+
+		/** 
+		* Optional ISWFContext instance used to make FTE calls as needed in the proper swf context. 
+		*
+		* 
+		* @see flashx.textLayout.compose.ISWFContext
+		* 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0
+	 	*/
+ 	
+		public function get swfContext():ISWFContext
+		{ return _swfContext; }
+		public function set swfContext(context:ISWFContext):void
+		{ 
+			_swfContext = context;
+			if (_composeState == COMPOSE_COMPOSER)
+				_textFlow.flowComposer.swfContext = _swfContext;
+			else
+				_damaged = true;
+		}
+		
+		/** @private - TextContainerManager wraps an underlying swfcontext - tell it to FlowComposerBase so it can avoid extra invalidation */
+		public function getBaseSWFContext():ISWFContext
+		{ return _swfContext; }
+		
+		/** @private - this is part of a performance optimziation for reusing existing TextLines in place iff recreateTextLine is available. */
+	    public function callInContext(fn:Function, thisArg:Object, argsArray:Array, returns:Boolean=true):*
+		{
+			var textBlock:TextBlock = thisArg as TextBlock;
+			if (textBlock)
+			{
+			 	if (fn == textBlock.createTextLine)
+					return createTextLine(textBlock,argsArray);
+				if (Configuration.playerEnablesArgoFeatures && fn == thisArg["recreateTextLine"])
+					return recreateTextLine(textBlock,argsArray);
+			}
+	        if (returns)
+	            return fn.apply(thisArg, argsArray);
+	        fn.apply(thisArg, argsArray);
+		}
+		
+		/** 
+		 * Uses the <code>textBlock</code> parameter, and calls the <code>TextBlock.createTextLine()</code> method on it 
+		 * using the remaining parameters.
+		 * WARNING: modifies argsArray
+		 *  
+		 * @copy flash.text.engine.TextBlock
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		private function createTextLine(textBlock:TextBlock, argsArray:Array):TextLine
+		{
+			var swfContext:ISWFContext = _swfContext ? _swfContext : BaseCompose.globalSWFContext;
+			
+			CONFIG::debug { assert(Configuration.playerEnablesArgoFeatures,"Bad call to createTextLine"); }
+			if (_composeRecycledInPlaceLines < _composedLines.length)
+			{
+				var textLine:TextLine = _composedLines[_composeRecycledInPlaceLines++];
+
+				argsArray.splice(0,0,textLine);
+				return swfContext.callInContext(textBlock["recreateTextLine"],textBlock,argsArray);
+			}
+
+			return swfContext.callInContext(textBlock.createTextLine,textBlock,argsArray);
+		}
+
+		/** 
+		 * Uses the <code>textBlock</code> parameter, and calls the <code>FlowComposerBase.recreateTextLine()</code> method on it 
+		 * using the remaining parameters.
+		 *
+		 * @param textBlock The TextBlock to which the TextLine belongs.
+		 * @param textLine  The TextLine to be recreated.
+		 * @param previousLine Specifies the previously broken line after 
+		 *	which breaking is to commence. Can be null when breaking the first line.  
+		 * @param width Specifies the desired width of the line in pixels. The 
+		 * 	actual width may be less.  
+		 * @param lineOffset An optional parameter which specifies the difference in 
+		 *	pixels between the origin of the line and the origin of the tab stops. This can be used when lines are not aligned, 
+		 * 	but it is desirable for their tabs to be so. 
+		 * @param fitSomething An optional parameter that instructs the runtime to fit at least one 
+		 * 	character into the text line, no matter what width has been specified (even if width is zero or negative, which 
+		 * 	would otherwise result in an exception being thrown).  
+		 * @return The recreated TextLine instance.
+		 *  
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		private function recreateTextLine(textBlock:TextBlock, argsArray:Array):TextLine
+		{
+			if (_composeRecycledInPlaceLines < _composedLines.length)
+			{
+				CONFIG::debug {assert(argsArray[0] != _composedLines[_composeRecycledInPlaceLines],"Bad args"); }
+				TextLineRecycler.addLineForReuse(argsArray[0]);	// not going to use this one
+				argsArray[0] = _composedLines[_composeRecycledInPlaceLines++];
+			}
+			var swfContext:ISWFContext = _swfContext ? _swfContext : BaseCompose.globalSWFContext;
+			return swfContext.callInContext(textBlock["recreateTextLine"],textBlock,argsArray);
+		}
+
+		
+		/** Returns the current ISelectionManager instance. Converts to TextFlow instance and creates one if necessary. 
+		 *
+		 * @return  the interaction manager for this TextContainerManager instance.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+	 	 * @see flashx.textLayout.edit.ISelectionManager ISelectionManager
+	 	 */
+		public function beginInteraction():ISelectionManager
+		{
+			++_interactionCount;
+			if (_composeState != COMPOSE_COMPOSER)
+				convertToTextFlowWithComposer();
+			return _textFlow.interactionManager;
+		}
+		
+		/** Terminates interaction. 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @see flashx.textLayout.edit.ISelectionManager ISelectionManager
+	 	 */
+		
+		public function endInteraction():void
+		{
+			--_interactionCount;
+		}
+		
+		/** Call this if you are editing, and want to reset the undo manager used for editing.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 */
+		public function invalidateUndoManager():void
+		{
+			if (_editingMode == EditingMode.READ_WRITE)
+				invalidateInteractionManager(true);
+		}
+		
+		
+		/** Call this if you change the selection formats (SelectionFormat) and want the interactionManager 
+		 * to update. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+	 	 */
+		public function invalidateSelectionFormats():void
+		{
+			invalidateInteractionManager();
+		}
+		
+		/** The interactionManager is invalid - update it. Clients should call this if they change the 
+		 * selectionFormats.  Its called automatically if editingMode is changed. */
+		private function invalidateInteractionManager(alwaysRecreateManager:Boolean = false):void
+		{
+			if (_composeState == COMPOSE_COMPOSER)
+			{
+				var interactionManager:ISelectionManager = _textFlow.interactionManager;
+				var activePos:int = interactionManager ? interactionManager.activePosition : -1
+				var anchorPos:int = interactionManager ? interactionManager.anchorPosition : -1;
+
+				if (_editingMode == EditingMode.READ_ONLY)
+				{
+					if (interactionManager)
+						_textFlow.interactionManager = null;
+				}
+				else if (_editingMode == EditingMode.READ_WRITE)
+				{
+					if (alwaysRecreateManager || interactionManager == null || interactionManager.editingMode == EditingMode.READ_SELECT)
+					{
+						_textFlow.interactionManager = createEditManager(getUndoManager());
+						if (_textFlow.interactionManager is SelectionManager)
+							SelectionManager(_textFlow.interactionManager).cloneSelectionFormatState(interactionManager);
+					}
+				}
+				else if (_editingMode == EditingMode.READ_SELECT)
+				{
+					if (alwaysRecreateManager || interactionManager == null || interactionManager.editingMode == EditingMode.READ_WRITE)
+					{
+						_textFlow.interactionManager = createSelectionManager();
+						if (_textFlow.interactionManager is SelectionManager)
+							SelectionManager(_textFlow.interactionManager).cloneSelectionFormatState(interactionManager);
+					}
+				}
+				
+				interactionManager = _textFlow.interactionManager;
+				if (interactionManager)
+				{
+					interactionManager.unfocusedSelectionFormat  = getUnfocusedSelectionFormat();
+					interactionManager.focusedSelectionFormat    = getFocusedSelectionFormat();
+					interactionManager.inactiveSelectionFormat = getInactiveSelectionFormat();
+					interactionManager.selectRange(anchorPos,activePos);
+				}				
+			}
+		}
+		
+		/**Create a selection manager to use for selection. Override this method if you have a custom SelectionManager that you
+		 * want to use in place of the default.
+		 *
+		 * @return	a new SelectionManager instance.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		protected function createSelectionManager():ISelectionManager
+		{
+			return new SelectionManager();
+		}
+		
+		/**Create an edit manager to use for editing. Override this method if you have a custom EditManager that you
+		 * want to use in place of the default.
+		 *
+		 * @param  an IUndoManager instance for the EditManager being created.
+		 * @return	the editing manager for this TextContainerManager instance.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		protected function createEditManager(undoManager:flashx.undo.IUndoManager):IEditManager
+		{
+			return new EditManager(undoManager);
+		}
+		
+		private function getController():TMContainerController
+		{ return _textFlow.flowComposer.getControllerAt(0) as TMContainerController; }
+
+		private var _composedLines:Array = [];
+		
+		/** Return the TextLine at the index from array of composed lines.
+		 *
+		 * @param index	Finds the line at this index position in the text.
+		 *
+		 * @return 	the TextLine that occurs at the specified index.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		public function getLineAt(index:int):TextLine
+		{ 
+			// note: this method is not reliable for damaged text
+			if (_composeState == COMPOSE_FACTORY)
+			{
+				// watch out for the empty TCM optimization and make a TextLine
+				if (_sourceState == SOURCE_STRING && _text.length == 0 && !_damaged && _composedLines.length == 0)
+				{
+					// flush the cache and force a recompose -- that will give us a TextLine
+					delete _emptyFormatCache[formatHash()];
+					
+					if (_needsRedraw)
+						compose();
+					else
+						updateContainer();
+					CONFIG::debug { assert(_composeState == COMPOSE_FACTORY,"no longer a factory??"); }
+				}
+				return _composedLines[index];
+			}
+			var tfl:TextFlowLine = _textFlow.flowComposer.getLineAt(index);
+			return tfl ? tfl.getTextLine(true) : null;
+		}
+		
+		/** @copy flashx.textLayout.compose.IFlowComposer#numLines 
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		public function get numLines():int
+		{ 
+			// note: this method is not reliable for damaged text
+			if (_composeState == COMPOSE_COMPOSER)
+				return _textFlow.flowComposer.numLines;
+			// watch out for possibly optimized zero length text
+			if (_sourceState == SOURCE_STRING && _text.length == 0)
+				return 1;
+			return _composedLines.length; 
+		}
+		
+		private function clearComposedLines():void
+		{
+			if (_composedLines)
+				_composedLines.length = 0;
+		}
+		
+		private function populateComposedLines(displayObject:DisplayObject):void
+		{
+			_composedLines.push(displayObject);
+		}
+		
+		// TODO FOR ARGO
+		private var _composeRecycledInPlaceLines:int;
+		private var _composePushedLines:int;
+		private function populateAndRecycleComposedLines(object:DisplayObject):void
+		{
+			var textLine:TextLine = object as TextLine;
+			if (textLine)
+			{
+				CONFIG::debug { assert(_composePushedLines >= _composedLines.length || _composedLines[_composePushedLines] == textLine,"mismatched recycled textline"); }
+				if (_composePushedLines >= _composedLines.length)
+					_composedLines.push(textLine);
+			}
+			else	// this is the background color and goes at the head of the list
+				_composedLines.splice(0,0,object);
+			_composePushedLines++;
+		}		
+		
+		/** @private return the current format hash */
+		tlf_internal function formatHash():uint
+		{
+			if (_hostFormatHash === undefined)
+			{
+				if (_hostFormat == null)
+					_hostFormatHash = 0;
+				else
+				{	
+					var hash:uint = 0;
+					for each (var prop:Property in TextLayoutFormat.description)
+					{
+						var val:Object = _hostFormat[prop.name];
+						if (val)
+							hash = prop.hash(val,hash);
+					}
+					_hostFormatHash = hash;
+				}
+			}
+
+			return _hostFormatHash;
+		}
+		
+		/** @private Cache of emptyFormat bounds */
+		static tlf_internal var _emptyFormatCache:Dictionary = new Dictionary();
+		
+		/** @private lookup bounds for the zero length factory optimization. */
+		tlf_internal function lookupZeroLengthTextBounds():Rectangle
+		{
+			if (_sourceState != SOURCE_STRING || _text.length != 0)
+				return null;
+				
+			var hash:uint = formatHash();
+			
+			var ref:WeakRef = _emptyFormatCache[hash];
+			if (ref == null)
+				return null;
+				
+			var cachedObject:Object = ref.get();
+			
+			if (cachedObject == null)
+				return null;
+				
+			return TextLayoutFormat.isEqual(_hostFormat,cachedObject.format) ? cachedObject.bounds : null;
+		}
+		
+		/** Composes the container text; calls either the factory or <code>updateAllControllers()</code>.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		public function compose():void
+		{
+			if (_composeState == COMPOSE_COMPOSER)
+				_textFlow.flowComposer.compose();
+			else if (_damaged)
+			{
+				if (_sourceState == SOURCE_TEXTFLOW && _textFlow.mustUseComposer())
+					convertToTextFlowWithComposer();
+				else
+				{
+					var bounds:Rectangle = lookupZeroLengthTextBounds();
+					if (bounds)
+					{
+						clearComposedLines();
+					}
+					else
+					{
+						var callback:Function;
+						if (Configuration.playerEnablesArgoFeatures)
+						{
+							// if the first thing in the array is not a TextLine its the background color from the last compose - remove it
+							var firstObj:Object = _composedLines[0];
+							if (firstObj && !(firstObj is TextLine))
+								_composedLines.splice(0,1);
+							_composeRecycledInPlaceLines = 0;
+							_composePushedLines = 0;
+							callback = populateAndRecycleComposedLines;
+						}
+						else
+						{
+							clearComposedLines();
+							callback = populateComposedLines;
+						}
+	
+						var inputManagerFactory:TextLineFactoryBase = (_sourceState == SOURCE_STRING) ? inputManagerStringFactory(_config) : _inputManagerTextFlowFactory;
+						inputManagerFactory.verticalScrollPolicy = _verticalScrollPolicy;
+						inputManagerFactory.horizontalScrollPolicy = _horizontalScrollPolicy;
+						inputManagerFactory.compositionBounds = new Rectangle(0,0,_compositionWidth,_compositionHeight);
+						inputManagerFactory.swfContext = Configuration.playerEnablesArgoFeatures ? this : _swfContext;
+							
+						if (_sourceState == SOURCE_STRING)
+						{
+							var stringFactory:StringTextLineFactory = inputManagerFactory as StringTextLineFactory;
+							// potential bug - here we use the format as textFlow.format but in the TextFlow case it is the hostFormat
+							if (!TextLayoutFormat.isEqual(stringFactory.textFlowFormat,_hostFormat))
+								stringFactory.textFlowFormat = _hostFormat;
+							stringFactory.text = _text;
+							stringFactory.createTextLines(callback);
+						}
+						else
+							_inputManagerTextFlowFactory.createTextLines(callback,_textFlow);
+							
+						if (Configuration.playerEnablesArgoFeatures)
+							_composedLines.length = _composePushedLines;
+
+						bounds = inputManagerFactory.getContentBounds();
+						
+						if (_sourceState == SOURCE_STRING && _text.length == 0)
+						{
+							var obj:Object = new Object();
+							obj.format = _hostFormat;
+							obj.bounds = bounds.clone();
+							
+							_emptyFormatCache[formatHash()] = new WeakRef(obj);
+						}
+					}
+					
+					_contentLeft   = bounds.x;
+					_contentTop    = bounds.y;
+					_contentWidth  = bounds.width;
+					_contentHeight = bounds.height;
+					_damaged = false;
+					
+					// generate a compositionComplete event.  Note that the last composed position isn't known
+					if (hasEventListener(CompositionCompleteEvent.COMPOSITION_COMPLETE))
+						dispatchEvent(new CompositionCompleteEvent(CompositionCompleteEvent.COMPOSITION_COMPLETE,false,false,_textFlow,0,-1));						
+				}
+				_needsRedraw = true;
+			}
+
+		}
+		
+		/** Updates the display; calls either the factory or updateAllControllers().
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		public function updateContainer():void
+		{
+			compose();
+
+			if (_composeState == COMPOSE_COMPOSER)
+				_textFlow.flowComposer.updateAllControllers();
+			else if (_needsRedraw)
+			{
+				var textObject:DisplayObject; 	// scratch - TextLines and background shapes
+				if (Configuration.playerEnablesArgoFeatures)
+				{
+					// if the first child in the container is a Shape - its the background color - lose it
+					if (_container.numChildren != 0)
+					{
+						textObject = _container.getChildAt(0);
+						if (textObject && !(textObject is TextLine))
+							_container.removeChildAt(0);
+					}
+						
+					// if the first child in _composedLines is a shape push it at the head of the container
+					textObject = _composedLines[0];
+					if (textObject && !(textObject is TextLine))
+						_container.addChildAt(textObject,0);
+						
+					// expect the leading lines are reused
+					while (_container.numChildren < _composedLines.length)
+						_container.addChild(_composedLines[_container.numChildren]);
+					// recycle any trailing lines
+					while (_container.numChildren > _composedLines.length)
+					{
+						var textLine:TextLine = _container.getChildAt(_composedLines.length) as TextLine;
+						_container.removeChildAt(_composedLines.length);
+						if (textLine)
+						{
+							// lines were rebroken but aren't being displayed
+							if (textLine.validity == TextLineValidity.VALID)
+								textLine.textBlock.releaseLines(textLine,textLine.textBlock.lastLine);
+							textLine.userData = null;
+							TextLineRecycler.addLineForReuse(textLine);
+						}
+					}
+				}
+				else
+				{
+					clearContainerChildren(false);
+					
+					for each (textObject in _composedLines)
+						_container.addChild(textObject);
+						
+					clearComposedLines();
+				}
+									
+				updateBackgroundAndVisibleRectangle();
+				
+				if (_handlersState == HANDLERS_NOTADDED)
+					addActivationEventListeners();
+
+				// generate a updateComplete event.  Note that the controller isn't known
+				if (hasEventListener(UpdateCompleteEvent.UPDATE_COMPLETE))
+					dispatchEvent(new UpdateCompleteEvent(UpdateCompleteEvent.UPDATE_COMPLETE,false,false,null));	
+					
+				_needsRedraw = false;
+			}
+		}
+		
+		/** @private */
+		private function updateBackgroundAndVisibleRectangle() :void
+		{
+			drawBackgroundAndSetScrollRect(0,0);
+		}
+		
+		private function addActivationEventListeners():void
+		{	
+			var newState:int =  HANDLERS_NONE;
+			
+			if (_editingMode != EditingMode.READ_ONLY && _composeState == COMPOSE_FACTORY)
+				newState = _handlersState == HANDLERS_NOTADDED ? HANDLERS_CREATION : HANDLERS_ACTIVE;
+			
+			if (newState == _handlersState)
+				return;
+			
+			removeActivationEventListeners();
+				
+			if (newState == HANDLERS_CREATION)
+			{
+				_container.addEventListener(FocusEvent.FOCUS_IN, requiredFocusInHandler);				
+				_container.addEventListener(MouseEvent.MOUSE_OVER, requiredMouseOverHandler);
+			}
+			else if (newState == HANDLERS_ACTIVE)
+			{
+				_container.addEventListener(FocusEvent.FOCUS_IN, requiredFocusInHandler);				
+				_container.addEventListener(MouseEvent.MOUSE_OVER, requiredMouseOverHandler);
+				_container.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
+				_container.addEventListener(MouseEvent.MOUSE_OUT,  mouseOutHandler);
+				_container.addEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelHandler);
+			//	_container.addEventListener(IMEEvent.IME_START_COMPOSITION, imeStartCompositionHandler);
+			// attach by literal event name to avoid Argo dependency
+				_container.addEventListener("imeStartComposition", imeStartCompositionHandler);
+				_container.contextMenu = getContextMenu();
+				if (_container.contextMenu)
+		            _container.contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, menuSelectHandler);
+		            
+		        _container.addEventListener(Event.SELECT_ALL, editHandler);
+			}
+			
+			_handlersState = newState;
+		}
+		
+		// The ContextMenu to be used.  The idea is that this is undefined until createContextMenu is called and then 
+		// createContextMenu is only called once and the result is shared with the ContainerController when it gets created
+		private var _contextMenu:*;
+		
+		/** @private  Returns the already created contextMenu.  If not created yet create it.  */
+		tlf_internal function getContextMenu():ContextMenu
+		{
+			if (_contextMenu === undefined)
+				_contextMenu = createContextMenu();
+			return _contextMenu;
+		}
+
+		private function removeActivationEventListeners():void
+		{
+			if (_handlersState == HANDLERS_CREATION)
+			{
+				_container.removeEventListener(FocusEvent.FOCUS_IN, requiredFocusInHandler);				
+				_container.removeEventListener(MouseEvent.MOUSE_OVER, requiredMouseOverHandler);
+			}
+			else if (_handlersState == HANDLERS_ACTIVE)
+			{
+				_container.removeEventListener(FocusEvent.FOCUS_IN, requiredFocusInHandler);				
+				_container.removeEventListener(MouseEvent.MOUSE_OVER, requiredMouseOverHandler);
+				_container.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
+				_container.removeEventListener(MouseEvent.MOUSE_OUT,  mouseOutHandler);
+				_container.removeEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelHandler);
+			//	_container.removeEventListener(IMEEvent.IME_START_COMPOSITION, imeStartCompositionHandler);
+			// detach by literal event name to avoid Argo dependency
+				_container.removeEventListener("imeStartComposition", imeStartCompositionHandler);
+				if (_container.contextMenu)	
+				{
+	            	_container.contextMenu.removeEventListener(ContextMenuEvent.MENU_SELECT, menuSelectHandler);
+					_container.contextMenu = null;
+				}
+		        _container.removeEventListener(Event.SELECT_ALL, editHandler);
+			}
+			_handlersState = HANDLERS_NOTADDED;
+		}
+		
+		private function addTextFlowListeners():void
+		{
+			for each (var event:String in eventList)			
+				_textFlow.addEventListener(event,dispatchEvent);
+		}
+		
+		private function removeTextFlowListeners():void
+		{
+			for each (var event:String in eventList)			
+				_textFlow.removeEventListener(event,dispatchEvent);
+			_handlersState = HANDLERS_NONE;
+		}
+		
+		/**
+		 * @copy flash.events.IEventDispatcher#dispatchEvent()
+		 * @private
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+ 		 */
+		public override function dispatchEvent(event:Event):Boolean
+		{
+			if (event.type == DamageEvent.DAMAGE)
+			{
+				_textDamaged = true;
+				if (_composeState == COMPOSE_FACTORY)
+					_damaged = true;
+			}
+			else if (event.type == FlowOperationEvent.FLOW_OPERATION_BEGIN)
+			{
+				if (_container.mouseChildren == false)
+					_container.mouseChildren = true;
+			}
+			var result:Boolean = super.dispatchEvent(event);
+			if (!result)
+				event.preventDefault();
+			return result;
+		}
+		
+		private function clearContainerChildren(recycle:Boolean):void
+		{
+			while(_container.numChildren)
+			{
+				var textLine:TextLine = _container.getChildAt(0) as TextLine;
+				_container.removeChildAt(0);
+				if (textLine)
+				{
+					// releasing all textLines so release each still connected textBlock
+					if (textLine.validity != TextLineValidity.INVALID && textLine.validity != TextLineValidity.STATIC)
+					{
+						var textBlock:TextBlock = textLine.textBlock;
+						CONFIG::debug { Debugging.traceFTECall(null,textBlock,"releaseLines",textBlock.firstLine, textBlock.lastLine); }	
+						textBlock.releaseLines(textBlock.firstLine,textBlock.lastLine);
+					}					
+					if (recycle)
+					{
+						textLine.userData = null;	// clear any userData
+						TextLineRecycler.addLineForReuse(textLine);
+					}
+				}
+			}
+		}
+		
+		private function convertToTextFlow():void
+		{
+			CONFIG::debug { assert(_sourceState != SOURCE_TEXTFLOW,"bad call to convertToTextFlow"); }
+									
+			_textFlow = new TextFlow(_config);
+			_textFlow.hostFormat = _hostFormat;
+			if(_swfContext)
+			{
+				_textFlow.flowComposer.swfContext = _swfContext;
+			}
+	
+			var p:ParagraphElement = new ParagraphElement();
+			_textFlow.addChild(p)
+			var s:SpanElement = new SpanElement();
+			s.text = _text;
+			p.addChild(s);
+			_sourceState = SOURCE_TEXTFLOW;
+			addTextFlowListeners();			
+		}
+				
+		/** @private */
+		tlf_internal function convertToTextFlowWithComposer():void
+		{
+			removeActivationEventListeners();
+			
+			if (_sourceState != SOURCE_TEXTFLOW)
+				convertToTextFlow();
+			
+			if (_composeState != COMPOSE_COMPOSER)
+			{
+				clearContainerChildren(true);
+				clearComposedLines();
+				var controller:TMContainerController = new TMContainerController(_container,_compositionWidth,_compositionHeight,this);
+				_textFlow.flowComposer = new StandardFlowComposer();
+				_textFlow.flowComposer.addController(controller);
+				_textFlow.flowComposer.swfContext = _swfContext;
+				_composeState = COMPOSE_COMPOSER;
+				
+				invalidateInteractionManager();
+				updateContainer();
+			}
+		}
+		
+		private function get effectiveBlockProgression():String
+		{
+			if (_textFlow)
+				return _textFlow.computedFormat.blockProgression;
+			return _hostFormat && _hostFormat.blockProgression && _hostFormat.blockProgression != FormatValue.INHERIT ? _hostFormat.blockProgression : BlockProgression.TB;
+		}
+		
+		/* CONFIG::debug private static function doTrace(msg:String):void
+		{ trace(msg); } */
+		
+		private function removeIBeamCursor():void
+		{
+			if (_ibeamCursorSet)
+			{
+				Mouse.cursor = MouseCursor.AUTO;
+				_ibeamCursorSet = false;
+			}
+		}
+		
+		private var _hasScrollRect:Boolean = false;
+		
+		/** 
+		 * Specifies whether this container has attached a ScrollRect object. Value is <code>true</code>
+		 * or <code>false</code>. A display object is cropped to the size defined by the scroll rectangle, and 
+		 * it scrolls within the rectangle when you change the x and y properties of the scrollRect object. 
+		 *
+		 * <p>This property enables a client to test for a ScrollRect object without accessing 
+		 * the DisplayObject.scrollRect property, which can have side effects in some cases.</p> 
+		 *
+		 * @return true if the controller has attached a ScrollRect instance.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 *
+		 * @see #drawBackgroundAndSetScrollRect 
+		 */
+		private function get hasScrollRect():Boolean
+		{ return _hasScrollRect; }
+		private function set hasScrollRect(value:Boolean):void
+		{ _hasScrollRect = value; }
+		
+		/**   
+		 * Returns <code>true</code> if it has filled in the container's scrollRect property.  
+		 * This method enables you to test whether <code>scrollRect</code> is set without actually accessing the <code>scrollRect</code> property 
+		 * which can possibly create a  performance issue. 
+		 * <p>Override this method to draw a background or a border.  Overriding this method can be tricky as the scrollRect <bold>must</bold> 
+		 * be set as specified.</p>
+		 * 
+		 * @param scrollX The starting horizontal position of the scroll rectangle.
+		 * @param scrollY The starting vertical position of the scroll rectangle.
+		 * 
+		 * @return 	<code>true</code> if it has created the <code>scrollRect</code> object.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */
+		public function drawBackgroundAndSetScrollRect(scrollX:Number,scrollY:Number):Boolean
+		{
+			var cont:Sprite = this.container;
+
+ 			var contentWidth:Number;
+			var contentHeight:Number;
+			if (_composeState == COMPOSE_FACTORY)
+			{
+				contentWidth = _contentWidth;
+				contentHeight = _contentHeight;
+			}
+			else
+			{
+				var controller:ContainerController = getController();
+				contentWidth = controller.contentWidth;
+				contentHeight = controller.contentHeight
+			}
+			var width:Number;
+			if (isNaN(compositionWidth))
+			{
+				var contentLeft:Number = (_composeState == COMPOSE_FACTORY) ? _contentLeft : controller.contentLeft;
+				width = contentLeft + contentWidth;
+			}
+			else
+				width = compositionWidth;
+			var height:Number;
+			if (isNaN(compositionHeight))
+			{ 
+				var contentTop:Number = (_composeState == COMPOSE_FACTORY) ? _contentTop : controller.contentTop;
+				height = contentTop+contentHeight;
+			}
+			else
+				height = compositionHeight;
+			
+			if (scrollX == 0 && scrollY == 0 && contentWidth <= width && contentHeight <= height)
+			{
+				// skip the scrollRect
+				if (_hasScrollRect)
+				{
+					cont.scrollRect = null;
+					_hasScrollRect = false;					
+				}
+			}
+			else
+			{
+				cont.scrollRect = new Rectangle(scrollX, scrollY, width, height);
+				_hasScrollRect = true;
+				
+				// adjust to the values actually in the scrollRect
+				scrollX = cont.scrollRect.x;
+				scrollY = cont.scrollRect.y;
+				width = cont.scrollRect.width;
+				height = cont.scrollRect.height;
+			}
+			
+	        // NOTE: must draw a background for interaction support - even it if is 100% transparent
+	        var s:Sprite = cont as Sprite;
+	        if (s)
+	        {
+				s.graphics.clear();
+				s.graphics.beginFill(0, 0); 
+		       	s.graphics.drawRect(scrollX,scrollY,width,height);
+		        s.graphics.endFill();
+		    }
+	
+	        return _hasScrollRect;
+		}
+		
+		/** Returns the focusedSelectionFormat - by default get it from the configuration.
+		 * This can be overridden in the subclass to supply a different SelectionFormat
+		 */
+		protected function getFocusedSelectionFormat():SelectionFormat
+		{
+			return _config.focusedSelectionFormat;
+		}
+		
+		/** Returns the inactiveSelectionFormat - by default get it from the configuration 
+		 * This can be overridden in the subclass to supply a different SelectionFormat
+		 */
+		protected function getInactiveSelectionFormat():SelectionFormat
+		{
+			return _config.inactiveSelectionFormat;
+		}
+		
+		/** Returns the unfocusedSelectionFormat - by default get it from the configuration 
+		 * You can override this method in the subclass to supply a different SelectionFormat.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		protected function getUnfocusedSelectionFormat():SelectionFormat
+		{
+			return _config.unfocusedSelectionFormat;
+		}
+		
+		/** 
+		 * Returns the undo manager to use. By default, creates a unique undo manager. 
+		 * You can override this method in the subclass if you want to customize the undo manager
+		 * (for example, to use a shared undo manager for multiple TextContainerManager instances).
+		 *
+		 * @return 	new IUndoManager instance.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+	 	 */
+		 
+		protected function getUndoManager():IUndoManager
+		{
+			return new UndoManager();
+		}
+						
+		/** Creates a ContextMenu for the TextContainerManager. Use the methods of the ContextMenu 
+		 *  class to add items to the menu. 
+		 * <p>You can override this method to define a custom context menu.</p>
+		 *
+		 * @return 	the created context menu.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 * @see flash.ui.ContextMenu ContextMenu
+		 */
+		protected function createContextMenu():ContextMenu
+		{
+			return ContainerController.createDefaultContextMenu();
+		}
+		/** @copy flashx.textLayout.container.ContainerController#editHandler()
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+ 		 *
+ 		 * @see flash.events.Event Event
+		 */	
+		public function editHandler(event:Event):void
+		{
+			if (_composeState == COMPOSE_FACTORY)
+			{
+				convertToTextFlowWithComposer();
+				getController().editHandler(event);
+				_textFlow.interactionManager.setFocus();
+			}
+			else
+				getController().editHandler(event);
+		}
+		
+		/** @copy flashx.textLayout.container.ContainerController#keyDownHandler() 
+		*
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+ 		* @see flash.events.KeyboardEvent#KEY_DOWN KeyboardEvent.KEY_DOWN
+		*/	
+		public function keyDownHandler(event:KeyboardEvent):void
+		{
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().keyDownHandler(event);
+		}
+		
+		/** @copy flashx.textLayout.container.ContainerController#keyUpHandler().
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+ 		* @see flash.events.KeyboardEvent#KEY_UP KeyboardEvent.KEY_UP
+		*/	
+		public function keyUpHandler(event:KeyboardEvent):void
+		{
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().keyUpHandler(event);
+		}
+
+		/** @copy flashx.textLayout.container.ContainerController#keyFocusChangeHandler().
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 * 	@param	event	the FocusChange event
+		 */	
+		public function keyFocusChangeHandler(event:FocusEvent):void
+		{
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().keyFocusChangeHandler(event);
+		}
+		
+		/** @copy flashx.textLayout.container.ContainerController#textInputHandler()
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+ 		* @see flash.events.TextEvent#TEXT_INPUT TextEvent.TEXT_INPUT
+		*/
+		public function textInputHandler(event:TextEvent):void
+		{
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().textInputHandler(event);
+		}
+
+		/** Processes the <code>IME_START_COMPOSITION</code> event when the client manages events.
+		 *
+		 * @param event  The IMEEvent object.
+		 *
+		 * @playerversion Flash 10.1
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * 
+		 *
+		 * @see flash.events.IMEEvent#IME_START_COMPOSITION IMEEvent.IME_START_COMPOSITION
+		 */
+		public function imeStartCompositionHandler(event:IMEEvent):void
+		{
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().imeStartCompositionHandler(event);
+		}
+		
+		/** @copy flashx.textLayout.container.ContainerController#mouseDownHandler()
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+ 		* @see flash.events.MouseEvent#MOUSE_DOWN MouseEvent.MOUSE_DOWN
+		*/	
+		public function mouseDownHandler(event:MouseEvent):void
+		{
+			// doTrace("IM:mouseDownHandler");
+			// before the mouseDown do a mouseOver
+			if (_composeState == COMPOSE_FACTORY)
+			{
+				CONFIG::debug { assert(event.currentTarget == this.container,"TextContainerManager:mouseDownHandler - unexpected currentTarget"); }
+				convertToTextFlowWithComposer();
+				getController().requiredFocusInHandler(null);
+				getController().requiredMouseOverHandler(event.target != container ? new RemappedMouseEvent(event) : event);
+				if (_hasFocus)
+					getController().requiredFocusInHandler(null);
+				getController().requiredMouseDownHandler(event);
+			}
+			else
+				getController().mouseDownHandler(event);
+		}
+
+		/** @copy flashx.textLayout.container.ContainerController#mouseMoveHandler()
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+ 		* @see flash.events.MouseEvent#MOUSE_MOVE MouseEvent.MOUSE_MOVE
+		*/	
+		public function mouseMoveHandler(event:MouseEvent):void
+		{
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().mouseMoveHandler(event);
+		}
+		
+		/** @copy flashx.textLayout.container.ContainerController#mouseUpHandler()
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+ 		* @see flash.events.MouseEvent#MOUSE_UP MouseEvent.MOUSE_UP
+		*/	
+		public function mouseUpHandler(event:MouseEvent):void
+		{
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().mouseUpHandler(event);
+		}
+		
+		/** @copy flashx.textLayout.container.ContainerController#mouseDoubleClickHandler()
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+ 		* @see flash.events.MouseEvent#DOUBLE_CLICK MouseEvent.DOUBLE_CLICK
+		*/	
+		public function mouseDoubleClickHandler(event:MouseEvent):void
+		{
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().mouseDoubleClickHandler(event);
+		}
+
+		/** @private Process a mouseOver event.
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+		*/			
+		tlf_internal final function requiredMouseOverHandler(event:MouseEvent):void
+		{
+			if (_composeState == COMPOSE_FACTORY)
+				mouseOverHandler(event);
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().requiredMouseOverHandler(event);
+		}
+		
+
+		/** Process a mouseOver event.
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+ 		* @see flash.events.MouseEvent#MOUSE_OVER MouseEvent.MOUSE_OVER
+		*/			
+		public function mouseOverHandler(event:MouseEvent):void
+		{
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().mouseOverHandler(event);
+			else
+			{
+				// doTrace("IM:mouseOverHandler");
+				if (effectiveBlockProgression != BlockProgression.RL)
+				{
+					Mouse.cursor = MouseCursor.IBEAM;
+					_ibeamCursorSet = true;
+				}	
+				addActivationEventListeners();
+			}
+		}
+		/** @copy flashx.textLayout.container.ContainerController#mouseOutHandler()
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+ 		* @see flash.events.MouseEvent#MOUSE_OUT MouseEvent.MOUSE_OUT
+		*/					
+		public function mouseOutHandler(event:MouseEvent):void
+		{
+			// doTrace("IM:mouseOutHandler");
+			if (_composeState == COMPOSE_FACTORY)
+				removeIBeamCursor();
+			else
+				getController().mouseOutHandler(event);
+		}		
+		/** @copy flashx.textLayout.container.ContainerController#focusInHandler()
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+ 		* @see flash.events.FocusEvent#FOCUS_IN FocusEvent.FOCUS_IN
+		*/
+
+		
+		/** Process a focusIn event.
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+		*/
+		public function focusInHandler(event:FocusEvent):void
+		{
+			_hasFocus = true;
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().focusInHandler(event);
+		}
+		
+		/** @private hook to get at requiredFocusOutHandler as needed */
+		tlf_internal function requiredFocusOutHandler(event:FocusEvent):void
+		{
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().requiredFocusOutHandler(event);
+		}
+		/** @copy flashx.textLayout.container.ContainerController#focusOutHandler()
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+ 		* @see flash.events.FocusEvent#FOCUS_OUT FocusEvent.FOCUS_OUT
+		*/
+		public function focusOutHandler(event:FocusEvent):void
+		{
+			_hasFocus = false;
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().focusOutHandler(event);
+		}
+
+		/** @copy flashx.textLayout.container.ContainerController#activateHandler()
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+ 		* @see flash.events.Event#ACTIVATE Event.ACTIVATE
+		*/				
+		public function activateHandler(event:Event):void
+		{
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().activateHandler(event);
+		}		
+		/** @copy flashx.textLayout.container.ContainerController#deactivateHandler()
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+ 		* @see flash.events.Event#DEACTIVATE Event.DEACTIVATE
+		*/				
+		public function deactivateHandler(event:Event):void
+		{
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().deactivateHandler(event);
+		}
+		
+		/** @copy flashx.textLayout.container.ContainerController#focusChangeHandler()
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+ 		*
+ 		* @see flash.events.FocusEvent#KEY_FOCUS_CHANGE FocusEvent.KEY_FOCUS_CHANGE
+		* @see flash.events.FocusEvent#MOUSE_FOCUS_CHANGE FocusEvent.MOUSE_FOCUS_CHANGE
+		*/				
+		public function focusChangeHandler(event:FocusEvent):void
+		{
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().focusChangeHandler(event);
+		}
+		
+		/** @copy flashx.textLayout.container.ContainerController#menuSelectHandler()
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+ 		*
+ 		* @see flash.events.ContextMenuEvent#MENU_SELECT ContextMenuEvent.MENU_SELECT
+		*/				
+		public function menuSelectHandler(event:ContextMenuEvent):void
+		{
+			if (_composeState == COMPOSE_FACTORY)
+			{
+				// there is no selection
+				var cbItems:ContextMenuClipboardItems = _container.contextMenu.clipboardItems
+				cbItems.selectAll = _editingMode != EditingMode.READ_ONLY;
+				cbItems.clear = false;
+				cbItems.copy = false;
+				cbItems.cut = false;
+				cbItems.paste = false;
+			}
+			else
+				getController().menuSelectHandler(event);			
+		}
+		
+		/** @copy flashx.textLayout.container.ContainerController#mouseWheelHandler()
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+ 		*
+ 		* @see flash.events.MouseEvent#MOUSE_WHEEL MouseEvent.MOUSE_WHEEL
+		*/				
+		public function mouseWheelHandler(event:MouseEvent):void
+		{
+			if (_composeState == COMPOSE_FACTORY)
+			{
+				convertToTextFlowWithComposer();
+				getController().requiredMouseOverHandler(event);
+			}
+			getController().mouseWheelHandler(event);
+		}
+
+		
+		/** @private required FocusIn handler.  Clients override focusInHandler
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 		* @langversion 3.0
+		*/
+		tlf_internal final function requiredFocusInHandler(event:FocusEvent):void
+		{			
+			// doTrace("IM:focusInHandler");
+			if (_composeState == COMPOSE_FACTORY)
+			{
+				addActivationEventListeners();
+				focusInHandler(event);
+			}			
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().requiredFocusInHandler(event);
+		}
+		
+		/** 
+		 * Called to request clients to begin the forwarding of mouseup and mousemove events from outside a security sandbox.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 */
+		public function beginMouseCapture():void
+		{ }
+		/** 
+		 * Called to inform clients that the the forwarding of mouseup and mousemove events from outside a security sandbox is no longer needed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 */
+		public function endMouseCapture():void
+		{ }
+		/** Client call to forward a mouseUp event from outside a security sandbox.  Coordinates of the mouse up are not needed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 */
+		public function mouseUpSomewhere(e:Event):void
+		{
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().mouseUpSomewhere(e);
+		}
+		/** Client call to forward a mouseMove event from outside a security sandbox.  Coordinates of the mouse move are not needed.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 *
+		 */		
+		public function mouseMoveSomewhere(e:Event):void
+		{ 
+			if (_composeState == COMPOSE_COMPOSER)
+				getController().mouseUpSomewhere(e);
+		}
+		
+	}
+	
+}
+
+import flash.display.DisplayObject;
+import flash.display.DisplayObjectContainer;
+import flash.display.Sprite;
+import flash.events.Event;
+import flash.geom.Rectangle;
+import flash.geom.Point;
+
+import flashx.textLayout.container.ContainerController;
+import flashx.textLayout.container.ScrollPolicy;
+import flashx.textLayout.container.TextContainerManager;
+import flashx.textLayout.edit.IInteractionEventHandler;
+import flashx.textLayout.formats.BlockProgression;
+import flashx.textLayout.tlf_internal;
+import flash.events.MouseEvent;
+import flashx.textLayout.formats.BackgroundColor;
+import flash.ui.ContextMenu;
+
+use namespace tlf_internal;
+
+class TMContainerController extends ContainerController
+{
+	private var _inputManager:TextContainerManager;
+	
+	public function TMContainerController(container:Sprite, compositionWidth:Number, compositionHeight:Number, tm:TextContainerManager)
+	{
+		super(container,compositionWidth,compositionHeight);
+		_inputManager = tm;
+		verticalScrollPolicy = tm.verticalScrollPolicy;
+		horizontalScrollPolicy = tm.horizontalScrollPolicy;
+	}
+
+	/** Reroute to the TextContainerManger's override.  Reuse the one that's already been created. */
+	protected override function createContextMenu():ContextMenu
+	{ return _inputManager.getContextMenu(); }
+
+	/** @private */
+	protected override function get attachTransparentBackground():Boolean
+	{ return false; }
+	
+	/** @private */
+	tlf_internal function doUpdateVisibleRectangle():void
+	{ updateVisibleRectangle(); }
+	
+	/** @private. Override clones and enhances parent class functionality. */
+	protected override function updateVisibleRectangle() :void
+	{
+		var xpos:Number;
+		var ypos:Number;
+		// see the adjustLines boolean in ContainerController.fillShapeChildren - this logic clones that and allows for skipping the scrollRect
+		xpos = effectiveBlockProgression == BlockProgression.RL && (verticalScrollPolicy != ScrollPolicy.OFF || horizontalScrollPolicy != ScrollPolicy.OFF) ? horizontalScrollPosition - compositionWidth : horizontalScrollPosition;
+		ypos = verticalScrollPosition;
+			
+		_hasScrollRect = _inputManager.drawBackgroundAndSetScrollRect(xpos,ypos);
+	}
+		
+	/** @private */
+	tlf_internal override function getInteractionHandler():IInteractionEventHandler
+	{ return _inputManager; }
+
+}
+
+// remap the mouse event for processing inside TLF.  This is just the initial click.  Make it as if the event was on the container and not the textline
+class RemappedMouseEvent extends MouseEvent
+{
+	private var _event:MouseEvent;
+	
+	public function RemappedMouseEvent(event:MouseEvent,cloning:Boolean = false)
+	{
+		var containerPoint:Point;
+		if (!cloning)
+		{
+			containerPoint = DisplayObject(event.target).localToGlobal(new Point(event.localX, event.localY));
+			containerPoint = DisplayObject(event.currentTarget).globalToLocal(containerPoint);
+		}
+		else
+			containerPoint = new Point();
+
+		/* event.commandKey,event.controlKey,event.clickCount are also supported in AIR.  IMHO they are a nonissue for the initial click */
+		super(event.type,event.bubbles,event.cancelable,containerPoint.x,containerPoint.y,event.relatedObject,event.ctrlKey,event.altKey,event.shiftKey,event.buttonDown,event.delta);
+		
+		_event = event;
+	}
+
+	// override methods/getters for things we couldn't set in the base class	
+
+	public override function get target():Object
+	{ return _event.currentTarget; }
+	
+	public override function get currentTarget():Object
+	{ return _event.currentTarget; }
+	
+	public override function get eventPhase():uint
+	{ return _event.eventPhase; }
+	
+	public override function get isRelatedObjectInaccessible():Boolean
+	{ return _event.isRelatedObjectInaccessible; }
+	
+	public override function get stageX():Number
+	{ return _event.stageX; }
+	
+	public override function get stageY():Number
+	{ return _event.stageY; }
+	
+	public override function clone():Event
+	{ 
+		var rslt:RemappedMouseEvent = new RemappedMouseEvent(_event,true); 
+		rslt.localX = localX;
+		rslt.localY = localY;
+		return rslt;
+	}
+	
+	public override function updateAfterEvent():void
+	{ _event.updateAfterEvent(); }
+	
+	public override function isDefaultPrevented():Boolean
+	{ return _event.isDefaultPrevented(); }
+	
+	public override function preventDefault():void
+	{ _event.preventDefault(); }
+	
+	public override function stopImmediatePropagation():void
+	{ _event.stopImmediatePropagation(); }
+	
+	public override function stopPropagation():void
+	{ _event.stopPropagation(); }
+}
diff --git a/textLayout_edit/src/flashx/textLayout/edit/EditManager.as b/textLayout_edit/src/flashx/textLayout/edit/EditManager.as
new file mode 100755
index 0000000..74ddd9d
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/edit/EditManager.as
@@ -0,0 +1,1549 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.edit
+{
+	import flash.display.DisplayObjectContainer;
+	import flash.errors.IllegalOperationError;
+	import flash.events.Event;
+	import flash.events.FocusEvent;
+	import flash.events.IMEEvent;
+	import flash.events.KeyboardEvent;
+	import flash.events.TextEvent;
+	import flash.system.Capabilities;
+	import flash.ui.Keyboard;
+	import flash.utils.getQualifiedClassName;
+	
+	import flashx.textLayout.compose.IFlowComposer;
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.debug.Debugging;
+	import flashx.textLayout.elements.Configuration;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.GlobalSettings;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.events.FlowOperationEvent;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.operations.ApplyElementIDOperation;
+	import flashx.textLayout.operations.ApplyElementStyleNameOperation;
+	import flashx.textLayout.operations.ApplyFormatOperation;
+	import flashx.textLayout.operations.ApplyFormatToElementOperation;
+	import flashx.textLayout.operations.ApplyLinkOperation;
+	import flashx.textLayout.operations.ApplyTCYOperation;
+	import flashx.textLayout.operations.ClearFormatOnElementOperation;
+	import flashx.textLayout.operations.ClearFormatOperation;
+	import flashx.textLayout.operations.CompositeOperation;
+	import flashx.textLayout.operations.CutOperation;
+	import flashx.textLayout.operations.DeleteTextOperation;
+	import flashx.textLayout.operations.FlowOperation;
+	import flashx.textLayout.operations.InsertInlineGraphicOperation;
+	import flashx.textLayout.operations.InsertTextOperation;
+	import flashx.textLayout.operations.ModifyInlineGraphicOperation;
+	import flashx.textLayout.operations.PasteOperation;
+	import flashx.textLayout.operations.RedoOperation;
+	import flashx.textLayout.operations.SplitParagraphOperation;
+	import flashx.textLayout.operations.UndoOperation;
+	import flashx.textLayout.tlf_internal;
+	import flashx.textLayout.utils.CharacterUtil;
+	import flashx.textLayout.utils.NavigationUtil;
+	import flashx.undo.IOperation;
+	import flashx.undo.IUndoManager;
+		
+	use namespace tlf_internal;
+	
+	/** 
+	 * The EditManager class manages editing changes to a TextFlow. 
+	 * 
+	 * <p>To enable text flow editing, assign an EditManager object to the <code>interactionManager</code> 
+	 * property of the TextFlow object. The edit manager handles changes to the text (such as insertions, 
+	 * deletions, and format changes). Changes are reversible if the edit manager has an undo manager. The edit
+	 * manager triggers the recomposition and display of the text flow, as necessary.</p>
+	 *
+	 * <p>The EditManager class supports the following keyboard shortcuts:</p>
+	 * 
+	 * <table class="innertable" width="100%">
+	 *      <tr><th>Keys</th><th>Result</th></tr>
+	 *      <tr><td>ctrl-z</td><td>undo</td></tr>					
+	 * 	<tr><td>ctrl-y</td><td>redo</td></tr>					
+	 * 	<tr><td>ctrl-backspace</td><td>deletePreviousWord</td></tr>					
+	 * 	<tr><td>ctrl-delete</td><td>deleteNextWord</td></tr>					
+	 * 	<tr><td>alt+delete</td><td>deleteNextWord</td></tr>					
+	 * 	<tr><td>ctrl+alt-delete</td><td>deleteNextWord</td></tr>					
+	 * 	<tr><td>ctrl-shift-hyphen</td><td>insert discretionary hyphen</td></tr>					
+	 * 	<tr><td>ctrl+backspace</td><td>deletePreviousWord</td></tr>					
+	 * 	<tr><td>alt+backspace</td><td>deletePreviousWord</td></tr>					
+	 * 	<tr><td>ctrl+alt-backspace</td><td>deletePreviousWord</td></tr>					
+	 * 	<tr><td>INSERT</td><td>toggles overWriteMode</td></tr>					
+	 * 	<tr><td>backspace</td><td>deletePreviousCharacter</td></tr>					
+	 * 	<tr><td>ENTER</td><td>if textFlow.configuration.manageEnterKey splitParagraph</td></tr>					
+	 * 	<tr><td>TAB</td><td>if textFlow.configuration.manageTabKey insert a TAB or overwrite next character with a TAB</td></tr>    
+	 * </table>
+	 *
+	 * <p><strong>Note:</strong> The following keys do not work on Windows: alt-backspace, alt-delete, ctrl+alt-backspace,
+	 * and ctrl+alt-delete. These keys do not generate an event for the runtime.</p>						
+ 	 * 
+ 	 * @see flashx.textLayout.elements.TextFlow
+ 	 * @see flashx.undo.UndoManager
+	 *
+	 * @includeExample examples\EditManager_example.as -noswf
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */			
+	public class EditManager extends SelectionManager implements IEditManager
+	{
+		 /**
+		 *  To minimize expensive recompositions during fast typing, inserts
+		 *  don't necessarily take place immediately. An insert operation that
+		 *  hasn't yet executed is held here.
+		 */
+		private var pendingInsert:InsertTextOperation;
+		
+		/** 
+		 * The object that has the ENTER_FRAME event listener attached to perform pending inserts.
+		 */
+		private var enterFrameListener:DisplayObjectContainer;
+		
+		/**
+		 *  Some operations can be undone & redone. The undoManager keeps track
+		 *  of the operations that have been done or undone so that they can be undone or
+		 *  redone.  I'm not sure if only text operations can be undone. If so, the undoManager
+		 *  should probably be moved to EditManager.
+		 */
+		private var _undoManager:flashx.undo.IUndoManager;
+		
+		private var _imeSession:IMEClient;
+		private var _imeOperationInProgress:Boolean;
+		
+		/** 
+		 * Indicates whether overwrite mode is on or off.
+		 * 
+		 * <p>If <code>true</code>, then a keystroke overwrites the character following the cursor.
+		 * If <code>false</code>, then a keystroke is inserted at the cursor location.</p> 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		*/		
+		public static var overwriteMode:Boolean = false;
+		
+		/** 
+		 * Creates an EditManager object.
+		 * 
+		 * <p>Assign an EditManager object to the <code>interactionManager</code> property
+		 * of a text flow to enable editing of that text flow. </p>
+		 *
+		 * <p>To enable support for undoing and redoing changes, pass an 
+		 * IUndoManager instance to the EditManager constructor. You can use
+		 * the <code>flashx.undo.UndoManager</code> class
+		 * or create a custom IUndoManager instance. Use a custom IUndoManager instance
+		 * to integrate Text Layout Framework changes with an existing
+		 * undo manager that is not an instance of the UndoManager class.
+		 * To create a custom IUndoManager instance, ensure that the class
+		 * you use to define the undo manager 
+		 * implements the IUndoManager interface.</p>
+		 * 
+		 * 
+		 * @param undo	The UndoManager for the application
+		 * 
+		 * @see flashx.textLayout.elements.TextFlow#interactionManager
+		 * @see flashx.undo.IUndoManager
+		 * 
+		 * @includeExample examples\EditManager_constructor.as -noswf
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function EditManager(undoManager:flashx.undo.IUndoManager = null)
+		{
+			super();
+			_undoManager = undoManager;
+		}
+
+		/**  
+		 * The IUndoManager assigned to this edit manager.
+		 * 
+		 * <p>To allow edits to be undone (and redone), pass an IUndoManager instance to the EditManager
+		 * constructor. The undo manager maintains a stack of operations that have been executed, and it can 
+		 * undo or redo individual operations. </p>
+		 * 
+		 * <p><b>Note:</b> If the TextFlow is modified directly (not via
+		 * calls to the EditManager, but directly via calls to the managed FlowElement objects), then the EditManager
+		 * clears the undo stack to prevent the stack from getting out of sync with the current state.</p>
+		 * 
+	 	 * @playerversion Flash 10
+	 	 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+	 	 */	
+		public function get undoManager():flashx.undo.IUndoManager
+		{
+			return _undoManager;
+		}
+		
+		// Backdoor provided so that IMEClient can temporarily use an undo manager to maintain the IME session state.
+		/** @private */
+		tlf_internal function setUndoManager(undoManager:flashx.undo.IUndoManager):void
+		{
+			_undoManager = undoManager;
+		}
+		
+		override public function editHandler(event:Event):void
+		{
+			super.editHandler(event);
+			switch (event.type)
+			{
+				case Event.CUT: 
+					if (activePosition != anchorPosition)
+						TextClipboard.setContents(cutTextScrap());
+					break;
+				case Event.CLEAR:
+					if(activePosition != anchorPosition)
+						deleteText(null);
+					break;
+				case Event.PASTE:
+					pasteTextScrap(TextClipboard.getContents());
+					break;
+			}
+		}
+
+		// ///////////////////////////////////
+		// keyboard methods 
+		// ///////////////////////////////////
+		
+		/** @private */
+		public override function keyDownHandler(event:KeyboardEvent):void
+		{
+			if (!hasSelection() || event.isDefaultPrevented())
+				return;
+				
+			super.keyDownHandler(event);
+			
+			if (event.ctrlKey)
+			{
+				// The player subsequently sends a text input event (which should be ignored) as listed below:
+				// CTRL/CMD+z: Only on Mac when using a pre-Argo player version
+				// CTRL/CMD+y: On all platforms (the exact char code for the text input event is platform dependent) 
+				if (!event.altKey)
+				{
+					switch(event.charCode)
+					{
+						case 122:	// small z
+							/* pre-Argo and on the mac then ignoreNextTextEvent */ 
+							if (!Configuration.versionIsAtLeast(10,1) && (Capabilities.os.search("Mac OS") > -1)) 
+								ignoreNextTextEvent = true;
+							undo();
+							event.preventDefault();
+							break;
+						case 121:	// small y
+							ignoreNextTextEvent = true;
+							redo();
+							event.preventDefault();
+							break;
+						case Keyboard.BACKSPACE:
+							if (_imeSession)
+								_imeSession.compositionAbandoned();
+							deletePreviousWord();
+							event.preventDefault();
+							break;
+					}
+					if (event.keyCode == Keyboard.DELETE)
+					{
+						if (_imeSession)
+							_imeSession.compositionAbandoned();
+						deleteNextWord();
+						event.preventDefault();
+					}
+					
+					if (event.shiftKey)
+					{
+						// detect ctrl-shift-"-" (cnd-shift-"-" on mac) and insert a DH
+						if (event.charCode == 95)
+						{
+							if (_imeSession)
+								_imeSession.compositionAbandoned();
+
+							//a discretionary hyphen is being inserted. 
+							var discretionaryHyphenString:String = String.fromCharCode(0x000000AD);
+							overwriteMode ? overwriteText(discretionaryHyphenString) : insertText(discretionaryHyphenString);
+							event.preventDefault();
+						}
+					}
+				}
+			} 
+			else if (event.altKey)
+			{
+				if (event.charCode == Keyboard.BACKSPACE)
+				{
+					deletePreviousWord();
+					event.preventDefault();
+				}
+				else if (event.keyCode == Keyboard.DELETE)
+				{
+					deleteNextWord();
+					event.preventDefault();
+				}
+			}
+			// not ctrl key or alt key
+			else if (event.keyCode == Keyboard.DELETE) //del
+			{
+				deleteNextCharacter();
+				event.preventDefault();
+			}
+			else if (event.keyCode == Keyboard.INSERT) //insert
+			{
+				overwriteMode = !overwriteMode;				
+				event.preventDefault();
+			}
+			else switch(event.charCode) {
+				case Keyboard.BACKSPACE:
+					deletePreviousCharacter();
+					event.preventDefault();
+					break;
+				case Keyboard.ENTER:
+					if (textFlow.configuration.manageEnterKey) 
+					{
+						splitParagraph();
+						event.preventDefault();
+						event.stopImmediatePropagation();
+					}
+					break;
+				case Keyboard.TAB:
+					if (textFlow.configuration.manageTabKey) 
+					{
+						overwriteMode ? overwriteText(String.fromCharCode(event.charCode)) : insertText(String.fromCharCode(event.charCode));
+						event.preventDefault();
+					}
+					break;
+			}
+		}
+		
+		/** @private */
+		public override function keyUpHandler(event:KeyboardEvent):void
+		{
+			if (!hasSelection() || event.isDefaultPrevented())
+				return;
+				
+			super.keyUpHandler(event);
+			
+			if ((textFlow.configuration.manageEnterKey && event.charCode == Keyboard.ENTER) || (textFlow.configuration.manageTabKey && event.charCode == Keyboard.TAB)) {
+				event.stopImmediatePropagation();
+			}
+		}
+		
+		/** @private */	
+		public override function keyFocusChangeHandler(event:FocusEvent):void
+		{
+			if (textFlow.configuration.manageTabKey) 
+				event.preventDefault();
+		}
+	
+		/** @private */
+		public override function textInputHandler(event:TextEvent):void
+		{
+			if (!ignoreNextTextEvent)
+			{
+				var charCode:int = event.text.charCodeAt(0);
+				// only if its a space or larger - ignore control characters here
+				if (charCode >=  32)
+					overwriteMode ? overwriteText(event.text) : insertText(event.text);
+			}
+			ignoreNextTextEvent = false;
+		}
+		
+		/** @private */
+		override public function focusOutHandler(event:FocusEvent):void
+		{
+			super.focusOutHandler(event);
+			if (_imeSession && selectionFormatState != SelectionFormatState.FOCUSED)
+				_imeSession.compositionAbandoned();
+		}
+		
+		/** @private */
+		override public function deactivateHandler(event:Event):void
+		{
+			super.deactivateHandler(event);
+			if (_imeSession)
+				_imeSession.compositionAbandoned();
+		}
+		
+		/** @private */
+		override public function imeStartCompositionHandler(event:IMEEvent):void
+		{
+			CONFIG::debug{ assert(!_imeSession, "IME session already in progress: IME not reentrant!"); }
+		//	CONFIG::debug { Debugging.traceOut("imeStartComposition event"); }
+
+			// any pending operations must be executed first, to
+			// preserve operation order.
+			flushPendingOperations();
+			
+			// Coded to avoid dependency on Argo (10.1). 
+			if (!(event["imeClient"]))
+			{
+				_imeSession = new IMEClient(this);
+				_imeOperationInProgress = false;
+				event["imeClient"] = _imeSession;
+			}
+		}
+		
+		/** @private */
+		override public function setFocus():void
+		{
+			var flowComposer:IFlowComposer = textFlow ? textFlow.flowComposer : null;
+			if (_imeSession && flowComposer && flowComposer.numControllers > 1)
+			{
+				// container with the ime start position gets the key focus
+				_imeSession.setFocus();
+
+				setSelectionFormatState(SelectionFormatState.FOCUSED);
+			}
+			else
+				super.setFocus();
+		}
+		/** @private */		
+		tlf_internal function endIMESession():void
+		{
+			_imeSession = null;
+			var flowComposer:IFlowComposer = textFlow ? textFlow.flowComposer : null;
+			if (flowComposer && flowComposer.numControllers > 1)
+				setFocus();
+		}
+		/** @private */
+		tlf_internal function beginIMEOperation():void
+		{
+			_imeOperationInProgress = true;
+			beginCompositeOperation();
+		}
+		/** @private */
+		tlf_internal function endIMEOperation():void
+		{
+			endCompositeOperation();
+			_imeOperationInProgress = false;
+		}
+
+		/** @private We track the nesting level of the doOperation, because in finalize we need to know if
+		we are at the outermost level and need to push the operation on the undo stack and redraw
+		the screen, or if we're in a nested level and need to append the operation to the next
+		level up. */
+		tlf_internal var captureLevel:int = 0;
+
+		/** 
+		  * @copy IEditManager#doOperation()
+		  * 
+		  * @includeExample examples\EditManager_doOperation.as -noswf
+		  * 
+		  * @playerversion Flash 10
+		  * @playerversion AIR 1.5
+ 	 	  * @langversion 3.0
+		  */
+		public override function doOperation(operation:FlowOperation):void
+		{
+			CONFIG::debug { assert(operation.textFlow == this.textFlow,"Operation from a different TextFlow"); }
+			
+			// If we get any operation during an IME session that is not owned by the session, we cancel the IME
+			if (_imeSession && !_imeOperationInProgress)
+				_imeSession.compositionAbandoned();
+			
+			// any pending operations must be executed first, to
+			// preserve operation order.
+			flushPendingOperations();
+			
+			try
+			{
+				captureLevel++;
+				operation = doInternal(operation);
+			}
+			catch(e:Error)
+			{
+				captureLevel--;
+				throw(e);
+			}
+			captureLevel--;
+			
+			if (operation)			// don't finalize if operation was cancelled
+				finalizeDo(operation);
+		}
+
+		private function finalizeDo(op:FlowOperation):void
+		{
+			// Handle operation if we're in a beginCompositeOperation/endCompositeOperation context
+			// In this case any nested commands we do will get added to the composite operation when 
+			// they're done instead of added to the undo stack.
+			var parentOperation:CompositeOperation;
+			if (parentStack && parentStack.length > 0)
+			{
+				var parent:Object = parentStack[parentStack.length - 1];
+				if (parent.captureLevel == captureLevel)
+					parentOperation = parent.operation as CompositeOperation;
+			}
+
+	//		CONFIG::debug { assert(captureLevel == 0 || parentOperation != null, "missing parent for nested operation"); }
+			
+			if (parentOperation)
+				parentOperation.addOperation(op);
+			
+			else if (captureLevel == 0)
+			{
+				captureOperations.length = 0; 
+				if (_undoManager)
+				{
+					if (_undoManager.canUndo() && allowOperationMerge)
+					{
+						var lastOp:FlowOperation = _undoManager.peekUndo() as FlowOperation;
+						if (lastOp)
+						{
+							// Try to merge the last operation on the stack with the current
+							// operation. This may modify lastOp, or return a new operation
+							var combinedOp:FlowOperation = lastOp.merge(op);
+							if (combinedOp)
+							{
+								combinedOp.setGenerations(lastOp.beginGeneration,textFlow.generation);
+								_undoManager.popUndo();
+								op = combinedOp;
+							}
+						}
+					}
+					if (op.canUndo())
+						_undoManager.pushUndo(op);
+					allowOperationMerge = true;
+
+					// following operations are no longer redoable
+					_undoManager.clearRedo();
+				}
+
+				updateAllControllers();			
+				
+				if (hasSelection())
+				{
+					var controllerIndex:int = textFlow.flowComposer.findControllerIndexAtPosition(activePosition);
+					if (controllerIndex >= 0)
+						textFlow.flowComposer.getControllerAt(controllerIndex).scrollToRange(activePosition,anchorPosition);	
+				}
+				if (!_imeSession)
+				{	
+					var opEvent:FlowOperationEvent = new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_COMPLETE,false,false,op,0,null);
+					textFlow.dispatchEvent(opEvent);
+				}
+			}	
+		}
+		
+		private var captureOperations:Array = [];
+
+		/** Internal guts of a dooperation - Execute a FlowOperation.  This function proceeds in steps.
+		  * <p>Step 2. Send a canceallable OperationEvent.  If cancelled this method returns immediately.</p>
+		  * If it is not cancelled, the listener may "do" other operations by calling back into the EditManager. This will result
+		  * in a nested call to do which will post additional commands to the captureOperations array.
+		  * <p>Step 3. Execute the operation.  The operation returns true or false.  false indicates no changes were made.</p>
+		  * <p>Step 7. Send a OperationEvent. </p>
+		  * The listener may "do" other operations by calling back into the EditManager. This will result
+		  * in a nested call to do which will post additional commands to the captureOperations array.
+		  * <p>Exception handling.  If the operation throws the exception is caught and the error is attached to the event dispatched
+		  * at step 7.  If the event is not cancelled the error is rethrown.</p>
+		  */
+		private function doInternal(op:FlowOperation):FlowOperation
+		{
+			CONFIG::debug { assert(op.textFlow == this.textFlow,"Operation from a different TextFlow"); }
+			
+			var captureStart:int = captureOperations.length;
+			var success:Boolean = false;
+			var opEvent:FlowOperationEvent;
+			
+			// tell any listeners about the operation
+			if (!_imeSession)
+			{
+				opEvent = new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_BEGIN,false,true,op,captureLevel-1,null);
+				textFlow.dispatchEvent(opEvent);
+				if (opEvent.isDefaultPrevented())
+					return null;
+				// user may replace the operation - TODO: WHAT IF SWITCH TO UNDO/REDO????
+				op = opEvent.operation;
+				if ((op is UndoOperation) || (op is RedoOperation))
+					throw new IllegalOperationError(GlobalSettings.resourceStringFunction("illegalOperation",[ getQualifiedClassName(op) ]));
+			}
+				
+			var opError:Error = null;
+			try
+			{
+				// begin this op after pending ops are flushed
+				CONFIG::debug 
+				{ 
+					if (captureLevel <= 1)
+						debugCheckTextFlow(); 
+				}
+				
+				// null return implies no operation was done - just discard it
+				var beforeGeneration:uint = textFlow.generation;
+				op.setGenerations(beforeGeneration,0);
+	
+				captureOperations.push(op);
+				success = op.doOperation();
+				if (success)		// operation succeeded
+				{
+					textFlow.normalize();   //force normalization at this point. Don't compose unless the captureLevel is 0
+					
+					// This has to be done after the normalize, because normalize increments the generation number
+					op.setGenerations(beforeGeneration,textFlow.generation);					
+				} 
+				else 
+				{
+					var index:int = captureOperations.indexOf(op);
+					if (index >= 0) 
+						captureOperations.splice(index, 1);
+				}
+			}
+			catch(e:Error)
+			{
+				opError = e;
+			}
+			
+			// operation completed - send event whether it succeeded or not.
+			// client can check generation number for changes
+			if (!_imeSession)
+			{
+				opEvent = new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_END,false,true,op,captureLevel-1,opError);
+				textFlow.dispatchEvent(opEvent);
+				opError = opEvent.isDefaultPrevented() ? null : opEvent.error;
+			}
+
+			if (opError)
+				throw (opError);
+				
+			// If we fired off any subsidiary operations, create a composite operation to hold them all
+		 	if (captureOperations.length - captureStart > 1)
+		 	{
+				op = new CompositeOperation(captureOperations.slice(captureStart));
+				op.setGenerations(FlowOperation(CompositeOperation(op).operations[0]).beginGeneration,textFlow.generation);
+				allowOperationMerge = false;
+				captureOperations.length = captureStart;		
+		 	}
+			 	
+			return success ? op : null;
+		}
+
+		/** Update the display after an operation has modified it */
+		protected function updateAllControllers():void
+		{
+			if (textFlow.flowComposer)
+				 textFlow.flowComposer.updateAllControllers(); 
+
+			selectionChanged(true, false);
+				
+			CONFIG::debug { debugCheckTextFlow(); }
+		}
+		
+		/** @private */
+		public override function flushPendingOperations():void
+		{
+			super.flushPendingOperations();
+			if (pendingInsert)
+			{
+				var pi0:InsertTextOperation = pendingInsert;
+				pendingInsert = null;
+				if (enterFrameListener)
+				{
+					enterFrameListener.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
+					enterFrameListener = null;
+				}
+				doOperation(pi0);
+			}
+		}
+
+		/** 
+		 * @copy IEditManager#undo()
+		 * @includeExample examples\EditManager_undo.as -noswf
+		 * 
+		 * @see flashx.undo.IUndoManager#undo()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function undo():void
+		{
+			// Cancel out of an IME session if there is one. 
+			// Some IMEs are on all the time, and so the undo has to win over the IME, 
+			// otherwise you would never be able to undo in Korean.
+			if (_imeSession)
+				_imeSession.compositionAbandoned();
+			
+			if (undoManager)
+				undoManager.undo();
+		}
+		 			
+		/** @private */
+		public function performUndo(theop:IOperation):void
+		{
+			var operation:FlowOperation = theop as FlowOperation;
+			if ((!operation) || (operation.textFlow != textFlow)) 
+				return;			
+			// tell any listeners about the operation
+			if (!_imeSession)
+			{
+				var undoPsuedoOp:UndoOperation = new UndoOperation(operation);
+				var opEvent:FlowOperationEvent = new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_BEGIN,false,true,undoPsuedoOp,0,null);
+				textFlow.dispatchEvent(opEvent);
+				if (opEvent.isDefaultPrevented())
+				{
+					//operation cancelled by user. Push the operation back onto the undo stack
+					undoManager.pushUndo(operation);
+					return;
+				}
+				undoPsuedoOp = opEvent.operation as UndoOperation;
+				if (!undoPsuedoOp)
+					throw new IllegalOperationError(GlobalSettings.resourceStringFunction("illegalOperation",[ getQualifiedClassName(opEvent.operation) ]));
+				operation = undoPsuedoOp.operation;
+			}
+					
+			if (operation.endGeneration != textFlow.generation)
+			{
+				//CONFIG::debug { trace("EditManager.undo: skipping undo due to mismatched generation numbers. textFlow",textFlow.generation,flash.utils.getQualifiedClassName(operation),operation.endGeneration); }
+				return;
+			}
+				
+			var opError:Error = null;
+			try
+			{
+				CONFIG::debug { debugCheckTextFlow(); }
+	
+				var rslt:SelectionState;
+				rslt = operation.undo();
+	
+				CONFIG::debug { assert(rslt != null,"undoable operations must return a SelectionState"); }
+				setSelectionState(rslt);
+				if (_undoManager)
+					_undoManager.pushRedo(operation);
+
+			}
+			catch(e:Error)
+			{
+				opError = e;
+			}
+				
+			// tell user its complete and give them a chance to cancel the rethrow
+			if (!_imeSession)
+			{
+				opEvent = new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_END,false,true,undoPsuedoOp,0,opError);
+				textFlow.dispatchEvent(opEvent);
+				opError = opEvent.isDefaultPrevented() ? null : opEvent.error;
+			}
+
+			if (opError)
+				throw (opError);
+			
+			updateAllControllers();
+			
+			// push the generation of the textFlow backwards - must be done after update which does a normalize
+			textFlow.setGeneration(operation.beginGeneration);
+			
+			if (hasSelection())
+			{
+				var controllerIndex:int = textFlow.flowComposer.findControllerIndexAtPosition(activePosition);
+				if (controllerIndex >= 0)
+					textFlow.flowComposer.getControllerAt(controllerIndex).scrollToRange(activePosition,anchorPosition);											
+			}
+			opEvent = new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_COMPLETE,false,false,undoPsuedoOp,0,null);
+			textFlow.dispatchEvent(opEvent);
+		}
+		
+		/** 
+		 * @copy IEditManager#redo()
+		 * @includeExample examples\EditManager_redo.as -noswf
+		 * 
+		 * @see flashx.undo.IUndoManager#redo()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function redo():void
+		{
+			// Cancel out of an IME session if there is one. 
+			// Some IMEs are on all the time, and so the undo has to win over the IME, 
+			// otherwise you would never be able to undo in Korean.
+			if (_imeSession)
+				_imeSession.compositionAbandoned();
+			
+			if (undoManager)
+				undoManager.redo();
+		}
+		
+		/** @private */
+		public function performRedo(theop:IOperation):void
+		{
+			var opEvent:FlowOperationEvent;
+			var op:FlowOperation = theop as FlowOperation;
+			if ((!op) || (op.textFlow != textFlow)) 
+				return;
+			// tell any listeners about the operation
+			if (!_imeSession)
+			{
+				var redoPsuedoOp:RedoOperation = new RedoOperation(op);
+				opEvent = new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_BEGIN,false,true,redoPsuedoOp,0,null);
+				textFlow.dispatchEvent(opEvent);
+				if (opEvent.isDefaultPrevented() && _undoManager)
+				{
+					//user cancelled the event. Push the operation back onto the redo stack
+					_undoManager.pushRedo(op);
+					return;
+				}
+				redoPsuedoOp = opEvent.operation as RedoOperation;
+				if (!redoPsuedoOp)
+					throw new IllegalOperationError(GlobalSettings.resourceStringFunction("illegalOperation",[ getQualifiedClassName(opEvent.operation) ]));
+				op = redoPsuedoOp.operation;
+			}
+					
+			if (op.beginGeneration != textFlow.generation)
+			{
+				//CONFIG::debug { trace("EditManager.redo: skipping redo due to mismatched generation numbers."); }
+				return;
+			}
+				
+			var opError:Error = null;
+			try
+			{
+				CONFIG::debug { debugCheckTextFlow(); }					
+				var rslt:SelectionState;
+				rslt = op.redo();
+					
+				CONFIG::debug { assert(rslt != null,"redoable operations must return a SelectionState"); }
+				setSelectionState(rslt);
+				if (_undoManager)
+					_undoManager.pushUndo(op);
+
+			
+			}
+			catch(e:Error)
+			{
+				opError = e;
+			}
+				
+			// tell user its complete and give them a chance to cancel the rethrow
+			if (!_imeSession)
+			{
+				opEvent = new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_END,false,true,redoPsuedoOp,0,opError);
+				textFlow.dispatchEvent(opEvent);
+				opError = opEvent.isDefaultPrevented() ? null : opEvent.error;
+			}
+			if (opError)
+				throw (opError);
+			
+			updateAllControllers();
+			
+			// push the generation of the textFlow backwards - must be done after update which does a normalize
+			// set the generation of the textFlow to end of redoOp.
+			textFlow.setGeneration(op.endGeneration);
+			
+			if (hasSelection())
+			{
+				var controllerIndex:int = textFlow.flowComposer.findControllerIndexAtPosition(activePosition);
+				if (controllerIndex >= 0)
+					textFlow.flowComposer.getControllerAt(controllerIndex).scrollToRange(activePosition,anchorPosition);						
+			}	
+			opEvent = new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_COMPLETE,false,false,op,0,null);
+			textFlow.dispatchEvent(opEvent);			
+		}
+		
+		/**
+		 * @private
+		 * Returns the editing mode (READ_ONLY, READ_SELECT, or READ_WRITE) of the EditManager.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 * @see flashx.textLayout.edit.EditingMode.
+		 */
+		 public override function get editingMode():String
+		 {
+		 	return EditingMode.READ_WRITE;
+		 }				 		
+		
+		// Resolve the operationState.
+		//		If the operation state is null...
+		//			Return the active selection
+		//			If there's no active selection, return null. The caller will have to check
+		//		Otherwise (operation not null)
+		//			just return it
+		/** @private */
+		tlf_internal function defaultOperationState(operationState:SelectionState = null):SelectionState
+		{
+			if (operationState)
+			{
+				// flush any pending operations and use marks to preserve the operationState positions
+				var markActive:Mark = createMark();
+				var markAnchor:Mark = createMark();
+				try
+				{
+					markActive.position = operationState.activePosition;
+					markAnchor.position = operationState.anchorPosition;
+					flushPendingOperations();
+				}
+				finally
+				{
+					removeMark(markActive);
+					removeMark(markAnchor);
+					operationState.activePosition = markActive.position;
+					operationState.anchorPosition = markAnchor.position;
+				}
+			}
+			else
+			{
+				flushPendingOperations();
+				if (hasSelection())
+				{
+					// tell the operation that the state is from the SelectionManager so it will update pending point formats
+					operationState = getSelectionState();
+					operationState.selectionManagerOperationState = true;
+				}
+			}
+			return operationState;
+		}
+
+		/** 
+		 * @copy IEditManager#splitParagraph()
+		 * @includeExample examples\EditManager_splitParagraph.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function splitParagraph(operationState:SelectionState = null):void
+		{
+			operationState = defaultOperationState(operationState);
+			if (!operationState)
+				return;
+
+			doOperation(new SplitParagraphOperation(operationState));
+		}
+
+		/** 
+		 * @copy IEditManager#deleteText()
+		 * @includeExample examples\EditManager_deleteText.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function deleteText(operationState:SelectionState = null):void
+		{
+
+			operationState = defaultOperationState(operationState);
+			if (!operationState)
+				return;
+
+			doOperation(new DeleteTextOperation(operationState, operationState, false /* don't allow merge when deleting by range */));				
+		}		
+		
+		/**
+		 * @copy IEditManager#deleteNextCharacter()
+		 * @includeExample examples\EditManager_deleteNextCharacter.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function deleteNextCharacter(operationState:SelectionState = null):void
+		{
+			operationState = defaultOperationState(operationState);
+			if (!operationState)
+				return;
+
+			// Delete the next character if it's a caret selection, and allow adejacent delete next's to merge
+			// If it's a range selection, delete the range and disallow merge
+			var deleteOp:DeleteTextOperation;
+			if (operationState.absoluteStart == operationState.absoluteEnd)
+			{
+				var nextPosition:int = NavigationUtil.nextAtomPosition(textFlow, absoluteStart);
+				deleteOp = new DeleteTextOperation(operationState, new SelectionState(textFlow, absoluteStart, nextPosition, pointFormat), true /* allowMerge for deleteForward */);	
+			}
+			else 
+				deleteOp = new DeleteTextOperation(operationState, operationState, false /* don't allow merge when deleting by range */);			
+			doOperation(deleteOp);			
+
+		}
+
+		/** 
+		 * @copy IEditManager#deleteNextWord()
+		 * @includeExample examples\EditManager_deleteNextWord.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */		
+		public function deleteNextWord(operationState:SelectionState = null):void
+		{
+			operationState = defaultOperationState(operationState);
+			if ((!operationState) || ((operationState.anchorPosition == operationState.activePosition) && (operationState.anchorPosition >= textFlow.textLength - 1)))
+				return;
+				
+			var nextWordSelState:SelectionState = getNextWordForDelete(operationState.absoluteStart);
+			if (nextWordSelState.anchorPosition == nextWordSelState.activePosition)
+				//nothing to delete. No operation required.
+				return;			
+
+			setSelectionState(new SelectionState(textFlow, operationState.absoluteStart, operationState.absoluteStart, new TextLayoutFormat(textFlow.findLeaf(operationState.absoluteStart).format)));
+			doOperation(new DeleteTextOperation(operationState, nextWordSelState, false));						
+		}
+
+		// Sadly, this is NOT the same as the cursor key movement - specialized for delete forward one word
+		private function getNextWordForDelete(absoluteStart:int):SelectionState
+		{
+			var leafEl:FlowLeafElement = textFlow.findLeaf(absoluteStart);
+			var paraEl:ParagraphElement = leafEl.getParagraph();
+			var paraElAbsStart:int = paraEl.getAbsoluteStart();
+			
+			var nextPosition:int = -1;
+			
+			if ((absoluteStart - paraElAbsStart) >= (paraEl.textLength - 1))
+			{
+				// We're at the end of the paragraph, delete the following newline
+				nextPosition = NavigationUtil.nextAtomPosition(textFlow, absoluteStart);
+			}
+			else
+			{
+				var curPos:int = absoluteStart - paraElAbsStart;			
+				var curPosCharCode:int = paraEl.getCharCodeAtPosition(curPos);
+				var prevPosCharCode:int = -1;
+				if (curPos > 0) prevPosCharCode = paraEl.getCharCodeAtPosition(curPos - 1);
+				var nextPosCharCode:int = paraEl.getCharCodeAtPosition(curPos + 1);
+				if (!CharacterUtil.isWhitespace(curPosCharCode) && ((curPos == 0) || ((curPos > 0) && CharacterUtil.isWhitespace(prevPosCharCode)))) {
+					nextPosition = NavigationUtil.nextWordPosition(textFlow, absoluteStart);
+				} else {
+					if (CharacterUtil.isWhitespace(curPosCharCode) && ((curPos > 0) && !CharacterUtil.isWhitespace(prevPosCharCode))) {
+						//if at beginning of space word then get through all the spaces					
+						curPos = paraEl.findNextWordBoundary(curPos);
+					}
+					nextPosition = paraElAbsStart + paraEl.findNextWordBoundary(curPos);
+				}
+			}
+			return new SelectionState(textFlow, absoluteStart, nextPosition, pointFormat);
+		}
+		
+		/**
+		 * @copy IEditManager#deletePreviousCharacter()
+		 * @includeExample examples\EditManager_deletePreviousCharacter.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */		
+		public function deletePreviousCharacter(operationState:SelectionState = null):void
+		{
+			operationState = defaultOperationState(operationState);
+			if (!operationState)
+				return;
+
+			var deleteOp:DeleteTextOperation;
+			if (operationState.absoluteStart == operationState.absoluteEnd)
+			{	// with a caret selection, delete the previous character
+				var beginPrevious:int = NavigationUtil.previousAtomPosition(textFlow, operationState.absoluteStart);
+				deleteOp = new DeleteTextOperation(operationState, new SelectionState(textFlow, beginPrevious, operationState.absoluteStart), true /* allowMerge */);
+			}
+			else	// just delete the range
+				deleteOp = new DeleteTextOperation(operationState);
+			doOperation(deleteOp);
+		}
+		
+		/** 
+		 * @copy IEditManager#deletePreviousWord()
+		 * @includeExample examples\EditManager_deletePreviousWord.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */		
+		public function deletePreviousWord(operationState:SelectionState = null):void
+		{
+			operationState = defaultOperationState(operationState);
+			if (!operationState)
+				return;
+				
+			var prevWordSelState:SelectionState = getPreviousWordForDelete(operationState.absoluteStart);
+			if (prevWordSelState.anchorPosition == prevWordSelState.activePosition)
+				//there is nothing to delete.  No operation required
+				return;			
+				
+			setSelectionState(new SelectionState(textFlow, operationState.absoluteStart, operationState.absoluteStart, new TextLayoutFormat(textFlow.findLeaf(operationState.absoluteStart).format)));
+			doOperation(new DeleteTextOperation(operationState, prevWordSelState, false /* don't allow merge */));						
+		}		
+		
+		// Sadly, this is NOT the same as the cursor key movement - specialized for delete backward one word
+		private function getPreviousWordForDelete(absoluteStart:int):SelectionState
+		{
+			var leafEl:FlowLeafElement = textFlow.findLeaf(absoluteStart);
+			var paraEl:ParagraphElement = leafEl.getParagraph();
+			var paraElAbsStart:int = paraEl.getAbsoluteStart();
+
+			if (absoluteStart == paraElAbsStart)		// at the start of the paragraph, delete the previous newline. Should insert a space after punctuation.
+			{
+				var beginPrevious:int = NavigationUtil.previousAtomPosition(textFlow, absoluteStart);
+				return new SelectionState(textFlow, beginPrevious, absoluteStart);				
+			}
+
+			var curPos:int = absoluteStart - paraElAbsStart;
+			var curPosCharCode:int = paraEl.getCharCodeAtPosition(curPos);
+			var prevPosCharCode:int = paraEl.getCharCodeAtPosition(curPos - 1);
+			var curAbsStart:int = absoluteStart;
+			
+			if (CharacterUtil.isWhitespace(curPosCharCode) && (curPos != (paraEl.textLength - 1)))
+			{
+				if (CharacterUtil.isWhitespace(prevPosCharCode)) //this will get you past the spaces
+				{
+					curPos = paraEl.findPreviousWordBoundary(curPos);
+				}
+				if (curPos > 0) {
+					curPos = paraEl.findPreviousWordBoundary(curPos); //this will get you to the beginning of the word before the space.
+					if (curPos > 0) {
+						prevPosCharCode = paraEl.getCharCodeAtPosition(curPos - 1);
+						if (CharacterUtil.isWhitespace(prevPosCharCode)) {
+							curPos = paraEl.findPreviousWordBoundary(curPos);
+						}
+					}
+				}
+			} else { //you are here if you are not on a space
+				if (CharacterUtil.isWhitespace(prevPosCharCode))
+				{
+					curPos = paraEl.findPreviousWordBoundary(curPos); //this will get you past the spaces
+					if (curPos > 0) {
+						curPos = paraEl.findPreviousWordBoundary(curPos);
+						if (curPos > 0) {
+							prevPosCharCode = paraEl.getCharCodeAtPosition(curPos - 1);
+							if (!CharacterUtil.isWhitespace(prevPosCharCode)) {
+								curAbsStart--; //Microsoft Word insists on keeping the original space
+								               //if the ending position does not have a space.
+							}
+						}
+					}
+				} else { //just delete to the previous word boundary
+					curPos = paraEl.findPreviousWordBoundary(curPos);
+				}
+			}
+			return new SelectionState(textFlow, paraElAbsStart + curPos, curAbsStart);
+		}		
+		
+		/** 
+		 * @copy IEditManager#insertText()
+		 * @includeExample examples\EditManager_insertText.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */	
+		public function insertText(text:String, origOperationState:SelectionState = null):void
+		{
+			// if there's another insert operation waiting to be executed, 
+			// just add to it, if possible
+			if (origOperationState == null && pendingInsert)
+				pendingInsert.text += text;
+			else 
+			{
+				var operationState:SelectionState = defaultOperationState(origOperationState);
+				if (!operationState)
+					return;
+				
+				// rather than execute the insert immediately, create
+				// it and wait for the next frame, in order to batch
+				// keystrokes.
+				pendingInsert = new InsertTextOperation(operationState, text);
+				
+				var controller:ContainerController = textFlow.flowComposer.getControllerAt(0);
+				if (captureLevel == 0 && origOperationState == null && controller && controller.container)
+				{
+					enterFrameListener = controller.container;
+					enterFrameListener.addEventListener(Event.ENTER_FRAME, enterFrameHandler, false, 1.0, true);
+				}
+				else
+					flushPendingOperations();
+			}
+		}
+				
+
+		
+		/** 
+		 * @copy IEditManager#overwriteText()
+		 * 
+		 * @includeExample examples\EditManager_overwriteText.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */	
+		public function overwriteText(text:String, operationState:SelectionState = null):void
+		{
+			operationState = defaultOperationState(operationState);
+			if (!operationState)
+				return;
+			var selState:SelectionState = getSelectionState();
+			NavigationUtil.nextCharacter(selState,true);
+			doOperation(new InsertTextOperation(operationState, text, selState));
+		}
+
+		/** 
+		 * @copy IEditManager#insertInlineGraphic()
+		 * @includeExample examples\EditManager_insertInlineGraphic.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 * @see flash.text.engine.TextRotation
+		 */			
+		public function insertInlineGraphic(source:Object, width:Object, height:Object, options:Object = null, operationState:SelectionState = null):void
+		{
+			operationState = defaultOperationState(operationState);
+			if (!operationState)
+				return;
+
+			doOperation(new InsertInlineGraphicOperation(operationState, source, width, height, options));
+		}	
+		
+		/** 
+		 * @copy IEditManager#modifyInlineGraphic()
+		 * @includeExample examples\EditManager_modifyInlineGraphic.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */			
+		public function modifyInlineGraphic(source:Object, width:Object, height:Object, options:Object = null, operationState:SelectionState = null):void
+		{
+			operationState = defaultOperationState(operationState);
+			if (!operationState)
+				return;
+
+			doOperation(new ModifyInlineGraphicOperation(operationState, source, width, height, options));
+		}					
+		
+		/** 
+		 * @copy IEditManager#applyFormat()
+		 * 
+		 * @includeExample examples\EditManager_applyFormat.as -noswf
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */		
+		public function applyFormat(leafFormat:ITextLayoutFormat, paragraphFormat:ITextLayoutFormat, containerFormat:ITextLayoutFormat, operationState:SelectionState = null):void
+		{
+			operationState = defaultOperationState(operationState);
+			if (!operationState)
+				return;
+
+			// apply to the current selection else remember new format for next char typed
+			doOperation(new ApplyFormatOperation(operationState, leafFormat, paragraphFormat, containerFormat));
+		}
+		/** 
+		 * @copy IEditManager#clearFormat()
+		 * 
+		 * Known issue is that undefines of leafFormat values with a point selection are not applied at the next insertion.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public function clearFormat(leafFormat:ITextLayoutFormat, paragraphFormat:ITextLayoutFormat, containerFormat:ITextLayoutFormat, operationState:SelectionState = null):void
+		{
+			operationState = defaultOperationState(operationState);
+			if (!operationState)
+				return;
+			
+			// apply to the current selection else remember new format for next char typed
+			doOperation(new ClearFormatOperation(operationState, leafFormat, paragraphFormat, containerFormat));
+		}
+		/** 
+		 * @copy IEditManager#applyLeafFormat()
+		 * 
+		 * @includeExample examples\EditManager_applyLeafFormat.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */		
+		public function applyLeafFormat(characterFormat:ITextLayoutFormat, operationState:SelectionState = null):void
+		{
+			applyFormat(characterFormat, null, null, operationState);
+		}
+
+		/** 
+		 * @copy IEditManager#applyParagraphFormat()
+		 * 
+		 * @includeExample examples\EditManager_applyParagraphFormat.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 		 */		
+		public function applyParagraphFormat(paragraphFormat:ITextLayoutFormat, operationState:SelectionState = null):void
+		{
+			applyFormat(null, paragraphFormat, null, operationState);
+		}
+
+		/** 
+		 * @copy IEditManager#applyContainerFormat()
+		 * 
+		 * @includeExample examples\EditManager_applyContainerFormat.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */		
+		public function applyContainerFormat(containerFormat:ITextLayoutFormat, operationState:SelectionState = null):void
+		{
+			applyFormat(null, null, containerFormat, operationState);
+		}
+		
+		/** 
+		 * @copy IEditManager#applyFormatToElement()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */	
+		public function applyFormatToElement(targetElement:FlowElement, format:ITextLayoutFormat, operationState:SelectionState = null):void
+		{
+			operationState = defaultOperationState(operationState);
+			if (!operationState)
+				return;
+
+			doOperation(new ApplyFormatToElementOperation(operationState, targetElement, format));
+		}
+
+		/** 
+		 * @copy IEditManager#clearFormatOnElement()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */	
+		public function clearFormatOnElement(targetElement:FlowElement, format:ITextLayoutFormat, operationState:SelectionState = null):void
+		{
+			operationState = defaultOperationState(operationState);
+			if (!operationState)
+				return;
+			
+			doOperation(new ClearFormatOnElementOperation(operationState, targetElement, format));
+		}
+		
+		/** 
+		 * @copy IEditManager#cutTextScrap()
+		 * @includeExample examples\EditManager_cutTextScrap.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 	 	 * 
+		 *  @see flashx.textLayout.edit.TextScrap
+		 */
+		public function cutTextScrap(operationState:SelectionState = null):TextScrap
+		{
+			operationState = defaultOperationState(operationState);
+			if (!operationState)
+				return null;
+				
+			if (operationState.anchorPosition == operationState.activePosition)
+				return null;
+
+			var tScrap:TextScrap = TextFlowEdit.createTextScrap(operationState.textFlow, operationState.absoluteStart, operationState.absoluteEnd);			
+			var beforeOpLen:int = textFlow.textLength;						
+			doOperation(new CutOperation(operationState, tScrap));
+			if (operationState.textFlow.textLength != beforeOpLen)
+			{
+				return tScrap;
+			}									
+			return null;			
+		}
+		
+		/** 
+		 * @copy IEditManager#pasteTextScrap()
+		 * @includeExample examples\EditManager_pasteTextScrap.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 	 	 * 
+		 *  @see flashx.textLayout.edit.TextScrap
+		 */
+		public function pasteTextScrap(scrapToPaste:TextScrap, operationState:SelectionState = null):void
+		{
+			operationState = defaultOperationState(operationState);
+			if (!operationState)
+				return;
+
+			doOperation(new PasteOperation(operationState, scrapToPaste));	
+		}
+		
+		/** 
+		 * @copy IEditManager#applyTCY()
+		 * @includeExample examples\EditManager_applyTCY.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */			
+		public function applyTCY(tcyOn:Boolean, operationState:SelectionState = null):void
+		{
+			operationState = defaultOperationState(operationState);
+			if (!operationState)
+				return;
+
+			doOperation(new ApplyTCYOperation(operationState, tcyOn));
+		}
+		
+		/** 
+		 * @copy IEditManager#applyLink()
+		 * @includeExample examples\EditManager_applyLink.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */			
+		public function applyLink(href:String, targetString:String = null, extendToLinkBoundary:Boolean=false, operationState:SelectionState = null):void
+		{
+			operationState = defaultOperationState(operationState);
+			if (!operationState)
+				return;
+				
+			if (operationState.absoluteStart == operationState.absoluteEnd)
+				return;
+
+			doOperation(new ApplyLinkOperation(operationState, href, targetString, extendToLinkBoundary));
+		}
+		
+		/**
+		 * @copy IEditManager#changeElementID()
+		 * @includeExample examples\EditManager_changeElementID.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+	 	*/
+		public function changeElementID(newID:String, targetElement:FlowElement, relativeStart:int = 0, relativeEnd:int = -1, operationState:SelectionState = null):void
+		{
+			operationState = defaultOperationState(operationState);
+			if (!operationState)
+				return;
+				
+			if (operationState.absoluteStart == operationState.absoluteEnd)
+				return;
+
+			doOperation(new ApplyElementIDOperation(operationState, targetElement, newID, relativeStart, relativeEnd));
+		}
+		
+		
+		/**
+		 * @copy IEditManager#changeStyleName()
+		 * @includeExample examples\EditManager_changeStyleName.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+	 	*/
+		public function changeStyleName(newName:String, targetElement:FlowElement, relativeStart:int = 0, relativeEnd:int = -1, operationState:SelectionState = null):void
+		{
+			operationState = defaultOperationState(operationState);
+			if (!operationState)
+				return;
+				
+			doOperation(new ApplyElementStyleNameOperation(operationState, targetElement, newName, relativeStart, relativeEnd));
+		}
+		
+		/* CompositeOperations
+			Normally when you call doOperation, it gets executed immediately. By calling beginCompositeOperation, you can instead accumulate the
+			operations into a CompositeOperation. The CompositeOperation is completed and returned when you call endCompositeOperation, and 
+			processing returns to normal state. The client code can then either call doOperation on the CompositeOperation that was returned, 
+			or just drop it if the operation should be aborted.
+			
+			The parentStack is a stack of pending CompositeOperations. 
+		*/
+		private var parentStack:Array;
+		
+		/** 
+		 * @copy IEditManager#beginCompositeOperation()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 	 	 * 
+		 * @includeExample examples\EditManager_beginCompositeOperation.as -noswf
+		 */
+		public function beginCompositeOperation():void
+		{
+			flushPendingOperations();
+			
+			if (!parentStack)
+				parentStack = [];
+			var operation:CompositeOperation = new CompositeOperation();
+			
+			if (!_imeSession)
+			{	
+				var opEvent:FlowOperationEvent = new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_BEGIN,false,false,operation,captureLevel,null);
+				textFlow.dispatchEvent(opEvent);
+			}
+			
+			CONFIG::debug { assert(!operation.operations  || operation.operations.length == 0, "opening a composite operation that already has operations"); }
+			operation.setGenerations(textFlow.generation, 0);
+			++captureLevel;
+			var parent:Object = new Object();
+			parent.operation = operation;
+			parent.captureLevel = captureLevel;
+			parentStack.push(parent);
+		}
+		
+		/** 
+		 * @copy IEditManager#endCompositeOperation()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 	 	 * 
+		 * @includeExample examples\EditManager_beginCompositeOperation.as -noswf
+		 */
+		public function endCompositeOperation():void
+		{
+			CONFIG::debug { assert( parentStack.length > 0 || captureLevel <= 0, "EditManager.endOperation - no composite operation in progress"); }
+			
+			--captureLevel;
+			
+			var parent:Object = parentStack.pop();
+			var operation:FlowOperation = parent.operation;
+			if (!_imeSession)
+			{	
+				var opEvent:FlowOperationEvent = new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_END,false,false,operation,captureLevel,null);
+				textFlow.dispatchEvent(opEvent);
+			}
+			operation.setGenerations(operation.beginGeneration, textFlow.generation);
+			finalizeDo(operation);
+		}
+		
+		/** @private
+		 * Handler function called when the selection has been changed.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 * @param doDispatchEvent	true if a selection changed event will be sent
+		 * @param resetPointFormat	true if the attributes associated with the caret should be discarded
+		 */
+		tlf_internal override function selectionChanged(doDispatchEvent:Boolean = true, resetPointFormat:Boolean=true):void
+		{	
+			if (_imeSession)
+				_imeSession.selectionChanged();
+			
+			super.selectionChanged(doDispatchEvent, resetPointFormat);
+		}
+
+
+	}
+}
diff --git a/textLayout_edit/src/flashx/textLayout/edit/ElementRange.as b/textLayout_edit/src/flashx/textLayout/edit/ElementRange.as
new file mode 100755
index 0000000..4f50fb7
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/edit/ElementRange.as
@@ -0,0 +1,327 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.edit
+{
+
+/**
+ * The ElementRange class represents the range of objects selected within a text flow.
+ * 
+ * <p>The beginning elements 
+ * (such as <code>firstLeaf</code>) are always less than or equal to the end elements (in this case, <code>lastLeaf</code>)
+ * for each pair of values in an element range.</p>
+ * 
+ * @see flashx.textLayout.elements.TextFlow
+ * 
+ * @playerversion Flash 10
+ * @playerversion AIR 1.5
+ * @langversion 3.0
+ */	
+public class ElementRange
+{
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.compose.IFlowComposer;
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.SubParagraphGroupElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+	
+	private var _absoluteStart:int;
+	private var _absoluteEnd:int;
+	private var _firstLeaf:FlowLeafElement;
+	private var _lastLeaf:FlowLeafElement;
+	private var _firstParagraph:ParagraphElement;
+	private var _lastParagraph:ParagraphElement;
+	private var _textFlow:TextFlow;	
+	
+	/** 
+	 * The absolute text position of the FlowLeafElement object that contains the start of the range.
+	 *  
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */
+	public function get absoluteStart():int
+	{
+		return _absoluteStart;
+	}
+	public function set absoluteStart(value:int):void
+	{
+		_absoluteStart = value;
+	}
+	
+	/** 
+	 * The absolute text position of the FlowLeafElement object that contains the end of the range. 
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+ 	 */
+	public function get absoluteEnd():int
+	{
+		return _absoluteEnd;
+	}
+	public function set absoluteEnd(value:int):void
+	{
+		_absoluteEnd = value;
+	}
+
+	/** 
+	 * The FlowLeafElement object that contains the start of the range. 
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */
+	public function get firstLeaf():FlowLeafElement
+	{
+		return _firstLeaf;
+	}
+	public function set firstLeaf(value:FlowLeafElement):void
+	{
+		_firstLeaf = value;
+	}
+
+	/** 
+	 * The FlowLeafElement object that contains the end of the range. 
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	*/
+	public function get lastLeaf():FlowLeafElement
+	{
+		return _lastLeaf;
+	}
+	public function set lastLeaf(value:FlowLeafElement):void
+	{
+		_lastLeaf = value;
+	}
+
+	/** 
+	 * The ParagraphElement object that contains the start of the range. 
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */
+	public function get firstParagraph():ParagraphElement
+	{
+		return _firstParagraph;
+	}
+	public function set firstParagraph(value:ParagraphElement):void
+	{
+		_firstParagraph = value;
+	}
+	
+	/** 
+	 * The ParagraphElement object that contains the end of the range. 
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	*/
+	public function get lastParagraph():ParagraphElement
+	{
+		return _lastParagraph;
+	}
+	public function set lastParagraph(value:ParagraphElement):void
+	{
+		_lastParagraph = value;
+	}
+	
+	/** 
+	 * The TextFlow object that contains the range. 
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */
+	public function get textFlow():TextFlow
+	{
+		return _textFlow;
+	}	
+	public function set textFlow(value:TextFlow):void
+	{
+		_textFlow = value;
+	}	
+	
+	// This constructor function is here just to silence a compile warning in Eclipse. There
+	// appears to be no way to turn the warning off selectively.
+	/** @private */
+	CONFIG::debug public function ElementRange()
+	{
+		super();
+	}
+	
+ 	// NOTE: We've been back and forth on this - should a range selection show null attributes or beginning of range attributes?
+	// After looking at this for a while I want it to show beginning of range attributes.  Two main reasons
+	// 1. If the range contains different objects but homogoneous settings we should show the attributes.
+	// 2. If we show null attributes on a range selection there's no way to, for example, turn BOLD off.
+	// Try this at home - restore the old code. Select the entire text.  Turn Bold on.  Can't turn bold off.
+	// Please don't revert this without further discussion.
+	// Ideally we would have a way of figuring out which attributes are homogoneous over the selection range
+	// and which were not and showing, for example, a "half-checked" bold item.  We'd have to work this out for all the properties.
+	
+	// OLD CODE that shows null attribute settings on a range selection
+	// var charAttr:ICharacterFormat = selRange.begElem == selRange.endElem ? selRange.begElem.computedCharacterFormat : new CharacterFormat();
+	// var paraAttr:IParagraphFormat = selRange.begPara == selRange.endPara ? selRange.begPara.computedParagraphFormat : new ParagraphFormat();
+
+
+	/** 
+	 * The format attributes of the container displaying the range. 
+	 * 
+	 * <p>If the range spans more than one container, the format of the first container is returned.</p>
+	 *  
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */
+	public function get containerFormat():ITextLayoutFormat
+	{
+		// see NOTE above before changing!!
+		// This is just wrong - only shows the first container
+		var container:ContainerController;
+		var flowComposer:IFlowComposer = firstParagraph.getTextFlow().flowComposer;
+		if (flowComposer && flowComposer.numControllers > 0)
+			container = flowComposer.getControllerAt(0);
+		if (!container)
+			return ContainerFormattedElement(firstParagraph.getParentByType(ContainerFormattedElement)).computedFormat;
+ 		return container.computedFormat;		
+	}
+		
+	/** 
+	 * The format attributes of the paragraph containing the range. 
+	 * 
+	 * <p>If the range spans more than one paragraph, the format of the first paragraph is returned.</p>
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */
+	public function get paragraphFormat():ITextLayoutFormat
+	{
+		// see NOTE above before changing!!
+  		return firstParagraph.computedFormat;
+ 	}
+		
+	/** 
+	 * The format attributes of the characters in the range. 
+	 * 
+	 * <p>If the range spans more than one FlowElement object, which means that more than one
+	 * character format may exist within the range, the format of the first FlowElement object is returned.</p>
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */
+	public function get characterFormat():ITextLayoutFormat
+	{
+		// see NOTE above before changing!!
+ 		return firstLeaf.computedFormat;
+	}
+	
+	/** 
+	 * Creates an ElementRange object.
+	 * 
+	 * @param textFlow	the text flow
+	 * @param beginIndex absolute text position of the first character in the text range
+	 * @param endIndex one beyond the absolute text position of the last character in the text range
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */
+	static public function createElementRange(textFlow:TextFlow, absoluteStart:int, absoluteEnd:int):ElementRange
+	{
+		var rslt:ElementRange = new ElementRange();
+		if (absoluteStart == absoluteEnd)
+		{
+			rslt.absoluteStart = rslt.absoluteEnd = absoluteStart;
+			rslt.firstLeaf = rslt.lastLeaf = textFlow.findLeaf(rslt.absoluteStart);
+			rslt.firstParagraph = rslt.lastParagraph = rslt.firstLeaf.getParagraph();
+	//		rslt.begContainer = rslt.endContainer = selState.textFlow.findAbsoluteContainer(rslt.begElemIdx);
+			adjustForLeanLeft(rslt);
+		}
+		else
+		{
+			// order the selection points
+			if (absoluteStart < absoluteEnd)
+			{
+				rslt.absoluteStart  = absoluteStart;
+				rslt.absoluteEnd = absoluteEnd;
+			}
+			else
+			{
+				rslt.absoluteStart  = absoluteEnd;
+				rslt.absoluteEnd = absoluteStart;
+			}
+			rslt.firstLeaf = textFlow.findLeaf(rslt.absoluteStart);
+			rslt.lastLeaf = textFlow.findLeaf(rslt.absoluteEnd);
+			// back up one element if the end of the selection is the start of an element
+			// otherwise a block selection of a span looks like it includes discreet selection ranges
+			if (((rslt.lastLeaf == null) && (rslt.absoluteEnd == textFlow.textLength)) || (rslt.absoluteEnd == rslt.lastLeaf.getAbsoluteStart()))
+				rslt.lastLeaf = textFlow.findLeaf(rslt.absoluteEnd-1);
+				
+			rslt.firstParagraph = rslt.firstLeaf.getParagraph();
+			rslt.lastParagraph = rslt.lastLeaf.getParagraph();
+			
+	//		rslt.begContainer = selState.textFlow.findAbsoluteContainer(rslt.begElemIdx);
+	//		rslt.endContainer = selState.textFlow.findAbsoluteContainer(rslt.endElemIdx);
+	//		if (rslt.endElemIdx == rslt.endContainer.relativeStart)
+	//			rslt.endContainer = rslt.endContainer.preventextContainer;
+				
+			// if the end of the range includes the next to last character in a paragraph 
+			// expand it to include the paragraph teriminate character
+			if (rslt.absoluteEnd == rslt.lastParagraph.getAbsoluteStart() + rslt.lastParagraph.textLength - 1)
+			{
+				rslt.absoluteEnd++
+				rslt.lastLeaf = rslt.lastParagraph.getLastLeaf();
+			}
+
+		}
+		rslt.textFlow = textFlow;
+			
+		return rslt;
+	}
+	
+	static private function adjustForLeanLeft(rslt:ElementRange):void
+	{		
+		// If we're at the start of a leaf element, look to the previous leaf element and see if it shares the same
+		// parent. If so, we're going to move the selection to the end of the previous element so it takes on
+		// the formatting of the character to the left. We don't want to do this if the previous element is in
+		// a different character, across link or tcy boundaries, etc.
+		if (rslt.firstLeaf.getAbsoluteStart() == rslt.absoluteStart)
+		{
+			var previousNode:FlowLeafElement = rslt.firstLeaf.getPreviousLeaf(rslt.firstParagraph);
+			if (previousNode && previousNode.getParagraph() == rslt.firstLeaf.getParagraph())
+			{
+				if((!(previousNode.parent is SubParagraphGroupElement) || (previousNode.parent as SubParagraphGroupElement).acceptTextAfter())
+					&& (!(rslt.firstLeaf.parent is SubParagraphGroupElement) || previousNode.parent === rslt.firstLeaf.parent))
+					rslt.firstLeaf = previousNode;
+			}
+				
+		}
+	}
+}
+}
\ No newline at end of file
diff --git a/textLayout_edit/src/flashx/textLayout/edit/IEditManager.as b/textLayout_edit/src/flashx/textLayout/edit/IEditManager.as
new file mode 100755
index 0000000..cc5ca53
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/edit/IEditManager.as
@@ -0,0 +1,644 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.edit
+{
+	import flash.geom.Rectangle;
+	
+	import flashx.undo.UndoManager;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.formats.Float;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.operations.CompositeOperation;
+	import flashx.textLayout.operations.FlowOperation;
+	
+	import flashx.undo.IOperation;
+	
+	/** 
+	 * IEditManager defines the interface for handling edit operations of a text flow.
+	 * 
+	 * <p>To enable text flow editing, assign an IEditManager instance to the <code>interactionManager</code> 
+	 * property of the TextFlow object. The edit manager handles changes to the text (such as insertions, 
+	 * deletions, and format changes). Changes are reversible if the edit manager has an undo manager. The edit
+	 * manager triggers the recomposition and display of the text flow, as necessary.</p>
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+ 	 * 
+ 	 * @see EditManager
+ 	 * @see flashx.textLayout.elements.TextFlow
+ 	 * @see flashx.undo.UndoManager
+ 	 * 
+	 */
+	public interface IEditManager extends ISelectionManager
+	{				
+
+		/** 
+		 * The UndoManager object assigned to this EditManager instance, if there is one.
+		 * 
+		 * <p>An undo manager handles undo and redo operations.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function get undoManager():flashx.undo.IUndoManager
+
+		/** 
+		 * Changes the formats of the specified (or current) selection.
+		 * 
+		 * <p>Executes an undoable operation that applies the new formats.
+		 * Only style attributes set for the TextLayoutFormat objects are applied.
+		 * Undefined attributes in the format objects are not changed.
+		 * </p>
+ 	 	 * 
+		 * @param leafFormat	the format to apply to leaf elements such as spans and inline graphics
+		 * @param paragraphFormat	format to apply to paragraph elements
+		 * @param containerFormat	format to apply to the containers
+		 * @param operationState	specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 *
+ 	 	 * @includeExample examples\EditManager_applyFormat.as -noswf
+ 	 	 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */		
+		function applyFormat(leafFormat:ITextLayoutFormat, paragraphFormat:ITextLayoutFormat, containerFormat:ITextLayoutFormat, operationState:SelectionState = null):void
+
+		
+		/** 
+		 * Undefines formats of the specified (or current) selection.
+		 * 
+		 * <p>Executes an undoable operation that undefines the specified formats.
+		 * Only style attributes set for the TextLayoutFormat objects are applied.
+		 * Undefined attributes in the format objects are not changed.
+		 * </p>
+		 * 
+		 * @param leafFormat	 The format whose set values indicate properties to undefine to LeafFlowElement objects in the selected range.
+		 * @param paragraphFormat The format whose set values indicate properties to undefine to ParagraphElement objects in the selected range.
+		 * @param containerFormat The format whose set values indicate properties to undefine to ContainerController objects in the selected range.
+		 * @param operationState	specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */		
+		function clearFormat(leafFormat:ITextLayoutFormat, paragraphFormat:ITextLayoutFormat, containerFormat:ITextLayoutFormat, operationState:SelectionState = null):void
+
+		/** 
+		 * Changes the format applied to the leaf elements in the 
+		 * specified (or current) selection.
+		 * 
+		 * <p>Executes an undoable operation that applies the new format to leaf elements such as
+		 * SpanElement and InlineGraphicElement objects.
+		 * Only style attributes set for the TextLayoutFormat objects are applied.
+		 * Undefined attributes in the format object are changed.</p>
+		 * 
+		 * @param format	the format to apply.
+		 * @param operationState	specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @includeExample examples\EditManager_applyLeafFormat.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */		
+		function applyLeafFormat(format:ITextLayoutFormat, operationState:SelectionState = null):void;
+
+		/** 
+		 * Transforms text into a TCY run, or a TCY run into non-TCY text. 
+		 * 
+		 * <p>TCY, or tate-chu-yoko, causes text to draw horizontally within a vertical line, and is 
+		 * used to make small blocks of non-Japanese text or numbers, such as dates, more readable in vertical text.</p>
+		 * 
+		 * @param tcyOn	specify <code>true</code> to apply TCY to a text range, <code>false</code> to remove TCY. 
+		 * @param operationState	specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @includeExample examples\EditManager_applyTCY.as -noswf
+		 * @see flashx.textLayout.elements.TCYElement
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 		 */			
+		function applyTCY(tcyOn:Boolean, operationState:SelectionState = null):void;
+		
+		/** 
+		 * Transforms a selection into a link, or a link into normal text.
+		 * 
+		 * <p>Executes an undoable operation that creates or removes the link.</p>
+		 * 
+		 *  <p>If a <code>target</code> parameter is specified, it must be one of the following values:</p>
+		 * <ul>
+		 *	<li>"_self"</li>
+		 *  <li>"_blank"</li>
+		 *  <li>"_parent"</li>
+		 *  <li>"_top"</li>
+         * </ul>
+		 * <p>In browser-hosted runtimes, a target of "_self" replaces the current html page.  
+		 * So, if the SWF content containing the link is in a page within
+		 * a frame or frameset, the linked content loads within that frame.  If the page 
+		 * is at the top level, the linked content opens to replace the original page.  
+		 * A target of "_blank" opens a new browser window with no name.  
+		 * A target of "_parent" replaces the parent of the html page containing the SWF content.  
+		 * A target of "_top" replaces the top-level page in the current browser window.</p>
+		 * 
+		 * <p>In other runtimes, such as Adobe AIR, the link opens in the user's default browser and the
+		 * <code>target</code> parameter is ignored.</p>
+		 * 
+		 * <p>The <code>extendToLinkBoundary</code> parameter determines how the edit manager 
+		 * treats a selection that intersects with one or more existing links. If the parameter is 
+		 * <code>true</code>, then the operation is applied as a unit to the selection and the
+		 * whole text of the existing links. Thus, a single link is created that spans from
+		 * the beginning of the first link intersected to the end of the last link intersected.
+		 * In contrast, if <code>extendToLinkBoundary</code> were <code>false</code> in this situation, 
+		 * the existing partially selected links would be split into two links.</p>
+		 *
+		 * @param href The uri referenced by the link.
+		 * @param target The target browser window of the link.
+		 * @param extendToLinkBoundary Specifies whether to consolidate selection with any overlapping existing links, and then apply the change.
+		 * @param operationState	specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @includeExample examples\EditManager_applyLink.as -noswf
+		 * @see flashx.textLayout.elements.LinkElement
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */			
+		function applyLink(href:String, target:String=null, extendToLinkBoundary:Boolean=false, operationState:SelectionState = null):void;
+		
+		/**
+		* Changes the ID of an element.
+		* 
+		 * <p>If the <code>relativeStart</code> or <code>relativeEnd</code> parameters are set (to
+		 * anything other than the default values), then the element is split. The parts of the element
+		 * outside this range retain the original ID. Setting both the <code>relativeStart</code> and 
+		 * <code>relativeEnd</code> parameters creates elements with duplicate IDs.</p>
+		 * 
+		* @param newID the new ID value
+		* @param targetElement the element to modify
+		* @param relativeStart an offset from the beginning of the element at which to split the element when assigning the new ID
+		* @param relativeEnd an offset from the end of the element at which to split the element when assigning the new ID
+		* @param operationState	specifies the selection to restore when undoing this operation; 
+		* if <code>null</code>, the operation saves the current selection.
+		* 
+		 * @includeExample examples\EditManager_changeElementID.as -noswf
+		 * 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0 
+	 	*/
+		function changeElementID(newID:String, targetElement:FlowElement, relativeStart:int = 0, relativeEnd:int = -1, operationState:SelectionState = null):void;
+		
+		/**
+		* Changes the styleName of an element or part of an element.
+		 * 
+		 * <p>If the <code>relativeStart</code> or <code>relativeEnd</code> parameters are set (to
+		 * anything other than the default values), then the element is split. The parts of the element
+		 * outside this range retain the original style.</p>
+		 * 
+		* @param newName the name of the new style.
+		* @param targetElement specifies the element to change.
+		* @param relativeStart an offset from the beginning of the element at which to split the element when assigning the new style
+		* @param relativeEnd an offset from the end of the element at which to split the element when assigning the new style
+		* @param operationState	specifies the selection to restore when undoing this operation; 
+		* if <code>null</code>, the operation saves the current selection.
+		* 
+		 * @includeExample examples\EditManager_changeStyleName.as -noswf
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0 
+	 	*/
+		function changeStyleName(newName:String, targetElement:FlowElement, relativeStart:int = 0, relativeEnd:int = -1, operationState:SelectionState = null):void;
+
+		/** 
+		 * Deletes a range of text, or, if a point selection is given, deletes the next character.
+		 * 
+		 * @param operationState	specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @includeExample examples\EditManager_deleteNextCharacter.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function deleteNextCharacter(operationState:SelectionState = null):void;
+		
+		/** 
+		 * Deletes a range of text, or, if a point selection is given, deletes the previous character.
+		 * 
+		 * @param operationState	specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @includeExample examples\EditManager_deletePreviousCharacter.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function deletePreviousCharacter(operationState:SelectionState = null):void;
+		
+		/** 
+		 * Deletes the next word.
+		 * 
+		 * <p>If a range is selected, the first word of the range is deleted.</p>
+		 * 
+		 * @param operationState specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @includeExample examples\EditManager_deleteNextWord.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */		
+		function deleteNextWord(operationState:SelectionState = null):void;
+		
+		/** 
+		 * Deletes the previous word.
+		 * 
+		 * <p>If a range is selected, the first word of the range is deleted.</p>
+		 * 
+		 * @param operationState	specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @includeExample examples\EditManager_deletePreviousWord.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */		
+		function deletePreviousWord(operationState:SelectionState = null):void;		
+		
+		/** 
+		 * Deletes a range of text.
+		 * 
+		 * @param operationState	specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @includeExample examples\EditManager_deleteText.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function deleteText(operationState:SelectionState = null):void
+
+		/** 
+		 * Inserts an image.
+		 * 
+		 * <p>The source of the image can be a string containing a URI, URLRequest object, a Class object representing an embedded asset,
+		 * or a DisplayObject instance.</p>
+		 *  
+		 * <p>The width and height values can be the number of pixels, a percent, or the string, 'auto', 
+		 * in which case the actual dimension of the graphic is used.</p>
+		 * 
+		 * <p>Set the <code>float</code> to one of the constants defined in the Float class to specify whether
+		 * the image should be displayed to the left or right of any text or inline with the text.</p>
+		 * 
+		 *	@param	source	can be either a String interpreted as a uri, a Class interpreted as the class of an Embed DisplayObject, 
+		 * 					a DisplayObject instance or a URLRequest. 
+		 *	@param	width	width of the image to insert (number, percent, or 'auto')
+		 *	@param	height	height of the image to insert (number, percent, or 'auto')
+		 *	@param	options	none supported.
+		 * @param operationState	specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @includeExample examples\EditManager_insertInlineGraphic.as -noswf
+		 * 
+		 * @see flashx.textLayout.elements.InlineGraphicElement
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 		 */			
+		function insertInlineGraphic(source:Object, width:Object, height:Object, options:Object = null, operationState:SelectionState = null):void;
+		
+		/** 
+		 * Modifies an existing inline graphic.
+		 * 
+		 * <p>Set unchanging properties to the values in the original graphic. (Modifying an existing graphic object
+		 * is typically more efficient than deleting and recreating one.)</p>
+		 * 
+		 *	@param	source	can be either a String interpreted as a uri, a Class interpreted as the class of an Embed DisplayObject, 
+		 * 					a DisplayObject instance or a URLRequest. 
+		 *	@param	width	new width for the image (number or percent)
+		 *	@param	height	new height for the image (number or percent)
+		 *	@param	options	none supported
+		 * @param operationState	specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @includeExample examples\EditManager_modifyInlineGraphic.as -noswf
+		 * 
+		 *  @see flashx.textLayout.elements.InlineGraphicElement
+		 * 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */			
+		function modifyInlineGraphic(source:Object, width:Object, height:Object, options:Object = null, operationState:SelectionState = null):void;
+
+		/** 
+		 * Inserts text.
+		 * 
+		 * <p>Inserts the text at a position or range in the text. If the location supplied in the 
+		 * <code>operationState</code> parameter is a range (or the parameter is <code>null</code> and the
+		 * current selection is a range), then the text currently in the range 
+		 * is replaced by the inserted text.</p>
+		 * 
+		 * @param	text		the string to insert
+		 * @param operationState	specifies the text in the flow to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @includeExample examples\EditManager_insertText.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */	
+		function insertText(text:String, operationState:SelectionState = null):void;
+		
+		/** 
+		 * Overwrites the selected text.
+		 * 
+		 * <p>If the selection is a point selection, the first character is overwritten by the new text.</p>
+		 * 
+		 * @param text the string to insert
+		 * @param operationState specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @includeExample examples\EditManager_overwriteText.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */	
+		function overwriteText(text:String, operationState:SelectionState = null):void;
+
+		/** 
+		 * Applies paragraph styles to any paragraphs in the selection.
+		 * 
+		 * <p>Any style properties in the format object that are <code>null</code> are left unchanged.</p> 
+		 * 
+ 	 	 * @param format the format to apply to the selected paragraphs.
+		 * @param operationState	specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @includeExample examples\EditManager_applyParagraphFormat.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 		 */		
+		function applyParagraphFormat(format:ITextLayoutFormat, operationState:SelectionState = null):void;
+
+		/** 
+		 * Applies container styles to any containers in the selection.
+		 * 
+		 * <p>Any style properties in the format object that are <code>null</code> are left unchanged.</p> 
+		 * 
+		 * @param format	the format to apply to the containers in the range
+		 * @param operationState	specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @includeExample examples\EditManager_applyContainerFormat.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */		
+		function applyContainerFormat(format:ITextLayoutFormat, operationState:SelectionState = null):void;
+		
+		/** 
+		 * Applies styles to the specified element.
+		 * 
+		 * <p>Any style properties in the format object that are <code>null</code> are left unchanged.
+		 * Only styles that are relevant to the specified element are applied.</p> 
+		 * 
+		 * @param 	targetElement the element to which the styles are applied.
+		 * @param	format	the format containing the styles to apply
+		 * @param operationState	specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @includeExample examples\EditManager_applyFormatToElement.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */	
+		function applyFormatToElement(targetElement:FlowElement, format:ITextLayoutFormat, operationState:SelectionState = null):void;
+		
+		/** 
+		 * Undefines styles to the specified element.
+		 * 
+		 * <p>Any style properties in the format object that are <code>undefined</code> are left unchanged.
+		 * Any styles that are defined in the specififed format are undefined on the specified element.</p> 
+		 * 
+		 * @param 	targetElement the element to which the styles are applied.
+		 * @param	format	the format containing the styles to undefine
+		 * @param operationState	specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */	
+		function clearFormatOnElement(targetElement:FlowElement, format:ITextLayoutFormat, operationState:SelectionState = null):void;
+		
+		/** 
+		 * Splits the paragraph at the current position.
+		 *   
+		 * <p>If a range of text is specified, the text 
+		 * in the range is deleted.</p>
+		 * 
+		 * @param operationState	specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @includeExample examples\EditManager_splitParagraph.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function splitParagraph(operationState:SelectionState = null):void;
+		
+		/** 
+		 * Deletes the selected area and returns the deleted area in a TextScrap object. 
+		 * 
+		 * <p>The resulting TextScrap can be posted to the system clipboard or used in a 
+		 * subsequent <code>pasteTextOperation()</code> operation.</p>
+		 * 
+		 * @param operationState	specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * @return the TextScrap that was cut
+		 * 
+		 * @includeExample examples\EditManager_cutTextScrap.as -noswf
+		 * 
+		 * @see flashx.textLayout.edit.IEditManager.pasteTextScrap
+		 * @see flashx.textLayout.edit.TextClipboard.setContents
+		 *  
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		function cutTextScrap(operationState:SelectionState = null):TextScrap;
+		
+		/** 
+		 * Pastes the TextScrap into the selected area.
+		 * 
+		 * <p>If a range of text is specified, the text 
+		 * in the range is deleted.</p>
+		 * 
+		 * @param scrapToPaste	the TextScrap to paste
+		 * @param operationState	specifies the text to which this operation applies; 
+		 * if <code>null</code>, the operation applies to the current selection.
+		 * 
+		 * @includeExample examples\EditManager_pasteTextScrap.as -noswf
+		 * 
+		 * @see flashx.textLayout.edit.IEditManager.cutTextScrap
+		 * @see flashx.textLayout.edit.TextClipboard.getContents
+		 * @see flashx.textLayout.edit.TextScrap
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */
+		 function pasteTextScrap(scrapToPaste:TextScrap, operationState:SelectionState = null):void;		
+
+		/** 
+		 * Begins a new group of operations. 
+		 * 
+		 * <p>All operations executed after the call to <code>beginCompositeOperation()</code>, and before the 
+		 * matching call to <code>endCompositeOperation()</code> are executed and grouped together as a single 
+		 * operation that can be undone as a unit.</p> 
+		 * 
+		 * <p>A <code>beginCompositeOperation</code>/<code>endCompositeOperation</code> block can be nested inside another 
+		 * <code>beginCompositeOperation</code>/<code>endCompositeOperation</code> block.</p>
+		 * 
+		 * @includeExample examples\EditManager_beginCompositeOperation.as -noswf
+		 * 
+		 * @see flashx.textLayout.edit.IEditManager.endCompositeOperation
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function beginCompositeOperation():void;
+		
+		/** 
+		 * Ends a group of operations. 
+		 * 
+		 * <p>All operations executed since the last call to <code>beginCompositeOperation()</code> are 
+		 * grouped as a CompositeOperation that is then completed. This CompositeOperation object is added 
+		 * to the undo stack or, if this composite operation is nested inside another composite operation, 
+		 * added to the parent operation.</p>
+		 * 
+		 * @see flashx.textLayout.edit.IEditManager.beginCompositeOperation
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function endCompositeOperation():void;
+
+		/** 
+		 * Executes a FlowOperation.  
+		  * 
+		  * <p>The <code>doOperation()</code> method is called by IEditManager functions that 
+		  * update the text flow. You do not typically need to call this function directly unless 
+		  * you create your own custom operations.</p>
+		  * 
+		  * <p>This function proceeds in the following steps:</p>
+		  * <ol>
+		  * <li>Flush any pending operations before performing this operation.</li>
+		  * <li>Send a cancelable flowOperationBegin event.  If canceled this method returns immediately.</li>
+		  * <li>Execute the operation.  The operation returns <code>true</code> or <code>false</code>.  
+		  * <code>False</code> indicates that no changes were made.</li>
+		  * <li>Push the operation onto the undo stack.</li>
+		  * <li>Clear the redo stack.</li>
+		  * <li>Update the display.</li>
+		  * <li>Send a cancelable flowOperationEnd event.</li>
+		  * </ol>
+		  * <p>Exception handling:  If the operation throws an exception, it is caught and the error is 
+		  * attached to the flowOperationEnd event.  If the event is not canceled the error is rethrown.</p>
+		  * 
+		  * @param operation a FlowOperation object
+		  * 
+		  * @includeExample examples\EditManager_doOperation.as -noswf
+		  * 
+		  * @playerversion Flash 10
+		  * @playerversion AIR 1.5
+ 	 	  * @langversion 3.0
+		  */
+		function doOperation(operation:FlowOperation):void;
+
+		/** 
+		 * Reverses the previous operation. 
+		 * 
+		 * <p><b>Note:</b> If the IUndoManager associated with this IEditManager is also associated with 
+		 * another IEditManager, then it is possible that the undo operation associated with the other 
+		 * IEditManager is the one undone.  This can happen if the FlowOperation of another IEditManager 
+		 * is on top of the undo stack.</p>  
+		 * 
+		 * <p>This function does nothing if undo is not turned on.</p>
+		 * 
+		 * @includeExample examples\EditManager_undo.as -noswf
+		 * 
+		 * @see flashx.undo.IUndoManager#undo()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function undo():void;
+
+		/** 
+		 * Reperforms the previous undone operation.
+		 * 
+		 * <p><b>Note:</b> If the IUndoManager associated with this IEditManager is also associated with 
+		 * another IEditManager, then it is possible that the redo operation associated with the other 
+		 * IEditManager is the one redone. This can happen if the FlowOperation of another IEditManager 
+		 * is on top of the redo stack.</p>  
+		 * 
+		 * <p>This function does nothing if undo is not turned on.</p>
+		 * 
+		 * @includeExample examples\EditManager_redo.as -noswf
+		 * 
+		 * @see flashx.undo.IUndoManager#redo()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function redo():void;
+		
+		/** @private */
+		function performUndo(operation:IOperation):void;
+
+		/** @private */
+		function performRedo(operation:IOperation):void;
+	}
+}
diff --git a/textLayout_edit/src/flashx/textLayout/edit/IMEClient.as b/textLayout_edit/src/flashx/textLayout/edit/IMEClient.as
new file mode 100755
index 0000000..b165d1d
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/edit/IMEClient.as
@@ -0,0 +1,376 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.edit {
+	import flash.geom.Point;
+	import flash.geom.Rectangle;
+	import flash.system.IME;
+	import flash.text.engine.TextLine;
+	import flash.text.ime.CompositionAttributeRange;
+	import flash.text.ime.IIMEClient;
+	
+	import flashx.textLayout.compose.IFlowComposer;
+	import flashx.textLayout.compose.TextFlowLine;
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.elements.TextRange;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.formats.IMEStatus;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.operations.ApplyElementUserStyleOperation;
+	import flashx.textLayout.operations.InsertTextOperation;
+	import flashx.textLayout.tlf_internal;
+	import flashx.textLayout.utils.GeometryUtil;
+	import flashx.undo.IOperation;
+	import flashx.undo.UndoManager;
+	
+	use namespace tlf_internal;
+
+	internal class IMEClient implements IIMEClient
+	{
+		private var _editManager:EditManager;
+		private var _undoManager:UndoManager;
+
+		/** Maintain position of text we've inserted while in the middle of processing IME. */
+		private var _imeAnchorPosition:int;		// start of IME text
+		private var _imeLength:int;				// length of IME text
+		private var _controller:ContainerController;		// controller that had focus at the start of the IME session -- we want this one to keep focus
+		private var _closing:Boolean;
+		CONFIG::debug { 
+			private var _imeOperation:IOperation; 	// IME in-progress edits - used for debugging to confirm that operation we're undoing is the one we did via IME
+		}
+		
+		public function IMEClient(editManager:EditManager)
+		{
+			_editManager = editManager;
+			_imeAnchorPosition = _editManager.absoluteStart;
+			if (_editManager.textFlow)
+			{
+				var flowComposer:IFlowComposer = _editManager.textFlow.flowComposer;
+				if (flowComposer) 
+				{
+					var controllerIndex:int = flowComposer.findControllerIndexAtPosition(_imeAnchorPosition);
+					_controller = flowComposer.getControllerAt(controllerIndex);
+					if (_controller)
+						_controller.setFocus();
+				}
+			}
+			_closing = false;
+			if (_editManager.undoManager == null)
+			{
+				_undoManager = new UndoManager();
+				_editManager.setUndoManager(_undoManager);
+			}
+		}
+		
+		/** @private
+		 * Handler function called when the selection has been changed.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function selectionChanged():void
+		{	
+		//	trace("IMEClient.selectionChanged", _editManager.anchorPosition, _editManager.activePosition);
+			
+			// If we change the selection to something outside the session, abort the 
+			// session. If we just moved the selection within the session, we tell the IME about the changes.
+			if (_editManager.absoluteStart > _imeAnchorPosition + _imeLength || _editManager.absoluteEnd < _imeAnchorPosition)
+			{
+				//trace("selection changed to out of IME session");
+				compositionAbandoned();
+			}
+			else 
+			{
+				// This code doesn't with current version of Argo, but should work in future
+				//trace("selection changed within IME session");
+			//	var imeCompositionSelectionChanged:Function = IME["compositionSelectionChanged"];
+			//	if (IME["compositionSelectionChanged"] !== undefined)
+			 //		imeCompositionSelectionChanged(_editManager.absoluteStart - _imeAnchorPosition, _editManager.absoluteEnd - (_imeAnchorPosition + _imeLength));
+			}
+		}
+
+		private function doIMEClauseOperation(selState:SelectionState, clause:int):void
+		{
+ 		    var leaf:FlowLeafElement = _editManager.textFlow.findLeaf(selState.absoluteStart);;
+		    var leafAbsoluteStart:int = leaf.getAbsoluteStart();
+			_editManager.doOperation(new ApplyElementUserStyleOperation(selState, leaf, IMEStatus.IME_CLAUSE, clause.toString(), selState.absoluteStart - leafAbsoluteStart, selState.absoluteEnd - leafAbsoluteStart));
+		}
+		
+		private function doIMEStatusOperation(selState:SelectionState, attrRange:CompositionAttributeRange):void
+		{
+			var imeStatus:String;
+			
+			// Get the IME status from the converted & selected flags
+			if (attrRange == null)
+				imeStatus = IMEStatus.DEAD_KEY_INPUT_STATE;
+    		else if (!attrRange.converted)
+    		{
+    			if(!attrRange.selected)
+    				imeStatus = IMEStatus.NOT_SELECTED_RAW;
+    			else
+    				imeStatus = IMEStatus.SELECTED_RAW;
+    		}
+    		else
+    		{
+    			if (!attrRange.selected)
+    				imeStatus = IMEStatus.NOT_SELECTED_CONVERTED;
+    			else
+    				imeStatus = IMEStatus.SELECTED_CONVERTED;
+    		}
+
+
+			// refind since the previous operation changed the spans
+    		var leaf:FlowLeafElement = _editManager.textFlow.findLeaf(selState.absoluteStart);
+			CONFIG::debug { assert(	leaf != null, "found null FlowLeafELement at" + (selState.absoluteStart).toString()); }						    		
+    		var leafAbsoluteStart:int = leaf.getAbsoluteStart();
+
+			_editManager.doOperation(new ApplyElementUserStyleOperation(selState, leaf, IMEStatus.IME_STATUS, imeStatus, selState.absoluteStart - leafAbsoluteStart, selState.absoluteEnd - leafAbsoluteStart));
+		}
+		
+		// IME-related functions
+		public function updateComposition(text:String, attributes:Vector.<CompositionAttributeRange>, compositionStartIndex:int, compositionEndIndex:int):void
+	    {
+		//	CONFIG::debug { Debugging.traceOut("updateComposition ", compositionStartIndex, compositionEndIndex, text.length); }
+		//	CONFIG::debug { Debugging.traceOut("updateComposition selection ", _editManager.absoluteStart, _editManager.absoluteEnd); }
+			
+			// Undo the previous interim ime operation, if there is one. This deletes any text that came in a previous updateComposition call.
+			// Doing it via undo keeps the undo stack in sync.
+			if (_imeLength > 0 && _editManager.undoManager.peekUndo() != null)
+			{
+				CONFIG::debug { assert(_editManager.undoManager.peekUndo() == _imeOperation, "Unexpected operation in undo stack at end of IME update"); }
+				if (_editManager.undoManager)
+					_editManager.undoManager.undo();
+				_imeLength = 0; // prevent double deletion
+				CONFIG::debug {  _imeOperation = null; }
+			}
+
+			if (text.length > 0)
+			{
+				// Insert the supplied string, using the current editing format.
+				var pointFormat:ITextLayoutFormat = _editManager.getSelectionState().pointFormat;
+				var selState:SelectionState = new SelectionState(_editManager.textFlow, _imeAnchorPosition, _imeAnchorPosition + _imeLength, pointFormat);
+				
+				_editManager.beginIMEOperation();
+				
+				if (_editManager.absoluteStart != _editManager.absoluteEnd)
+					_editManager.deleteText();		// delete current selection
+				
+				var insertOp:InsertTextOperation = new InsertTextOperation(selState, text);
+				_imeLength = text.length;
+				_editManager.doOperation(insertOp);
+				
+				if (attributes && attributes.length > 0)
+				{
+					var attrLen:int = attributes.length;
+					for (var i:int = 0; i < attrLen; i++)
+					{
+						var attrRange:CompositionAttributeRange = attributes[i];
+						var clauseSelState:SelectionState = new SelectionState(_editManager.textFlow, _imeAnchorPosition + attrRange.relativeStart, _imeAnchorPosition + attrRange.relativeEnd);
+						
+						doIMEClauseOperation(clauseSelState, i);
+						doIMEStatusOperation(clauseSelState, attrRange);
+					}
+				}
+				else // composing accented characters
+				{	
+					clauseSelState = new SelectionState(_editManager.textFlow, _imeAnchorPosition, _imeAnchorPosition + _imeLength, pointFormat);
+					doIMEClauseOperation(clauseSelState, 0);
+					doIMEStatusOperation(clauseSelState, null);
+				}
+				
+				var newSelectionStart:int = _imeAnchorPosition + compositionStartIndex;
+				var newSelectionEnd:int = _imeAnchorPosition + compositionEndIndex;
+				if (_editManager.absoluteStart != newSelectionStart || _editManager.absoluteEnd != newSelectionEnd)
+				{
+					_editManager.selectRange(_imeAnchorPosition + compositionStartIndex, _imeAnchorPosition + compositionEndIndex);
+				}
+
+				CONFIG::debug {  _imeOperation = null; }
+				_editManager.endIMEOperation();	
+				CONFIG::debug {  _imeOperation = _editManager.undoManager.peekUndo(); }
+			}
+	    }
+	    
+	    public function confirmComposition(text:String = null, preserveSelection:Boolean = false):void
+		{
+		//	trace("confirmComposition", text, preserveSelection);
+			endIMESession();
+		}
+		
+		public function compositionAbandoned():void
+		{
+		//	trace("compositionAbandoned");
+
+			// In Argo we could just do this:
+			// IME.compositionAbandoned();
+			// but for support in Astro/Squirt where this API is undefined we do this:
+			var imeCompositionAbandoned:Function = IME["compositionAbandoned"];
+			if (IME["compositionAbandoned"] !== undefined)
+				imeCompositionAbandoned();
+		}
+		
+		private function endIMESession():void
+		{
+			if (!_editManager || _closing)
+				return;
+			
+			_closing = true;
+			
+			// Undo the IME operation. We're going to re-add the text, without all the special attributes, as part of handling
+			// the textInput event that comes next.
+			if (_imeLength > 0)
+			{
+				if (_editManager.undoManager.peekUndo() != null)
+				{
+					//trace("undoing imeOperation at end of IME session");
+					CONFIG::debug { assert(_editManager.undoManager.peekUndo() == _imeOperation, "Unexpected operation in undo stack at end of IME session"); }
+					if (_editManager.undoManager)
+						_editManager.undoManager.undo();
+					CONFIG::debug { assert(_editManager.undoManager.peekRedo() == _imeOperation, "Unexpected operation in redo stack at end of IME session"); }
+					_editManager.undoManager.popRedo();
+				}
+			}
+
+			if (_undoManager)
+				_editManager.setUndoManager(null);
+
+			// Clear IME state - tell EditManager to release IMEClient to finally close session
+			_editManager.endIMESession();
+			_editManager = null;
+		}
+		
+		public function getTextBounds(startIndex:int, endIndex:int):Rectangle
+		{
+			if(startIndex >= 0 && startIndex < _editManager.textFlow.textLength && endIndex >= 0 && endIndex < _editManager.textFlow.textLength)
+			{
+				if (startIndex != endIndex)
+				{
+					var boundsResult:Array = GeometryUtil.getHighlightBounds(new TextRange(_editManager.textFlow, startIndex, endIndex));
+				    //bail out if we don't have any results to show
+					if (boundsResult.length > 0)
+					{
+						var bounds:Rectangle = boundsResult[0].rect; 
+					    var textLine:TextLine = boundsResult[0].textLine; 
+					    var resultTopLeft:Point = textLine.localToGlobal(bounds.topLeft);
+					    var resultBottomRight:Point = textLine.localToGlobal(bounds.bottomRight);
+						if (textLine.parent)
+						{
+							var containerTopLeft:Point = textLine.parent.globalToLocal(resultTopLeft);
+							var containerBottomLeft:Point = textLine.parent.globalToLocal(resultBottomRight);
+							return new Rectangle(containerTopLeft.x, containerTopLeft.y, containerBottomLeft.x - containerTopLeft.x, containerBottomLeft.y - containerTopLeft.y);
+						}
+					}
+				}
+				else
+				{
+					var flowComposer:IFlowComposer = _editManager.textFlow.flowComposer;
+					var lineIndex:int = flowComposer.findLineIndexAtPosition(startIndex);
+	
+					// Stick to the end of the last line
+					if (lineIndex == flowComposer.numLines)
+						lineIndex--;
+					if (flowComposer.getLineAt(lineIndex).controller == _controller)
+					{
+						var line:TextFlowLine = flowComposer.getLineAt(lineIndex);
+						var previousLine:TextFlowLine = lineIndex != 0 ? flowComposer.getLineAt(lineIndex-1) : null;
+						var nextLine:TextFlowLine = lineIndex != flowComposer.numLines-1 ? flowComposer.getLineAt(lineIndex+1) : null;
+						return line.computePointSelectionRectangle(startIndex, _controller.container, previousLine, nextLine, true);
+					}
+				}
+			}
+			
+			return new Rectangle(0,0,0,0);
+		}
+		
+		public function get compositionStartIndex():int
+		{
+		//	trace("compositionStartIndex");
+			return _imeAnchorPosition;
+		}
+		
+		public function get compositionEndIndex():int
+		{
+		//	trace("compositionEndIndex");
+			return _imeAnchorPosition + _imeLength;
+		}
+		
+		public function get verticalTextLayout():Boolean
+		{
+		//	trace("verticalTextLayout");
+			return _editManager.textFlow.computedFormat.blockProgression == BlockProgression.RL;
+		}
+
+		public function get selectionActiveIndex():int
+		{
+			//trace("selectionActiveIndex");
+			return _editManager.activePosition;
+		}
+		
+		public function get selectionAnchorIndex():int
+		{
+			//trace("selectionAnchorIndex");
+			return _editManager.anchorPosition;
+		}
+		
+		public function selectRange(anchorIndex:int, activeIndex:int):void
+		{
+			_editManager.selectRange(anchorIndex, activeIndex);
+		}
+
+		public function setFocus():void
+		{
+			if (_controller && _controller.container && _controller.container.stage && _controller.container.stage.focus != _controller.container)
+				_controller.setFocus();
+		}
+		
+		/** 
+		 * Gets the specified range of text from a component implementing ITextSupport.
+		 * To retrieve all text in the component, do not specify values for <code>startIndex</code> and <code>endIndex</code>.
+		 * Components which wish to support inline IME or web searchability should call into this method.
+		 * Components overriding this method should ensure that the default values of <code>-1</code> 
+		 * for <code>startIndex</code> and <code>endIndex</code> are supported.
+		 * 
+		 * @playerversion Flash 10.0
+		 * @langversion 3.0
+		 */
+		public function getTextInRange(startIndex:int, endIndex:int):String
+		{
+			//trace("getTextInRange");
+			// Check for valid indices
+			var textFlow:TextFlow = _editManager.textFlow;
+			if (startIndex < -1 || endIndex < -1 || startIndex > (textFlow.textLength - 1) || endIndex > (textFlow.textLength - 1))
+				return null;
+			
+			// Make sure they're in the right order
+			if (endIndex < startIndex)
+			{
+				var tempIndex:int = endIndex;
+				endIndex = startIndex;
+				startIndex = tempIndex;
+			}
+			
+			if (startIndex == -1)
+				startIndex = 0;
+			
+			return textFlow.getText(startIndex, endIndex);
+		} 
+	}
+}
\ No newline at end of file
diff --git a/textLayout_edit/src/flashx/textLayout/edit/Mark.as b/textLayout_edit/src/flashx/textLayout/edit/Mark.as
new file mode 100755
index 0000000..8091a7c
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/edit/Mark.as
@@ -0,0 +1,38 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.edit
+{
+[ExcludeClass]
+
+	/** @private - not ready for prime time */
+	public class Mark
+	{
+		private var _position:int;
+
+		public function Mark(value:int = 0)
+		{
+			_position = value;
+		}
+		
+		public function get position():int
+			{ return _position; }
+		public function set position(value:int):void
+			{ _position = value; }
+	}
+}
\ No newline at end of file
diff --git a/textLayout_edit/src/flashx/textLayout/edit/ParaEdit.as b/textLayout_edit/src/flashx/textLayout/edit/ParaEdit.as
new file mode 100755
index 0000000..9831e90
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/edit/ParaEdit.as
@@ -0,0 +1,653 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.edit
+{
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.InlineGraphicElement;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.SpanElement;
+	import flashx.textLayout.elements.SubParagraphGroupElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.formats.Float;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormatValueHolder;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+
+	[ExcludeClass]
+	/**
+	 * Encapsulates all methods necessary for dynamic editing of a text.  The methods are all static member functions of this class.
+	 * @private - because we can't make it tlf_internal. Used by the operations package 
+	 */
+ 	public class ParaEdit
+	{
+		/**
+		 * Inserts text into specified paragraph
+		 * @param p		ParagraphElement to insert into
+		 * @param paraSelBegIdx	index relative to beginning of the paragraph to insert text
+		 * @param leanBack  at an attribute change boundary are we on the left or the right
+		 * @param text	actual text to insert 
+		 * @param forceIntoLeafGiven	flag to suppress creation of new leaf element during insert (useful for type-to-replace)
+		 */
+		public static function insertText(para:ParagraphElement, elem:FlowLeafElement, paraSelBegIdx:int,insertText:String, forceIntoLeafGiven:Boolean = false):void
+		{
+			if (insertText.length == 0)
+				return;	// error? other sanity checks needed here?
+				
+			var createNewSpan:Boolean = false;
+			var insertParent:FlowGroupElement = elem.parent;
+			
+			var curSPGElement:SubParagraphGroupElement = elem.getParentByType(SubParagraphGroupElement) as SubParagraphGroupElement;
+			while (curSPGElement != null)
+			{
+				var subParInsertionPoint:int = paraSelBegIdx - curSPGElement.getElementRelativeStart(para);
+				if (((subParInsertionPoint == 0) && (!curSPGElement.acceptTextBefore())) ||
+					((!curSPGElement.acceptTextAfter() && (subParInsertionPoint == curSPGElement.textLength || 
+					(subParInsertionPoint == curSPGElement.textLength - 1 && (elem == para.getLastLeaf()))))))
+				{
+					createNewSpan = !forceIntoLeafGiven;
+					insertParent = insertParent.parent;
+					curSPGElement = curSPGElement.getParentByType(SubParagraphGroupElement) as SubParagraphGroupElement;
+				} else {
+					break;
+				}
+			}
+				
+			// adjust the flow so that we are in a span for the insertion
+			if ((!(elem is SpanElement)) || (createNewSpan == true))
+			{
+				var newSpan:SpanElement;	// scratch
+				var insertIdx:int;	// scratch
+				
+				// if were not in a span then we must be at the beginning or end of some other FlowLeafElement.  
+				// go to prev or next and use if it is a span.  add a span if needed.
+				var paraRelativeStart:int = elem.getElementRelativeStart(para);
+				CONFIG::debug{ assert(paraRelativeStart == paraSelBegIdx || paraRelativeStart+elem.textLength == paraSelBegIdx || paraRelativeStart+elem.textLength - 1 == paraSelBegIdx,"selection inside non-SpanElement Leaf"); }
+				if (paraRelativeStart == paraSelBegIdx)
+				{
+					elem = elem.getPreviousLeaf(para);
+					if (!(elem is SpanElement))
+					{
+						newSpan = new SpanElement();
+						if (elem)
+						{
+							newSpan.format = elem.format;
+							insertIdx = insertParent.getChildIndex(elem)+1;
+						}
+						else
+						{
+							newSpan.format = para.getFirstLeaf().format;
+							insertIdx = 0;
+						}
+						insertParent.replaceChildren(insertIdx,insertIdx,newSpan);
+						elem = newSpan;
+					}
+				}
+				else
+				{
+					newSpan = new SpanElement();
+					newSpan.format = elem.format;
+					if(elem.parent == insertParent)
+						insertIdx = insertParent.getChildIndex(elem)+1;
+					else
+						insertIdx = insertParent.getChildIndex(elem.parent)+1;
+						
+					insertParent.replaceChildren(insertIdx,insertIdx,newSpan);
+					elem = newSpan;
+				}
+			}
+			
+			var curSpan:SpanElement = elem as SpanElement;
+			var runInsertionPoint:int;
+			//if we added a new span, then 
+			runInsertionPoint = paraSelBegIdx - curSpan.getElementRelativeStart(para);
+			
+				
+			curSpan.replaceText(runInsertionPoint, runInsertionPoint, insertText);
+		}
+		
+		private static function deleteTextInternal(para:ParagraphElement, paraSelBegIdx:int, totalToDelete:int):void
+		{
+			var composeNode:FlowElement;
+			var curSpan:SpanElement;
+			
+			var curNumToDelete:int;
+			var curSpanDeletePos:int = 0;
+			
+			while (totalToDelete > 0)
+			{
+				composeNode = para.findLeaf(paraSelBegIdx);
+				CONFIG::debug { assert(composeNode is SpanElement,"deleteTextInternal: leaf element is not a span"); }
+								
+				curSpan = composeNode as SpanElement;
+				var curSpanRelativeStart:int = curSpan.getElementRelativeStart(para);
+				curSpanDeletePos = paraSelBegIdx - curSpanRelativeStart;
+				if (paraSelBegIdx > (curSpanRelativeStart + curSpan.textLength))
+				{
+					curNumToDelete = curSpan.textLength;
+				}
+				else
+				{
+					curNumToDelete = (curSpanRelativeStart + curSpan.textLength) - paraSelBegIdx;
+				}
+				
+				if (totalToDelete < curNumToDelete)
+				{
+					curNumToDelete = totalToDelete;
+				}
+				
+				curSpan.replaceText(curSpanDeletePos, curSpanDeletePos + curNumToDelete, "");
+				if (curSpan.textLength == 0)
+				{
+					var delIdx:int = curSpan.parent.getChildIndex(curSpan);
+					curSpan.parent.replaceChildren(delIdx,delIdx+1,null);						
+				}
+				totalToDelete -= curNumToDelete;
+			}			
+		}
+		
+		public static function deleteText(para:ParagraphElement, paraSelBegIdx:int, totalToDelete:int):void
+		{
+			var lastParPos:int = para.textLength - 1;
+			if ((paraSelBegIdx < 0) || (paraSelBegIdx > lastParPos))
+			{
+				//not much we can do. There's nothing to delete in this paragraph
+				return;
+			}
+			
+			if (totalToDelete <= 0)
+			{
+				//can't delete a negative number of characters... just return
+				return;
+			}
+			
+			var endPos:int = paraSelBegIdx + totalToDelete - 1;
+			if (endPos > lastParPos)
+			{
+				endPos = lastParPos;
+				totalToDelete = endPos - paraSelBegIdx + 1
+			}
+			
+			deleteTextInternal(para,paraSelBegIdx,totalToDelete);
+		}
+		
+		/**
+		 * Creates image and inserts it into specified FlowGroupElement
+		 * @param flowBlock	FlowGroupElement to insert image into
+		 * @param flowSelBegIdx	index relative to beginning of the FlowGroupElement to insert image
+		 * @param urlString	the url of image to insert
+		 * @param width	the width of the image
+		 * @param height the height of the image
+		 * @param options none supported
+		 */
+		public static function createImage(flowBlock:FlowGroupElement, flowSelBegIdx:int,source:Object, width:Object, height:Object, options:Object, pointFormat:ITextLayoutFormat):InlineGraphicElement
+		{
+			//first, split the element that we are on
+			var curComposeNode:FlowElement = flowBlock.findLeaf(flowSelBegIdx);
+			var posInCurComposeNode:int = 0;
+			if (curComposeNode != null)
+			{
+				posInCurComposeNode = flowSelBegIdx - curComposeNode.getElementRelativeStart(flowBlock); // curComposeNode.parentRelativeStart;
+			}			
+			
+			if ((curComposeNode != null) && (posInCurComposeNode > 0) && (posInCurComposeNode < curComposeNode.textLength))
+			{
+				//it is a LeafElement, and not position 0. It has to be a Span 
+				(curComposeNode as SpanElement).splitAtPosition(posInCurComposeNode);
+			}
+			
+			//the FlowElement or FlowGroupElement is now split.  Insert the image now.
+			var imgElem:InlineGraphicElement = new InlineGraphicElement();
+			imgElem.height = height;
+			imgElem.width = width;
+			imgElem.float = options ? options.toString() : Float.NONE;
+			
+			var src:Object = source;
+			var embedStr:String = "@Embed";
+			if (src is String && src.length > embedStr.length && src.substr(0, embedStr.length) == embedStr) {
+				// we should be dealing with an embedded asset. They are of the form "url=@Embed(source='path-to-asset')"
+				var searchStr:String = "source=";
+				var index:int = src.indexOf(searchStr, embedStr.length);
+				if (index > 0) {
+					index += searchStr.length;
+					index = src.indexOf("'", index);
+					src = src.substring(index+1, src.indexOf("'", index+1));
+				}
+			}
+			imgElem.source = src;
+			
+			while (curComposeNode && curComposeNode.parent != flowBlock)
+			{
+				curComposeNode = curComposeNode.parent;
+			}
+
+			var elementIdx:int = curComposeNode != null ? flowBlock.getChildIndex(curComposeNode) : flowBlock.numChildren;
+			if (curComposeNode && posInCurComposeNode > 0)
+				elementIdx++;
+			flowBlock.replaceChildren(elementIdx,elementIdx,imgElem);
+			
+			//clone characterFormat from the left OR iff the the first element the right
+			var p:ParagraphElement = imgElem.getParagraph();
+			var attrElem:FlowLeafElement = imgElem.getPreviousLeaf(p);
+			if (!attrElem)
+				attrElem = imgElem.getNextLeaf(p);
+			CONFIG::debug { assert(attrElem != null, "no element to get attributes from"); }
+			
+			if (attrElem.format || pointFormat)
+			{
+				var imageElemFormat:TextLayoutFormat = new TextLayoutFormat(attrElem.format);
+				if (pointFormat)
+					imageElemFormat.apply(pointFormat);
+				imgElem.format = imageElemFormat;
+			}
+			return imgElem;			
+		}		
+		
+		/** Merge changed attributes into this
+		 */
+		static private function splitForChange(span:SpanElement,begIdx:int,rangeLength:int):SpanElement
+		{
+			var startOffset:int = span.getAbsoluteStart();
+			if (begIdx == startOffset && rangeLength == span.textLength)
+				return span;
+				
+			// element must be split into spans
+			var elemToUpdate:SpanElement;
+			var origLength:int = span.textLength;
+			
+			var begRelativeIdx:int = begIdx - startOffset;
+			if (begRelativeIdx > 0)
+			{
+				// We create an initial span to hold the text before the new span, then
+				// a following span for the specified range.
+				elemToUpdate = span.splitAtPosition(begRelativeIdx) as SpanElement;
+				if (begRelativeIdx + rangeLength < origLength)
+					elemToUpdate.splitAtPosition(rangeLength);
+			}
+			else
+			{
+				// The specified range falls at the start of the element, so this span is the 
+				// one that's getting the new format.
+				span.splitAtPosition(rangeLength);
+				elemToUpdate = span;
+			}
+
+			return elemToUpdate;
+		}
+		
+		private static function undefineDefinedFormats(target:TextLayoutFormatValueHolder,undefineFormat:ITextLayoutFormat):void
+		{
+			if (undefineFormat)
+			{
+				// this is fairly rare so this operation is not optimizied
+				for (var prop:String in TextLayoutFormat.description)
+				{
+					if (undefineFormat[prop] !== undefined)
+						target[prop] = undefined;
+				} 
+			}
+		}
+
+		/**
+		 * Apply formatting changes to a range of text in the FlowElement
+		 *
+		 * @param begIdx	text index of first text in span
+		 * @param rangeLength	number of characters to modify
+		 * @param applyFormat		Character Format to apply to content
+		 * @param undefineFormat	Character Format to undefine to content
+		 * @return begIdx + number of actual actual characters modified.
+		 */
+		static private function applyCharacterFormat(leaf:FlowLeafElement, begIdx:int, rangeLength:int, applyFormat:ITextLayoutFormat, undefineFormat:ITextLayoutFormat):int
+		{
+			var newFormat:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder(leaf.format);
+			if (applyFormat)
+				newFormat.apply(applyFormat);
+			undefineDefinedFormats(newFormat,undefineFormat);
+			return setCharacterFormat(leaf, newFormat, begIdx, rangeLength);
+		}
+		
+		/**
+		 * Set formatting to a range of text in the FlowElement
+		 *
+		 * @param format	Character Format to apply to content
+		 * @param begIdx	text index of first text in span
+		 * @param rangeLength	number of characters to modify
+		 * @return starting position of following span
+		 */
+		static private function setCharacterFormat(leaf:FlowLeafElement, format:Object, begIdx:int, rangeLength:int):int
+		{
+			var startOffset:int = leaf.getAbsoluteStart();
+			if (!(format is ITextLayoutFormat) || !TextLayoutFormat.isEqual(ITextLayoutFormat(format),leaf.format))
+			{				
+				var para:ParagraphElement = leaf.getParagraph();
+				var paraStartOffset:int = para.getAbsoluteStart();
+				
+				// clip rangeLength to the length of this span. Extend the rangeLength by one to include the terminator if
+				// it is in the span, and the end of the range abuts the terminator. That way the terminator will stay in the 
+				// last span.
+				var begRelativeIdx:int = begIdx - startOffset;
+				if (begRelativeIdx + rangeLength > leaf.textLength)
+					rangeLength = leaf.textLength - begRelativeIdx;
+				if (begRelativeIdx + rangeLength == leaf.textLength - 1 && (leaf is SpanElement) && SpanElement(leaf).hasParagraphTerminator)
+					++rangeLength;
+				
+				var elemToUpdate:FlowLeafElement
+				if (leaf is SpanElement)
+					elemToUpdate = splitForChange(SpanElement(leaf),begIdx,rangeLength);
+				else
+				{
+					CONFIG::debug { assert(rangeLength >= leaf.textLength,"unable to split non-span leaf"); }
+					elemToUpdate = leaf;
+				}
+				
+				if (format is ITextLayoutFormat)
+					elemToUpdate.format = ITextLayoutFormat(format);
+				else
+					elemToUpdate.setCoreStylesInternal(format);
+				
+				return begIdx+rangeLength;
+			}
+			
+			rangeLength = leaf.textLength;
+			return startOffset+rangeLength;
+		}
+		
+		public static function applyTextStyleChange(flowRoot:TextFlow,begChange:int,endChange:int,applyFormat:ITextLayoutFormat,undefineFormat:ITextLayoutFormat):void
+		{	
+			// TODO: this code only works for span's.  Revisit when new FlowLeafElement types enabled
+			var workIdx:int = begChange;
+			while (workIdx < endChange)
+			{
+				var elem:FlowLeafElement = flowRoot.findLeaf(workIdx);
+				CONFIG::debug  { assert(elem != null,"null FlowLeafElement found"); }
+				workIdx = applyCharacterFormat(elem,workIdx,endChange-workIdx,applyFormat,undefineFormat); 
+			}
+		}
+		
+		// used for undo of operation
+		public static function setTextStyleChange(flowRoot:TextFlow,begChange:int, endChange:int, coreStyle:Object):void
+		{
+			// TODO: this code only works for span's.  Revisit when new FlowLeafElement types enabled
+			var workIdx:int = begChange;
+			while (workIdx < endChange)
+			{
+				var elem:FlowElement = flowRoot.findLeaf(workIdx);
+				CONFIG::debug  { assert(elem != null,"null FlowLeafElement found"); }
+				workIdx = setCharacterFormat(FlowLeafElement(elem),coreStyle,workIdx,endChange-workIdx);
+			}
+		}
+
+		public static function splitParagraph(para:ParagraphElement, paraSplitPos:int, pointFormat:ITextLayoutFormat=null):ParagraphElement
+		{
+			CONFIG::debug { assert(((paraSplitPos >= 0) && (paraSplitPos <= para.textLength - 1)), "Invalid call to ParaEdit.splitParagraph"); }
+
+			var newPar:ParagraphElement;
+			var paraStartAbsolute:int = para.getAbsoluteStart();
+			var absSplitPos:int = paraStartAbsolute + paraSplitPos;
+			
+			if ((paraSplitPos == para.textLength - 1))
+			{
+				newPar = para.shallowCopy() as ParagraphElement;
+				newPar.replaceChildren(0, 0, new SpanElement());
+				var startIdx:int = para.parent.getChildIndex(para);
+				para.parent.replaceChildren(startIdx + 1, startIdx + 1, newPar);
+				if (newPar.textLength == 1)
+				{
+					//we have an empty paragraph.  Make sure that the first
+					//span of this paragraph has the same character attributes
+					//of the last span of this
+
+					var lastSpan:FlowLeafElement = para.getLastLeaf();
+					var prevSpan:FlowLeafElement;
+					if (lastSpan != null && lastSpan.textLength == 1)
+					{
+						//if the lastSpan is only a newline, you really want the span right before
+						var elementIdx:int = lastSpan.parent.getChildIndex(lastSpan);
+						if (elementIdx > 0)
+						{
+							prevSpan = lastSpan.parent.getChildAt(elementIdx - 1) as SpanElement;
+							if (prevSpan != null) lastSpan = prevSpan;
+						}
+					}
+					if (lastSpan != null)
+					{
+						ParaEdit.setTextStyleChange(para.getTextFlow(), absSplitPos + 1, absSplitPos + 2, lastSpan.format);
+					}
+					if (pointFormat != null)
+						ParaEdit.applyTextStyleChange(para.getTextFlow(),absSplitPos + 1, absSplitPos + 2, pointFormat, null);
+				}							
+			}
+			else
+			{
+				newPar = para.splitAtPosition(paraSplitPos) as ParagraphElement;
+			}
+			
+			//you can't have empty paragraphs.  Put the span back
+			// This now handled in normalize()
+			if (para.numChildren == 0)
+			{
+				//If we are injecting a new Span, we need to clone the attributes from 
+				//the newPar's first child.  If we don't, then contents of para will have
+				//no formatting. (2464521)
+				var newFormattedSpan:SpanElement = new SpanElement();
+				newFormattedSpan.quickCloneTextLayoutFormat(newPar.getChildAt(0));
+				para.replaceChildren(0, 0, newFormattedSpan);
+			}
+			
+			return newPar;
+		}
+		
+		// TODO: rewrite this method by moving the elements.  This is buggy.
+		public static function mergeParagraphWithNext(para:ParagraphElement):Boolean
+		{
+			var indexOfPara:int = para.parent.getChildIndex(para);
+			
+			// last can't merge
+			if (indexOfPara == para.parent.numChildren-1)
+				return false;
+				
+			var nextPar:ParagraphElement  = para.parent.getChildAt(indexOfPara + 1) as ParagraphElement;
+			// next is not a paragraph
+			if (nextPar == null)
+				return false;
+				
+			// remove nextPar from its parent - do this first because it will require less updating of starts and lengths
+			para.parent.replaceChildren(indexOfPara+1,indexOfPara+2,null);
+			if (nextPar.textLength <= 1) 
+				return true;
+			
+			// move all the elements
+			while (nextPar.numChildren)
+			{
+				var elem:FlowElement = nextPar.getChildAt(0);
+				nextPar.replaceChildren(0,1,null);
+				para.replaceChildren(para.numChildren,para.numChildren,elem);
+				if ((para.numChildren >  1) && (para.getChildAt(para.numChildren - 2).textLength == 0))
+				{
+					//bug 1658164
+					//imagine that the last element of para is only a kParaTerminator (like a single
+					//span of length 1 that only contains a kParaTerminator, and you merge with the
+					//next paragraph. That kParaTerminator will move, leaving an empty leaf element
+					para.replaceChildren(para.numChildren - 2, para.numChildren - 1, null);
+				}
+			}
+
+			return true;
+		}
+		
+		public static function cacheParagraphStyleInformation(flowRoot:TextFlow,begSel:int,endSel:int,undoArray:Array):void
+		{
+			while (begSel <= endSel && begSel >= 0)
+			{
+				var para:ParagraphElement = flowRoot.findLeaf(begSel).getParagraph();
+				
+				// build an object holding the old style and format
+				var obj:Object = new Object();
+				obj.begIdx = para.getAbsoluteStart();
+				obj.endIdx = obj.begIdx + para.textLength - 1;
+				obj.attributes = para.coreStyles;
+				undoArray.push(obj);
+
+				begSel = obj.begIdx + para.textLength;
+			}
+		}
+
+		/**
+		 * Replace the existing paragraph attributes with the incoming attributes.
+		 * 
+		 * @param flowRoot	text flow where paragraphs are
+		 * @param format	attributes to apply
+		 * @param beginIndex	text index within the first paragraph in the range
+		 * @param endIndex		text index within the last paragraph in the range
+		 */
+		// used for undo of operation
+		public static function setParagraphStyleChange(flowRoot:TextFlow,begChange:int, endChange:int, coreStyles:Object):void
+		{
+			var beginPara:int = begChange;
+			while (beginPara < endChange)
+			{
+				var para:ParagraphElement = flowRoot.findLeaf(beginPara).getParagraph();
+				
+				para.setCoreStylesInternal(coreStyles);
+				beginPara = para.getAbsoluteStart() + para.textLength;
+			}
+		}
+		
+		/**
+		 * Additively apply the paragraph formating attributes to the paragraphs in the specified range.
+		 * Each non-null field in the incoming format is copied into the existing paragraph attributes.
+		 * 
+		 * @param flowRoot	text flow where paragraphs are
+		 * @param format	attributes to apply
+		 * @param beginIndex	text index within the first paragraph in the range
+		 * @param endIndex		text index within the last paragraph in the range
+		 */
+		public static function applyParagraphStyleChange(flowRoot:TextFlow,begChange:int,endChange:int,applyFormat:ITextLayoutFormat,undefineFormat:ITextLayoutFormat):void
+		{	
+			var curIndex:int = begChange;
+			while (curIndex <= endChange)
+			{
+				var para:ParagraphElement = flowRoot.findLeaf(curIndex).getParagraph();
+				
+				// now, need to get the change from "format" and apply to para. We make
+				// a new ParagraphFormat object instead of changing the ParagraphFormat
+				// already in the paragraph so that if the object is shared, other uses
+				// in other paragraphs will not be affected.
+				var newFormat:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder(para.format);
+				if (applyFormat)
+					newFormat.apply(applyFormat);
+				undefineDefinedFormats(newFormat,undefineFormat);
+				para.format = newFormat;
+				
+				curIndex = para.getAbsoluteStart() + para.textLength;
+			}		
+		}
+
+		public static function cacheStyleInformation(flowRoot:TextFlow,begSel:int,endSel:int,undoArray:Array):void
+		{
+			var elem:FlowElement = flowRoot.findLeaf(begSel);
+			var elemLength:int = elem.getAbsoluteStart()+elem.textLength-begSel;
+			var countRemaining:int = endSel - begSel;
+			CONFIG::debug { assert(countRemaining != 0,"cacheStyleInformation called on point selection"); }
+			for (;;)
+			{
+				// build an object holding the old style and format
+				var obj:Object = new Object();
+
+				obj.begIdx = begSel;
+				var objLength:int = Math.min(countRemaining, elemLength);
+				obj.endIdx = begSel + objLength;
+				
+				// save just the styles
+				obj.style = elem.coreStyles;
+				undoArray.push(obj);
+				
+				countRemaining -= Math.min(countRemaining, elemLength);
+				if (countRemaining == 0)
+					break;
+				
+				// advance
+				begSel = obj.endIdx;
+				
+				elem = flowRoot.findLeaf(begSel);
+				elemLength = elem.textLength;
+			}
+		}
+		
+		public static function cacheContainerStyleInformation(flowRoot:TextFlow,begIdx:int,endIdx:int,undoArray:Array):void
+		{
+			CONFIG::debug { assert(begIdx <= endIdx,"bad indexeds passed to ParaEdit.cacheContainerStyleInformation");  }
+			if (flowRoot.flowComposer)
+			{
+				var controllerIndex:int = flowRoot.flowComposer.findControllerIndexAtPosition(begIdx,false);
+				if (controllerIndex >= 0)
+				{
+					while (controllerIndex < flowRoot.flowComposer.numControllers)
+					{
+						var controller:ContainerController = flowRoot.flowComposer.getControllerAt(controllerIndex);
+						if (controller.absoluteStart >= endIdx)
+							break;
+						var obj:Object = new Object();
+						obj.container = controller;
+						// save just the styles
+						obj.attributes = controller.coreStyles;
+						undoArray.push(obj);
+						controllerIndex++;
+					}
+				}
+			}
+		}
+
+		public static function applyContainerStyleChange(flowRoot:TextFlow,begIdx:int,endIdx:int,applyFormat:ITextLayoutFormat,undefineFormat:ITextLayoutFormat):void
+		{
+			CONFIG::debug { assert(begIdx <= endIdx,"bad indexes passed to ParaEdit.cacheContainerStyleInformation");  }
+			if (flowRoot.flowComposer)
+			{
+				var controllerIndex:int = flowRoot.flowComposer.findControllerIndexAtPosition(begIdx,false);
+				if (controllerIndex >= 0)
+				{
+					while (controllerIndex < flowRoot.flowComposer.numControllers)
+					{
+						var controller:ContainerController = flowRoot.flowComposer.getControllerAt(controllerIndex);
+						if (controller.absoluteStart >= endIdx)
+							break;
+						var newFormat:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder(controller.format);
+						if (applyFormat)
+							newFormat.apply(applyFormat);
+						undefineDefinedFormats(newFormat,undefineFormat);
+						controller.format = newFormat;
+						controllerIndex++;
+					}
+				}
+			}
+		}
+
+		/** obj is created by cacheContainerStyleInformation */
+		public static function setContainerStyleChange(flowRoot:TextFlow,obj:Object):void
+		{
+			obj.container.format = obj.attributes as ITextLayoutFormat;
+		}
+	}
+}
diff --git a/textLayout_edit/src/flashx/textLayout/edit/SelectionFormatState.as b/textLayout_edit/src/flashx/textLayout/edit/SelectionFormatState.as
new file mode 100755
index 0000000..6129843
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/edit/SelectionFormatState.as
@@ -0,0 +1,38 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.edit
+{
+	[ExcludeClass]
+	/**
+	 *  Values for the selection background state
+	 *
+	 *  @see text.edit.SelectionFormat
+	 */
+ 	public final class SelectionFormatState 
+ 	{
+		/** default selection format state */
+    	public static const FOCUSED:String = "focused";
+    
+		/** selection state when selection doesn't have focus */    
+    	public static const UNFOCUSED:String = "unfocused";
+    
+		/** selection state when SelectionManager is inactive */        
+    	public static const INACTIVE:String = "inactive";
+	}
+}
diff --git a/textLayout_edit/src/flashx/textLayout/edit/SelectionManager.as b/textLayout_edit/src/flashx/textLayout/edit/SelectionManager.as
new file mode 100755
index 0000000..7eb003f
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/edit/SelectionManager.as
@@ -0,0 +1,2043 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.edit
+{
+	import flash.desktop.Clipboard;
+	import flash.desktop.ClipboardFormats;
+	import flash.display.DisplayObject;
+	import flash.display.InteractiveObject;
+	import flash.display.Stage;
+	import flash.errors.IllegalOperationError;
+	import flash.events.ContextMenuEvent;
+	import flash.events.Event;
+	import flash.events.FocusEvent;
+	import flash.events.IMEEvent;
+	import flash.events.KeyboardEvent;
+	import flash.events.MouseEvent;
+	import flash.events.TextEvent;
+	import flash.geom.Point;
+	import flash.geom.Rectangle;
+	import flash.text.engine.TextLine;
+	import flash.text.engine.TextLineValidity;
+	import flash.text.engine.TextRotation;
+	import flash.ui.ContextMenu;
+	import flash.ui.Keyboard;
+	import flash.ui.Mouse;
+	import flash.ui.MouseCursor;
+	import flash.utils.getQualifiedClassName;
+	
+	import flashx.textLayout.compose.TextFlowLine;
+	import flashx.textLayout.container.ColumnState;
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.debug.Debugging;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.GlobalSettings;
+	import flashx.textLayout.elements.InlineGraphicElement;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.elements.TextRange;
+	import flashx.textLayout.events.FlowOperationEvent;
+	import flashx.textLayout.events.SelectionEvent;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.formats.Category;
+	import flashx.textLayout.formats.Direction;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.operations.CopyOperation;
+	import flashx.textLayout.operations.FlowOperation;
+	import flashx.textLayout.property.Property;
+	import flashx.textLayout.tlf_internal;
+	import flashx.textLayout.utils.NavigationUtil;
+	
+	use namespace tlf_internal;
+	
+	/** 
+	 * The SelectionManager class manages text selection in a text flow.
+	 * 
+	 * <p>The selection manager keeps track of the selected text range, manages its formatting, 
+	 * and can handle events affecting the selection. To allow a user to make selections in
+	 * a text flow, assign a SelectionManager object to the <code>interactionManager</code>
+	 * property of the flow. (To allow editing, assign an instance of the EditManager class,
+	 * which extends SelectionManager.)</p>
+	 *
+	 * <p>The following table describes how the SelectionManager class handles keyboard shortcuts:</p>
+	 *
+	 * <table class="innertable" width="100%">
+	 * <thead>
+	 * <tr><th></th><th></th><th align = "center">TB,LTR</th><th align = "right"></th><th></th><th align = "center">TB,RTL</th><th></th><th></th><th align = "center">TL,LTR</th><th></th><th></th><th align = "center">RL,RTL</th><th></th></tr>
+	 * <tr><th></th><th>none</th><th>ctrl</th><th>alt|ctrl+alt</th><th>none</th><th>ctrl</th><th>alt|ctrl+alt</th><th>none</th><th>ctrl</th><th>alt|ctrl+alt</th><th>none</th><th>ctrl</th><th>alt|ctrl+alt</th></tr>
+	 * </thead>
+	 * <tr><td>leftarrow</td><td>previousCharacter</td><td>previousWord</td><td>previousWord</td><td>nextCharacter</td><td>nextWord</td><td>nextWord</td><td>nextLine</td><td>endOfDocument</td><td>endOfParagraph</td><td>nextLine</td><td>endOfDocument</td><td>endOfParagraph</td></tr>
+	 * <tr><td>uparrow</td><td>previousLine</td><td>startOfDocument</td><td>startOfParagraph</td><td>previousLine</td><td>startOfDocument</td><td>startOfParagraph</td><td>previousCharacter</td><td>previousWord</td><td>previousWord</td><td>nextCharacter</td><td>nextWord</td><td>nextWord</td></tr>
+	 * <tr><td>rightarrow</td><td>nextCharacter</td><td>nextWord</td><td>nextWord</td><td>previousCharacter</td><td>previousWord</td><td>previousWord</td><td>previousLine</td><td>startOfDocument</td><td>startOfParagraph</td><td>previousLine</td><td>startOfDocument</td><td>startOfParagraph</td></tr>
+	 * <tr><td>downarrow</td><td>nextLine</td><td>endOfDocument</td><td>endOfParagraph</td><td>nextLine</td><td>endOfDocument</td><td>endOfParagraph</td><td>nextCharacter</td><td>nextWord</td><td>nextWord</td><td>previousCharacter</td><td>previousWord</td><td>previousWord</td></tr>
+	 * <tr><td>home</td><td>startOfLine</td><td>startOfDocument</td><td>startOfLine</td><td>startOfLine</td><td>startOfDocument</td><td>startOfLine</td><td>startOfLine</td><td>startOfDocument</td><td>startOfLine</td><td>startOfLine</td><td>startOfDocument</td><td>startOfLine</td></tr>
+	 * <tr><td>end</td><td>endOfLine</td><td>endOfDocument</td><td>endOfLine</td><td>endOfLine</td><td>endOfDocument</td><td>endOfLine</td><td>endOfLine</td><td>endOfDocument</td><td>endOfLine</td><td>endOfLine</td><td>endOfDocument</td><td>endOfLine</td></tr>
+	 * <tr><td>pagedown</td><td>nextPage</td><td>nextPage</td><td>nextPage</td><td>nextPage</td><td>nextPage</td><td>nextPage</td><td>nextPage</td><td>nextPage</td><td>nextPage</td><td>nextPage</td><td>nextPage</td><td>nextPage</td></tr>
+	 * <tr><td>pageup</td><td>previousPage</td><td>previousPage</td><td>previousPage</td><td>previousPage</td><td>previousPage</td><td>previousPage</td><td>previousPage</td><td>previousPage</td><td>previousPage</td><td>previousPage</td><td>previousPage</td><td>previousPage</td></tr>
+	 * </table>
+	 *
+	 * <p><strong>Key:</strong>
+	 * <ul>
+	 *	<li>none = no modifier</li>
+	 *	<li>ctrl, shift, alt = modifiers</li>
+	 *	<li>alt-key and ctrl+alt-key are the same on all platforms (on some platforms alt-key does not get to TLF)</li>
+	 *	<li>shift key modifes to extend the active end of the selection in the specified manner</li>			
+	 *	<li>TB (top-to-bottom),RL (right-to-left) are textFlow level <code>blockProgression</code> settings</li>						
+	 * 	<li>LTR (left-to-right),RTL (right-to-left) are textFlow level <code>direction</code> settings</li>					
+	 *	<li>next and prev in logical order in the textFlow - the effect in RTL text is that the selection moves in the physical direction</li>
+	 * </ul></p>
+	 * 
+	 * @see EditManager
+	 * @see flashx.elements.TextFlow
+	 * 
+	 * @includeExample examples\SelectionManager_example.as -noswf
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */
+	public class SelectionManager implements ISelectionManager
+	{		
+		private var _focusedSelectionFormat:SelectionFormat;
+		private var _unfocusedSelectionFormat:SelectionFormat;
+		private var _inactiveSelectionFormat:SelectionFormat;
+		private var _selFormatState:String = SelectionFormatState.UNFOCUSED;
+		private var _isActive:Boolean;
+		
+		/** The TextFlow of the selection. */
+		private var _textFlow:TextFlow;
+		
+		// current range of selection
+		/** Anchor point of the current selection, as an index into the TextFlow. */
+		private var anchorMark:Mark;
+		/** Active end of the current selection, as an index into the TextFlow. */
+		private var activeMark:Mark;
+		
+		// used to save pending attributes at a point selection
+		private var _pointFormat:ITextLayoutFormat;
+		/** 
+		 * The format that will be applied to inserted text. 
+		 * 
+		 * TBD: pointFormat needs to be extended to remember user styles and "undefine" of formats from calls to IEditManager.undefineFormat with leafFormat values on a point selection.
+		 */
+		protected function get pointFormat():ITextLayoutFormat
+		{ return _pointFormat; }
+
+		
+		/** @private
+		 * Ignore the next text input event. This is needed because the player may send a text input event
+		 * following by a key down event when ctrl+key is entered. 
+		 */
+		protected var ignoreNextTextEvent:Boolean = false;
+		
+		/**
+		 *  @private
+		 *  For usability reasons, operations are sometimes grouped (merged) so they 
+		 *  can be undone together. Certain events, such as changing the selection, may make merging 
+		 *  inappropriate. This flag is used to keep track of when operation merging
+		 *  is appropriate.  This might need to be moved to SelectionManager later. I'm keeping it
+		 *  here for now since I'm unsure if other regular selection operations that we add can
+		 *  be undone.
+		 */
+		protected var allowOperationMerge:Boolean = false;
+		
+		private var _mouseOverSelectionArea:Boolean = false;	
+
+		CONFIG::debug 
+		{
+			protected var id:String;
+			static private var smCount:int = 0;
+		}
+		
+		/** 
+		 * 
+		 * Creates a SelectionManager object.
+		 * 
+		 * <p>Assign a SelectionManager object to the <code>interactionManager</code> property of
+		 * a text flow to enable text selection.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function SelectionManager()
+		{
+			_textFlow = null;
+			anchorMark = createMark();
+			activeMark = createMark();
+			_pointFormat = null;
+			_isActive = false;
+			CONFIG::debug 
+			{
+				this.id = smCount.toString();
+				smCount++;
+			}
+		}
+		/**
+		 * @copy ISelectionManager#getSelectionState()
+		 * 
+		 * @includeExample examples\SelectionManager_getSelectionState.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 	 	 * 
+		 * @see flashx.textLayout.edit.SelectionState
+		 */
+		public function getSelectionState():SelectionState
+		{
+			return new SelectionState(_textFlow, anchorMark.position, activeMark.position, pointFormat);
+		}
+				
+		/**
+		 * @copy ISelectionManager#setSelectionState()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 * 
+		 * @see flashx.textLayout.edit.SelectionState
+		 */
+		public function setSelectionState(sel:SelectionState):void
+		{
+			internalSetSelection(sel.textFlow, sel.anchorPosition, sel.activePosition, sel.pointFormat);
+		}
+
+		/**
+		 *  @copy ISelectionManager#hasSelection()
+		 * 
+		 * @includeExample examples\SelectionManager_hasSelection.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function hasSelection():Boolean
+		{ return anchorMark.position != -1; }
+
+		/** 
+		 *  @copy ISelectionManager#isRangeSelection()
+		 * 
+		 * @includeExample examples\SelectionManager_isRangeSelection.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */				
+		public function isRangeSelection():Boolean
+		{ return anchorMark.position != -1 && anchorMark.position != activeMark.position; }
+		
+		/**
+		 * The TextFlow object managed by this selection manager. 
+		 * 
+		 * <p>A selection manager manages a single text flow. A selection manager can also be
+		 * assigned to a text flow by setting the <code>interactionManager</code> property of the
+		 * TextFlow object.</p>
+		 * 
+		 * @see flashx.textLayout.elements.TextFlow#interactionManager
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+ 		 */
+		public function get textFlow():TextFlow
+		{
+			return _textFlow;
+		}
+		public function set textFlow(value:TextFlow):void
+		{
+			if (_textFlow != value)
+			{
+				if (_textFlow)
+					flushPendingOperations();
+				
+				clear();
+				
+				_textFlow = value;
+				
+				if (_textFlow && _textFlow.interactionManager != this)
+					_textFlow.interactionManager = this;
+			}
+		}  
+		
+		/**
+		 *  @copy ISelectionManager#editingMode
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 	 	 * 
+		 * @see flashx.textLayout.edit.EditingMode
+		 */
+		 public function get editingMode():String
+		 {
+		 	return EditingMode.READ_SELECT;
+		 }				 
+		 
+		/** 
+		 *  @copy ISelectionManager#windowActive
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		 public function get windowActive():Boolean
+		 {
+		 	return _selFormatState != SelectionFormatState.INACTIVE;
+		 }
+		 
+		/** 
+		 *  @copy ISelectionManager#focused
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		*/
+		 public function get focused():Boolean
+		 {
+		 	return _selFormatState == SelectionFormatState.FOCUSED;
+		 }
+		 
+		/**
+		 *  @copy ISelectionManager#currentSelectionFormat
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 	 	 * 
+		 * @see flashx.textLayout.edit.SelectionFormat
+		 */
+		 public function get currentSelectionFormat():SelectionFormat
+		 { 
+		 	if (_selFormatState == SelectionFormatState.UNFOCUSED)
+		 	{
+		 		return unfocusedSelectionFormat;
+		 	}
+		 	else if (_selFormatState == SelectionFormatState.INACTIVE)
+		 	{
+		 		return inactiveSelectionFormat;
+		 	}
+		 	return focusedSelectionFormat;
+		 }
+		 
+		/**
+		 *  @copy ISelectionManager#focusedSelectionFormat
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 	 	 * 
+		 * @see flashx.textLayout.edit.SelectionFormat
+		 */
+		 public function set focusedSelectionFormat(val:SelectionFormat):void
+		 { 
+	 		_focusedSelectionFormat = val;
+		 	if (this._selFormatState == SelectionFormatState.FOCUSED)
+		 		refreshSelection();
+		 }
+		 
+		/**
+		 * @private - docs on setter
+		 */
+		 public function get focusedSelectionFormat():SelectionFormat
+		 { 
+		 	return _focusedSelectionFormat ? _focusedSelectionFormat : (_textFlow ? _textFlow.configuration.focusedSelectionFormat : null);
+		 }		 
+
+		/**
+		 *  @copy ISelectionManager#unfocusedSelectionFormat
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 	 	 * 
+		 * @see flashx.textLayout.edit.SelectionFormat
+		 */
+		 public function set unfocusedSelectionFormat(val:SelectionFormat):void
+		 { 
+	 		_unfocusedSelectionFormat = val;
+	 		if (this._selFormatState == SelectionFormatState.UNFOCUSED)
+	 			refreshSelection();
+		 }		 	
+		 
+		/**
+		 *  @private - docs on setter
+		 */
+		 public function get unfocusedSelectionFormat():SelectionFormat
+		 { 
+		 	return _unfocusedSelectionFormat ? _unfocusedSelectionFormat : (_textFlow ? _textFlow.configuration.unfocusedSelectionFormat : null);
+		 }
+		 
+		/**
+		 *  @copy ISelectionManager#inactiveSelectionFormat
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 	 	 * 
+		 * @see flashx.textLayout.edit.SelectionFormat
+		 */
+		 public function set inactiveSelectionFormat(val:SelectionFormat):void
+		 { 
+	 		_inactiveSelectionFormat = val;
+	 		if (this._selFormatState == SelectionFormatState.INACTIVE)
+	 			refreshSelection();
+		 }		 	
+		 
+		/**
+		 * @private - docs on setter
+		 */
+		 public function get inactiveSelectionFormat():SelectionFormat
+		 { 
+		 	return _inactiveSelectionFormat ? _inactiveSelectionFormat : (_textFlow ? _textFlow.configuration.inactiveSelectionFormat : null);
+		 }		 
+		 
+		 /** @private - returns the selectionFormatState.  @see flashx.textLayout.edit.SelectionFormatState */
+		 tlf_internal function get selectionFormatState():String
+		 { return _selFormatState; }
+		 
+		 /** @private - sets the SelectionFormatState. @see flashx.textLayout.edit.SelectionFormatState */
+		 tlf_internal function setSelectionFormatState(selFormatState:String):void
+		 {
+		 	if (selFormatState != _selFormatState)
+		 	{		 			
+		 	//	trace("changing selection state: was", _selFormatState, "switching to", selFormatState, "on selectionManager", id);
+			 	var oldSelectionFormat:SelectionFormat = currentSelectionFormat;
+			 	_selFormatState = selFormatState;
+			 	var newSelectionFormat:SelectionFormat = currentSelectionFormat;
+			 	if (!newSelectionFormat.equals(oldSelectionFormat))
+			 	{
+			 		refreshSelection();
+			 	}
+			 }
+		 }
+		 
+		 /** @private */
+		 tlf_internal function cloneSelectionFormatState(oldISelectionManager:ISelectionManager):void
+		 {
+			var oldSelectionManager:SelectionManager = oldISelectionManager as SelectionManager;
+			if (oldSelectionManager)
+			{
+				_isActive = oldSelectionManager._isActive;
+				_mouseOverSelectionArea = oldSelectionManager._mouseOverSelectionArea;
+				setSelectionFormatState(oldSelectionManager.selectionFormatState);
+			}
+		 }
+		 
+		/**
+		 * Gets the SelectionState at the specified mouse position.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 * @see flashx.textLayout.edit.SelectionState
+		 * @param currentTarget		The object that is actively processing the Event object with an event listener.
+		 * @param target			The InteractiveObject instance under the pointing device. The target is not always the object in the display list that registered the event listener. Use the currentTarget property to access the object in the display list that is currently processing the event.
+		 * @param localX			The horizontal coordinate at which the event occurred relative to the containing sprite.
+		 * @param localY			The vertical coordinate at which the event occurred relative to the containing sprite.
+		 * @param extendSelection	Indicates that only activeIndex should move
+		 * @return the resulting SelectionState
+		 */		 		 		 		 		 		 		 		 		 		 		 		 		 		 
+		 private function selectionPoint(currentTarget:Object, target:InteractiveObject, localX:Number, localY:Number, extendSelection:Boolean = false):SelectionState
+		 {
+		 	//trace("selectionPoint");
+		 	if (!_textFlow) 
+		 		return null;
+		 	if (!hasSelection()) 
+		 		extendSelection = false;
+		 	
+			var begIdx:int = anchorMark.position;
+			var endIdx:int = activeMark.position;
+		 	
+			endIdx = computeSelectionIndex(_textFlow, target, currentTarget, localX, localY);
+			if (endIdx == -1)
+				return null;	// ignore
+			
+			// attempt to position in the logical hierarchy
+			var leaf:FlowLeafElement = _textFlow.findLeaf(endIdx);
+			
+			// make sure we aren't selecting after the paragraph terminating character
+			var para:ParagraphElement = leaf.getParagraph();
+			if (endIdx == para.getAbsoluteStart() + para.textLength)
+				endIdx--;
+				
+			if (!extendSelection)
+				begIdx = endIdx;							
+
+			if (begIdx == endIdx)
+			{
+				if (leaf is InlineGraphicElement) {
+					endIdx++;
+				}
+				begIdx = NavigationUtil.updateStartIfInReadOnlyElement(_textFlow, begIdx);
+				endIdx = NavigationUtil.updateEndIfInReadOnlyElement(_textFlow, endIdx);
+			} else {
+				endIdx = NavigationUtil.updateEndIfInReadOnlyElement(_textFlow, endIdx);
+			}			
+		 	return new SelectionState(textFlow, begIdx, endIdx);
+		 }		 		 		 
+		 
+		/** 
+		 *  @copy ISelectionManager#setFocus()
+		 * 
+		 * @includeExample examples\SelectionManager_setFocus.as -noswf
+		 * 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		*/
+		 public function setFocus():void
+		 {
+			if (hasSelection())
+		 	{
+			 //	trace("setFocus sm", id);
+
+		 		// container with the activePosition gets the key focus
+		 		if (_textFlow.flowComposer)
+		 			_textFlow.flowComposer.setFocus(activePosition,false);
+		 		setSelectionFormatState(SelectionFormatState.FOCUSED);
+		 	}
+		 }
+		 
+		/**
+		 *  @copy ISelectionManager#anchorPosition
+		 */
+		public function get anchorPosition() : int
+		{
+			return anchorMark.position;
+		}
+		/**
+		 *  @copy ISelectionManager#activePosition
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function get activePosition() : int
+		{
+			return activeMark.position;			
+		}
+		/**
+		 *  @copy ISelectionManager#absoluteStart
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function get absoluteStart() : int
+		{
+			return (anchorMark.position < activeMark.position) ? anchorMark.position : activeMark.position;
+		}
+		/**
+		 *  @copy ISelectionManager#absoluteEnd
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function get absoluteEnd() : int
+		{
+			return (anchorMark.position > activeMark.position) ? anchorMark.position : activeMark.position;
+		}
+		
+		/** 
+		 *  @copy ISelectionManager#selectAll
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 	 	 * 
+		 * @see flashx.textLayout.compose.IFlowComposer
+		 */
+		public function selectAll() : void
+		{
+			selectRange(0, int.MAX_VALUE);
+		}
+		
+		/** 
+		 *  @copy ISelectionManager#selectRange
+		 * 
+		 * @includeExample examples\SelectionManager_selectRange.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+ 	 	 * 
+		 * @see flashx.textLayout.compose.IFlowComposer
+		 */
+		public function selectRange(anchorPosition:int, activePosition:int) : void
+		{
+			flushPendingOperations();
+			
+			// anchor and active can be in any order
+			// TODO: range check and clamp anchor,active
+			if (anchorPosition != anchorMark.position || activePosition != activeMark.position)
+			{	
+				clearSelectionShapes();
+					
+				internalSetSelection(_textFlow, anchorPosition, activePosition);
+				
+				// selection changed
+				selectionChanged();		
+				
+				allowOperationMerge = false;
+			}
+		}
+		
+		private function internalSetSelection(root:TextFlow,anchorPosition:int,activePosition:int,format:ITextLayoutFormat = null) : void
+		{
+			_textFlow = root;
+			
+			// clamp anchor/active
+			if (anchorPosition < 0 || activePosition < 0)
+			{
+				anchorPosition = -1;
+				activePosition = -1;
+			}
+			
+			if (anchorPosition != -1 && activePosition != -1)
+			{
+				if (anchorPosition >= _textFlow.textLength)
+					anchorPosition = _textFlow.textLength - 1;
+				
+				if (activePosition >= _textFlow.textLength)
+					activePosition = _textFlow.textLength - 1;
+			}
+
+			_pointFormat = format;
+			anchorMark.position = anchorPosition; // NavigationUtil.updateStartIfInReadOnlyElement(root, anchorPosition);
+			activeMark.position = activePosition; // NavigationUtil.updateEndIfInReadOnlyElement(root, activePosition);
+		//	trace("Selection ", anchorMark, "to", activeMark.position);
+		}		
+		
+		/** Clear any active selections.
+		 */
+		private function clear(): void
+		{
+			if (hasSelection())
+			{
+				flushPendingOperations();
+				clearSelectionShapes();
+				internalSetSelection(_textFlow, -1, -1);
+				// selection cleared
+				selectionChanged();
+				allowOperationMerge = false;
+			}
+		}
+		
+		private function addSelectionShapes():void
+		{
+			var blinking:Boolean = (currentSelectionFormat.pointBlinkRate != 0);
+			if (_textFlow.flowComposer && (blinking || (!blinking && (activeMark.position != anchorMark.position))))
+			{
+				// zero alpha means nothing is drawn so skip it
+				if (currentSelectionFormat && 
+					(((absoluteStart == absoluteEnd) &&  (currentSelectionFormat.pointAlpha != 0)) ||
+					 ((absoluteStart != absoluteEnd) && (currentSelectionFormat.rangeAlpha != 0))))
+				{
+					var containerIter:int = 0;
+					while(containerIter < _textFlow.flowComposer.numControllers)
+					{
+						_textFlow.flowComposer.getControllerAt(containerIter++).addSelectionShapes(currentSelectionFormat, absoluteStart, absoluteEnd);
+					}
+				} 
+			}
+		}
+		
+		private function clearSelectionShapes():void
+		{
+			if (_textFlow.flowComposer)
+			{
+				var containerIter:int = 0;
+				while(containerIter < _textFlow.flowComposer.numControllers)
+				{
+					_textFlow.flowComposer.getControllerAt(containerIter++).clearSelectionShapes();
+				}
+			}
+		}
+		
+		/** 
+		 *  @copy ISelectionManager#refreshSelection()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		*/
+		public function refreshSelection(): void
+		{
+			if (hasSelection())
+			{
+				clearSelectionShapes();
+				addSelectionShapes();
+			}
+		}
+		
+		/** Verifies that the selection is in a legal state. @private */
+		CONFIG::debug public function debugCheckSelectionManager():int
+		{
+			var rslt:int = 0;
+			if (hasSelection())
+			{
+				// both points must be within the flow - may not include trailing \n in final paragraph
+				rslt+= assert(anchorMark.position >= 0 && anchorMark.position < _textFlow.textLength,"SelectionManager:validate selBegIdx is out of range");
+				rslt += assert(activeMark.position >= 0 && activeMark.position < _textFlow.textLength,"SelectionManager:validate selEndIdx is out of range");
+			}
+			return rslt;
+		}
+		
+		// ////////////////////////////////////
+		// internal selection handling methods
+		// ////////////////////////////////////
+		
+		/** @private
+		 * Handler function called when the selection has been changed.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 * @param doDispatchEvent	true if a selection changed event will be sent
+		 * @param resetPointFormat	true if the attributes associated with the caret should be discarded
+		 */
+		tlf_internal function selectionChanged(doDispatchEvent:Boolean = true, resetPointFormat:Boolean=true):void
+		{
+			CONFIG::debug { debugCheckSelectionManager(); }	// validates the selection
+			
+			// clear any remembered attributes for the next character
+			if (resetPointFormat) 
+				_pointFormat = null;
+			
+			if (doDispatchEvent)
+				textFlow.dispatchEvent(new SelectionEvent(SelectionEvent.SELECTION_CHANGE, false, false, hasSelection() ? getSelectionState() : null));
+		}
+
+		// TODO: this routine could be much more efficient - instead of iterating over all lines in the TextFlow it should iterate over 
+		// the visible lines in the container.  Todo that move this routine into ContainerController and use the shapeChildren along with the logic in fillShapeChildren
+		static private function computeSelectionIndexInContainer(textFlow:TextFlow, controller:ContainerController, localX:Number, localY:Number):int
+		{
+			//var origX:Number = localX;
+			//var origY:Number = localY;
+			var lineIndex:int = -1;
+			
+			var firstCharVisible:int = controller.absoluteStart;
+			var length:int  = controller.textLength;
+			
+			// try to find a point on the line
+			var bp:String = textFlow.computedFormat.blockProgression;
+			var isTTB:Boolean = (bp == BlockProgression.RL);
+			var isDirectionRTL:Boolean = (textFlow.computedFormat.direction == Direction.RTL);
+			
+			//Establish perpendicular the coordinate for use with TTB or LTR/RTL lines
+			var perpCoor:Number = isTTB ? localX : localY;
+			
+			//get the nearest column so we can ignore lines which aren't in the column we're looking for.
+			//if we don't do this, we won't be able to select across column boundaries.
+			var nearestColIdx:int = locateNearestColumn(controller, localX, localY, textFlow.computedFormat.blockProgression,textFlow.computedFormat.direction);
+			
+			var prevLineBounds:Rectangle = null;
+			var previousLineIndex:int = -1;
+			
+			var lastLineIndexInColumn:int = -1;
+			
+			// Matching TextFlowLine and TextLine - they are not necessarily valid
+			var rtline:TextFlowLine;
+			var rtTextLine:TextLine;
+			
+			for (var testIndex:int = textFlow.flowComposer.numLines - 1; testIndex >= 0; testIndex--)
+			{
+				rtline = textFlow.flowComposer.getLineAt(testIndex);
+				if (rtline.controller != controller || rtline.columnIndex != nearestColIdx)
+				{
+					// use last line in previous column
+					if (lastLineIndexInColumn != -1)
+					{
+						lineIndex = testIndex+1;
+						break;
+					}
+					continue;
+				}
+					
+				// is this line even displayed?
+				if (rtline.absoluteStart < firstCharVisible || rtline.absoluteStart >= firstCharVisible+length)
+					continue;
+				rtTextLine = rtline.getTextLine();
+				if (rtTextLine == null || rtTextLine.parent == null)
+					continue;
+				
+				if (lastLineIndexInColumn == -1)
+					lastLineIndexInColumn = testIndex;
+					
+				var bounds:Rectangle = rtTextLine.getBounds(DisplayObject(controller.container));
+				// trace(testIndex.toString(),":",bounds.toString());
+				
+				var linePerpCoor:Number = isTTB ? bounds.left : bounds.bottom;
+				var midPerpCoor:Number = -1;//will be a positive value if prevLineBounds is not null
+				
+				//if this is not the first test loop, use the prevLineBounds to find the mid-point between the current
+				//line, which will be logically up from the previous line - we're walking back-to-front
+				if(prevLineBounds)
+				{
+					//if it's ttb, use the right bounds (ie the top of the line)...
+					var prevPerpCoor:Number = (isTTB ? prevLineBounds.right : prevLineBounds.top);
+					//calculate the midpoint
+					midPerpCoor = (linePerpCoor + prevPerpCoor)/2;
+				}
+				
+				//if the current line is below the click, then this OR the previous line, is the line we're looking for
+				var isLineBelow:Boolean = (isTTB ? linePerpCoor > perpCoor : linePerpCoor < perpCoor);
+				if(isLineBelow || testIndex == 0)
+				{
+					//if we haven't calculated the midPerpCoor (-1), then this is the first loop and we want to use the 
+					//current line,. Otherwise, if the click's perpendicular coordinate is below the mid point between the current
+					//line or below it, then we want to use the line below (ie the previous line, but logically the one after the current)
+					var inPrevLine:Boolean = midPerpCoor != -1 && (isTTB ? perpCoor < midPerpCoor : perpCoor > midPerpCoor);
+					lineIndex = inPrevLine && testIndex != lastLineIndexInColumn ? testIndex+1 : testIndex;	
+					break;
+				}
+				else
+				{
+					//this line is below the click, so set the prevLineBounds to bounds of the current line and move on...
+					prevLineBounds = bounds;
+					previousLineIndex = testIndex;
+				}
+			}
+
+			if (lineIndex == -1)
+			{
+				lineIndex = previousLineIndex;
+				if (lineIndex == -1)
+					return -1;	// no lines in container
+			}	
+				
+			//Get a valid textLine -- check to make sure line is valid, regenerate if necessary, make sure it has correct container relative coordinates
+			var tfl:TextFlowLine = textFlow.flowComposer.getLineAt(lineIndex);
+			var textLine:TextLine = tfl.getTextLine(true);
+			
+			// adjust localX,localY to be relative to the textLine.  
+			// Can't use localToGlobal/globalToLocal because textLine may not be on the display list due to virtualization
+			// we may need to bring this back if textline's can be rotated or placed by any mechanism other than a translation
+			// but then we'll need to provisionally place a virtualized TextLine in its parent container
+			localX -= textLine.x;
+			localY -= textLine.y;
+			/* var localPoint:Point = DisplayObject(controller.container).localToGlobal(new Point(localX,localY));
+			localPoint = textLine.globalToLocal(localPoint);
+			localX = localPoint.x;
+			localY = localPoint.y; */
+			
+			var lastAtomRect:Rectangle = new Rectangle(0, 0, 0, 0);
+			var textFlowLine:TextFlowLine = TextFlowLine(textLine.userData);
+			var startOnNextLineIfNecessary:Boolean = false;
+			
+			if (isDirectionRTL) {
+				lastAtomRect = textLine.getAtomBounds(textLine.atomCount - 1);
+			} else {
+				if ((textFlowLine.absoluteStart + textFlowLine.textLength) >= textFlowLine.paragraph.textLength) {
+					if (textLine.atomCount > 1) lastAtomRect = textLine.getAtomBounds(textLine.atomCount - 2);
+				} else {
+					var lastLinePosInPar:int = textFlowLine.absoluteStart + textFlowLine.textLength - 1;
+					var lastChar:String = textLine.textBlock.content.rawText.charAt(lastLinePosInPar);
+					if (lastChar == " ") {
+						if (textLine.atomCount > 1) lastAtomRect = textLine.getAtomBounds(textLine.atomCount - 2);
+					} else {
+						startOnNextLineIfNecessary = true;
+						if (textLine.atomCount > 0) lastAtomRect = textLine.getAtomBounds(textLine.atomCount - 1);
+					}
+				}
+			}
+						
+			if (!isTTB)
+			{
+				if (localX < 0)
+					localX = 0;
+				else if (localX > (lastAtomRect.x + lastAtomRect.width))
+				{
+					if (startOnNextLineIfNecessary) 
+						return textFlowLine.absoluteStart + textFlowLine.textLength;
+					localX = lastAtomRect.x + lastAtomRect.width;
+				}
+			}
+			else
+			{	
+				if (localY < 0)
+					localY = 0;
+				else if (localY > (lastAtomRect.y + lastAtomRect.height))
+				{
+					if (startOnNextLineIfNecessary) 
+						return textFlowLine.absoluteStart + textFlowLine.textLength;			
+					localY = lastAtomRect.y + lastAtomRect.height;
+				}
+			}
+			
+			var result:int = computeSelectionIndexInLine(textFlow, textLine, localX, localY);
+			// trace("computeSelectionIndexInContainer:(",origX,origY,")",textFlow.flowComposer.getControllerIndex(controller).toString(),lineIndex.toString(),result.toString());
+			return result != -1 ? result : firstCharVisible + length;	
+		}
+		
+		static private function locateNearestColumn(container:ContainerController, localX:Number, localY:Number, wm:String, direction:String):int
+		{
+			var colIdx:int = 0;
+			//if we only have 1 column, no need to perform calculation...
+			var columnState:ColumnState = container.columnState;
+
+			//we need to compare the current column to the nextColmn
+			while(colIdx < columnState.columnCount - 1)
+			{
+				var curCol:Rectangle  = columnState.getColumnAt(colIdx);
+				var nextCol:Rectangle = columnState.getColumnAt(colIdx + 1);
+				
+				if(curCol.contains(localX, localY)) //in current column
+					break;
+				
+				if(nextCol.contains(localX, localY))//in next column
+				{
+					++colIdx;
+					break;
+				}
+				else
+				{
+					if(wm == BlockProgression.RL)
+					{
+						//if localY is above curCol || between columns, but close to current
+						if(localY < curCol.top || localY < nextCol.top && Math.abs(curCol.bottom - localY) <= Math.abs(nextCol.top - localY))
+							break;
+						
+						if(localY > nextCol.top)//between but closer to nextCol
+						{
+							++colIdx;
+							break;
+						}
+					}
+					else
+					{
+						if(direction  == Direction.LTR)
+						{
+							//if localX is left of curCol || between columns but closer to current, break here
+							if(localX < curCol.left || localX < nextCol.left && Math.abs(curCol.right - localX) <= Math.abs(nextCol.left - localX)) 
+								break;
+							if(localX < nextCol.left) // between, but closer to next column
+							{
+								++colIdx;
+								break;
+							}
+						}
+						else
+						{
+							//if localX is right of curCol || between columns, but closer to current
+							if(localX > curCol.right || localX > nextCol.right && Math.abs(curCol.left - localX) <= Math.abs(nextCol.right - localX))
+								break;
+							
+							if(localX > nextCol.right) // between, but closer to next column
+							{
+								++colIdx;
+								break;
+							}
+						} 
+					}
+				}
+				
+				//increment colIdx.  If this is the last pass through, then the conditions above were never met
+				//so we want the last column
+				++colIdx;
+			}
+
+			
+			return colIdx;
+		}
+		
+		static private function computeSelectionIndexInLine(textFlow:TextFlow, textLine:TextLine,localX:Number,localY:Number):int
+		{
+			if (!(textLine.userData is TextFlowLine))
+				return -1;	// not a TextLayout generated line
+				
+			var rtline:TextFlowLine = TextFlowLine(textLine.userData);
+			if (rtline.validity == TextLineValidity.INVALID)
+				return -1;	// not currently composed 
+			textLine = rtline.getTextLine(true);	// make sure the TextLine is not released
+			
+				
+			var isTTB:Boolean = textFlow.computedFormat.blockProgression == BlockProgression.RL;
+			var perpCoor:Number = isTTB ? localX : localY;
+			
+			// new code for builds 385 and later
+			var pt:Point = new Point();
+			pt.x = localX;
+			pt.y = localY;
+			
+			// in most cases, we want to "fixup" the coordiates of the x and y coordinates
+			//because we could be getting a positive results for a click in the line, but the
+			//coordinates do not match any particular glyph.  However, there are cases where the 
+			//fix leads to bad results. For example, if there is a TCY run, this code will always cause
+			//a selection to be created in the middle of the run, meaning idividual glyphs cannot be selected.
+			//
+			//As a result, we need to be performing the less common case check prior to adjusting the 
+			//coordinates.
+			pt = textLine.localToGlobal(pt);
+			var elemIdx:int = textLine.getAtomIndexAtPoint(pt.x,pt.y);
+			//trace("global point: " + pt);
+			//trace("elemIdx: " + elemIdx);
+			if(elemIdx == -1)
+			{
+				//reset the pt
+				pt.x = localX;
+				pt.y = localY;
+				
+				//make adjustments
+				if (pt.x < 0 || (isTTB && perpCoor > textLine.ascent))
+					pt.x = 0;
+				if (pt.y < 0 || (!isTTB && perpCoor > textLine.descent))
+					pt.y = 0;
+				
+				//get the global again and get try for the element again
+				pt = textLine.localToGlobal(pt);
+				elemIdx = textLine.getAtomIndexAtPoint(pt.x,pt.y);
+				//trace("global point (second): " + pt);
+				//trace("elemIdx (second): " + elemIdx);
+			}
+			
+			//now we REALLY don't have a glyph, so return the head or tail of the line.
+			if (elemIdx == -1)
+			{
+				//we need to use global coordinates here.  reset pt and get conversion...
+				pt.x = localX;
+				pt.y = localY;
+				pt = textLine.localToGlobal(pt)
+				
+				if(!isTTB)
+					return (pt.x <= textLine.x) ? rtline.absoluteStart : (rtline.absoluteStart + rtline.textLength - 1);
+				else
+					return (pt.y <= textLine.y) ? rtline.absoluteStart : (rtline.absoluteStart + rtline.textLength - 1);
+			}
+			
+			// get the character box and if check we are past the middle select past this character. 
+			var glyphRect:Rectangle = textLine.getAtomBounds(elemIdx);
+			// trace("idx",elemIdx,"x",glyphRect.x,"y",glyphRect.y,"width",glyphRect.width,"height",glyphRect.height,"localX",localX,"localY",localY,"textLine.x",textLine.x);
+			var leanRight:Boolean = false;
+			if(glyphRect)
+			{	
+				//if this is TTB and NOT TCY determine lean based on Y coordinates...
+				if(isTTB && textLine.getAtomTextRotation(elemIdx) != TextRotation.ROTATE_0)
+					leanRight = (localY > (glyphRect.y + glyphRect.height/2));
+				else //use X..
+					leanRight = (localX > (glyphRect.x + glyphRect.width/2));
+			}
+			
+			var paraSelectionIdx:int;
+			if ((textLine.getAtomBidiLevel(elemIdx) % 2) != 0) // Right to left case, right is "start" unicode
+				paraSelectionIdx = leanRight ? textLine.getAtomTextBlockBeginIndex(elemIdx) : textLine.getAtomTextBlockEndIndex(elemIdx);
+			else  // Left to right case, right is "end" unicode
+				paraSelectionIdx = leanRight ? textLine.getAtomTextBlockEndIndex(elemIdx) : textLine.getAtomTextBlockBeginIndex(elemIdx);
+
+			//we again need to do some fixup here.  Unfortunately, we don't have the index into the paragraph until
+			
+			return rtline.paragraph.getAbsoluteStart() + paraSelectionIdx;
+		}
+		
+		static private function checkForDisplayed(container:DisplayObject):Boolean
+		{
+			while (container)
+			{
+				if (!container.visible)
+					return false;
+				container = container.parent;
+				if (container is Stage)
+					return true;					
+			}
+			return false;	// not on the stage
+
+		}
+		/** @private - given a target and location compute the selectionIndex */
+		static tlf_internal function computeSelectionIndex(textFlow:TextFlow, target:Object, currentTarget:Object, localX:Number,localY:Number):int
+		{			
+			//trace("computeSelectionIndex");
+			var rslt:int = 0;
+			var containerPoint:Point; // scratch
+			
+			//Make sure that if the target is a line, that it is part of THIS textFlow and not another.  Can happen
+			//when holding down mouse and moving out of one flow and over another. Could also happen when moving over
+			//TextLines that are either non-TLF or generated from a factory. 
+			var useTargetedTextLine:Boolean = false;
+			if (target is TextLine)
+			{
+				var tfl:TextFlowLine = TextLine(target).userData as TextFlowLine;
+				if (tfl)
+				{
+					var para:ParagraphElement = tfl.paragraph;
+					if(para.getTextFlow() == textFlow)
+						useTargetedTextLine = true;
+				}
+			}
+			/* trace("got target class", target.toString(), "at (", localX, localY, ")");
+			trace("Mapping",localX,localY,"for",target);
+			containerPoint = DisplayObject(target).localToGlobal(new Point(localX, localY));
+			trace("... Global",containerPoint.x,containerPoint.y);
+			containerPoint = DisplayObject(currentTarget).globalToLocal(containerPoint);
+			trace("... container Local",containerPoint.x,containerPoint.y); */
+			
+			if (useTargetedTextLine)
+				rslt = computeSelectionIndexInLine(textFlow, TextLine(target), localX, localY);
+			else
+			{
+				var controller:ContainerController;
+				for (var idx:int = 0; idx < textFlow.flowComposer.numControllers; idx++)
+				{
+					var testController:ContainerController = textFlow.flowComposer.getControllerAt(idx); 
+					if (testController.container == target || testController.container == currentTarget)
+					{
+						controller = testController;
+						break;
+					}
+				}
+				if (controller)
+				{	
+					if (target != controller.container)
+					{
+						containerPoint = DisplayObject(target).localToGlobal(new Point(localX, localY));
+						containerPoint = DisplayObject(controller.container).globalToLocal(containerPoint);
+						localX = containerPoint.x;
+						localY = containerPoint.y;
+					}
+					rslt = computeSelectionIndexInContainer(textFlow, controller, localX, localY);			
+				} 
+				else 
+				{
+					//the point is someplace else on stage.  Map the target 
+					//to the textFlow.container.
+					CONFIG::debug { assert(textFlow.flowComposer && textFlow.flowComposer.numControllers,"computeSelectionIndex: invalid textFlow"); }
+					
+					
+					// result of the search
+					var controllerCandidate:ContainerController = null;
+					var candidateLocalX:Number;
+					var candidateLocalY:Number;
+					var relDistance:Number = Number.MAX_VALUE;
+					
+					for (var containerIndex:int = 0; containerIndex < textFlow.flowComposer.numControllers; containerIndex++)
+					{
+						var curContainerController:ContainerController = textFlow.flowComposer.getControllerAt(containerIndex);
+						
+						// displayed??
+						if (!checkForDisplayed(curContainerController.container as DisplayObject))
+							continue;
+
+						// handle measured containers??
+						var bounds:Rectangle = curContainerController.getContentBounds();
+						var containerWidth:Number = isNaN(curContainerController.compositionWidth) ? curContainerController.effectivePaddingLeft+bounds.width : curContainerController.compositionWidth;
+						var containerHeight:Number = isNaN(curContainerController.compositionHeight) ? curContainerController.effectivePaddingTop+bounds.height : curContainerController.compositionHeight;
+						
+						containerPoint = DisplayObject(target).localToGlobal(new Point(localX, localY));
+						containerPoint = DisplayObject(curContainerController.container).globalToLocal(containerPoint);
+						
+						// remove scrollRect effects for the distance test but add it back in for the result
+						var adjustX:Number = 0;
+						var adjustY:Number = 0;
+						
+						if (curContainerController.hasScrollRect)
+						{
+							containerPoint.x -= (adjustX = curContainerController.container.scrollRect.x);
+							containerPoint.y -= (adjustY = curContainerController.container.scrollRect.y);
+						}
+						
+						if ((containerPoint.x >= 0) && (containerPoint.x <= containerWidth) &&
+							(containerPoint.y >= 0) && (containerPoint.y <= containerHeight))
+						{
+							controllerCandidate = curContainerController;
+							candidateLocalX = containerPoint.x+adjustX;
+							candidateLocalY = containerPoint.y+adjustY;
+							break;
+						}
+						
+						// figure minimum distance of containerPoint to curContainerController - 8 cases
+						var relDistanceX:Number = 0;
+						var relDistanceY:Number = 0;
+
+						if (containerPoint.x < 0)
+						{
+							relDistanceX = containerPoint.x;
+							if (containerPoint.y < 0)
+								relDistanceY = containerPoint.y;
+							else if (containerPoint.y > containerHeight)
+								relDistanceY = containerPoint.y-containerHeight;
+						}
+						else if (containerPoint.x > containerWidth)
+						{
+							relDistanceX = containerPoint.x-containerWidth;
+							if (containerPoint.y < 0)
+								relDistanceY = containerPoint.y;
+							else if (containerPoint.y > containerHeight)
+								relDistanceY = containerPoint.y-containerHeight;
+						}
+						else if (containerPoint.y < 0)
+							relDistanceY = -containerPoint.y;
+						else
+							relDistanceY = containerPoint.y-containerHeight;
+						var tempDist:Number = relDistanceX*relDistanceX + relDistanceY*relDistanceY;	// could do sqrt but why bother - there is no Math.hypot function
+						if (tempDist <= relDistance)
+						{
+							relDistance = tempDist;
+							controllerCandidate = curContainerController;
+							candidateLocalX = containerPoint.x+adjustX;
+							candidateLocalY = containerPoint.y+adjustY;
+						}
+					}
+
+
+					rslt = controllerCandidate ? computeSelectionIndexInContainer(textFlow, controllerCandidate, candidateLocalX, candidateLocalY) : -1;
+				}
+			}
+			
+			if (rslt >= textFlow.textLength)
+				rslt = textFlow.textLength-1;
+			return rslt;
+		}
+		
+		/** initialize a new point selection at click point @private */
+		tlf_internal function setNewSelectionPoint(currentTarget:Object, target:InteractiveObject, localX:Number, localY:Number, extendSelection:Boolean = false):Boolean
+		{
+			var selState:SelectionState = selectionPoint(currentTarget, target, localX, localY, extendSelection);
+			if (selState == null)
+				return false;	// ignore
+			
+			if (selState.anchorPosition != anchorMark.position || selState.activePosition != activeMark.position)
+			{
+			//	clear(false);
+			//	internalSetSelection(_textFlow, selState.anchorPosition, selState.activePosition);
+				selectRange(selState.anchorPosition, selState.activePosition);
+				return true;
+			}
+			return false;
+		}
+		
+		// ///////////////////////////////////
+		// Mouse and keyboard methods 
+		// ///////////////////////////////////
+		
+		/** 
+		 *  @copy IInteractionEventHandler#mouseDownHandler()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */	
+		public function mouseDownHandler(event:MouseEvent):void
+		{
+			handleMouseEventForSelection(event, event.shiftKey);
+		}
+		
+		/**
+		 * @copy IInteractionEventHandler#mouseMoveHandler()
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */	
+		public function mouseMoveHandler(event:MouseEvent):void
+		{
+			var wmode:String = textFlow.computedFormat.blockProgression;			
+			if (wmode != BlockProgression.RL) 
+				Mouse.cursor = MouseCursor.IBEAM;			
+			if (event.buttonDown)
+				handleMouseEventForSelection(event, true);
+		}
+		
+		private function handleMouseEventForSelection(event:MouseEvent, allowExtend:Boolean):void
+		{
+			var startSelectionActive:Boolean = hasSelection();
+			
+			if (setNewSelectionPoint(event.currentTarget, event.target as InteractiveObject, event.localX, event.localY, startSelectionActive && allowExtend))
+			{
+				selectionChanged();
+				if (startSelectionActive)
+					clearSelectionShapes();
+
+				if (hasSelection())
+					addSelectionShapes();
+			}		
+			allowOperationMerge = false;
+		}
+		
+		/** 
+		 * @copy IInteractionEventHandler#mouseUpHandler()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */	
+		public function mouseUpHandler(event:MouseEvent):void
+		{
+			if (!_mouseOverSelectionArea)
+			{
+				Mouse.cursor = MouseCursor.AUTO;
+			}
+		}
+		
+		private function atBeginningWordPos(activePara:ParagraphElement, pos:int):Boolean
+		{
+			if (pos == 0) return true;
+			var nextPos:int = activePara.findNextWordBoundary(pos);
+			nextPos = activePara.findPreviousWordBoundary(nextPos);
+			return (pos == nextPos);
+		}
+				
+		
+		/** 
+		 * @copy IInteractionEventHandler#mouseDoubleClickHandler()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */	
+		public function mouseDoubleClickHandler(event:MouseEvent):void
+		{
+			if (!hasSelection())
+				return;
+
+			// We got a previous single click event that set the selection.
+			// Extend it into a selection for the entire word.
+
+			// Adjust the active end to the beginning or end of the nearest word, depending on which end of the selection is active
+			var activePara:ParagraphElement = _textFlow.findAbsoluteParagraph(activeMark.position);
+			var activeParaStart:int = activePara.getAbsoluteStart();
+			var newActiveIndex:int; // adjusted active index
+			if (anchorMark.position <= activeMark.position)
+				newActiveIndex = activePara.findNextWordBoundary(activeMark.position - activeParaStart) + activeParaStart;
+			else
+				newActiveIndex = activePara.findPreviousWordBoundary(activeMark.position - activeParaStart) + activeParaStart;
+				
+			// don't include end of paragraph marker
+			if (newActiveIndex == activeParaStart+activePara.textLength)
+				newActiveIndex--;
+
+			// Adjust the anchor end. If we're doing a dbl-click shift select to extend the selection, the anchor point stays the same.
+			// Otherwise adjust it to the beginning or end of the nearest word, depending on which end of the selection is active
+			var newAnchorIndex:int; // adjusted anchor index
+			if (event.shiftKey)	
+				newAnchorIndex = anchorMark.position;
+			else
+			{
+				var anchorPara:ParagraphElement = _textFlow.findAbsoluteParagraph(anchorMark.position);
+				var anchorParaStart:int = anchorPara.getAbsoluteStart();
+				if (atBeginningWordPos(anchorPara, anchorMark.position - anchorParaStart))
+				{
+					newAnchorIndex = anchorMark.position;					
+				}
+				else
+				{
+					if (anchorMark.position <= activeMark.position)
+						newAnchorIndex = anchorPara.findPreviousWordBoundary(anchorMark.position - anchorParaStart) + anchorParaStart;
+					else
+						newAnchorIndex = anchorPara.findNextWordBoundary(anchorMark.position - anchorParaStart) + anchorParaStart;
+					// don't include end of paragraph marker
+					if (newAnchorIndex == anchorParaStart+anchorPara.textLength)
+						newAnchorIndex--;
+				}	
+			}
+			
+			if (newAnchorIndex != anchorMark.position || newActiveIndex != activeMark.position)
+			{
+				internalSetSelection(_textFlow, newAnchorIndex, newActiveIndex, null);				
+				selectionChanged();
+				clearSelectionShapes();
+
+				if (hasSelection())
+					addSelectionShapes();
+			}
+			
+			allowOperationMerge = false;
+		}
+
+		/** 
+		 * @copy IInteractionEventHandler#mouseOverHandler()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */							
+		public function mouseOverHandler(event:MouseEvent):void
+		{
+			_mouseOverSelectionArea = true;
+			var wmode:String = textFlow.computedFormat.blockProgression;
+			if (wmode != BlockProgression.RL) 
+				Mouse.cursor = MouseCursor.IBEAM;	
+			else 
+				Mouse.cursor = MouseCursor.AUTO;								
+		}
+
+		/** 
+		 * @copy IInteractionEventHandler#mouseOutHandler()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */					
+		public function mouseOutHandler(event:MouseEvent):void
+		{
+			_mouseOverSelectionArea = false;			
+			Mouse.cursor = MouseCursor.AUTO;									
+		}		
+		
+		/** 
+		 * @copy IInteractionEventHandler#focusInHandler()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function focusInHandler(event:FocusEvent):void
+		{			
+			// The focusIn can come before the activate. If so, we don't want the later activate to wipe out the focusIn
+			_isActive = true;	
+			
+			//trace("focusIn event on selectionManager", this.id);
+			setSelectionFormatState(SelectionFormatState.FOCUSED);		
+		}
+		 
+		/** 
+		 * @copy IInteractionEventHandler#focusOutHandler()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function focusOutHandler(event:FocusEvent):void
+		{
+			//trace("focusOut event on selectionManager", this.id);
+			if (_isActive)	// don't do it if we aren't active
+				setSelectionFormatState(SelectionFormatState.UNFOCUSED);			
+		}
+
+		/** 
+		 * @copy IInteractionEventHandler#activateHandler()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */				
+		public function activateHandler(event:Event):void
+		{
+			//trace("activate selectionManager", id);
+			// If there are multiple containers, the selection manager will get multiple activate & deactivate events,
+			// one per container. We only want to respond to the first one, because otherwise a focus event that comes
+			// in the middle will get its state change overwritten.
+			if (!_isActive)
+			{		
+				_isActive = true;
+				setSelectionFormatState(SelectionFormatState.UNFOCUSED);
+			}	
+		}
+		
+		/** 
+		 * @copy IInteractionEventHandler#deactivateHandler()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */				
+		public function deactivateHandler(event:Event):void
+		{
+			//trace("deactivate selectionManager", id);
+			// If there are multiple containers, the selection manager will get multiple activate & deactivate events,
+			// one per container. We only want to respond to the first one, because otherwise a focus event that comes
+			// in the middle will get its state change overwritten.
+			if (_isActive)
+			{
+				_isActive = false;
+				setSelectionFormatState(SelectionFormatState.INACTIVE);			
+			}
+		}
+		
+		/** Perform a SelectionManager operation - these may never modify the flow but clients still are able to cancel them. 
+		  * 
+		  * @playerversion Flash 10
+		  * @playerversion AIR 1.5
+ 	 	  * @langversion 3.0
+		  */
+		public function doOperation(op:FlowOperation):void
+		{
+			var opEvent:FlowOperationEvent = new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_BEGIN,false,true,op,0,null);
+			textFlow.dispatchEvent(opEvent);
+			if (!opEvent.isDefaultPrevented())
+			{
+				op = opEvent.operation;
+				
+				// only copy operation is allowed
+				if (!(op is CopyOperation))
+					throw new IllegalOperationError(GlobalSettings.resourceStringFunction("illegalOperation",[ getQualifiedClassName(op) ]));
+				var opError:Error = null;
+				try
+				{
+					op.doOperation();
+				}
+				catch(e:Error)
+				{
+					opError = e;
+				}
+				// operation completed - send event whether it succeeded or not.
+				opEvent = new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_END,false,true,op,0,opError);
+				textFlow.dispatchEvent(opEvent);
+				opError = opEvent.isDefaultPrevented() ? null : opEvent.error;
+				if (opError)
+					throw (opError);
+				textFlow.dispatchEvent(new FlowOperationEvent(FlowOperationEvent.FLOW_OPERATION_COMPLETE,false,false,op,0,null));
+			}			
+		}
+
+		/** 
+		 * @copy IInteractionEventHandler#editHandler()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 		 * @langversion 3.0
+		 */	
+		public function editHandler(event:Event):void
+		{
+			switch (event.type)
+			{
+				case Event.COPY:
+					flushPendingOperations();
+					doOperation(new CopyOperation(getSelectionState()));
+
+					break;
+				case Event.SELECT_ALL:
+					flushPendingOperations();
+					selectAll();
+					refreshSelection();
+					break;	
+			}
+			
+		}
+
+		private function handleLeftArrow(event:KeyboardEvent):SelectionState
+		{			
+			var selState:SelectionState = getSelectionState();
+			if(_textFlow.computedFormat.blockProgression != BlockProgression.RL)
+			{
+				if(_textFlow.computedFormat.direction == Direction.LTR)
+				{
+					if (event.ctrlKey || event.altKey)
+						NavigationUtil.previousWord(selState,event.shiftKey);
+					else
+						NavigationUtil.previousCharacter(selState,event.shiftKey);
+				}
+				else
+				{
+					if (event.ctrlKey || event.altKey)
+						NavigationUtil.nextWord(selState,event.shiftKey);
+					else
+						NavigationUtil.nextCharacter(selState,event.shiftKey);
+				}
+			} 
+			else 
+			{
+				// always test for altkey first - that way ctrl-alt is the same as alt
+				if (event.altKey)
+					NavigationUtil.endOfParagraph(selState,event.shiftKey);
+				else if (event.ctrlKey)
+					NavigationUtil.endOfDocument(selState,event.shiftKey);
+				else
+					NavigationUtil.nextLine(selState,event.shiftKey);
+			}
+			return selState;
+		}
+		
+		private function handleUpArrow(event:KeyboardEvent):SelectionState
+		{			
+			var selState:SelectionState = getSelectionState();
+			if(_textFlow.computedFormat.blockProgression != BlockProgression.RL)
+			{
+				// always test for altkey first - that way ctrl-alt is the same as alt
+				if (event.altKey)
+					NavigationUtil.startOfParagraph(selState,event.shiftKey);
+				else if (event.ctrlKey)
+					NavigationUtil.startOfDocument(selState,event.shiftKey);
+				else
+					NavigationUtil.previousLine(selState,event.shiftKey);
+			}
+			else
+			{
+				if(_textFlow.computedFormat.direction == Direction.LTR)
+				{
+					if (event.ctrlKey || event.altKey)
+						NavigationUtil.previousWord(selState,event.shiftKey);
+					else
+						NavigationUtil.previousCharacter(selState,event.shiftKey); 
+				}
+				else
+				{
+					if (event.ctrlKey || event.altKey)
+						NavigationUtil.nextWord(selState,event.shiftKey);
+					else
+						NavigationUtil.nextCharacter(selState,event.shiftKey);
+				}
+			}
+			return selState;
+		}
+		
+		private function handleRightArrow(event:KeyboardEvent):SelectionState
+		{
+			var selState:SelectionState = getSelectionState();
+			
+		 	if(_textFlow.computedFormat.blockProgression  != BlockProgression.RL)
+		 	{
+		 		if(_textFlow.computedFormat.direction == Direction.LTR)
+		 		{
+			 		if (event.ctrlKey || event.altKey)
+			 			NavigationUtil.nextWord(selState,event.shiftKey);
+			 		else
+			 			NavigationUtil.nextCharacter(selState,event.shiftKey);
+			 	}
+			 	else
+			 	{
+			 		if (event.ctrlKey || event.altKey)
+						NavigationUtil.previousWord(selState,event.shiftKey);
+					else
+						NavigationUtil.previousCharacter(selState,event.shiftKey);
+			 	}
+		 	}
+		 	else
+		 	{
+				// always test for altkey first - that way ctrl-alt is the same as alt
+				if (event.altKey)
+					NavigationUtil.startOfParagraph(selState,event.shiftKey);
+				else if (event.ctrlKey)
+					NavigationUtil.startOfDocument(selState,event.shiftKey);
+				else
+					NavigationUtil.previousLine(selState,event.shiftKey);
+			}
+			return selState;
+		}
+		
+		private function handleDownArrow(event:KeyboardEvent):SelectionState
+		{
+			var selState:SelectionState = getSelectionState();
+			
+			if(_textFlow.computedFormat.blockProgression != BlockProgression.RL)
+			{
+				// always test for altkey first - that way ctrl-alt is the same as alt
+				if (event.altKey)
+					NavigationUtil.endOfParagraph(selState,event.shiftKey);
+				else if (event.ctrlKey)
+					NavigationUtil.endOfDocument(selState,event.shiftKey);
+				else
+					NavigationUtil.nextLine(selState,event.shiftKey);
+			}
+			else
+			{
+				if(_textFlow.computedFormat.direction == Direction.LTR)
+				{
+					if (event.ctrlKey || event.altKey)
+						NavigationUtil.nextWord(selState,event.shiftKey);
+					else
+						NavigationUtil.nextCharacter(selState,event.shiftKey);
+				}
+				else
+				{
+					if (event.ctrlKey || event.altKey)
+						NavigationUtil.previousWord(selState,event.shiftKey);
+					else
+						NavigationUtil.previousCharacter(selState,event.shiftKey); 
+				}
+			}
+
+			return selState;
+		}
+		
+		private function handleHomeKey(event:KeyboardEvent):SelectionState
+		{
+			var selState:SelectionState = getSelectionState();
+			if (event.ctrlKey && !event.altKey)
+				NavigationUtil.startOfDocument(selState,event.shiftKey);
+			else
+				NavigationUtil.startOfLine(selState,event.shiftKey);
+			return selState;
+		}
+		
+		private function handleEndKey(event:KeyboardEvent):SelectionState
+		{
+			var selState:SelectionState = getSelectionState();
+			if (event.ctrlKey && !event.altKey)
+				NavigationUtil.endOfDocument(selState,event.shiftKey);
+			else
+				NavigationUtil.endOfLine(selState,event.shiftKey);
+			return selState;
+		}
+		
+		private function handlePageUpKey(event:KeyboardEvent):SelectionState
+		{
+			var selState:SelectionState = getSelectionState();
+			NavigationUtil.previousPage(selState,event.shiftKey);
+			return selState;
+		}
+
+		private function handlePageDownKey(event:KeyboardEvent):SelectionState
+		{
+			var selState:SelectionState = getSelectionState();
+			NavigationUtil.nextPage(selState,event.shiftKey);
+			return selState;
+		}		
+						
+		private function handleKeyEvent(event:KeyboardEvent):void
+		{
+			var selState:SelectionState = null;
+			flushPendingOperations();			
+			
+			switch(event.keyCode)
+			{
+				case Keyboard.LEFT:
+					selState = handleLeftArrow(event);
+					break;
+				case Keyboard.UP:
+					selState = handleUpArrow(event);
+					break;
+				case Keyboard.RIGHT:
+					selState = handleRightArrow(event);
+					break;
+				case Keyboard.DOWN:
+					selState = handleDownArrow(event);
+					break;
+				case Keyboard.HOME:
+					selState = handleHomeKey(event);
+					break;
+				case Keyboard.END:
+					selState = handleEndKey(event);
+					break;
+				case Keyboard.PAGE_DOWN:
+					selState = handlePageDownKey(event);
+					break;
+				case Keyboard.PAGE_UP:
+					selState = handlePageUpKey(event);
+					break;
+			}
+
+			if (selState != null)
+			{
+				event.preventDefault();
+				updateSelectionAndShapes(_textFlow, selState.anchorPosition, selState.activePosition);
+
+				// make sure the active end is visible in the container -- scroll if necessary
+				if (_textFlow.flowComposer && _textFlow.flowComposer.numControllers != 0)
+					 _textFlow.flowComposer.getControllerAt(_textFlow.flowComposer.numControllers-1).scrollToRange(selState.activePosition,selState.activePosition);
+			}
+			allowOperationMerge = false;
+		}																										
+			
+		/** 
+		 * @copy IInteractionEventHandler#keyDownHandler()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */	
+		public function keyDownHandler(event:KeyboardEvent):void
+		{
+			if (!hasSelection() || event.isDefaultPrevented())
+				return;
+
+			if (event.charCode == 0)
+			{	
+				// the keycodes that we currently handle
+				switch(event.keyCode)
+				{
+					case Keyboard.LEFT:
+					case Keyboard.UP:
+					case Keyboard.RIGHT:
+					case Keyboard.DOWN:
+					case Keyboard.HOME:
+					case Keyboard.END:
+					case Keyboard.PAGE_DOWN:
+					case Keyboard.PAGE_UP:
+					case Keyboard.ESCAPE:
+						handleKeyEvent(event);
+						break;
+				}
+			}
+			else if (event.keyCode == Keyboard.ESCAPE)
+				handleKeyEvent(event);
+		}
+
+		/** 
+		 * @copy IInteractionEventHandler#keyUpHandler()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 * 	@param	event	the keyUp event
+		 */			
+		public function keyUpHandler(event:KeyboardEvent):void
+		{
+			//do nothing here
+		}
+		
+		/** 
+		 * @copy IInteractionEventHandler#keyFocusChangeHandler()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 * 	@param	event	the FocusChange event
+		 */	
+		public function keyFocusChangeHandler(event:FocusEvent):void
+		{
+			return;	// ignores manageTabKey if not editable
+		}	
+		
+		/** 
+		 * @copy IInteractionEventHandler#textInputHandler()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		*/
+		public function textInputHandler(event:TextEvent):void
+		{
+			// do nothing
+			ignoreNextTextEvent = false;
+		}
+
+		/** 
+		 * @copy IInteractionEventHandler#imeStartCompositionHandler()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		*/
+		public function imeStartCompositionHandler(event:IMEEvent):void
+		{
+			// Do nothing -- this is handled in the EditManager if editing is supported
+			// If there is no EditManager, doing nothing will refuse the IME session.
+		}
+		
+		/**
+		 *  @private
+		 * 
+		 *  Execute asynchronous operations at the beginning of a frame. This
+		 *  event listener is called only if there is work that needs to be done.
+		 */
+		protected function enterFrameHandler(event:Event):void
+		{
+			flushPendingOperations();
+		}
+
+		/**
+		 * @copy IInteractionEventHandler#focusChangeHandler()
+		 */
+		public function focusChangeHandler(event:FocusEvent):void
+		{ }
+		
+		/**
+		 * @copy IInteractionEventHandler#menuSelectHandler()
+		 */
+		public function menuSelectHandler(event:ContextMenuEvent):void
+		{
+			var menu:ContextMenu = event.target as ContextMenu;
+			
+			if (activePosition != anchorPosition)
+			{
+				menu.clipboardItems.copy = true;
+				menu.clipboardItems.cut = editingMode == EditingMode.READ_WRITE;
+				menu.clipboardItems.clear = editingMode == EditingMode.READ_WRITE;
+			} else {
+				menu.clipboardItems.copy = false;
+				menu.clipboardItems.cut = false;
+				menu.clipboardItems.clear = false;
+			}
+			
+			var systemClipboard:Clipboard = Clipboard.generalClipboard;
+			if (activePosition != -1 && editingMode == EditingMode.READ_WRITE && (systemClipboard.hasFormat(TextClipboard.TEXT_LAYOUT_MARKUP) || systemClipboard.hasFormat(ClipboardFormats.TEXT_FORMAT)))
+			{
+				menu.clipboardItems.paste = true;
+			} else {
+				menu.clipboardItems.paste = false;
+			}
+			menu.clipboardItems.selectAll = true;		
+		}
+		
+		/**
+		 * @copy IInteractionEventHandler#mouseWheelHandler()
+		 */
+		public function mouseWheelHandler(event:MouseEvent):void
+		{ }				
+		/**
+		 * @copy IInteractionEventHandler#flushPendingOperations()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function flushPendingOperations():void
+		{	}
+
+		/**
+		 * @copy ISelectionManager#getCommonCharacterFormat()
+		 * 
+		 * @includeExample examples\SelectionManager_getCommonCharacterFormat.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function getCommonCharacterFormat(range:TextRange=null):ITextLayoutFormat
+		{
+			if (!range && !hasSelection())
+				return null;
+			
+			var selRange:ElementRange = ElementRange.createElementRange(_textFlow, range ? range.absoluteStart : absoluteStart, range? range.absoluteEnd : absoluteEnd);
+			
+			var leaf:FlowLeafElement = selRange.firstLeaf;
+			var attr:TextLayoutFormat = new TextLayoutFormat(leaf.computedFormat);
+	
+			// include any attributes set on a point selection but not yet applied	and return	
+			if (!isRangeSelection())
+			{
+				if (pointFormat)
+					attr.apply(pointFormat)
+			}
+			else
+			{
+				for (;;)
+				{
+					if (leaf == selRange.lastLeaf)
+						break;
+					leaf = leaf.getNextLeaf();
+					attr.removeClashing(leaf.computedFormat);
+				}
+			}
+			
+			return Property.extractInCategory(TextLayoutFormat, TextLayoutFormat.description, attr, Category.CHARACTER) as ITextLayoutFormat;
+		}
+		
+		 
+		 /**
+		 * @copy ISelectionManager#getCommonParagraphFormat()
+		 * 
+		 * @includeExample examples\SelectionManager_getCommonParagraphFormat.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function getCommonParagraphFormat (range:TextRange=null):ITextLayoutFormat
+		{
+			if (!range && !hasSelection())
+				return null;
+			
+			var selRange:ElementRange = ElementRange.createElementRange(_textFlow, range ? range.absoluteStart : absoluteStart, range? range.absoluteEnd : absoluteEnd);
+			
+			var para:ParagraphElement = selRange.firstParagraph;
+			var attr:TextLayoutFormat = new TextLayoutFormat(para.computedFormat);
+			for (;;)
+			{
+				if (para == selRange.lastParagraph)
+					break;
+				para = _textFlow.findAbsoluteParagraph(para.getAbsoluteStart()+para.textLength);
+				attr.removeClashing(para.computedFormat);
+			}
+			return Property.extractInCategory(TextLayoutFormat,TextLayoutFormat.description,attr,Category.PARAGRAPH) as ITextLayoutFormat;
+		 }
+		 
+		/**
+		 * @copy ISelectionManager#getCommonContainerFormat()
+		 * 
+		 * @includeExample examples\SelectionManager_getCommonContainerFormat.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function getCommonContainerFormat (range:TextRange=null):ITextLayoutFormat
+		{
+			if (!range && !hasSelection())
+				return null;
+			
+			// TODO: FIX THIS - tlf_core supports mulutiple containers
+		 	// container attributes changes through the UI apply to TextFlow and all containers 
+		 	// as of changelist# 625596, so all attributes values are 'common'.
+		 	// note: that's true of your UI but that's no guarantee of common - the API supports users doing direct modifications outside the UI
+		 	// need to revisit this when there are linked controllers
+		 	CONFIG::debug { assert(textFlow.flowComposer.numControllers  == 1,"multiple containers not supported by SelectionManager.getCommonContainerFormat"); }
+		 	return Property.extractInCategory(TextLayoutFormat,TextLayoutFormat.description,textFlow.flowComposer.getControllerAt(0).computedFormat,Category.CONTAINER) as ITextLayoutFormat;
+		}
+		 
+		/**
+		 * Refreshes and displays TextFlow selection defined by a beginning and ending index.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		private function updateSelectionAndShapes(tf:TextFlow, begIdx:int, endIdx:int):void
+		{
+			internalSetSelection(tf, begIdx, endIdx);
+			if (_textFlow.flowComposer && _textFlow.flowComposer.numControllers != 0)
+				_textFlow.flowComposer.getControllerAt(_textFlow.flowComposer.numControllers-1).scrollToRange(activeMark.position,anchorMark.position);
+				
+			selectionChanged();
+			clearSelectionShapes();
+			addSelectionShapes();
+		}
+		
+		/** @private */
+		CONFIG::debug tlf_internal function debugCheckTextFlow():int
+		{
+			if (flashx.textLayout.debug.Debugging.debugOn)
+				return _textFlow.debugCheckTextFlow();
+			return 0;
+		}
+		
+		private var marks:Array = [];
+		
+		/** @private */
+		tlf_internal function createMark():Mark
+		{
+			var mark:Mark = new Mark(-1);
+			marks.push(mark);
+			return mark;
+		}
+		/** @private */
+		tlf_internal function removeMark(mark:Mark):void
+		{
+			var idx:int = marks.indexOf(mark);
+			if (idx != -1)
+				marks.splice(idx,idx+1);
+		}
+		
+		/** 
+		 * @copy ISelectionManager#notifyInsertOrDelete()
+		 * 
+		 * @includeExample examples\SelectionManager_notifyInsertOrDelete.as -noswf
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function notifyInsertOrDelete(absolutePosition:int, length:int):void
+		{
+			if (length == 0)
+				return;
+			for (var i:int = 0; i < marks.length; i++)
+			{
+				var mark:Mark = marks[i];
+				if (mark.position >= absolutePosition)
+				{
+					if (length < 0)
+						mark.position = (mark.position + length < absolutePosition) ? absolutePosition : mark.position + length;
+					else
+						mark.position += length;
+				}
+			}
+		}
+	}
+}
diff --git a/textLayout_edit/src/flashx/textLayout/edit/TextClipboard.as b/textLayout_edit/src/flashx/textLayout/edit/TextClipboard.as
new file mode 100755
index 0000000..8ec6133
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/edit/TextClipboard.as
@@ -0,0 +1,366 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.edit
+{
+	import flash.desktop.Clipboard;
+	import flash.desktop.ClipboardFormats;
+	
+	import flashx.textLayout.conversion.*;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.SpanElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.tlf_internal;
+		
+	use namespace tlf_internal;
+
+	/**
+	 * The TextClipboard class copies and pastes TextScrap objects to and from the system clipboard.
+	 * 
+	 * <p>When you copy a TextScrap to the TextClipboard, the information is copied to the
+	 * system clipboard in two clipboard formats. One format is an XML string expressing the copied 
+	 * TextScrap object in Text Layout Markup syntax. This clipboard object uses the format name: 
+	 * "TEXT_LAYOUT_MARKUP". The second format is a plain-text string, which uses the standard 
+	 * Clipboard.TEXT_FORMAT name.</p>
+	 * 
+	 * <p>The methods of the TextClipboard class are static functions, you do not need to
+	 * create an instance of TextClipboard.</p>  
+	 * 
+	 * @see flash.desktop.Clipboard
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	*/
+	public class TextClipboard
+	{	
+		/** @private */
+		static tlf_internal const TEXT_LAYOUT_MARKUP:String = "TEXT_LAYOUT_MARKUP";
+		
+		/** @private */
+		static tlf_internal function getTextOnClipboardForFormat(format:String):String
+		{
+			var systemClipboard:Clipboard = Clipboard.generalClipboard;
+			return (systemClipboard.hasFormat(format)) ? String(systemClipboard.getData(format)) : null;
+		}
+		
+		/**
+		 * Gets any text on the system clipboard as a TextScrap object.
+		 *  
+		 * <p>If the "TEXT_LAYOUT_MARKUP" format is available, this method converts the formatted
+		 * string into a TextScrap and returns it. Otherwise, if the Clipboard.TEXT_Format is available,
+		 * this method converts the plain-text string into a TextScrap. If neither clipboard format
+		 * is available, this method returns <code>null</code>.</p>
+		 * 
+		 * <p>Flash Player requires that the <code>getContents()</code> method be called in a paste event handler. In AIR, 
+		 * this restriction only applies to content outside of the application security sandbox.</p>
+		 * 
+		 * @see flash.events.Event#PASTE
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */										
+		public static function getContents():TextScrap
+		{
+			var retTextScrap:TextScrap = null;
+			var textFlow:TextFlow;
+			var textOnClipboard:String;
+			
+			// first look for text_layout_markup
+			textOnClipboard = getTextOnClipboardForFormat(TEXT_LAYOUT_MARKUP);
+			
+			if ((textOnClipboard != null) && (textOnClipboard != ""))
+			{
+				var originalSettings:Object = XML.settings();
+				try {
+					XML.ignoreProcessingInstructions = false;
+					XML.ignoreWhitespace = false;
+					var xmlTree:XML = new XML(textOnClipboard);
+					var beginArrayChild:XML = xmlTree..*::BeginMissingElements[0];
+					var endArrayChild:XML = xmlTree..*::EndMissingElements[0];
+					var textLayoutMarkup:XML = xmlTree..*::TextFlow[0];
+					
+					textFlow = TextConverter.importToFlow(textLayoutMarkup, TextConverter.TEXT_LAYOUT_FORMAT);
+					
+					if (textFlow != null)
+					{
+						retTextScrap = new TextScrap(textFlow);
+						retTextScrap.beginMissingArray = getBeginArray(beginArrayChild, textFlow);
+						retTextScrap.endMissingArray = getEndArray(endArrayChild, textFlow);
+					}
+				}
+				finally
+				{
+					XML.setSettings(originalSettings);
+				}			
+			}
+			
+			// if there is no retTextScrap let's get the text_format and try that
+			if (retTextScrap == null)
+			{
+				textOnClipboard = getTextOnClipboardForFormat(ClipboardFormats.TEXT_FORMAT);
+
+				if (textOnClipboard != null && textOnClipboard != "")
+				{
+					textFlow = TextConverter.importToFlow(textOnClipboard, TextConverter.PLAIN_TEXT_FORMAT);
+					if (textFlow)
+					{
+						retTextScrap = new TextScrap(textFlow);
+						var firstLeaf:FlowLeafElement = textFlow.getFirstLeaf();
+						if (firstLeaf)
+						{
+							retTextScrap.beginMissingArray.push(firstLeaf);
+							retTextScrap.beginMissingArray.push(firstLeaf.parent);
+							retTextScrap.beginMissingArray.push(textFlow);
+							
+							var lastLeaf:FlowLeafElement = textFlow.getLastLeaf();
+							retTextScrap.endMissingArray.push(lastLeaf);
+							retTextScrap.endMissingArray.push(lastLeaf.parent);
+							retTextScrap.endMissingArray.push(textFlow);
+						}
+					}
+				}
+			}
+			return retTextScrap;
+		}
+		
+		/** @private */
+		tlf_internal static function createTextFlowExportString(scrap:TextScrap):String
+		{
+			var textFlowExportString:String = "";
+			var originalSettings:Object = XML.settings();
+			try
+			{
+				XML.ignoreProcessingInstructions = false;		
+				XML.ignoreWhitespace = false;
+				XML.prettyPrinting = false;
+					
+				var exporter:ITextExporter = TextConverter.getExporter(TextConverter.TEXT_LAYOUT_FORMAT);
+				var result:String = '<?xml version="1.0" encoding="utf-8"?>\n';
+				result += "<TextScrap>\n";
+				result += getPartialElementString(scrap);
+				
+				var xmlExport:XML = exporter.export(scrap.textFlow, ConversionType.XML_TYPE) as XML;
+				result += xmlExport;
+				result += "</TextScrap>\n";				
+				textFlowExportString = result.toString();
+				XML.setSettings(originalSettings);
+			}				
+			catch(e:Error)
+			{
+				XML.setSettings(originalSettings);
+			}
+			return textFlowExportString;
+		}
+		
+		/** @private */
+		tlf_internal static function createPlainTextExportString(scrap:TextScrap):String
+		{
+			// At some point, import/export filters will be installable. We want our clipboard fomat to be
+			// predictable, so we explicitly use the PlainTextExporter 
+			// var plainTextExporter:ITextExporter = TextConverter.getExporter(TextConverter.PLAIN_TEXT_FORMAT);
+			var plainTextExporter:PlainTextExporter = new PlainTextExporter();
+			var plainTextExportString:String = plainTextExporter.export(scrap.textFlow, ConversionType.STRING_TYPE) as String;
+			
+			// The plain text exporter does not append the paragraph separator after the last paragraph
+			// When putting text on the clipboard, the last paragraph should get a separator if it was 
+			// copied through its end, i.e., if its end is not missing 
+			var lastPara:ParagraphElement = scrap.textFlow.getLastLeaf().getParagraph();
+			if (!scrap.isEndMissing(lastPara))
+				plainTextExportString += plainTextExporter.paragraphSeparator;
+			return plainTextExportString;
+		}
+		
+		/** @private */
+		tlf_internal static function setClipboardContents(textFlowExportString:String,plainTextExportString:String):void
+		{	
+			var systemClipboard:Clipboard = Clipboard.generalClipboard;
+			systemClipboard.clear();
+			systemClipboard.setData(TEXT_LAYOUT_MARKUP, textFlowExportString);
+			systemClipboard.setData(ClipboardFormats.TEXT_FORMAT, plainTextExportString);
+		}
+		/**
+		 * Puts a TextScrap onto the system clipboard.  
+		 * 
+		 * <p>The TextScrap is placed onto the system clipboard as both a Text Layout Markup
+		 * representation and a plain text representation.</p>
+		 * 
+		 * <p>Flash Player requires a user event (such as a key press or mouse click) before 
+		 * calling <code>setContents()</code>. In AIR, this restriction only applies to content outside of 
+		 * the application security sandbox. </p>
+		 * 
+		 * @param scrap The TextScrap to paste into the clipboard.
+		 * 
+		 * @see flash.events.Event#COPY
+		 * @see flash.events.Event#CUT
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+ 		 */										
+		public static function setContents(scrap:TextScrap):void
+		{
+			if (scrap == null) 
+				return;
+			var textFlowExportString:String = createTextFlowExportString(scrap);
+			var plainTextExportString:String = createPlainTextExportString(scrap);
+			setClipboardContents(textFlowExportString,plainTextExportString);
+		}
+		
+		private static function getPartialElementString(scrap:TextScrap):String
+		{
+			var beginMissingArray:Array = scrap.beginMissingArray;
+			var endMissingArray:Array = scrap.endMissingArray;
+			var beginMissingString:String = "";
+			var endMissingString:String = "";
+			var resultString:String = "";
+			
+			var curPos:int = beginMissingArray.length - 2;
+			var curFlElement:FlowElement;
+			var curFlElementIndex:int;
+			
+			if (beginMissingArray.length > 0)
+			{
+				beginMissingString = "0";
+				while (curPos >= 0)
+				{
+					curFlElement = beginMissingArray[curPos];
+					curFlElementIndex = curFlElement.parent.getChildIndex(curFlElement);
+					beginMissingString = beginMissingString + "," + curFlElementIndex;
+					curPos--;
+				}
+			}
+			
+			curPos = endMissingArray.length - 2;
+			if (endMissingArray.length > 0)
+			{
+				endMissingString = "0";
+				
+				while (curPos >= 0)
+				{
+					curFlElement = endMissingArray[curPos];
+					curFlElementIndex = curFlElement.parent.getChildIndex(curFlElement);
+					endMissingString = endMissingString + "," + curFlElementIndex;
+					curPos--;					
+				}
+			}
+			
+			if (beginMissingString != "")
+			{
+				resultString = '<BeginMissingElements value="';
+				resultString += beginMissingString;
+				resultString += '"';
+				resultString += '/>\n';
+			}
+			
+			if (endMissingString != "")
+			{
+				resultString += '<EndMissingElements value="';
+				resultString += endMissingString;
+				resultString += '"';
+				resultString += '/>\n';				
+			}
+			return resultString;
+		}
+		
+		private static function getBeginArray(beginArrayChild:XML, textFlow:TextFlow):Array
+		{
+			var beginArray:Array = new Array();
+			var curFlElement:FlowElement = textFlow;
+			if (beginArrayChild != null)
+			{
+				var value:String = (beginArrayChild.@value != undefined) ? String(beginArrayChild.@value) : "";
+				beginArray.push(textFlow);
+				var posOfComma:int = value.indexOf(",");
+				var startPos:int;
+				var endPos:int;
+				var curStr:String;
+				var indexIntoFlowElement:int;
+				while (posOfComma >= 0)
+				{
+					startPos = posOfComma + 1;
+					posOfComma = value.indexOf(",", startPos);
+					if (posOfComma >= 0)
+					{
+						endPos = posOfComma;
+					} else {
+						endPos = value.length;
+					}
+					curStr = value.substring(startPos, endPos);
+					if (curStr.length > 0)
+					{
+						indexIntoFlowElement = parseInt(curStr);
+						if (curFlElement is FlowGroupElement)
+						{
+							curFlElement = (curFlElement as FlowGroupElement).getChildAt(indexIntoFlowElement);
+							beginArray.push(curFlElement);
+						}
+					}
+				}				
+			}
+			return beginArray.reverse();
+		}
+		
+		private static function getEndArray(endArrayChild:XML, textFlow:TextFlow):Array
+		{
+			var endArray:Array = new Array();
+			var curFlElement:FlowElement = textFlow;
+			if (endArrayChild != null)
+			{
+				var value:String = (endArrayChild.@value != undefined) ? String(endArrayChild.@value) : "";
+				endArray.push(textFlow);
+				var posOfComma:int = value.indexOf(",");
+				var startPos:int;
+				var endPos:int;
+				var curStr:String;
+				var indexIntoFlowElement:int;
+				while (posOfComma >= 0)
+				{
+					startPos = posOfComma + 1;
+					posOfComma = value.indexOf(",", startPos);
+					if (posOfComma >= 0)
+					{
+						endPos = posOfComma;
+					} else {
+						endPos = value.length;
+					}
+					curStr = value.substring(startPos, endPos);
+					if (curStr.length > 0)
+					{
+						indexIntoFlowElement = parseInt(curStr);
+						if (curFlElement is FlowGroupElement)
+						{
+							curFlElement = (curFlElement as FlowGroupElement).getChildAt(indexIntoFlowElement);
+							endArray.push(curFlElement);
+						}
+					}
+				}				
+			}
+			return endArray.reverse();
+		}
+
+		
+	} // end TextClipboard class
+}
+
+class TextClipboardSingletonEnforcer {}
diff --git a/textLayout_edit/src/flashx/textLayout/edit/TextFlowEdit.as b/textLayout_edit/src/flashx/textLayout/edit/TextFlowEdit.as
new file mode 100755
index 0000000..aedb08f
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/edit/TextFlowEdit.as
@@ -0,0 +1,1245 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.edit
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.DivElement;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.LinkElement;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.SpanElement;
+	import flashx.textLayout.elements.SubParagraphGroupElement;
+	import flashx.textLayout.elements.TCYElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+	
+	[ExcludeClass]
+	/**
+	 * Encapsulates all methods necessary for dynamic editing of a text.  The methods are all static member functions of this class.
+     * @private - because we can't make it tlf_internal. Used by the operations package 
+	 */	
+	public class TextFlowEdit
+	{
+		private static function deleteRange(theFlow:FlowGroupElement, startPos:int, endPos:int):int
+		{
+			var curFlowElementIdx:int = 0;
+			var curFlowElement:FlowElement;
+			var needToMergeWhenDone:Boolean = false;
+			var relStart:int = 0;
+			var relEnd:int = 0;
+			var s:SpanElement;
+			var processedAnElement:Boolean = false;
+			var totalItemsDeleted:int = 0;
+			var curNumDeleted:int = 0;
+			var tempFlowElement:FlowElement;
+			var numItems:int;
+			
+			while (curFlowElementIdx < theFlow.numChildren)
+			{
+				curFlowElement = theFlow.getChildAt(curFlowElementIdx);
+				relStart = startPos - curFlowElement.parentRelativeStart;
+				if (relStart < 0) relStart = 0;
+				relEnd = endPos - curFlowElement.parentRelativeStart;
+							
+				if ((relStart < curFlowElement.textLength) && (relEnd > 0))
+				{
+					//at least partially selected
+					if ((relStart <= 0) && ((relEnd > curFlowElement.textLength) || ((relEnd >= curFlowElement.textLength) && (curFlowElement is ParagraphElement))))
+					{
+						//completely selected
+						// If the last character of a paragraph is part of the span, it won't get deleted. We will skip over it for now, and may delete it later as 
+						// part of a paragraph merge.
+						curNumDeleted = curFlowElement.textLength;
+						var skippingTerminator:Boolean = curFlowElementIdx == theFlow.numChildren - 1 && (curFlowElement is SpanElement) && (theFlow is ParagraphElement);
+						theFlow.replaceChildren(curFlowElementIdx, curFlowElementIdx + 1, null);
+						if (skippingTerminator)
+							++curFlowElementIdx;
+						totalItemsDeleted += curNumDeleted;
+						endPos -= curNumDeleted;
+					} else { //not completely selected
+						if (curFlowElement is SpanElement) {
+							s = curFlowElement as SpanElement;
+							
+							if(relEnd > s.textLength) 
+								relEnd = s.textLength;	
+								
+							s.replaceText(relStart, relEnd, "");
+							curNumDeleted = (relEnd - relStart);
+							totalItemsDeleted += curNumDeleted;
+							endPos -= curNumDeleted;
+						} else if (!(curFlowElement is FlowGroupElement))
+						{
+							curNumDeleted = curFlowElement.textLength;
+							totalItemsDeleted += curFlowElement.textLength;
+							endPos -= curNumDeleted;
+							theFlow.replaceChildren(curFlowElementIdx, curFlowElementIdx + 1, null);			
+						} else { //it must be a FlowGroupElement of some kind
+							if ((!processedAnElement) && (relEnd >= curFlowElement.textLength))
+							{
+								if (curFlowElement is ParagraphElement)
+									needToMergeWhenDone = true;
+								else if (curFlowElement is FlowGroupElement)
+								{
+									numItems = (curFlowElement as FlowGroupElement).numChildren;
+									if (numItems > 0)
+									{
+										tempFlowElement = (curFlowElement as FlowGroupElement).getChildAt(numItems - 1);
+										if (tempFlowElement is ParagraphElement)
+										{
+											needToMergeWhenDone = true;
+										}
+									}
+								}
+							}							
+							curNumDeleted = TextFlowEdit.deleteRange(curFlowElement as FlowGroupElement, relStart, relEnd);
+							totalItemsDeleted += curNumDeleted;
+							endPos -= curNumDeleted;
+							if (needToMergeWhenDone == true) 
+								endPos++;
+							if (!(curFlowElement is ParagraphElement)) 
+								needToMergeWhenDone = false;
+						}
+						if (processedAnElement)
+						{
+							break;
+						}						
+						curFlowElementIdx++;
+					}
+					processedAnElement = true;
+				} else if (processedAnElement)
+				{
+					break;
+				} else {
+					curFlowElementIdx++;
+				}
+			}
+			if (needToMergeWhenDone)
+			{
+				joinNextParagraph(ParagraphElement(curFlowElement.getPreviousSibling()));
+			}
+			
+			return totalItemsDeleted;
+		}
+		
+		private static function isFlowElementInArray(arr:Array, fl:FlowElement):Boolean
+		{
+			if (arr != null)
+			{
+				var arrLen:int = arr.length;
+				var currPos:int = 0;
+				while (currPos < arrLen)
+				{
+					if (arr[currPos] == fl)
+					{
+						return true;
+					}
+					currPos++;
+				}
+			}
+			return false;
+		}
+				
+		private static function getContainer(flEl:FlowElement):ContainerFormattedElement
+		{
+			while (!(flEl.parent is ContainerFormattedElement))
+			{
+				flEl = flEl.parent;
+			}
+			return flEl.parent as ContainerFormattedElement;
+		}
+		
+		private static function isInsertableItem(flItem:FlowElement, missingBeginElements:Array, missingEndElements:Array):Boolean
+		{
+			return ((flItem is ParagraphElement) ||
+					(!TextFlowEdit.isFlowElementInArray(missingBeginElements, flItem) &&
+					 !TextFlowEdit.isFlowElementInArray(missingEndElements, flItem)));
+		}
+		
+		private static function putDivAtEndOfContainer(container:ContainerFormattedElement):DivElement
+		{
+			var tempDiv:DivElement = new DivElement();
+			var tempPar:ParagraphElement = new ParagraphElement();
+			tempPar.replaceChildren(0, 0, new SpanElement());
+			tempDiv.replaceChildren(0, 0, tempPar);
+			container.replaceChildren(container.numChildren, container.numChildren, tempDiv);
+			return tempDiv;			
+		}
+		
+		private static function putDivAtEndOfContainerAndInsertTextFlow(theFlow:TextFlow, pos:int, insertedTextFlow:FlowGroupElement, missingBeginElements:Array, missingEndElements:Array, separatorArray:Array):int
+		{
+			var tempFlChild:FlowElement;
+			var nextInsertionPosition:int = pos;
+			var insertContainer:ContainerFormattedElement = TextFlowEdit.getContainer(theFlow.findAbsoluteParagraph(nextInsertionPosition));						
+			var tempDiv:DivElement = TextFlowEdit.putDivAtEndOfContainer(insertContainer);
+			separatorArray.push(tempDiv);
+			while (insertedTextFlow.numChildren > 0)
+			{
+				tempFlChild = insertedTextFlow.getChildAt(0);
+				insertedTextFlow.replaceChildren(0, 1, null);
+				nextInsertionPosition = TextFlowEdit.insertTextFlow(theFlow, nextInsertionPosition, tempFlChild as FlowGroupElement, missingBeginElements, missingEndElements, separatorArray);
+			}
+			var elementIdx:int = tempDiv.parent.getChildIndex(tempDiv);
+			tempDiv.parent.replaceChildren(elementIdx, elementIdx + 1, null);
+			separatorArray.pop();
+			return nextInsertionPosition;
+		}
+		
+		private static function isContainerSeparator(fl:FlowElement, separatorArray:Array):Boolean
+		{
+			var i:int = 0;
+			var numItemsInArray:int = separatorArray.length;
+			while (i < numItemsInArray)
+			{
+				if (separatorArray[i] == fl)
+				{
+					return true;
+				}
+				i++;
+			}
+			return false;
+		}
+		
+		private static var processedFirstFlowElement:Boolean = false;
+		private static function insertTextFlow(theFlow:TextFlow, pos:int, insertedTextFlow:FlowGroupElement, missingBeginElementsInFlow:Array = null, missingEndElementsInFlow:Array = null, separatorArray:Array = null):int
+		{
+			var nextInsertionPosition:int = pos;
+						
+			if (!TextFlowEdit.isInsertableItem(insertedTextFlow, missingBeginElementsInFlow, missingEndElementsInFlow) ||
+				(insertedTextFlow is TextFlow))
+			{
+				if (insertedTextFlow is TextFlow)
+				{
+					processedFirstFlowElement = false;
+					var tempDiv:DivElement = TextFlowEdit.putDivAtEndOfContainer(theFlow as ContainerFormattedElement);
+					separatorArray = new Array();
+					separatorArray.push(tempDiv);
+				}
+				var tempFlChild:FlowElement = insertedTextFlow.getChildAt(0);
+				if (TextFlowEdit.isInsertableItem(tempFlChild, missingBeginElementsInFlow, missingEndElementsInFlow))
+				{
+					nextInsertionPosition = TextFlowEdit.putDivAtEndOfContainerAndInsertTextFlow(theFlow, nextInsertionPosition, insertedTextFlow, missingBeginElementsInFlow, missingEndElementsInFlow, separatorArray);  
+				} else {				
+					while (insertedTextFlow.numChildren > 0)
+					{
+						tempFlChild = insertedTextFlow.getChildAt(0);
+						insertedTextFlow.replaceChildren(0, 1, null);
+						nextInsertionPosition = TextFlowEdit.insertTextFlow(theFlow, nextInsertionPosition, tempFlChild as FlowGroupElement, missingBeginElementsInFlow, missingEndElementsInFlow, separatorArray);
+					}
+				}
+				
+				if (insertedTextFlow is TextFlow)
+				{
+					theFlow.replaceChildren(theFlow.numChildren - 1, theFlow.numChildren, null);
+					if (nextInsertionPosition >= theFlow.textLength)
+					{
+						nextInsertionPosition = theFlow.textLength - 1;
+					}
+					separatorArray.pop();					
+				}				
+			} else {
+				//if you are inserting at the very end of a paragraph, bump up the position
+				//by one.  Otherwise, if you are not at the end of the paragraph, split at
+				//the position, and then move up by 1.
+										
+				var leafEl:FlowLeafElement = null;
+				if (pos > 0) leafEl = theFlow.findLeaf(pos - 1);
+				var para:ParagraphElement = theFlow.findAbsoluteParagraph(pos);
+				var paraSplitIndex:int = pos - para.getAbsoluteStart();
+				var flowElIndex:int = para.parent.getChildIndex(para);
+				var okToMergeWithAfter:Boolean = true;
+				
+				if (paraSplitIndex > 0)
+				{
+					if (paraSplitIndex < (para.textLength - 1))
+					{
+						
+						para.splitAtPosition(paraSplitIndex);
+						
+					} else if ((insertedTextFlow.textLength == 1) && !processedFirstFlowElement) {
+						if (TextFlowEdit.isFlowElementInArray(missingEndElementsInFlow, insertedTextFlow) ||
+							TextFlowEdit.isFlowElementInArray(missingBeginElementsInFlow, insertedTextFlow))
+						{ 
+							processedFirstFlowElement = true;
+							return nextInsertionPosition;
+						} else {
+							
+							para.splitAtPosition(paraSplitIndex);
+									
+						}
+					} else {
+						okToMergeWithAfter = false;
+					}
+					pos++;
+				} else { //no split done. So we want to insert after the previous paragraph.
+					flowElIndex = flowElIndex - 1;
+				}
+			
+				//insert the insertedTextFlow after the paragraph at paragraphIndex
+				var paragraphContainer:FlowGroupElement = para.parent;
+				
+				if (TextFlowEdit.isContainerSeparator(paragraphContainer, separatorArray))
+				{
+					flowElIndex = paragraphContainer.parent.getChildIndex(paragraphContainer);
+					paragraphContainer = paragraphContainer.parent;
+					flowElIndex--;	
+				}
+				
+				paragraphContainer.replaceChildren(flowElIndex + 1, flowElIndex + 1, insertedTextFlow);
+				nextInsertionPosition = pos + insertedTextFlow.textLength;
+
+				if (insertedTextFlow is ParagraphElement)
+				{	
+					var missingEnd:Boolean = TextFlowEdit.isFlowElementInArray(missingEndElementsInFlow, insertedTextFlow);
+					if (okToMergeWithAfter && missingEnd)
+					{
+						// Merge the paragraph with what comes next. If the inserted paragraph is inserted to the middle or end of the paragraph,
+						// then merge the next paragraph into the inserted paragraph. If we're inserting to the start of the paragraph, merge
+						// the inserted paragraph into the next paragraph, so that the original host paragraph maintains its format settings.
+						if (paraSplitIndex == 0)
+						{
+							if (joinToNextParagraph(ParagraphElement(insertedTextFlow)))
+								nextInsertionPosition--;
+						}
+						else if (joinNextParagraph(ParagraphElement(insertedTextFlow)))
+							nextInsertionPosition--;
+					}
+
+					if (!processedFirstFlowElement)
+					{
+						if (paraSplitIndex > 0)
+						{
+							var prevSibling:ParagraphElement = insertedTextFlow.getPreviousSibling() as ParagraphElement;
+							if (prevSibling && joinNextParagraph(prevSibling))
+								nextInsertionPosition--;
+						}
+					}
+					
+					if (missingEnd)
+					{
+						var absolutePar:ParagraphElement = paragraphContainer.getTextFlow().findAbsoluteParagraph(nextInsertionPosition);
+						var absoluteParIndex:int = absolutePar.getAbsoluteStart();
+						if ((nextInsertionPosition - absolutePar.getAbsoluteStart()) == 0)
+						{
+							nextInsertionPosition--;
+						}
+					}
+				}
+				
+				
+				processedFirstFlowElement = true;			
+			}
+			return nextInsertionPosition;
+		}
+		
+		/**
+		 * Replaces the range of text positions that the <code>startPos</code> and
+		 * <code>endPos</code> parameters specify with the <code>newTextFlow</code> parameter in
+		 * <code>theFlow</code>.
+		 * <p>To delete elements, pass <code>null</code> for <code>newTextFlow</code>.</p>
+		 * <p>To insert an element, pass the same value for <code>startPos</code> and <code>endPos</code>.
+		 * <p>To insert a newline after the <code>newTextFlow</code> is inserted, pass in
+		 * <code>true</code> for <code>insertParAfter</code></p>   
+		 * <p>The new element will be inserted before the specified index.</p>
+		 * <p>To append the TextFlow, pass <code>theFlow.length</code> for <code>startPos</code> and <code>endPos</code>.</p>
+		 * 
+		 * @param theFlow The TextFlow that is being inserted into.
+		 * @param startPos The index value of the first position of the replacement range in the TextFlow.
+		 * @param endPos The index value following the end position of the replacement range in the TextFlow.
+		 * @param newTextFlow The TextFlow to be merged into theFlow.
+		 * @param missingBeginElementsInFlow Array indicating all the elements within the TextFlow that have their beginning parts chopped off.
+		 * @param missingEndElementsInFlow Array indicating all the elements within the TextFlow that have their ending parts chopped off.
+		 */				
+		public static function replaceRange(theFlow:TextFlow, startPos:int, endPos:int, textScrap:TextScrap = null):int
+		{
+			var nextInsertPosition:int = startPos;
+			if (endPos > startPos)
+			{
+				deleteRange(theFlow, startPos, endPos);
+			}
+			
+			if (textScrap != null)
+			{
+				textScrap = textScrap.clone();	// make a copy so the original isn't mutated
+				nextInsertPosition = insertTextFlow(theFlow, startPos, textScrap.textFlow, textScrap.beginMissingArray, textScrap.endMissingArray);	
+			}
+			return nextInsertPosition;
+		}
+
+		/**
+		 * Creates a copy of the TextFlow in between two positions and returns the TextFlow
+		 * within a TextScrap object.  See TextScrap for more information.
+		 * @param theFlow The TextFlow that is being copied from.
+		 * @param startPos The index value of the first position of the TextFlow being copied from.
+		 * @param endPos The index value following the end position of the TextFlow being copied from.
+		 */			 
+		public static function createTextScrap(theFlow:TextFlow, startPos:int, endPos:int):TextScrap
+		{
+			if (!theFlow || startPos >= endPos) 
+				return null;
+			var newTextFlow:TextFlow = theFlow.deepCopy(startPos, endPos) as TextFlow;
+			newTextFlow.normalize();
+			var retTextScrap:TextScrap = new TextScrap(newTextFlow);
+			if (newTextFlow.textLength > 0)
+			{
+				var fl:FlowElement = newTextFlow.getLastLeaf();
+			
+				var srcElem:FlowElement = theFlow.findLeaf(startPos);
+				var copyElem:FlowElement = newTextFlow.getFirstLeaf();
+				while (copyElem && srcElem)
+				{
+					if ((startPos - srcElem.getAbsoluteStart()) > 0)
+					{
+						retTextScrap.addToBeginMissing(copyElem);
+					}
+					copyElem = copyElem.parent;
+					srcElem = srcElem.parent;
+				}
+			
+				srcElem = theFlow.findLeaf(endPos - 1);
+				copyElem = newTextFlow.getLastLeaf();
+				if ((copyElem is SpanElement) && (!(srcElem is SpanElement)))
+				{
+					copyElem = newTextFlow.findLeaf(newTextFlow.textLength - 2);
+				}
+				
+				while (copyElem && srcElem)
+				{
+					if (endPos < (srcElem.getAbsoluteStart() + srcElem.textLength))
+					{
+						retTextScrap.addToEndMissing(copyElem);
+					}
+					copyElem = copyElem.parent;
+					srcElem = srcElem.parent;
+				}
+				return retTextScrap;
+			}
+			return null;
+		}		
+		
+		/**
+		 * Creates a TCY run out of the selected positions.
+		 * @param theFlow The TextFlow of interest.
+		 * @param startPos The index value of the first position of the TextFlow to be turned into a TCY run.
+		 * @param endPos The index value following the end position of the TextFlow to be turned into a TCY run.
+		 */	
+		public static function makeTCY(theFlow:TextFlow, startPos:int, endPos:int):Boolean
+		{
+			var madeTCY:Boolean = true;
+			var curPara:ParagraphElement = theFlow.findAbsoluteParagraph(startPos);
+			if(!curPara)
+				return false;
+			while(curPara)
+			{
+				var paraEnd:int = curPara.getAbsoluteStart() + curPara.textLength;
+				var curEndPos:int = Math.min(paraEnd, endPos);
+				
+				//we have an entire para selected and the para only contains a kParaTerminator char, which cannot be
+				//made into TCY. 
+				if(canInsertSPBlock(theFlow, startPos, curEndPos, TCYElement) && curPara.textLength > 1)
+				{
+					var new_tcyElem:TCYElement = new TCYElement();
+					
+					//don't hide an error!
+					if(madeTCY)
+						madeTCY = insertNewSPBlock(theFlow, startPos, curEndPos, new_tcyElem, TCYElement);
+					else
+						insertNewSPBlock(theFlow, startPos, curEndPos, new_tcyElem, TCYElement);
+				}
+				else
+					madeTCY = false;
+				
+				if(paraEnd < endPos)
+				{
+					curPara = theFlow.findAbsoluteParagraph(curEndPos);	
+					startPos = curEndPos;
+				}
+				else
+					curPara = null;
+			}
+			
+			return madeTCY;
+		}
+		
+		/**
+		 * Creates one or more LinkElements out of the selected positions. It will go through
+		 * every paragraph within the selected position and make links.
+		 * @param theFlow The TextFlow of interest.
+		 * @param startPos The index value of the first position of the TextFlow to be turned into a link.
+		 * @param endPos The index value following the end position of the TextFlow to be turned into a link.
+		 * @param urlString The url string to be associated with the link.
+		 */			
+		public static function makeLink(theFlow:TextFlow, startPos:int, endPos:int, urlString:String, target:String):Boolean
+		{
+			var madeLink:Boolean = true;
+			var curPara:ParagraphElement = theFlow.findAbsoluteParagraph(startPos);
+			if(!curPara)
+				return false;
+				
+			while(curPara)
+			{
+				var paraEnd:int = curPara.getAbsoluteStart() + curPara.textLength;
+				var curEndPos:int = Math.min(paraEnd, endPos);
+				var linkEndPos:int = (curEndPos == paraEnd) ? (curEndPos - 1) : curEndPos;
+				if (linkEndPos > startPos)
+				{
+					//if the end of the paragraph is < endPos, we are going across bounds
+					if(!canInsertSPBlock(theFlow, startPos, linkEndPos, LinkElement))
+					{
+						return false;
+					}
+				
+					var newLinkElement:LinkElement = new LinkElement();
+					newLinkElement.href = urlString;
+					newLinkElement.target = target;
+				
+					//don't hide an error!
+					if(madeLink)
+						madeLink = insertNewSPBlock(theFlow, startPos, linkEndPos, newLinkElement, LinkElement);
+					else
+						insertNewSPBlock(theFlow, startPos, linkEndPos, newLinkElement, LinkElement);
+				}	
+				if(paraEnd < endPos)
+				{
+					curPara = theFlow.findAbsoluteParagraph(curEndPos);	
+					startPos = curEndPos;
+				}
+				else
+					curPara = null;
+			}
+			
+			return madeLink;
+		}
+		
+		
+		/**
+		 * Removes the TCY block at the selected positions. 
+		 * @param theFlow The TextFlow of interest.
+		 * @param startPos The index value of the first position of the TextFlow.
+		 * @param endPos The index value following the end position of the TextFlow.
+		 */			
+		public static function removeTCY(theFlow:TextFlow, startPos:int, endPos:int):Boolean
+		{
+			if (endPos <= startPos)
+			{
+				return false;
+			}
+			
+			return findAndRemoveFlowGroupElement(theFlow, startPos, endPos, TCYElement);;
+		}
+		
+		/**
+		 * Removes all LinkElements under the selected positions. It will go through
+		 * every paragraph within the selected position and remove any link.
+		 * @param theFlow The TextFlow of interest.
+		 * @param startPos The index value of the first position of the TextFlow.
+		 * @param endPos The index value following the end position of the TextFlow.
+		 */			
+		public static function removeLink(theFlow:TextFlow, startPos:int, endPos:int):Boolean
+		{
+			if (endPos <= startPos)
+			{
+				return false;
+			}
+			
+			return findAndRemoveFlowGroupElement(theFlow, startPos, endPos, LinkElement);
+		}
+		
+		/**
+		 * @private
+		 * insertNewSPBlock - add a SubParagraphGroupElement (spg) to <code>theFlow</code> at the indicies specified by <code>startPos</code> and
+		 * <code>endPos</code>.  The <code>newSPB</code> will take ownership of any FlowElements within the range and will split them
+		 * as needed.  If the parent of the FlowGroupElement indicated by <code>startPos</code> is the same as <code>spgClass</code> then
+		 * the method fails and returns false because a spg cannot own children of the same class as itself.  Any spg of type <code>spgClass</code>
+		 * found within the indicies, however, is subsumed into <code>newSPB</code>, effectively replacing it.
+		 *
+		 * @param theFlow:TextFlow - The TextFlow that is the destination for the newSPB
+		 * @param startPos:int - The absolute index value of the first position of the range in the TextFlow to perform the insertion.
+		 * @param endPos:int - The index value following the end position of the range in the TextFlow to perform the insertion.
+		 * @param newSPB:SubParagraphGroupElement - The new SubParagraphElement which is to be added into theFlow.
+		 * @param spgClass:Class - the class of the fbe we intend to add.
+		 * 
+		 * Examples: Simple and complex where insertion is of <code>spgClass</code> b.  Selection is l~o
+		 *		1) <a><span>ghijklmnop</span></a>
+		 * 		2) <a><span>ghij</span><b><span>klm</span></b><span>nop</span></a>
+		 * 		3) <a><span>ghijk</span><c><span>lmn</span></c><span>op</span></a>
+		 * 
+		 */
+		tlf_internal static function insertNewSPBlock(theFlow:TextFlow, startPos:int, endPos:int, newSPB:SubParagraphGroupElement, spgClass:Class):Boolean
+		{
+			var curPos:int = startPos;
+			var curFBE:FlowGroupElement = theFlow.findAbsoluteFlowGroupElement(curPos);
+			var elementIdx:int = 0;
+			
+			CONFIG::debug{ assert(curFBE != null, "No FBE at location curPos(" + curPos + ")!");}
+			
+			//if we are at the last "real" glyph of the paragraph, include the terminator.
+			var paraEl:ParagraphElement = curFBE.getParagraph();
+			if(endPos == (paraEl.getAbsoluteStart() + paraEl.textLength - 1))
+				++endPos;
+			
+			//before processing this any further, we need to make sure that we are not
+			//splitting a spg which is contained within the same type of spg as the curFBE's parent.
+			//for example, if we had a tcyElement inside a linkElement, then we cannot allow a link element
+			//to be made within the tcyElement as the link would not function.  As a rule, a SubParagraphElement
+			//cannot own a child of the same class.
+			//
+			//However, if the curFBE is parented by a spg and the objects have the same start and end, then we are doing
+			//a replace and we're not splitting the parent. Check if the bounds are the same and if so, don't skip it...
+			var parentStart:int = curFBE.parent.getAbsoluteStart();
+			var curFBEStart:int = curFBE.getAbsoluteStart();
+			if(curFBE.parent && curFBE.parent is spgClass && 
+				!(parentStart == curFBEStart && parentStart + curFBE.parent.textLength == curFBEStart + curFBE.textLength))
+			{
+				return false;
+			}
+			
+			//entire FBE is selected and is not a paragraph, get its parent.
+			if(!(curFBE is ParagraphElement) && curPos == curFBEStart && curPos + curFBE.textLength <= endPos)
+			{
+				elementIdx = curFBE.parent.getChildIndex(curFBE);
+				curFBE = curFBE.parent;
+			}
+			//first, if the curFBE is of the same class as the newSPB, then we need to split it to allow for insertion
+			//of the new one IF the start position is > the start of the curFBE
+			//
+			//running example after this block:
+			//	1) <a><span>ghijk</span><span>lmnop</span></a>
+			//	2) <a><span>ghij</span><b><span>k</span></b><b><span>lm</span></b><span>nop</span></a>
+			//	3) <a><span>ghijk</span><c><span>lmn</span></c><span>op</span></a> - no change
+			if(curPos >= curFBEStart)
+			{
+				if(!(curFBE is spgClass))
+					elementIdx = findAndSplitElement(curFBE, elementIdx, curPos, true);
+				else
+				{
+					elementIdx = findAndSplitElement(curFBE.parent, curFBE.parent.getChildIndex(curFBE), curPos, false);
+					curFBE = curFBE.parent;
+				}
+			}
+			
+			//now that the curFBE has been split, we want to insert the newSPB into the flow and then start absorbing the
+			//contents...
+			//running example after this block:
+			//	1) <a><span>ghijk</span><b></b><span>lmnop</span></a>
+			//	2) <a><span>ghij</span><b><span>k</span></b><b></b><b><span>lm</span></b><span>nop</span></a>
+			//	3) <a><span>ghijk</span><b></b><c><span>lmn</span></c><span>op</span></a> - no change
+			//
+		//	we need another use case here where selection is entire sbp and selection runs from the head of a spg to
+		//	part way through it - so that a) does into parent and b) goes into spg
+			
+			// if this is case 2, then the new element must go into the parent...
+			if(curFBE is spgClass)
+			{
+				curFBEStart = curFBE.getAbsoluteStart();
+				elementIdx = curFBE.parent.getChildIndex(curFBE);
+				if(curPos > curFBEStart)//we're splitting the element, not replacing it...
+					elementIdx += 1;
+				
+				//if the spg, curFBE is entirely selected then we want to use the parent, not the item itself.
+				while(endPos >= curFBEStart + curFBE.textLength)
+				{
+					//we need access to the parent, which contains both the start and end not the FBE we just split
+					curFBE = curFBE.parent;
+				}
+				curFBE.replaceChildren(elementIdx, elementIdx, newSPB);
+			}
+			else
+			{
+				//we're inserting into the curFBE
+				curFBE.replaceChildren(elementIdx, elementIdx, newSPB);
+			}
+			
+			//see subsumeElementsToSPBlock to see effects on running example
+			subsumeElementsToSPBlock(curFBE, elementIdx + 1, curPos, endPos, newSPB, spgClass);
+			
+			return true;
+		}
+		
+		
+		/**
+		 * @private
+		 * splitElement - split <code>elem</code> at the relative index of <code>splitPos</code>.  If <code>splitSubBlockContents</code>
+		 * is true, split the contents of <code>elem</code> if it is a SubParagraphGroupElement, otherwise just split <code>elem</code>
+		 * 
+		 * @param elem:FlowElement - the FlowElement to split
+		 * @param splitPos:int - The elem relative index indicating where to split
+		 * @param splitSubBlockContents:Boolean - boolean indicating whether a SubParagraphGroupElement is to be split OR that it's contents
+		 * should be split.  For example, are we splitting a link or are we splitting the child of the link
+		 * 
+		 * <spg><span>ABCDEF</span></spg>
+		 * 
+		 * if <code>splitPos</code> indicated index between C and D, then if <code>splitSubBlockContents</code> equals true,
+		 * result is:
+		 * 
+		 * <spg><span>ABC</span><span>DEF</span></spg>
+		 * 
+		 * if <code>splitSubBlockContents</code> equals false, result is:
+		 * 
+		 * <spg><span>ABC</span></spg><spg><span>DEF</span></spg>
+		 */
+		tlf_internal static function splitElement(elem:FlowElement, splitPos:int, splitSubBlockContents:Boolean):void
+		{
+			CONFIG::debug{ assert(splitPos < elem.textLength, "trying to splic FlowElement at illegal index!"); }
+			if (elem is SpanElement)
+			{
+				SpanElement(elem).splitAtPosition(splitPos);
+			}
+			else if(elem is SubParagraphGroupElement && splitSubBlockContents)
+			{
+				var subBlock:SubParagraphGroupElement = SubParagraphGroupElement(elem);
+				// Split the SpanElement of the block at splitPos.  If the item at the splitPos is not a SpanElement, no action occurs.
+				var tempElem:SpanElement = subBlock.findLeaf(splitPos) as SpanElement;
+				if (tempElem)
+					tempElem.splitAtPosition(splitPos - tempElem.getElementRelativeStart(subBlock));
+			}
+			else if (elem is FlowGroupElement)
+			{
+				FlowGroupElement(elem).splitAtPosition(splitPos);
+			}
+			else
+			{
+				CONFIG::debug { assert(false, "Trying to split on an illegal FlowElement"); }				
+			}
+		}
+		
+		/**
+		 * @private
+		 * findAndSplitElement - starting at the child <code>elementIdx</code> of <code>fbe</code>, iterate
+		 * through the elements untill we find the one located at the aboslute index of <code>startIdx</code>. Upon
+		 * locating the child, split either the element itself OR its children based on the value of <code>splitSubBlockContents</code>
+		 * 
+		 * @param fbe:FlowGroupElement - the FBE into which the newSPB is being inserted.
+		 * @param elementIdx:int - The index into the <code>fbe's</code> child list to start
+		 * @param startIdx:int - The absolute index value into the TextFlow.
+		 * @param splitSubBlockContents:Boolean - boolean indicating whether a subElement is to be split OR that it's contents
+		 * should be split.  For example, are we splitting a link or are we splitting the child of the link
+		 * 
+		 * <p>ZYX<link>ABCDEF</link>123</p>
+		 * 
+		 * if we are inserting a TCY into the link, splitSubBlockContents should be false. We want to split the span ABCDEF such that result is:
+		 * <p>ZYX<link>AB<tcy>CD</tcy>EF</link>123</p>
+		 * 
+		 * if we are creating a new link from X to B, then we want the link to split and splitSubBlockContents should be false:
+		 * 
+		 * <p>ZY<link>XAB</link><link>CDEF</link>123</p>
+		 * 
+		 * @return int - the index of the last child of <code>fbe</code> processed.
+		 */
+		tlf_internal static function findAndSplitElement(fbe:FlowGroupElement, elementIdx:int, startIdx:int, splitSubBlockContents:Boolean):int
+		{
+			var curFlowEl:FlowElement = null;
+			var curIndexInPar:int = startIdx - fbe.getAbsoluteStart();
+			
+			while(elementIdx < fbe.numChildren)
+			{
+				curFlowEl = fbe.getChildAt(elementIdx);
+				if (curIndexInPar == curFlowEl.parentRelativeStart)
+					return elementIdx;
+				if ((curIndexInPar > curFlowEl.parentRelativeStart) && (curIndexInPar < curFlowEl.parentRelativeEnd))
+				{
+					splitElement(curFlowEl, curIndexInPar - curFlowEl.parentRelativeStart, splitSubBlockContents); 
+				}
+				++elementIdx;
+			}
+			return elementIdx;
+		}
+		
+		/**
+		 * @private
+		 * subsumeElementsToSPBlock - incorporates all elements of <code>parentFBE</code> into
+		 * the <code>newSPB</code> between the <code>curPos</code> and <code>endPos</code>.  If a child of
+		 * <code>parentFBE</code> is of type <code>spgClass</code> then the child's contents are removed from the child,
+		 * added to the <code>newSPB</code>, the child is then removed from the <code>parentFBE</code>
+		 * 
+		 * @param parentFBE:FlowGroupElement - the FBE into which the newSPB is being inserted.
+		 * @param startPos:int - The index value of the first position of the replacement range in the TextFlow.
+		 * @param endPos:int - The index value following the end position of the replacement range in the TextFlow.
+		 * @param newSPB:SubParagraphGroupElement - the new SubParagraphGroupElement we intend to insert.
+		 * @param spgClass:Class - the class of the fbe we intend to insert.
+		 * 
+		 * @return int - the aboslute index in the text flow after insertion.
+		 * 
+		 *  Examples: Simple and complex where insertion is of <code>spgClass</class> b.  Selection is l~o
+		 *		1) <a><span>ghijk</span><b></b><span>lmnop</span></a>
+		 *		2) <a><span>ghij</span><b><span>k</span></b><b></b><b><span>lm</span></b><span>nop</span></a>
+		 * 
+		 * 	parentFBE = <a>
+		 *  elementIdx = 1) 2, 2) 3
+		 *  curPos = 5
+		 *  endPos = 9
+		 *  newSPB is of type <b>
+		 */
+		tlf_internal static function subsumeElementsToSPBlock(parentFBE:FlowGroupElement, elementIdx:int, curPos:int, endPos:int, newSPB:SubParagraphGroupElement, spgClass:Class):int
+		{
+			var curFlowEl:FlowElement = null;
+			
+			//if we have an invalid index, then skip out.  elementIdx will always point one
+			//element beyond the one we are inserting....
+			if(elementIdx >= parentFBE.numChildren)
+				return curPos;
+			
+			while (curPos < endPos)
+			{
+				//running example: curFlowEl is the element immediately after the inserted newSPB:
+				//	1) <a><span>ghijk</span><b></b><span>lmnop</span></a>
+				//		points to span-lmnop
+				//	2) <a><span>ghij</span><b><span>k</span></b><b></b><b><span>lm</span></b><span>nop</span></a>
+				//		points to b-lm
+				curFlowEl = parentFBE.getChildAt(elementIdx);
+				
+				//if the curFlowEl is of the Class we are adding (spgClass), and the entire thing is selected,
+				//then we are adding the entire block, but not spliting it - perform the split on the next block
+				
+				//I think this can be safely removed from here as ownership of contents is handled below.
+				//leaving in commented out code in case we need to revert - gak 05.01.08
+			/*	if(curFlowEl is spgClass && curPos == curFlowEl.getAbsoluteStart() && curFlowEl.getAbsoluteStart() + curFlowEl.textLength <= endPos)
+				{
+					curPos = parentFBE.getAbsoluteStart() + parentFBE.textLength;
+					continue;
+				}*/
+				
+				//if the endPos is less than the length of the curFlowEl, then we need to split it.
+				//if the curFlowEl is NOT of class type spgClass, then we need to break it
+				//
+				//Use case: splitting a link in two (or three as will be the result with head and tail sharing
+				//attributes...
+				//running example 1 hits this, but 2 does not. Using variation of 2:
+				//
+				// example: 1) <a><span>ghijk</span><b></b><span>lmnop</span></a>
+				// 			2a) <a><span>fo</span><b></b><b><span>obar</span></b></a> - selection: from o~a
+				//
+				// after this code:
+				//			1) <a><span>ghijk</span><b></b><span>lmno</span><span>p</span></a>
+				//			2a) <a><span>fo</span><b></b><b><span>oba</span></b><b><span>or</span></b></a>
+				if ((curPos + curFlowEl.textLength) > endPos)
+				{
+					splitElement(curFlowEl, endPos - curFlowEl.getAbsoluteStart(), !(curFlowEl is spgClass));  //changed to curFlowEl from newSPB as newSPB should be of type spgClass
+				}
+				
+				//add the length before replacing the elements
+				curPos += curFlowEl.textLength;
+				
+				//running example: after parentFBE.replaceChildren
+				//
+				//	1) curFlowEl = <span>lmno</span>
+				//		<a><span>ghijk</span><b></b>{curFlowEl}<span>p</span></a>
+				//
+				//	2) curFlowEl = <b><span>lm</span></b>
+				//		<a><span>ghij</span><b><span>k</span></b><b></b>{curFlowEl}<span>nop</span></a>
+				parentFBE.replaceChildren(elementIdx, elementIdx + 1, null);
+				
+				//if the curFlowEl is of type spgClass, then we need to take its children and
+				//add them to the newSPB because a spg cannot contain a child of the same class
+				//as itself
+				//
+				// exmaple: 2) curFlowEl = <b><span>lm</span></b>
+				if (curFlowEl is spgClass)
+				{
+					var subBlock:SubParagraphGroupElement = curFlowEl as SubParagraphGroupElement;
+					//elementCount == 1 - <span>lm</span>
+					while (subBlock.numChildren > 0)
+					{
+						//fe[0] = <span>lm</span>
+						var fe:FlowElement = subBlock.getChildAt(0);
+						//<span></span>
+						subBlock.replaceChildren(0, 1, null);
+						//<b><span>lm</span></b>
+						newSPB.replaceChildren(newSPB.numChildren, newSPB.numChildren, fe);
+					}
+					//when compelete, example 2 is:
+					//2) <a><span>ghij</span><b><span>k</span></b><b><span>lm</span></b><span>nop</span></a>
+				}
+				else 
+				{
+					//example 1, curFlowEl is <span>lmno</span>, so this is not hit
+					//
+					// extending element <a> from foo~other
+					// <a>foo</a><b>bar<a>other</a><b>
+					// curFlowEl = <b>bar<a>other</a><b>
+					//
+					// since <b> is a spg, we need to walk it's contents and remove any <a> elements
+					if(curFlowEl is SubParagraphGroupElement)
+					{
+						//we need to dive into this spgClass and remove any fbes of type spgClass
+						//pass in the curFlowEl as the newSPB, remove any spgs of type spgClass, then 
+						//perform the replace on the newSPB passed in here
+						//
+						//ignore the return value of the recursive call as the length has already been
+						//accounted for above
+						flushSPBlock(curFlowEl as SubParagraphGroupElement, spgClass);
+					}
+					newSPB.replaceChildren(newSPB.numChildren, newSPB.numChildren, curFlowEl);
+					
+					if(newSPB.numChildren == 1 && curFlowEl is SubParagraphGroupElement)
+					{
+						var childSPGE:SubParagraphGroupElement = curFlowEl as SubParagraphGroupElement;
+						//running example:
+						//a.precedence = 800, tcy.precedence = kMinSPGEPrecedence
+						//this = <tcy><a><span>fooBar</span></a><tcy>
+						//childSPGE = <a><span>fooBar</span></a>
+						if(childSPGE.textLength == newSPB.textLength && (curPos >= endPos))
+						{
+							CONFIG::debug { assert(childSPGE.precedence != newSPB.precedence, "normalizeRange found two equal SPGEs"); }
+	
+							//if the child's precedence is higher than mine, I need to swap
+							if(childSPGE.precedence > newSPB.precedence)
+							{
+								//first, remove the child
+								//this = <tcy></tcy>
+								newSPB.replaceChildren(0,1,null);
+								
+								//we need to flop this object for the child
+								while(childSPGE.numChildren > 0)
+								{
+									//tempFE = <span>fooBar</span>
+									var tempFE:FlowElement = childSPGE.getChildAt(0);
+									//child = <a></a>
+									childSPGE.replaceChildren(0,1,null);
+									//this = <tcy><span>fooBar</span></tcy>
+									newSPB.replaceChildren(newSPB.numChildren, newSPB.numChildren, tempFE);
+								}
+								
+								var myIdx:int = newSPB.parent.getChildIndex(newSPB);
+								CONFIG::debug{ assert(myIdx >= 0, "Invalid index!  How can a SubParagraphGroupElement normalizing not have a parent!"); }
+								
+								//add childSPGE in my place
+								newSPB.parent.replaceChildren(myIdx, myIdx + 1, childSPGE)
+								
+								//childSPGE = <tcy><a><span>fooBar</span></a></tcy>
+								childSPGE.replaceChildren(0,0,newSPB);
+							}
+						}
+					}
+				}
+				
+			}
+	
+			return curPos;
+		}
+		
+		/**
+		 * @private
+		 * findAndRemoveFlowGroupElement 
+		 *
+		 * @param theFlow The TextFlow that is containing the elements to remove.
+		 * @param startPos The index value of the first position of the range in the TextFlow where we want to perform removal.
+		 * @param endPos The index value following the end position of the range in the TextFlow where we want to perform removal.
+		 * @param fbeClass Class the class of the fbe we intend to remove.
+		 * 
+		 * Walks through the elements of <code>theFlow</code> looking for any FlowGroupElement of type <code>fbeClass</class>
+		 * On finding one, it removes the FBE's contents and adds them back into the FBE's parent.  If the class of object is
+		 * embedded within another spg and this removal would break the parent spg, then the method does nothing.
+		 * 
+		 * Example:
+		 * 	<link>ABC<tcy>DEF</tcy>GHI</link>
+		 * 	Selection is on E and removal of link is attempted.
+		 * 	Because E is a child of a spg (tcy), and removing the link from E would split the parent spg (link),
+		 *  the action is disallowed.
+		 * 
+		 * Running example:
+		 * 	1) <link><tcy><span>foo</span></tcy><span>bar</span></link>
+		 * @return Boolean - true if items are removed or none are found.  false if operation is illegal.
+		 */ 
+		tlf_internal static function findAndRemoveFlowGroupElement(theFlow:TextFlow, startPos:int, endPos:int, fbeClass:Class):Boolean
+		{
+			var curPos:int = startPos;
+			var curEl:FlowElement;
+			
+			//walk through the elements
+			while (curPos < endPos)
+			{
+				var containerFBE:FlowGroupElement = theFlow.findAbsoluteFlowGroupElement(curPos);
+				
+				//if the start of the parent is the same as the start of the current containerFBE, then
+				//we potentially have the wrong object.  We need to walk up the parents until we get to
+				//the one which starts at our start AND is the topmost object at that index.
+				//example: <a><b>foo</b> bar</a> - getting the object at "f" will yield the <b> element, not <a>
+				while(containerFBE.parent && containerFBE.parent.getAbsoluteStart() == containerFBE.getAbsoluteStart() && 
+					!(containerFBE.parent is ParagraphElement)) //don't go beyond paragraph
+				{
+					containerFBE = containerFBE.parent;
+				}
+				
+				//if the absoluteFBE is the item we are trying to remove, we need to work with its parent, so
+				//reassign containerFBE.  For example, if an entire link were selected, we'd need to get it's parent to
+				//perform the removal
+				if(containerFBE is fbeClass)
+					containerFBE = containerFBE.parent;
+					
+				//before processing this any further, we need to make sure that we are not
+				//splitting a spg which is contained within the same type of spg as the curFBE's parent.
+				//for example, if we had a tcyElement inside a linkElement, then we cannot allow a link element
+				//to be broken within the tcyElement as the link would have to split the TCY.
+				var ancestorOfFBE:FlowGroupElement = containerFBE.parent;
+				while(ancestorOfFBE != null && !(ancestorOfFBE is fbeClass))
+				{
+					if(ancestorOfFBE.parent is fbeClass)
+					{
+						return false;
+					}
+					ancestorOfFBE = ancestorOfFBE.parent;
+				}
+				
+				//if this is a sbe block contained in another sbe, and it is entire within the 
+				//selection bounds, we need to use the parent sbe's container.  If it is splitting
+				//the child sbe, we don't allow this and it is handled later...
+				var containerFBEStart:int = containerFBE.getAbsoluteStart();
+				if(ancestorOfFBE is fbeClass && (containerFBEStart >= curPos && containerFBEStart + containerFBE.textLength <= endPos))
+					containerFBE = ancestorOfFBE.parent;
+					
+				var childIdx:int = containerFBE.findChildIndexAtPosition(curPos - containerFBEStart);
+				curEl = containerFBE.getChildAt(childIdx);
+				if(curEl is fbeClass)
+				{
+					CONFIG::debug{ assert(curEl is SubParagraphGroupElement, "Wrong FBE type!  Trying to remove illeage FBE!") };
+					var curFBE:FlowGroupElement = curEl as FlowGroupElement;
+					
+					//get it's parent and the index of the curFBE
+					var parentBlock:FlowGroupElement = curFBE.parent;
+					var idxInParent:int = parentBlock.getChildIndex(curFBE);
+					
+					//if the curPos is not at the head of the SPB, then we need to split it here
+					//curFBE will point to the FBE starting at curPos
+					if(curPos > curFBE.getAbsoluteStart())
+					{
+						splitElement(curFBE, curPos - curFBE.getAbsoluteStart(), false);
+						curPos = curFBE.getAbsoluteStart() + curFBE.textLength;
+						continue;
+					}
+					
+					//if curFBE goes beyond the endPos, then we need to split off the tail.
+					if (curFBE.getAbsoluteStart() + curFBE.textLength > endPos)
+					{
+						splitElement(curFBE, endPos - curFBE.getAbsoluteStart(), false);
+					}
+				
+					//apply the length of the curFBE to the curPos tracker.  Do this before 
+					//removing the contents or it will be 0!
+					curPos = curFBE.getAbsoluteStart() + curFBE.textLength;
+					
+					//walk all the contents of the FBE into it's parent container
+					while (curFBE.numChildren > 0)
+					{
+						var childFE:FlowElement = curFBE.getChildAt(0);
+						curFBE.replaceChildren(0, 1, null);
+						parentBlock.replaceChildren(idxInParent, idxInParent, childFE);
+						idxInParent++; 
+					}
+					
+					//remove the curFBE
+					parentBlock.replaceChildren(idxInParent, idxInParent + 1, null);
+				}
+				else if(curEl is SubParagraphGroupElement) //check all the parents...
+				{
+					var curSPB:SubParagraphGroupElement = SubParagraphGroupElement(curEl);
+					if(curSPB.numChildren == 1)
+						curPos = curSPB.getAbsoluteStart() + curSPB.textLength;
+					else
+					{
+						curEl = curSPB.getChildAt(curSPB.findChildIndexAtPosition(curPos - curSPB.getAbsoluteStart()));
+						curPos = curEl.getAbsoluteStart() + curEl.textLength;
+					}
+				}
+				else
+				{
+					//the current block isn't the type we're looking for, so just go to the end of the
+					//FlowElement and continue
+					curPos = curEl.getAbsoluteStart() + curEl.textLength;
+				}
+				
+			}
+			
+			return true;
+		}
+		
+		/**
+		 * @private
+		 * canInsertSPBlock 
+		 * 
+		 * validate that we a valid selection to allow for insertion of a subBlock.  The rules are as
+		 * follows:
+		 * 	endPos > start
+		 * 	the new block will not span multiple paragraphs
+		 *  if the block is going into a SubParagraphGroupElement, it must not split the block:
+		 * 		example:  Text 		- ABCDEFG with a link on CDE
+		 * 		legal new Block		- D, CD, CDE, [n-chars]CDE[n1-chars]
+		 * 		illegal new Block 	- [1 + n-chars]C[D], [D]E[1 + n-chars]
+		 * 			exception - if the newBlock is the same class as the one we are trying to split
+		 * 			then we can truncate the original and add its contents to the new one, or extend it
+		 * 			as appropriate
+		 * 
+		 * @param theFlow The TextFlow that is containing the elements to validate.
+		 * @param startPos The index value of the first position of the range in the TextFlow to test.
+		 * @param endPos The index value following the end position of the range in the TextFlow to test.
+		 * @param blockClass Class the class of the fbe we intend to insert.
+		 */
+		tlf_internal static function canInsertSPBlock(theFlow:TextFlow, startPos:int, endPos:int, blockClass:Class):Boolean
+		{
+			if(endPos <= startPos)
+				return false;
+				
+			var anchorFBE:FlowGroupElement = theFlow.findAbsoluteFlowGroupElement(startPos);
+			if(anchorFBE.getParentByType(blockClass))
+				anchorFBE = anchorFBE.getParentByType(blockClass) as FlowGroupElement;
+				
+			var tailFBE:FlowGroupElement = theFlow.findAbsoluteFlowGroupElement(endPos - 1);
+			if(tailFBE.getParentByType(blockClass))
+				tailFBE = tailFBE.getParentByType(blockClass) as FlowGroupElement;
+			
+			//if these are the same FBEs then we are safe to insert a SubParagraphGroupElement
+			if(anchorFBE == tailFBE)
+				return true;
+			//make sure that the two FBEs belong to the same paragraph!
+			else if(anchorFBE.getParagraph() != tailFBE.getParagraph())
+				return false;
+			else if(anchorFBE is blockClass && tailFBE is blockClass)//they're the same class, OK to merge, split, etc...
+				return true;
+			else if(anchorFBE is SubParagraphGroupElement && !(anchorFBE is blockClass))
+			{
+				var anchorStart:int = anchorFBE.getAbsoluteStart();
+				if(startPos > anchorStart && endPos > anchorStart + anchorFBE.textLength)
+					return false;
+			}
+			else if((anchorFBE.parent is SubParagraphGroupElement || tailFBE.parent is SubParagraphGroupElement)
+				&& anchorFBE.parent != tailFBE.parent)
+			{
+				//if either FBE parent is a SPGE and they are not the same, prevent the split.  
+				return false;
+			}	
+			
+			//if we got here, then the anchorFBE is OK, check the tail.  If endPos is pointing to the
+			//0th character of a FlowGroupElement, we don't need to worry about the tail.
+			if(tailFBE is SubParagraphGroupElement && !(tailFBE is blockClass) && endPos > tailFBE.getAbsoluteStart())
+			{
+				var tailStart:int = tailFBE.getAbsoluteStart();
+				if(startPos < tailStart && endPos < tailStart + tailFBE.textLength)
+					return false;
+			}	
+			return true;
+		}
+		
+		/**
+		 * @private flushSPBlock recursively walk a spg looking for elements of type spgClass.  On finding one,
+		 * remove it's children and then remove the object itself.  Since spg's cannot hold children of the same type
+		 * as themselves, recursion is only needed for spg's of a class other than that of spgClass.
+		 * 
+		 * example: subPB = <b>bar<a>other</a><b> extending an <a> element to include all of "other"
+		 */ 
+		tlf_internal static function flushSPBlock(subPB:SubParagraphGroupElement, spgClass:Class):void
+		{
+			var subParaIter:int = 0;
+	
+			//example, subPB has 2 elements, <span>bar</span> and <a><span>other</span></a>
+			while(subParaIter < subPB.numChildren)
+			{
+				//subParaIter == 0, subFE = <span>bar</span> skip the FE and move to next
+				//subParaIter == 1, subFE = <a><span>other</span></a> - is a spgClass
+				var subFE:FlowElement = subPB.getChildAt(subParaIter);
+				if(subFE is spgClass)
+				{
+					//subParaIter == 1, subFE = <a><span>other</span></a>
+					var subChildFBE:FlowGroupElement = subFE as FlowGroupElement;
+					while(subChildFBE.numChildren > 0)
+					{
+						//subFEChild = <span>other</span>
+						var subFEChild:FlowElement = subChildFBE.getChildAt(0);
+						//subFEChild = <a></a>
+						subChildFBE.replaceChildren(0, 1, null);
+						//subPB = <b>barother<a></a><b>
+						subPB.replaceChildren(subParaIter, subParaIter, subFEChild);
+					}
+					
+					//increment so that subParaIter points to the element we just emptied
+					++subParaIter;
+					//remove the empty child
+					//subPB = <b>barother<b>
+					subPB.replaceChildren(subParaIter, subParaIter + 1, null);
+				}
+				else if(subFE is SubParagraphGroupElement)
+				{
+					flushSPBlock(subFE as SubParagraphGroupElement, spgClass);
+					++subParaIter;
+				}
+				else
+					++subParaIter;//go to next child
+			}
+		}
+		/** Joins this paragraph's next sibling to this if it is a paragraph */
+		static public function joinNextParagraph(para:ParagraphElement):Boolean
+		{		
+			if (para && para.parent)
+			{
+				var myidx:int = para.parent.getChildIndex(para);
+				if (myidx != para.parent.numChildren-1)
+				{
+					// right now, you can only merge with other paragraphs
+					var sibParagraph:ParagraphElement = para.parent.getChildAt(myidx+1) as ParagraphElement;
+					if (sibParagraph)
+					{						
+						while (sibParagraph.numChildren > 0)
+						{
+							var curFlowElement:FlowElement = sibParagraph.getChildAt(0);
+							sibParagraph.replaceChildren(0, 1, null);
+							para.replaceChildren(para.numChildren, para.numChildren, curFlowElement);
+						}
+						para.parent.replaceChildren(myidx+1, myidx+2, null);
+						return true;
+					}
+				}
+			} 
+			return false;
+		}
+
+		/** Joins this paragraph's next sibling to this if it is a paragraph */
+		static public function joinToNextParagraph(para:ParagraphElement):Boolean
+		{		
+			if (para && para.parent)
+			{
+				var myidx:int = para.parent.getChildIndex(para);
+				if (myidx != para.parent.numChildren-1)
+				{
+					// right now, you can only merge with other paragraphs
+					var sibParagraph:ParagraphElement = para.parent.getChildAt(myidx+1) as ParagraphElement;
+					if (sibParagraph)
+					{			
+						// Add the first paragraph's children to the front of the next paragraph's child list
+						var addAtIndex:int = 0;
+						while (para.numChildren > 0)
+						{
+							var curFlowElement:FlowElement = para.getChildAt(0);
+							para.replaceChildren(0, 1, null);
+							sibParagraph.replaceChildren(addAtIndex, addAtIndex, curFlowElement);
+							++addAtIndex;
+						}
+						para.parent.replaceChildren(myidx, myidx+1, null);
+						return true;
+					}
+				}
+			} 
+			return false;
+		}
+
+								
+	}
+}
diff --git a/textLayout_edit/src/flashx/textLayout/edit/TextScrap.as b/textLayout_edit/src/flashx/textLayout/edit/TextScrap.as
new file mode 100755
index 0000000..8d7bdf5
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/edit/TextScrap.as
@@ -0,0 +1,261 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.edit
+{
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.elements.TextRange;
+	import flashx.textLayout.edit.TextFlowEdit;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+
+	/**
+	 * The TextScrap class represents a fragment of a text flow.
+	 * 
+	 * <p>A TextScrap is a holding place for all or part of a TextFlow. A range of text can be copied 
+	 * from a TextFlow into a TextScrap, and pasted from the TextScrap into another TextFlow.</p>
+	 *
+	 * @see flashx.textLayout.elements.TextFlow
+	 * @see flashx.textLayout.edit.SelectionManager
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	*/	
+	public class TextScrap
+	{	
+		private var _textFlow:TextFlow;
+		private var _beginMissingArray:Array;
+		private var _endMissingArray:Array;
+
+		/**
+		 * Creates a TextScrap object.
+		 * 
+		 * <p>Use the <code>createTextScrap()</code> method to create a TextScrap object from
+		 * a range of text represented by a TextRange object.</p>
+		 *  
+		 * @param textFlow if set, the new TextScrap object contains the entire text flow.
+		 * Otherwise, the TextScrap object is empty.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */												
+		public function TextScrap(textFlow:TextFlow = null)
+		{
+			_textFlow = textFlow;
+			_textFlow.flowComposer = null;	// no flowcomposer in a TextScrap
+			_beginMissingArray = new Array();
+			_endMissingArray = new Array();
+		}
+
+		/**
+		 * Creates a TextScrap object from a range of text represented by a TextRange object.
+		 * 
+		 * @param range the TextRange object representing the range of text to copy.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public static function createTextScrap(range:TextRange):TextScrap
+		{
+			return TextFlowEdit.createTextScrap(range.textFlow, range.absoluteStart, range.absoluteEnd);
+		}
+		
+		/** @private
+		 * Gets the TextFlow that is currently in the TextScrap.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */												
+		tlf_internal function get textFlow():TextFlow
+		{
+			return _textFlow;
+		}
+		
+		/**
+		 * @private
+		 * 
+		 * Indicates whether the specified FlowElement has it's beginning part missing.
+		 */												
+		tlf_internal function isBeginMissing(fl:FlowElement):Boolean
+		{
+			var arrLen:int = _beginMissingArray.length;
+			var currPos:int = 0;
+			while (currPos < arrLen)
+			{
+				if (_beginMissingArray[currPos] == fl)
+				{
+					return true;
+				}
+				currPos++;
+			}
+			return false;
+		}
+		
+		/**
+		 * @private
+		 * 
+		 * Indicates whether the specified FlowElement has it's end part missing.
+		 */												
+		tlf_internal function isEndMissing(fl:FlowElement):Boolean
+		{
+			var arrLen:int = _endMissingArray.length;
+			var currPos:int = 0;
+			while (currPos < arrLen)
+			{
+				if (_endMissingArray[currPos] == fl)
+				{
+					return true;
+				}
+				currPos++;
+			}
+			return false;			
+		}
+
+		/**
+		 * @private
+		 * 
+		 * Indicates that the specified FlowElement has it's beginning part missing.
+		 */														
+		tlf_internal function addToBeginMissing(fl:FlowElement):void
+		{
+			_beginMissingArray.push(fl);
+		}
+
+		/**
+		 * @private
+		 * 
+		 * Indicates that the specified FlowElement has it's end part missing.
+		 */																
+		tlf_internal function addToEndMissing(fl:FlowElement):void
+		{
+			_endMissingArray.push(fl);			
+		}
+
+		/**
+		 * @private
+		 * 
+		 * Returns all the FlowElements in the TextFlow that have their beginning
+		 * parts missing.
+		 */																		
+		tlf_internal function get beginMissingArray():Array
+		{
+			return _beginMissingArray;
+		}
+
+		/**
+		 * @private
+		 * 
+		 * Returns all the FlowElements in the TextFlow that have their ending
+		 * parts missing.
+		 */																				
+		tlf_internal function get endMissingArray():Array
+		{
+			return _endMissingArray;
+		}
+
+		/**
+		 * @private
+		 * 
+		 * Sets an array of FlowElements that are missing their
+		 * beginning parts in this TextFlow.
+		 */																						
+		tlf_internal function set beginMissingArray(arr:Array):void
+		{
+			_beginMissingArray = arr;
+		}	
+
+		/**
+		 * Sets an array of FlowElements that are missing their
+		 * ending parts in this TextFlow.
+		 * @private
+		 */																						
+		tlf_internal function set endMissingArray(arr:Array):void
+		{	
+			_endMissingArray = arr;
+		}
+		
+		/**
+		 * Creates a duplicate copy of this TextScrap object.
+		 * 
+		 * @return TextScrap A copy of this TextScrap.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function clone():TextScrap
+		{
+			var t:TextFlow = textFlow.deepCopy() as TextFlow;
+			var newTextScrap:TextScrap = new TextScrap(t);
+			
+			var beginMissingArray:Array = _beginMissingArray;
+			var endMissingArray:Array = _endMissingArray;
+			
+			var curPos:int = beginMissingArray.length - 2;
+			var curFlElement:FlowElement;
+			var curFlElementIndex:int;
+			var newFlowElement:FlowElement = newTextScrap.textFlow;
+			
+			if (beginMissingArray.length > 0)
+			{
+				var newBeginArray:Array = new Array();
+				newBeginArray.push(newFlowElement);
+				while (curPos >= 0)
+				{
+					curFlElement = beginMissingArray[curPos];
+					curFlElementIndex = curFlElement.parent.getChildIndex(curFlElement);
+					if (newFlowElement is FlowGroupElement)
+					{
+						newFlowElement = (newFlowElement as FlowGroupElement).getChildAt(curFlElementIndex);
+						newBeginArray.push(newFlowElement);
+					}
+					curPos--;
+				}
+				newTextScrap.beginMissingArray = newBeginArray;
+			}
+			
+			curPos = endMissingArray.length - 2;
+			newFlowElement = newTextScrap.textFlow;
+			if (endMissingArray.length > 0)
+			{
+				var newEndArray:Array = new Array();
+				newEndArray.push(newFlowElement);
+				while (curPos >= 0)
+				{
+					curFlElement = endMissingArray[curPos];
+					curFlElementIndex = curFlElement.parent.getChildIndex(curFlElement);
+					if (newFlowElement is FlowGroupElement)
+					{
+						newFlowElement = (newFlowElement as FlowGroupElement).getChildAt(curFlElementIndex);
+						newEndArray.push(newFlowElement);
+					}
+					curPos--;					
+				}
+				newTextScrap.endMissingArray = newEndArray;
+			}
+			return newTextScrap;
+		}
+
+	} // end TextScap class
+} // end package
diff --git a/textLayout_edit/src/flashx/textLayout/events/FlowOperationEvent.as b/textLayout_edit/src/flashx/textLayout/events/FlowOperationEvent.as
new file mode 100755
index 0000000..aa76b23
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/events/FlowOperationEvent.as
@@ -0,0 +1,168 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.events
+{
+	import flash.events.Event;
+	
+	import flashx.textLayout.operations.FlowOperation; 
+	
+	/** A TextFlow instance dispatches this event just before an operation commences
+	 * and again just after an operation completes. Although the event object
+	 * dispatched in both cases is an instance of FlowOperationEvent, the events
+	 * dispatched before and after an operation differ in significant ways.
+	 *
+	 * <p>Before any operation is carried out, a TextFlow object dispatches a FlowOperationEvent
+	 * with its <code>type</code> property set to <code>FlowOperationEvent.FLOW_OPERATION_BEGIN.</code>
+	 * You can determine what type of operation is about to commence by checking
+	 * the <code>operation</code> property. Events of type FLOW_OPERATION_BEGIN are
+	 * cancellable, which means that if you decide that the operation should not proceed,
+	 * you can call <code>Event.PreventDefault()</code> to cancel the operation.
+	 * If you cancel the operation, the operation is not performed and the 
+	 * FLOW_OPERATION_END event is not dispatched. You may also choose to call back into the
+	 * EditManager to do another operation before the operation that triggered the event is done. If you do
+	 * this, the operations you initiate in your event handler will be undone as a single
+	 * operation with the operation that triggered the event.</p>
+	 *
+	 * <p>If you allow the operation to proceed, TextFlow will dispatch a FlowOperationEvent
+	 * upon completion of the operation with its <code>type</code> property set to
+	 * <code>FlowOperationEvent.FLOW_OPERATION_END</code>. This event is dispatched
+	 * before Flash Player throws any errors that may have occurred as a result of the
+	 * operation. This gives you an opportunity to process the error before Flash Player
+	 * throws the error. You can access the error through the event's <code>error</code>
+	 * property. If you choose to handle the error in your event handler, you can prevent
+	 * Flash Player from throwing the error by cancelling the FLOW_OPERATION_END event
+	 * by calling <code>Event.preventDefault()</code>. You may also choose to call back into the
+	 * EditManager to do some additional operations. If you do this, the operations that result
+	 * will be undone as a unit with the operation that triggered the event.
+	 * </p> 
+	 *
+	 * @includeExample examples\FlowOperationEvent_example.as -noswf
+	 * @see flashx.textLayout.operations.FlowOperation
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class FlowOperationEvent extends Event
+	{
+		/** 
+		 * Defines the value of the <code>type</code> property of a <code>flowOperationBegin</code> event object.
+		 * Dispatched before an operation is executed.   Cancelling this event blocks the operation. 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		
+		public static const FLOW_OPERATION_BEGIN:String = "flowOperationBegin";
+		
+		/**  
+		 * Defines the value of the <code>type</code> property of a <code>flowOperationEnd</code> event object.
+		 * Dispatched after an operation completes. Any errors are stored in <code>OperationEvent.error</code>.
+	 	 * If there is an error, cancelling this event blocks the rethrow of the error.
+	 	 * Generally speaking all errors are likely to be fatal.
+	 	 * <p>Changing an operation at this time (after it has been executed) may fail.</p> 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+	 	 */
+	 	
+		public static const FLOW_OPERATION_END:String = "flowOperationEnd";
+
+		/**  
+		 * Defines the value of the <code>type</code> property of a <code>flowOperationComplete</code> event object.
+		 * Dispatched after all operations including pending and composite operations are completed, composition is finished and the display is scrolled.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		
+		public static const FLOW_OPERATION_COMPLETE:String = "flowOperationComplete";
+				
+		private var _op:FlowOperation;
+		private var _e:Error;
+		private var _level:int;
+
+		/** 
+		 * The operation that is about to begin or has just ended.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+	         * @see flashx.textLayout.operations.FlowOperation
+		 */		
+		public function get operation():FlowOperation
+		{ return _op; }	
+		public function set operation(value:FlowOperation):void
+		{ _op = value; }	
+
+		/** 
+		 * The error thrown, if any, during an operation.  
+		 * If an error occurs during an operation, a reference to the error object is attached to the 
+		 * FLOW_OPERATION_END event. This give you the opportunity to deal with the error
+		 * before Flash Player throws the error. If you cancel the event, Flash Player will not throw the error.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function get error():Error
+		{ return _e; }
+		public function set error(value:Error):void
+		{ _e = value; }
+		
+		/** 
+		 * Operations may be merged into composite operations through nesting.  This flag describes the nesting level of the operation.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function get level():int
+		{ return _level; }
+		public function set level(value:int):void
+		{ _level = value; }		
+		
+		/** Creates an event object that contains information about a flow operation.
+		 * @param type			The type of the event. Event listeners can access this information through the
+		 * inherited <code>type</code> property. There are two types: 
+		 * <code>FlowOperationEvent.FLOW_OPERATION_BEGIN</code>; 
+		 * <code>FlowOperationEvent.FLOW_OPERATION_END</code>.
+		 * @param bubbles 		Indicates whether an event is a bubbling event.This event does not bubble.
+		 * @param cancelable 	Indicates whether the behavior associated with the event can be prevented.
+		 * This event can be cancelled by calling the <code>Event.preventDefault()</code> method in
+		 * your event handler function.
+		 * @param operation		The FlowOperation that is about to commence or that has just ended.
+		 * @param error			Any Error generating during the operation.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function FlowOperationEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false, operation:FlowOperation = null, level:int = 0, error:Error = null)
+		{
+			_op = operation;
+			_e  = error;
+			_level = level;
+			super(type, bubbles, cancelable);
+		}
+		
+       	/** @private */
+		override public function clone():Event
+		{
+			return new FlowOperationEvent(type, bubbles, cancelable, _op, _level, _e);
+		}
+		
+	}
+}
\ No newline at end of file
diff --git a/textLayout_edit/src/flashx/textLayout/events/SelectionEvent.as b/textLayout_edit/src/flashx/textLayout/events/SelectionEvent.as
new file mode 100755
index 0000000..db0e4df
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/events/SelectionEvent.as
@@ -0,0 +1,106 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.events
+{
+	import flash.events.Event;
+	import flashx.textLayout.edit.SelectionState;
+	
+	/** 
+	 * A TextFlow instance dispatches a SelectionEvent object when
+	 * an EditManager or SelectionManager changes or selects a range of text. 
+	 * For example, this event is dispatched not only when a range of text is
+	 * selected, but also when the selection changes because the
+	 * user clicks elsewhere in the text flow. Moreover, this
+	 * event is also dispatched when an EditManager changes
+	 * the text or text formatting within a range of text.
+	 *
+	 * @includeExample examples\SelectionEvent_example.as -noswf
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class SelectionEvent extends Event
+	{
+		/** 
+		 * The SelectionEvent.SELECTION_CHANGE constant defines the value of the 
+		 * type property of the event object for a selection event. 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public static const SELECTION_CHANGE:String = "selectionChange";
+		
+		private var _selectionState:SelectionState;
+		
+		/** 
+		 * Creates an event object that contains information about a flow operation.
+		 * @param type		The type of the event. Event listeners can access this information through the
+		 * inherited <code>type</code> property. There is only one type of SelectionEvent: 
+		 * <code>SelectionEvent.SELECTION_CHANGE</code>; 
+		 * @param bubbles 	Indicates whether an event is a bubbling event.This event does not bubble.
+		 * @param cancelable 	Indicates whether the behavior associated with the event can be prevented.
+		 * @param range		An object of type ElementRange that describes the range of text selected.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function SelectionEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false, selectionState:SelectionState=null)
+		{
+			_selectionState = selectionState;
+			super(type, bubbles, cancelable);
+		}
+
+		/** 
+		 * An object of type SelectionState that represents the selected range associated with this SelectionEvent.
+		 * 
+		 * <p>You can use this property, along with the ElementRange class, to create an ElementRange
+		 * instance that represents the range of selected text.
+		 * You can use the following line of code to create an instance of the
+		 * ElementRange class that represents the range of selected text
+		 * (the <code>ev</code> variable represents the event object, and the conditional operator 
+		 * is used to guard against a <code>null</code> value for the <code>selectionState</code>
+		 * property):</p>
+		 * <listing>
+		 * // Find selected element range
+		 * var range:ElementRange = ev.selectionState ?  
+		 * 	ElementRange.createElementRange(ev.selectionState.textFlow,
+		 * 	ev.selectionState.absoluteStart, ev.selectionState.absoluteEnd) : null;</listing>
+		 * 
+		 * 
+		 * 
+		 * @see flashx.textLayout.edit.ElementRange
+		 * @see flashx.textLayout.edit.SelectionState
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */		
+		public function get selectionState():SelectionState
+		{ return _selectionState; }	
+		public function set selectionState(value:SelectionState):void
+		{ _selectionState = value; }	
+		
+		
+		/** @private */
+		override public function clone():Event
+		{
+			return new SelectionEvent(type, bubbles, cancelable, _selectionState);
+		}
+		
+	}
+}
\ No newline at end of file
diff --git a/textLayout_edit/src/flashx/textLayout/operations/ApplyElementIDOperation.as b/textLayout_edit/src/flashx/textLayout/operations/ApplyElementIDOperation.as
new file mode 100755
index 0000000..dbdd30c
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/ApplyElementIDOperation.as
@@ -0,0 +1,109 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.ParagraphFormattedElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+	
+	/**
+	 * The ChangeElementIDOperation class encapsulates an element ID change.
+	 *
+	 * @see flashx.textLayout.elements.FlowElement
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class ApplyElementIDOperation extends FlowElementOperation
+	{	
+		private var _origID:String;
+		private var _newID:String;
+		
+		/** 
+		 * Creates a ChangeElementIDOperation object. 
+		 * 
+		 * <p>If the <code>relativeStart</code> or <code>relativeEnd</code> parameters are set, then the existing
+		 * element is split into two elements, one using the existing ID and the other
+		 * using the new ID. If both parameters are set, then the existing element is split into three elements.
+		 * The first and last elements of the set are both assigned the original ID.</p>
+		 * 
+		 * @param operationState Specifies the selection state before the operation
+		 * @param targetElement Specifies the element to change
+		 * @param newID The ID to assign
+		 * @param relativeStart An offset from the beginning of the target element.
+		 * @param relativeEnd An offset from the end of the target element.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function ApplyElementIDOperation(operationState:SelectionState, targetElement:FlowElement, newID:String, relativeStart:int = 0, relativeEnd:int = -1)
+		{
+			_newID = newID;
+			super(operationState,targetElement,relativeStart,relativeEnd);
+		}
+		
+		/** 
+		 * The ID assigned by this operation.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function get newID():String
+		{ return _newID; }
+		public function set newID(val:String):void
+		{ _newID = val; }
+
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			var targetElement:FlowElement = getTargetElement();
+			_origID = targetElement.id;
+
+			adjustForDoOperation(targetElement);
+			
+			targetElement.id = _newID;
+			return true;
+		}	
+		
+		/** @private */
+		public override function undo():SelectionState
+		{
+			var targetElement:FlowElement = getTargetElement();
+			targetElement.id = _origID;
+			
+			adjustForUndoOperation(targetElement);
+			
+			return originalSelectionState;
+		}
+	}
+}
\ No newline at end of file
diff --git a/textLayout_edit/src/flashx/textLayout/operations/ApplyElementStyleNameOperation.as b/textLayout_edit/src/flashx/textLayout/operations/ApplyElementStyleNameOperation.as
new file mode 100755
index 0000000..679c7cb
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/ApplyElementStyleNameOperation.as
@@ -0,0 +1,108 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.ParagraphFormattedElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+	
+	/**
+	 * The ApplyElementStyleNameOperation class encapsulates a style name change.
+	 *
+	 * @see flashx.textLayout.elements.FlowElement#styleName
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class ApplyElementStyleNameOperation extends FlowElementOperation
+	{	
+		private var _origStyleName:String;
+		private var _newStyleName:String;
+		
+		/** 
+		 * Creates a ApplyElementStyleNameOperation object. 
+		 * 
+		 * <p>If the <code>relativeStart</code> and <code>relativeEnd</code> parameters are set, then the existing
+		 * element is split into multiple elements, the selected portion using the new 
+		 * style name and the rest using the existing style name.</p>
+		 * 
+		 * @param operationState Describes the current selection.
+		 * @param targetElement Specifies the element to change.
+		 * @param newStyleName The style name to assign.
+		 * @param relativeStart An offset from the beginning of the target element.
+		 * @param relativeEnd An offset from the end of the target element.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function ApplyElementStyleNameOperation(operationState:SelectionState, targetElement:FlowElement, newStyleName:String, relativeStart:int = 0, relativeEnd:int = -1)
+		{
+			_newStyleName = newStyleName;
+			super(operationState,targetElement,relativeStart,relativeEnd);
+		}
+		
+		/** 
+		 * The style name assigned by this operation.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function get newStyleName():String
+		{ return _newStyleName; }
+		public function set newStyleName(val:String):void
+		{ _newStyleName = val; }
+
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			var targetElement:FlowElement = getTargetElement();
+			_origStyleName = targetElement.styleName;
+			
+			adjustForDoOperation(targetElement);
+			
+			targetElement.styleName = _newStyleName;
+			return true;
+		}	
+		
+		/** @private */
+		public override function undo():SelectionState
+		{
+			var targetElement:FlowElement = getTargetElement();
+			targetElement.styleName = _origStyleName;
+			
+			adjustForUndoOperation(targetElement);
+			
+			return originalSelectionState;
+		}
+	}
+}
\ No newline at end of file
diff --git a/textLayout_edit/src/flashx/textLayout/operations/ApplyElementUserStyleOperation.as b/textLayout_edit/src/flashx/textLayout/operations/ApplyElementUserStyleOperation.as
new file mode 100755
index 0000000..afc251f
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/ApplyElementUserStyleOperation.as
@@ -0,0 +1,124 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.ParagraphFormattedElement;
+	import flashx.textLayout.elements.TextFlow;
+
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+	
+	/**
+	 * The ApplyElementUserStyleOperation class encapsulates a change in a style value of an element.
+	 *
+	 * @see flashx.textLayout.elements.FlowElement#userStyles
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class ApplyElementUserStyleOperation extends FlowElementOperation
+	{	
+		private var _styleName:String;
+		
+		private var _origValue:*;
+		private var _newValue:*;
+		
+		/** 
+		 * Creates a ApplyElementUserStyleOperation object.
+		 * 
+		 * <p>If the <code>relativeStart</code> and <code>relativeEnd</code> parameters are set, then the existing
+		 * element is split into multiple elements, the selected portion using the new 
+		 * style value and the rest using the existing style value.</p>
+		 * 
+		 * @param operationState Describes the range of text to style.
+		 * @param targetElement Specifies the element to change.
+		 * @param styleName The name of the style to change.
+		 * @param value The new style value.
+		 * @param relativeStart An offset from the beginning of the target element.
+		 * @param relativeEnd An offset from the end of the target element.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function ApplyElementUserStyleOperation(operationState:SelectionState, targetElement:FlowElement, styleName:String, value:*, relativeStart:int = 0, relativeEnd:int = -1)
+		{
+			_styleName = styleName;
+			_newValue = value;
+			
+			super(operationState,targetElement,relativeStart,relativeEnd);
+		}
+		
+		/** 
+		 * The name of the style changed. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function get styleName():String
+		{ return _styleName; }
+		public function set styleName(val:String):void
+		{ _styleName = val; }
+		
+		/** 
+		 * The new style value.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function get newValue():*
+		{ return _newValue; }
+		public function set newValue(val:*):void
+		{ _newValue = val; }
+
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			var targetElement:FlowElement = getTargetElement();
+			_origValue = targetElement.getStyle(_styleName);
+			
+			adjustForDoOperation(targetElement);
+			
+			targetElement.setStyle(_styleName,_newValue);
+			return true;
+		}	
+		
+		/** @private */
+		public override function undo():SelectionState
+		{
+			var targetElement:FlowElement = getTargetElement();
+			targetElement.setStyle(_styleName,_origValue);
+			
+			adjustForUndoOperation(targetElement);
+			
+			return originalSelectionState;
+		}
+	}
+}
\ No newline at end of file
diff --git a/textLayout_edit/src/flashx/textLayout/operations/ApplyFormatOperation.as b/textLayout_edit/src/flashx/textLayout/operations/ApplyFormatOperation.as
new file mode 100755
index 0000000..9c737ae
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/ApplyFormatOperation.as
@@ -0,0 +1,238 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.edit.ElementRange;
+	import flashx.textLayout.edit.ParaEdit;
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.formats.Category;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormatValueHolder;
+	import flashx.textLayout.property.Property;
+	import flashx.textLayout.tlf_internal;
+	use namespace tlf_internal;
+		
+	/**
+	 * The ApplyFormatOperation class encapsulates a style change.
+	 * 
+	 * <p>An ApplyFormatOperation applies the leaf format to the text in the 
+	 * specified range (no change is made if the specified range is a single point). 
+	 * It applies the paragraph format to any paragraphs at least partially within the range 
+	 * (or a single paragraph if the range is a single point). 
+	 * And it applies the container format to any containers at least partially within the range 
+	 * (or a single container if the range is a single point).</p>
+	 *
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @includeExample examples\ApplyFormatOperation_example.as -noswf
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class ApplyFormatOperation extends FlowTextOperation
+	{
+		private var applyLeafFormat:ITextLayoutFormat;
+		private var applyParagraphFormat:ITextLayoutFormat;
+		private var applyContainerFormat:ITextLayoutFormat;
+
+		// helper array of styles to revert
+		// each entry has a begIdx, endIdx, ContainerFormat
+		private var undoLeafArray:Array;	
+		private var undoParagraphArray:Array;	
+		private var undoContainerArray:Array;	
+		
+		/** 
+		 * Creates an ApplyFormatOperation object.
+		 *
+		 *  @param operationState	Defines the text range to which the format is applied.
+		 *  @param leafFormat	 The format to apply to LeafFlowElement objects in the selected range.
+		 *  @param paragraphFormat The format to apply to ParagraphElement objects in the selected range.
+		 *  @param containerFormat The format to apply to containers in the selected range.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */		
+		public function ApplyFormatOperation(operationState:SelectionState, leafFormat:ITextLayoutFormat, paragraphFormat:ITextLayoutFormat, containerFormat:ITextLayoutFormat = null)
+		{
+			super(operationState);
+			this.leafFormat = leafFormat;
+			this.paragraphFormat = paragraphFormat;
+			this.containerFormat = containerFormat;
+		}
+
+		/** 
+		 * The format properties to apply to the leaf elements in the range.
+		 * 
+		 * <p>If the range of this operation is a point, or if <code>leafFormat</code> is <code>null</code>,
+		 * then no leaf element formats are changed.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get leafFormat():ITextLayoutFormat
+		{
+			return applyLeafFormat;
+		}
+		public function set leafFormat(value:ITextLayoutFormat):void
+		{
+			applyLeafFormat = value ? new TextLayoutFormat(value) : null;
+		}
+		
+		/** 
+		 * The format properties to apply to the paragraphs in the range.
+		 * 
+		 * <p>The formats of any paragraphs at least partially within the range are updated. 
+		 * If the range of this operation is a point, then a single paragraph is updated.
+		 * If <code>paragraphFormat</code> is <code>null</code>, then no paragraph formats are changed.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get paragraphFormat():ITextLayoutFormat
+		{
+			return applyParagraphFormat;
+		}
+		public function set paragraphFormat(value:ITextLayoutFormat):void
+		{
+			applyParagraphFormat = value ? new TextLayoutFormat(value) : null;
+		}
+		
+		/** 
+		 * The format properties to apply to the containers in the range.
+		 * 
+		 * <p>The formats of any containers at least partially within the range are updated. 
+		 * If the range of this operation is a point, then a single container is updated.
+		 * If <code>containerFormat</code> is <code>null</code>, then no container formats are changed.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get containerFormat():ITextLayoutFormat
+		{
+			return applyContainerFormat;
+		}
+		public function set containerFormat(value:ITextLayoutFormat):void
+		{
+			applyContainerFormat = value ? new TextLayoutFormat(value) : null;
+		}
+		
+		private function doInternal():SelectionState
+		{
+			var anyNewSelectionState:SelectionState;
+			
+			// Apply character format
+			if (applyLeafFormat)
+			{
+				if (absoluteStart != absoluteEnd)
+				{
+					var range:ElementRange = ElementRange.createElementRange(textFlow, absoluteStart,absoluteEnd);
+					
+					var begSel:int = range.absoluteStart;
+					var endSel:int = range.absoluteEnd;
+					if(endSel == textFlow.textLength - 1)
+						++endSel;
+						
+				//	CONFIG::debug { if (begSel != absoluteStart || endSel != absoluteEnd) trace("found mismatch ApplyFormatOperation"); }
+					if (!undoLeafArray)
+					{
+						undoLeafArray = new Array();
+						ParaEdit.cacheStyleInformation(textFlow,begSel,endSel,undoLeafArray);
+					}
+					ParaEdit.applyTextStyleChange(textFlow,begSel,endSel,applyLeafFormat,null);
+				}
+				else if (originalSelectionState.selectionManagerOperationState && textFlow.interactionManager)
+				{
+					// on point selection remember pendling leaf formats for next char typed
+					
+					anyNewSelectionState = originalSelectionState.clone();
+					var newFormat:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder(anyNewSelectionState.pointFormat);
+					newFormat.apply(applyLeafFormat);
+					anyNewSelectionState.pointFormat = newFormat;
+				}
+			}
+
+			if (applyParagraphFormat)
+			{
+				if (!undoParagraphArray)
+				{
+					undoParagraphArray = new Array();
+					ParaEdit.cacheParagraphStyleInformation(textFlow,absoluteStart, absoluteEnd,undoParagraphArray);
+				}
+				ParaEdit.applyParagraphStyleChange(textFlow,absoluteStart, absoluteEnd,applyParagraphFormat,null);
+			}
+			if (applyContainerFormat)
+			{
+				if (!undoContainerArray)
+				{
+					undoContainerArray = new Array();
+					ParaEdit.cacheContainerStyleInformation(textFlow,absoluteStart,absoluteEnd,undoContainerArray);
+				}
+				ParaEdit.applyContainerStyleChange(textFlow,absoluteStart,absoluteEnd,applyContainerFormat,null);
+			}
+			return anyNewSelectionState;
+		}
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{ 
+			var newSelectionState:SelectionState = doInternal();
+			if (newSelectionState && textFlow.interactionManager)
+				textFlow.interactionManager.setSelectionState(newSelectionState);
+			return true;
+		}	
+		
+		/** @private */
+		override public function redo():SelectionState
+		{
+			var newSelectionState:SelectionState = doInternal();
+			return newSelectionState? newSelectionState : originalSelectionState;
+		}
+		
+		/** @private */
+		public override function undo():SelectionState
+		{ 
+			var obj:Object;
+			
+			// Undo character format changes
+			for each (obj in undoLeafArray)
+				ParaEdit.setTextStyleChange(textFlow,obj.begIdx,obj.endIdx,obj.style);
+
+			// Undo paragraph format changes
+			for each (obj in undoParagraphArray)
+				ParaEdit.setParagraphStyleChange(textFlow,obj.begIdx,obj.endIdx,obj.attributes);
+
+			// Undo container format changes
+			for each (obj in undoContainerArray)
+				ParaEdit.setContainerStyleChange(textFlow,obj);
+
+			return originalSelectionState;
+		}
+		
+	}
+}
\ No newline at end of file
diff --git a/textLayout_edit/src/flashx/textLayout/operations/ApplyFormatToElementOperation.as b/textLayout_edit/src/flashx/textLayout/operations/ApplyFormatToElementOperation.as
new file mode 100755
index 0000000..5ae25f9
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/ApplyFormatToElementOperation.as
@@ -0,0 +1,123 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.ParagraphFormattedElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.formats.Category;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.property.Property;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+	
+	/**
+	 * The ApplyFormatToElementOperation class encapsulates a style change to an element.
+	 *
+	 * <p>This operation applies one or more formats to a flow element.</p>
+	 * 
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.formats.TextLayoutFormat
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class ApplyFormatToElementOperation extends FlowElementOperation
+	{
+		private var _format:ITextLayoutFormat;
+		
+		private var undoCoreStyles:Object;
+				
+		/** 
+		* Creates an ApplyFormatToElementOperation object. 
+		* 
+		* @param operationState Specifies the text flow containing the element to which this operation is applied.
+		* @param targetElement specifies the element to which this operation is applied.
+		* @param format The formats to apply in this operation.
+		 * 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0 
+		*/
+		public function ApplyFormatToElementOperation(operationState:SelectionState, targetElement:FlowElement, format:ITextLayoutFormat, relativeStart:int = 0, relativeEnd:int = -1)
+		{
+			super(operationState,targetElement,relativeStart,relativeEnd);
+				
+			// split up the properties by category
+			_format = format;
+		}
+				
+		/** 
+		 * The character formats applied in this operation.
+		 * 
+		 * <p>If <code>null</code> no character formats are changed.</p> 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get format():ITextLayoutFormat
+		{
+			return _format;
+		}
+		public function set format(value:ITextLayoutFormat):void
+		{
+			_format = value;
+		}
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			var targetElement:FlowElement = getTargetElement();
+			
+			adjustForDoOperation(targetElement);
+			
+			undoCoreStyles = targetElement.coreStyles;
+			
+			if (_format)
+			{
+				var newFormat:TextLayoutFormat = new TextLayoutFormat(targetElement.format);
+				newFormat.apply(_format);
+				targetElement.format = newFormat;
+			}
+			
+			return true;
+		}	
+		
+		/** @private */
+		public override function undo():SelectionState
+		{
+			var targetElement:FlowElement = getTargetElement();
+			
+			targetElement.setCoreStylesInternal (undoCoreStyles);
+			
+			adjustForUndoOperation(targetElement);
+			
+			return originalSelectionState;
+		}
+	}
+}
\ No newline at end of file
diff --git a/textLayout_edit/src/flashx/textLayout/operations/ApplyLinkOperation.as b/textLayout_edit/src/flashx/textLayout/operations/ApplyLinkOperation.as
new file mode 100755
index 0000000..8d315ea
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/ApplyLinkOperation.as
@@ -0,0 +1,187 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.LinkElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.edit.TextFlowEdit;
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.edit.TextScrap;
+	import flashx.textLayout.edit.TextFlowEdit;
+	import flashx.textLayout.tlf_internal;
+	use namespace tlf_internal;
+	
+	/**
+	 * The ApplyLinkOperation class encapsulates a link creation or modification operation.
+	 *
+	 * @see flashx.textLayout.elements.LinkElement
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @includeExample examples\ApplyLinkOperation_example.as -noswf
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */			
+	public class ApplyLinkOperation extends FlowTextOperation
+	{
+		private var _textScrap:TextScrap;
+		private var _hrefString:String;
+		private var _target:String;
+		private var _extendToLinkBoundary:Boolean;
+
+		/** 
+		 * Creates an ApplyLinkOperation object.
+		 * 
+		 * @param operationState	The text range to which the operation is applied.
+		 * @param href The URI to be associated with the link.  If href is an empty string, 
+		 * the URI of links in the selection are removed.
+		 * @param target The target of the link.
+		 * @param extendToLinkBoundary Whether to extend the selection to include the entire 
+		 * text of any existing links overlapped by the selection, and then apply the change.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		function ApplyLinkOperation(operationState:SelectionState, href:String, target:String, extendToLinkBoundary:Boolean)
+		{
+			super(operationState);
+		
+			_hrefString = href;
+			_target = target;
+			_extendToLinkBoundary = extendToLinkBoundary;
+		}
+		
+		/** 
+		 * The URI to be associated with the link.  If href is an empty string, 
+		 * the URI of links in the selection are removed.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get href():String
+		{
+			return _hrefString;
+		}
+		public function set href(value:String):void
+		{
+			_hrefString = value;
+		}
+		
+		/**
+		 * The target of the link.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get target():String
+		{
+			return _target;
+		}
+		public function set target(value:String):void
+		{
+			_target = value;
+		}
+		
+		/**
+		 * Whether to extend the selection to include the entire 
+		 * text of any existing links overlapped by the selection, and then apply the change.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get extendToLinkBoundary():Boolean
+		{
+			return _extendToLinkBoundary;
+		}
+		public function set extendToLinkBoundary(value:Boolean):void
+		{
+			_extendToLinkBoundary = value;
+		}
+
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			if (absoluteStart == absoluteEnd)
+				return false;
+			
+			if (_extendToLinkBoundary)
+			{
+				var leaf:FlowLeafElement = textFlow.findLeaf(absoluteStart);
+				var link:LinkElement = leaf.getParentByType(LinkElement) as LinkElement;
+				if (link)
+				{
+					absoluteStart = link.getAbsoluteStart();
+				}
+				
+				leaf = textFlow.findLeaf(absoluteEnd-1);
+				link = leaf.getParentByType(LinkElement) as LinkElement;
+				if (link)
+				{
+					absoluteEnd = link.getAbsoluteStart() + link.textLength;
+				}
+			}
+			//save it off so that we can restore the flow on undo			
+			_textScrap = TextFlowEdit.createTextScrap(textFlow, absoluteStart, absoluteEnd);
+				
+			if (_hrefString != "")
+			{
+				var madeLink:Boolean = TextFlowEdit.makeLink(textFlow, absoluteStart, absoluteEnd, _hrefString, _target);
+				if (!madeLink) return false;
+			}
+			else
+			{
+				TextFlowEdit.removeLink(textFlow, absoluteStart, absoluteEnd);				
+			} 
+			return true;
+		}
+		
+		/** @private */
+		public override function undo():SelectionState
+		{
+			if (absoluteStart != absoluteEnd && _textScrap != null) 
+				TextFlowEdit.replaceRange(textFlow, absoluteStart, absoluteEnd, _textScrap);
+			return originalSelectionState;				
+		}
+	
+		/** @private */
+		public override function redo():SelectionState
+		{
+			if (absoluteStart != absoluteEnd)
+			{
+				if (_hrefString != "")
+				{
+					TextFlowEdit.makeLink(textFlow, absoluteStart, absoluteEnd, _hrefString, _target);
+				}
+				else
+				{
+					TextFlowEdit.removeLink(textFlow, absoluteStart, absoluteEnd);				
+				} 
+			}
+			return originalSelectionState;	
+		}
+	}
+}
diff --git a/textLayout_edit/src/flashx/textLayout/operations/ApplyTCYOperation.as b/textLayout_edit/src/flashx/textLayout/operations/ApplyTCYOperation.as
new file mode 100755
index 0000000..8b482b1
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/ApplyTCYOperation.as
@@ -0,0 +1,183 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.elements.TCYElement;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.edit.TextScrap;
+	import flashx.textLayout.edit.TextFlowEdit;
+	import flashx.textLayout.tlf_internal;
+	
+	import flashx.textLayout.debug.assert;
+	
+	use namespace tlf_internal;
+	
+	/** 
+	 * The ApplyTCYOperation class encapsulates a TCY transformation.
+	 *
+	 * @see flashx.textLayout.elements.TCYElement
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class ApplyTCYOperation extends FlowTextOperation
+	{
+		
+		private var makeBegIdx:int;
+		private var makeEndIdx:int;
+		private var removeBegIdx:int;
+		private var removeEndIdx:int;
+		private var removeRedoBegIdx:int;
+		private var removeRedoEndIdx:int;
+		
+		private var _textScrap:TextScrap;
+		private var _tcyOn:Boolean;
+
+		/** 
+		 * Creates an ApplyTCYOperation object.
+		 * 
+		 * @param operationState Describes the range of text to which the operation is applied.
+		 * @param tcyValue Specifies whether to apply TCY (<code>true</code>), or remove TCY (<code>false</code>).
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function ApplyTCYOperation(operationState:SelectionState, tcyOn:Boolean)
+		{
+			super(operationState);
+			
+			if(tcyOn)
+			{
+				makeBegIdx = operationState.absoluteStart;
+				makeEndIdx = operationState.absoluteEnd;
+			}
+			else
+			{
+				removeBegIdx = operationState.absoluteStart;
+				removeEndIdx = operationState.absoluteEnd;
+			}
+			
+			_tcyOn = tcyOn;
+		}
+
+		/** 
+		 * Indicates whether the operation applies or removes TCY formatting.
+		 * 
+		 * <p>If <code>true</code>, then the operation transforms the range into a 
+		 * TCY element. If <code>false</code>, then the operation removes TCY formatting from
+		 * the first TCY element in the range.</p>
+		 * 
+		 * @see flashx.textLayout.elements.TCYElement
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function get tcyOn():Boolean
+		{
+			return _tcyOn;
+		}
+		
+		public function set tcyOn(val:Boolean):void
+		{
+			_tcyOn = val;
+		}
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			if (_tcyOn && makeEndIdx <= makeBegIdx)
+			{
+				return false;
+			}
+			else if(!_tcyOn && removeEndIdx <= removeBegIdx)
+			{
+				return false;
+			}
+			
+			if (_tcyOn)
+			{
+				//save it off so that we can restore the flow on undo - make and remove need different scraps		
+				_textScrap = TextFlowEdit.createTextScrap(textFlow, makeBegIdx, makeEndIdx);
+				TextFlowEdit.makeTCY(textFlow, makeBegIdx, makeEndIdx);
+			}
+			else
+			{
+				var leaf:FlowLeafElement = textFlow.findLeaf(removeBegIdx);
+				var tcyElem:TCYElement = leaf.getParentByType(TCYElement) as TCYElement
+				CONFIG::debug{ assert(tcyElem != null, "Trying to remove TCY from a non-TCY element!"); }
+				
+				//collect the bounds for redo of removal - redo bounds are only the selection, while do bounds are the whole
+				//tcyElement
+				removeRedoBegIdx = removeBegIdx;
+				removeRedoEndIdx = removeEndIdx;
+				
+				//now reset the beg and end idx's	
+				removeBegIdx = tcyElem.getAbsoluteStart();
+				removeEndIdx = removeBegIdx + tcyElem.textLength;
+				
+				//create the scrap of the whole TCY element
+				_textScrap = TextFlowEdit.createTextScrap(textFlow, removeBegIdx, removeEndIdx);
+			
+				//use the removeRedoBegIdx/removeRedoEndIdx
+				TextFlowEdit.removeTCY(textFlow, removeRedoBegIdx, removeRedoEndIdx);
+			} 
+			return true;				
+		}
+		
+		/** @private */
+		public override function undo():SelectionState
+		{
+			if (_textScrap != null) {
+				if (_tcyOn)
+				{
+					TextFlowEdit.replaceRange(textFlow, makeBegIdx, makeEndIdx, _textScrap);
+				}
+				else
+				{
+					TextFlowEdit.replaceRange(textFlow, removeBegIdx, removeEndIdx, _textScrap);
+				}
+			}
+			return originalSelectionState;				
+		}
+	
+		/** @private */
+		public override function redo():SelectionState
+		{
+			if(_textScrap != null)
+			{
+				if (_tcyOn)
+				{
+					TextFlowEdit.makeTCY(textFlow, makeBegIdx, makeEndIdx);
+				}
+				else
+				{
+					TextFlowEdit.removeTCY(textFlow, removeRedoBegIdx, removeRedoEndIdx);				
+				} 
+			}
+			return originalSelectionState;
+		}
+	}
+}
\ No newline at end of file
diff --git a/textLayout_edit/src/flashx/textLayout/operations/ClearFormatOnElementOperation.as b/textLayout_edit/src/flashx/textLayout/operations/ClearFormatOnElementOperation.as
new file mode 100755
index 0000000..98845dc
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/ClearFormatOnElementOperation.as
@@ -0,0 +1,131 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.ParagraphFormattedElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.formats.Category;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormatValueHolder;
+	import flashx.textLayout.property.Property;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+	
+	/**
+	 * The ClearFormatOnElementOperation class encapsulates a style change to an element.
+	 *
+	 * <p>This operation undefines one or more formats to a flow element.</p>
+	 * 
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.formats.TextLayoutFormat
+	 * @see flashx.textLayout.events.FlowOperationEvent
+
+	 * @see ApplyFormatToElementOperation
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class ClearFormatOnElementOperation extends FlowElementOperation
+	{
+		private var _format:ITextLayoutFormat;
+		
+		private var undoCoreStyles:Object;
+				
+		/** 
+		* Creates an ClearFormatOnElementOperation object. 
+		* 
+		* @param operationState Specifies the text flow containing the element to which this operation is applied.
+		* @param targetElement specifies the element to which this operation is applied.
+		* @param format The formats to apply in this operation.
+		 * 
+		* @playerversion Flash 10
+		* @playerversion AIR 1.5
+	 	* @langversion 3.0 
+		*/
+		public function ClearFormatOnElementOperation(operationState:SelectionState, targetElement:FlowElement, format:ITextLayoutFormat, relativeStart:int = 0, relativeEnd:int = -1)
+		{
+			super(operationState,targetElement,relativeStart,relativeEnd);
+				
+			// split up the properties by category
+			_format = format;
+		}
+				
+		/** 
+		 * The character formats applied in this operation.
+		 * 
+		 * <p>If <code>null</code> no character formats are changed.</p> 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get format():ITextLayoutFormat
+		{
+			return _format;
+		}
+		public function set format(value:ITextLayoutFormat):void
+		{
+			_format = value;
+		}
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			var targetElement:FlowElement = getTargetElement();
+			
+			adjustForDoOperation(targetElement);
+			
+			undoCoreStyles = targetElement.coreStyles;
+			
+			if (_format)
+			{
+				var newFormat:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder(targetElement.format);
+				// this is fairly rare so this operation is not optimizied
+				for (var prop:String in TextLayoutFormat.description)
+				{
+					if (_format[prop] !== undefined)
+						newFormat[prop] = undefined;
+				} 
+				targetElement.format = newFormat;
+			}
+			
+			return true;
+		}	
+		
+		/** @private */
+		public override function undo():SelectionState
+		{
+			var targetElement:FlowElement = getTargetElement();
+			
+			targetElement.setCoreStylesInternal (undoCoreStyles);
+			
+			adjustForUndoOperation(targetElement);
+			
+			return originalSelectionState;
+		}
+	}
+}
diff --git a/textLayout_edit/src/flashx/textLayout/operations/ClearFormatOperation.as b/textLayout_edit/src/flashx/textLayout/operations/ClearFormatOperation.as
new file mode 100755
index 0000000..36ac8a9
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/ClearFormatOperation.as
@@ -0,0 +1,244 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.edit.ElementRange;
+	import flashx.textLayout.edit.ParaEdit;
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.formats.Category;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormatValueHolder;
+	import flashx.textLayout.property.Property;
+	import flashx.textLayout.tlf_internal;
+	use namespace tlf_internal;
+		
+	/**
+	 * The ClearFormatOperation class encapsulates a way to undefine formats.
+	 * 
+	 * <p>An UndefineFormatOperation undefines properties set in the leaf format to the text in the 
+	 * specified range (no change is made if the specified range is a single point). 
+	 * It undefines properties set in the paragraph format to any paragraphs at least partially within the range 
+	 * (or a single paragraph if the range is a single point). 
+	 * And it undefines properties set in the container format to any containers at least partially within the range 
+	 * (or a single container if the range is a single point).</p>
+	 *
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @includeExample examples\ApplyFormatOperation_example.as -noswf
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class ClearFormatOperation extends FlowTextOperation
+	{
+		private var applyLeafFormat:ITextLayoutFormat;
+		private var applyParagraphFormat:ITextLayoutFormat;
+		private var applyContainerFormat:ITextLayoutFormat;
+
+		// helper array of styles to revert
+		// each entry has a begIdx, endIdx, ContainerFormat
+		private var undoLeafArray:Array;	
+		private var undoParagraphArray:Array;	
+		private var undoContainerArray:Array;	
+		
+		/** 
+		 * Creates an ClearFormatOperation object.
+		 *
+		 *  @param operationState	Defines the text range to which the format is applied.
+		 *  @param leafFormat	 The format whose set values indicate properties to undefine to LeafFlowElement objects in the selected range.
+		 *  @param paragraphFormat The format whose set values indicate properties to undefine to ParagraphElement objects in the selected range.
+		 *  @param containerFormat The format whose set values indicate properties to undefine to ContainerController objects in the selected range.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */		
+		public function ClearFormatOperation(operationState:SelectionState, leafFormat:ITextLayoutFormat, paragraphFormat:ITextLayoutFormat, containerFormat:ITextLayoutFormat = null)
+		{
+			super(operationState);
+			this.leafFormat = leafFormat;
+			this.paragraphFormat = paragraphFormat;
+			this.containerFormat = containerFormat;
+		}
+
+		/** 
+		 * The format properties to undefine on the leaf elements in the range.
+		 * 
+		 * <p>If the range of this operation is a point, or if <code>leafFormat</code> is <code>null</code>,
+		 * then no leaf element formats are changed.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get leafFormat():ITextLayoutFormat
+		{
+			return applyLeafFormat;
+		}
+		public function set leafFormat(value:ITextLayoutFormat):void
+		{
+			applyLeafFormat = value ? new TextLayoutFormat(value) : null;
+		}
+		
+		/** 
+		 * The format properties to undefine on the paragraphs in the range.
+		 * 
+		 * <p>The formats of any paragraphs at least partially within the range are updated. 
+		 * If the range of this operation is a point, then a single paragraph is updated.
+		 * If <code>paragraphFormat</code> is <code>null</code>, then no paragraph formats are changed.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get paragraphFormat():ITextLayoutFormat
+		{
+			return applyParagraphFormat;
+		}
+		public function set paragraphFormat(value:ITextLayoutFormat):void
+		{
+			applyParagraphFormat = value ? new TextLayoutFormat(value) : null;
+		}
+		
+		/** 
+		 * The format properties to undefine on the containers in the range.
+		 * 
+		 * <p>The formats of any containers at least partially within the range are updated. 
+		 * If the range of this operation is a point, then a single container is updated.
+		 * If <code>containerFormat</code> is <code>null</code>, then no container formats are changed.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get containerFormat():ITextLayoutFormat
+		{
+			return applyContainerFormat;
+		}
+		public function set containerFormat(value:ITextLayoutFormat):void
+		{
+			applyContainerFormat = value ? new TextLayoutFormat(value) : null;
+		}
+		
+		private function doInternal():SelectionState
+		{
+			var anyNewSelectionState:SelectionState;
+
+			// Apply character format
+			if (applyLeafFormat)
+			{
+				if (absoluteStart != absoluteEnd)
+				{
+					var range:ElementRange = ElementRange.createElementRange(textFlow, absoluteStart,absoluteEnd);
+					
+					var begSel:int = range.absoluteStart;
+					var endSel:int = range.absoluteEnd;
+					if(endSel == textFlow.textLength - 1)
+						++endSel;
+						
+				//	CONFIG::debug { if (begSel != absoluteStart || endSel != absoluteEnd) trace("found mismatch ApplyFormatOperation"); }
+					if (!undoLeafArray)
+					{
+						undoLeafArray = new Array();
+						ParaEdit.cacheStyleInformation(textFlow,begSel,endSel,undoLeafArray);
+					}
+					ParaEdit.applyTextStyleChange(textFlow,begSel,endSel,null,applyLeafFormat);
+				}
+				else if (originalSelectionState.selectionManagerOperationState && textFlow.interactionManager)
+				{
+					// on point selection remember pendling leaf formats for next char typed
+					
+					anyNewSelectionState = originalSelectionState.clone();
+					// This is only a partial implementation - see watson bug 
+					// here if the format is pending we can clear it
+					// The bug is that we don't remember any pending clear that's not set in pointFormat on the next character typed
+					var newFormat:TextLayoutFormatValueHolder = new TextLayoutFormatValueHolder(anyNewSelectionState.pointFormat);
+					for (var prop:String in TextLayoutFormat.description)
+					{
+						if (applyLeafFormat[prop] !== undefined)
+							newFormat[prop] = undefined;
+					}
+					anyNewSelectionState.pointFormat = newFormat;
+				}				
+			}
+
+			if (applyParagraphFormat)
+			{
+				if (!undoParagraphArray)
+				{
+					undoParagraphArray = new Array();
+					ParaEdit.cacheParagraphStyleInformation(textFlow,absoluteStart, absoluteEnd,undoParagraphArray);
+				}
+				ParaEdit.applyParagraphStyleChange(textFlow,absoluteStart, absoluteEnd, null, applyParagraphFormat);
+			}
+			if (applyContainerFormat)
+			{
+				if (!undoContainerArray)
+				{
+					undoContainerArray = new Array();
+					ParaEdit.cacheContainerStyleInformation(textFlow,absoluteStart,absoluteEnd,undoContainerArray);
+				}
+				ParaEdit.applyContainerStyleChange(textFlow,absoluteStart,absoluteEnd, null, applyContainerFormat);
+			}
+			return anyNewSelectionState;
+		}
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{ 
+			var newSelectionState:SelectionState = doInternal();
+			if (newSelectionState && textFlow.interactionManager)
+				textFlow.interactionManager.setSelectionState(newSelectionState);
+			return true;
+		}
+
+		override public function redo():SelectionState
+		{
+			var newSelectionState:SelectionState = doInternal();
+			return newSelectionState? newSelectionState : originalSelectionState;
+		}		
+
+		/** @private */
+		public override function undo():SelectionState
+		{ 
+			var obj:Object;
+			
+			// Undo character format changes
+			for each (obj in undoLeafArray)
+				ParaEdit.setTextStyleChange(textFlow,obj.begIdx,obj.endIdx,obj.style);
+
+			// Undo paragraph format changes
+			for each (obj in undoParagraphArray)
+				ParaEdit.setParagraphStyleChange(textFlow,obj.begIdx,obj.endIdx,obj.attributes);
+
+			// Undo container format changes
+			for each (obj in undoContainerArray)
+				ParaEdit.setContainerStyleChange(textFlow,obj);
+
+			return originalSelectionState;
+		}
+		
+	}
+}
diff --git a/textLayout_edit/src/flashx/textLayout/operations/CompositeOperation.as b/textLayout_edit/src/flashx/textLayout/operations/CompositeOperation.as
new file mode 100755
index 0000000..76c575b
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/CompositeOperation.as
@@ -0,0 +1,218 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.tlf_internal;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.debug.assert;
+
+	use namespace tlf_internal;
+
+	/**
+	 * The CompositeOperation class encapsulates a group of transformations managed as a unit.
+	 *
+	 * <p>The CompositeOperation class provides a grouping mechanism for combining multiple FlowOperations 
+	 * into a single atomic operation. Grouping operations allows them to be undone and redone as a unit. 
+	 * For example, several single character inserts followed by several backspaces can be undone together as if 
+	 * they were a single operation. Grouping also provides a mechanism for representing
+	 * complex operations. For example, a replace operation that modifies more than one text ranges
+	 * can be represented and managed as a single composite operation.</p>
+	 * 
+	 * <p><b>Note:</b> It can be more efficient to merge individual atomic operations
+	 *  rather than to combine separate operations into a group. For example, several sequential
+	 *  character inserts can easily be represented as a single insert operation,
+	 *  and undoing or redoing that single operation is more efficient than
+	 *  undoing or redoing a group of insert operations.</p>
+	 * 
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class CompositeOperation extends FlowOperation
+	{
+		private var _operations:Array;
+		
+		/** 
+		 * Creates a CompositeOperation object.
+		 * 
+		 * @param operations The operations to group.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function CompositeOperation(operations:Array = null)
+		{
+			super(null);
+			this.operations = operations;
+		}
+
+		/** @private */
+		override public function get textFlow():TextFlow
+		{ return _operations.length > 0 ? _operations[0].textFlow : null; }
+		
+		/**
+		 * An array containing the operations grouped by this composite operation.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function get operations():Array
+		{
+			return _operations;
+		}
+		public function set operations(value:Array):void
+		{
+			_operations = value ? value.slice() : [];	// make a copy
+		}
+		
+		/** 
+		 * Adds an additional operation to the end of the list. 
+		 * 
+		 * <p>The new operation must operate on the same TextFlow object as 
+		 * the other operations in the list.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function addOperation(operation:FlowOperation):void
+		{
+			// Can't handle operations from other TextFlows
+			if (_operations.length > 0 && operation.textFlow != textFlow)
+				return;
+				
+			CONFIG::debug { assert(_operations.length <= 0 || operation.beginGeneration == _operations[_operations.length - 1].endGeneration,
+				"adding non-contiguous operation to composite operation"); }
+			_operations.push(operation);
+		}
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			// execute all the operations in order
+			var success:Boolean = true;
+			for (var i:int = 0; i < _operations.length; i++)
+				success = success && FlowOperation(_operations[i]).doOperation();
+			
+			// return selectionState from last operation
+			return true;
+		}
+		
+		/** @private */
+		public override function undo():SelectionState
+		{
+			// undo all the operations in reverse order
+			var selState:SelectionState;
+			for (var i:int = _operations.length - 1; i >= 0; i--)
+				selState = FlowOperation(_operations[i]).undo();
+			
+			// return selectionState from last performed
+			// (i.e., the first in the set of operations)
+			return selState;
+		}
+		
+		/** @private */
+		public override function redo():SelectionState
+		{
+			// execute all the operations in order
+			var selState:SelectionState;
+			for (var i:int = 0; i < _operations.length; i++)
+				selState = FlowOperation(_operations[i]).redo();
+			
+			// return selectionState from last operation
+			return selState;
+		}		
+		
+		/** @private */
+		public override function canUndo():Boolean
+		{ 
+			// All operations within the CompositeOperation must have matching generation numbers, and be undoable
+			var undoable:Boolean = true;
+			var generation:int = beginGeneration;
+			var opCount:int = _operations.length;
+			for (var i:int = 0; i < opCount && undoable; i++)
+			{
+				var op:FlowOperation = _operations[i];
+				if (op.beginGeneration != generation || !op.canUndo())
+					undoable = false;
+				generation = op.endGeneration;
+			}
+			if (opCount > 0 && _operations[opCount - 1].endGeneration != endGeneration)
+				undoable = false;
+			
+			return undoable; 
+		}
+		
+		
+		/** @private */
+		tlf_internal override function merge(operation:FlowOperation):FlowOperation
+		{
+			if (operation is InsertTextOperation || operation is SplitParagraphOperation || operation is DeleteTextOperation)
+			{
+				if (this.endGeneration != operation.beginGeneration)
+					return null;
+				// For efficiency, try to combine the last low-level operation
+				// with the new operation. If that's not possible, we just add it 
+				// as an additional operation.
+				// Note that we are making various assumptions here about the technical
+				// feasability and appropriateness of merging the individual operations (e.g.,
+				// that the selection hasn't changed), relying on SelectionManager to
+				// guarantee that these are satisfied.
+				var mergedOp:FlowOperation;
+				var lastOp:FlowOperation = (_operations && _operations.length) ? 
+										FlowOperation(_operations[_operations.length - 1]) :
+										null;
+				if (lastOp) 
+					mergedOp = lastOp.merge(operation);
+				
+				if (mergedOp && !(mergedOp is CompositeOperation))
+					_operations[_operations.length - 1] = mergedOp;
+				else
+					_operations.push(operation);
+				return this;
+			}
+			return null;
+		}
+		
+//		/**
+//		 *  Add an additional operation to the end of this operation.
+//		 *  If the additional operation is itself a CompositeOperation, 
+//		 *  its child operations are just added to this operation's 
+//		 *  set of child operations.
+//		 * 	
+//		 * @param operation The operation to be merged.
+//		 * 
+//		 */
+//		private function mergeOperationViaConcatenation(operation:FlowOperation):void
+//		{
+//			var compositeOp:CompositeOperation = operation as CompositeOperation;
+//			if (compositeOp)
+//				operations = operations.concat(compositeOp.operations);
+//			else
+//				operations.push(operation);
+//		}
+
+	}
+}
\ No newline at end of file
diff --git a/textLayout_edit/src/flashx/textLayout/operations/CopyOperation.as b/textLayout_edit/src/flashx/textLayout/operations/CopyOperation.as
new file mode 100755
index 0000000..f9d9fe5
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/CopyOperation.as
@@ -0,0 +1,85 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.edit.TextClipboard;
+	import flashx.textLayout.edit.TextScrap;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+
+	
+	/**
+	 * The CopyOperation class encapsulates a copy operation.
+	 * 
+	 * <p><b>Note:</b> The operation is responsible for copying the 
+	 * text scrap to the clipboard. Undonig a copy operation does not restore
+	 * the original clipboard state.</p>
+	 * 
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class CopyOperation extends FlowTextOperation
+	{		
+		/** 
+		 * Creates a CopyOperation object.
+		 * 
+		 * @param operationState The range of text to be copied.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function CopyOperation(operationState:SelectionState)
+		{
+			super(operationState);
+		}
+		
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			if (originalSelectionState.activePosition != originalSelectionState.anchorPosition)
+				TextClipboard.setContents(TextScrap.createTextScrap(originalSelectionState));		
+			return true;
+		}
+		
+		/** @private */
+		public override function undo():SelectionState
+		{				
+			return originalSelectionState;	
+		}
+	
+		/** @private */
+		public override function redo():SelectionState
+		{
+			return originalSelectionState;	
+
+		}		
+		
+		/** @private */
+		public override function canUndo():Boolean
+		{ return false; }
+	}
+}
diff --git a/textLayout_edit/src/flashx/textLayout/operations/CutOperation.as b/textLayout_edit/src/flashx/textLayout/operations/CutOperation.as
new file mode 100755
index 0000000..17f8a29
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/CutOperation.as
@@ -0,0 +1,114 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.edit.TextFlowEdit;
+	import flashx.textLayout.edit.TextScrap;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+
+	
+	/**
+	 * The CutOperation class encapsulates a cut operation.
+	 *
+	 * <p>The specified range is removed from the text flow.</p>
+	 * 
+	 * <p><b>Note:</b> The edit manager is responsible for copying the 
+	 * text scrap to the clipboard. Undoing a cut operation does not restore
+	 * the original clipboard state.</p>
+	 * 
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class CutOperation extends FlowTextOperation
+	{
+		private var _tScrap:TextScrap;
+		
+		/** 
+		 * Creates a CutOperation object.
+		 * 
+		 * @param operationState The range of text to be cut.
+		 * @param scrapToCut A copy of the deleted text.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		function CutOperation(operationState:SelectionState, scrapToCut:TextScrap)
+		{
+			super(operationState);
+			_tScrap = scrapToCut;
+		}
+		
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			var beforeOpLen:int = textFlow.textLength;
+			TextFlowEdit.replaceRange(textFlow, absoluteStart, absoluteEnd, null);			
+			if (textFlow.interactionManager)
+				textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, -(absoluteEnd - absoluteStart));
+			if (textFlow.textLength == beforeOpLen)
+			{
+				_tScrap = null;
+			}			
+			return true;
+		}
+		
+		/** @private */
+		public override function undo():SelectionState
+		{
+			if (_tScrap != null) 
+			{
+				TextFlowEdit.replaceRange(textFlow, absoluteStart, absoluteStart, _tScrap);
+				if (textFlow.interactionManager)
+					textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, absoluteEnd - absoluteStart);
+			}				
+			return originalSelectionState;	
+		}
+	
+		/** @private */
+		public override function redo():SelectionState
+		{
+			TextFlowEdit.replaceRange(textFlow, absoluteStart,absoluteEnd, null);												
+			if (textFlow.interactionManager)
+				textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, -(absoluteEnd - absoluteStart));
+			return new SelectionState(textFlow, absoluteStart, absoluteStart, null);
+		}
+		
+		/** 
+		 * scrapToCut the original removed text
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function get scrapToCut():TextScrap
+		{ return _tScrap; }
+		public function set scrapToCut(val:TextScrap):void
+		{ _tScrap = val; }
+		
+	}
+}
diff --git a/textLayout_edit/src/flashx/textLayout/operations/DeleteTextOperation.as b/textLayout_edit/src/flashx/textLayout/operations/DeleteTextOperation.as
new file mode 100755
index 0000000..ab7414e
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/DeleteTextOperation.as
@@ -0,0 +1,216 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.edit.SelectionManager;
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.edit.TextFlowEdit;
+	import flashx.textLayout.edit.TextScrap;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormatValueHolder;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+
+	/**
+	 * The DeleteTextOperation class encapsulates the deletion of a range of text.
+	 *
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class DeleteTextOperation extends FlowTextOperation
+	{
+		private var _textScrap:TextScrap;
+		private var _allowMerge:Boolean;
+		private var _undoParaFormat:TextLayoutFormatValueHolder;
+		private var _undoCharacterFormat:TextLayoutFormatValueHolder;
+		private var _needsOldFormat:Boolean = false;
+		private var _pendingFormat:TextLayoutFormatValueHolder;
+		
+		private var _deleteSelectionState:SelectionState = null;
+		/** 
+		 * Creates a DeleteTextOperation operation.
+		 * 
+		 * @param operationState The original range of text.
+		 * @param deleteSelectionState The range of text to delete, if different from the range 
+		 * described by <code>operationState</code>. (Set to <code>null</code> to delete the range
+		 * described by <code>operationState</code>.)
+		 * @param allowMerge Set to <code>true</code> if this operation can be merged with the next or previous operation.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function DeleteTextOperation(operationState:SelectionState, deleteSelectionState:SelectionState = null, allowMerge:Boolean = false)
+		{
+			_deleteSelectionState = deleteSelectionState ? deleteSelectionState : operationState;				
+			
+			super(_deleteSelectionState);
+			originalSelectionState = operationState;
+			_allowMerge = allowMerge;
+		}
+		
+		/** 
+		 * Indicates whether this operation can be merged with operations executed before or after it.
+		 * 
+		 * <p>Some delete operations, for example, a sequence of backspace keystrokes, can be fruitfully 
+		 * merged into one operation so that undoing the operation reverses the entire sequence.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get allowMerge():Boolean
+		{
+			return _allowMerge;
+		}
+		public function set allowMerge(value:Boolean):void
+		{
+			_allowMerge = value;
+		}
+		
+		/** 
+		 * deleteSelectionState The range of text to delete
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get deleteSelectionState():SelectionState
+		{
+			return _deleteSelectionState;
+		}
+		public function set deleteSelectionState(value:SelectionState):void
+		{
+			_deleteSelectionState = value;
+		}
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			// Nothing to delete
+			if (absoluteStart == absoluteEnd)
+				return false;
+				
+			_textScrap = TextFlowEdit.createTextScrap(textFlow, absoluteStart, absoluteEnd);
+			var leafEl:FlowLeafElement = textFlow.findLeaf(absoluteStart);
+			var paraEl:ParagraphElement = leafEl.getParagraph(); 
+			var paraElAbsStart:int = paraEl.getAbsoluteStart();
+			
+			_pendingFormat = new TextLayoutFormatValueHolder(leafEl.format);
+						
+			if (_textScrap)
+			{
+				if ((_textScrap.textFlow.textLength == 1) && 
+						((absoluteEnd == (textFlow.textLength - 1)) || (absoluteEnd == (paraElAbsStart + paraEl.textLength))))
+			 	{
+					//special case. Always insert the paragraph
+					_textScrap.beginMissingArray = new Array();
+					_textScrap.endMissingArray = new Array();
+			 	}
+			 	
+			 	if (_textScrap.textFlow.textLength >= 1)
+			 	{
+					//save off the paragraph format of the next paragraph since we will need to set it back
+					//on an undo operation					
+					leafEl = textFlow.findLeaf(absoluteEnd);
+					paraEl = leafEl.getParagraph();
+					if (absoluteEnd == paraEl.getAbsoluteStart())
+					{
+						_undoParaFormat = new TextLayoutFormatValueHolder(paraEl.format);
+						_undoCharacterFormat = new TextLayoutFormatValueHolder(leafEl.format);
+						_needsOldFormat = true;
+					}
+				}
+			} 
+			
+			var beforeOpLen:int = textFlow.textLength;
+			TextFlowEdit.replaceRange(textFlow, absoluteStart, absoluteEnd, null);
+			if (textFlow.interactionManager)
+				textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, -(absoluteEnd - absoluteStart));
+			
+			if (originalSelectionState.selectionManagerOperationState && textFlow.interactionManager)
+			{
+				// set pointFormat from leafFormat
+				var state:SelectionState = textFlow.interactionManager.getSelectionState();
+				if (state.anchorPosition == state.activePosition)
+				{
+					state.pointFormat = new TextLayoutFormatValueHolder(_pendingFormat);
+					textFlow.interactionManager.setSelectionState(state);
+				}
+			}
+
+			// nothing deleted???
+			if (beforeOpLen == textFlow.textLength)
+				_textScrap = null;
+			return true;	
+		}
+		
+		/** @private */
+		public override function undo():SelectionState
+		{
+			if (_textScrap != null) {
+				TextFlowEdit.replaceRange(textFlow, absoluteStart, absoluteStart, _textScrap);
+				if (_needsOldFormat)
+				{
+					textFlow.normalize();
+					var leafEl:FlowLeafElement = textFlow.findLeaf(absoluteEnd);
+					if (leafEl)
+					{
+						var paraEl:ParagraphElement = leafEl.getParagraph();
+						paraEl.format = _undoParaFormat;
+						leafEl.format = _undoCharacterFormat; 
+					}
+					
+				}
+				if (textFlow.interactionManager)
+					textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, absoluteEnd - absoluteStart);
+			}
+			return originalSelectionState;				
+		}
+	
+		/** @private */
+		public override function redo():SelectionState
+		{
+			TextFlowEdit.replaceRange(textFlow, absoluteStart, absoluteEnd, null);			
+			if (textFlow.interactionManager)
+				textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, -(absoluteEnd - absoluteStart));
+			return new SelectionState(textFlow,absoluteStart,absoluteStart,_pendingFormat);	
+		}
+
+		/** @private */
+		tlf_internal override function merge(op2:FlowOperation):FlowOperation
+		{
+			if (this.endGeneration != op2.beginGeneration)
+					return null;
+			var delOp:DeleteTextOperation = op2 as DeleteTextOperation;
+			if ((delOp == null) || !delOp.allowMerge || !_allowMerge)
+				return null;
+				
+			return new CompositeOperation([this, op2]);
+		}	
+	}
+}
diff --git a/textLayout_edit/src/flashx/textLayout/operations/FlowElementOperation.as b/textLayout_edit/src/flashx/textLayout/operations/FlowElementOperation.as
new file mode 100755
index 0000000..2412048
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/FlowElementOperation.as
@@ -0,0 +1,248 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.SpanElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+	
+	/**
+	 * The FlowElementOperation class is the base class for operations that transform a FlowElement.
+	 *
+	 * @see flashx.textLayout.formats.TextLayoutFormat
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class FlowElementOperation extends FlowTextOperation
+	{	
+		private var nestLevel:int;
+		private var absStart:int;
+		private var absEnd:int;
+		
+		private var origAbsStart:int;
+		private var origAbsEnd:int;
+		
+		private var firstTime:Boolean = true;
+		private var splitAtStart:Boolean = false;
+		private var splitAtEnd:Boolean = false;
+		
+		private var _relStart:int = 0;
+		private var _relEnd:int = -1;
+		
+		/** 
+		 * Creates a FlowElementOperation object.
+		 *  
+		 * @param operationState Specifies the TextFlow object this operation acts upon.
+		 * @param targetElement Specifies the element this operation modifies.
+		 * @param relativeStart An offset from the beginning of the <code>targetElement</code>.
+		 * @param relativeEnd An offset from the end of the <code>targetElement</code>.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function FlowElementOperation(operationState:SelectionState, targetElement:FlowElement, relativeStart:int = 0, relativeEnd:int = -1)
+		{
+			super(operationState);
+			
+			CONFIG::debug { 
+				var elem:FlowElement = this.targetElement;
+				for (var i:int = nestLevel; i > 0; i--)
+					elem = elem.parent;
+				
+				assert (elem is TextFlow, "ChangeElementIdOperation targetElement root is not a TextFlow!"); 
+				assert (elem == operationState.textFlow, "ChangeElementIdOperation element is not part of selectionState TextFlow"); 
+			}
+			
+			initialize(targetElement,relativeStart,relativeEnd);
+		}
+		
+		
+		private function initialize(targetElement:FlowElement, relativeStart:int, relativeEnd:int ):void
+		{
+			this.targetElement = targetElement;
+			this.relativeEnd = relativeEnd;
+			this.relativeStart = relativeStart;
+			
+			if (relativeEnd == -1)
+				relativeEnd = targetElement.textLength;
+				
+			CONFIG::debug { assert(relativeStart >= 0 && relativeStart <= targetElement.textLength,"ChangeElementIdOperation bad relativeStart"); } 
+			CONFIG::debug { assert(relativeEnd >= 0 && relativeEnd <= targetElement.textLength,"ChangeElementIdOperation bad relativeEnd"); } 
+			CONFIG::debug { assert(relativeStart <= relativeEnd,"ChangeElementIdOperation relativeStart not before relativeEnd"); } 
+
+			// If we're changing the format of the text right before the terminator, change the terminator to match.
+			// This will make it so that when the format change is undone, the terminator will be restored to previous state. Also
+			// prevents unnecessary split & join of spans (split for apply, joined during normalize).
+			if (targetElement is SpanElement && SpanElement(targetElement).hasParagraphTerminator && relativeEnd == targetElement.textLength - 1)
+				relativeEnd += 1;
+				
+			origAbsStart = absStart = targetElement.getAbsoluteStart() + relativeStart;
+			origAbsEnd   = absEnd   = absStart - relativeStart + relativeEnd;
+			
+		}
+		
+		/** 
+		 * Specifies the element this operation modifies.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get targetElement():FlowElement
+		{
+			var element:FlowElement = originalSelectionState.textFlow;
+			for (var i:int = nestLevel; i > 0; i--)
+			{
+				var groupElement:FlowGroupElement = element as FlowGroupElement;
+				element = groupElement.getChildAt(groupElement.findChildIndexAtPosition(absStart - element.getAbsoluteStart()));
+			}
+			return element;
+		}
+		public function set targetElement(value:FlowElement):void
+		{
+			nestLevel = 0;
+			for (var element:FlowElement = value; element.parent != null; element = element.parent)
+				++nestLevel;
+		}
+		
+	
+		/** 
+		 * An offset from the beginning of the <code>targetElement</code>.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get relativeStart():int
+		{
+			return _relStart;
+		}
+		public function set relativeStart(value:int):void
+		{
+			_relStart = value;
+		}
+		
+		/** 
+		 * An offset from the start of the <code>targetElement</code>.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get relativeEnd():int
+		{
+			return _relEnd;
+		}
+		public function set relativeEnd(value:int):void
+		{
+			_relEnd = value;
+		}
+		
+		
+		/** @private */
+		protected function getTargetElement():FlowElement
+		{
+			var element:FlowElement = this.targetElement;
+			
+			var elemStart:int = element.getAbsoluteStart();
+			var splitElement:FlowElement;	// scratch
+			// split at the back and then split at the start - that way paragraph terminators don't get in the way
+			if (absEnd != elemStart + element.textLength)
+			{
+				splitElement = element.splitAtPosition(absEnd - elemStart);
+				if (firstTime && splitElement != element)
+					splitAtEnd = true;
+			}
+				
+			if (absStart != elemStart)
+			{
+				splitElement = element.splitAtPosition(absStart-elemStart);
+				if (splitElement != element)
+				{
+					if (firstTime)
+						splitAtStart = true;
+					element = splitElement;
+				}
+			}
+			
+			firstTime = false;	
+			return element;
+		}
+		
+		
+		/** @private */
+		protected function adjustForDoOperation(targetElement:FlowElement):void
+		{
+			// adjust for undo
+			absStart = targetElement.getAbsoluteStart();
+			absEnd   = absStart + targetElement.textLength;
+		}	
+		
+		/** @private */
+		protected function adjustForUndoOperation(targetElement:FlowElement):void
+		{
+			// need to do manual merging
+			if ((splitAtEnd || splitAtStart) && (targetElement is FlowGroupElement))
+			{
+				var targetIdx:int = targetElement.parent.getChildIndex(targetElement);
+				var workElem:FlowGroupElement;
+				var child:FlowElement;
+				
+				if (splitAtEnd)
+				{
+					// merge next to targetElement
+					workElem = targetElement.parent.getChildAt(targetIdx+1) as FlowGroupElement;
+					while (workElem.numChildren)
+					{
+						child = workElem.getChildAt(0);
+						workElem.removeChildAt(0);
+						FlowGroupElement(targetElement).addChild(child);
+					}
+					targetElement.parent.removeChildAt(targetIdx+1);
+				}
+				if (splitAtStart)
+				{
+					// merge targetElement to prevElement
+					workElem = targetElement.parent.getChildAt(targetIdx-1) as FlowGroupElement;
+					while (FlowGroupElement(targetElement).numChildren)
+					{
+						child = FlowGroupElement(targetElement).getChildAt(0);
+						FlowGroupElement(targetElement).removeChildAt(0);
+						workElem.addChild(child);
+					}
+					targetElement.parent.removeChildAt(targetIdx);
+				}
+			}
+			
+			absStart = origAbsStart;
+			absEnd   = origAbsEnd;
+		}
+	}
+}
\ No newline at end of file
diff --git a/textLayout_edit/src/flashx/textLayout/operations/FlowOperation.as b/textLayout_edit/src/flashx/textLayout/operations/FlowOperation.as
new file mode 100755
index 0000000..06def47
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/FlowOperation.as
@@ -0,0 +1,241 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+
+	//
+	// Considered several ways of doing undo/redo
+	// 1 - object model level - stashing copies of all changed objects in the model and restoring them
+	// 2 - cookies - saving an audit trail of every modified property of the model objects
+	// 3 - operations - each operation creates an object that knows how to do/undo/redo itself
+	// going with # 3 for now
+	//
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.edit.IEditManager;
+	import flashx.undo.IOperation;
+
+	/** 
+	 * The FlowOperation class is the base class for all Text Layout Framework operations. 
+	 * 
+	 * <p>Operations are transformations of a text flow. An Operation class defines the
+	 * logic for performing and undoing the transformation. Operations are executed by an
+	 * edit manager. Most applications do not need to create or manage operations directly
+	 * (unless implementing a custom edit manager).</p>
+	 * 
+	 * <p>When an operation is performed, the edit manager dispatches an Operation object 
+	 * within the FlowOperationEvent object. You can query 
+	 * this Operation object to decide whether or not to allow the operation, to decide whether 
+	 * to perform some other operation as well, or to update related user-interface elements.</p>
+	 * 
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * @see flashx.textLayout.edit.EditManager
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class FlowOperation implements IOperation
+	{
+		/** 
+		 * Arbitrary data associated with an element. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public var userData:*;
+		
+		// uint or null
+		private var _beginGeneration:uint;
+		private var _endGeneration:uint;
+		
+		private var _textFlow:TextFlow;		// target of the operation
+
+		/** 
+		 * Creates the FlowOperation object.
+		 * 
+		 * @param textFlow	The text flow to which this operation is applied.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function FlowOperation(textFlow:TextFlow)
+		{
+			_textFlow = textFlow;
+		}
+		
+		/** 
+		 * The TextFlow object to which this operation is applied.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function get textFlow():TextFlow
+		{ return _textFlow; }
+		public function set textFlow(value:TextFlow):void
+		{ _textFlow = value; }
+		
+		/** 
+		 * Executes the operation. 
+		 * 
+		 * <p>This method must be overridden in derived classes. The base class method does nothing.
+		 * You should not call <code>doOperation()</code> directly. The edit manager 
+		 * calls the method when it executes the operation. </p>
+		 * 
+		 * @return Boolean <code>true</code>, if the operation succeeded. Otherwise, <code>false</code>.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function doOperation():Boolean
+		{
+			return false;
+		}
+		
+		/**	
+		 * Reverses the operation. 
+		 * 
+		 * <p>This method must be overridden in derived classes. The base class method does nothing.
+		 * You should not call <code>undo()</code> directly. The edit manager 
+		 * calls the method when it reverses the operation. </p>
+		 * 
+		 * @return The SelectionState object passed to the operation when it was performed. This
+		 * SelectionState object can be the current selection or a selection created specifically
+		 * for the operation. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function undo():SelectionState
+		{
+			return null;
+		}
+		
+		/**	
+		 * Test if this operation be placed on the undo stack.
+		 * 
+		 * @return true means to push the operation onto the undo stack.  false means do not push this operation.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0 
+		 */
+		public function canUndo():Boolean
+		{ return true; }
+		
+		/**	
+		 * Re-executes the operation. 
+		 * 
+		 * <p>This method must be overridden in derived classes. The base class method does nothing.
+		 * You should not call <code>redo()</code> directly. The edit manager 
+		 * calls the method when it re-executes the operation. </p>
+		 * 
+		 * @return The SelectionState object passed to the operation when it was performed. This
+		 * SelectionState object can be the current selection or a selection created specifically
+		 * for the operation. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function redo():SelectionState
+		{
+			return null;
+		}
+		
+		// Generation numbers
+		
+		/**
+		 * The text flow generation before the operation.
+		 *   
+		 * <p>A generation of 0 indicates that the operation did not complete.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get beginGeneration():uint
+		{ return _beginGeneration; }
+		/** 
+		 * The text flow generation after the operation.
+		 * 
+		 * <p>A generation of 0 indicates that the operation did not complete.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get endGeneration():uint
+		{ return _endGeneration; }
+
+		/** @private */
+		public function performUndo():void
+		{
+			var editManager:IEditManager = textFlow ? textFlow.interactionManager as IEditManager : null;
+			if (editManager != null)
+			{
+				editManager.performUndo(this);
+			}
+		}
+
+		/** @private */
+		public function performRedo():void
+		{
+			var editManager:IEditManager = textFlow ? textFlow.interactionManager as IEditManager : null;
+			if (editManager != null)
+			{
+				editManager.performRedo(this);
+			}
+		}
+		
+		/** @private -- Sets the generation numbers into the operation.  */
+		tlf_internal function setGenerations(beginGeneration:uint,endGeneration:uint):void
+		{
+			_beginGeneration = beginGeneration;
+			_endGeneration   = endGeneration;
+		}
+		
+		/**
+		 * @private
+		 * 
+		 *  Combine this operation with another operation if the result can 
+		 *  be represented as a single operation.  In general, operations cannot be 
+		 *  merged. But sequential inserts or deletes may be mergeable.
+		 * 
+		 *  Merging may occur through updating the properties of the operation
+		 *  on which this method is called, by creating a new operation.
+		 * 
+		 *  @param operation 	The FlowOperation to merge against
+		 *  @return A FlowOperation representing the combined operation if 
+		 *  the merge was successful, null otherwise.
+		 */
+		tlf_internal function merge(operation:FlowOperation):FlowOperation
+		{
+			return null;
+		}
+	}
+}
\ No newline at end of file
diff --git a/textLayout_edit/src/flashx/textLayout/operations/FlowTextOperation.as b/textLayout_edit/src/flashx/textLayout/operations/FlowTextOperation.as
new file mode 100755
index 0000000..665e7ac
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/FlowTextOperation.as
@@ -0,0 +1,125 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+
+	//
+	// Considered several ways of doing undo/redo
+	// 1 - object model level - stashing copies of all changed objects in the model and restoring them
+	// 2 - cookies - saving an audit trail of every modified property of the model objects
+	// 3 - operations - each operation creates an object that knows how to do/undo/redo itself
+	// going with # 3 for now
+	//
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.tlf_internal;
+
+	/** 
+	 * The FlowTextOperation is the base class for operations that transform a range of text.
+	 * 
+	 * @see flashx.textLayout.edit.EditManager
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class FlowTextOperation extends FlowOperation
+	{
+		private var _originalSelectionState:SelectionState;
+		private var _absoluteStart:int;
+		private var _absoluteEnd:int;
+
+		/** 
+		 * Creates the FlowTextOperation object.
+		 * 
+		 * @param operationState Specifies the relevant selection. If relevant to the operation, the 
+		 * <code>operationState</code> describes the text range to which this operation applies.
+		 * Otherwise, <code>operationState</code> is used to save the current selection state so that
+		 * it can be restored when the operation is undone.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function FlowTextOperation(operationState:SelectionState)
+		{
+			super(operationState.textFlow);
+			_absoluteStart = operationState.absoluteStart;
+			_absoluteEnd = operationState.absoluteEnd;
+			_originalSelectionState = operationState;
+		}
+				
+		/** 
+		 * The absolute start point of the range of text to which this operation is applied.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get absoluteStart():int
+		{ return _absoluteStart; }
+		public function set absoluteStart(value:int):void
+		{ _absoluteStart = value; }
+		
+		/** 
+		 * The absolute end point of the range of text to which this operation is applied. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get absoluteEnd():int
+		{ return _absoluteEnd; }
+		public function set absoluteEnd(value:int):void
+		{ _absoluteEnd = value; }
+		
+		/** 
+		 * The selection state at the start of the operation. 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get originalSelectionState():SelectionState
+		{
+			return _originalSelectionState;
+		}
+		public function set originalSelectionState(value:SelectionState):void
+		{
+			_originalSelectionState = value;
+		}
+		
+		/**	
+		 * @inheritDoc
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		override public function redo():SelectionState
+		{
+			doOperation();
+			return _originalSelectionState;
+		}
+		
+	}
+}
\ No newline at end of file
diff --git a/textLayout_edit/src/flashx/textLayout/operations/InsertInlineGraphicOperation.as b/textLayout_edit/src/flashx/textLayout/operations/InsertInlineGraphicOperation.as
new file mode 100755
index 0000000..c560dd9
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/InsertInlineGraphicOperation.as
@@ -0,0 +1,219 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.edit.ElementRange;
+	import flashx.textLayout.edit.ParaEdit;
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.SubParagraphGroupElement;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+
+	
+
+	/**
+	 * The InsertInlineGraphicOperation class encapsulates the insertion of an inline
+	 * graphic into a text flow.
+	 *
+	 * @see flashx.textLayout.elements.InlineGraphicElement
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class InsertInlineGraphicOperation extends FlowTextOperation
+	{
+		private var delSelOp:DeleteTextOperation; 
+		private var _source:Object;
+		private var imageWidth:Object;
+		private var imageHeight:Object;
+		private var _options:Object;
+		private var selPos:int = 0;
+		
+		/** 
+		 * Creates an InsertInlineGraphicsOperation object.
+		 * 
+		 * @param operationState Describes the insertion point. 
+		 * If a range is selected, the operation deletes the contents of that range.
+		 * @param	source	The graphic source (uri string, URLRequest, DisplayObject, or Class of an embedded asset). 
+		 * @param	width	The width to assign (number of pixels, percent, or the string 'auto')
+		 * @param	height	The height to assign (number of pixels, percent, or the string 'auto')
+		 * @param	options	None supported
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		function InsertInlineGraphicOperation(operationState:SelectionState, source:Object, width:Object, height:Object, options:Object = null)
+		{
+			super(operationState);
+			
+			if (absoluteStart != absoluteEnd)
+				delSelOp = new DeleteTextOperation(operationState);
+				
+			_source = source;
+			_options = options;
+			imageWidth = width;
+			imageHeight = height;
+		}
+		
+		/**	
+		 * @copy flashx.textLayout.elements.InlineGraphicElement#source
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+ 		 */
+		public function get source():Object
+		{
+			return _source;
+		}
+		public function set source(value:Object):void
+		{
+			_source = value;
+		}
+
+		/** 
+		 * @copy flashx.textLayout.elements.InlineGraphicElement#width
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public function get width():Object
+		{
+			return imageWidth;
+		}
+		public function set width(value:Object):void
+		{
+			imageWidth = value;
+		}
+
+		/** 
+		 * @copy flashx.textLayout.elements.InlineGraphicElement#height
+		 * 
+		 * @see flashx.textLayout.InlineGraphicElement#height
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get height():Object
+		{
+			return imageHeight;
+		}
+		public function set height(value:Object):void
+		{
+			imageHeight = value;
+		}
+		
+		/** 
+		 * options are not supported
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get options():Object
+		{
+			return _options;
+		}
+		public function set options(value:Object):void
+		{
+			_options = value;
+		}
+
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			var pointFormat:ITextLayoutFormat;
+			
+			selPos = absoluteStart;
+			if (delSelOp) 
+			{
+				var leafEl:FlowLeafElement = textFlow.findLeaf(absoluteStart);
+				var deleteFormat:ITextLayoutFormat = new TextLayoutFormat(textFlow.findLeaf(absoluteStart).format);
+				if (delSelOp.doOperation())
+					pointFormat = deleteFormat;
+			}
+			else
+				pointFormat = originalSelectionState.pointFormat;
+				
+			// lean left logic included
+			var range:ElementRange = ElementRange.createElementRange(textFlow,selPos, selPos);		
+			var leafNode:FlowElement = range.firstLeaf;
+			var leafNodeParent:FlowGroupElement = leafNode.parent;
+			while (leafNodeParent is SubParagraphGroupElement)
+			{
+				var subParInsertionPoint:int = selPos - leafNodeParent.getAbsoluteStart();
+				if (((subParInsertionPoint == 0) && (!(leafNodeParent as SubParagraphGroupElement).acceptTextBefore())) ||
+					((subParInsertionPoint == leafNodeParent.textLength) && (!(leafNodeParent as SubParagraphGroupElement).acceptTextAfter())))
+				{
+					leafNodeParent = leafNodeParent.parent;
+				} else {
+					break;
+				}
+			}
+			
+			ParaEdit.createImage(leafNodeParent, selPos - leafNodeParent.getAbsoluteStart(), _source, imageWidth, imageHeight, options, pointFormat);
+			if (textFlow.interactionManager)
+				textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, 1);
+			
+			return true;
+		}
+	
+		/** @private */
+		public override function undo():SelectionState
+		{
+			var leafNode:FlowElement = textFlow.findLeaf(selPos);
+			var leafNodeParent:FlowGroupElement = leafNode.parent;
+			var elementIdx:int = leafNode.parent.getChildIndex(leafNode);
+			leafNodeParent.replaceChildren(elementIdx, elementIdx + 1, null);			
+					
+			if (textFlow.interactionManager)
+				textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, -1);
+
+			return delSelOp ? delSelOp.undo() : originalSelectionState; 
+		}
+
+		/**
+		 * Re-executes the operation after it has been undone.
+		 * 
+		 * <p>This function is called by the edit manager, when necessary.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public override function redo():SelectionState
+		{ 
+			doOperation();
+			return new SelectionState(textFlow,selPos+1,selPos+1,null);
+		}
+
+	}
+}
diff --git a/textLayout_edit/src/flashx/textLayout/operations/InsertTextOperation.as b/textLayout_edit/src/flashx/textLayout/operations/InsertTextOperation.as
new file mode 100755
index 0000000..ecaef8d
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/InsertTextOperation.as
@@ -0,0 +1,306 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.edit.ElementRange;
+	import flashx.textLayout.edit.ParaEdit;
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.InlineGraphicElement;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.SpanElement;
+	import flashx.textLayout.elements.TCYElement;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+
+
+	/**
+	 * The InsertTextOperation class encapsulates a text insertion operation.
+	 *
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class InsertTextOperation extends FlowTextOperation
+	{
+		private var _deleteSelectionState:SelectionState;
+		private var delSelOp:DeleteTextOperation = null; 
+		/** @private - this should be private but too late for code changes on Labs */
+		public var _text:String;
+		private var adjustedForInsert:Boolean = false;
+		
+		private var _characterFormat:ITextLayoutFormat;
+			
+		/** 
+		 * Creates an InsertTextOperation object.
+		 * 
+		 * @param operationState Describes the insertion point or range of text.
+		 * @param text The string to insert.
+		 * @param deleteSelectionState Describes the range of text to delete before doing insertion, 
+		 * if different than the range described by <code>operationState</code>.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */	
+		public function InsertTextOperation(operationState:SelectionState, text:String, deleteSelectionState:SelectionState = null)
+		{
+			super(operationState);
+			
+			_characterFormat = operationState.pointFormat;
+			_text = text;
+			
+			initialize(deleteSelectionState);
+		}
+		
+		private function initialize(deleteSelectionState:SelectionState):void
+		{	
+			if (deleteSelectionState == null)
+				deleteSelectionState = originalSelectionState;
+			if (deleteSelectionState.anchorPosition != deleteSelectionState.activePosition)
+			{
+				_deleteSelectionState = deleteSelectionState;
+				delSelOp = new DeleteTextOperation(_deleteSelectionState);
+			}
+		}
+		
+		/** 
+		 * The text inserted by this operation. 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get text():String
+		{
+			return _text;
+		}
+		public function set text(value:String):void
+		{
+			_text = value;
+		}
+		
+		/** 
+		 * The text deleted by this operation, if any.
+		 * 
+		 * <p><code>null</code> if no text is deleted.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get deleteSelectionState():SelectionState
+		{
+			return _deleteSelectionState;
+		}
+		public function set deleteSelectionState(value:SelectionState):void
+		{
+			_deleteSelectionState = value;
+		}
+		
+		/** 
+		 * The character format applied to the inserted text.
+		 *  
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get characterFormat():ITextLayoutFormat
+		{
+			return _characterFormat;
+		}
+		public function set characterFormat(value:ITextLayoutFormat):void
+		{
+			_characterFormat = new TextLayoutFormat(value);
+		}
+		
+		private function doInternal():void
+		{
+			var leafEl:FlowLeafElement = textFlow.findLeaf(absoluteStart);
+			var tcyEl:TCYElement = null;
+			
+			if(leafEl is InlineGraphicElement && leafEl.parent is TCYElement)
+			{
+				tcyEl = leafEl.parent as TCYElement;
+			}
+			
+			if (delSelOp != null) {	
+				var deleteFormat:ITextLayoutFormat = new TextLayoutFormat(textFlow.findLeaf(absoluteStart).format);
+				if (delSelOp.doOperation())		// figure out what to do here
+				{
+					//do not change characterFormat if user specified one already
+					if ((characterFormat == null) && (absoluteStart < absoluteEnd))
+					{
+						_characterFormat = deleteFormat;
+					} 
+					else 
+					{
+						if (leafEl.textLength == 0) 
+						{
+							var pos:int = leafEl.parent.getChildIndex(leafEl);
+							leafEl.parent.replaceChildren(pos, pos + 1, null);
+						}
+					}
+					
+					if(tcyEl && tcyEl.numChildren == 0)
+					{
+						leafEl = new SpanElement();
+						tcyEl.replaceChildren(0,0,leafEl);
+					}
+				} 
+			} 
+			
+			// Wasteful, but it gives us the leanLeft logic for insert - which we only want to do if this is a point selection.
+			
+			var range:ElementRange;
+			var useExistingLeaf:Boolean = false;
+			// favor using leaf we have if it's valid (i.e., it has a paragraph in its parent chain and it is still inside a TextFlow)
+			if (absoluteStart >= absoluteEnd || leafEl.getParagraph() == null || leafEl.getTextFlow() == null)
+			{
+				range = ElementRange.createElementRange(textFlow,absoluteStart, absoluteStart);
+			}
+			else
+			{
+				range = new ElementRange();
+				range.firstParagraph = leafEl.getParagraph();
+				range.firstLeaf = leafEl;
+				useExistingLeaf = true;
+			}
+			var paraSelBegIdx:int = absoluteStart-range.firstParagraph.getAbsoluteStart();
+			
+			// force insert to use the leaf given if we have a good one
+			ParaEdit.insertText(range.firstParagraph, range.firstLeaf, paraSelBegIdx, _text, useExistingLeaf);
+			if (textFlow.interactionManager)
+				textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, _text.length);
+			
+			if (_characterFormat && !TextLayoutFormat.isEqual(_characterFormat, range.firstLeaf.format))
+				ParaEdit.applyTextStyleChange(textFlow,absoluteStart,absoluteStart+_text.length,_characterFormat,null);
+		}
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			doInternal();
+			if (originalSelectionState.selectionManagerOperationState && textFlow.interactionManager)
+			{
+				var state:SelectionState = textFlow.interactionManager.getSelectionState();
+				if (state.pointFormat)
+				{
+					state.pointFormat = null;
+					textFlow.interactionManager.setSelectionState(state);
+				}
+			}
+			return true;
+		}
+	
+		/** @private */
+		public override function undo():SelectionState
+		{ 
+			var para:ParagraphElement = textFlow.findAbsoluteParagraph(absoluteStart);
+			// paragraph relative offset - into the store
+			var paraSelBegIdx:int = absoluteStart-para.getAbsoluteStart();
+
+			ParaEdit.deleteText(para, paraSelBegIdx, _text.length);
+			if (textFlow.interactionManager)
+				textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, -_text.length);
+			
+			var newSelectionState:SelectionState = originalSelectionState;
+			if (delSelOp != null)
+			{
+				newSelectionState = delSelOp.undo();
+			}
+			
+			if (adjustedForInsert)
+			{
+				var newBegIdx:int = newSelectionState.anchorPosition;
+				var newEndIdx:int = newSelectionState.activePosition;
+				if (newEndIdx > newBegIdx) newEndIdx--;
+				else newBegIdx--;
+				
+				if (absoluteStart < absoluteEnd)
+				{
+					return new SelectionState(textFlow, newBegIdx, newEndIdx, newSelectionState.pointFormat);
+				}
+				else
+				{
+					return new SelectionState(textFlow, newBegIdx, newEndIdx, originalSelectionState.pointFormat);
+				}
+			}
+			return originalSelectionState;
+		}
+		
+		/**
+		 * Re-executes the operation after it has been undone.
+		 * 
+		 * <p>This function is called by the edit manager, when necessary.</p>
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		public override function redo():SelectionState
+		{ 
+			doInternal();
+			return new SelectionState(textFlow,absoluteStart+_text.length,absoluteStart+_text.length,null);
+		}
+
+		/** @private */
+		tlf_internal override function merge(op2:FlowOperation):FlowOperation
+		{
+			if (absoluteStart < absoluteEnd)
+				return null;
+			if (this.endGeneration != op2.beginGeneration)
+				return null;
+			// We are assuming here that these operations are contiguous, because
+			// SelectionManager doesn't try to merge operations if the selection
+			// has changed
+			var insertOp:InsertTextOperation = null;
+			if (op2 is InsertTextOperation)
+				insertOp = op2 as InsertTextOperation;
+			if (insertOp)
+			{
+				if (insertOp.deleteSelectionState != null || deleteSelectionState != null)
+					return null;
+				if ((insertOp.originalSelectionState.pointFormat == null) && (originalSelectionState.pointFormat != null))
+					return null;
+				if ((originalSelectionState.pointFormat == null) && (insertOp.originalSelectionState.pointFormat != null))
+					return null;
+				if (originalSelectionState.absoluteStart + _text.length != insertOp.originalSelectionState.absoluteStart)
+					return null;
+				if (((originalSelectionState.pointFormat == null) && (insertOp.originalSelectionState.pointFormat == null)) ||
+					(TextLayoutFormat.isEqual(originalSelectionState.pointFormat, insertOp.originalSelectionState.pointFormat)))
+					_text += insertOp.text;
+				else
+					return null;
+				setGenerations(beginGeneration,insertOp.endGeneration);
+				return this;
+			}
+			
+			if (op2 is SplitParagraphOperation)
+				return new CompositeOperation([this,op2]);
+
+			return null;
+		}
+	}
+}
\ No newline at end of file
diff --git a/textLayout_edit/src/flashx/textLayout/operations/ModifyInlineGraphicOperation.as b/textLayout_edit/src/flashx/textLayout/operations/ModifyInlineGraphicOperation.as
new file mode 100755
index 0000000..9537853
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/ModifyInlineGraphicOperation.as
@@ -0,0 +1,171 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.InlineGraphicElement;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+
+
+	/**
+	 * The InsertInlineGraphicOperation class encapsulates the modification of an existing inline graphic.
+	 *
+	 * @see flashx.textLayout.elements.InlineGraphicElement
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */
+	public class ModifyInlineGraphicOperation extends FlowTextOperation
+	{ 
+		private var _source:Object;
+		private var imageWidth:Object;
+		private var imageHeight:Object;
+		private var _options:Object;
+		private var oldImage:FlowElement;
+		private var selPos:int = 0;
+		
+		/** 
+		 * Creates a ModifyInlineGraphicsOperation object.
+		 * 
+		 * @param operationState Describes the insertion point. 
+		 * If a range is selected, the operation deletes the contents of that range.
+		 * @param	source	The graphic source (uri string, URLRequest, DisplayObject, or Class of an embedded asset). 
+		 * @param	width	The width to assign (number of pixels, percent, or the string 'auto')
+		 * @param	height	The height to assign (number of pixels, percent, or the string 'auto')
+		 * @param	options	None supported
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		function ModifyInlineGraphicOperation(operationState:SelectionState, source:Object, width:Object, height:Object, options:Object = null)
+		{
+			super(operationState);
+							
+			_source = source;
+			_options = options;
+			imageWidth = width;
+			imageHeight = height;
+		}
+		
+		/**	
+		 * @copy flashx.textLayout.elements.InlineGraphicElement#source
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+ 		 */
+		public function get source():Object
+		{
+			return _source;
+		}
+		public function set source(value:Object):void
+		{
+			_source = value;
+		}
+
+		/** 
+		 * @copy flashx.textLayout.elements.InlineGraphicElement#width
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get width():Object
+		{
+			return imageWidth;
+		}
+		public function set width(value:Object):void
+		{
+			imageWidth = value;
+		}
+
+		/** 
+		 * @copy flashx.textLayout.elements.InlineGraphicElement#height
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get height():Object
+		{
+			return imageHeight;
+		}
+		public function set height(value:Object):void
+		{
+			imageHeight = value;
+		}
+		
+		/** 
+		 * options are not supported
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		*/
+		public function get options():Object
+		{
+			return _options;
+		}
+		public function set options(value:Object):void
+		{
+			_options = value;
+		}
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			selPos = absoluteStart;
+			var img:InlineGraphicElement = textFlow.findLeaf(selPos) as InlineGraphicElement;
+			if (img)
+			{
+				oldImage = img.shallowCopy(0,1);
+				// only update changed things
+				if (img.width != imageWidth)
+					img.width = imageWidth;
+				if (img.height != imageHeight)
+					img.height = imageHeight;
+				if (img.source != _source)
+					img.source = _source;
+				if (options && img.float != options.toString())
+					img.float = options.toString();
+			}
+			
+			return true;	
+		}
+	
+		/** @private */
+		public override function undo():SelectionState
+		{
+			var leafNode:FlowElement = textFlow.findLeaf(selPos);
+			var leafNodeParent:FlowGroupElement = leafNode.parent;
+			var elementIdx:int = leafNode.parent.getChildIndex(leafNode);
+			leafNodeParent.replaceChildren(elementIdx, elementIdx + 1, oldImage);			
+
+			return originalSelectionState; 
+		}
+	}
+}
\ No newline at end of file
diff --git a/textLayout_edit/src/flashx/textLayout/operations/PasteOperation.as b/textLayout_edit/src/flashx/textLayout/operations/PasteOperation.as
new file mode 100755
index 0000000..0554f6f
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/PasteOperation.as
@@ -0,0 +1,128 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.edit.TextFlowEdit;
+	import flashx.textLayout.edit.TextScrap;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.tlf_internal;
+
+
+	use namespace tlf_internal;
+
+
+	/**
+	 * 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 flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */			
+	public class PasteOperation extends FlowTextOperation
+	{
+		private var _textScrap:TextScrap;
+		private var _tScrapUnderSelection:TextScrap;
+		private var _numCharsAdded:int = 0;
+		
+		/** 
+		 * 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)
+		{
+			super(operationState);
+			_textScrap = textScrap;
+		}
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{
+			if (_textScrap != null)
+			{
+				_tScrapUnderSelection = TextFlowEdit.createTextScrap(originalSelectionState.textFlow, originalSelectionState.absoluteStart, originalSelectionState.absoluteEnd);
+				internalDoOperation();
+			}
+			return true;	
+		}
+		
+		private function internalDoOperation():void
+		{
+			if (absoluteStart != absoluteEnd)	
+			{
+				TextFlowEdit.replaceRange(textFlow, absoluteStart, absoluteEnd, null);
+				if (textFlow.interactionManager)
+					textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, absoluteStart - absoluteEnd);
+			}
+			
+			var nextInsertPosition:int = TextFlowEdit.replaceRange(textFlow, absoluteStart, absoluteStart, _textScrap);
+			if (textFlow.interactionManager)
+				textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, nextInsertPosition - absoluteStart);				
+			_numCharsAdded = (nextInsertPosition - absoluteStart) /*- (absoluteEnd - absoluteStart) */;
+		}
+		
+		/** @private */
+		public override function undo():SelectionState
+		{
+			if (_textScrap != null)
+			{
+				TextFlowEdit.replaceRange(textFlow, absoluteStart, absoluteStart + _numCharsAdded, _tScrapUnderSelection);
+				if (textFlow.interactionManager)
+					textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, -_numCharsAdded);
+			}
+			return originalSelectionState;	
+		}
+	
+		/** @private */
+		public override function redo():SelectionState
+		{
+			if (_textScrap != null)
+				internalDoOperation();								
+			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; }		
+	}
+}
diff --git a/textLayout_edit/src/flashx/textLayout/operations/RedoOperation.as b/textLayout_edit/src/flashx/textLayout/operations/RedoOperation.as
new file mode 100755
index 0000000..3fbb8c3
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/RedoOperation.as
@@ -0,0 +1,74 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+
+	/** 
+	 * The RedoOperation class encapsulates a redo operation.
+	 *
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @includeExample examples\RedoOperation_example.as -noswf
+	 * 
+	 * @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;
+		}
+	}
+}
diff --git a/textLayout_edit/src/flashx/textLayout/operations/SplitParagraphOperation.as b/textLayout_edit/src/flashx/textLayout/operations/SplitParagraphOperation.as
new file mode 100755
index 0000000..346e0b7
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/SplitParagraphOperation.as
@@ -0,0 +1,177 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.operations
+{
+	import flash.utils.getQualifiedClassName;
+	
+	import flashx.textLayout.edit.ParaEdit;
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.SpanElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.formats.TextLayoutFormat;
+	import flashx.textLayout.formats.ITextLayoutFormat;
+	import flashx.textLayout.tlf_internal;
+
+
+	use namespace tlf_internal;
+
+
+	/**
+	 * 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 flashx.textLayout.elements.ParagraphElement
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0 
+	 */			
+	public class SplitParagraphOperation extends FlowTextOperation
+	{
+		private var delSelOp:DeleteTextOperation;
+		private var _characterFormat:ITextLayoutFormat;
+		
+		/** 
+		 * 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 
+		 */
+		function SplitParagraphOperation(operationState:SelectionState)
+		{
+			super(operationState);
+			characterFormat = operationState.pointFormat;
+		}
+		
+		/** 
+		 * The format applied to the new empty paragraph when a paragraph is split at the end.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0 
+		 */
+		private function get characterFormat():ITextLayoutFormat
+		{
+			return _characterFormat;
+		}
+		private function set characterFormat(value:ITextLayoutFormat):void
+		{
+			_characterFormat = value ? new TextLayoutFormat(value) : null;
+		}
+		
+		/** @private */
+		public override function doOperation():Boolean
+		{ 
+			if (absoluteStart < absoluteEnd)
+			{
+				delSelOp = new DeleteTextOperation(originalSelectionState);
+				delSelOp.doOperation();
+			}
+			
+			var para:ParagraphElement = textFlow.findAbsoluteParagraph(absoluteStart);
+			
+			// paragraph relative offset - into the store
+			var paraSelBegIdx:int = absoluteStart-para.getAbsoluteStart();
+			
+			var nextPara:ParagraphElement = ParaEdit.splitParagraph(para, paraSelBegIdx, _characterFormat);
+			if (textFlow.interactionManager)
+				textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, 1);
+
+			// splitParagraph guarantees these exist
+			var lastParaLeaf:FlowLeafElement = para.getLastLeaf(); 
+			if (lastParaLeaf != null && lastParaLeaf.textLength == 1)
+			{
+				//if the lastParaLeaf is only a newline, you really want the span right before
+				var elementIdx:int = lastParaLeaf.parent.getChildIndex(lastParaLeaf);
+				if (elementIdx > 0)
+				{
+					var prevSpan:SpanElement = lastParaLeaf.parent.getChildAt(elementIdx - 1) as SpanElement;
+					if (prevSpan != null) lastParaLeaf = prevSpan;
+				}
+			}
+			
+			var firstNextParaLeaf:FlowLeafElement = nextPara.getFirstLeaf();
+			
+			var newCharAttrs:TextLayoutFormat; // Point format for new selection position
+			if (getQualifiedClassName(lastParaLeaf.parent) != getQualifiedClassName(firstNextParaLeaf.parent))
+			{
+				// Reset it; no easy way to migrate point format when parent types differ
+				newCharAttrs = new TextLayoutFormat();
+			} 
+			else
+			{
+				// 1. Convert to absolute (position-independent) value by concatenating with the actual attribute of para's last leaf
+				newCharAttrs = new TextLayoutFormat(_characterFormat);
+				
+				if (nextPara.textLength == 1)
+				{
+					//we have a completely new paragraph.  Just append on the character
+					//attributes of the last leaf and stop.
+					if (lastParaLeaf.format != null)
+					{
+						newCharAttrs.concat(lastParaLeaf.format);
+					}
+				}
+				else
+				{
+					newCharAttrs.concat(lastParaLeaf.computedFormat);
+					
+					// 2. Convert to a relative value (dependent on the new position) by removing attributes 
+					// that match the actual  attributes of nextPar's first leaf 
+					newCharAttrs.removeMatching(firstNextParaLeaf.computedFormat);
+				}
+			}		
+
+			return true;
+		}
+	
+		/** @private */
+		public override function undo():SelectionState
+		{ 
+			var para:ParagraphElement = textFlow.findAbsoluteParagraph(absoluteStart);
+			ParaEdit.mergeParagraphWithNext(para);
+			if (textFlow.interactionManager)
+				textFlow.interactionManager.notifyInsertOrDelete(absoluteStart, -1);
+			
+			return absoluteStart < absoluteEnd ? delSelOp.undo() : originalSelectionState;
+		}
+		
+		/** @private */
+		tlf_internal 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
diff --git a/textLayout_edit/src/flashx/textLayout/operations/UndoOperation.as b/textLayout_edit/src/flashx/textLayout/operations/UndoOperation.as
new file mode 100755
index 0000000..623b6ac
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/operations/UndoOperation.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 flashx.textLayout.operations
+{
+	import flashx.textLayout.edit.SelectionState;
+	import flashx.textLayout.tlf_internal;
+
+	use namespace tlf_internal;
+
+	/** 
+	 * The UndoOperation class encapsulates an undo operation.
+	 *
+	 * @see flashx.textLayout.edit.EditManager
+	 * @see flashx.textLayout.events.FlowOperationEvent
+	 * 
+	 * @includeExample examples\UndoOperation_example.as -noswf
+	 * 
+	 * @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;
+		}
+	}
+}
diff --git a/textLayout_edit/src/flashx/textLayout/utils/NavigationUtil.as b/textLayout_edit/src/flashx/textLayout/utils/NavigationUtil.as
new file mode 100755
index 0000000..faf5770
--- /dev/null
+++ b/textLayout_edit/src/flashx/textLayout/utils/NavigationUtil.as
@@ -0,0 +1,1220 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.utils
+{
+	import flash.geom.Point;
+	import flash.geom.Rectangle;
+	import flash.text.engine.TextLine;
+	import flash.text.engine.TextRotation;
+	
+	import flashx.textLayout.compose.IFlowComposer;
+	import flashx.textLayout.compose.TextFlowLine;
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.container.ScrollPolicy;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.elements.TextRange;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.formats.Direction;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+	
+
+	/** 
+	 * Utilities for manipulating a TextRange 
+	 * The methods of this class are static and must be called using
+	 * the syntax <code>NavigationUtil.method(<em>parameter</em>)</code>.
+	 *
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+	 * @langversion 3.0
+	 */
+	public final class NavigationUtil 
+	{
+		private static function validateTextRange(range:TextRange):Boolean
+		{ return range.textFlow != null && range.anchorPosition != -1 && range.activePosition != -1; }
+		
+		private static function doIncrement(flowRoot:TextFlow, pos:int, incrementer:Function):int
+		{
+			var para:ParagraphElement = flowRoot.findAbsoluteParagraph(pos);
+			return incrementer(flowRoot, para, pos, para.getAbsoluteStart());			
+		}
+		
+		private static function previousAtomHelper(flowRoot:TextFlow, para:ParagraphElement, pos:int, paraStart:int):int
+		{
+			if (pos - paraStart == 0)
+				return (pos > 0) ? pos - 1 : 0;
+			return para.findPreviousAtomBoundary(pos - paraStart) + paraStart;
+		}
+		
+		/** 
+		 * Returns the absolute position of the previous atom. 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public static function previousAtomPosition(flowRoot:TextFlow, absolutePos:int):int
+		{
+			return doIncrement(flowRoot,absolutePos,previousAtomHelper);
+		}
+	
+		private static function nextAtomHelper(flowRoot:TextFlow, para:ParagraphElement, pos:int, paraStart:int):int
+		{
+			if (pos - paraStart == para.textLength - 1)
+				return Math.min(flowRoot.textLength - 1, pos + 1);
+			return para.findNextAtomBoundary(pos - paraStart) + paraStart;
+		}
+		
+		/** 
+		 * Returns the absolute position of the next atom.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public static function nextAtomPosition(flowRoot:TextFlow, absolutePos:int):int
+		{
+			return doIncrement(flowRoot,absolutePos,nextAtomHelper);
+		}
+	
+		/** 
+		 * Returns absolute position of the beginning of the previous word.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public static function previousWordPosition(flowRoot:TextFlow, absolutePos:int):int
+		{
+			if (isOverset(flowRoot, absolutePos))
+				return endOfLastController(flowRoot);
+			
+			var para:ParagraphElement = flowRoot.findAbsoluteParagraph(absolutePos);
+			var paraStart:int = para.getAbsoluteStart();
+			
+			var prevWordPos:int = absolutePos - paraStart;
+			var nextWordPos:int = 0;
+			if (absolutePos - paraStart == 0)
+				return (absolutePos > 0) ? absolutePos - 1 : 0;
+			do
+			{
+				nextWordPos = para.findPreviousWordBoundary(prevWordPos);
+				if (prevWordPos == nextWordPos) prevWordPos = para.findPreviousWordBoundary(prevWordPos - 1);
+				else prevWordPos = nextWordPos;
+			} while (prevWordPos > 0 && CharacterUtil.isWhitespace(para.getCharCodeAtPosition(prevWordPos)));
+			return prevWordPos + paraStart;
+		}
+	
+		/** 
+		 * Returns the absolute position of the beginning of the next word.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		public static function nextWordPosition(flowRoot:TextFlow, absolutePos:int):int
+		{
+			var para:ParagraphElement = flowRoot.findAbsoluteParagraph(absolutePos);
+			var paraStart:int = para.getAbsoluteStart();
+			
+			var nextWordPos:int = absolutePos - paraStart;
+			
+			if (absolutePos - paraStart == para.textLength - 1)
+				return Math.min(flowRoot.textLength - 1, absolutePos + 1);
+			do
+			{
+				nextWordPos = para.findNextWordBoundary(nextWordPos);
+			} while (nextWordPos < (para.textLength - 1) && CharacterUtil.isWhitespace(para.getCharCodeAtPosition(nextWordPos)))
+			return nextWordPos + paraStart;
+		}
+		
+		/** @private */
+		static tlf_internal function updateStartIfInReadOnlyElement(textFlow:TextFlow, idx:int):int
+		{
+			return idx;
+		}
+		
+		/** @private */
+		static tlf_internal function updateEndIfInReadOnlyElement(textFlow:TextFlow, idx:int):int
+		{
+			return idx; 
+		}
+		
+		static private function moveForwardHelper(range:TextRange, extendSelection:Boolean, incrementor:Function):Boolean
+		{
+			var textFlow:TextFlow = range.textFlow;
+			var begIdx:int = range.anchorPosition;
+			var endIdx:int = range.activePosition;
+				
+			if (extendSelection) 
+				endIdx = incrementor(textFlow, endIdx);
+			else {
+				if (begIdx == endIdx) //no selection, just move insertion point
+				{
+					begIdx = incrementor(textFlow, begIdx);
+					endIdx = begIdx;
+				}
+				else if (endIdx > begIdx) //change selection to insertion point
+					begIdx = endIdx;
+				else
+					endIdx = begIdx;
+			}
+			
+			if (begIdx == endIdx)
+			{
+				begIdx = updateStartIfInReadOnlyElement(textFlow, begIdx);
+				endIdx = updateEndIfInReadOnlyElement(textFlow, endIdx);
+			} else {
+				endIdx = updateEndIfInReadOnlyElement(textFlow, endIdx);
+			} 
+					
+			if (!extendSelection && (range.anchorPosition == begIdx) && (range.activePosition == endIdx))
+			{
+				if (begIdx < endIdx)
+				{
+					begIdx = Math.min(endIdx + 1, textFlow.textLength - 1);
+					endIdx = begIdx;
+				}else {
+					endIdx = Math.min(begIdx + 1, textFlow.textLength - 1);
+					begIdx = endIdx;
+				}	
+			}
+			return range.updateRange(begIdx,endIdx);							 	
+		}
+		
+		static private function moveBackwardHelper(range:TextRange, extendSelection:Boolean, incrementor:Function):Boolean
+		{
+			var textFlow:TextFlow = range.textFlow;
+			var begIdx:int = range.anchorPosition;
+			var endIdx:int = range.activePosition;
+				
+			if (extendSelection)	//shift key is pressed 
+				endIdx = incrementor(textFlow, endIdx);
+			else {
+				if (begIdx == endIdx) //no selection, just move insertion point
+				{
+					begIdx = incrementor(textFlow, begIdx);
+					endIdx = begIdx;
+				}
+				else if (endIdx > begIdx) //change selection to insertion point
+					endIdx = begIdx;
+				else
+					begIdx = endIdx;
+			}
+					
+			if (begIdx == endIdx)
+			{
+				begIdx = updateEndIfInReadOnlyElement(textFlow, begIdx);
+				endIdx = updateStartIfInReadOnlyElement(textFlow, endIdx);
+			} else {
+				endIdx = updateStartIfInReadOnlyElement(textFlow, endIdx);
+			} 
+					
+			if (!extendSelection && (range.anchorPosition == begIdx) && (range.activePosition == endIdx))
+			{
+				if (begIdx < endIdx)
+				{
+					endIdx = Math.max(begIdx - 1, 0);
+					begIdx = endIdx;
+				}else {
+					begIdx = Math.max(endIdx - 1, 0);
+					endIdx = begIdx;
+				}	
+			}
+			return range.updateRange(begIdx,endIdx);
+		 }
+		
+		/**
+		 * Sets the TextRange forward by one character.
+		 * @param extendSelection	Indicates that only activeIndex should move
+		 * @return true if selection changed.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */		 
+		static public function nextCharacter(range:TextRange, extendSelection:Boolean = false):Boolean
+		{
+			if (validateTextRange(range))
+			{
+				if (!adjustForOversetForward(range))
+					moveForwardHelper(range, extendSelection, nextAtomPosition);
+				return true;
+			}
+		 	return false;
+		}
+		 
+		/**
+		 * Sets the TextRange backward by one character.
+		 * @param extendSelection	Indicates that only activeIndex should move
+		 * @return true if selection changed.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */		 		 
+		static public function previousCharacter(range:TextRange, extendSelection:Boolean = false):Boolean
+		{
+			if (validateTextRange(range))
+			{
+				if (!adjustForOversetBack(range))
+					moveBackwardHelper(range, extendSelection, previousAtomPosition);
+				return true;
+			} 
+			return false;
+		} 
+		/**
+		 * Sets the TextRange forward by one word.
+		 * @param extendSelection	Indicates that only activeIndex should move
+		 * @return true if selection changed.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */		 		 		 
+		static public function nextWord(range:TextRange, extendSelection:Boolean = false):Boolean
+		{
+			if (validateTextRange(range))
+			{
+				if (!adjustForOversetForward(range))
+					moveForwardHelper(range, extendSelection, nextWordPosition);
+				return true;
+			}
+			return false;
+		}
+		 
+		/**
+		 * Sets the TextRange backward by one word.
+		 * @param extendSelection	Indicates that only activeIndex should move
+		 * @return true if selection changed.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */		 		 		 		 
+		static public function previousWord(range:TextRange, extendSelection:Boolean = false):Boolean
+		{
+			if (validateTextRange(range))
+			{
+				if (!adjustForOversetBack(range))
+		 			moveBackwardHelper(range, extendSelection, previousWordPosition);
+		 		return true;
+		 	}
+		 	return false;
+		} 
+		/**
+		 * Sets the TextRange down one line
+		 * @param extendSelection	Indicates that only activeIndex should move
+		 * @return true if selection changed.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */		 		 		 		 		 
+		static public function nextLine(range:TextRange, extendSelection:Boolean = false):Boolean
+		{
+			if (!validateTextRange(range))
+				return false;
+		
+			if (adjustForOversetForward(range))
+				return true;
+				
+			var textFlow:TextFlow = range.textFlow;
+			var begIdx:int = range.anchorPosition;
+			var endIdx:int = range.activePosition;
+			var limitIdx:int = endOfLastController(textFlow);
+			
+			var curLine:int = textFlow.flowComposer.findLineIndexAtPosition(endIdx);
+			var isRTLDirection:Boolean = (textFlow.computedFormat.direction == Direction.RTL);			
+
+			if (curLine < textFlow.flowComposer.numLines-1)	//create, expand or shrink the selection
+			{
+				var curTextFlowLine:TextFlowLine = textFlow.flowComposer.getLineAt(curLine);
+				var lineStart:int = curTextFlowLine.absoluteStart;
+				var lineDelta:int = endIdx - lineStart;
+				var currentTextLine:TextLine = curTextFlowLine.getTextLine(true);
+				var para:ParagraphElement = curTextFlowLine.paragraph;
+				var atomIndex:int = currentTextLine.getAtomIndexAtCharIndex(endIdx - para.getAbsoluteStart());
+				var bidiRightToLeft:Boolean = ((currentTextLine.getAtomBidiLevel(atomIndex) % 2) != 0); 
+				var curPosRect:Rectangle = currentTextLine.getAtomBounds(atomIndex);
+				var currentTextLineX:Number = currentTextLine.x;
+				var curPosRectLeft:Number = curPosRect.left;
+				var curPosRectRight:Number = curPosRect.right;
+				if(textFlow.computedFormat.blockProgression == BlockProgression.RL)
+				{
+					currentTextLineX = currentTextLine.y;
+					curPosRectLeft = curPosRect.top;
+					curPosRectRight = curPosRect.bottom;
+				}
+				
+				//find the atom
+				var globalPoint:Point = new Point();				
+						
+				if(textFlow.computedFormat.blockProgression != BlockProgression.RL)
+				{
+					if (!isRTLDirection)
+						globalPoint.x = curPosRect.left;
+					else
+						globalPoint.x = curPosRect.right;
+					globalPoint.y = 0;
+				} else {						
+					globalPoint.x = 0;
+					if (!isRTLDirection)
+						globalPoint.y = curPosRect.top;
+					else
+						globalPoint.y = curPosRect.bottom;
+				}
+				
+				globalPoint = currentTextLine.localToGlobal(globalPoint);
+				
+				//at this point, we have the global point of our current position.  Now adjust x or y to the
+				//baseline of the next line.
+				var nextFlowLine:TextFlowLine = textFlow.flowComposer.getLineAt(curLine + 1);
+				if (nextFlowLine.absoluteStart >= limitIdx)
+				{
+					if (!extendSelection)
+						range.anchorPosition = textFlow.textLength-1;
+					range.activePosition = textFlow.textLength-1;
+					return true;
+				}
+				
+				
+				// get the last container so that we can make sure the previous line is in view.
+				var controller:ContainerController = textFlow.flowComposer.getControllerAt(textFlow.flowComposer.numControllers-1);
+				var firstPosInContainer:int = controller.absoluteStart;
+				var lastPosInContainer:int = firstPosInContainer + controller.textLength;
+				if ((nextFlowLine.absoluteStart >= firstPosInContainer) && (nextFlowLine.absoluteStart < lastPosInContainer))
+				{
+					if (nextFlowLine.isDamaged())
+					{
+						textFlow.flowComposer.composeToPosition(nextFlowLine.absoluteStart+1);
+						nextFlowLine = textFlow.flowComposer.getLineAt(curLine + 1);
+					}
+					controller.scrollToRange(nextFlowLine.absoluteStart, nextFlowLine.absoluteStart + nextFlowLine.textLength - 1);
+				}
+				
+				var nextTextLine:TextLine = nextFlowLine.getTextLine(true);
+				if (nextFlowLine.controller == curTextFlowLine.controller)
+				{				
+					if(textFlow.computedFormat.blockProgression != BlockProgression.RL)
+					{
+						globalPoint.y += (nextFlowLine.y - curTextFlowLine.y);
+					} else {
+						globalPoint.x -= (curTextFlowLine.x - nextFlowLine.x);
+					}
+				} else {
+					var firstAtomRect:Rectangle = nextTextLine.getAtomBounds(0);
+					var firstAtomPoint:Point = new Point();
+					firstAtomPoint.x = firstAtomRect.left;
+					firstAtomPoint.y = 0;
+					firstAtomPoint = nextTextLine.localToGlobal(firstAtomPoint);
+					if(textFlow.computedFormat.blockProgression != BlockProgression.RL)
+					{
+						globalPoint.x += nextFlowLine.controller.container.x;
+						globalPoint.y = firstAtomPoint.y;
+					} else {
+						globalPoint.x = firstAtomPoint.x;
+						globalPoint.y += nextFlowLine.controller.container.y; 
+					}					
+				} 
+				
+				atomIndex = nextTextLine.getAtomIndexAtPoint(globalPoint.x,globalPoint.y);
+				if (atomIndex == -1)
+				{
+					if(textFlow.computedFormat.blockProgression != BlockProgression.RL) {
+						if (!bidiRightToLeft) {
+							endIdx = (globalPoint.x <= nextTextLine.x) ? nextFlowLine.absoluteStart : (nextFlowLine.absoluteStart + nextFlowLine.textLength - 1);
+						} else {
+							endIdx = (globalPoint.x <= nextTextLine.x) ? (nextFlowLine.absoluteStart + nextFlowLine.textLength - 1) : nextFlowLine.absoluteStart;							
+						}
+					} else {
+						if (!bidiRightToLeft) {
+							endIdx = (globalPoint.y <= nextTextLine.y) ? nextFlowLine.absoluteStart : (nextFlowLine.absoluteStart + nextFlowLine.textLength - 1);							
+						} else {
+							endIdx = (globalPoint.y <= nextTextLine.y) ? (nextFlowLine.absoluteStart + nextFlowLine.textLength - 1) : nextFlowLine.absoluteStart;
+						}
+					}
+				} else {
+					// get the character box and if check we are past the middle select past this character. 
+					var glyphRect:Rectangle = nextTextLine.getAtomBounds(atomIndex);
+					var leanRight:Boolean = false;
+					if(glyphRect)
+					{	
+						//if this is TTB and NOT TCY determine lean based on Y coordinates...
+						var glyphGlobalPoint:Point = new Point();
+						glyphGlobalPoint.x = glyphRect.x;
+						glyphGlobalPoint.y = glyphRect.y;
+						glyphGlobalPoint = nextTextLine.localToGlobal(glyphGlobalPoint);
+						
+						if((textFlow.computedFormat.blockProgression == BlockProgression.RL) && nextTextLine.getAtomTextRotation(atomIndex) != TextRotation.ROTATE_0)
+							leanRight = (globalPoint.y > (glyphGlobalPoint.y + glyphRect.height/2));
+						else //use X..
+							leanRight = (globalPoint.x > (glyphGlobalPoint.x + glyphRect.width/2));
+					}
+			
+					var paraSelectionIdx:int;
+					if ((nextTextLine.getAtomBidiLevel(atomIndex) % 2) != 0) // Right to left case, right is "start" unicode
+						paraSelectionIdx = leanRight ? nextTextLine.getAtomTextBlockBeginIndex(atomIndex) : nextTextLine.getAtomTextBlockEndIndex(atomIndex);
+					else  {// Left to right case, right is "end" unicode
+						if (isRTLDirection) {
+							if ((leanRight == false) && (atomIndex > 0))
+							{
+								paraSelectionIdx = nextTextLine.getAtomTextBlockBeginIndex(atomIndex - 1);	
+							} else {
+								paraSelectionIdx = nextTextLine.getAtomTextBlockBeginIndex(atomIndex);
+							}
+						} else {
+							paraSelectionIdx = leanRight ? nextTextLine.getAtomTextBlockEndIndex(atomIndex) : nextTextLine.getAtomTextBlockBeginIndex(atomIndex);							
+						}
+					}
+					endIdx = nextFlowLine.paragraph.getAbsoluteStart() + paraSelectionIdx;
+					if (endIdx >= textFlow.textLength)
+					{
+						endIdx = textFlow.textLength - 1;
+					}
+				}
+			} else {
+				endIdx = textFlow.textLength - 1;
+			}
+				
+			if (!extendSelection)
+				begIdx = endIdx;
+											
+			if (begIdx == endIdx)
+			{
+				begIdx = updateStartIfInReadOnlyElement(textFlow, begIdx);
+				endIdx = updateEndIfInReadOnlyElement(textFlow, endIdx);
+			} else {
+				endIdx = updateEndIfInReadOnlyElement(textFlow, endIdx);
+			}
+			return range.updateRange(begIdx,endIdx);			
+		}
+		  
+		/**
+		 * Sets the TextRange up one line.
+		 * @param extendSelection	Indicates that only activeIndex should move
+		 * @return true if selection changed.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */		 		 		 		 		 		 
+		static public function previousLine(range:TextRange, extendSelection:Boolean = false):Boolean
+		{
+			if (!validateTextRange(range))
+				return false;
+			
+			if (adjustForOversetBack(range))
+				return true;
+				
+			var textFlow:TextFlow = range.textFlow;
+			var begIdx:int = range.anchorPosition;
+			var endIdx:int = range.activePosition;
+			
+			var curLine:int = textFlow.flowComposer.findLineIndexAtPosition(endIdx);
+			var isRTLDirection:Boolean = (textFlow.computedFormat.direction == Direction.RTL);			
+
+			if (curLine > 0)	//create, expand or shrink the selection
+			{
+				var curTextFlowLine:TextFlowLine = textFlow.flowComposer.getLineAt(curLine);
+				var lineStart:int = curTextFlowLine.absoluteStart;
+				var lineDelta:int = endIdx - lineStart;
+				var currentTextLine:TextLine = curTextFlowLine.getTextLine(true);
+				var para:ParagraphElement = curTextFlowLine.paragraph;
+				var atomIndex:int = currentTextLine.getAtomIndexAtCharIndex(endIdx - para.getAbsoluteStart());
+				var bidiRightToLeft:Boolean = ((currentTextLine.getAtomBidiLevel(atomIndex) % 2) != 0); 				
+				var curPosRect:Rectangle = currentTextLine.getAtomBounds(atomIndex);
+				var currentTextLineX:Number = currentTextLine.x;
+				var curPosRectLeft:Number = curPosRect.left;
+				var curPosRectRight:Number = curPosRect.right;
+				if(textFlow.computedFormat.blockProgression == BlockProgression.RL)
+				{
+					currentTextLineX = currentTextLine.y;
+					curPosRectLeft = curPosRect.top;
+					curPosRectRight = curPosRect.bottom;
+				}
+				
+				//find the atom
+				var globalPoint:Point = new Point();				
+						
+				if(textFlow.computedFormat.blockProgression != BlockProgression.RL)
+				{
+					if (!isRTLDirection)
+						globalPoint.x = curPosRect.left;
+					else
+						globalPoint.x = curPosRect.right;
+					globalPoint.y = 0;
+				} else {						
+					globalPoint.x = 0;
+					if (!isRTLDirection)
+						globalPoint.y = curPosRect.top;
+					else
+						globalPoint.y = curPosRect.bottom;
+				}
+				
+				globalPoint = currentTextLine.localToGlobal(globalPoint);
+				
+				//at this point, we have the global point of our current position.  Now adjust x or y to the
+				//baseline of the next line.
+				var prevFlowLine:TextFlowLine = textFlow.flowComposer.getLineAt(curLine - 1);
+				// get the last container so that we can make sure the previous line is in view.
+				var controller:ContainerController = textFlow.flowComposer.getControllerAt(textFlow.flowComposer.numControllers-1);
+				var firstPosInContainer:int = controller.absoluteStart;
+				var lastPosInContainer:int = firstPosInContainer + controller.textLength;
+				if ((prevFlowLine.absoluteStart >= firstPosInContainer) && (prevFlowLine.absoluteStart < lastPosInContainer))
+				{
+					controller.scrollToRange(prevFlowLine.absoluteStart,prevFlowLine.absoluteStart+prevFlowLine.textLength-1);
+				}
+				
+				var preventextLine:TextLine = prevFlowLine.getTextLine(true);
+				if (prevFlowLine.controller == curTextFlowLine.controller)
+				{
+					if(textFlow.computedFormat.blockProgression != BlockProgression.RL)
+					{
+						globalPoint.y -= (currentTextLine.y - preventextLine.y);
+					} else {
+						globalPoint.x += (preventextLine.x - currentTextLine.x);
+					}
+				} else {
+					var firstAtomRect:Rectangle = preventextLine.getAtomBounds(0);
+					var firstAtomPoint:Point = new Point();
+					firstAtomPoint.x = firstAtomRect.left;
+					firstAtomPoint.y = 0;
+					firstAtomPoint = preventextLine.localToGlobal(firstAtomPoint);
+					if(textFlow.computedFormat.blockProgression != BlockProgression.RL)
+					{
+						globalPoint.x -= curTextFlowLine.controller.container.x;
+						globalPoint.y = firstAtomPoint.y;
+					} else {
+						globalPoint.x = firstAtomPoint.x;
+						globalPoint.y -= curTextFlowLine.controller.container.y; 
+					}					
+				} 
+				
+				atomIndex = preventextLine.getAtomIndexAtPoint(globalPoint.x,globalPoint.y);
+				if (atomIndex == -1)
+				{
+					if(textFlow.computedFormat.blockProgression != BlockProgression.RL) {
+						if (!bidiRightToLeft)
+							endIdx = (globalPoint.x <= preventextLine.x) ? prevFlowLine.absoluteStart : (prevFlowLine.absoluteStart + prevFlowLine.textLength - 1);
+						else
+							endIdx = (globalPoint.x <= preventextLine.x) ? (prevFlowLine.absoluteStart + prevFlowLine.textLength - 1) : prevFlowLine.absoluteStart;						
+					} else {
+						if (!bidiRightToLeft)
+							endIdx = (globalPoint.y <= preventextLine.y) ? prevFlowLine.absoluteStart : (prevFlowLine.absoluteStart + prevFlowLine.textLength - 1);
+						else
+							endIdx = (globalPoint.y <= preventextLine.y)  ? (prevFlowLine.absoluteStart + prevFlowLine.textLength - 1) : prevFlowLine.absoluteStart;						
+					}
+				} else {
+					// get the character box and if check we are past the middle select past this character. 
+					var glyphRect:Rectangle = preventextLine.getAtomBounds(atomIndex);
+					var leanRight:Boolean = false;
+					if(glyphRect)
+					{	
+						//if this is TTB and NOT TCY determine lean based on Y coordinates...
+						var glyphGlobalPoint:Point = new Point();
+						glyphGlobalPoint.x = glyphRect.x;
+						glyphGlobalPoint.y = glyphRect.y;
+						glyphGlobalPoint = preventextLine.localToGlobal(glyphGlobalPoint);
+						
+						if((textFlow.computedFormat.blockProgression == BlockProgression.RL) && preventextLine.getAtomTextRotation(atomIndex) != TextRotation.ROTATE_0)
+							leanRight = (globalPoint.y > (glyphGlobalPoint.y + glyphRect.height/2));
+						else //use X..
+							leanRight = (globalPoint.x > (glyphGlobalPoint.x + glyphRect.width/2));
+					}
+			
+					var paraSelectionIdx:int;
+					if ((preventextLine.getAtomBidiLevel(atomIndex) % 2) != 0) // Right to left case, right is "start" unicode
+						paraSelectionIdx = leanRight ? preventextLine.getAtomTextBlockBeginIndex(atomIndex) : preventextLine.getAtomTextBlockEndIndex(atomIndex);
+					else  {// Left to right case, right is "end" unicode
+						if (isRTLDirection) {
+							if ((leanRight == false) && (atomIndex > 0))
+							{
+								paraSelectionIdx = preventextLine.getAtomTextBlockBeginIndex(atomIndex - 1);	
+							} else {
+								paraSelectionIdx = preventextLine.getAtomTextBlockBeginIndex(atomIndex);
+							}
+						} else {
+							paraSelectionIdx = leanRight ? preventextLine.getAtomTextBlockEndIndex(atomIndex) : preventextLine.getAtomTextBlockBeginIndex(atomIndex);							
+						}
+					}
+					endIdx = prevFlowLine.paragraph.getAbsoluteStart() + paraSelectionIdx;
+				}
+			} else {
+				endIdx = 0;
+			}
+				
+			if (!extendSelection)
+				begIdx = endIdx;
+											
+			if (begIdx == endIdx)
+			{
+				begIdx = updateStartIfInReadOnlyElement(textFlow, begIdx);
+				endIdx = updateEndIfInReadOnlyElement(textFlow, endIdx);
+			} else {
+				endIdx = updateEndIfInReadOnlyElement(textFlow, endIdx);
+			}
+			return range.updateRange(begIdx,endIdx);			
+		}
+		 
+		/**
+		 * Sets the TextRange down one page.
+		 * @param extendSelection	Indicates that only activeIndex should move
+		 * @return true if selection changed.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */		 		 		 		 		 		 		 
+		static public function nextPage(range:TextRange, extendSelection:Boolean = false):Boolean
+		{
+			var controller:ContainerController;
+			
+			if (!validateTextRange(range))
+				return false;
+				
+			var textFlow:TextFlow = range.textFlow;
+			
+			// if not the last container go to the beginning of the next container
+			var controllerIndex:int = textFlow.flowComposer.findControllerIndexAtPosition(range.activePosition);
+			if (controllerIndex != textFlow.flowComposer.numControllers-1)
+			{
+				range.activePosition = textFlow.flowComposer.getControllerAt(controllerIndex+1).absoluteStart;
+				if (!extendSelection)
+					range.anchorPosition = range.activePosition;
+				return true;
+			}
+			
+			if (!isScrollable(textFlow, range.activePosition))		// paging applies only to containers that scroll
+				return false;
+								
+			if (adjustForOversetForward(range))
+				return true;
+		 	
+			var begIdx:int = range.absoluteStart;
+			var endIdx:int = range.absoluteEnd;
+			var curLine:int = textFlow.flowComposer.findLineIndexAtPosition(endIdx);
+			var curTextFlowLine:TextFlowLine = textFlow.flowComposer.getLineAt(curLine);
+			
+			var lineStart:int = textFlow.flowComposer.getLineAt(curLine).absoluteStart;
+			var linePos:int = endIdx - lineStart;
+ 			var nextLine:int;
+ 			var nextTextFlowLine:TextFlowLine = curTextFlowLine;
+ 											
+			var isTTB:Boolean = textFlow.computedFormat.blockProgression == BlockProgression.RL;
+			var amount:Number;
+			
+			// get the last container
+			controller = textFlow.flowComposer.getControllerAt(textFlow.flowComposer.numControllers-1);
+
+			if (isTTB)
+			{
+				amount = controller.compositionWidth * textFlow.configuration.scrollPagePercentage;
+			} else {
+				amount = controller.compositionHeight * textFlow.configuration.scrollPagePercentage;
+			}
+  								
+ 			if (isTTB)
+ 			{
+ 				if ((controller.horizontalScrollPosition - amount) < -controller.contentWidth)
+ 				{
+ 					controller.horizontalScrollPosition = -controller.contentWidth;
+					nextLine = textFlow.flowComposer.numLines - 1;
+					nextTextFlowLine = textFlow.flowComposer.getLineAt(nextLine);								
+ 				} else
+ 				{
+ 					var oldHorzScrollPos:Number = controller.horizontalScrollPosition;
+ 					controller.horizontalScrollPosition -= amount;
+ 					var newHorzScrollPos:Number = controller.horizontalScrollPosition;
+ 					if (oldHorzScrollPos == newHorzScrollPos) {
+						nextLine = textFlow.flowComposer.numLines - 1;
+						nextTextFlowLine = textFlow.flowComposer.getLineAt(nextLine);													
+ 					} else {
+ 						nextLine = curLine;
+ 						while (nextLine < (textFlow.flowComposer.numLines - 1))
+ 						{
+ 							nextLine++;
+							nextTextFlowLine = textFlow.flowComposer.getLineAt(nextLine);
+							if ((curTextFlowLine.x - nextTextFlowLine.x) >= (oldHorzScrollPos - newHorzScrollPos))
+								break;
+ 						}
+ 					}
+ 				} 					
+ 			}
+ 			else
+ 			{
+ 				if ((controller.verticalScrollPosition + amount) > controller.contentHeight)
+ 				{
+ 					controller.verticalScrollPosition = controller.contentHeight;
+					nextLine = textFlow.flowComposer.numLines - 1;
+					nextTextFlowLine = textFlow.flowComposer.getLineAt(nextLine);								 						
+ 				} else
+ 				{
+ 					var oldVertScrollPos:Number = controller.verticalScrollPosition;
+ 					controller.verticalScrollPosition += amount;
+ 					var newVertScrollPos:Number = controller.verticalScrollPosition;
+ 					if (newVertScrollPos == oldVertScrollPos) {
+						nextLine = textFlow.flowComposer.numLines - 1;
+						nextTextFlowLine = textFlow.flowComposer.getLineAt(nextLine);								 											
+ 					} else {
+ 						nextLine = curLine;
+ 						while (nextLine < (textFlow.flowComposer.numLines - 1))
+ 						{
+ 							nextLine++;
+							nextTextFlowLine = textFlow.flowComposer.getLineAt(nextLine);
+							if ((nextTextFlowLine.y - curTextFlowLine.y) >= (newVertScrollPos - oldVertScrollPos))
+								break;
+ 						} 						
+ 					}
+ 				}
+ 			}
+ 			
+ 			endIdx = nextTextFlowLine.absoluteStart + linePos; 
+			var nextLineEnd:int = nextTextFlowLine.absoluteStart + nextTextFlowLine.textLength - 1;
+			if (endIdx > nextLineEnd)
+			{
+				endIdx = nextLineEnd;
+			}
+			
+			if (!extendSelection)
+				begIdx = endIdx;							
+			if (begIdx == endIdx)
+			{
+				begIdx = updateEndIfInReadOnlyElement(textFlow, begIdx);
+				endIdx = updateStartIfInReadOnlyElement(textFlow, endIdx);
+			} else {
+				endIdx = updateStartIfInReadOnlyElement(textFlow, endIdx);
+			}
+			
+			return range.updateRange(begIdx,endIdx);				
+		 }
+		  
+		/**
+		 * Sets the TextRange up one page.
+		 * @param extendSelection	Indicates that only activeIndex should move
+		 * @return true if selection changed.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */		 		 		 		 		 		 		 		 
+		static public function previousPage(range:TextRange, extendSelection:Boolean = false):Boolean
+		{
+			if (!validateTextRange(range))
+				return false;
+				
+			var textFlow:TextFlow = range.textFlow;
+			
+			var controllerIndex:int = textFlow.flowComposer.findControllerIndexAtPosition(range.activePosition);
+			var controller:ContainerController = textFlow.flowComposer.getControllerAt(controllerIndex);
+			
+			// first line in container
+			var controllerFirstLine:TextFlowLine = textFlow.flowComposer.findLineAtPosition(controller.absoluteStart);
+
+			// if on the first line of a controller go to the beginning of the previous controller
+			if (range.activePosition <= controller.absoluteStart+controllerFirstLine.textLength)
+			{
+				if (controllerIndex == 0)
+					return false;
+				range.activePosition = textFlow.flowComposer.getControllerAt(controllerIndex-1).absoluteStart;
+				if (!extendSelection)
+					range.anchorPosition = range.activePosition;
+				return true;
+			}
+			
+			// if not the last container go to the beginning of the current container
+			if (controllerIndex != textFlow.flowComposer.numControllers-1)
+			{
+				range.activePosition = controller.absoluteStart;
+				if (!extendSelection)
+					range.anchorPosition = range.activePosition;
+				return true;
+			}
+				
+			if (!isScrollable(textFlow, range.activePosition))		// paging applies only to containers that scroll
+				return false;
+								
+			if (adjustForOversetBack(range))
+				return true;
+			
+			var begIdx:int = range.absoluteStart;
+			var endIdx:int = range.absoluteEnd;
+			var curLine:int = textFlow.flowComposer.findLineIndexAtPosition(endIdx);
+			var curTextFlowLine:TextFlowLine = textFlow.flowComposer.getLineAt(curLine);
+			
+			var lineStart:int = textFlow.flowComposer.getLineAt(curLine).absoluteStart;
+			var linePos:int = endIdx - lineStart;
+ 			var nextLine:int;
+ 			var nextLinePos:int;
+ 			var nextTextFlowLine:TextFlowLine = curTextFlowLine;
+ 											
+			var isTTB:Boolean = textFlow.computedFormat.blockProgression == BlockProgression.RL;
+			var amount:Number;
+			
+			// get the last container
+			controller = textFlow.flowComposer.getControllerAt(textFlow.flowComposer.numControllers-1);
+			
+			if (isTTB)
+			{
+				amount = controller.compositionWidth * textFlow.configuration.scrollPagePercentage;
+			} else {
+				amount = controller.compositionHeight * textFlow.configuration.scrollPagePercentage;
+			}
+  								
+ 			if (isTTB)
+ 			{
+ 				if ((controller.horizontalScrollPosition + amount + controller.compositionWidth) > 0)
+ 				{
+ 					controller.horizontalScrollPosition = 0;
+					nextLine = textFlow.flowComposer.findLineIndexAtPosition(controller.absoluteStart);
+					nextTextFlowLine = textFlow.flowComposer.getLineAt(nextLine);								
+ 				} else
+ 				{
+ 					var oldHorzPos:Number = controller.horizontalScrollPosition;
+ 					controller.horizontalScrollPosition += amount;
+ 					var newHorzPos:Number = controller.horizontalScrollPosition;
+ 					if (oldHorzPos == newHorzPos) {
+						nextLine = textFlow.flowComposer.findLineIndexAtPosition(controller.absoluteStart);
+						nextTextFlowLine = textFlow.flowComposer.getLineAt(nextLine);													
+ 					} else {
+ 						nextLine = curLine;
+ 						while (nextLine > 0)
+ 						{
+ 							nextLine--;
+							nextTextFlowLine = textFlow.flowComposer.getLineAt(nextLine);
+							if ((nextTextFlowLine.x - curTextFlowLine.x) >= (newHorzPos - oldHorzPos) || nextTextFlowLine.absoluteStart < controller.absoluteStart)
+								break;
+ 						}
+ 					}
+ 				} 					
+ 			}
+ 			else
+ 			{
+ 				if ((controller.verticalScrollPosition - amount + controller.compositionHeight) < 0)
+ 				{
+ 					controller.verticalScrollPosition = 0;
+					nextLine = textFlow.flowComposer.findLineIndexAtPosition(controller.absoluteStart);
+					nextTextFlowLine = textFlow.flowComposer.getLineAt(nextLine);								 						
+ 				} else
+ 				{
+ 					var oldVertPos:Number = controller.verticalScrollPosition;
+ 					controller.verticalScrollPosition -= amount;
+ 					var newVertPos:Number = controller.verticalScrollPosition;
+ 					if (oldVertPos == newVertPos) {
+						nextLine = textFlow.flowComposer.findLineIndexAtPosition(controller.absoluteStart);
+						nextTextFlowLine = textFlow.flowComposer.getLineAt(nextLine);								 											
+ 					} else {
+ 						nextLine = curLine;
+ 						while (nextLine > 0)
+ 						{
+ 							nextLine--;
+							nextTextFlowLine = textFlow.flowComposer.getLineAt(nextLine);
+							if ((curTextFlowLine.y - nextTextFlowLine.y) >= (oldVertPos - newVertPos) || nextTextFlowLine.absoluteStart < controller.absoluteStart)
+								break;
+ 						}
+ 					} 						
+ 				}
+ 			}
+ 			
+ 			endIdx = nextTextFlowLine.absoluteStart + linePos; 
+			var nextLineEnd:int = nextTextFlowLine.absoluteStart + nextTextFlowLine.textLength - 1;
+			if (endIdx > nextLineEnd)
+			{
+				endIdx = nextLineEnd;
+			}
+			
+			if (!extendSelection)
+				begIdx = endIdx;							
+			if (begIdx == endIdx)
+			{
+				begIdx = updateEndIfInReadOnlyElement(textFlow, begIdx);
+				endIdx = updateStartIfInReadOnlyElement(textFlow, endIdx);
+			} else {
+				endIdx = updateStartIfInReadOnlyElement(textFlow, endIdx);
+			}
+			return range.updateRange(begIdx,endIdx);						
+		} 
+		/**
+		 * Sets the TextRange at the end of the line.
+		 * @param extendSelection	Indicates that only activeIndex should move
+		 * @return true if selection changed.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */		 		 		 		 		 		 		 		 		 
+		static public function endOfLine(range:TextRange, extendSelection:Boolean = false):Boolean
+		{
+			if (!validateTextRange(range))
+				return false;
+			
+
+			var textFlow:TextFlow = range.textFlow;
+			checkCompose(textFlow.flowComposer, range.absoluteEnd);
+
+			var begIdx:int = range.anchorPosition;
+			var endIdx:int = range.activePosition;
+			var curLine:int = textFlow.flowComposer.findLineIndexAtPosition(endIdx);
+			var lineStart:int = textFlow.flowComposer.getLineAt(curLine).absoluteStart;
+			var lineEnd:int = lineStart + textFlow.flowComposer.getLineAt(curLine).textLength - 1;
+			
+			var leaf:FlowLeafElement = textFlow.findLeaf(endIdx);
+			var para:ParagraphElement = leaf.getParagraph();
+			if (CharacterUtil.isWhitespace(para.getCharCodeAtPosition(lineEnd - para.getAbsoluteStart())))
+			{
+				endIdx = lineEnd;
+			} else {
+				endIdx = lineEnd + 1;
+			}
+			if (!extendSelection)
+				begIdx = endIdx;							
+			if (begIdx == endIdx)
+			{
+				begIdx = updateEndIfInReadOnlyElement(textFlow, begIdx);
+				endIdx = updateStartIfInReadOnlyElement(textFlow, endIdx);
+			} else {
+				endIdx = updateStartIfInReadOnlyElement(textFlow, endIdx);
+			}
+			return range.updateRange(begIdx,endIdx);
+		 }
+		 
+		/**
+		 * Sets the TextRange at the beginning of the line.
+		 * @param extendSelection	Indicates that only activeIndex should move
+		 * @return true if selection changed.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */		 		 		 		 		 		 		 		 		 		 
+		static public function startOfLine(range:TextRange, extendSelection:Boolean = false):Boolean
+		{
+			if (!validateTextRange(range))
+				return false;
+				
+			var textFlow:TextFlow = range.textFlow;
+			checkCompose(textFlow.flowComposer, range.absoluteEnd);
+			var begIdx:int = range.anchorPosition;
+			var endIdx:int = range.activePosition;
+		
+			var curLine:int = textFlow.flowComposer.findLineIndexAtPosition(endIdx);
+			var lineStart:int = textFlow.flowComposer.getLineAt(curLine).absoluteStart;
+			endIdx = lineStart;
+			if (!extendSelection)
+				begIdx = endIdx;							
+			if (begIdx == endIdx)
+			{
+				begIdx = updateEndIfInReadOnlyElement(textFlow, begIdx);
+				endIdx = updateStartIfInReadOnlyElement(textFlow, endIdx);
+			} else {
+				endIdx = updateStartIfInReadOnlyElement(textFlow, endIdx);
+			}
+			return range.updateRange(begIdx,endIdx);
+		} 
+		/**
+		 * Sets the TextRange at the end of the document.
+		 * @param extendSelection	Indicates that only activeIndex should move
+		 * @return true if selection changed.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */		 		 		 		 		 		 		 		 		 		 		 
+		static public function endOfDocument(range:TextRange, extendSelection:Boolean = false):Boolean
+		{
+			if (!validateTextRange(range))
+				return false;
+				
+			var textFlow:TextFlow = range.textFlow
+			var begIdx:int = range.anchorPosition;
+			var endIdx:int = range.activePosition;
+			endIdx = textFlow.textLength - 1;
+			if (!extendSelection)
+				begIdx = endIdx;							
+			if (begIdx == endIdx)
+			{
+				begIdx = updateEndIfInReadOnlyElement(textFlow, begIdx);
+				endIdx = updateStartIfInReadOnlyElement(textFlow, endIdx);
+			} else {
+				endIdx = updateStartIfInReadOnlyElement(textFlow, endIdx);
+			}
+			return range.updateRange(begIdx,endIdx);				
+		}
+		
+		/**
+		 * Sets the TextRange at the beginning of the document.
+		 * @param extendSelection	Indicates that only activeIndex should move
+		 * @return true if selection changed.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */		 		 		 		 		 		 		 		 		 		 		 		 
+		static public function startOfDocument(range:TextRange, extendSelection:Boolean = false):Boolean
+		{
+			var begIdx:int = range.anchorPosition;
+			var endIdx:int = 0;
+
+			if (!extendSelection)
+				begIdx = endIdx;							
+			if (begIdx == endIdx)
+			{
+				begIdx = updateEndIfInReadOnlyElement(range.textFlow, begIdx);
+				endIdx = updateStartIfInReadOnlyElement(range.textFlow, endIdx);
+			} else {
+				endIdx = updateStartIfInReadOnlyElement(range.textFlow, endIdx);
+			}
+			return range.updateRange(begIdx,endIdx);				
+		}
+		 
+		/**
+		 * Sets the TextRange at the beginning of the paragraph.
+		 * @param extendSelection	Indicates that only activeIndex should move
+		 * @return true if selection changed.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */		 		 		 		 		 		 		 		 		 		 		 		 		 
+		static public function startOfParagraph(range:TextRange, extendSelection:Boolean = false):Boolean
+		{
+			var begIdx:int = range.anchorPosition;
+			var endIdx:int = range.activePosition;
+			var leaf:FlowLeafElement = range.textFlow.findLeaf(endIdx);
+			var para:ParagraphElement = leaf.getParagraph();
+			
+			endIdx = para.getAbsoluteStart();
+			if (!extendSelection)
+				begIdx = endIdx;							
+
+			if (begIdx == endIdx)
+			{
+				begIdx = updateStartIfInReadOnlyElement(range.textFlow, begIdx);
+				endIdx = updateEndIfInReadOnlyElement(range.textFlow, endIdx);
+			} else {
+				endIdx = updateEndIfInReadOnlyElement(range.textFlow, endIdx);
+			}
+			return range.updateRange(begIdx,endIdx);
+		 }
+		 
+		/**
+		 * Sets the TextRange at the end of the paragraph.
+		 * @param extendSelection	Indicates that only activeIndex should move
+		 * @return true if selection changed.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */		 		 		 		 		 		 		 		 		 		 		 		 		 		 
+		static public function endOfParagraph(range:TextRange, extendSelection:Boolean = false):Boolean
+		{
+			if (!validateTextRange(range))
+				return false;
+				
+			var begIdx:int = range.anchorPosition;
+			var endIdx:int = range.activePosition;
+			var leaf:FlowLeafElement = range.textFlow.findLeaf(endIdx);
+			var para:ParagraphElement = leaf.getParagraph();
+			
+			endIdx = para.getAbsoluteStart() + para.textLength - 1;
+			if (!extendSelection)
+				begIdx = endIdx;							
+			if (begIdx == endIdx)
+			{
+				begIdx = updateStartIfInReadOnlyElement(range.textFlow, begIdx);
+				endIdx = updateEndIfInReadOnlyElement(range.textFlow, endIdx);
+			} else {
+				endIdx = updateEndIfInReadOnlyElement(range.textFlow, endIdx);
+			}
+			return range.updateRange(begIdx,endIdx);
+		 }
+	
+		/** If the range is in overset text (after the last container in a non-scrolling flow), adjust the range so it is at the end of the flow. */
+		static private function adjustForOversetForward(range:TextRange):Boolean
+		{
+			var flowComposer:IFlowComposer = range.textFlow.flowComposer;
+			var controller:ContainerController = null;
+			checkCompose(flowComposer, range.absoluteEnd);
+			if (flowComposer && flowComposer.numControllers)
+			{
+				var controllerIndex:int = flowComposer.findControllerIndexAtPosition(range.absoluteEnd);
+				if (controllerIndex >= 0)
+					controller = flowComposer.getControllerAt(controllerIndex);
+				if (controllerIndex == flowComposer.numControllers-1)
+				{
+					if (controller.absoluteStart + controller.textLength <= range.absoluteEnd && controller.absoluteStart + controller.textLength != range.textFlow.textLength)
+						controller = null;
+				}
+			}
+
+			if (!controller)		// we're overset, or one position before overset
+			{
+				range.anchorPosition = range.textFlow.textLength - 1;
+				range.activePosition = range.anchorPosition;
+				return true;
+			}
+			return false;
+		}
+		
+		/** If the range is in overset text (after the last container in a non-scrolling flow), adjust the range so it is at the end of the last controller in the flow. */
+		static private function adjustForOversetBack(range:TextRange):Boolean
+		{
+			var flowComposer:IFlowComposer = range.textFlow.flowComposer;
+			if (flowComposer)
+			{
+				checkCompose(flowComposer, range.absoluteEnd);
+				if (flowComposer.findControllerIndexAtPosition(range.absoluteEnd) == -1)
+				{
+					range.anchorPosition = endOfLastController(range.textFlow);
+					range.activePosition = range.anchorPosition;
+					return true;
+				}				
+			}
+				
+			return false;
+		}
+		
+		private static function checkCompose(flowComposer:IFlowComposer, pos:int):void
+		{
+			if (flowComposer.damageAbsoluteStart <= pos)
+				flowComposer.composeToPosition(pos);
+		}
+		
+		// Returns absolute position of the last controller in the flow, or 0 if the flow has no controllers
+		private static function endOfLastController(flowRoot:TextFlow):int
+		{
+			var flowComposer:IFlowComposer = flowRoot.flowComposer;
+			if (!flowComposer || flowComposer.numControllers <= 0)
+				return 0;
+				
+			var controller:ContainerController = flowComposer.getControllerAt(flowComposer.numControllers - 1);
+			return controller.absoluteStart + Math.max(controller.textLength - 1, 0);
+		}
+		
+		// Returns true if the position is in the overset text after the last container in the flow.
+		private static function isOverset(flowRoot:TextFlow, absolutePos:int):Boolean
+		{
+			var flowComposer:IFlowComposer = flowRoot.flowComposer;
+			return (!flowComposer || flowComposer.findControllerIndexAtPosition(absolutePos) == -1);
+		}
+	
+		// Returns true if the position is in a scollable container
+		private static function isScrollable(flowRoot:TextFlow, absolutePos:int):Boolean
+		{
+			var flowComposer:IFlowComposer = flowRoot.flowComposer;
+			if (!flowComposer)
+				return false;
+			var controllerIndex:int = flowComposer.findControllerIndexAtPosition(absolutePos);
+			if (controllerIndex >= 0)
+			{
+				var controller:ContainerController = flowComposer.getControllerAt(controllerIndex);
+				var blockProgression:String = controller.rootElement.computedFormat.blockProgression;
+				return ((blockProgression == BlockProgression.TB && controller.verticalScrollPolicy != ScrollPolicy.OFF) ||
+					(blockProgression == BlockProgression.RL && controller.horizontalScrollPolicy != ScrollPolicy.OFF));
+			}
+			return false;
+		}
+		
+	}
+}
diff --git a/textLayout_edit/src/flashx/undo/IOperation.as b/textLayout_edit/src/flashx/undo/IOperation.as
new file mode 100755
index 0000000..c94cb3a
--- /dev/null
+++ b/textLayout_edit/src/flashx/undo/IOperation.as
@@ -0,0 +1,51 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.undo
+{
+	/** 
+	 * IOperation defines the interface for operations that can be undone and redone.
+	 *  
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */
+	public interface IOperation
+	{
+		/** 
+		 * Reperforms the operation.
+		 * 
+		 * <p>The operation is also responsible for pushing itself onto the undo stack.</p>
+		 *  
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		function performRedo():void;
+		/** 
+		 * Reverses the operation.
+		 * 
+		 * <p>The operation is also responsible for pushing itself onto the redo stack.</p> 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+	 	 * @langversion 3.0
+		 */
+		function performUndo():void;
+	}
+}
diff --git a/textLayout_edit/src/flashx/undo/IUndoManager.as b/textLayout_edit/src/flashx/undo/IUndoManager.as
new file mode 100755
index 0000000..0e3ab2d
--- /dev/null
+++ b/textLayout_edit/src/flashx/undo/IUndoManager.as
@@ -0,0 +1,177 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.undo
+{	
+	/**
+	 * IUndoManager defines the interface for managing the undo and redo stacks.
+	 * 
+	 * <p>An undo manager maintains a stack of operations that can be undone and redone.</p>
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 */
+	public interface IUndoManager 
+	{	
+		/**
+		 * Clears both the undo and the redo histories.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */	
+		function clearAll():void;
+		
+		/**
+		 * The maximum number of undoable or redoable operations to track.
+		 * 
+		 * <p>To disable the undo function, set this value to 0.</p> 
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function get undoAndRedoItemLimit():int;
+		function set undoAndRedoItemLimit(value:int):void;
+
+		/**
+		 * Indicates whether there is currently an operation that can be undone.
+		 * 
+		 * @return Boolean <code>true</code>, if there is an operation on the undo stack that can be reversed.
+		 * Otherwise, <code>false</code>.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function canUndo():Boolean;
+		
+		/**
+		 * Returns the next operation to be undone.
+		 * 
+		 * @return IOperation The undoable IOperation object, or <code>null</code>, if no undoable operation
+		 * is on the stack.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function peekUndo():IOperation;
+		
+		/**
+		 * Removes the next operation to be undone from the undo stack, and returns it.
+		 * 
+		 * @return IOperation The undoable IOperation object, or <code>null</code>, if no undoable operation
+		 * is on the stack.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function popUndo():IOperation;
+
+		/**
+		 * Adds an undoable operation to the undo stack.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function pushUndo(operation:IOperation):void;
+		
+		/**
+		 * Clears the redo stack.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function clearRedo():void;
+
+		/**
+		 * Indicates whether there is currently an operation that can be redone.
+		 * 
+		 * @return Boolean <code>true</code>, if there is an operation on the redo stack that can be redone.
+		 * Otherwise, <code>false</code>.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function canRedo():Boolean;
+
+		/**
+		 * Returns the next operation to be redone.
+		 * 
+		 * @return IOperation The redoable IOperation object, or <code>null</code>, if no redoable operation
+		 * is on the stack.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function peekRedo():IOperation;
+		
+		/**
+		 * Removes the next operation to be redone from the redo stack, and returns it.
+		 * 
+		 * @return IOperation The redoable IOperation object, or <code>null</code>, if no redoable operation
+		 * is on the stack.
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function popRedo():IOperation;
+
+		/**
+		 * Adds a redoable operation to the redo stack.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		function pushRedo(operation:IOperation):void;
+
+		/** 
+		 * Removes the next IOperation object from the undo stack and calls the performUndo() 
+		 * function of that object.
+		 * 
+		 * @see flashx.textLayout.edit.IEditManager#undo()
+		 * @see flashx.undo.IUndoManager#canUndo()
+		 * @see flashx.undo.IUndoManager#clearUndo()
+		 * @see flashx.undo.IUndoManager#peekUndo()
+		 * @see flashx.undo.IUndoManager#pushUndo()
+		 * @see flashx.undo.IUndoManager#popUndo()
+		 */
+		function undo():void;
+		
+		/** 
+		 * Removes the next IOperation object from the redo stack and calls the performRedo() 
+		 * function of that object.
+		 * 
+		 * @see flashx.textLayout.edit.IEditManager#redo()
+		 * @see flashx.undo.IUndoManager#canRedo()
+		 * @see flashx.undo.IUndoManager#clearRedo()
+		 * @see flashx.undo.IUndoManager#peekRedo()
+		 * @see flashx.undo.IUndoManager#pushRedo()
+		 * @see flashx.undo.IUndoManager#popRedo()
+		 */
+		function redo():void;						
+	}
+}
diff --git a/textLayout_edit/src/flashx/undo/UndoManager.as b/textLayout_edit/src/flashx/undo/UndoManager.as
new file mode 100755
index 0000000..845d904
--- /dev/null
+++ b/textLayout_edit/src/flashx/undo/UndoManager.as
@@ -0,0 +1,251 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.undo
+{
+			
+	/** 
+	 * The UndoManager class manages the history of editing operations on a text flow so
+	 * that these operations can be undone and redone.
+	 * 
+	 * <p>The undo manager maintains two stacks of IOperation objects. When a reversible
+	 * operation is executed, it is placed on the undo stack. If that operation is undone,
+	 * it is removed from the undo stack, reversed, and placed on the redo stack. Likewise, 
+	 * if that operation is then redone, it is removed from the redo stack, re-executed, and
+	 * then placed onto the undo stack again. If another operation is executed first, the redo 
+	 * stack is cleared.</p>
+	 * 
+	 * <p>If the TextFlow is modified directly (not via
+	 * calls to the edit manager, but directly via calls to the managed FlowElement objects), then the edit manager
+	 * clears the undo stack to prevent the stack from getting out of sync with the current state.</p>
+	 * 
+	 * 
+	 * @playerversion Flash 10
+	 * @playerversion AIR 1.5
+ 	 * @langversion 3.0
+	 *
+	 * @see flashx.textLayout.edit.EditManager
+	 */
+	public class UndoManager implements IUndoManager
+	{
+		private var undoStack:Array;
+		private var redoStack:Array;
+		
+		private var _undoAndRedoItemLimit:int = 25;
+
+		/**
+		 * Creates an UndoManager object.
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */	
+		public function UndoManager()
+		{
+			undoStack = new Array();
+			redoStack = new Array();
+		}
+		
+		/**
+		 * @copy IUndoManager#clearAll()
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */	
+		public function clearAll():void
+		{
+			undoStack.length = 0;
+			redoStack.length = 0;			
+		}
+		
+		/**
+		 * @copy IUndoManager#canUndo()
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function canUndo():Boolean
+		{
+			return undoStack.length > 0;
+		}
+		
+		/**
+		 * @copy IUndoManager#peekUndo()
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function peekUndo():IOperation
+		{
+			return undoStack.length > 0 ? undoStack[undoStack.length-1] : null;
+		}
+		
+		/**
+		 * @copy IUndoManager#popUndo()
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function popUndo():IOperation
+		{
+			return IOperation(undoStack.pop());
+		}
+
+		/**
+		 * @copy IUndoManager#pushUndo()
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function pushUndo(operation:IOperation):void
+		{
+			undoStack.push(operation);
+			trimUndoRedoStacks();
+		}
+		
+		/**
+		 * @copy IUndoManager#canRedo()
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function canRedo():Boolean
+		{
+			return redoStack.length > 0;
+		}
+
+		/**
+		 * @copy IUndoManager#clearRedo()
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function clearRedo():void
+		{
+			redoStack.length = 0;
+		}
+
+		/**
+		 * @copy IUndoManager#peekRedo()
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function peekRedo():IOperation
+		{
+			return redoStack.length > 0 ? redoStack[redoStack.length-1] : null;
+		}
+		
+		/**
+		 * @copy IUndoManager#popRedo()
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function popRedo():IOperation
+		{
+			return IOperation(redoStack.pop());
+		}
+
+		/**
+		 * @copy IUndoManager#pushRedo()
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function pushRedo(operation:IOperation):void
+		{
+			redoStack.push(operation);
+			trimUndoRedoStacks();
+		}
+
+		/**
+		 * @copy IUndoManager#undoAndRedoItemLimit
+		 * @tiptext The maximum number of undoable or redoable operations to track. 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function get undoAndRedoItemLimit():int
+		{ return _undoAndRedoItemLimit; }
+		public function set undoAndRedoItemLimit(value:int):void
+		{ 
+			_undoAndRedoItemLimit = value;
+			trimUndoRedoStacks();
+		}
+
+		/** 
+		 * @copy IUndoManager#undo()
+		 * @see flashx.textLayout.edit.IEditManager#undo()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function undo():void
+		{
+			if (canUndo())
+			{
+				var undoOp:IOperation = popUndo();
+				undoOp.performUndo();
+			}
+		}
+		
+		/** 
+		 * @copy IUndoManager#redo()
+		 * 
+		 * @see flashx.textLayout.edit.IEditManager#redo()
+		 * 
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+ 	 	 * @langversion 3.0
+		 */
+		public function redo():void
+		{
+			if (canRedo())
+			{
+				var redoOp:IOperation = popRedo();
+				redoOp.performRedo();
+			}			
+		}									
+		
+		/** trim the sizes of the undo/redo stacks to the maximum limits */
+		private function trimUndoRedoStacks():void
+		{
+			// trim the undoStack and the redoStack so its in bounds 
+			var numItems:int = undoStack.length + redoStack.length;
+			if (numItems > _undoAndRedoItemLimit)
+			{
+				// trim redoStack first
+				var numToSplice:int = Math.min(numItems-_undoAndRedoItemLimit,redoStack.length);
+				if (numToSplice)
+				{
+					redoStack.splice(0,numToSplice);
+					numItems = undoStack.length+redoStack.length;
+				} 
+				// trim some undoable items
+				if (numItems > _undoAndRedoItemLimit)
+				{
+					numToSplice = Math.min(numItems-_undoAndRedoItemLimit,undoStack.length);
+					undoStack.splice(0,numToSplice);
+				}
+			}
+		}
+		
+	}
+}
diff --git a/textLayout_layout/.actionScriptProperties b/textLayout_layout/.actionScriptProperties
new file mode 100755
index 0000000..375eb43
--- /dev/null
+++ b/textLayout_layout/.actionScriptProperties
@@ -0,0 +1,64 @@
+# 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.
+
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<actionScriptProperties mainApplicationPath="textLayout_layout.as" projectUUID="f693cc15-9fd2-48a8-a0bd-ce309dda5fa0" version="6">
+  <compiler additionalCompilerArguments="-locale en_US -load-config+=../../config.xml" autoRSLOrdering="true" copyDependentFiles="false" generateAccessible="false" htmlExpressInstall="true" htmlGenerate="false" htmlHistoryManagement="false" htmlPlayerVersionCheck="true" includeNetmonSwc="false" outputFolderPath="bin" sourceFolderPath="src" strict="true" targetPlayerVersion="0.0.0" useApolloConfig="false" useDebugRSLSwfs="true" verifyDigests="true" warn="true">
+    <compilerSourcePath/>
+    <libraryPath defaultLinkType="0">
+      <libraryPathEntry kind="3" linkType="4" path="/textLayout_conversion/bin/textLayout_conversion.swc" useDefaultLinkType="true"/>
+      <libraryPathEntry kind="3" linkType="4" path="/textLayout_core/bin/textLayout_core.swc" useDefaultLinkType="true"/>
+      <libraryPathEntry kind="4" path="">
+        <excludedEntries>
+          <libraryPathEntry kind="1" linkType="1" path="${PROJECT_FRAMEWORKS}/locale/{locale}"/>
+          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/flex.swc" useDefaultLinkType="false"/>
+          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/sparkskins.swc" useDefaultLinkType="false"/>
+          <libraryPathEntry index="4" kind="3" linkType="4" path="${PROJECT_FRAMEWORKS}/libs/rpc.swc" useDefaultLinkType="true">
+            <crossDomainRsls>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="http://fpdownload.adobe.com/pub/swz/crossdomain.xml" rslUrl="http://fpdownload.adobe.com/pub/swz/flex/4.0.0.10485/rpc_4.0.0.10485.swz"/>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="" rslUrl="rpc_4.0.0.10485.swz"/>
+            </crossDomainRsls>
+          </libraryPathEntry>
+          <libraryPathEntry index="2" kind="3" linkType="4" path="${PROJECT_FRAMEWORKS}/libs/framework.swc" useDefaultLinkType="true">
+            <crossDomainRsls>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="http://fpdownload.adobe.com/pub/swz/crossdomain.xml" rslUrl="http://fpdownload.adobe.com/pub/swz/flex/4.0.0.10485/framework_4.0.0.10485.swz"/>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="" rslUrl="framework_4.0.0.10485.swz"/>
+            </crossDomainRsls>
+          </libraryPathEntry>
+          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/datavisualization.swc" useDefaultLinkType="false"/>
+          <libraryPathEntry index="1" kind="3" linkType="4" path="${PROJECT_FRAMEWORKS}/libs/textLayout.swc" useDefaultLinkType="true">
+            <crossDomainRsls>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="http://fpdownload.adobe.com/pub/swz/crossdomain.xml" rslUrl="http://fpdownload.adobe.com/pub/swz/flex/4.0.0.10485/textLayout_4.0.0.10485.swz"/>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="" rslUrl="textLayout_4.0.0.10485.swz"/>
+            </crossDomainRsls>
+          </libraryPathEntry>
+          <libraryPathEntry index="3" kind="3" linkType="4" path="${PROJECT_FRAMEWORKS}/libs/spark.swc" useDefaultLinkType="true">
+            <crossDomainRsls>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="http://fpdownload.adobe.com/pub/swz/crossdomain.xml" rslUrl="http://fpdownload.adobe.com/pub/swz/flex/4.0.0.10485/spark_4.0.0.10485.swz"/>
+              <crossDomainRslEntry autoExtract="true" policyFileUrl="" rslUrl="spark_4.0.0.10485.swz"/>
+            </crossDomainRsls>
+          </libraryPathEntry>
+          <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/utilities.swc" useDefaultLinkType="false"/>
+        </excludedEntries>
+      </libraryPathEntry>
+    </libraryPath>
+    <sourceAttachmentPath/>
+  </compiler>
+  <applications>
+    <application path="textLayout_layout.as"/>
+  </applications>
+  <modules/>
+  <buildCSSFiles/>
+</actionScriptProperties>
diff --git a/textLayout_layout/.flexLibProperties b/textLayout_layout/.flexLibProperties
new file mode 100755
index 0000000..1439998
--- /dev/null
+++ b/textLayout_layout/.flexLibProperties
@@ -0,0 +1,23 @@
+# 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.
+
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<flexLibProperties includeAllClasses="false" version="3">
+  <includeClasses>
+    <classEntry path="flashx.textLayout.LayoutClasses"/>
+  </includeClasses>
+  <includeResources/>
+  <namespaceManifests/>
+</flexLibProperties>
diff --git a/textLayout_layout/.project b/textLayout_layout/.project
new file mode 100755
index 0000000..213b3c8
--- /dev/null
+++ b/textLayout_layout/.project
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<projectDescription>
+	<name>textLayout_layout</name>
+	<comment></comment>
+	<projects>
+		<project>textLayout_conversion</project>
+		<project>textLayout_core</project>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.adobe.flexbuilder.project.flexbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.adobe.flexbuilder.project.flexlibnature</nature>
+		<nature>com.adobe.flexbuilder.project.actionscriptnature</nature>
+	</natures>
+</projectDescription>
diff --git a/textLayout_layout/src/flashx/textLayout/BuildInfoLayout.as b/textLayout_layout/src/flashx/textLayout/BuildInfoLayout.as
new file mode 100755
index 0000000..18f508a
--- /dev/null
+++ b/textLayout_layout/src/flashx/textLayout/BuildInfoLayout.as
@@ -0,0 +1,59 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout
+{
+	/**
+	 * Contains identifying information for the current build. 
+	 * This may not be the form that this information is presented in the final API.
+	 */
+	public class BuildInfoLayout
+	{		
+		[ExcludeClass]
+		/**
+		 * Contains the current version number. 
+		 */
+		public static const VERSION:String = "1.0";
+		
+		/**
+		 * Contains the current build number. 
+		 * It is static and can be called with <code>BuildInfo.kBuildNumber</code>
+		 * <p>String Format: "BuildNumber (Changelist)"</p>
+		 */
+		public static const kBuildNumber:String = "595 (738907)";
+		
+		/**
+		 * Contains the branch name. 
+		 */
+		public static const kBranch:String = "1.0";
+
+		/**
+		 * @private 
+		 */
+		public static const AUDIT_ID:String = "";
+		
+		/**
+		 * @private 
+		 */
+		public function dontStripAuditID():String
+		{
+			return AUDIT_ID;
+		}
+	}
+}
+
diff --git a/textLayout_layout/src/flashx/textLayout/LayoutClasses.as b/textLayout_layout/src/flashx/textLayout/LayoutClasses.as
new file mode 100755
index 0000000..6dcb20c
--- /dev/null
+++ b/textLayout_layout/src/flashx/textLayout/LayoutClasses.as
@@ -0,0 +1,33 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout
+{
+	internal class LayoutClasses
+	{
+		import flashx.textLayout.BuildInfoLayout; BuildInfoLayout;
+		
+		import flashx.textLayout.compose.LayoutFlowComposer; LayoutFlowComposer;
+		import flashx.textLayout.container.LayoutContainerController; LayoutContainerController;
+		import flashx.textLayout.container.IWrapManager; IWrapManager;
+		import flashx.textLayout.container.WrapManager; WrapManager;
+		
+		import flashx.textLayout.conversion.LayoutConfiguration; LayoutConfiguration;
+	}
+}
+
diff --git a/textLayout_layout/src/flashx/textLayout/compose/LayoutComposeState.as b/textLayout_layout/src/flashx/textLayout/compose/LayoutComposeState.as
new file mode 100755
index 0000000..a55ef76
--- /dev/null
+++ b/textLayout_layout/src/flashx/textLayout/compose/LayoutComposeState.as
@@ -0,0 +1,269 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{
+	import flash.display.DisplayObject;
+	import flash.display.DisplayObjectContainer;
+	import flash.display.Graphics;
+	import flash.display.Sprite;
+	import flash.geom.Rectangle;
+	import flash.text.engine.TextBaseline;
+	
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.container.IFloatController;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.FlowElement;
+	import flashx.textLayout.elements.FlowGroupElement;
+	import flashx.textLayout.elements.FlowLeafElement;
+	import flashx.textLayout.elements.InlineGraphicElement;
+	import flashx.textLayout.elements.InlineGraphicElementStatus;
+	import flashx.textLayout.elements.ParagraphElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.formats.BlockProgression;
+	import flashx.textLayout.formats.Float;
+	import flashx.textLayout.tlf_internal;
+		
+	use namespace tlf_internal;
+	
+	/** Keeps track of internal state during composition. 
+	 * 
+	 * This is the advanced layout version, used when there are floats, wraps, or columns.
+	 */
+	public class LayoutComposeState extends ComposeState 
+	{
+		// a single ComposeState that is checked out and checked in
+		static private var _sharedLayoutComposeState:LayoutComposeState;
+
+		/** @private */
+		static tlf_internal function getLayoutComposeState():LayoutComposeState
+		{
+			var rslt:LayoutComposeState = _sharedLayoutComposeState ? _sharedLayoutComposeState : new LayoutComposeState();
+			_sharedLayoutComposeState = null;
+			return rslt;
+		}
+		
+		/** @private */
+		static tlf_internal function releaseLayoutComposeState(state:ComposeState):void
+		{
+			if (_sharedLayoutComposeState == null)
+				_sharedLayoutComposeState = state as LayoutComposeState;
+		}
+		
+		public function LayoutComposeState()
+		{
+			super();
+		}
+		/** @private */
+		protected override function createParcelList():IParcelList
+		{
+			return LayoutParcelList.getLayoutParcelList();
+
+		}
+		/** @private */
+		protected override function releaseParcelList(list:IParcelList):void
+		{
+			LayoutParcelList.releaseLayoutParcelList(list);
+		}
+		
+		// Debugging code to show parcel edges - requires removing graphics.clear from ContainerControllerBase
+	/*	CONFIG::debug override public function composeTextFlow(textFlow:TextFlow):int
+		{
+			var value:int = super.composeTextFlow(textFlow);
+			var controller:ContainerController = textFlow.flowComposer.getControllerAt(0);
+			if (controller)
+			{
+				var container:Sprite = textFlow.flowComposer.getControllerAt(0).container as Sprite;
+				var graphics:Graphics = container.graphics;
+				graphics.clear();
+				graphics.lineStyle(1, 0xFF0000);
+				var boundsArray:Array = LayoutParcelList(_parcelList).getBounds();
+				for (var i:int = 0; i < boundsArray.length; ++i)
+				{
+					var bounds:Rectangle = boundsArray[i] as Rectangle;
+					graphics.moveTo(bounds.x, bounds.y);
+					graphics.lineTo(bounds.right, bounds.y);
+					graphics.lineTo(bounds.right, bounds.bottom);
+					graphics.lineTo(bounds.left, bounds.bottom);
+					graphics.lineTo(bounds.left, bounds.top);
+				}
+			}
+			
+			return value;
+		} */
+		
+		/* @private */
+		override protected function parcelHasChanged(newParcel:Parcel):void
+		{
+			if (_curParcel && newParcel && _curParcel.controller == newParcel.controller && _curParcel.column == newParcel.column)
+				vjDisableThisParcel = true;
+			super.parcelHasChanged(newParcel);
+		}
+		
+		/* @private */
+		protected override function composeFloat(elem:ContainerFormattedElement,composeFrame:ContainerController):void
+		{
+			elem.createGeometry(null);
+			// TODO: support arbitrary containers?
+			var floatContainer:DisplayObjectContainer = ContainerFormattedElement(elem).flowComposer.getControllerAt(0).container as DisplayObjectContainer;
+			// var floatContainer:DisplayObjectContainer = ContainerFormattedElement(elem).container as DisplayObjectContainer;
+			if (floatContainer != null) // is inline
+			{
+				if (!(composeFrame is IFloatController))
+					throw("need a float layout-capable controller!");
+				// Add as an inline, figure out the size of the inline, wrap around the inline
+				var parcelRect:Rectangle = IFloatController(composeFrame).computeInlineArea(floatContainer);
+
+				// See if it fits. If so, update the state to show the change. If not, remove the item.
+				if (parcelList.createParcel(parcelRect, elem.computedFormat.blockProgression, true /* next text goes below */))
+				{
+					floatContainer.x = parcelList.left;
+					floatContainer.y = parcelList.top;
+					floatContainer.height = parcelRect.height;
+					IFloatController(parcelList.controller).recordInlineChild(floatContainer);
+
+					//_contentAlignmentWidth = Math.max(_contentAlignmentWidth, parcelList.right);
+					parcelList.addTotalDepth(parcelRect.height);
+					parcelList.next();		 // advance to next parcel
+				}
+			}
+			
+			_curLineIndex = composeFrame.rootElement.getTextFlow().flowComposer.findLineIndexAtPosition(elem.getAbsoluteStart() + elem.textLength);
+			vjDisableThisParcel = true;
+			vjBeginLineIndex = _curLineIndex;
+		}
+
+		/*
+		 * Compose a floating graphic
+		 * 
+		 * @param elem	float we'e composing
+		 */
+		protected function composeFloatInline(elem:InlineGraphicElement):void
+		{
+			if (elem.elementHeight == 0 || elem.elementWidth == 0)		// can't compose yet -- graphic isn't ready
+				return;
+			
+			var containerElement:ContainerFormattedElement = elem.getAncestorWithContainer();
+			var blockProgression:String = containerElement.computedFormat.blockProgression;
+			
+		// HACK!!!
+		//	if the baselineZero is set to ideographicTop, then the descent is the point size (measured from ideographic top)
+		//	but in this case we've already factored that into the line height, so we're adding twice. Very confusing.
+			var effectiveLastLineDescent:Number = 0;
+			if (!isNaN(_lastLineDescent))
+				effectiveLastLineDescent = _lastLineDescent;
+			
+			var floatRect:Rectangle = new Rectangle(parcelList.left, parcelList.top, elem.elementWidth, elem.elementHeight);
+			if (blockProgression == BlockProgression.RL)
+			{				
+				floatRect.left -= effectiveLastLineDescent;
+				if (elem.float == Float.RIGHT)
+					floatRect.offset(0, (parcelList.bottom - elem.elementHeight) - floatRect.y);
+			}
+			else
+			{				
+				floatRect.bottom += effectiveLastLineDescent;
+				if (elem.float == Float.RIGHT)
+					floatRect.offset((parcelList.right - elem.elementWidth) - floatRect.x, 0);
+			}
+				
+			// See if it fits. If so, update the state to show the change. If not, remove the item.
+			if (parcelList.createParcelExperimental(floatRect, elem.float == Float.RIGHT ? "left" : "right"))
+			{
+				var graphic:DisplayObject = elem.graphic;
+				if (graphic)
+				{
+					IFloatController(parcelList.controller).recordInlineChild(graphic);
+					graphic.x = parcelList.left;
+					graphic.y = parcelList.top;
+					if (blockProgression == BlockProgression.TB)
+						graphic.y += effectiveLastLineDescent;
+				}
+
+				if (blockProgression == BlockProgression.TB)
+				{
+					parcelList.addTotalDepth(floatRect.height);
+					//_contentAlignmentWidth = Math.max(_contentAlignmentWidth, floatRect.width);
+					
+				}
+				else
+				{
+					parcelList.addTotalDepth(floatRect.width);
+					//_contentAlignmentWidth = Math.max(_contentAlignmentWidth, floatRect.height);					
+				}
+				parcelList.next();		 // advance to next parcel
+			}
+			
+		//	_curLineIndex = _curParcel.controller.rootElement.getTextFlow().getAbsoluteLineIndex(elem.getAbsoluteStart() + elem.textLength);
+			vjDisableThisParcel = true;
+		//	vjBeginLineIndex = _curLineIndex;
+		}
+		
+		// Called from composeParagraphElement when we are starting to compose a line. Has hooks to handle floats.
+		protected override function startLine():void
+		{
+			// Compose floats that appear at the start of the line, before processing any text. That way the following text will
+			// wrap correctly
+			if (_curElement is InlineGraphicElement && InlineGraphicElement(_curElement).float != Float.NONE)
+			{
+				var graphic:InlineGraphicElement = InlineGraphicElement(_curElement);
+				while (graphic && graphic.float != Float.NONE)
+				{
+					composeFloatInline(graphic);
+					graphic = graphic.getNextLeaf() as InlineGraphicElement;
+				}
+			}
+		}
+
+		// Called from composeParagraphElement when we are starting to compose a line. Has hooks to handle floats.
+		protected override function endLine():void
+		{
+			var currentOffset:int = _curElementOffset;
+			var currentElementStart:int = _curElementStart;
+			var element:FlowLeafElement = _curElement;
+			
+			// advance to the next element, using the rootElement of the container as a limitNode
+			// to prevent going past the content bound to this container
+			if (currentOffset >= element.textLength)
+			{
+				// We may have composed ahead over several spans; skip until we match up
+				// Loop until we use catch up to where the line we just composed ended (pos).
+				// Stop if we run out of elements. Skip empty inline elements, and skip floats
+				// that came at the start of the line before any text -- they've already been 
+				// processed.
+				var firstTextSpan:Boolean = true;
+				do{
+					if (element is InlineGraphicElement && InlineGraphicElement(element).float != Float.NONE)
+					{
+						if (!firstTextSpan)
+							composeFloatInline(element as InlineGraphicElement);
+					}
+					else firstTextSpan = false;
+					currentOffset -= element.textLength;
+					currentElementStart  += _curElement.textLength;
+					if (currentElementStart == _curParaStart+_curParaElement.textLength)
+					{
+						break;		// reached end of paragraph
+					}
+					element = element.getNextLeaf();
+				} while (element != null && (currentOffset >= element.textLength || element.textLength == 0 ));
+			}
+		}
+
+	}
+}
diff --git a/textLayout_layout/src/flashx/textLayout/compose/LayoutFlowComposer.as b/textLayout_layout/src/flashx/textLayout/compose/LayoutFlowComposer.as
new file mode 100755
index 0000000..5273d95
--- /dev/null
+++ b/textLayout_layout/src/flashx/textLayout/compose/LayoutFlowComposer.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 flashx.textLayout.compose
+{
+	import __AS3__.vec.Vector;
+	
+	import flash.display.Sprite;
+	
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.container.LayoutContainerController;
+	import flashx.textLayout.events.CompositionCompleteEvent;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+	
+	public class LayoutFlowComposer extends StandardFlowComposer
+	{
+		public function LayoutFlowComposer():void
+		{
+			super();
+		}
+		
+		/** @private */
+		tlf_internal override function getComposeState():ComposeState
+		{ return LayoutComposeState.getLayoutComposeState(); }
+		
+		/** @private */
+		tlf_internal override function releaseComposeState(state:ComposeState):void
+		{ LayoutComposeState.releaseLayoutComposeState(state); }
+		
+		// This override makes the LayoutComposer less efficient but is necessary or floats dissapear if updateAllControllers is called when scrolling
+		// is enabled on the last container.  The base class skips the compose but marks the controllers as needing update.  Since compose was skipped
+		// the inlineChildren arrays are empty and no inlines get composed.  This works around that problem.  A better solution is needed when inlines
+		// become first class and well supported.
+		tlf_internal override function callTheComposer(composeToPosition:int, controllerEndIndex:int):ContainerController
+		{				
+			var state:ComposeState = getComposeState();
+			
+			var lastComposedPosition:int = state.composeTextFlow(textFlow, composeToPosition, controllerEndIndex);
+			if (_damageAbsoluteStart < lastComposedPosition)
+				_damageAbsoluteStart = lastComposedPosition;
+			CONFIG::debug { checkFirstDamaged(); }
+			
+			// make sure there is an empty TextFlowLine covering any trailing content
+			finalizeLinesAfterCompose();
+			
+			releaseComposeState(state);
+							
+			textFlow.dispatchEvent(new CompositionCompleteEvent(CompositionCompleteEvent.COMPOSITION_COMPLETE,false,false,textFlow, 0,lastComposedPosition));
+
+			CONFIG::debug { textFlow.debugCheckTextFlow(); }
+			// TODO: optimize to the first damaged controller
+			return getControllerAt(0);
+		}
+	}
+}
+
diff --git a/textLayout_layout/src/flashx/textLayout/compose/LayoutParcelList.as b/textLayout_layout/src/flashx/textLayout/compose/LayoutParcelList.as
new file mode 100755
index 0000000..31544f9
--- /dev/null
+++ b/textLayout_layout/src/flashx/textLayout/compose/LayoutParcelList.as
@@ -0,0 +1,684 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.compose
+{
+	import flash.geom.Matrix;
+	import flash.geom.Point;
+	import flash.geom.Rectangle;
+	
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.container.IFloatController;
+	import flashx.textLayout.container.IWrapManager;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.formats.BlockProgression;
+	
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;		
+	/** The area inside a text container is sub-divided into smaller areas available for
+	 * text layout. These smaller areas within the container are called Parcels. The 
+	 * ParcelList manages the parcel associated with a TextFlow during composition.
+	 * 
+	 * A container will always have at least one parcel, which corresponds to the container's
+	 * bounding box. If the container has more than one column, each column appears as
+	 * a parcel in the parcel list. If the container has wrap applied, the area around the
+	 * wrap that is available for layout is divided into rectangular-shaped parcels.
+	 * Lastly, parcels may be created during composition for use by flow elements that require
+	 * layout within a specific geometry that may not be the same as the columns: for instance, 
+	 * a straddle head, a table, or a sidehead.
+	 */
+	internal class LayoutParcelList extends ParcelList
+	{	
+		/** This is a list of the wraps, or parcels that are NOT available for text layout. */
+		private var wraps:Array;	/* of Rectangle */
+		
+		/** Inlines can extend across columns, so we have a separate parcel list
+			that is independent of columns (just has container bboxes) used for
+			creating new parcels that can extend across columns. */
+		// private var inlineWrap:LayoutParcelList;
+	
+		/** minimum allowable width of a line */
+		private static const MIN_WIDTH:Number = 40;
+		
+		// a single parcellist that is checked out and checked in
+		static private var _sharedLayoutParcelList:LayoutParcelList;
+
+		/** @private */
+		static tlf_internal function getLayoutParcelList():LayoutParcelList
+		{
+			var rslt:LayoutParcelList = _sharedLayoutParcelList ? _sharedLayoutParcelList : new LayoutParcelList();
+			_sharedLayoutParcelList = null;
+			return rslt;
+		}
+		
+		/** @private */
+		static tlf_internal function releaseLayoutParcelList(list:IParcelList):void
+		{
+			if (_sharedLayoutParcelList == null)
+			{
+				_sharedLayoutParcelList = list as LayoutParcelList;
+				if (_sharedLayoutParcelList)
+					_sharedLayoutParcelList.releaseAnyReferences();
+			}
+		}
+			
+		/** Constructor */
+		public function LayoutParcelList()
+		{
+			super();
+		}
+
+		/** prevent any leaks. @private */
+		tlf_internal override function releaseAnyReferences():void
+		{
+			super.releaseAnyReferences();
+			wraps = null;
+		}
+				
+		override protected function addOneControllerToParcelList(controllerToInitialize:ContainerController):void
+		{
+			super.addOneControllerToParcelList(controllerToInitialize);
+			if (controllerToInitialize is IFloatController)
+			{
+				if (IFloatController(controllerToInitialize).wraps)
+					this.wraps = IFloatController(controllerToInitialize).wraps.wraps;
+				for each (var wrapExclude:Rectangle in wraps)
+					addWrap(wrapExclude, controllerToInitialize, false /* wrap around the sides */);
+			}
+		}
+
+		private function isNextAdjacent():Boolean
+		{
+			// trace("LPL: isNextAdjacent");
+			CONFIG::debug { assert(_currentParcelIndex >= 0 && _currentParcelIndex < numParcels, "invalid _currentParcelIndex in ParcelList"); }
+			if (_currentParcelIndex + 1 >= numParcels)
+				return false;
+			var nextParcel:Parcel = getParcelAtIndex(_currentParcelIndex + 1);
+			if(_blockProgression != BlockProgression.RL)
+			{
+				if (_currentParcel.bottom != nextParcel.top || _currentParcel.left > nextParcel.right)
+					return false;
+			} 
+			else
+			{
+				if(_currentParcel.left != nextParcel.right || _currentParcel.top > nextParcel.bottom)
+					return false;
+			}
+			return true;
+		}
+
+		private function getBBox(controller:ContainerController):Rectangle
+		{
+			// trace("LPL: getBBox");
+			var bbox:Rectangle = null;
+			for (var idx:int = 0; idx < numParcels; idx++)
+			{
+				var p:Parcel = getParcelAtIndex(idx);
+				if (p.controller == controller)
+				{
+					if (!bbox)
+						bbox = p.clone();
+					else
+						bbox = bbox.union(p);
+				}					
+			}
+			return bbox;
+		}
+		
+		private function intersects(r:Rectangle, rectArray:Array):Boolean
+			// true if r intersects any of the rectangles in rectArray
+		{
+			// trace("LPL: getBBox");
+			if (rectArray)
+			{
+				for each (var i:Rectangle in rectArray)
+				{
+					if (i.intersects(r))
+						return true;
+				}
+			}
+			return false;
+		}
+		
+			/** @private */
+		override public function createParcel(parcel:Rectangle, blockProgression:String, verticalJump:Boolean):Boolean
+			// If we can get the requested parcel to fit, create it in the parcels list
+		{
+			// trace("LPL: createParcel");
+		//	trace("createParcel start", parcel.toString());
+		//	traceOut();
+			
+			var fitRect:Rectangle = new Rectangle();
+			do {
+				getLineSlug(fitRect,parcel.height);
+				if (!fitRect || atEnd())	// Can't find contiguous vertical space for the parcel
+					return false;
+				else 
+				{
+					if (blockProgression == BlockProgression.TB)
+						parcel.offset(0, fitRect.top - parcel.top);		// parcel location may have been adjusted by getLineSlug
+					else
+						parcel.offset(fitRect.left - parcel.left, 0);		// parcel location may have been adjusted by getLineSlug
+
+					if (fitRect.width >= parcel.width)
+						break;		// found enough vertical & horizontal space
+
+					// Found vertical space, but not enough horizontal.
+					// It could be that parcel would fit across contiguous columns. Check for a wrap.
+					// Check that it fits within the bounding box for the container, 
+					// and doesn't intersect any wraps	
+					var bbox:Rectangle = getBBox(_currentParcel.controller);
+					if (bbox.containsRect(parcel) && !intersects(parcel, wraps))
+						break;
+
+					next();		// keep looking in other parcels
+
+					if (_currentParcelIndex >= numParcels)
+						return false;		// hit the end: space not found
+				}
+			} while (fitRect.width < parcel.width);
+				
+			// Create a new parcel, and insert it in the correct location in the parcels array
+			var targetController:ContainerController = _currentParcel.controller;
+			addWrap(parcel, targetController, verticalJump /* jumpOver */);
+			for (var l:int = 0; l < numParcels; l++)
+			{
+				var testParcel:Parcel = getParcelAtIndex(l);
+				if (testParcel.top > parcel.top && 
+					!((testParcel.left > parcel.right) || (testParcel.right < parcel.left)))
+				{
+					if (testParcel.controller == targetController)
+						break;
+				}
+			}
+			var splitParcel:Parcel = getParcelAtIndex(l);
+			var splitCoverage:int = splitParcel.columnCoverage;
+			
+			// clear top of column splitParcel is not that anymore
+			splitParcel.columnCoverage = splitCoverage & ~Parcel.TOP_OF_COLUMN;
+			// we're inserting before so its bot_of_column - we aren't
+			insertParcel(l,new Parcel(parcel.x, parcel.y, parcel.width, parcel.height, targetController, splitParcel.column, splitCoverage&~Parcel.BOT_OF_COLUMN));
+
+			// Set the current parcel to be the one we just added
+			_currentParcelIndex = l;
+			_currentParcel = getParcelAtIndex(l);
+			
+	//		trace("createParcel done");
+	//		traceOut();
+				
+			return true;
+		}
+
+		/** @private */
+		override public function getLineSlug(slugRect:Rectangle,height:Number, minWidth:Number = 0):Boolean
+		{
+			return (_currentParcelIndex < numParcels) && getWidthInternal(slugRect, height, minWidth);
+		}
+		
+		/**Helper function for getLineSlug, used internally. Similar to getWidth, but
+		 * although it allows a line to extend across parcels, if necessary, the line
+		 * will always start in the current parce. If a line does not fit starting
+		 * from the current parcel, this function (unlike getWidth) will return
+		 * 0 instead of changing the parcel.
+		 * @param height	amount of contiguous vertical space that must be available
+		 * @param minWidth	amount of contiguous horizontal space that must be available 
+		 * @return amount of contiguous horizontal space actually available
+		 */
+		private function getWidthInternal(slugRect:Rectangle, height:Number, minWidth:Number):Boolean
+		{
+			// trace("LPL: getWidthInternal");
+			CONFIG::debug { assert(_currentParcelIndex >= 0 && _currentParcelIndex < numParcels, "invalid position in ParcelList"); }
+			
+			// See if it fits in the current parcel
+			var tileWidth:Number = getComposeWidth(_currentParcel);
+			if (tileWidth <= minWidth)
+				return false;
+			var requiredHeight:Number = currentParcel.fitAny ? 1 : height;
+			if (currentParcel.composeToPosition || _totalDepth + requiredHeight <= getComposeHeight(_currentParcel))
+			{
+				if (this._blockProgression != BlockProgression.RL)
+				{
+					slugRect.x = left;
+					slugRect.y = _currentParcel.top + _totalDepth;
+					slugRect.width = tileWidth;
+					slugRect.height = height;
+				}
+				else
+				{
+					slugRect.x = left;
+					slugRect.y = _currentParcel.top;
+					slugRect.width = _currentParcel.width-_totalDepth;
+					slugRect.height = tileWidth;
+				}
+				return true;
+			}
+
+			// This tile won't fit in the parcel. Look at the next parcel(s) that are adejacent,
+			// as many as are required fit the tile. The width of the tile will be the minimum
+			// of this list. If the width of the tile is less than the minimum specified by the 
+			// caller, or if there aren't enough adejacent parcels to fit the tile, 
+			// return 0 to indicate the tile doesn't fit in the parcel. The client code can try 
+			// again on the next parcel.
+			var offset:Number = getComposeHeight(_currentParcel) - _totalDepth;
+			var heightRemaining:Number = height - offset;
+			var leftEdge:Number = _currentParcel.left;
+			var rightEdge:Number = _currentParcel.right;
+			var topEdge:Number = _currentParcel.top;
+			if (_blockProgression == BlockProgression.RL)
+				rightEdge -= _totalDepth;
+			else
+				topEdge += _totalDepth;
+			do 
+			{
+				// Next parcel isn't adejacent. We can't fit the tile.
+				if (!isNextAdjacent())
+					return false;
+				next();
+				tileWidth = Math.min(tileWidth, getComposeWidth(_currentParcel));
+				if (tileWidth <= minWidth)
+					return false;	// try again on next tile
+				var newDepth:Number;
+				if (_blockProgression == BlockProgression.RL)
+				{
+					topEdge = Math.max(topEdge, _currentParcel.top);
+					newDepth = -(height - heightRemaining);
+					heightRemaining -= Math.min(heightRemaining, _currentParcel.width);
+				}
+				else
+				{
+					leftEdge = Math.max(leftEdge, _currentParcel.left);
+					newDepth = -(height - heightRemaining);
+					heightRemaining -= Math.min(heightRemaining, _currentParcel.height);
+				}
+			} while (heightRemaining > 0)
+
+			_totalDepth = newDepth;
+			_hasContent = true;
+			
+			slugRect.x = leftEdge;
+			slugRect.y = topEdge;
+			if (_blockProgression == BlockProgression.RL)
+			{
+				slugRect.x = rightEdge - height;
+				slugRect.width = height;
+				slugRect.height = tileWidth;
+			}
+			else
+			{
+				slugRect.width = tileWidth;
+				slugRect.height = height;
+			}
+			return true;
+		}
+		
+		private function getSlugParcel(parcel:Rectangle, blockProgression:String):Rectangle
+		{
+			var fitRect:Rectangle = new Rectangle();
+			do {
+				getLineSlug(fitRect,parcel.height);
+				if (!fitRect || atEnd())	// Can't find contiguous vertical space for the parcel
+					return null;
+				else 
+				{
+					if (blockProgression == BlockProgression.TB)
+						parcel.offset(0, fitRect.top - parcel.top);		// parcel location may have been adjusted by getLineSlug
+					else
+						parcel.offset(fitRect.right - parcel.right, 0);		// parcel location may have been adjusted by getLineSlug
+
+					if (fitRect.width >= parcel.width)
+						break;		// found enough vertical & horizontal space
+
+					// Found vertical space, but not enough horizontal.
+					// It could be that parcel would fit across contiguous columns. Check for a wrap.
+					// Check that it fits within the bounding box for the container, 
+					// and doesn't intersect any wraps	
+					var bbox:Rectangle = getBBox(_currentParcel.controller);
+					if (bbox.containsRect(parcel) && !intersects(parcel, wraps))
+						break;
+
+					next();		// keep looking in other parcels
+
+					if (_currentParcelIndex >= numParcels)
+						return null;		// hit the end: space not found
+				}
+			} while (fitRect.width < parcel.width);
+			return parcel;			
+		}
+		
+		public const NONE:String = "none";			// don't wrap -- allow overlap
+		public const LEFT:String = "left";			// allow text to the left
+		public const RIGHT:String = "right";		// allow text to the right
+	//	public const BIGGEST:String = "biggest";	// wrap either left or right, whichever is a bigger space - not yet supported
+	//	public const BOTH:String = "both";			// "allow text on left and right - BUT jump-overs not supported
+				
+			/** @private */
+		override public function createParcelExperimental(parcel:Rectangle, wrapType:String) : Boolean
+		{
+			// trace("LPL: createParcel");
+		//	trace("createParcel start", parcel.toString());
+		//	traceOut();			
+			parcel = getSlugParcel(parcel, _blockProgression);
+			if (!parcel)
+				return false;	// doesn't fit
+			
+			
+		//	trace("before");
+		//	traceOut();
+		//	trace("parcel", parcel.toString());
+
+			var p:Parcel = getParcelAtIndex(0);
+			var rotationPoint:Point = new Point(p.left, p.top);
+			if (_blockProgression == BlockProgression.RL)
+			{
+				// rotate parcels to TB orientation
+				for (var i:int = 0; i < numParcels; i++)
+				{
+					p = getParcelAtIndex(i);
+					p.replaceBounds(transformRect(p, rotationPoint, true));
+				}	
+				parcel = transformRect(parcel, rotationPoint, true);
+			}
+
+			// Create a new parcel, and insert it in the correct location in the parcels array
+			var targetController:ContainerController = _currentParcel.controller;
+			addWrapExperimental(parcel, targetController, wrapType);
+			_currentParcelIndex = numParcels;
+			_currentParcel = null;
+			for (var l:int = 0; l < numParcels; l++)
+			{
+				p = getParcelAtIndex(l);
+				if (p.equals(parcel))
+				{
+					_currentParcelIndex = l;
+					_currentParcel =  p;
+					break;
+				}
+			}
+			CONFIG::debug { assert (_currentParcelIndex != numParcels, "New parcel not current!"); }
+			
+			if (_blockProgression == BlockProgression.RL)
+			{
+				// rotate back
+				parcel = transformRect(parcel, rotationPoint, false);				
+				for (i = 0; i < numParcels; i++)
+				{
+					p = getParcelAtIndex(i);
+					p.replaceBounds(transformRect(p, rotationPoint, false));
+				}
+			}
+			
+		//	trace("createParcel done");
+		//	traceOut();
+				
+			return true;			
+		}
+		
+		private function transformRect(r:Rectangle, rotationPoint:Point, up:Boolean):Rectangle
+		{
+			var dx:Number = r.x - rotationPoint.x;
+			var dy:Number = (up ? r.y : r.bottom) - rotationPoint.y;
+			if (up)
+				return new Rectangle((rotationPoint.x + dy), (rotationPoint.y - dx) - r.width, r.height, r.width);
+			return new Rectangle((rotationPoint.x - dy), (rotationPoint.y + dx), r.height, r.width);
+		}
+		
+		
+		private function addWrapExperimental(wrap:Rectangle, controller:ContainerController, wrapType:String):void
+		{
+		//	trace("addWrap", wrap.toString());
+		//	traceOut();
+			
+			// Subtracts the wrap from the space available for laying out text.
+			var insertWrap:Boolean = true;
+			var newparcels:Array = new Array();	/* of Parcel */
+			for (var idx:int = 0; idx < numParcels; idx++)
+			{
+				var p:Parcel = getParcelAtIndex(idx);
+				if (p.controller == controller && wrap.intersects(p))
+				{
+					// If the wrap intersects the area, return the unintersected 
+					// part of the area as an array of parcels that replaces
+					// the area. If the area is entirely contained within the wrap,
+					// this will remove the area.
+					//
+					// If the wrap appears inside the area, pick the larger side
+					// to be in the area, and let the smaller side drop out as if
+					// it were part of the wrap. Note that this means we do not
+					// support jump-overs.
+					unintersectExperimental(newparcels, p, wrap, wrapType, insertWrap);
+					insertWrap = false;
+				}
+				else
+					newparcels.push(p);
+			}
+			
+			
+		        // Keep track of the number of wraps per text frame.  It is needed to for vertical alignment.
+		    if (controller.container is IFloatController)
+				IFloatController(controller.container).numWraps++;
+			
+			parcels = newparcels;
+			CONFIG::debug { validate(); }
+		//	trace("after");
+		//	traceOut();
+		}
+		
+		private function unintersectExperimental(result:Array, parcel:Parcel, wrap:Rectangle, wrapType:String, insertWrap:Boolean):void
+		{
+			var area:Rectangle = parcel;
+			// trace("LPL: unintersect");
+			var columnCoverage:int = parcel.columnCoverage;
+						
+			// Return the unintersected part of the area that wrap does not
+			// intersect as an array of parcels
+			var r:Rectangle = area.intersection(wrap);
+			
+			// split into zero, one, two or three chunks
+			var addTopParcel:Boolean = r.top > area.top;
+			var addMidParcel:Boolean = ((r.left - area.left > Math.max(area.right - r.right, MIN_WIDTH)) || (area.right > r.right && area.right - r.right > MIN_WIDTH));
+			var addBotParcel:Boolean = area.bottom > r.bottom;
+			
+			var newCoverage:int;	// scratch for computing coverage
+			
+			var parcelRect:Rectangle;
+			
+			// Space above the intersection
+			if (addTopParcel)
+			{
+				newCoverage = columnCoverage;
+				if (addBotParcel || addMidParcel)
+					newCoverage &= ~Parcel.BOT_OF_COLUMN;
+				columnCoverage &= ~Parcel.TOP_OF_COLUMN;
+				
+				result.push(new Parcel(area.left, area.top, area.width, r.top - area.top, parcel.controller, parcel.column, newCoverage));
+			}
+
+			newCoverage = columnCoverage;
+			if (addBotParcel)
+				newCoverage &= ~Parcel.BOT_OF_COLUMN;
+			columnCoverage &= ~Parcel.TOP_OF_COLUMN;
+
+			// Push our parcel
+			if (insertWrap)
+				result.push(new Parcel(wrap.x, wrap.y, wrap.width, wrap.height, parcel.controller, parcel.column, newCoverage));
+			
+			// Allocate space beside the parcel, depending on wrapType
+			if (wrapType == LEFT)
+			{
+				if (r.left - area.left  > MIN_WIDTH)
+					result.push(new Parcel(area.left, r.top, r.left - area.left, r.height, parcel.controller, parcel.column, newCoverage));
+		}
+			if (wrapType == RIGHT)
+			{
+				if (area.right - r.right  > MIN_WIDTH)
+					result.push(new Parcel(r.right, r.top, area.right - r.right, r.height, parcel.controller, parcel.column, newCoverage));
+			}
+
+			// Space along the bottom
+			if (addBotParcel)
+				result.push(new Parcel(area.left, r.bottom, area.width, area.bottom - r.bottom, parcel.controller, parcel.column, columnCoverage));
+		}
+
+		private function addWrap(wrap:Rectangle, controller:ContainerController, verticalJump:Boolean):void
+		{
+			// trace("LPL: addWrap");
+		//	trace("addWrap", wrap.toString());
+		//	trace("before");
+		//	traceOut();
+			
+			// Subtracts the wrap from the space available for laying out text.
+			var newparcels:Array = new Array();	/* of Parcel */
+			for (var idx:int = 0; idx < numParcels; idx++)
+			{
+				var p:Parcel = getParcelAtIndex(idx);
+				if (p.controller == controller && wrap.intersects(p))
+				{
+					// If the wrap intersects the area, return the unintersected 
+					// part of the area as an array of parcels that replaces
+					// the area. If the area is entirely contained within the wrap,
+					// this will remove the area.
+					//
+					// If the wrap appears inside the area, pick the larger side
+					// to be in the area, and let the smaller side drop out as if
+					// it were part of the wrap. Note that this means we do not
+					// support jump-overs.
+					unintersect(newparcels, p, wrap, verticalJump);
+				//	verticalJump = false; // Yuck! Turning off multiple insertions
+				}
+				else
+					newparcels.push(p);
+			}
+			
+			
+		        // Keep track of the number of wraps per text frame.  It is needed to for vertical alignment.
+		    if (controller.container is IFloatController)
+				IFloatController(controller.container).numWraps++;
+			
+			parcels = newparcels;
+			CONFIG::debug { validate(); }
+		//	trace("after");
+		//	traceOut();
+		}
+		
+		private function unintersect(result:Array, parcel:Parcel, wrap:Rectangle, verticalJump:Boolean):void
+		{
+			// trace("LPL: unintersect");
+			var area:Rectangle = parcel;
+			var columnCoverage:int = parcel.columnCoverage;
+			
+			// Return the unintersected part of the area that wrap does not
+			// intersect as an array of parcels
+			var r:Rectangle = area.intersection(wrap);
+			
+			// split into zero, one, two or three chunks
+			var addTopParcel:Boolean = r.top > area.top;
+			var addMidParcel:Boolean = !verticalJump && ((r.left - area.left > Math.max(area.right - r.right, MIN_WIDTH)) || (area.right > r.right && area.right - r.right > MIN_WIDTH));
+			var addBotParcel:Boolean = area.bottom > r.bottom;
+			
+			var newCoverage:int;	// scratch for computing coverage
+			
+			// Space above the intersection
+			if (addTopParcel)
+			{
+				newCoverage = columnCoverage;
+				if (addBotParcel || addMidParcel)
+					newCoverage &= ~Parcel.BOT_OF_COLUMN;
+				columnCoverage &= ~Parcel.TOP_OF_COLUMN;
+				
+				result.push(new Parcel(area.left, area.top, area.width, r.top - area.top, parcel.controller, parcel.column, newCoverage));
+			}
+			// Space along the left side of the intersection, if the width is great than on the right
+			if (addMidParcel)
+			{
+				newCoverage = columnCoverage;
+				if (addBotParcel)
+					newCoverage &= ~Parcel.BOT_OF_COLUMN;
+				columnCoverage &= ~Parcel.TOP_OF_COLUMN;
+				
+				if (r.left - area.left > Math.max(area.right - r.right, MIN_WIDTH))
+					result.push(new Parcel(area.left, r.top, r.left - area.left, r.height, parcel.controller,  parcel.column, newCoverage));
+				// Space along the right side if that's bigger
+				else // if (area.right > r.right && area.right - r.right > MIN_WIDTH)
+					result.push(new Parcel(r.right, r.top, area.right - r.right, r.height, parcel.controller, parcel.column, newCoverage));
+			}
+			// Space along the bottom
+			if (addBotParcel)
+				result.push(new Parcel(area.left, r.bottom, area.width, area.bottom - r.bottom, parcel.controller, parcel.column, columnCoverage));
+		}
+
+		/** @private */
+		CONFIG::debug private function validate():void
+		{
+			// Check that there are no empty parcels, and that no parcels intersect any other parcel.
+			for (var idx:int; idx < numParcels; idx++)
+			{
+				var i:Parcel = getParcelAtIndex(idx);
+				var parcelRect:Rectangle = i;
+				
+				assert(parcelRect.height != 0 && parcelRect.width != 0, "empty parcel");
+			//	assert(parcelRect.width > MIN_WIDTH, "parcel too small"); we can get a small parcel if we explicitly ask for it (e.g., for a small float)
+				for (var nidx:int; nidx < numParcels; nidx++)
+				{
+					var n:Parcel = getParcelAtIndex(nidx);
+					assert(i == n || i.controller != n.controller || !parcelRect.intersects(n), "parcels intersect");
+				}
+			}
+		}
+		
+		CONFIG::debug {
+			private function traceOut():void
+			{
+				trace("parcels\n");
+				for (var idx:int; idx < numParcels; idx++)
+				{
+					var p:Parcel = getParcelAtIndex(idx);
+					trace(idx.toString(), ":", p, "controller", p.controller);
+				}
+		//		traceRects("wraps\n", wraps);
+			}
+		}
+
+		CONFIG::debug {
+			private function traceRects(description:String, rects:Array):void
+			{
+				trace(description);
+				var count:int = 0;
+				for each (var i:Rectangle in rects)
+				{
+					trace(count.toString(), i);
+					count++;
+				}
+			}
+		}
+		
+		CONFIG::debug {
+			private function traceParcels(description:String, parcels:Array /* of Parcel */):void
+			{
+				trace(description);
+				var count:int = 0;
+				for each (var i:Parcel in parcels)
+				{
+					trace(count.toString(), ":", i, "controller", i.controller);
+					count++;
+				}
+			}
+		}
+
+	}	//end class
+} //end package
diff --git a/textLayout_layout/src/flashx/textLayout/container/IFloatController.as b/textLayout_layout/src/flashx/textLayout/container/IFloatController.as
new file mode 100755
index 0000000..1b87cd5
--- /dev/null
+++ b/textLayout_layout/src/flashx/textLayout/container/IFloatController.as
@@ -0,0 +1,41 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.container
+{
+	import flash.display.DisplayObject;
+	import flash.display.DisplayObjectContainer;
+	import flash.geom.Rectangle;
+
+	import flashx.textLayout.container.IWrapManager;
+	
+	/** Controllers that support floats inside the container implement this interface. */
+	public interface IFloatController
+	{
+		/** Add a float to the container. */
+		function recordInlineChild(value:DisplayObject):void;
+
+		/** Figure out how much space a float will require. */
+		function computeInlineArea(value:DisplayObject):Rectangle;		
+
+		function get wraps():IWrapManager;
+		function set wraps(wrapsValue:IWrapManager):void;
+		function get numWraps():int;
+		function set numWraps(value:int):void;
+	}
+}
\ No newline at end of file
diff --git a/textLayout_layout/src/flashx/textLayout/container/IWrapManager.as b/textLayout_layout/src/flashx/textLayout/container/IWrapManager.as
new file mode 100755
index 0000000..14aa9ee
--- /dev/null
+++ b/textLayout_layout/src/flashx/textLayout/container/IWrapManager.as
@@ -0,0 +1,31 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.container
+{
+[ExcludeClass]
+	/** @private The wrap manager keeps track of rectangular text wrap regions.
+	 * A wrap manager keeps track of a list of wraps. 
+	 */
+	public interface IWrapManager
+	{		
+		/** Array of rectangular wraps. Each entry is expected to be a flash rectangle object. */
+		function get wraps():Array;
+		function set wraps(wrapsValue:Array):void;
+	}
+}
\ No newline at end of file
diff --git a/textLayout_layout/src/flashx/textLayout/container/LayoutContainerController.as b/textLayout_layout/src/flashx/textLayout/container/LayoutContainerController.as
new file mode 100755
index 0000000..3de23db
--- /dev/null
+++ b/textLayout_layout/src/flashx/textLayout/container/LayoutContainerController.as
@@ -0,0 +1,253 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.container
+{
+	import flash.display.DisplayObject;
+	import flash.display.DisplayObjectContainer;
+	import flash.display.Sprite;
+	import flash.geom.Rectangle;
+	
+	import flashx.textLayout.compose.IFlowComposer;
+	import flashx.textLayout.compose.LayoutFlowComposer;
+	import flashx.textLayout.conversion.LayoutConfiguration;
+	import flashx.textLayout.debug.assert;
+	import flashx.textLayout.elements.ContainerFormattedElement;
+	import flashx.textLayout.elements.TextFlow;
+	import flashx.textLayout.tlf_internal;
+	
+	use namespace tlf_internal;
+	
+
+	[ExcludeClass]
+	/** @private
+	 *  A container controller to be used for TextFlows that require extended feature set.
+	 */
+	public class LayoutContainerController extends ContainerController implements IFloatController
+	{
+		private var inlineChildren:Array;
+		private var lastInlineChildren:Array = []; // inlineChildren during the last compose pass
+
+		private var _wrapList:IWrapManager;
+				
+		// Composition Results
+		private var _numWraps:int;		// number of wraps in this text frame
+		
+		/** Constructor - creates a new LayoutContainerController instance.
+		 *
+		 * @param cont The DisplayObjectContainer in which to manage the text lines.
+		 * @param compositionWidth The initial width for composing text in the container.
+		 * @param compositionHeight The initial height for composing text in the container.
+		 *
+		 * @playerversion Flash 10
+		 * @playerversion AIR 1.5
+		 * @langversion 3.0
+		 */
+		 
+		public function LayoutContainerController(container:Sprite,compositionWidth:Number=100,compositionHeight:Number=100):void
+		{
+			super(container, compositionWidth, compositionHeight);
+		}
+		
+		public function get wraps():IWrapManager
+		{
+			return _wrapList;
+		}
+		
+		public function set wraps(wrapsValue:IWrapManager):void
+		{
+			if (!(flowComposer is LayoutFlowComposer))
+				throw new Error("Layout feature set requires LayoutConfiguration");
+				
+			_wrapList = wrapsValue;
+			invalidateContents();
+		}
+
+		public function get numWraps():int
+		{
+			return _numWraps;
+		}
+		
+		public function set numWraps(value:int):void
+		{
+			_numWraps = value;
+		}
+			/** @private */
+		override tlf_internal function setRootElement(value:ContainerFormattedElement):void
+		{
+			if (value && wraps != null && !(flowComposer is LayoutFlowComposer))
+				throw new Error("Layout feature set requires LayoutConfiguration");
+				
+			super.setRootElement(value);
+		}						
+
+		/** Find the container of the position in the flow */
+		//--------------------------------------------------------------------------
+		//
+		//  Inlines
+		//
+		//--------------------------------------------------------------------------
+
+		/** inlines */
+		private function addInlineChild(child:DisplayObject):void
+		{
+			if (!container.contains(child))
+			{
+ 				container.addChildAt(child,container.numChildren>0 ? container.numChildren-1 : 0);
+ 			}
+		}
+		private function removeInlineChild(child:DisplayObject):void
+		{
+			// If the graphic was switched from float to inline ("none"), then it has been reparented to a TextLine,
+			// which causes it not to be a child of the container anymore. We catch this as an exception that we handle.
+			try
+			{
+				container.removeChild(child);
+			}
+			catch(e:Error)
+			{
+				if (e.errorID != 2025)
+					throw e;
+			}
+		}
+
+		public function recordInlineChild(value:DisplayObject):void
+		{
+			if (!inlineChildren)
+				inlineChildren = [];
+			else if (inlineChildren.indexOf(value) != -1)
+				return;	// don't read it
+			inlineChildren.push(value);
+		}
+
+		public function computeInlineArea(value:DisplayObject):Rectangle
+		{
+			// HACK
+			var vbc:TextLayoutBaseContainer = value as TextLayoutBaseContainer;
+			if (vbc)
+			{
+				vbc.validateSize();
+				return new Rectangle(0, 0, vbc.width, vbc.height);
+			}
+
+			var cont:DisplayObjectContainer = value as DisplayObjectContainer;
+			
+			// HACK Currently using a few weak typing tricks to play
+			// nicely with Flex components without compiler dependencies.
+			// Undoubtedly there's a better way to do this.
+			if (cont.hasOwnProperty("validateNow"))
+				cont["validateNow"].call(cont);
+			
+			// This moves the container from the rawChildren into the parent container for the purpose of layout
+			// It gets moved back later in updateCompositionShapes/createShapes
+			// TODO: don't do this as its really expensive and forced a complete redraw
+			// cont.includeInLayout = false;
+			if (cont.hasOwnProperty("includeInLayout"))
+				cont["includeInLayout"] = false;
+			// TEMP - force add and remove
+			// if (container.parent != this && container.parent != null)
+			if (cont.parent)
+				cont.parent.removeChild(cont);
+				
+			if (isDamaged())
+			{
+				// temporary hack until appropriate interface is determined
+				if (cont.hasOwnProperty("invalidateSize"))
+					Function(cont["invalidateSize"]).call(cont);
+				//cont.invalidateSize();
+			}
+			if (cont.hasOwnProperty("validateNow"))
+				cont["validateNow"].call(cont);
+			
+			var inlineRect:Rectangle = new Rectangle(0, 0, cont.width, cont.height);
+
+			return inlineRect;
+		}
+		
+		/** @private */
+		override tlf_internal function clearCompositionResults():void
+		{
+			super.clearCompositionResults();
+			
+			clearLastInlineChildren();
+			numWraps = 0;
+		} 
+		
+		private function clearLastInlineChildren():void
+		{
+			if (lastInlineChildren)
+			{
+				for (var i:int = 0; i < lastInlineChildren.length; i++)
+				{
+					var oldInline:DisplayObject = DisplayObject(lastInlineChildren[i]);
+					if ((inlineChildren.indexOf(oldInline) < 0))
+						removeInlineChild(oldInline);
+				}
+			}
+			lastInlineChildren = [];
+		}
+		
+		/** @private */
+		override tlf_internal function updateInlineChildren():void
+		{
+			// Remove the inlines from last time that are not part of what we are going to redisplay this time		
+			clearLastInlineChildren();
+			
+			// synchronize the inline shapes beginning at childIdx
+			// Add in the new shapes from this time that are not already in the list
+			for each (var inline:DisplayObject in inlineChildren)
+			{
+				addInlineChild(inline);
+				
+				// inlines can update themselves if necessary here
+				// We need this because editing a table, e.g., curently invalidates
+				// through the text flow, rather than through the component hierarchy.
+				// (Is this the right thing to do?)
+				if (inline is TextLayoutBaseContainer)
+					TextLayoutBaseContainer(inline).validateNow();	
+			}
+			if (inlineChildren)
+			{
+				lastInlineChildren = inlineChildren.slice();
+				inlineChildren.length = 0;
+			}
+		}
+
+		private function clearInlineSelectionShapes(c:DisplayObjectContainer):void
+		{
+			if (c.hasOwnProperty("controller"))
+				c["controller"].clearAllSelectionShapes();
+			else
+			{
+				for (var idx:int = 0; idx < c.numChildren; idx++)
+				{
+					var child:DisplayObjectContainer = c.getChildAt(idx) as DisplayObjectContainer;
+					if (child)
+						clearInlineSelectionShapes(child);
+				}
+			}
+		}
+		
+		CONFIG::debug tlf_internal override function validateLines():void
+		{
+			// doesn't work in layout yet
+		}
+		
+	}
+}
+
diff --git a/textLayout_layout/src/flashx/textLayout/container/TextLayoutBaseContainer.as b/textLayout_layout/src/flashx/textLayout/container/TextLayoutBaseContainer.as
new file mode 100755
index 0000000..7f11281
--- /dev/null
+++ b/textLayout_layout/src/flashx/textLayout/container/TextLayoutBaseContainer.as
@@ -0,0 +1,75 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 flashx.textLayout.container
+{
+	import flash.display.Sprite;
+
+[ExcludeClass]
+	/** @private */
+	public class TextLayoutBaseContainer extends Sprite
+	{
+		/////////////////////////////////////////////////////////////////////////
+		//  Width and Height
+		/////////////////////////////////////////////////////////////////////////
+
+		private var _width:Number;
+		private var _height:Number;
+
+		// This constructor function is here just to silence a compile warning in Eclipse. There
+		// appears to be no way to turn the warning off selectively.
+		CONFIG::debug public function TextLayoutBaseContainer()
+		{
+			super();
+		}
+		
+		/** @private */
+		override public function get width():Number
+		{
+			return _width;
+		}
+
+		/** @private */
+		override public function set width(value:Number):void
+		{
+			_width = value;
+		}
+
+		/** @private */
+		override public function get height():Number
+		{
+			return _height;
+		}
+
+		/** @private */
+		override public function set height(value:Number):void
+		{
+			_height = value;
+		}
+
+		public function validateSize(recursive:Boolean = false):void
+		{
+			// override		
+		}
+		
+		public function validateNow():void
+		{
+			
+		}
+	}
+}
\ No newline at end of file
diff --git a/textLayout_layout/src/flashx/textLayout/container/WrapManager.as b/textLayout_layout/src/flashx/textLayout/container/WrapManager.as
new file mode 100755
index 0000000..23f4788
--- /dev/null
+++ b/textLayout_layout/src/flashx/textLayout/container/WrapManager.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 flashx.textLayout.container 
+{
+	import flashx.textLayout.container.IWrapManager;
+	
+	[ DefaultProperty("wraps")]
+	public class WrapManager implements IWrapManager
+	{
+		private var _wraps:Array;
+		
+		// This constructor function is here just to silence a compile warning in Eclipse. There
+		// appears to be no way to turn the warning off selectively.
+		CONFIG::debug public function WrapManager()
+		{
+			super();
+		}
+		
+		public function get wraps():Array
+		{
+			return _wraps;
+		}
+		
+		public function set wraps(value:Array):void
+		{
+			_wraps = value;
+		}
+	}
+}
\ No newline at end of file
diff --git a/textLayout_layout/src/flashx/textLayout/conversion/LayoutConfiguration.as b/textLayout_layout/src/flashx/textLayout/conversion/LayoutConfiguration.as
new file mode 100755
index 0000000..676d4db
--- /dev/null
+++ b/textLayout_layout/src/flashx/textLayout/conversion/LayoutConfiguration.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 flashx.textLayout.conversion
+{
+	import flashx.textLayout.compose.LayoutComposeState;
+	import flashx.textLayout.compose.LayoutFlowComposer;
+	import flashx.textLayout.container.ContainerController;
+	import flashx.textLayout.elements.Configuration;
+	import flashx.textLayout.elements.TextFlow;
+	
+	
+	public class LayoutConfiguration 
+	{
+
+		static public function isLayoutComposer(controllerClass:Class) : Boolean
+		{
+			return controllerClass == LayoutFlowComposer;
+		}		
+		
+		/** Set LayoutConfiguration as the default. This updates both the default TextFlow Configuration and the ImportExport configuration for layout support */
+		static public function SetLayoutConfigurationAsDefault():void
+		{
+			TextLayoutImporter.restoreDefaults();
+			var config:ImportExportConfiguration = TextLayoutImporter.defaultConfiguration;
+
+			TextFlow.defaultConfiguration.flowComposerClass = LayoutFlowComposer;
+		}
+	}
+}
\ No newline at end of file
