http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/4e4f9830/Squiggly/main/AdobeSpellingUITLF/src/com/adobe/linguistics/spelling/SquigglyCustomContainerController.as
----------------------------------------------------------------------
diff --git 
a/Squiggly/main/AdobeSpellingUITLF/src/com/adobe/linguistics/spelling/SquigglyCustomContainerController.as
 
b/Squiggly/main/AdobeSpellingUITLF/src/com/adobe/linguistics/spelling/SquigglyCustomContainerController.as
deleted file mode 100644
index 9ea0f9a..0000000
--- 
a/Squiggly/main/AdobeSpellingUITLF/src/com/adobe/linguistics/spelling/SquigglyCustomContainerController.as
+++ /dev/null
@@ -1,258 +0,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.
-//
-////////////////////////////////////////////////////////////////////////////////
-package com.adobe.linguistics.spelling
-{
-       import com.adobe.linguistics.spelling.SpellUIForTLF;
-       import com.adobe.linguistics.spelling.framework.SpellingService;
-       import com.adobe.linguistics.spelling.ui.IHighlighter;
-       import com.adobe.linguistics.spelling.ui.IWordProcessor;
-       import com.adobe.linguistics.spelling.ui.TLFHighlighter;
-       import com.adobe.linguistics.spelling.ui.TLFWordProcessor;
-       import com.adobe.linguistics.utils.TextTokenizer;
-       import com.adobe.linguistics.utils.Token;
-       
-       import flash.display.Sprite;
-       import flash.events.ContextMenuEvent;
-       import flash.events.Event;
-       import flash.events.EventDispatcher;
-       import flash.geom.Point;
-       import flash.geom.Rectangle;
-       import flash.ui.ContextMenu;
-       import flash.ui.ContextMenuItem;
-       
-       import flashx.textLayout.compose.StandardFlowComposer;
-       import flashx.textLayout.compose.TextFlowLine;
-       import flashx.textLayout.container.ContainerController;
-       import flashx.textLayout.conversion.TextConverter;
-       import flashx.textLayout.edit.SelectionManager;
-       import flashx.textLayout.elements.FlowLeafElement;
-       import flashx.textLayout.elements.ParagraphElement;
-       import flashx.textLayout.elements.TextFlow;
-       import flashx.textLayout.events.CompositionCompleteEvent;
-       import flashx.textLayout.events.StatusChangeEvent;
-       import flashx.textLayout.tlf_internal;
-       
-       /** Custom container controller for populating context menu and 
hanlding menu item selection  */
-       internal class SquigglyCustomContainerController extends 
ContainerController
-       {
-               private var disableMenuItem:ContextMenuItem = new 
ContextMenuItem("Disable spell checking",true);
-               private var enableMenuItem:ContextMenuItem = new 
ContextMenuItem("Enable spell checking");              
-               
-               private var controlMenuItemList:Array = new Array();
-               private var suggestionMenuItemList:Array = new Array();
-               private var _spellingEnabled:Boolean;
-               private var _contextMenu:ContextMenu;
-               private var mTextHighlighter:IHighlighter;
-               private var mWordProcessor:IWordProcessor;
-               private var mSpellEngine:SpellingService;
-               private var mTextFlow:TextFlow;
-               private var _ignoreWordFunctionProcessor:Function;
-               private var _misspelledToken:Token;
-               private var _misspelled:String;
-               
-               public function 
SquigglyCustomContainerController(container:Sprite,textHighlighter:IHighlighter,
 wordProcessor:IWordProcessor, engine:SpellingService,
-                                                                               
                                  func:Function, 
compositionWidth:Number=100,compositionHeight:Number=100)
-               {
-                       super (container, compositionWidth, compositionHeight);
-                       mTextHighlighter = textHighlighter;
-                       mWordProcessor = wordProcessor;
-                       mSpellEngine = engine;
-                       _ignoreWordFunctionProcessor = func;
-                       
-                       spellingEnabled = true;
-               }
-               
-               /** Overridden to add custom items to the context menu */
-               override protected function createContextMenu():ContextMenu
-               {
-                       // Get the default context menu used by TLF for 
editable flows
-                       _contextMenu = super.container.contextMenu;
-                       if (_contextMenu == null)
-                               _contextMenu = super.createContextMenu();
-                               
-                       
-                       
enableMenuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, 
handleEnableSpellCheck);
-                       
disableMenuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, 
handleDisableSpellCheck);
-                       controlMenuItemList.push(enableMenuItem);
-                       controlMenuItemList.push(disableMenuItem);
-                       
-                       _contextMenu.customItems.push(disableMenuItem);
-                       _contextMenu.customItems.push(enableMenuItem);
-                       
-                       // Listen for menu selection
-                       
_contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, 
updateCustomMenuItems);
-                       
-                       return _contextMenu;
-               }
-               
-               /** Update the state of the custom menu items before the 
context menu is displayed */
-               private function 
updateCustomMenuItems(event:ContextMenuEvent):void 
-               {
-                       /* Clear the context menu */
-                       //spellingEnabled= mTextHighlighter.spellingEnabled;
-                       //SpellUI.doSpelling1();
-                       var removedNum:int = 0;
-                       var count:uint = _contextMenu.customItems.length;
-                       for (var j:uint=count; j>0; j--) {
-                               if ( isWordItem(_contextMenu.customItems[j-1]) 
) {
-                                       _contextMenu.customItems.splice(j-1,1);
-                                       removedNum++
-                               }
-                       }
-                       if ( removedNum != suggestionMenuItemList.length ) {
-                               trace("internal error");
-                       }
-                       
-                       
-                       suggestionMenuItemList = new Array();
-                       
-                       // localized entries
-                       var entries:Object = 
SpellUIForTLF.getSpellingMenuEntries();
-                       disableMenuItem.caption = entries.disable;
-                       enableMenuItem.caption = entries.enable;                
                
-                       
-                       if (spellingEnabled == true) {
-                               (mWordProcessor as 
TLFWordProcessor).textFlowContainerController = this;
-                               
-                               //trace("stageX " +  
super.container.stage.mouseX);
-                               //trace("stageY " +  
super.container.stage.mouseY);
-                               //trace("mouseX " +  super.container.mouseX);
-                               //trace("mouseY " +  super.container.mouseY);
-                               _misspelledToken = 
mWordProcessor.getWordAtPoint(this.container.mouseX, this.container.mouseY);
-                               if (_misspelledToken==null) return;
-                               var currentLeaf:FlowLeafElement = 
this.textFlow.findLeaf(_misspelledToken.first);
-                               var currentParagraph:ParagraphElement = 
currentLeaf ? currentLeaf.getParagraph() : null;
-                               _misspelled =   
currentParagraph.getText().substring(_misspelledToken.first - 
currentParagraph.getAbsoluteStart(), 
-                                                                               
                                                                
_misspelledToken.last - currentParagraph.getAbsoluteStart());
-                               if ((_misspelled==null) || (_misspelled == "")) 
return;
-                               
-                               if (mSpellEngine.checkWord(_misspelled)==true) 
return;                          
-                               
-                               var suseAddToItem:ContextMenuItem = new 
ContextMenuItem(entries.add);
-                               
suseAddToItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, 
handleAddToItemSelect);
-                               suggestionMenuItemList.push(suseAddToItem);
-                               
_contextMenu.customItems.splice(0,0,suseAddToItem);     
-                               //var result:Array = 
mWordProcessor.getSuggestionsAtPoint();
-                               var resultVector:Vector.<String> = 
mSpellEngine.getSuggestions(_misspelled);
-                               var result:Array = new Array();
-                               if (resultVector) {
-                                       for each (var w:String in resultVector)
-                                       result.push(w);
-                               }
-                               if (result!=null) {
-                                       for (var i:int=result.length-1;i>=0;i-- 
) {
-                                               var 
suseMenuItem:ContextMenuItem = new ContextMenuItem(result[i]);
-                                               
suseMenuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, 
handleSuseItemSelect);
-                                               
suggestionMenuItemList.push(suseMenuItem);
-                                               
//_contextMenu.customItems.push(suseMenuItem);
-                                               
_contextMenu.customItems.splice(0,0,suseMenuItem);
-                                       }
-                               }
-                       }
-               }
-               
-               private function 
handleAddToItemSelect(event:ContextMenuEvent):void
-               {
-                       if ( _ignoreWordFunctionProcessor == null ) return;
-                       
-                       /*
-                       var menuEntry:String = (event.currentTarget as 
ContextMenuItem).caption;
-                       var start:uint = 5;
-                       var end:uint = menuEntry.length - 15;
-                       var word:String = menuEntry.substring(start, end);
-                       */
-                       _ignoreWordFunctionProcessor(_misspelled);
-                       
SpellUIForTLF.UITable[SpellUIForTLF.parentComp[super.textFlow]].doSpellingJob();
-               }
-               
-               private function 
handleSuseItemSelect(event:ContextMenuEvent):void
-               {
-                       mWordProcessor.replaceText(_misspelledToken, 
(event.currentTarget as ContextMenuItem).caption );
-                       
SpellUIForTLF.UITable[SpellUIForTLF.parentComp[super.textFlow]].doSpellingJob();
-               }
-                       
-               private function set spellingEnabled(value:Boolean) :void {
-                       _spellingEnabled = value;
-                       disableMenuItem.visible=spellingEnabled;
-                       enableMenuItem.visible=!spellingEnabled;
-               }
-               private function get spellingEnabled():Boolean {
-                       return this._spellingEnabled;
-               }
-               
-               private function isWordItem(item:ContextMenuItem):Boolean {
-                       
-                       for ( var i:int=0; i<suggestionMenuItemList.length; ++i 
) {
-                               if ( suggestionMenuItemList[i] == item ) return 
true;
-                       }
-                       return false;
-               }
-               
-               private function isControlItem(item:ContextMenuItem):Boolean {
-                       for (var i:int=0; i<controlMenuItemList.length; ++i) {
-                               if ( controlMenuItemList[i] == item) return 
true;
-                       }
-                       return false;
-               }
-               
-               private function 
handleEnableSpellCheck(event:ContextMenuEvent):void
-               {
-                       spellingEnabled= true;
-                       //mTextHighlighter.spellingEnabled= spellingEnabled;
-                       //SpellUI.doSpellingJob();
-                       //dispatchEvent(new Event(Event.RENDER));
-                       
-                       
SpellUIForTLF.UITable[SpellUIForTLF.parentComp[this.textFlow]].spellingEnabled 
= spellingEnabled;
-                       
SpellUIForTLF.UITable[SpellUIForTLF.parentComp[this.textFlow]].doSpellingJob();
-                       //spellCheckRange(getValidFirstWordIndex(), 
getValidLastWordIndex());
-               }
-               private function 
handleDisableSpellCheck(event:ContextMenuEvent):void
-               {
-                       spellingEnabled= false;
-                       
SpellUIForTLF.UITable[SpellUIForTLF.parentComp[this.textFlow]].spellingEnabled 
= spellingEnabled;
-                       mTextHighlighter.clearSquiggles();
-               }
-               
-               public function cleanUpContextMenu():void
-               {
-                       mTextHighlighter=null;
-                       mWordProcessor=null;
-                       spellingEnabled = false;
-                       _ignoreWordFunctionProcessor=null;
-                       
-                       
_contextMenu.removeEventListener(ContextMenuEvent.MENU_SELECT, 
updateCustomMenuItems);
-                       
-                       var removedNum:int = 0;
-                       var count:uint = _contextMenu.customItems.length;
-                       for (var j:uint=count; j>0; j--) {
-                               if ( isWordItem(_contextMenu.customItems[j-1]) 
|| isControlItem(_contextMenu.customItems[j-1]) ) {
-                                       _contextMenu.customItems.splice(j-1,1);
-                                       removedNum++
-                               }
-                       }
-                       if ( removedNum != suggestionMenuItemList.length + 
controlMenuItemList.length ) {
-                               trace("internal error");
-                       }
-                       
-                       suggestionMenuItemList = null;
-                       controlMenuItemList = null;
-               }
-               
-       }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/4e4f9830/Squiggly/main/LinguisticUtils/src/com/adobe/linguistics/utils/ITokenizer.as
----------------------------------------------------------------------
diff --git 
a/Squiggly/main/LinguisticUtils/src/com/adobe/linguistics/utils/ITokenizer.as 
b/Squiggly/main/LinguisticUtils/src/com/adobe/linguistics/utils/ITokenizer.as
new file mode 100644
index 0000000..e40772d
--- /dev/null
+++ 
b/Squiggly/main/LinguisticUtils/src/com/adobe/linguistics/utils/ITokenizer.as
@@ -0,0 +1,76 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+
+
+
+package com.adobe.linguistics.utils
+{
+       /**
+        * The <code>ITokenizer</code> Interface.
+        * This interface defines default methods which will be used for Adobe 
Linguistic Service.
+        * Be independent from any UI component or be able to adapt to a given 
UI component. 
+        * Provide or define standardized way so that third-party can switch to 
their tokenizer.
+        * Be able to use for any given language either by some kind of 
language specific handling or by some kind of unified logic for any given 
language.
+        * More sophisticated implementations can be done for particular 
locales or environments in an application by implementing this interface.
+
+        * @playerversion Flash 10
+        * @langversion 3.0
+        */
+       public interface ITokenizer
+       {
+               
+               /**
+                * Return the first word in the text being scanned. 
+                * 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               function getFirstToken():Token;
+               
+               /**
+                * Return the last word in the text being scanned. 
+                * 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               function getLastToken():Token;
+               
+               /**
+                * Determine the next word following the current token.  
+                * 
+                * Return the token of the next word or <code>lastToken</code> 
object if all word have been returned.
+                * @param token A <code>Token</code> object to be used for 
determining next word.
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               function getNextToken(token:Token):Token;
+               
+               /**
+                * Determine the previous word preceding the current token.  
+                * 
+                * Return the token of the previous word or 
<code>firstToken</code> object if all word have been returned.
+                * @param token A <code>Token</code> object to be used for 
determining previous word.
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               function getPreviousToken(token:Token):Token;
+
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/4e4f9830/Squiggly/main/LinguisticUtils/src/com/adobe/linguistics/utils/TextTokenizer.as
----------------------------------------------------------------------
diff --git 
a/Squiggly/main/LinguisticUtils/src/com/adobe/linguistics/utils/TextTokenizer.as
 
b/Squiggly/main/LinguisticUtils/src/com/adobe/linguistics/utils/TextTokenizer.as
new file mode 100644
index 0000000..596481c
--- /dev/null
+++ 
b/Squiggly/main/LinguisticUtils/src/com/adobe/linguistics/utils/TextTokenizer.as
@@ -0,0 +1,393 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 com.adobe.linguistics.utils
+{
+       import __AS3__.vec.Vector;
+       
+       import flash.utils.Dictionary;
+       
+    import flash.text.engine.TextBlock;
+    import flash.text.engine.TextElement;
+    import flash.text.engine.ElementFormat;
+
+               
+       /**
+        * <p>The <code>TextTokenizer</code> class locates the boundaries of 
words in a 
+        * block of text.</p>
+        * 
+        * Word boundary locations are found according to these general 
principles:
+        * <ul>
+        *              <li> Be able to tokenize a block of text specified by 
start and end positions </li> 
+        *              <li> Default separator is Unicode white space 
character. Also break on newlines </li> 
+        *              <li> Tokens consist of either words or numbers in which 
case it may include commas, etc.. </li> 
+        *              <li> Apostrophes or hyphens within a word are kept with 
the word </li> 
+        *              <li> Punctuation, spaces and other characters that are 
not part of a token, are broken out separately </li> 
+        * </ul>
+        * <p>In the future versions, this class would also provide a way for 
the developers to customize the separators used by the tokenizer. </p>
+        * 
+        * @playerversion Flash 9.x
+        * @langversion 3.0
+       */
+       public class TextTokenizer implements ITokenizer
+       {
+               
+
+               private var _textBlock:TextBlock;
+               private var _textHolder:String;
+               private var _startIndex:int;
+               private var _endIndex:int;
+               private var _firstToken:Token;
+               private var _lastToken:Token;
+               
+               private var _ignoredCharactersDict:Dictionary = new 
Dictionary();
+
+
+               /**
+                * The tokenizer for a String object.
+                * This class implements the ITokenizer interface.
+                * Constructs a new TextTokenizer object to break String to 
words by creating with a new piece of text. 
+                * @param textHolder A <code>String</code> object to hold the 
text which will be processed by this tokenizer.
+                * @param startIndex A <code>int</code> type input to hold the 
starting index of input text should be scanned.
+                * @param endIndex A <code>int</code> type input to hold the 
ending index of input text should be scanned.
+                * <span class="hide"> TODO param requestedLocaleIDName The 
LocaleID name to be used by this TextTokenizer object. </span>
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */
+               public function TextTokenizer(textHolder:String, 
startIndex:int=0, endIndex:int=int.MAX_VALUE)//, 
requestedLocaleIDName:String=null)
+               {
+                       //requestedLocaleIDName parameter is useful for 
potential extension. won't handle it in the first round of implementation.
+                       //  same comments for API: 
requestedLocaleIDName()/actualLocaleIDName()/getAvailableLocaleIDNames()
+            var textElement:TextElement = new TextElement(textHolder, new 
ElementFormat()); 
+            var textBlock:TextBlock = new TextBlock();
+            textBlock.content = textElement; 
+                       
+                       /* init a tokenizer object */
+                       this._textBlock = textBlock;
+                       this._textHolder = textHolder;
+                       this._startIndex =  0;
+                       this._endIndex = this._textBlock.content.text.length;
+                       initDefaultIgnoredCharacters();
+                       setStartIndex(startIndex);
+                       setEndIndex(endIndex);
+                       
+               }
+               
+               private function setStartIndex(value:int):void {
+                       if ( value <= 0 ) 
+                               this._startIndex = 0;
+                       else if ( value >= this._endIndex ) 
+                               this._startIndex = this._endIndex;
+                       else
+                               this._startIndex=value;
+               }
+               
+               // strange behaviour with String.substring() function... need 
more thinking....
+               private function setEndIndex(value:int):void {
+                       if ( value >= this._textBlock.content.text.length ) 
+                               this._endIndex = 
this._textBlock.content.text.length;
+                       else if ( value <= this._startIndex ) 
+                               this._endIndex = this._startIndex;
+                       else
+                               this._endIndex = value;
+               }
+
+               private function initDefaultIgnoredCharacters():void {
+                       var ignoredCharsArray:Array = [
+                               0x002d,
+                               0x2010
+                       ];
+                       var ignoredChars:String = "";
+                       for ( var i:int=0; i< ignoredCharsArray.length; ++i ) {
+                               
ignoredChars=ignoredChars+String.fromCharCode(ignoredCharsArray[i]);
+                       }
+                       this.ignoredCharacters = ignoredChars;
+               }
+
+               private function getNextTokenByIndex( startPos:int ):Token{
+                       var resultToken:Token = null;
+                       /* calculate first token and return it. */
+                       var i:int = (startPos > this._startIndex) ? startPos: 
this._startIndex;
+                       while ( i< this._endIndex ) {
+                               var begin:int = i;
+                               i = this._textBlock.findNextWordBoundary(begin);
+                               var end:int = ( i <= this._endIndex) ? i : 
this._endIndex;
+                               if ( !isSingleSpecialCharacter( 
this._textHolder.substring(begin,end) ) ) {
+                                       resultToken = new Token(begin,end);
+                                       break;                          
+                               }
+                       }
+                       if ( resultToken==null ) resultToken = 
this.getLastToken();
+                       return resultToken;
+               }
+               
+               private function getPreviousTokenByIndex( endPos:int):Token {
+                       var resultToken:Token = null;
+                       /* calculate first token and return it. */
+                       var i:int = (endPos < this._endIndex) ? endPos: 
this._endIndex;
+                       
+                       /* special handling for last element in the word, bof */
+                       var specialHandling:Boolean = false;
+                       if ( i == this._endIndex ) {
+                               specialHandling = true;
+                               i = this._endIndex -1;
+                       }
+                       /* special handling for last element in the word, eof */
+                       
+                       while ( i > this._startIndex ) {
+                               var end:int = i;
+                               i = 
this._textBlock.findPreviousWordBoundary(end);
+                               var begin:int = ( i > this._startIndex) ? i : 
this._startIndex;
+                               
+                               /* special handling for last element in the 
word, bof */
+                               if ( specialHandling ) {
+                                       end = 
(this._textBlock.findNextWordBoundary(begin)<this._endIndex) 
?this._textBlock.findNextWordBoundary(begin):this._endIndex;
+                                       specialHandling=false;
+                                       if ( (end != this._endIndex) && 
!isSingleSpecialCharacter(this._textHolder.substring(this._endIndex-1,this._endIndex))
 ) {
+                                               begin = this._endIndex-1;
+                                               i=begin;
+                                               end = this._endIndex;
+                                       } 
+                               }
+                               /* special handling for last element in the 
word, eof */
+                               
+                               if ( !isSingleSpecialCharacter( 
this._textHolder.substring(begin,end) ) ) {
+                                       resultToken = new Token(begin,end);
+                                       break;  
+                               }
+                       }
+                       if ( resultToken==null ) resultToken = 
this.getFirstToken();
+                       return resultToken;
+               }
+               
+               private function isExceptionCharacter(word:String):Boolean {
+                       if ( word.length != 1 ) return false;
+                       if ( this._ignoredCharactersDict[word] == true ) return 
true;
+                       return false;
+               }
+               
+               private function 
getNextFilteredTokenByIndex(startPos:int):Token {
+                       var token:Token = getNextTokenByIndex(startPos);
+                       var firstToken:Token = token;
+                       var cursor:int=token.last+1;
+                       
+                       while ( (cursor < this._endIndex) ) {
+                               if ( 
!isExceptionCharacter(this._textHolder.substring(cursor-1,cursor)) ) {
+                                       break;
+                               }else {
+                                       //another request from Harish about 
handling case abc\\abc abc\.abc case...not 100% sure about the correct 
behavior...
+                                       /*bof*/
+                                       while( cursor < this._endIndex && 
isExceptionCharacter(this._textHolder.substring(cursor-1,cursor)) ) {
+                                               cursor++;
+                                       }
+                                       cursor--;
+                                       /*eof*/
+                               }
+                               token = getNextTokenByIndex(cursor);
+                               if ( token.first != cursor ) {
+                                       token = firstToken;
+                                       break;
+                               }
+                               token.first=firstToken.first;
+                               firstToken = token;
+                               cursor = token.last+1;
+                       } 
+                       return token;
+               }
+
+               private function 
getPreviousFilteredTokenByIndex(endPos:int):Token {
+                       var token:Token = getPreviousTokenByIndex(endPos);
+                       var lastToken:Token = token;
+                       var cursor:int=token.first-1;
+                       
+                       while ( ( cursor > this._startIndex ) ) {
+                               if ( 
!isExceptionCharacter(this._textHolder.substring(cursor,cursor+1)) ) {
+                                       break;
+                               }else {
+                                       //another request from Harish about 
handling case abc\\abc abc\.abc case...not 100% sure about the correct 
behavior...
+                                       /*bof*/
+                                       while( cursor > this._startIndex && 
isExceptionCharacter(this._textHolder.substring(cursor,cursor+1)) ) {
+                                               cursor--;
+                                       }
+                                       cursor++;
+                                       /*eof*/
+                               }
+                               token = getPreviousTokenByIndex(cursor);
+                               if ( token.last != cursor ) {
+                                       token = lastToken;
+                                       break;
+                               }
+                               token.last=lastToken.last;
+                               lastToken = token;
+                               cursor = token.first-1;
+                       } 
+                       return token;
+               }
+
+               private function isSingleSpecialCharacter(word:String):Boolean{
+                       if ( word.length != 1 ) return false;
+                       if ( word.toLocaleLowerCase() == 
word.toLocaleUpperCase() ) return true;
+                       return false;
+               }
+               
+               /** 
+                * Set all of ignored separators to this tokenizer class.
+                * 
+                * A vector of int containing all of ignored separators code 
point which are used by this class. 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               public function set 
ignoredSeparators(characters:Vector.<int>):void {
+                       if ( characters == null || characters.length==0 ) 
return;
+                       this._ignoredCharactersDict = new Dictionary();
+                       for ( var i:int =0;i<characters.length;++i) {
+                               
this._ignoredCharactersDict[String.fromCharCode(characters[i])]=true;
+                       }
+               }
+               
+               /**
+                * Get all of ignored separators used by this tokenizer class.
+                * 
+                * A vector of int containing all of ignored separators code 
point which are used by this class. 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               public function get ignoredSeparators():Vector.<int>{
+                       var result:Vector.<int> = new Vector.<int>();
+                       for ( var key:String in _ignoredCharactersDict) {
+                               result.push(key.charCodeAt(0) );
+                       }
+                       return result;
+                       
+               }
+               
+               private function set ignoredCharacters(value:String ) :void {
+                       if( value == null || value == "" ) return;
+                       var charArr:Array = value.split("");
+                       this._ignoredCharactersDict = new Dictionary();
+                       for ( var i:int = 0;i< charArr.length;++i) {
+                               this._ignoredCharactersDict[charArr[i]]=true;
+                       }
+               }
+               
+               private function get ignoredCharacters():String {
+                       var result:String = "";
+                       for ( var key:String in _ignoredCharactersDict) {
+                               result +=key;
+                       }
+                       return result;
+               }
+               
+               /**
+                * The name of the requested locale ID that was passed to the 
constructor of this TextTokenizer object. 
+                * 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */     /*      
+               public function get requestedLocaleIDName():String {
+                       return null;
+               }
+               
+               
+               /**
+                * The name of the actual locale ID used by this TextTokenizer 
object. 
+                * 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */     /*      
+               public function get actualLocaleIDName():String {
+                       return null;
+               }
+               
+               /**
+                * Lists all of the locale ID names supported by this class.
+                * 
+                * A vector of strings containing all of the locale ID names 
supported by this class. 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             /*
+               public static function 
getAvailableLocaleIDNames():Vector.<String>{ return null;}
+*/
+               /**
+                * Return the first word in the text being scanned. 
+                * <p> NOTE: In a special case when there are no valid tokens 
in text, it returns a pseudo token having first and last index set to 
int.MAX_VALUE. As a result<code> firstToken().first </code>equals int.MAX_VALUE 
and<code> firstToken().last </code>equals int.MAX_VALUE.</p>
+                * 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               public function getFirstToken():Token {
+                       
+                       /* return the cached one. */
+                       if ( this._firstToken != null )
+                               return this._firstToken;
+                       
+                       /* calculate first token and return it. */
+                       //this._firstToken = 
getNextTokenByIndex(this._startIndex); // without any filter from LS, directly 
use FTE tokenizer...
+                       this._firstToken = 
getNextFilteredTokenByIndex(this._startIndex);
+
+                       return this._firstToken;
+               }
+               
+               /**
+                * @private
+                * Return the last word in the text being scanned. 
+                * 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               public function getLastToken():Token {
+                       /* return the cached one. */
+                       if ( this._lastToken != null )
+                               return this._lastToken;
+                               
+                       /* calculate last token and return it. */
+                       this._lastToken = new 
Token(int.MAX_VALUE,int.MAX_VALUE);
+                       return this._lastToken;
+               }
+               
+               /**
+                * Determine the next word following the current token.  
+                * 
+                * <p>Returns the token of the next word.</p><p> NOTE: When 
there are no more valid tokens, it returns a pseudo token having first and last 
index set to int.MAX_VALUE. As a result<code> getNextToken().first 
</code>equals int.MAX_VALUE and<code> getNextToken().last </code>equals 
int.MAX_VALUE.</p>
+                * @param token A <code>Token</code> object to be used for 
determining next word.
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               public function getNextToken(token:Token):Token {
+                       //return getNextTokenByIndex(token.last); // without 
any filter from LS, directly use FTE tokenizer...
+                       return getNextFilteredTokenByIndex(token.last);
+               }
+               
+               /**
+                * Determine the word preceding the current token.  
+                * 
+                * <p>Returns the token of the previous word or<code> 
getFirstToken </code>object if there is no preceding word.</p>
+                * @param token A <code>Token</code> object to be used for 
determining previous word.
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               public function getPreviousToken(token:Token):Token {
+                       //return getPreviousTokenByIndex( token.first );// 
without any filter from LS, directly use FTE tokenizer...
+                       return getPreviousFilteredTokenByIndex( token.first )
+               }
+
+       }
+       
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/4e4f9830/Squiggly/main/LinguisticUtils/src/com/adobe/linguistics/utils/Token.as
----------------------------------------------------------------------
diff --git 
a/Squiggly/main/LinguisticUtils/src/com/adobe/linguistics/utils/Token.as 
b/Squiggly/main/LinguisticUtils/src/com/adobe/linguistics/utils/Token.as
new file mode 100644
index 0000000..27fcfb2
--- /dev/null
+++ b/Squiggly/main/LinguisticUtils/src/com/adobe/linguistics/utils/Token.as
@@ -0,0 +1,94 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 com.adobe.linguistics.utils
+{
+       /**
+        * A Token is an occurrence of a word in a block of text. It consists 
of the start and end offset of the word in the block of text.
+        * The start and end offsets permit applications to re-associate a 
token with its source text, e.g., to display highlighted misspelled word in 
+        * a block of text.
+        * @playerversion Flash 10
+        * @langversion 3.0
+        */
+       public class Token
+       {
+               private var _first:uint;
+               private var _last:uint;
+               
+               /**
+                * The Token class.
+                * Constructs a Token with first and last offsets. . 
+                * @param first A <code>int</code> type input to point start 
offset in the source text.
+                * @param last A <code>int</code> type input to point end 
offset in the source text.
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */
+               public function Token(inFirst:int, inLast:int)
+               {
+                       _first = inFirst;
+                       _last = inLast;
+
+               }
+               
+               /**
+                * Set the start offset in the source text. 
+                * 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               public function set first(value:int):void {
+                       _first=value;
+               }
+               
+               /**
+                * Return the start offset in the source text. 
+                * 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               public function get first():int
+               {
+                       return _first;
+               }
+               
+               /**
+                * Set the end offset in the source text. 
+                * 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               public function set last(value:int):void {
+                       _last = value;
+               }
+               
+               /**
+                * Return the end offset in the source text. 
+                * 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               public function get last():int
+               {
+                       return _last;
+               }
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/4e4f9830/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/HunspellDictionary.as
----------------------------------------------------------------------
diff --git 
a/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/HunspellDictionary.as
 
b/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/HunspellDictionary.as
new file mode 100644
index 0000000..7ec0312
--- /dev/null
+++ 
b/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/HunspellDictionary.as
@@ -0,0 +1,205 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 com.adobe.linguistics.spelling
+{
+       import com.adobe.linguistics.spelling.core.LinguisticRule;
+       import com.adobe.linguistics.spelling.core.SquigglyDictionary;
+       import com.adobe.linguistics.spelling.core.utils.LinguisticRuleLoader;
+       import 
com.adobe.linguistics.spelling.core.utils.SquigglyDictionaryLoader;
+       
+       import flash.errors.IllegalOperationError;
+       import flash.events.ErrorEvent;
+       import flash.events.Event;
+       import flash.events.EventDispatcher;
+       import flash.events.IOErrorEvent;
+       import flash.events.SecurityErrorEvent;
+
+       /**
+        *
+        * This class enables creation and loading of spelling metadata 
including rules and dictionary data
+        *
+        * @playerversion Flash 10
+        * @langversion 3.0
+        * @includeExample Examples/Air/CheckWord/src/CheckWord.mxml -noswf
+        */
+        
+       public final class HunspellDictionary extends EventDispatcher 
implements ISpellingDictionary
+       {
+               private var _dict:SquigglyDictionary;
+               private var _attrMgr:LinguisticRule;
+               private var _rulePath:String;
+               private var _dictionaryPath:String;
+               
+               private var ruleLoader:LinguisticRuleLoader = new 
LinguisticRuleLoader();
+               private var dictLoader:SquigglyDictionaryLoader = new 
SquigglyDictionaryLoader();
+
+               private var _loaded:Boolean;
+               
+               //adding vars for loading dictionaries in parts
+               private var _enableDictionarySplit:Boolean;
+               private var _wordsPerDictionarySplit:int;
+
+               /**
+                * Constructs a new <code>HunspellDictionary</code> which can 
later be used by a <code>SpellChecker</code> object.
+                *
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */
+               public function HunspellDictionary()
+               {
+                       _attrMgr = null;
+                       _dict = null;
+                       _rulePath = null ;
+                       _dictionaryPath = null;
+                       _loaded = false;
+                       //giving default values in case user does not want to 
specify these
+                       _enableDictionarySplit =false;
+                       _wordsPerDictionarySplit= 20000;
+
+               }
+
+               /**
+                       @private
+                       (This property is for Squiggly Developer use only.)
+               */
+               public function get linguisticRule():LinguisticRule {
+                       return _attrMgr;
+               }
+               
+               /**
+                       @private
+                       (This property is for Squiggly Developer use only.)
+               */
+               public function get squigglyDictionary():SquigglyDictionary {
+                       return  _dict;
+               }
+               
+               /**
+                * Loads a Hunspell dictionary and corresponding rules files as 
specified by the <code>dictionaryURL</code> and the <code>rulesURL</code>.
+                *
+                * <p>The actual loading is done asynchronously and
+                *      the <code>HunspellDictionary</code> object will 
dispatch an <code>Event.COMPLETE</code> event.
+                *      When an error condition occurs, it will dispatch an 
<code>IOErrorEvent.IO_ERROR</code> event.</p>
+                * @param rulesURL The URL of rule file to be loaded.
+                * @param dictionaryURL The URL of Dictionary file to be loaded.
+                * @playerversion Flash 10
+                * @langversion 3.0
+                * @example The following code shows how load API is called to 
load a Rule and Dictionary file to create a HunspellDictionay.
+                * <listing version="3.0">
+                * private var _newdict:HunspellDictionary = new 
HunspellDictionary();
+                * _newdict.load("dictionaries/en_US/en_US.aff", 
"dictionaries/en_US/en_US.dic");
+                * </listing>
+                */
+               public function load(rulesURL:String, 
dictionaryURL:String):void {
+                       if ( rulesURL == null || dictionaryURL == null ) {
+                               throw new IllegalOperationError("load function 
did not receive two valid URLs.");
+                       }
+                       _rulePath = rulesURL;
+                       _dictionaryPath = dictionaryURL;
+                       
+                       
ruleLoader.addEventListener(Event.COMPLETE,loadRuleComplete);
+                       
ruleLoader.addEventListener(IOErrorEvent.IO_ERROR,handleError);
+                       
ruleLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,handleError);
+                       ruleLoader.load( _rulePath);
+                       
+               }
+
+               /**
+                * A flag that indicates if the dictionary has finished loading.
+                * 
+                * @return <code>true</code> if loading is completed. 
<code>false</code> if loading has not completed.
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */
+               public function get loaded():Boolean
+               {
+                       return _loaded;
+               }
+
+               
+               // Private method to dispatch complete Event.
+               private function loadRuleComplete(evt:Event):void {
+                       _attrMgr = ruleLoader.linguisticRule;
+                       
+                       dictLoader.linguisticRule = _attrMgr;
+                       
dictLoader.addEventListener(Event.COMPLETE,loadDictionaryComplete);
+                       
dictLoader.addEventListener(IOErrorEvent.IO_ERROR,handleError);
+                       
dictLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,handleError);
+                       dictLoader.load(_dictionaryPath, 
_enableDictionarySplit, _wordsPerDictionarySplit);
+               }
+
+               // Private method to dispatch complete Event.
+               private function loadDictionaryComplete(evt:Event):void {
+                       _dict = dictLoader.squigglyDictionary;
+                       _loaded = true;
+                       dispatchEvent(new Event(Event.COMPLETE));
+               }
+               
+               //Private method to dispatch an error event.
+               private function handleError(evt:Event):void {
+                       bounceEvent(evt);
+               }
+               
+               private function bounceEvent(evt:Event):void {
+                       dispatchEvent(evt.clone());
+               }
+               
+               /**
+                * This is a flag that enables/disables loading of dictionary 
in splits.
+                * By default this flag is set to <code>false</code>. In case 
the initial loading time of dictionaries is found slow, this flag should be set 
to <code>true</code>. By enabling this, squiggly will load dictionary in splits 
with each split having <code>wordsPerDictionarySplit</code> number of words.
+                * <p>NOTE: This property, if used, should be set before 
calling <code>HunspellDictionary.load</code>. Once 
<code>HunspellDictionary.load</code> is called dictionaries will be loaded 
according to default values, and this property will not be used. </p>
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */
+               public function get enableDictionarySplit():Boolean
+               {
+                       return _enableDictionarySplit;  
+               }
+               
+               public function set 
enableDictionarySplit(enableDictionarySplit:Boolean):void
+               {
+                       _enableDictionarySplit = enableDictionarySplit;
+               }
+               
+               /**
+                * This property defines the number of words in one dictionary 
split.
+                * By default the value of this property is set to 20000 words. 
This property is used only if <code>enableDictionarySplit</code> is set to 
<code>true</code>. If <code>enableDictionarySplit</code> is set to 
<code>flase</code> this property turns void.
+                * <p>NOTE: This property, if used, should be defined before 
calling <code>HunspellDictionary.load</code>. Once 
<code>HunspellDictionary.load</code> is called dictionaries will be loaded 
according to default values, and this property will not be used. </p>
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */
+               public function get wordsPerDictionarySplit():int
+               {
+                       
+                       return _wordsPerDictionarySplit;        
+               }
+               
+               public function set 
wordsPerDictionarySplit(wordsPerDictionarySplit:int):void
+               {
+                       if(wordsPerDictionarySplit<=0){
+                               //Do error Handling
+                               throw new 
IllegalOperationError("wordsPerDictionarySplit should be a positive non-zero 
value.");
+                       }
+                       _wordsPerDictionarySplit = wordsPerDictionarySplit;
+               }
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/4e4f9830/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/ISpellChecker.as
----------------------------------------------------------------------
diff --git 
a/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/ISpellChecker.as
 
b/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/ISpellChecker.as
new file mode 100644
index 0000000..34917bd
--- /dev/null
+++ 
b/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/ISpellChecker.as
@@ -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.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package com.adobe.linguistics.spelling
+{
+       /**
+        * Interface for actual SpellChecker class implementations
+        *
+        * <p>If a new SpellChecker class is created, it must implement the 
methods and properties defined by this interface.
+        * The <code>SpellChecker</code> class implements this interface.</p>
+        * 
+        * @playerversion Flash 10
+        * @langversion 3.0
+        */
+       public interface ISpellChecker
+       {       
+               /**
+                * Spellchecks a word.
+                * 
+                * @param word  A string containing a word.
+                *                      <p><strong>Note: </strong>Please be 
aware that it is the caller's responsibility to break down sentences into words 
that can be handled by this method.
+                *                      For example, this method does not 
support punctuation marks such as comma, colon, quotes, etc.
+                *                              Punctuation marks should be 
stripped out from the word prior to calling this method.</p>
+                * @return <code>true</code> if the word is properly spelled. 
<code>false</code> if the word is misspelled.
+                *
+                * @includeExample Examples/Flex/CheckWord/src/CheckWord.mxml
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */
+               function checkWord(word:String):Boolean;
+               
+               /**
+                * Gets suggestions for a misspelled word. 
+                *
+                * @param word  A string containing a misspelled word.
+                *                                      <p>A properly spelled 
word does not generate any suggestions.</p>  
+                * @return      A list of suggestions.
+                *                                      If the input word is 
properly spelled, an empty list will be returned.</p>
+                *
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */
+               function getSuggestions(word:String):Array;
+               
+       }
+}

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/4e4f9830/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/ISpellingDictionary.as
----------------------------------------------------------------------
diff --git 
a/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/ISpellingDictionary.as
 
b/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/ISpellingDictionary.as
new file mode 100644
index 0000000..8a46ef4
--- /dev/null
+++ 
b/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/ISpellingDictionary.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 com.adobe.linguistics.spelling
+{
+       import com.adobe.linguistics.spelling.core.LinguisticRule;
+       import com.adobe.linguistics.spelling.core.SquigglyDictionary;
+       public interface ISpellingDictionary
+       {
+
+               /**
+                * @private
+                * (This property is for Squiggly Developer use only.)
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */
+               function get linguisticRule():LinguisticRule;
+               
+               /**
+                * @private
+                * (This property is for Squiggly Developer use only.)
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */
+               function get squigglyDictionary():SquigglyDictionary;
+               
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/4e4f9830/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/SpellChecker.as
----------------------------------------------------------------------
diff --git 
a/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/SpellChecker.as
 
b/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/SpellChecker.as
new file mode 100644
index 0000000..bc23a91
--- /dev/null
+++ 
b/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/SpellChecker.as
@@ -0,0 +1,387 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 com.adobe.linguistics.spelling
+{      
+       import com.adobe.linguistics.spelling.core.*;
+
+       /**
+        * The spelling engine.
+        *
+        * <p>This class implements the <code>ISpellChecker</code> interface.
+        * This class performs spell&#x2d;checking and generates suggestion 
lists for misspelled words.
+        * This class does not include any user-interface elements. Use this 
class if you want to offer 
+        * control over how all upper case words are handled or words with 
numbers are handled, as this 
+        * level of control is not offered by the SpellUI class.  However, 
please keep in mind that if 
+        * you use this class, you will need to write your own UI.</p>
+        *
+        * <p>This class is based on the Hunspell algorithm and works with 
Hunspell/MySpell 
+        * dictionaries and corresponding language rules files.</p>
+        * <p>Currently, we support a subset of Hunspell rules(options). </p>
+        * <p>The future of this class is to align as much as possible with 
existing Hunspell solution 
+        * both for the algorithms and the content. </p> 
+        * <p>In this version, users can also directly load Open-Office 
dictionaries to HunspellDictionary 
+        * class and initialize a SpellChecker instance with this 
HunspellDictionary object. When using this 
+        * class, the language of use is implied by the dictionary supplied.  
Please make sure you load the 
+        * appropriate dictionary based on the language the user selects to 
input.</p>
+        * 
+        * <p>Note: In the current implementation, only one main dictionary can 
be used at a time. In addition, 
+        * in this version, suggestions for misspelled words do not include 
words from the user dictionary.</p>
+        *
+        * @includeExample Examples/Flex/TextEditor/src/TextEditor.mxml -noswf
+        * 
+        * @playerversion Flash 10
+        * @langversion 3.0
+        */
+       public class SpellChecker implements ISpellChecker
+       {
+               private var _spellingEngine:SquigglyEngine;
+               private var _rule:LinguisticRule;
+               private var _dict:SquigglyDictionary;
+               
+               private var _udEngine:UserDictionaryEngine;
+               
+               /**
+                * Constructs a new <code>SpellChecker</code> object that 
performs language sensitive spell checking.
+                * 
+                * @param spellingDictionary A <code>ISpellingDictionary</code> 
interface to be used by this <code>SpellChecker</code>.
+                * For example, you can pass a <code>HunspellDictonary</code> 
object which already implemented the <code>ISpellingDictionary</code> interface 
to this constructor.
+                *
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */
+               public function 
SpellChecker(spellingDictionary:ISpellingDictionary)
+               {
+                       _rule = spellingDictionary.linguisticRule;
+                       _dict = spellingDictionary.squigglyDictionary;
+                       _spellingEngine = new SquigglyEngine(_rule,_dict);
+                       _spellingEngine.fastMode = true;
+                       _udEngine = new UserDictionaryEngine();
+               }
+
+               /**
+                * Add a user dictionary to the SpellChecker.
+                * 
+                * @return <code>true</code> if the operation is successful. 
<code>false</code> if the operation failed.
+                * @param userDictionary A <code>UserDictionary</code> object 
to be added to this <code>SpellChecker</code>.
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               public function 
addUserDictionary(userDictionary:UserDictionary):Boolean
+               {
+                       return 
_udEngine.addDictionary(userDictionary.internalUserDictionary);
+               }
+               
+               /**
+                * Remove a user dictionary from the SpellChecker.
+                * 
+                * @return <code>true</code> if the operation is successful. 
<code>false</code> if the operation failed.
+                * @param userDictionary A <code>UserDictionary</code> object 
to be removed from this <code>SpellChecker</code>.
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               public function 
removeUserDictionary(userDictionary:UserDictionary):Boolean
+               {
+                       return 
_udEngine.removeDictionary(userDictionary.internalUserDictionary);
+               }
+
+               
+               /**
+                * Spellchecks a word.
+                * 
+                * @param word  A string containing a word.
+                *                      <p><strong>Notes:</strong></p>
+                *                              <ul>
+                *                                      <li>
+                *                                              Please be aware 
that it is the caller's responsibility to break down sentences into words that 
can be handled by this method.
+                *                                      For example, this 
method does not support punctuation marks such as comma, colon, quotes, etc.
+                *                                              Punctuation 
marks should be stripped out from the word prior to calling this method.
+                *                                              If a word 
contains white spaces (such as a regular space or non-breaking space), the word 
will be considered as misspelled.
+                *                                      </li>
+                *                              </ul>
+                * @return <code>true</code> if the word is properly spelled. 
<code>false</code> if the word is misspelled.
+                *
+                * @includeExample Examples/Flex/CheckWord/src/CheckWord.mxml 
-noswf
+                * 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */
+               public function checkWord(word:String):Boolean
+               {
+                       return (_spellingEngine==null)? 
false:(_udEngine.spell(word) || _spellingEngine.spell(word));
+               }
+               
+               /**
+                * Gets suggestions for a misspelled word. 
+                *
+                * @param word  A string containing a misspelled word.
+                *      
+                * @return      A list of suggestions. <p>Up to ten suggestions 
may be returned.</p>
+                *
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */
+               public function getSuggestions(word:String):Array
+               {
+                       return (_spellingEngine==null)? 
null:_spellingEngine.suggest(word);
+               }
+
+
+               /** @private
+                * The version of this <code>SpellChecker</code> class.
+                * 
+                * <p>Example: "0.3"</p>
+                * 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */
+               public static function get version():String
+               {
+                       return "0.5";
+               }
+
+
+
+               /**
+                * This property controls if Title Case Words should be 
considered as properly spelled.
+                * 
+                * <p>The default value is <code>false</code>.</p> 
+                *
+                * <p>If <code>ignoreTitleCase</code> is set to 
<code>true</code>, any words with first character capped are always considered 
as properly spelled.</p>
+                * <p>If <code>ignoreWordWithTitleCase</code> is set to 
<code>true</code>, "Spel" will be considered as properly spelled even if the 
dictionary does not contain "spel" or "Spel".
+                * If <code>ignoreWordWithTitleCase</code> is set to 
<code>false</code>, "Spel" will be considered as mispelled unless the 
dictionary contain "Spel".</p>
+                *
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */
+               private function get ignoreWordWithTitleCase():Boolean
+               {
+                       return _spellingEngine.ignoreCappedWord;
+               }
+               private function set ignoreWordWithTitleCase(value:Boolean):void
+               {
+                       _spellingEngine.ignoreCappedWord = value;
+               }
+               
+               /**
+                * This property controls if words in all upper case should be 
considered as properly spelled or not.
+                * 
+                * <table class="innertable">
+                *              <tr>
+                *                      <td 
align="center"><strong><code>ignoreWordWithAllUpperCase</code></strong></td>
+                *                      <td 
align="center"><strong>&#160;</strong></td>
+                *                      <td 
align="center"><strong>Description</strong></td>
+                *              </tr>
+                *              <tr>
+                *                      <td><code>false</code></td>
+                *                      <td>Default</td>
+                *                      <td><p>Words with all characters in 
upper case are checked against the dictionary for proper spelling.</p>
+                *                              <p>Example: if 
<code>ignoreWordWithAllUpperCase = false</code>, "MISPEL" will be checked for 
proper spelling.</p></td>
+                *              </tr>
+                *              <tr>
+                *                      <td><code>true</code></td>
+                *                      <td>&#160;</td>
+                *                      <td><p>Any words with all characters in 
upper case are always considered as properly spelled,
+                *                                      no matter whether the 
word is in the dictionary or not.</p>
+                *                              <p>Example: if 
<code>ignoreWordWithAllUpperCase = true</code>, "MISPEL" will be considered as 
properly spelled.</p></td>
+                *              </tr>
+                *      </table>
+                *
+                *      <!--
+                *      <p>Following table contains some examples to show how 
this property works.</p>
+                *      <p>Assumption: <code>ignoreWordWithTitleCase</code> = 
<code>false</code></p>
+                *      <table class="innertable">
+                *              <tr>
+                *                      <td rowspan=2 
align="center"><strong>Word in dictionary</strong></td>
+                *                      <td rowspan=2 
align="center"><strong>Input word</strong></td>
+                *                      <td colspan=2 
align="center"><strong><code>ignoreWordWithAllUpperCase</code></strong></td>
+                *              </tr>
+                *              <tr>
+                *                      <td 
align="center"><strong><code>false</code></strong></td>
+                *                      <td 
align="center"><strong><code>true</code></strong></td>
+                *              </tr>
+                *              <tr>
+                *                      <td rowspan="4">apple</td>
+                *                      <td>apple</td>
+                *                      <td>Properly spelled</td>
+                *                      <td>Properly spelled</td>
+                *              </tr>
+                *              <tr>
+                *                      <td>APPLE</td>
+                *                      <td>Properly spelled</td>
+                *                      <td>Properly spelled</td>
+                *              </tr>
+                *              <tr>
+                *                      <td>Apple</td>
+                *                      <td>Properly spelled</td>
+                *                      <td>Properly spelled</td>
+                *              </tr>
+                *              <tr>
+                *                      <td>aPPLe</td>
+                *                      <td>Properly spelled</td>
+                *                      <td>Properly spelled</td>
+                *              </tr>
+                *              <tr>
+                *                      <td rowspan="4">NATO</td>
+                *                      <td>nato</td>
+                *                      <td>Properly spelled</td>
+                *                      <td>Properly spelled</td>
+                *              </tr>
+                *              <tr>
+                *                      <td>NATO</td>
+                *                      <td>Properly spelled</td>
+                *                      <td>Properly spelled</td>
+                *              </tr>
+                *              <tr>
+                *                      <td>Nato</td>
+                *                      <td>Properly spelled</td>
+                *                      <td>Properly spelled</td>
+                *              </tr>
+                *              <tr>
+                *                      <td>NaTo</td>
+                *                      <td>Properly spelled</td>
+                *                      <td>Properly spelled</td>
+                *              </tr>
+                *              <tr>
+                *                      <td rowspan="4">London</td>
+                *                      <td>london</td>
+                *                      <td>Properly spelled</td>
+                *                      <td>Properly spelled</td>
+                *              </tr>
+                *              <tr>
+                *                      <td>LONDON</td>
+                *                      <td>Properly spelled</td>
+                *                      <td>Properly spelled</td>
+                *              </tr>
+                *              <tr>
+                *                      <td>London</td>
+                *                      <td>Properly spelled</td>
+                *                      <td>Properly spelled</td>
+                *              </tr>
+                *              <tr>
+                *                      <td>LoNDoN</td>
+                *                      <td>Properly spelled</td>
+                *                      <td>Properly spelled</td>
+                *              </tr>
+                *              <tr>
+                *                      <td rowspan="4">iPhone</td>
+                *                      <td>iphone</td>
+                *                      <td>Properly spelled</td>
+                *                      <td>Properly spelled</td>
+                *              </tr>
+                *              <tr>
+                *                      <td>IPHONE</td>
+                *                      <td>Properly spelled</td>
+                *                      <td>Properly spelled</td>
+                *              </tr>
+                *              <tr>
+                *                      <td>IPhone</td>
+                *                      <td>Properly spelled</td>
+                *                      <td>Properly spelled</td>
+                *              </tr>
+                *              <tr>
+                *                      <td>iPHoNe</td>
+                *                      <td>Properly spelled</td>
+                *                      <td>Properly spelled</td>
+                *              </tr>
+                *      </table>
+                *      -->
+                * 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */
+               public function get ignoreWordWithAllUpperCase():Boolean
+               {
+                       return _spellingEngine.ignoreAllUpperCase;
+               }
+               public function set 
ignoreWordWithAllUpperCase(value:Boolean):void
+               {
+                       _spellingEngine.ignoreAllUpperCase = value;
+               }
+               
+               
+               /**
+                * This property controls if words with numbers, such as 
windows95, should be considered as properly spelled.
+                * 
+                * <table class="innertable">
+                *              <tr>
+                *                      <td 
align="center"><strong><code>ignoreWordWithNumber</code></strong></td>
+                *                      <td 
align="center"><strong>&#160;</strong></td>
+                *                      <td 
align="center"><strong>Description</strong></td>
+                *              </tr>
+                *              <tr>
+                *                      <td><code>false</code></td>
+                *                      <td>Default</td>
+                *                      <td><p>Any words containing digits are 
checked for proper spelling.</p>
+                *                              <p>Example: If 
<code>ignoreWordWithNumber</code> = <code>false</code>, "mispel99" will be 
checked for proper spelling.</p>
+                *                      </td>
+                *              </tr>
+                *              <tr>
+                *                      <td><code>true</code></td>
+                *                      <td>&#160;</td>
+                *                      <td><p>Words containing digits are 
always ignored/skipped regardless of the dictionary.</p>
+                *                              <p>Example: If 
<code>ignoreWordWithNumber</code> = <code>true</code>, "mispel99" will be 
considered as properly spelled.</p>
+                *                      </td>
+                *              </tr>
+                *      </table>
+                *
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */
+               public function get ignoreWordWithNumber():Boolean 
+               {
+                       return _spellingEngine.ignoreWordWithNumber;
+               }
+               public function set ignoreWordWithNumber(value:Boolean):void
+               {
+                       _spellingEngine.ignoreWordWithNumber = value;
+               }
+
+
+               /**
+                * <span class="hide">
+                * TODO: Decide this block based API.
+                * Check a block of text and find out all misspelled words in 
the text.
+                * 
+                * 
+                * @param text  A string containing a block of texts.
+                * @param separators    An array of separators.
+                *
+                * @return An Array of misspelled word tokens, each token 
contains the startIndex and length
+                *
+                * @playerversion Flash 10
+                * @langversion 3.0
+                * 
+                * Option 1:
+                *
+                * public function checkText(text:String, 
separators:Array):Array
+                * {
+                * }
+                * 
+                * Option 2:
+                *
+                * public function checkText(text:String, 
tokenizer:ITokenizer):SpellResultIterator
+                * {
+                * }
+                * </span>
+                */
+       }
+}
+

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/4e4f9830/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/UserDictionary.as
----------------------------------------------------------------------
diff --git 
a/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/UserDictionary.as
 
b/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/UserDictionary.as
new file mode 100644
index 0000000..d22f42c
--- /dev/null
+++ 
b/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/UserDictionary.as
@@ -0,0 +1,113 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 com.adobe.linguistics.spelling
+{
+       import __AS3__.vec.Vector;
+       
+       import com.adobe.linguistics.spelling.UserDictionaryInternal;
+       /**
+        * Represents a user dictionary.
+        *
+        * <p>This class represents a user dictionary that is used by the 
<code>SpellingService</code> class. This class itself is an in-memory object
+        * and doesn't store persistent data. However, developers can 
import/export a <code>UserDictionary</code> object from/to a vector of String, 
+        * and use other flash classes to keep the data persistent. You may 
want to consider using one of the following options for permanent storage:
+        *
+        * <ul>
+        *      <li>SharedObject, which is used in our SpellingUI class to 
store words added from the ContextMenu</li>
+        *      <li>File/FileStream, which is used in our UserDictionaryExample 
and can be shared across AIR applications</li>
+        *      <li>Server side storage, for example database so that it can be 
shared across users</li>
+        * </ul>
+        * </p>
+        * <p>If you are using our SpellingUI class the UserDictionary will be 
created behind the scene and stored in a SharedObject.</p>
+        */      
+       public class UserDictionary
+       {
+               private var _ud:UserDictionaryInternal;
+               
+               /**
+                * @private
+                */
+               public function get 
internalUserDictionary():UserDictionaryInternal
+               {
+                       return _ud;
+               }
+               
+               /**
+                * Constructs a new <code>UserDictionary</code> which can later 
be added to a <code>SpellingService</code> object.
+                *
+                * @param wordList A vector of words (String) to be added as 
the initial entries of this <code>UserDictionary</code>
+                * @see UserDictionary.wordList
+                *
+                */
+               public function UserDictionary(wordList:Vector.<String>=null)
+               {
+                       var array:Array = new Array();
+                       if (wordList) {
+                               for each (var w:String in wordList)
+                                       array.push(w);
+                       }
+                       
+                       _ud = new UserDictionaryInternal(array);
+               }
+
+               /**
+                * Add a word to the user dictionary.
+                * 
+                * @param word A word to be added to this 
<code>UserDictionary</code>.
+                * @return <code>true</code> if the operation is successful. 
<code>false</code> if the operation is failed, for example if the word is 
already added.
+                * @see UserDictionary.removeWord()
+                * 
+                */             
+               public function addWord(word:String):Boolean    
+               {
+                       return _ud.addWord(word);
+               }
+
+               /**
+                * Removes a word from the user dicitonary.
+                * 
+                * @param word A word to be removed from this 
<code>UserDictionary</code>.
+                * @return True if the operation was successful, false if the 
operation was failed, for example if the word doesn't exist in the dictionary.
+                * @see UserDictionary.addWord()
+                * 
+                */             
+               public function removeWord(word:String):Boolean
+               {
+                       return _ud.removeWord(word);
+               }
+
+               /**
+                * All words in this user dictionary.
+                *
+                * @return A vector of String that contains all words in this 
user dictionary
+                * 
+                */             
+               public function get wordList():Vector.<String>
+               {
+                       var result:Vector.<String> = new Vector.<String>();
+                       var array:Array = _ud.wordList;
+                       
+                       for each (var w:String in array)
+                               result.push(w);
+                       
+                       return result;
+               }
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/4e4f9830/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/UserDictionaryInternal.as
----------------------------------------------------------------------
diff --git 
a/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/UserDictionaryInternal.as
 
b/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/UserDictionaryInternal.as
new file mode 100644
index 0000000..d4034a8
--- /dev/null
+++ 
b/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/UserDictionaryInternal.as
@@ -0,0 +1,115 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 com.adobe.linguistics.spelling
+{
+       import com.adobe.linguistics.spelling.utils.WordList;
+       
+       /**
+        * Represents a user dictionary.
+        *
+        * <p>This class represents a user dictionary that is used by the 
<code>SpellChecker</code> class. This class itself is an in-memory object
+        * and doesn't store persistent data. However, developers can 
import/export a <code>UserDictionaryInternal</code> object from/to an Array of 
String, 
+        * and use other flash classes to keep the data persistent. You may 
want to consider using one of the following options for permanent storage:
+        *
+        * <ul>
+        *      <li>SharedObject, which is used in our SpellUI class to store 
words added from the ContextMenu</li>
+        *      <li>File/FileStream, which is used in our 
UserDictionaryInternalExample and can be shared across AIR applications</li>
+        *      <li>Server side storage, for example database so that it can be 
shared across users</li>
+        * </ul>
+        * </p>
+        * <p>If you are using our SpellUI class the UserDictionaryInternal 
will be created behind the scene and stored in a SharedObject.</p>
+        * @includeExample 
Examples/Air/UserDictionaryInternalExample/src/UserDictionaryInternalExample.mxml
 -noswf
+        * @playerversion Flash 10
+        * @langversion 3.0
+        */      
+       public class UserDictionaryInternal
+       {
+               /**
+                @private
+                (This property is for Squiggly Developer use only.)
+                */
+               public var _wordList:WordList;
+               
+               /**
+                * Constructs a new <code>UserDictionaryInternal</code> which 
can later be added to a <code>SpellChecker</code> object.
+                *
+                * @param wordList An array of words (String) to be added as 
the initial entries of this <code>UserDictionaryInternal</code>
+                * @see UserDictionaryInternal.wordList
+                *
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */
+               public function UserDictionaryInternal(wordList:Array=null)
+               {
+                       // TODO: exception if has some problem with insert
+                       _wordList= new WordList();
+                       if (wordList) {
+                               for each (var w:String in wordList)
+                               _wordList.insert(w); 
+                       }
+               }
+               
+               /**
+                * Add a word to the user dictionary.
+                * 
+                * @param word A word to be added to this 
<code>UserDictionaryInternal</code>.
+                * @return <code>true</code> if the operation is successful. 
<code>false</code> if the operation is failed.
+                * @see UserDictionaryInternal.removeWord()
+                * 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               public function addWord(word:String):Boolean    
+               {
+                       return _wordList.insert(word);
+               }
+               
+               /**
+                * Removes a word from the user dicitonary.
+                * 
+                * @param word A word to be removed from this 
<code>UserDictionaryInternal</code>.
+                * @return <code>true</code> if the operation is successful. 
<code>false</code> if the operation is failed.
+                * @see UserDictionaryInternal.addWord()
+                * 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               public function removeWord(word:String):Boolean
+               {
+                       return _wordList.remove(word);
+               }
+               
+               /**
+                * List of all words in this user dictionary.
+                *
+                * @return An Array of String that contains all words in this 
user dictionary
+                * 
+                * @playerversion Flash 10
+                * @langversion 3.0
+                */             
+               public function get wordList():Array
+               {
+                       // TODO: make sure no return by reference
+                       return _wordList.toArray();
+               }
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/4e4f9830/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/core/DictionaryManager.as
----------------------------------------------------------------------
diff --git 
a/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/core/DictionaryManager.as
 
b/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/core/DictionaryManager.as
new file mode 100644
index 0000000..cef5b0d
--- /dev/null
+++ 
b/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/core/DictionaryManager.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 com.adobe.linguistics.spelling.core
+{
+       import com.adobe.linguistics.spelling.core.container.HashTable;
+       public class DictionaryManager
+       {
+               private var _table:Array;
+               public function DictionaryManager()
+               {
+                       _table = new Array();
+               }
+               
+               public function addDictionary(dict:SquigglyDictionary):Boolean {
+                       if ( dict == null ) return false;
+                       for ( var i:int = 0; i< _table.length; ++i ) {
+                               if ( dict == _table[i] )
+                                       return false;
+                       }
+                       _table.push(dict);
+                       return true;
+               }
+               
+               public function 
removeDictionary(dict:SquigglyDictionary):Boolean {
+                       if ( dict == null) return false;
+                       for ( var i:int = 0; i< _table.length; ++i ) {
+                               if ( dict == _table[i] ) {
+                                       _table = _table.slice(i,1); // remove 
dictionary from the table.
+                               }
+                       }
+                       return true;
+                       
+               }
+               
+               public function get dictonaryList():Array {
+                       return this._table;
+               }
+               
+               public function isEmpty():Boolean {
+                       return (this._table == null ) ? true : false;
+               }
+               
+               public function get size():int {
+                       return this._table.length;
+               }
+               
+               public function lookup( word:String ) :HashEntry {
+                       for ( var i:int = 0; i < _table.length; ++i ) {
+                               if ( _table[i].containsKey(word) )
+                                       return _table[i].getElement(word);
+                       }
+                       return null;
+               }
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/4e4f9830/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/core/HashEntry.as
----------------------------------------------------------------------
diff --git 
a/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/core/HashEntry.as
 
b/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/core/HashEntry.as
new file mode 100644
index 0000000..64ac685
--- /dev/null
+++ 
b/Squiggly/main/SpellingEngine/src/com/adobe/linguistics/spelling/core/HashEntry.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 com.adobe.linguistics.spelling.core
+{
+       import com.adobe.linguistics.spelling.core.utils.StringUtils;
+       public class HashEntry
+       {
+               private var _affStr:String; // affix flag vector
+               private var _nextEntry:HashEntry;
+               
+               // Not sure now..just leave it here.
+               private var _variableFields:String;   // variable fields (only 
for special pronounciation yet)
+               
+               
+               public function HashEntry(affStr:String=null,desc:String = null)
+               {
+                       this._affStr = StringUtils.sort(affStr);
+                       this._variableFields = desc;
+                       this._nextEntry = null;
+               }
+               
+               public function addEntry(affStr:String=null,desc:String = 
null):Boolean {
+                       if ( this._nextEntry != null ) return false;
+                       this._nextEntry = new HashEntry(affStr, desc);
+                       return true;
+               }
+               
+               public function get next():HashEntry {
+                       return this._nextEntry;
+               }
+               
+               public function get affixFlagVector():String {
+                       return this._affStr;
+               }
+               
+               public function set affixFlagVector(affStr:String):void {
+                       this._affStr = StringUtils.sort(affStr);
+               }
+               
+               public function get variableFields():String {
+                       return this._variableFields;
+               }
+               
+               public function set variableFields( varF:String) :void {
+                       this._variableFields = varF;
+               }
+               
+               public function testAffix(flag:Number):Boolean {
+                       if ( this._affStr == null ) return false;
+                       var mid:int, left:int=0, right:int= this._affStr.length 
- 1;
+                       while ( left <= right ) {
+                               mid = (right+left)/2;
+                               if ( this._affStr.charCodeAt(mid) == flag )
+                                       return true;
+                               if ( flag < this._affStr.charCodeAt(mid) ) 
right = mid -1;
+                               else left = mid + 1;
+                       }
+                       return false;
+               }
+
+               public function testAffixs(flags:Array):Boolean {
+                       for ( var i:int; i< flags.length; ++i) {
+                               if( testAffix(flags[i]) )
+                                       return true;
+                       }
+                       return false;
+               }
+               //For develepors only, this function is made so that when 
flagmode=flag_long flags can be viewed.
+               public function printFlag(flag:Number):void{
+                       var result:String =  String.fromCharCode(flag>>8) + 
String.fromCharCode(flag-((flag>>8)<<8));
+                       
+               }
+
+               
+               static public function TESTAFF(affix:String, 
flag:Number):Boolean {
+                       if ( affix == null ) return false;
+                       affix =  StringUtils.sort(affix);
+                       var mid:int, left:int=0, right:int= affix.length - 1;
+                       while ( left <= right ) {
+                               mid = (right+left)/2;
+                               if ( affix.charCodeAt(mid) == flag )
+                                       return true;
+                               if ( flag < affix.charCodeAt(mid) ) right = mid 
-1;
+                               else left = mid + 1;
+                       }
+                       return false;
+                       
+               }
+       }
+}
\ No newline at end of file

Reply via email to