You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ah...@apache.org on 2014/04/25 07:27:21 UTC

[16/18] Squiggly spell checker donation from Adobe Systems Inc.

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/a52655ac/Squiggly/ane/Squiggly/AdobeLinguisticUtils/src/com/adobe/linguistics/utils/TextFilter.as
----------------------------------------------------------------------
diff --git a/Squiggly/ane/Squiggly/AdobeLinguisticUtils/src/com/adobe/linguistics/utils/TextFilter.as b/Squiggly/ane/Squiggly/AdobeLinguisticUtils/src/com/adobe/linguistics/utils/TextFilter.as
new file mode 100644
index 0000000..e906527
--- /dev/null
+++ b/Squiggly/ane/Squiggly/AdobeLinguisticUtils/src/com/adobe/linguistics/utils/TextFilter.as
@@ -0,0 +1,90 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/* 
+* ToDo: Create ASDoc style comment to generate the API document.
+*/
+package com.adobe.linguistics.utils
+{
+	/**
+	 * <p>This class provides some methods to filter out certain characters from the text.</p>
+	 */
+	public class TextFilter
+	{
+		public static const kTextChar_DiscretionaryHyphen:int 	= 0x00AD;
+		public static const kTextChar_BreakRunInStyle:int		= 0x0003;
+		public static const kTextChar_IndentToHere:int 			= 0x0007;
+		public static const kTextChar_InvisibleSeparator:int 	= 0x2063;
+		public static const kTextChar_ZeroWidthNonJoiner:int 	= 0x200C;
+		public static const kTextChar_ZeroWidthJoiner:int		= 0x200D;
+		public static const kTextChar_ZeroSpaceBreak:int 		= 0x200B;
+		public static const kTextChar_ZeroSpaceNoBreak:int		= 0xFEFF;
+		public static const kTextChar_RightSingleQuotationMark:int = 0x2019;
+		public static const kTextChar_Apostrophe:int			= 0x0027;
+		public static const kTextChar_NoBreakHyphen:int			= 0x2011;
+		public static const kTextChar_UnicodeHyphen:int			= 0x2010;
+		public static const kTextChar_HyphenMinus:int			= 0x002D;
+
+		
+		public function TextFilter()
+		{
+		}
+		
+		public function filterWord(inpWord:String):String
+		{
+			return replaceIgnoredCharacter((removeIgnoredCharacter(inpWord)));	
+		}
+		private function removeIgnoredCharacter(inpWord:String):String
+		{
+			if(!inpWord || inpWord.length<=0) 
+				return inpWord;
+			
+			var tempWord:String= new String;
+
+			for(var i:int=0; i< inpWord.length; i++)
+			{
+				if (   inpWord.charCodeAt(i)==kTextChar_DiscretionaryHyphen
+					|| inpWord.charCodeAt(i)==kTextChar_BreakRunInStyle
+					|| inpWord.charCodeAt(i)==kTextChar_IndentToHere
+					|| inpWord.charCodeAt(i)==kTextChar_InvisibleSeparator
+					|| inpWord.charCodeAt(i)==kTextChar_ZeroWidthNonJoiner
+					|| inpWord.charCodeAt(i)==kTextChar_ZeroWidthJoiner
+					|| inpWord.charCodeAt(i)==kTextChar_ZeroSpaceBreak
+					|| inpWord.charCodeAt(i)==kTextChar_ZeroSpaceNoBreak
+					)
+				continue;
+				
+				tempWord=tempWord+inpWord.charAt(i); 
+			}
+			return tempWord;		
+		}
+		
+		private function replaceIgnoredCharacter(inpWord:String):String
+		{
+			for(var i:int=0; inpWord && i<inpWord.length; i++)
+			{
+				if(inpWord.charCodeAt(i)==kTextChar_RightSingleQuotationMark)
+					inpWord= inpWord.slice(0,i)+String.fromCharCode(kTextChar_Apostrophe)+inpWord.slice(i+1);
+				else if(inpWord.charCodeAt(i)==kTextChar_NoBreakHyphen || inpWord.charCodeAt(i)==kTextChar_UnicodeHyphen)
+					inpWord= inpWord.slice(0,i)+String.fromCharCode(kTextChar_HyphenMinus)+inpWord.slice(i+1);;
+			}
+			return inpWord;
+		}
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/a52655ac/Squiggly/ane/Squiggly/AdobeLinguisticUtils/src/com/adobe/linguistics/utils/TextTokenizer.as
----------------------------------------------------------------------
diff --git a/Squiggly/ane/Squiggly/AdobeLinguisticUtils/src/com/adobe/linguistics/utils/TextTokenizer.as b/Squiggly/ane/Squiggly/AdobeLinguisticUtils/src/com/adobe/linguistics/utils/TextTokenizer.as
new file mode 100644
index 0000000..1c68256
--- /dev/null
+++ b/Squiggly/ane/Squiggly/AdobeLinguisticUtils/src/com/adobe/linguistics/utils/TextTokenizer.as
@@ -0,0 +1,400 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/* 
+* ToDo: Create ASDoc style comment to generate the API document.
+*/
+
+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,
+				0x2011,
+				0x0003,
+				0x0007
+			];
+			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;
+				//trace(this._textHolder.substring(begin,end));
+				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/a52655ac/Squiggly/ane/Squiggly/AdobeLinguisticUtils/src/com/adobe/linguistics/utils/Token.as
----------------------------------------------------------------------
diff --git a/Squiggly/ane/Squiggly/AdobeLinguisticUtils/src/com/adobe/linguistics/utils/Token.as b/Squiggly/ane/Squiggly/AdobeLinguisticUtils/src/com/adobe/linguistics/utils/Token.as
new file mode 100644
index 0000000..fd93c8e
--- /dev/null
+++ b/Squiggly/ane/Squiggly/AdobeLinguisticUtils/src/com/adobe/linguistics/utils/Token.as
@@ -0,0 +1,95 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/* 
+* ToDo: Create ASDoc style comment to generate the API document.
+*/
+
+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/a52655ac/Squiggly/ane/Squiggly/AdobeSpellingEngine/src/com/adobe/linguistics/spelling/UserDictionary.as
----------------------------------------------------------------------
diff --git a/Squiggly/ane/Squiggly/AdobeSpellingEngine/src/com/adobe/linguistics/spelling/UserDictionary.as b/Squiggly/ane/Squiggly/AdobeSpellingEngine/src/com/adobe/linguistics/spelling/UserDictionary.as
new file mode 100644
index 0000000..330ba4d
--- /dev/null
+++ b/Squiggly/ane/Squiggly/AdobeSpellingEngine/src/com/adobe/linguistics/spelling/UserDictionary.as
@@ -0,0 +1,173 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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;
+	import com.adobe.linguistics.spelling.utils.WordList;
+	
+	import flash.utils.Dictionary;
+
+	/**
+	 * 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 var _udMap:Dictionary;
+		/**
+		 * @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(wordListMap:Array=null)
+		{
+			_udMap= new Dictionary();
+			
+			if(wordListMap)
+			{
+				for (var k:String in wordListMap)
+				{
+					//var wordList:Vector.<Object>= wordListMap[k] as Vector.<Object>;
+					var array:Array = new Array();
+					if (wordListMap[k]/*wordList*/) 
+					{
+						for each (var w:Object in wordListMap[k]/*wordList*/)
+						array.push(w.toString());
+					}
+					_udMap[k] = new UserDictionaryInternal(k, 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, language:String = "en_US"):Boolean	
+		{
+			if(_udMap[language]==null)
+				_udMap[language]=new UserDictionaryInternal(language);
+			return _udMap[language].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, language:String = "en_US"):Boolean
+		{
+			
+			return _udMap[language].removeWord(word);
+		}
+
+		/**
+		 * All words in this user dictionary.
+		 *
+		 * @return A vector of String that contains all words in this user dictionary
+		 * 
+		 */		
+		public function getWordList(language:String):WordList
+		{
+			if(language==null || language == "")
+				return null;
+			//var result:Vector.<String> = new Vector.<String>();
+			
+			//for each (var w:String in array)
+			//	result.push(w);
+			var udInternal:UserDictionaryInternal=_udMap[language];
+			
+			return (udInternal? udInternal.wordList as WordList :null);
+		}
+		
+		public function get wordListMap():Array
+		{
+			var result:Array = new Array();
+			for each(var k:Object in _udMap)
+			{
+				var lang:String= k._language;
+				var array:Array= (k.wordList as WordList).toArray();
+				var wordVector:Vector.<String>= new Vector.<String>;
+				if (array) 
+				{
+					for each (var w:String in array)
+					wordVector.push(w);
+				}
+				result[lang] = wordVector;
+				
+			}
+			return result;
+		}
+        
+        public function get wordList():Array
+        {
+            var result:Array = new Array();
+            for each(var k:Object in _udMap)
+            {
+                var lang:String= k._language;
+                var array:Array= (k.wordList as WordList).toArray();
+                var wordVector:Vector.<String>= new Vector.<String>;
+                if (array) 
+                {
+                    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/a52655ac/Squiggly/ane/Squiggly/AdobeSpellingEngine/src/com/adobe/linguistics/spelling/UserDictionaryInternal.as
----------------------------------------------------------------------
diff --git a/Squiggly/ane/Squiggly/AdobeSpellingEngine/src/com/adobe/linguistics/spelling/UserDictionaryInternal.as b/Squiggly/ane/Squiggly/AdobeSpellingEngine/src/com/adobe/linguistics/spelling/UserDictionaryInternal.as
new file mode 100644
index 0000000..a5225fe
--- /dev/null
+++ b/Squiggly/ane/Squiggly/AdobeSpellingEngine/src/com/adobe/linguistics/spelling/UserDictionaryInternal.as
@@ -0,0 +1,120 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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;
+		public var _language:String;
+		
+		/**
+		 * 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(language:String, wordList:Array=null)
+		{
+			if(language==null || language=="")
+			{
+				//todo: throw error
+				return;
+			}
+			_language= language;
+			// TODO: exception if has some problem with insert
+			_wordList= new WordList(_language);
+			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():WordList
+		{
+			// TODO: make sure no return by reference
+			return _wordList;
+		}
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/a52655ac/Squiggly/ane/Squiggly/AdobeSpellingEngine/src/com/adobe/linguistics/spelling/core/UserDictionaryEngine.as
----------------------------------------------------------------------
diff --git a/Squiggly/ane/Squiggly/AdobeSpellingEngine/src/com/adobe/linguistics/spelling/core/UserDictionaryEngine.as b/Squiggly/ane/Squiggly/AdobeSpellingEngine/src/com/adobe/linguistics/spelling/core/UserDictionaryEngine.as
new file mode 100644
index 0000000..a8a60bc
--- /dev/null
+++ b/Squiggly/ane/Squiggly/AdobeSpellingEngine/src/com/adobe/linguistics/spelling/core/UserDictionaryEngine.as
@@ -0,0 +1,75 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package com.adobe.linguistics.spelling.core
+{
+	import com.adobe.linguistics.spelling.UserDictionary;
+	import com.adobe.linguistics.spelling.utils.WordList;
+	
+	public class UserDictionaryEngine
+	{
+		// Private properties
+		private var _dictionaryList:Array;		// get only
+		private var _userDict:UserDictionary;
+
+		public function UserDictionaryEngine(ud:UserDictionary=null)
+		{
+			_dictionaryList = new Array();
+		}
+		public function addDictionary(userDictionary:UserDictionary):Boolean
+		{
+			if ( (userDictionary == null) ) return false;
+			
+			for ( var i:int = 0;i < _dictionaryList.length; ++i ) {
+				if ( userDictionary == _dictionaryList[i] )
+					return false;
+			} 
+			_dictionaryList.push(userDictionary);
+			return true;
+		}
+
+		public function removeDictionary(userDictionary:UserDictionary):Boolean
+		{
+			
+			for ( var i:int =0; i < _dictionaryList.length; ++i ) {
+				if ( userDictionary == _dictionaryList[i] ) {
+					_dictionaryList.splice(i,1);
+					return true;
+				}
+			}
+			return false;
+		}
+		
+		public function spell( word:String, language:String ) :Boolean {
+			var result:Boolean = false;
+			for ( var i:int =0; (i < _dictionaryList.length) && (!result);++i ) {
+				_userDict = _dictionaryList[i];
+				if ( _userDict ) {
+					var wordList:WordList=_userDict.getWordList(language);
+					if(wordList)
+						result = (wordList.lookup(word) != -1);
+					else
+						result=false;
+				}
+			}
+			return result;
+		}
+
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/a52655ac/Squiggly/ane/Squiggly/AdobeSpellingEngine/src/com/adobe/linguistics/spelling/utils/WordList.as
----------------------------------------------------------------------
diff --git a/Squiggly/ane/Squiggly/AdobeSpellingEngine/src/com/adobe/linguistics/spelling/utils/WordList.as b/Squiggly/ane/Squiggly/AdobeSpellingEngine/src/com/adobe/linguistics/spelling/utils/WordList.as
new file mode 100644
index 0000000..b405551
--- /dev/null
+++ b/Squiggly/ane/Squiggly/AdobeSpellingEngine/src/com/adobe/linguistics/spelling/utils/WordList.as
@@ -0,0 +1,128 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/* 
+* ToDo: Create ASDoc style comment to generate the API document.
+*/
+
+package com.adobe.linguistics.spelling.utils
+{
+	[RemoteClass]
+	public class WordList
+	{
+		private var _words:Array;
+		private var _sorted:Boolean;  // TODO: Shouldn't be always sorted?
+		private var _language:String;
+		
+		public function WordList(language:String, wordsList:Array=null)
+		{
+			if(wordsList!=null) {
+				_words=wordsList;	
+			}else {
+				_words=new Array();
+			}
+			if(language!=null && language!="")
+				_language=language;
+		}
+		
+		public function toArray():Array {
+			return this._words;
+		}
+
+		public function set data(inData:Array):void {
+			this._words = inData;
+		}
+		
+		public function get data():Array {
+			return this._words;
+		}
+		
+		public function insert(value:String):Boolean {
+			if( _words.length==0 ) {
+				_words.push(value)
+				return true;
+			}
+			var low:uint= 0;
+			var high:uint= _words.length-1;
+			var middle:uint= (low+high)/2;
+			while (low<high) {
+				if(_words[middle]<value) {
+					low=middle+1;
+				}else {
+					high=middle;
+				}
+				middle= (low+high)/2;
+			}
+			if( (low <= _words.length-1) && (_words[low]!=value) ) {
+				var pos:uint=_words[low]>value?low:low+1;
+				_words.splice(pos,0,value);
+				return true;
+			}else {
+				return false;
+			}
+			_words.push(value);
+			return true;
+		}
+		
+		public function remove(value:String):Boolean {
+			var pos:int= lookup(value);
+			if( pos!= -1 ) {
+				_words.splice(pos,1);
+				return true;
+			}else {
+				return false;
+			}
+		}
+		
+		//binary search to find the word.
+		public function lookup(value:String):int {
+			if(_words.length==0) {
+				return -1;
+			}
+			var low:uint= 0;
+			var high:uint= _words.length-1;
+			var middle:uint= (low+high)/2;
+			while (low<high) {
+				if(_words[middle]<value) {
+					low=middle+1;
+				}else {
+					high=middle;
+				}
+				middle= (low+high)/2;
+			}
+			if( (low <= _words.length-1) && (_words[low]==value) ) {
+				return low;
+			}else {
+				return -1;
+			}
+			
+		}
+		
+		public function mergeWordLists(list1:WordList,list2:WordList):WordList {
+			return null;
+		}
+
+		public function get language():String
+		{
+			return _language;
+		}
+
+
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/a52655ac/Squiggly/ane/Squiggly/AdobeSpellingFramework/asdocgen.bat
----------------------------------------------------------------------
diff --git a/Squiggly/ane/Squiggly/AdobeSpellingFramework/asdocgen.bat b/Squiggly/ane/Squiggly/AdobeSpellingFramework/asdocgen.bat
new file mode 100644
index 0000000..96f705c
--- /dev/null
+++ b/Squiggly/ane/Squiggly/AdobeSpellingFramework/asdocgen.bat
@@ -0,0 +1,18 @@
+@echo off
+rem Licensed to the Apache Software Foundation (ASF) under one or more
+rem contributor license agreements.  See the NOTICE file distributed with
+rem this work for additional information regarding copyright ownership.
+rem The ASF licenses this file to You under the Apache License, Version 2.0
+rem (the "License"); you may not use this file except in compliance with
+rem the License.  You may obtain a copy of the License at
+rem
+rem     http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing, software
+rem distributed under the License is distributed on an "AS IS" BASIS,
+rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem See the License for the specific language governing permissions and
+rem limitations under the License.
+
+REM This generates the ASDoc for Engine and SInC. Modify the path as you need. TODO: move to build folder.
+"C:\Program Files\Adobe\Adobe Flash Builder 4\sdks\4.0.0\bin\asdoc" -source-path src -doc-classes com.adobe.linguistics.spelling.framework.ResourceConfig com.adobe.linguistics.spelling.framework.SpellingConfiguration com.adobe.linguistics.spelling.framework.SpellingService com.adobe.linguistics.spelling.framework.UserDictionary -library-path "C:\Program Files\Adobe\Adobe Flash Builder 4\sdks\4.0.0\frameworks\libs" -exclude-dependencies=true -output docs -main-title "AdobeSpellingFramework API Documentation 0.4" -package com.adobe.linguistics.spelling.framework "This package provides spell checking framework for easy integration with the Squiggly spelling engine."

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/a52655ac/Squiggly/ane/Squiggly/AdobeSpellingFramework/src/com/adobe/linguistics/spelling/framework/ResourceTable.as
----------------------------------------------------------------------
diff --git a/Squiggly/ane/Squiggly/AdobeSpellingFramework/src/com/adobe/linguistics/spelling/framework/ResourceTable.as b/Squiggly/ane/Squiggly/AdobeSpellingFramework/src/com/adobe/linguistics/spelling/framework/ResourceTable.as
new file mode 100644
index 0000000..acbaeed
--- /dev/null
+++ b/Squiggly/ane/Squiggly/AdobeSpellingFramework/src/com/adobe/linguistics/spelling/framework/ResourceTable.as
@@ -0,0 +1,143 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.framework
+{
+	import flash.utils.IDataInput;
+	import flash.utils.IDataOutput;
+	import flash.utils.IExternalizable;
+	
+	[RemoteClass(alias='com.adobe.linguistics.spelling.framework.ResourceConfig')]
+		
+	/**
+	 * The ResourceTable class contains a table mapping language to the spelling resources. Resources here imply the URL of rule file and dict file to be used for the language.
+	 * 
+	 * @includeExample ../Examples/Flex/ConfigExample/src/ConfigExample.mxml -noswf
+	 * @playerversion Flash 10
+	 * @langversion 3.0
+	 */
+	public class ResourceTable implements IExternalizable
+	{
+		//private var _resources:Object;
+		private var _thirdPatyResourceLocation:String;
+		/**
+		 * Constructs a new ResourceTable object that performs language to resource mapping. 
+		 */
+		public function ResourceTable()
+		{
+			_thirdPatyResourceLocation=null;
+	//		_resources = new Object();
+		}
+
+		/**
+		 * A list of languages supported in this ResourceTable
+		 */
+/*		public function get availableLanguages():Vector.<String>
+		{
+			var result:Vector.<String> = new Vector.<String>();
+			for (var i:String in _resources)
+			{
+				result.push(i);
+			}
+			return result;
+		}
+*/		
+		/**
+		 * Set the resource for the specified language.
+		 * 
+		 * @param language The language that you want to assign spelling resources to.
+		 * @param resource A <code>Object</code> that behave as an associated array, it 
+		 * contains the path(s) to the resource file(s). For the time being, the only 
+		 * supported resource is hunspell dictionary, which contains a rule file (.aff) and a 
+		 * dictionary file (.dic). 
+		 * 
+		 * @example The following code sets the resource for American English language.
+		 * <listing version="3.0">
+		 * var resourceTable:ResourceTable = new ResourceTable();
+		 * resourceTable.setResource("en_US", {rule:"en_US.aff", dict:"en_US.dic"});
+		 * </listing>
+		 */
+/*		public function setResource(language:String, resource:Object):void
+		{
+			_resources[language] = resource;
+		}
+*/		
+		/**
+		 * Get the resource for the specified language.
+		 * 
+		 * @param language The language associated with the resource you are looking for.
+		 * @return An <code>Object</code> that stores the resource file URL(s).
+		 * @example The following code gets and uses the resource for American English language.
+		 * <listing version="3.0">
+		 * var resource_en_US:Object = SpellingConfiguration.resourceTable.getResource("en_US");
+		 * trace("rule file:" + resource_en_US["rule"] + ", dictionary file:" + resource_en_US.dict);
+		 * </listing>
+		 */
+/*		public function getResource(language:String):Object
+		{
+			return _resources[language];
+		}
+*/		
+		public function set thirdPatyResourceLocation(value:String):void{
+			_thirdPatyResourceLocation= value;
+		}
+		public function get thirdPatyResourceLocation():String{
+			return _thirdPatyResourceLocation;
+		}
+		
+		/**
+		 * Overwrite toString() for debug purpose.
+		 * @private
+		 */
+/*		public function toString():String
+		{
+			var result:String = new String();
+			for (var i:String in _resources)
+			{
+				result += i;
+				result += ": ";
+				result += "[";
+				for (var j:String in getResource(i))
+				{
+					result += j + ":" + getResource(i)[j] + " "
+				}
+				result += "]";
+				result += "; ";
+			}
+			return result;
+		}
+*/		
+		/**
+		 * Implement this IExternalizable API so that it can be serialized to an ByteArray.
+		 * @private
+		 */
+		public function readExternal(input:IDataInput):void {
+			_thirdPatyResourceLocation = input.readUTF();
+		}
+		
+		/**
+		 * Implement this IExternalizable API so that it can be serialized to an ByteArray.
+		 * @private
+		 */
+		public function writeExternal(output:IDataOutput):void {
+			output.writeUTF(_thirdPatyResourceLocation);
+		}
+
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/a52655ac/Squiggly/ane/Squiggly/AdobeSpellingFramework/src/com/adobe/linguistics/spelling/framework/SpellingConfiguration.as
----------------------------------------------------------------------
diff --git a/Squiggly/ane/Squiggly/AdobeSpellingFramework/src/com/adobe/linguistics/spelling/framework/SpellingConfiguration.as b/Squiggly/ane/Squiggly/AdobeSpellingFramework/src/com/adobe/linguistics/spelling/framework/SpellingConfiguration.as
new file mode 100644
index 0000000..88dc4bf
--- /dev/null
+++ b/Squiggly/ane/Squiggly/AdobeSpellingFramework/src/com/adobe/linguistics/spelling/framework/SpellingConfiguration.as
@@ -0,0 +1,103 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+  
+package com.adobe.linguistics.spelling.framework
+{
+	
+	
+	import flash.errors.IllegalOperationError;
+	//import com.adobe.linguistics.spelling.core.env.InternalConstants;
+	import com.adobe.linguistics.spelling.framework.ResourceTable;
+	
+	/**
+	 * The SpellingConfiguration is for setting and getting the configuration for the spell checker.
+	 * 
+	 * @includeExample ../Examples/Flex/ConfigExample/src/ConfigExample.mxml -noswf
+	 * @playerversion Flash 10
+	 * @langversion 3.0
+	 */
+	
+	public class SpellingConfiguration
+	{
+		
+
+		private static var _resourceTable:ResourceTable = null;
+	//	private static var _enableDictionarySplit:Boolean=false;//static value so can be initialised here
+	//	private static var _wordsPerDictionarySplit:int=InternalConstants.WORDS_PER_SPLIT;
+		
+		/**
+		 * The resourceTable is used for mapping the language to resources.
+		 */
+		public static function get resourceTable():ResourceTable
+		{
+			// Lazy initialization for the default value
+			if (_resourceTable == null) {
+				_resourceTable = new ResourceTable();
+				//_resourceTable.setResource("en_US", {rule:"data/en_US.aff", dict:"data/en_US.dic"});
+			}
+			return _resourceTable;	
+		}
+		
+		public static function set resourceTable(resourceTable:ResourceTable):void
+		{
+			_resourceTable = resourceTable;
+		}
+		
+		/**
+		 * 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>SpellUI.enableSpeliing</code>. Once <code>SpellUI.enableSpeliing</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 static function get enableDictionarySplit():Boolean
+		{
+			return _enableDictionarySplit;	
+		}
+		
+		public static 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>SpellUI.enableSpeliing</code>. Once <code>SpellUI.enableSpeliing</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 static function get wordsPerDictionarySplit():int
+		{
+			
+			return _wordsPerDictionarySplit;	
+		}
+		
+		public static 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;
+		}
+	*/	
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/a52655ac/Squiggly/ane/Squiggly/AdobeSpellingFramework/src/com/adobe/linguistics/spelling/framework/SpellingService.as
----------------------------------------------------------------------
diff --git a/Squiggly/ane/Squiggly/AdobeSpellingFramework/src/com/adobe/linguistics/spelling/framework/SpellingService.as b/Squiggly/ane/Squiggly/AdobeSpellingFramework/src/com/adobe/linguistics/spelling/framework/SpellingService.as
new file mode 100644
index 0000000..629d592
--- /dev/null
+++ b/Squiggly/ane/Squiggly/AdobeSpellingFramework/src/com/adobe/linguistics/spelling/framework/SpellingService.as
@@ -0,0 +1,223 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.framework
+{
+	import com.adobe.linguistics.extensions.HunspellNativeExtension;
+	import com.adobe.linguistics.spelling.UserDictionary;
+	import com.adobe.linguistics.spelling.core.UserDictionaryEngine;
+	
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+	/**
+	 * The SpellingService provides spell checking features for the specified language. 
+	 * This class makes use of SpellingConfiguration class to dynamically get the language dictionary location. The dictionaries are then loaded and SpellChecker object
+	 * created based on these dictionaries. 
+	 * @includeExample ../Examples/Flex/SpellingServiceEsg/src/SpellingServiceEsg.mxml -noswf
+	 * @playerversion Flash 10
+	 * @langversion 3.0.
+	 * 
+	 */
+	public class SpellingService extends EventDispatcher
+	{
+		private var _language:String = null;
+		private const _allLanguage:String= "lang_neutral";
+		private var _udEngine:UserDictionaryEngine = null;
+		private var _userDictionaries:Array = new Array();
+		private var _thirdPatyResourceLocation:String;
+		
+		private var _nativeExtension:HunspellNativeExtension;
+		private var _nativeIsInit:Boolean;				
+		// Static table for caching engines and fixed dictionaries
+		//private static var _engines:Array = new Array();
+	//	private static var _dicts:Array = new Array();
+		private static const HUNSPELL_INIT_FAIL:int= -1
+		private static const RESOURCE_FILES_MISSING:int= -2
+		private static const HUNSPELL_INIT_SUCCESS:int= 1
+			
+		
+		
+		/**
+		 * Constructs a spelling service object.
+		 *
+		 * @param language The language used to create a <code>SpellingService</code>.
+		 */
+		public function SpellingService(language:String)
+		{
+			_language = language;	
+			_thirdPatyResourceLocation="";
+		}
+
+		/**
+		 * Initialize the <code>SpellingService</code>. 
+		 */		
+		public function init():void
+		{
+			_udEngine = new UserDictionaryEngine();
+			//initialize native extension
+			_nativeExtension= new HunspellNativeExtension();
+			//"E:\\P90\\esg\\users\\ugoyal\\nativeLib\\Dictionaries"
+			
+			if(_thirdPatyResourceLocation!="" && ( _nativeExtension.initHunspellObject(_language, _thirdPatyResourceLocation)==HUNSPELL_INIT_SUCCESS ) )
+				_nativeIsInit=true;
+			else
+				_nativeIsInit=false;
+			loadDictComplete(null);//TODO: If performace problems are found use event mechanism in DLL to load ANE.
+		}
+		
+		private function loadDictComplete(e:Event):void
+		{
+
+			dispatchEvent(new Event(Event.COMPLETE));
+		}
+	
+		/**
+		 * Check the spelling of a word.
+		 *
+		 * @param word The word to be checked.
+		 * @return True if the word is correctly spelled, false if it is misspelled.
+		 */		
+		public function checkWord(word:String):Boolean
+		{
+			if(_nativeIsInit)
+			return (  _udEngine.spell(word, _language) || _udEngine.spell(word, _allLanguage)|| _nativeExtension.checkWord(word,_language) );
+			else //return true if the ANE is failed to initialize i.e. stop spell checking without effect working of the Product.
+				return true;
+			//return ((_udEngine.spell(word)) || (_engine.checkWord(word)));
+		}
+
+		/**
+		 * Get the suggestion of a misspelled word. 
+		 *
+		 * @param word The word to be checked.
+		 * @return A vector containing all suggestions for the misspelled word, ordered by similarity to the original word. 
+		 * Note that if a word is already correctly spelled, an empty Vector is returned.
+		 * @internal TODO: get the suggestions from user dicitonaries
+		 */			
+		public function getSuggestions(word:String):Vector.<String>
+		{
+			var resultArray:Array;
+			if (_nativeIsInit)
+				resultArray=_nativeExtension.getSuggestions(word, _language);
+		//	var resultArray:Array;= _engine.getSuggestions(word);
+			
+			var resultVector:Vector.<String> = new Vector.<String>();
+			for each (var i:String in resultArray) {
+				resultVector.push(i);		
+			}
+			
+			return resultVector;
+		}
+		
+		/** 
+		 * Add a <code>UserDictionary</code> to the <code>SpellingService</code>.
+		 * 
+		 * @param userDictionary The UserDictionary to be added.
+		 * @return True if the UserDictionary is added successfully, false if any error occurs. An example error scenario: Trying to add a previously added user dictionary. 
+		 * @see UserDictionary
+		 */
+		public function addUserDictionary(userDictionary:UserDictionary):Boolean
+		{
+			if  (_udEngine.addDictionary(userDictionary) == true)
+			{
+				_userDictionaries.push(userDictionary);
+				return true;
+			} 
+			
+			return false;
+		}
+
+		/** 
+		 * Remove a <code>UserDictionary</code> from the <code>SpellingService</code>.
+		 * 
+		 * @param userDictionary The UserDictionary to be removed.
+		 * @return True if the UserDictionary is removed successfully, false if any error occurs. An example error scenario: Trying to remove a user dictionary that has not been added previously. 
+		 * @see UserDictionary
+		 */		
+		public function removeUserDictionary(userDictionary:UserDictionary):Boolean
+		{
+			if (_udEngine.removeDictionary(userDictionary) == true)
+			{
+				for ( var i:int =0; i < _userDictionaries.length; ++i ) {
+					if ( userDictionary == _userDictionaries[i] ) {
+						_userDictionaries.splice(i,1);
+						return true;
+					}
+				}
+			}
+			
+			return false;
+		}
+		
+		/**
+		 * A <code>Vector</code> of user dictionaries added to this <code>SpellingService</code>.
+		 * 
+		 * @return A <code>Vector</code> of <code>UserDictionary</code> objects.
+		 * @see UserDictionary
+		 */
+		public function get userDictionaries():Vector.<UserDictionary>
+		{	
+			var resultVector:Vector.<UserDictionary> = new Vector.<UserDictionary>;
+			for each (var i:UserDictionary in _userDictionaries) {
+				resultVector.push(i);		
+			}
+			
+			return resultVector;
+		}
+		
+		/**
+		 * 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>
+		 * */
+
+		
+		public function get thirdPatyResourceLocation():String
+		{
+			return _thirdPatyResourceLocation;
+		}
+		
+		public function set thirdPatyResourceLocation(value:String):void
+		{
+			_thirdPatyResourceLocation = value;
+		}
+	}
+}
+
+

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/a52655ac/Squiggly/ane/Squiggly/AdobeSpellingFramework/src/com/adobe/linguistics/spelling/framework/UserDictionaryV.as
----------------------------------------------------------------------
diff --git a/Squiggly/ane/Squiggly/AdobeSpellingFramework/src/com/adobe/linguistics/spelling/framework/UserDictionaryV.as b/Squiggly/ane/Squiggly/AdobeSpellingFramework/src/com/adobe/linguistics/spelling/framework/UserDictionaryV.as
new file mode 100644
index 0000000..a96ba50
--- /dev/null
+++ b/Squiggly/ane/Squiggly/AdobeSpellingFramework/src/com/adobe/linguistics/spelling/framework/UserDictionaryV.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.framework
+{
+	import __AS3__.vec.Vector;
+	
+	import com.adobe.linguistics.spelling.UserDictionary;
+	/**
+	 * 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 UserDictionaryV
+	{
+		private var _ud:com.adobe.linguistics.spelling.UserDictionary;
+		
+		/**
+		 * @private
+		 */
+		public function get internalUserDictionary():com.adobe.linguistics.spelling.UserDictionary
+		{
+			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 UserDictionaryV(wordList:Vector.<String>=null)
+		{
+			var array:Array = new Array();
+			if (wordList) {
+				for each (var w:String in wordList)
+					array.push(w);
+			}
+			
+			_ud = new com.adobe.linguistics.spelling.UserDictionary(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